Merge "usb: f_cdev: Add function suspend support for serial interfaces"
diff --git a/AndroidKernel.mk b/AndroidKernel.mk
index 26e5cb8..7233829 100644
--- a/AndroidKernel.mk
+++ b/AndroidKernel.mk
@@ -210,9 +210,11 @@
echo $(KERNEL_CONFIG_OVERRIDE) >> $(KERNEL_OUT)/.config; \
$(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) oldconfig; fi
+.PHONY: kerneltags
kerneltags: $(KERNEL_OUT) $(KERNEL_CONFIG)
$(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) tags
+.PHONY: kernelconfig
kernelconfig: $(KERNEL_OUT) $(KERNEL_CONFIG)
env KCONFIG_NOTIMESTAMP=true \
$(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) menuconfig
diff --git a/Documentation/devicetree/bindings/arm/msm/hidqvr-smp2p.txt b/Documentation/devicetree/bindings/arm/msm/hidqvr-smp2p.txt
new file mode 100644
index 0000000..32f1d16
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/hidqvr-smp2p.txt
@@ -0,0 +1,39 @@
+Qualcomm Technologies, Inc. HID QVR (hid-qvr) driver
+
+Required properties:
+-compatible :
+ To communicate with cdsp
+ qcom,smp2pgpio-qvrexternal-5-out (outbound)
+ qcom,smp2pgpio-qvrexternal-5-in (inbound)
+
+Example:
+ smp2pgpio_qvrexternal_5_out: qcom,smp2pgpio-qvrexternal-5-out {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "qvrexternal";
+ qcom,remote-pid = <5>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ smp2pgpio_qvrexternal_5_in: qcom,smp2pgpio-qvrexternal-5-in {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "qvrexternal";
+ qcom,remote-pid = <5>;
+ qcom,is-inbound;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ qcom,smp2pgpio_client_qvrexternal_5_out {
+ compatible = "qcom,smp2pgpio_client_qvrexternal_5_out";
+ gpios = <&smp2pgpio_qvrexternal_5_out 0 0>;
+ };
+
+ qcom,smp2pgpio_client_qvrexternal_5_in {
+ compatible = "qcom,smp2pgpio_client_qvrexternal_5_in";
+ gpios = <&smp2pgpio_qvrexternal_5_in 0 0>;
+ }
\ No newline at end of file
diff --git a/Documentation/devicetree/bindings/arm/msm/msm.txt b/Documentation/devicetree/bindings/arm/msm/msm.txt
index 0319e2f..ab58089 100644
--- a/Documentation/devicetree/bindings/arm/msm/msm.txt
+++ b/Documentation/devicetree/bindings/arm/msm/msm.txt
@@ -68,6 +68,9 @@
- MSM8917
compatible = "qcom,msm8917"
+- MSM8940
+ compatible = "qcom,msm8940"
+
- MSM8936
compatible = "qcom,msm8936"
@@ -279,6 +282,7 @@
compatible = "qcom,msm8917-rumi"
compatible = "qcom,msm8917-qrd"
compatible = "qcom,msm8917-qrd-sku5"
+compatible = "qcom,msm8940-mtp"
compatible = "qcom,msm8926-cdp"
compatible = "qcom,msm8926-mtp"
compatible = "qcom,msm8926-qrd"
diff --git a/Documentation/devicetree/bindings/arm/msm/wil6210.txt b/Documentation/devicetree/bindings/arm/msm/wil6210.txt
index 0c75cf6..23e4bd5 100644
--- a/Documentation/devicetree/bindings/arm/msm/wil6210.txt
+++ b/Documentation/devicetree/bindings/arm/msm/wil6210.txt
@@ -25,6 +25,7 @@
Optional properties:
- qcom,sleep-clk-en: GPIO for sleep clock used for low power modes by 11ad card
- qcom,wigig-en: Enable GPIO connected to 11ad card
+- qcom,wigig-dc: Enable DC to DC GPIO connected to 11ad card
- qcom,use-ext-supply: Boolean flag to indicate if 11ad SIP uses external power supply
- vdd-supply: phandle to 11ad VDD regulator node
- vddio-supply: phandle to 11ad VDDIO regulator node
@@ -45,6 +46,7 @@
qcom,smmu-mapping = <0x20000000 0xe0000000>;
qcom,pcie-parent = <&pcie1>;
qcom,wigig-en = <&tlmm 94 0>;
+ qcom,wigig-dc = <&tlmm 81 0>;
qcom,msm-bus,name = "wil6210";
qcom,msm-bus,num-cases = <2>;
qcom,msm-bus,num-paths = <1>;
diff --git a/Documentation/devicetree/bindings/drm/msm/mdss-dsi-panel.txt b/Documentation/devicetree/bindings/drm/msm/mdss-dsi-panel.txt
index c17970c..72c46f2 100644
--- a/Documentation/devicetree/bindings/drm/msm/mdss-dsi-panel.txt
+++ b/Documentation/devicetree/bindings/drm/msm/mdss-dsi-panel.txt
@@ -187,6 +187,9 @@
255 = default value.
- qcom,mdss-brightness-max-level: Specifies the max brightness level supported.
255 = default value.
+- qcom,bl-update-flag: A string that specifies controls for backlight update of the panel.
+ "delay_until_first_frame" = Delay backlight update of the panel
+ until the first frame is received from the HW.
- qcom,mdss-dsi-interleave-mode: Specifies interleave mode.
0 = default value.
- qcom,mdss-dsi-panel-type: Specifies the panel operating mode.
@@ -599,6 +602,7 @@
qcom,mdss-dsi-bl-min-level = <1>;
qcom,mdss-dsi-bl-max-level = < 15>;
qcom,mdss-brightness-max-level = <255>;
+ qcom,bl-update-flag = "delay_until_first_frame";
qcom,mdss-dsi-interleave-mode = <0>;
qcom,mdss-dsi-panel-type = "dsi_video_mode";
qcom,mdss-dsi-te-check-enable;
diff --git a/Documentation/devicetree/bindings/gpu/adreno.txt b/Documentation/devicetree/bindings/gpu/adreno.txt
index a4e9ba7..a59a322 100644
--- a/Documentation/devicetree/bindings/gpu/adreno.txt
+++ b/Documentation/devicetree/bindings/gpu/adreno.txt
@@ -6,8 +6,9 @@
- label: A string used as a descriptive name for the device.
- compatible: Must be "qcom,kgsl-3d0" and "qcom,kgsl-3d"
- reg: Specifies the register base address and size, the shader memory
- base address and size (if it exists), and the base address and size
- of the CX_DBGC block (if it exists).
+ base address and size (if it exists), base address and size
+ of the CX_DBGC block (if it exists), and the base address and
+ size of the CX_MISC block (if it exists).
- reg-names: Resource names used for the physical address of device registers
and shader memory. "kgsl_3d0_reg_memory" gives the physical address
and length of device registers while "kgsl_3d0_shader_memory" gives
@@ -15,7 +16,8 @@
specified, "qfprom_memory" gives the range for the efuse
registers used for various configuration options. If specified,
"kgsl_3d0_cx_dbgc_memory" gives the physical address and length
- of the CX DBGC block.
+ of the CX DBGC block. If specified, "cx_misc" gives
+ the physical address and length of the CX_MISC block.
- interrupts: Interrupt mapping for GPU IRQ.
- interrupt-names: String property to describe the name of the interrupt.
- qcom,id: An integer used as an identification number for the device.
diff --git a/Documentation/devicetree/bindings/i2c/qcom,i2c-qcom-geni.txt b/Documentation/devicetree/bindings/i2c/qcom,i2c-qcom-geni.txt
index 21edaa0..950884c 100644
--- a/Documentation/devicetree/bindings/i2c/qcom,i2c-qcom-geni.txt
+++ b/Documentation/devicetree/bindings/i2c/qcom,i2c-qcom-geni.txt
@@ -17,6 +17,9 @@
Optional property:
- qcom,clk-freq-out : Desired I2C bus clock frequency in Hz.
When missing default to 400000Hz.
+ - qcom,disable-autosuspend : Disable autosuspend for I2C controller and
+ I2C clients should call pm_runtime_get_sync()/put_sync() for the
+ I2C controller.
Child nodes should conform to i2c bus binding.
diff --git a/Documentation/devicetree/bindings/net/dsa/qca8k.txt b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
index 9c67ee4..bbcb255 100644
--- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
@@ -2,7 +2,10 @@
Required properties:
-- compatible: should be "qca,qca8337"
+- compatible: should be one of:
+ "qca,qca8334"
+ "qca,qca8337"
+
- #size-cells: must be 0
- #address-cells: must be 1
@@ -14,6 +17,20 @@
referencing the internal PHY connected to it. The CPU port of this switch is
always port 0.
+A CPU port node has the following optional node:
+
+- fixed-link : Fixed-link subnode describing a link to a non-MDIO
+ managed entity. See
+ Documentation/devicetree/bindings/net/fixed-link.txt
+ for details.
+
+For QCA8K the 'fixed-link' sub-node supports only the following properties:
+
+- 'speed' (integer, mandatory), to indicate the link speed. Accepted
+ values are 10, 100 and 1000
+- 'full-duplex' (boolean, optional), to indicate that full duplex is
+ used. When absent, half duplex is assumed.
+
Example:
@@ -53,6 +70,10 @@
label = "cpu";
ethernet = <&gmac1>;
phy-mode = "rgmii";
+ fixed-link {
+ speed = 1000;
+ full-duplex;
+ };
};
port@1 {
diff --git a/Documentation/devicetree/bindings/net/meson-dwmac.txt b/Documentation/devicetree/bindings/net/meson-dwmac.txt
index 89e62dd..da37da0 100644
--- a/Documentation/devicetree/bindings/net/meson-dwmac.txt
+++ b/Documentation/devicetree/bindings/net/meson-dwmac.txt
@@ -10,6 +10,7 @@
- "amlogic,meson6-dwmac"
- "amlogic,meson8b-dwmac"
- "amlogic,meson-gxbb-dwmac"
+ - "amlogic,meson-axg-dwmac"
Additionally "snps,dwmac" and any applicable more
detailed version number described in net/stmmac.txt
should be used.
diff --git a/Documentation/devicetree/bindings/pci/msm_ep_pcie.txt b/Documentation/devicetree/bindings/pci/msm_ep_pcie.txt
index faf56c2..6026756 100644
--- a/Documentation/devicetree/bindings/pci/msm_ep_pcie.txt
+++ b/Documentation/devicetree/bindings/pci/msm_ep_pcie.txt
@@ -49,6 +49,8 @@
- qcom,phy-status-reg: Register offset for PHY status.
- qcom,dbi-base-reg: Register offset for DBI base address.
- qcom,slv-space-reg: Register offset for slave address space size.
+ - qcom,pcie-vendor-id: Vendor id to be written to the Vendor ID register.
+ - qcom,pcie-device-id: Device id to be written to the Device ID register.
- qcom,pcie-link-speed: generation of PCIe link speed. The value could be
1, 2 or 3.
- qcom,pcie-active-config: boolean type; active configuration of PCIe
diff --git a/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt
index fe7fe0b..1b98817 100644
--- a/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt
@@ -3,8 +3,10 @@
Required properties for the root node:
- compatible: one of "amlogic,meson8-cbus-pinctrl"
"amlogic,meson8b-cbus-pinctrl"
+ "amlogic,meson8m2-cbus-pinctrl"
"amlogic,meson8-aobus-pinctrl"
"amlogic,meson8b-aobus-pinctrl"
+ "amlogic,meson8m2-aobus-pinctrl"
"amlogic,meson-gxbb-periphs-pinctrl"
"amlogic,meson-gxbb-aobus-pinctrl"
- reg: address and size of registers controlling irq functionality
diff --git a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt
index 22b9f59..ea13d36 100644
--- a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt
+++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt
@@ -179,6 +179,14 @@
Element 0 - Retry value for timer
Element 1 - Maximum value for timer
+- qcom,fg-esr-timer-shutdown
+ Usage: optional
+ Value type: <prop-encoded-array>
+ Definition: Number of cycles between ESR pulses at/after shutdwon.This is
+ defined when TWM (traditional watch mode) is supported.
+ Element 0 - Retry value for timer
+ Element 1 - Maximum value for timer
+
- qcom,fg-esr-pulse-thresh-ma
Usage: optional
Value type: <u32>
@@ -464,6 +472,22 @@
Definition: A boolean property when defined uses software based
ESR during charging.
+- qcom,fg-disable-esr-pull-dn
+ Usage: optional
+ Value type: <empty>
+ Definition: A boolean property which disables ESR pull-down.
+ This is to be used for debug purposes only.
+
+- qcom,fg-sync-sleep-threshold-ma
+ Usage: optional
+ Value type: <u32>
+ Definition: The minimum battery current for FG to enter into sync-sleep.
+
+- qcom,fg-disable-in-twm
+ Usage: optional
+ Value type: <empty>
+ Definition: A boolean property which disables FG during TWM entry.
+
==========================================================
Second Level Nodes - Peripherals managed by FG Gen3 driver
==========================================================
diff --git a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-qg.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-qg.txt
index 83f964d..1e49e96 100644
--- a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-qg.txt
+++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-qg.txt
@@ -308,6 +308,20 @@
Definition: Boolean property to support external-rsense based
configuration.
+- qcom,shutdown-temp-diff
+ Usage: optional
+ Value type: <u32>
+ Definition: The allowed battery temperature in deci-degree difference
+ between shutdown and power-on to continue with the shutdown
+ SOC. If not specified the default value is 6 degrees C (60).
+
+- qcom,shutdown-soc-threshold
+ Usage: optional
+ Value type: <u32>
+ Definition: The SOC difference allowed between PON and SHUTDOWN SOC
+ for the shutdown SOC to be used. If the difference is
+ beyond this value the PON SOC is used.
+
==========================================================
Second Level Nodes - Peripherals managed by QGAUGE driver
==========================================================
diff --git a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb2.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb2.txt
index 9de24c3..452fff9 100644
--- a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb2.txt
+++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb2.txt
@@ -199,6 +199,12 @@
Definition: Boolean flag which when present disables STAT pin default software
override configuration.
+- qcom,fcc-stepping-enable
+ Usage: optional
+ Value type: bool
+ Definition: Boolean flag which when present enables stepwise change in FCC.
+ The default stepping rate is 100mA/sec.
+
=============================================
Second Level Nodes - SMB2 Charger Peripherals
=============================================
diff --git a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb5.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb5.txt
index 2c26743..bba5784 100644
--- a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb5.txt
+++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb5.txt
@@ -247,6 +247,12 @@
Definition: Boolean flag which when present enables mositure protection
feature.
+- qcom,fcc-stepping-enable
+ Usage: optional
+ Value type: bool
+ Definition: Boolean flag which when present enables stepwise change in FCC.
+ The default stepping rate is 100mA/sec.
+
=============================================
Second Level Nodes - SMB5 Charger Peripherals
=============================================
diff --git a/Documentation/devicetree/bindings/regulator/qpnp-lcdb-regulator.txt b/Documentation/devicetree/bindings/regulator/qpnp-lcdb-regulator.txt
index 72c4eaf..748cfbe 100644
--- a/Documentation/devicetree/bindings/regulator/qpnp-lcdb-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/qpnp-lcdb-regulator.txt
@@ -31,6 +31,14 @@
Value type: <phandle>
Definition: Phandle to the PMIC's revid node
+- qcom,voltage-step-ramp
+ Usage: optional
+ Value type: <bool>
+ Definition: Required only if the voltage needs to be set in the
+ steps of 500 mV starting from the 4500 mV. This needs
+ to be enabled only on platforms where voltage needs to
+ be ramped up with multiple steps.
+
Touch-to-wake (TTW) properties:
TTW supports 2 modes of operation - HW and SW. In the HW mode the enable/disable
diff --git a/Documentation/devicetree/bindings/usb/msm-phy.txt b/Documentation/devicetree/bindings/usb/msm-phy.txt
index c28b05b..bcaa311 100644
--- a/Documentation/devicetree/bindings/usb/msm-phy.txt
+++ b/Documentation/devicetree/bindings/usb/msm-phy.txt
@@ -107,6 +107,9 @@
microvolts or a value corresponding to voltage corner.
- "pcs_clamp_enable_reg" : Clamps the phy data inputs and enables USB3
autonomous mode.
+ - extcon : phandle to external connector devices which provide type-C based
+ "USB-HOST" cable events. This phandle is used for notifying number
+ of lanes used in case of USB+DP concurrent mode to driver.
Example:
ssphy0: ssphy@f9b38000 {
diff --git a/Documentation/filesystems/fscrypt.rst b/Documentation/filesystems/fscrypt.rst
new file mode 100644
index 0000000..48b424d
--- /dev/null
+++ b/Documentation/filesystems/fscrypt.rst
@@ -0,0 +1,626 @@
+=====================================
+Filesystem-level encryption (fscrypt)
+=====================================
+
+Introduction
+============
+
+fscrypt is a library which filesystems can hook into to support
+transparent encryption of files and directories.
+
+Note: "fscrypt" in this document refers to the kernel-level portion,
+implemented in ``fs/crypto/``, as opposed to the userspace tool
+`fscrypt <https://github.com/google/fscrypt>`_. This document only
+covers the kernel-level portion. For command-line examples of how to
+use encryption, see the documentation for the userspace tool `fscrypt
+<https://github.com/google/fscrypt>`_. Also, it is recommended to use
+the fscrypt userspace tool, or other existing userspace tools such as
+`fscryptctl <https://github.com/google/fscryptctl>`_ or `Android's key
+management system
+<https://source.android.com/security/encryption/file-based>`_, over
+using the kernel's API directly. Using existing tools reduces the
+chance of introducing your own security bugs. (Nevertheless, for
+completeness this documentation covers the kernel's API anyway.)
+
+Unlike dm-crypt, fscrypt operates at the filesystem level rather than
+at the block device level. This allows it to encrypt different files
+with different keys and to have unencrypted files on the same
+filesystem. This is useful for multi-user systems where each user's
+data-at-rest needs to be cryptographically isolated from the others.
+However, except for filenames, fscrypt does not encrypt filesystem
+metadata.
+
+Unlike eCryptfs, which is a stacked filesystem, fscrypt is integrated
+directly into supported filesystems --- currently ext4, F2FS, and
+UBIFS. This allows encrypted files to be read and written without
+caching both the decrypted and encrypted pages in the pagecache,
+thereby nearly halving the memory used and bringing it in line with
+unencrypted files. Similarly, half as many dentries and inodes are
+needed. eCryptfs also limits encrypted filenames to 143 bytes,
+causing application compatibility issues; fscrypt allows the full 255
+bytes (NAME_MAX). Finally, unlike eCryptfs, the fscrypt API can be
+used by unprivileged users, with no need to mount anything.
+
+fscrypt does not support encrypting files in-place. Instead, it
+supports marking an empty directory as encrypted. Then, after
+userspace provides the key, all regular files, directories, and
+symbolic links created in that directory tree are transparently
+encrypted.
+
+Threat model
+============
+
+Offline attacks
+---------------
+
+Provided that userspace chooses a strong encryption key, fscrypt
+protects the confidentiality of file contents and filenames in the
+event of a single point-in-time permanent offline compromise of the
+block device content. fscrypt does not protect the confidentiality of
+non-filename metadata, e.g. file sizes, file permissions, file
+timestamps, and extended attributes. Also, the existence and location
+of holes (unallocated blocks which logically contain all zeroes) in
+files is not protected.
+
+fscrypt is not guaranteed to protect confidentiality or authenticity
+if an attacker is able to manipulate the filesystem offline prior to
+an authorized user later accessing the filesystem.
+
+Online attacks
+--------------
+
+fscrypt (and storage encryption in general) can only provide limited
+protection, if any at all, against online attacks. In detail:
+
+fscrypt is only resistant to side-channel attacks, such as timing or
+electromagnetic attacks, to the extent that the underlying Linux
+Cryptographic API algorithms are. If a vulnerable algorithm is used,
+such as a table-based implementation of AES, it may be possible for an
+attacker to mount a side channel attack against the online system.
+Side channel attacks may also be mounted against applications
+consuming decrypted data.
+
+After an encryption key has been provided, fscrypt is not designed to
+hide the plaintext file contents or filenames from other users on the
+same system, regardless of the visibility of the keyring key.
+Instead, existing access control mechanisms such as file mode bits,
+POSIX ACLs, LSMs, or mount namespaces should be used for this purpose.
+Also note that as long as the encryption keys are *anywhere* in
+memory, an online attacker can necessarily compromise them by mounting
+a physical attack or by exploiting any kernel security vulnerability
+which provides an arbitrary memory read primitive.
+
+While it is ostensibly possible to "evict" keys from the system,
+recently accessed encrypted files will remain accessible at least
+until the filesystem is unmounted or the VFS caches are dropped, e.g.
+using ``echo 2 > /proc/sys/vm/drop_caches``. Even after that, if the
+RAM is compromised before being powered off, it will likely still be
+possible to recover portions of the plaintext file contents, if not
+some of the encryption keys as well. (Since Linux v4.12, all
+in-kernel keys related to fscrypt are sanitized before being freed.
+However, userspace would need to do its part as well.)
+
+Currently, fscrypt does not prevent a user from maliciously providing
+an incorrect key for another user's existing encrypted files. A
+protection against this is planned.
+
+Key hierarchy
+=============
+
+Master Keys
+-----------
+
+Each encrypted directory tree is protected by a *master key*. Master
+keys can be up to 64 bytes long, and must be at least as long as the
+greater of the key length needed by the contents and filenames
+encryption modes being used. For example, if AES-256-XTS is used for
+contents encryption, the master key must be 64 bytes (512 bits). Note
+that the XTS mode is defined to require a key twice as long as that
+required by the underlying block cipher.
+
+To "unlock" an encrypted directory tree, userspace must provide the
+appropriate master key. There can be any number of master keys, each
+of which protects any number of directory trees on any number of
+filesystems.
+
+Userspace should generate master keys either using a cryptographically
+secure random number generator, or by using a KDF (Key Derivation
+Function). Note that whenever a KDF is used to "stretch" a
+lower-entropy secret such as a passphrase, it is critical that a KDF
+designed for this purpose be used, such as scrypt, PBKDF2, or Argon2.
+
+Per-file keys
+-------------
+
+Master keys are not used to encrypt file contents or names directly.
+Instead, a unique key is derived for each encrypted file, including
+each regular file, directory, and symbolic link. This has several
+advantages:
+
+- In cryptosystems, the same key material should never be used for
+ different purposes. Using the master key as both an XTS key for
+ contents encryption and as a CTS-CBC key for filenames encryption
+ would violate this rule.
+- Per-file keys simplify the choice of IVs (Initialization Vectors)
+ for contents encryption. Without per-file keys, to ensure IV
+ uniqueness both the inode and logical block number would need to be
+ encoded in the IVs. This would make it impossible to renumber
+ inodes, which e.g. ``resize2fs`` can do when resizing an ext4
+ filesystem. With per-file keys, it is sufficient to encode just the
+ logical block number in the IVs.
+- Per-file keys strengthen the encryption of filenames, where IVs are
+ reused out of necessity. With a unique key per directory, IV reuse
+ is limited to within a single directory.
+- Per-file keys allow individual files to be securely erased simply by
+ securely erasing their keys. (Not yet implemented.)
+
+A KDF (Key Derivation Function) is used to derive per-file keys from
+the master key. This is done instead of wrapping a randomly-generated
+key for each file because it reduces the size of the encryption xattr,
+which for some filesystems makes the xattr more likely to fit in-line
+in the filesystem's inode table. With a KDF, only a 16-byte nonce is
+required --- long enough to make key reuse extremely unlikely. A
+wrapped key, on the other hand, would need to be up to 64 bytes ---
+the length of an AES-256-XTS key. Furthermore, currently there is no
+requirement to support unlocking a file with multiple alternative
+master keys or to support rotating master keys. Instead, the master
+keys may be wrapped in userspace, e.g. as done by the `fscrypt
+<https://github.com/google/fscrypt>`_ tool.
+
+The current KDF encrypts the master key using the 16-byte nonce as an
+AES-128-ECB key. The output is used as the derived key. If the
+output is longer than needed, then it is truncated to the needed
+length. Truncation is the norm for directories and symlinks, since
+those use the CTS-CBC encryption mode which requires a key half as
+long as that required by the XTS encryption mode.
+
+Note: this KDF meets the primary security requirement, which is to
+produce unique derived keys that preserve the entropy of the master
+key, assuming that the master key is already a good pseudorandom key.
+However, it is nonstandard and has some problems such as being
+reversible, so it is generally considered to be a mistake! It may be
+replaced with HKDF or another more standard KDF in the future.
+
+Encryption modes and usage
+==========================
+
+fscrypt allows one encryption mode to be specified for file contents
+and one encryption mode to be specified for filenames. Different
+directory trees are permitted to use different encryption modes.
+Currently, the following pairs of encryption modes are supported:
+
+- AES-256-XTS for contents and AES-256-CTS-CBC for filenames
+- AES-128-CBC for contents and AES-128-CTS-CBC for filenames
+- Speck128/256-XTS for contents and Speck128/256-CTS-CBC for filenames
+
+It is strongly recommended to use AES-256-XTS for contents encryption.
+AES-128-CBC was added only for low-powered embedded devices with
+crypto accelerators such as CAAM or CESA that do not support XTS.
+
+Similarly, Speck128/256 support was only added for older or low-end
+CPUs which cannot do AES fast enough -- especially ARM CPUs which have
+NEON instructions but not the Cryptography Extensions -- and for which
+it would not otherwise be feasible to use encryption at all. It is
+not recommended to use Speck on CPUs that have AES instructions.
+Speck support is only available if it has been enabled in the crypto
+API via CONFIG_CRYPTO_SPECK. Also, on ARM platforms, to get
+acceptable performance CONFIG_CRYPTO_SPECK_NEON must be enabled.
+
+New encryption modes can be added relatively easily, without changes
+to individual filesystems. However, authenticated encryption (AE)
+modes are not currently supported because of the difficulty of dealing
+with ciphertext expansion.
+
+For file contents, each filesystem block is encrypted independently.
+Currently, only the case where the filesystem block size is equal to
+the system's page size (usually 4096 bytes) is supported. With the
+XTS mode of operation (recommended), the logical block number within
+the file is used as the IV. With the CBC mode of operation (not
+recommended), ESSIV is used; specifically, the IV for CBC is the
+logical block number encrypted with AES-256, where the AES-256 key is
+the SHA-256 hash of the inode's data encryption key.
+
+For filenames, the full filename is encrypted at once. Because of the
+requirements to retain support for efficient directory lookups and
+filenames of up to 255 bytes, a constant initialization vector (IV) is
+used. However, each encrypted directory uses a unique key, which
+limits IV reuse to within a single directory. Note that IV reuse in
+the context of CTS-CBC encryption means that when the original
+filenames share a common prefix at least as long as the cipher block
+size (16 bytes for AES), the corresponding encrypted filenames will
+also share a common prefix. This is undesirable; it may be fixed in
+the future by switching to an encryption mode that is a strong
+pseudorandom permutation on arbitrary-length messages, e.g. the HEH
+(Hash-Encrypt-Hash) mode.
+
+Since filenames are encrypted with the CTS-CBC mode of operation, the
+plaintext and ciphertext filenames need not be multiples of the AES
+block size, i.e. 16 bytes. However, the minimum size that can be
+encrypted is 16 bytes, so shorter filenames are NUL-padded to 16 bytes
+before being encrypted. In addition, to reduce leakage of filename
+lengths via their ciphertexts, all filenames are NUL-padded to the
+next 4, 8, 16, or 32-byte boundary (configurable). 32 is recommended
+since this provides the best confidentiality, at the cost of making
+directory entries consume slightly more space. Note that since NUL
+(``\0``) is not otherwise a valid character in filenames, the padding
+will never produce duplicate plaintexts.
+
+Symbolic link targets are considered a type of filename and are
+encrypted in the same way as filenames in directory entries. Each
+symlink also uses a unique key; hence, the hardcoded IV is not a
+problem for symlinks.
+
+User API
+========
+
+Setting an encryption policy
+----------------------------
+
+The FS_IOC_SET_ENCRYPTION_POLICY ioctl sets an encryption policy on an
+empty directory or verifies that a directory or regular file already
+has the specified encryption policy. It takes in a pointer to a
+:c:type:`struct fscrypt_policy`, defined as follows::
+
+ #define FS_KEY_DESCRIPTOR_SIZE 8
+
+ struct fscrypt_policy {
+ __u8 version;
+ __u8 contents_encryption_mode;
+ __u8 filenames_encryption_mode;
+ __u8 flags;
+ __u8 master_key_descriptor[FS_KEY_DESCRIPTOR_SIZE];
+ };
+
+This structure must be initialized as follows:
+
+- ``version`` must be 0.
+
+- ``contents_encryption_mode`` and ``filenames_encryption_mode`` must
+ be set to constants from ``<linux/fs.h>`` which identify the
+ encryption modes to use. If unsure, use
+ FS_ENCRYPTION_MODE_AES_256_XTS (1) for ``contents_encryption_mode``
+ and FS_ENCRYPTION_MODE_AES_256_CTS (4) for
+ ``filenames_encryption_mode``.
+
+- ``flags`` must be set to a value from ``<linux/fs.h>`` which
+ identifies the amount of NUL-padding to use when encrypting
+ filenames. If unsure, use FS_POLICY_FLAGS_PAD_32 (0x3).
+
+- ``master_key_descriptor`` specifies how to find the master key in
+ the keyring; see `Adding keys`_. It is up to userspace to choose a
+ unique ``master_key_descriptor`` for each master key. The e4crypt
+ and fscrypt tools use the first 8 bytes of
+ ``SHA-512(SHA-512(master_key))``, but this particular scheme is not
+ required. Also, the master key need not be in the keyring yet when
+ FS_IOC_SET_ENCRYPTION_POLICY is executed. However, it must be added
+ before any files can be created in the encrypted directory.
+
+If the file is not yet encrypted, then FS_IOC_SET_ENCRYPTION_POLICY
+verifies that the file is an empty directory. If so, the specified
+encryption policy is assigned to the directory, turning it into an
+encrypted directory. After that, and after providing the
+corresponding master key as described in `Adding keys`_, all regular
+files, directories (recursively), and symlinks created in the
+directory will be encrypted, inheriting the same encryption policy.
+The filenames in the directory's entries will be encrypted as well.
+
+Alternatively, if the file is already encrypted, then
+FS_IOC_SET_ENCRYPTION_POLICY validates that the specified encryption
+policy exactly matches the actual one. If they match, then the ioctl
+returns 0. Otherwise, it fails with EEXIST. This works on both
+regular files and directories, including nonempty directories.
+
+Note that the ext4 filesystem does not allow the root directory to be
+encrypted, even if it is empty. Users who want to encrypt an entire
+filesystem with one key should consider using dm-crypt instead.
+
+FS_IOC_SET_ENCRYPTION_POLICY can fail with the following errors:
+
+- ``EACCES``: the file is not owned by the process's uid, nor does the
+ process have the CAP_FOWNER capability in a namespace with the file
+ owner's uid mapped
+- ``EEXIST``: the file is already encrypted with an encryption policy
+ different from the one specified
+- ``EINVAL``: an invalid encryption policy was specified (invalid
+ version, mode(s), or flags)
+- ``ENOTDIR``: the file is unencrypted and is a regular file, not a
+ directory
+- ``ENOTEMPTY``: the file is unencrypted and is a nonempty directory
+- ``ENOTTY``: this type of filesystem does not implement encryption
+- ``EOPNOTSUPP``: the kernel was not configured with encryption
+ support for this filesystem, or the filesystem superblock has not
+ had encryption enabled on it. (For example, to use encryption on an
+ ext4 filesystem, CONFIG_EXT4_ENCRYPTION must be enabled in the
+ kernel config, and the superblock must have had the "encrypt"
+ feature flag enabled using ``tune2fs -O encrypt`` or ``mkfs.ext4 -O
+ encrypt``.)
+- ``EPERM``: this directory may not be encrypted, e.g. because it is
+ the root directory of an ext4 filesystem
+- ``EROFS``: the filesystem is readonly
+
+Getting an encryption policy
+----------------------------
+
+The FS_IOC_GET_ENCRYPTION_POLICY ioctl retrieves the :c:type:`struct
+fscrypt_policy`, if any, for a directory or regular file. See above
+for the struct definition. No additional permissions are required
+beyond the ability to open the file.
+
+FS_IOC_GET_ENCRYPTION_POLICY can fail with the following errors:
+
+- ``EINVAL``: the file is encrypted, but it uses an unrecognized
+ encryption context format
+- ``ENODATA``: the file is not encrypted
+- ``ENOTTY``: this type of filesystem does not implement encryption
+- ``EOPNOTSUPP``: the kernel was not configured with encryption
+ support for this filesystem
+
+Note: if you only need to know whether a file is encrypted or not, on
+most filesystems it is also possible to use the FS_IOC_GETFLAGS ioctl
+and check for FS_ENCRYPT_FL, or to use the statx() system call and
+check for STATX_ATTR_ENCRYPTED in stx_attributes.
+
+Getting the per-filesystem salt
+-------------------------------
+
+Some filesystems, such as ext4 and F2FS, also support the deprecated
+ioctl FS_IOC_GET_ENCRYPTION_PWSALT. This ioctl retrieves a randomly
+generated 16-byte value stored in the filesystem superblock. This
+value is intended to used as a salt when deriving an encryption key
+from a passphrase or other low-entropy user credential.
+
+FS_IOC_GET_ENCRYPTION_PWSALT is deprecated. Instead, prefer to
+generate and manage any needed salt(s) in userspace.
+
+Adding keys
+-----------
+
+To provide a master key, userspace must add it to an appropriate
+keyring using the add_key() system call (see:
+``Documentation/security/keys/core.rst``). The key type must be
+"logon"; keys of this type are kept in kernel memory and cannot be
+read back by userspace. The key description must be "fscrypt:"
+followed by the 16-character lower case hex representation of the
+``master_key_descriptor`` that was set in the encryption policy. The
+key payload must conform to the following structure::
+
+ #define FS_MAX_KEY_SIZE 64
+
+ struct fscrypt_key {
+ u32 mode;
+ u8 raw[FS_MAX_KEY_SIZE];
+ u32 size;
+ };
+
+``mode`` is ignored; just set it to 0. The actual key is provided in
+``raw`` with ``size`` indicating its size in bytes. That is, the
+bytes ``raw[0..size-1]`` (inclusive) are the actual key.
+
+The key description prefix "fscrypt:" may alternatively be replaced
+with a filesystem-specific prefix such as "ext4:". However, the
+filesystem-specific prefixes are deprecated and should not be used in
+new programs.
+
+There are several different types of keyrings in which encryption keys
+may be placed, such as a session keyring, a user session keyring, or a
+user keyring. Each key must be placed in a keyring that is "attached"
+to all processes that might need to access files encrypted with it, in
+the sense that request_key() will find the key. Generally, if only
+processes belonging to a specific user need to access a given
+encrypted directory and no session keyring has been installed, then
+that directory's key should be placed in that user's user session
+keyring or user keyring. Otherwise, a session keyring should be
+installed if needed, and the key should be linked into that session
+keyring, or in a keyring linked into that session keyring.
+
+Note: introducing the complex visibility semantics of keyrings here
+was arguably a mistake --- especially given that by design, after any
+process successfully opens an encrypted file (thereby setting up the
+per-file key), possessing the keyring key is not actually required for
+any process to read/write the file until its in-memory inode is
+evicted. In the future there probably should be a way to provide keys
+directly to the filesystem instead, which would make the intended
+semantics clearer.
+
+Access semantics
+================
+
+With the key
+------------
+
+With the encryption key, encrypted regular files, directories, and
+symlinks behave very similarly to their unencrypted counterparts ---
+after all, the encryption is intended to be transparent. However,
+astute users may notice some differences in behavior:
+
+- Unencrypted files, or files encrypted with a different encryption
+ policy (i.e. different key, modes, or flags), cannot be renamed or
+ linked into an encrypted directory; see `Encryption policy
+ enforcement`_. Attempts to do so will fail with EPERM. However,
+ encrypted files can be renamed within an encrypted directory, or
+ into an unencrypted directory.
+
+- Direct I/O is not supported on encrypted files. Attempts to use
+ direct I/O on such files will fall back to buffered I/O.
+
+- The fallocate operations FALLOC_FL_COLLAPSE_RANGE,
+ FALLOC_FL_INSERT_RANGE, and FALLOC_FL_ZERO_RANGE are not supported
+ on encrypted files and will fail with EOPNOTSUPP.
+
+- Online defragmentation of encrypted files is not supported. The
+ EXT4_IOC_MOVE_EXT and F2FS_IOC_MOVE_RANGE ioctls will fail with
+ EOPNOTSUPP.
+
+- The ext4 filesystem does not support data journaling with encrypted
+ regular files. It will fall back to ordered data mode instead.
+
+- DAX (Direct Access) is not supported on encrypted files.
+
+- The st_size of an encrypted symlink will not necessarily give the
+ length of the symlink target as required by POSIX. It will actually
+ give the length of the ciphertext, which will be slightly longer
+ than the plaintext due to NUL-padding and an extra 2-byte overhead.
+
+- The maximum length of an encrypted symlink is 2 bytes shorter than
+ the maximum length of an unencrypted symlink. For example, on an
+ EXT4 filesystem with a 4K block size, unencrypted symlinks can be up
+ to 4095 bytes long, while encrypted symlinks can only be up to 4093
+ bytes long (both lengths excluding the terminating null).
+
+Note that mmap *is* supported. This is possible because the pagecache
+for an encrypted file contains the plaintext, not the ciphertext.
+
+Without the key
+---------------
+
+Some filesystem operations may be performed on encrypted regular
+files, directories, and symlinks even before their encryption key has
+been provided:
+
+- File metadata may be read, e.g. using stat().
+
+- Directories may be listed, in which case the filenames will be
+ listed in an encoded form derived from their ciphertext. The
+ current encoding algorithm is described in `Filename hashing and
+ encoding`_. The algorithm is subject to change, but it is
+ guaranteed that the presented filenames will be no longer than
+ NAME_MAX bytes, will not contain the ``/`` or ``\0`` characters, and
+ will uniquely identify directory entries.
+
+ The ``.`` and ``..`` directory entries are special. They are always
+ present and are not encrypted or encoded.
+
+- Files may be deleted. That is, nondirectory files may be deleted
+ with unlink() as usual, and empty directories may be deleted with
+ rmdir() as usual. Therefore, ``rm`` and ``rm -r`` will work as
+ expected.
+
+- Symlink targets may be read and followed, but they will be presented
+ in encrypted form, similar to filenames in directories. Hence, they
+ are unlikely to point to anywhere useful.
+
+Without the key, regular files cannot be opened or truncated.
+Attempts to do so will fail with ENOKEY. This implies that any
+regular file operations that require a file descriptor, such as
+read(), write(), mmap(), fallocate(), and ioctl(), are also forbidden.
+
+Also without the key, files of any type (including directories) cannot
+be created or linked into an encrypted directory, nor can a name in an
+encrypted directory be the source or target of a rename, nor can an
+O_TMPFILE temporary file be created in an encrypted directory. All
+such operations will fail with ENOKEY.
+
+It is not currently possible to backup and restore encrypted files
+without the encryption key. This would require special APIs which
+have not yet been implemented.
+
+Encryption policy enforcement
+=============================
+
+After an encryption policy has been set on a directory, all regular
+files, directories, and symbolic links created in that directory
+(recursively) will inherit that encryption policy. Special files ---
+that is, named pipes, device nodes, and UNIX domain sockets --- will
+not be encrypted.
+
+Except for those special files, it is forbidden to have unencrypted
+files, or files encrypted with a different encryption policy, in an
+encrypted directory tree. Attempts to link or rename such a file into
+an encrypted directory will fail with EPERM. This is also enforced
+during ->lookup() to provide limited protection against offline
+attacks that try to disable or downgrade encryption in known locations
+where applications may later write sensitive data. It is recommended
+that systems implementing a form of "verified boot" take advantage of
+this by validating all top-level encryption policies prior to access.
+
+Implementation details
+======================
+
+Encryption context
+------------------
+
+An encryption policy is represented on-disk by a :c:type:`struct
+fscrypt_context`. It is up to individual filesystems to decide where
+to store it, but normally it would be stored in a hidden extended
+attribute. It should *not* be exposed by the xattr-related system
+calls such as getxattr() and setxattr() because of the special
+semantics of the encryption xattr. (In particular, there would be
+much confusion if an encryption policy were to be added to or removed
+from anything other than an empty directory.) The struct is defined
+as follows::
+
+ #define FS_KEY_DESCRIPTOR_SIZE 8
+ #define FS_KEY_DERIVATION_NONCE_SIZE 16
+
+ struct fscrypt_context {
+ u8 format;
+ u8 contents_encryption_mode;
+ u8 filenames_encryption_mode;
+ u8 flags;
+ u8 master_key_descriptor[FS_KEY_DESCRIPTOR_SIZE];
+ u8 nonce[FS_KEY_DERIVATION_NONCE_SIZE];
+ };
+
+Note that :c:type:`struct fscrypt_context` contains the same
+information as :c:type:`struct fscrypt_policy` (see `Setting an
+encryption policy`_), except that :c:type:`struct fscrypt_context`
+also contains a nonce. The nonce is randomly generated by the kernel
+and is used to derive the inode's encryption key as described in
+`Per-file keys`_.
+
+Data path changes
+-----------------
+
+For the read path (->readpage()) of regular files, filesystems can
+read the ciphertext into the page cache and decrypt it in-place. The
+page lock must be held until decryption has finished, to prevent the
+page from becoming visible to userspace prematurely.
+
+For the write path (->writepage()) of regular files, filesystems
+cannot encrypt data in-place in the page cache, since the cached
+plaintext must be preserved. Instead, filesystems must encrypt into a
+temporary buffer or "bounce page", then write out the temporary
+buffer. Some filesystems, such as UBIFS, already use temporary
+buffers regardless of encryption. Other filesystems, such as ext4 and
+F2FS, have to allocate bounce pages specially for encryption.
+
+Filename hashing and encoding
+-----------------------------
+
+Modern filesystems accelerate directory lookups by using indexed
+directories. An indexed directory is organized as a tree keyed by
+filename hashes. When a ->lookup() is requested, the filesystem
+normally hashes the filename being looked up so that it can quickly
+find the corresponding directory entry, if any.
+
+With encryption, lookups must be supported and efficient both with and
+without the encryption key. Clearly, it would not work to hash the
+plaintext filenames, since the plaintext filenames are unavailable
+without the key. (Hashing the plaintext filenames would also make it
+impossible for the filesystem's fsck tool to optimize encrypted
+directories.) Instead, filesystems hash the ciphertext filenames,
+i.e. the bytes actually stored on-disk in the directory entries. When
+asked to do a ->lookup() with the key, the filesystem just encrypts
+the user-supplied name to get the ciphertext.
+
+Lookups without the key are more complicated. The raw ciphertext may
+contain the ``\0`` and ``/`` characters, which are illegal in
+filenames. Therefore, readdir() must base64-encode the ciphertext for
+presentation. For most filenames, this works fine; on ->lookup(), the
+filesystem just base64-decodes the user-supplied name to get back to
+the raw ciphertext.
+
+However, for very long filenames, base64 encoding would cause the
+filename length to exceed NAME_MAX. To prevent this, readdir()
+actually presents long filenames in an abbreviated form which encodes
+a strong "hash" of the ciphertext filename, along with the optional
+filesystem-specific hash(es) needed for directory lookups. This
+allows the filesystem to still, with a high degree of confidence, map
+the filename given in ->lookup() back to a particular directory entry
+that was previously listed by readdir(). See :c:type:`struct
+fscrypt_digested_name` in the source for more details.
+
+Note that the precise way that filenames are presented to userspace
+without the key is subject to change in the future. It is only meant
+as a way to temporarily present valid filenames so that commands like
+``rm -r`` work as expected on encrypted directories.
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 435a509..16149a7 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -4045,6 +4045,23 @@
spia_pedr=
spia_peddr=
+ ssbd= [ARM64,HW]
+ Speculative Store Bypass Disable control
+
+ On CPUs that are vulnerable to the Speculative
+ Store Bypass vulnerability and offer a
+ firmware based mitigation, this parameter
+ indicates how the mitigation should be used:
+
+ force-on: Unconditionally enable mitigation for
+ for both kernel and userspace
+ force-off: Unconditionally disable mitigation for
+ for both kernel and userspace
+ kernel: Always enable mitigation in the
+ kernel, and offer a prctl interface
+ to allow userspace to register its
+ interest in being mitigated too.
+
stack_guard_gap= [MM]
override the default stack gap protection. The value
is in page units and it defines how many pages prior
diff --git a/Makefile b/Makefile
index 98ce41f..64bf5d1 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
VERSION = 4
PATCHLEVEL = 9
-SUBLEVEL = 112
+SUBLEVEL = 117
EXTRAVERSION =
NAME = Roaring Lionus
@@ -654,6 +654,7 @@
KBUILD_CFLAGS += $(call cc-disable-warning, format-truncation)
KBUILD_CFLAGS += $(call cc-disable-warning, format-overflow)
KBUILD_CFLAGS += $(call cc-disable-warning, int-in-bool-context)
+KBUILD_CFLAGS += $(call cc-disable-warning, attribute-alias)
ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION
KBUILD_CFLAGS += $(call cc-option,-ffunction-sections,)
diff --git a/arch/arc/configs/axs101_defconfig b/arch/arc/configs/axs101_defconfig
index 0a0eaf0..5367fe3 100644
--- a/arch/arc/configs/axs101_defconfig
+++ b/arch/arc/configs/axs101_defconfig
@@ -11,7 +11,6 @@
# CONFIG_UTS_NS is not set
# CONFIG_PID_NS is not set
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE="../arc_initramfs/"
CONFIG_EMBEDDED=y
CONFIG_PERF_EVENTS=y
# CONFIG_VM_EVENT_COUNTERS is not set
diff --git a/arch/arc/configs/axs103_defconfig b/arch/arc/configs/axs103_defconfig
index 2233f57..d40fad4 100644
--- a/arch/arc/configs/axs103_defconfig
+++ b/arch/arc/configs/axs103_defconfig
@@ -11,7 +11,6 @@
# CONFIG_UTS_NS is not set
# CONFIG_PID_NS is not set
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE="../../arc_initramfs_hs/"
CONFIG_EMBEDDED=y
CONFIG_PERF_EVENTS=y
# CONFIG_VM_EVENT_COUNTERS is not set
diff --git a/arch/arc/configs/axs103_smp_defconfig b/arch/arc/configs/axs103_smp_defconfig
index 1108747..06cbd27 100644
--- a/arch/arc/configs/axs103_smp_defconfig
+++ b/arch/arc/configs/axs103_smp_defconfig
@@ -11,7 +11,6 @@
# CONFIG_UTS_NS is not set
# CONFIG_PID_NS is not set
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE="../../arc_initramfs_hs/"
CONFIG_EMBEDDED=y
CONFIG_PERF_EVENTS=y
# CONFIG_VM_EVENT_COUNTERS is not set
diff --git a/arch/arc/configs/nsim_700_defconfig b/arch/arc/configs/nsim_700_defconfig
index b0066a7..df609fc 100644
--- a/arch/arc/configs/nsim_700_defconfig
+++ b/arch/arc/configs/nsim_700_defconfig
@@ -11,7 +11,6 @@
# CONFIG_UTS_NS is not set
# CONFIG_PID_NS is not set
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE="../arc_initramfs/"
CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y
CONFIG_PERF_EVENTS=y
diff --git a/arch/arc/configs/nsim_hs_defconfig b/arch/arc/configs/nsim_hs_defconfig
index ebe9ebb..1dbb661 100644
--- a/arch/arc/configs/nsim_hs_defconfig
+++ b/arch/arc/configs/nsim_hs_defconfig
@@ -11,7 +11,6 @@
# CONFIG_UTS_NS is not set
# CONFIG_PID_NS is not set
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE="../../arc_initramfs_hs/"
CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y
CONFIG_PERF_EVENTS=y
diff --git a/arch/arc/configs/nsim_hs_smp_defconfig b/arch/arc/configs/nsim_hs_smp_defconfig
index 4bde432..cb36a69 100644
--- a/arch/arc/configs/nsim_hs_smp_defconfig
+++ b/arch/arc/configs/nsim_hs_smp_defconfig
@@ -9,7 +9,6 @@
# CONFIG_UTS_NS is not set
# CONFIG_PID_NS is not set
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE="../arc_initramfs_hs/"
CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y
CONFIG_PERF_EVENTS=y
diff --git a/arch/arc/configs/nsimosci_defconfig b/arch/arc/configs/nsimosci_defconfig
index f6fb3d26..5680daa6 100644
--- a/arch/arc/configs/nsimosci_defconfig
+++ b/arch/arc/configs/nsimosci_defconfig
@@ -11,7 +11,6 @@
# CONFIG_UTS_NS is not set
# CONFIG_PID_NS is not set
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE="../arc_initramfs/"
CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y
CONFIG_PERF_EVENTS=y
diff --git a/arch/arc/configs/nsimosci_hs_defconfig b/arch/arc/configs/nsimosci_hs_defconfig
index b9f0fe0..87decc4 100644
--- a/arch/arc/configs/nsimosci_hs_defconfig
+++ b/arch/arc/configs/nsimosci_hs_defconfig
@@ -11,7 +11,6 @@
# CONFIG_UTS_NS is not set
# CONFIG_PID_NS is not set
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE="../arc_initramfs_hs/"
CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y
CONFIG_PERF_EVENTS=y
diff --git a/arch/arc/configs/nsimosci_hs_smp_defconfig b/arch/arc/configs/nsimosci_hs_smp_defconfig
index 6da71ba..4d14684 100644
--- a/arch/arc/configs/nsimosci_hs_smp_defconfig
+++ b/arch/arc/configs/nsimosci_hs_smp_defconfig
@@ -9,7 +9,6 @@
# CONFIG_UTS_NS is not set
# CONFIG_PID_NS is not set
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE="../arc_initramfs_hs/"
CONFIG_PERF_EVENTS=y
# CONFIG_COMPAT_BRK is not set
CONFIG_KPROBES=y
diff --git a/arch/arc/include/asm/page.h b/arch/arc/include/asm/page.h
index 296c342..ffb5f33 100644
--- a/arch/arc/include/asm/page.h
+++ b/arch/arc/include/asm/page.h
@@ -105,7 +105,7 @@
#define virt_addr_valid(kaddr) pfn_valid(virt_to_pfn(kaddr))
/* Default Permissions for stack/heaps pages (Non Executable) */
-#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE)
+#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
#define WANT_PAGE_VIRTUAL 1
diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h
index e94ca72..c10f5cb 100644
--- a/arch/arc/include/asm/pgtable.h
+++ b/arch/arc/include/asm/pgtable.h
@@ -378,7 +378,7 @@
/* Decode a PTE containing swap "identifier "into constituents */
#define __swp_type(pte_lookalike) (((pte_lookalike).val) & 0x1f)
-#define __swp_offset(pte_lookalike) ((pte_lookalike).val << 13)
+#define __swp_offset(pte_lookalike) ((pte_lookalike).val >> 13)
/* NOPs, to keep generic kernel happy */
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 04b90d3..b7b2864 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1781,7 +1781,7 @@
choice
prompt "Virtual Memory Reclaim"
- default NO_VM_RECLAIM
+ default ENABLE_VMALLOC_SAVING
help
Select the method of reclaiming virtual memory
diff --git a/arch/arm/boot/dts/emev2.dtsi b/arch/arm/boot/dts/emev2.dtsi
index cd11940..fd6f9ce 100644
--- a/arch/arm/boot/dts/emev2.dtsi
+++ b/arch/arm/boot/dts/emev2.dtsi
@@ -30,13 +30,13 @@
#address-cells = <1>;
#size-cells = <0>;
- cpu@0 {
+ cpu0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <0>;
clock-frequency = <533000000>;
};
- cpu@1 {
+ cpu1: cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <1>;
@@ -56,6 +56,7 @@
compatible = "arm,cortex-a9-pmu";
interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-affinity = <&cpu0>, <&cpu1>;
};
clocks@e0110000 {
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-memory-256.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-memory-256.dtsi
index 0c21814..6dc8354 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-memory-256.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-memory-256.dtsi
@@ -15,5 +15,5 @@
};
&mss_mem {
- reg = <0x87000000 0x8300000>;
+ reg = <0x86c00000 0x8300000>;
};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-mtp.dts b/arch/arm/boot/dts/qcom/sdxpoorwills-mtp.dts
index a383f3e..de5922c 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-mtp.dts
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-mtp.dts
@@ -25,6 +25,14 @@
status = "okay";
};
+&qseecom_mem {
+ status = "okay";
+};
+
+&qseecom_ta_mem {
+ status = "okay";
+};
+
&blsp1_uart2b_hs {
status = "okay";
};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-thermal.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-thermal.dtsi
index 65467f9..0f2fe90 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-thermal.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-thermal.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -339,6 +339,35 @@
};
};
+ mdm-core-step {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-governor = "step_wise";
+ thermal-sensors = <&tsens0 4>;
+ trips {
+ mdm_step_trip0: mdm-step-trip-0 {
+ temperature = <95000>;
+ hysteresis = <5000>;
+ type = "passive";
+ };
+ mdm_step_trip1: mdm-step-trip-1 {
+ temperature = <105000>;
+ hysteresis = <5000>;
+ type = "passive";
+ };
+ };
+ cooling-maps {
+ modem_proc-lv11 {
+ trip = <&mdm_step_trip0>;
+ cooling-device = <&modem_proc 1 1>;
+ };
+ modem_proc_lvl3 {
+ trip = <&mdm_step_trip1>;
+ cooling-device = <&modem_proc 3 3>;
+ };
+ };
+ };
+
xo-therm-adc {
polling-delay-passive = <0>;
polling-delay = <0>;
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-usb.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-usb.dtsi
index a26aa71..8d3e8dc 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-usb.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-usb.dtsi
@@ -73,6 +73,7 @@
interrupts = <0 133 0>;
usb-phy = <&usb2_phy>, <&usb3_qmp_phy>;
tx-fifo-resize;
+ snps,usb3-u1u2-disable;
linux,sysdev_is_parent;
snps,bus-suspend-enable;
snps,disable-clk-gating;
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
index 37495a1..5aece95 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
@@ -65,7 +65,7 @@
mss_mem: mss_region@87400000 {
compatible = "removed-dma-pool";
no-map;
- reg = <0x87000000 0x8700000>;
+ reg = <0x86c00000 0x8b00000>;
label = "mss_mem";
};
@@ -85,14 +85,16 @@
compatible = "shared-dma-pool";
reusable;
alignment = <0x400000>;
- size = <0x1400000>;
+ size = <0x400000>;
+ status = "disabled";
};
qseecom_ta_mem: qseecom_ta_region@0 {
compatible = "shared-dma-pool";
reusable;
alignment = <0x400000>;
- size = <0x1000000>;
+ size = <0x400000>;
+ status = "disabled";
};
};
@@ -237,17 +239,17 @@
cpubw: qcom,cpubw {
compatible = "qcom,devbw";
- governor = "cpufreq";
+ governor = "performance";
qcom,src-dst-ports = <1 512>;
qcom,active-only;
qcom,bw-tbl =
- < MHZ_TO_MBPS(200, 2) >, /* 381 MB/s */
- < MHZ_TO_MBPS(470, 2) >, /* 896 MB/s */
- < MHZ_TO_MBPS(547, 2) >, /* 1043 MB/s */
- < MHZ_TO_MBPS(691, 2) >, /* 1317 MB/s */
- < MHZ_TO_MBPS(806, 2) >, /* 1537 MB/s */
- < MHZ_TO_MBPS(940, 2) >, /* 1792 MB/s */
- < MHZ_TO_MBPS(1383, 2) >; /* 2637 MB/s */
+ < MHZ_TO_MBPS(200, 4) >, /* 762 MB/s */
+ < MHZ_TO_MBPS(470, 4) >, /* 1792 MB/s */
+ < MHZ_TO_MBPS(547, 4) >, /* 2086 MB/s */
+ < MHZ_TO_MBPS(691, 4) >, /* 2634 MB/s */
+ < MHZ_TO_MBPS(806, 4) >, /* 3074 MB/s */
+ < MHZ_TO_MBPS(940, 4) >, /* 3584 MB/s */
+ < MHZ_TO_MBPS(1383, 4) >; /* 5274 MB/s */
};
devfreq_compute: qcom,devfreq-compute {
@@ -416,6 +418,8 @@
<45 512 0 0>,
<45 512 500 800>;
+ qcom,pcie-vendor-id = /bits/ 16 <0x17cb>;
+ qcom,pcie-device-id = /bits/ 16 <0x0304>;
qcom,pcie-link-speed = <2>;
qcom,pcie-phy-ver = <6>;
qcom,pcie-active-config;
@@ -908,10 +912,10 @@
dcc: dcc_v2@10a2000 {
compatible = "qcom,dcc-v2";
reg = <0x10a2000 0x1000>,
- <0x10ae000 0x2000>;
+ <0x10ae400 0x1c00>;
reg-names = "dcc-base", "dcc-ram-base";
- dcc-ram-offset = <0x6000>;
+ dcc-ram-offset = <0x400>;
};
system_pm {
diff --git a/arch/arm/boot/dts/sh73a0.dtsi b/arch/arm/boot/dts/sh73a0.dtsi
index 032fe2f..6b0cc22 100644
--- a/arch/arm/boot/dts/sh73a0.dtsi
+++ b/arch/arm/boot/dts/sh73a0.dtsi
@@ -22,7 +22,7 @@
#address-cells = <1>;
#size-cells = <0>;
- cpu@0 {
+ cpu0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <0>;
@@ -30,7 +30,7 @@
power-domains = <&pd_a2sl>;
next-level-cache = <&L2>;
};
- cpu@1 {
+ cpu1: cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <1>;
@@ -89,6 +89,7 @@
compatible = "arm,cortex-a9-pmu";
interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-affinity = <&cpu0>, <&cpu1>;
};
cmt1: timer@e6138000 {
diff --git a/arch/arm/configs/msm8909-perf_defconfig b/arch/arm/configs/msm8909-perf_defconfig
index 10031dd..cedb79b 100644
--- a/arch/arm/configs/msm8909-perf_defconfig
+++ b/arch/arm/configs/msm8909-perf_defconfig
@@ -25,6 +25,8 @@
CONFIG_SCHED_TUNE=y
CONFIG_DEFAULT_USE_ENERGY_AWARE=y
CONFIG_BLK_DEV_INITRD=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
# CONFIG_RD_XZ is not set
# CONFIG_RD_LZO is not set
# CONFIG_RD_LZ4 is not set
@@ -252,15 +254,21 @@
CONFIG_KEYBOARD_GPIO=y
CONFIG_INPUT_JOYSTICK=y
CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_GT9XX_v28=y
+CONFIG_TOUCHSCREEN_GT9XX_UPDATE=y
+CONFIG_TOUCHSCREEN_GT9XX_TOOL=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_QPNP_POWER_ON=y
CONFIG_STMVL53L0X=y
CONFIG_INPUT_UINPUT=y
+# CONFIG_VT is not set
+# CONFIG_LEGACY_PTYS is not set
CONFIG_SERIAL_MSM_HS=y
CONFIG_SERIAL_MSM_SMD=y
CONFIG_DIAG_CHAR=y
CONFIG_DIAG_USES_SMD=y
CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_MSM_LEGACY=y
CONFIG_MSM_SMD_PKT=y
CONFIG_MSM_ADSPRPC=y
CONFIG_I2C_CHARDEV=y
@@ -277,6 +285,8 @@
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_QCOM=y
CONFIG_QCOM_DLOAD_MODE=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_POWER_RESET_SYSCON_POWEROFF=y
CONFIG_POWER_SUPPLY=y
CONFIG_SMB1360_CHARGER_FG=y
CONFIG_QPNP_VM_BMS=y
@@ -296,7 +306,6 @@
CONFIG_REGULATOR_COOLING_DEVICE=y
CONFIG_MFD_QCOM_RPM=y
CONFIG_MFD_SPMI_PMIC=y
-CONFIG_MFD_SYSCON=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_PROXY_CONSUMER=y
@@ -333,19 +342,14 @@
CONFIG_SND_SOC=y
CONFIG_UHID=y
CONFIG_HID_A4TECH=y
-CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
CONFIG_HID_CHERRY=y
CONFIG_HID_CHICONY=y
CONFIG_HID_CYPRESS=y
-CONFIG_HID_ELECOM=y
CONFIG_HID_EZKEY=y
CONFIG_HID_KENSINGTON=y
CONFIG_HID_LOGITECH=y
-CONFIG_HID_MAGICMOUSE=y
-CONFIG_HID_MICROSOFT=y
CONFIG_HID_MONTEREY=y
-CONFIG_HID_MULTITOUCH=y
CONFIG_USB=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
CONFIG_USB_MON=y
@@ -452,13 +456,15 @@
CONFIG_PRINTK_TIME=y
CONFIG_DEBUG_INFO=y
CONFIG_FRAME_WARN=2048
+CONFIG_DEBUG_FS=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_WQ_WATCHDOG=y
CONFIG_PANIC_TIMEOUT=5
CONFIG_PANIC_ON_SCHED_BUG=y
CONFIG_PANIC_ON_RT_THROTTLING=y
# CONFIG_DEBUG_PREEMPT is not set
-CONFIG_FUNCTION_TRACER=y
+CONFIG_STACKTRACE=y
+# CONFIG_FTRACE is not set
CONFIG_DEBUG_SET_MODULE_RONX=y
CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y
CONFIG_SECURITY=y
diff --git a/arch/arm/configs/msm8909_defconfig b/arch/arm/configs/msm8909_defconfig
index 17640c9..bed9c9d 100644
--- a/arch/arm/configs/msm8909_defconfig
+++ b/arch/arm/configs/msm8909_defconfig
@@ -271,6 +271,9 @@
CONFIG_INPUT_JOYSTICK=y
CONFIG_JOYSTICK_XPAD=y
CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_GT9XX_v28=y
+CONFIG_TOUCHSCREEN_GT9XX_UPDATE=y
+CONFIG_TOUCHSCREEN_GT9XX_TOOL=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_QPNP_POWER_ON=y
CONFIG_STMVL53L0X=y
@@ -304,6 +307,8 @@
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_QCOM=y
CONFIG_QCOM_DLOAD_MODE=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_POWER_RESET_SYSCON_POWEROFF=y
CONFIG_POWER_SUPPLY=y
CONFIG_SMB1360_CHARGER_FG=y
CONFIG_QPNP_VM_BMS=y
@@ -324,7 +329,6 @@
CONFIG_REGULATOR_COOLING_DEVICE=y
CONFIG_MFD_QCOM_RPM=y
CONFIG_MFD_SPMI_PMIC=y
-CONFIG_MFD_SYSCON=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_PROXY_CONSUMER=y
diff --git a/arch/arm/configs/msm8909w-perf_defconfig b/arch/arm/configs/msm8909w-perf_defconfig
index 6ef7915..27878b6 100644
--- a/arch/arm/configs/msm8909w-perf_defconfig
+++ b/arch/arm/configs/msm8909w-perf_defconfig
@@ -241,6 +241,7 @@
CONFIG_DM_ANDROID_VERITY_AT_MOST_ONCE_DEFAULT_ENABLED=y
CONFIG_NETDEVICES=y
CONFIG_DUMMY=y
+CONFIG_IFB=y
CONFIG_TUN=y
CONFIG_PPP=y
CONFIG_PPP_BSDCOMP=y
diff --git a/arch/arm/configs/msm8909w_defconfig b/arch/arm/configs/msm8909w_defconfig
index 986a65c..eab8410d 100644
--- a/arch/arm/configs/msm8909w_defconfig
+++ b/arch/arm/configs/msm8909w_defconfig
@@ -230,6 +230,7 @@
CONFIG_DM_ANDROID_VERITY_AT_MOST_ONCE_DEFAULT_ENABLED=y
CONFIG_NETDEVICES=y
CONFIG_DUMMY=y
+CONFIG_IFB=y
CONFIG_TUN=y
CONFIG_PPP=y
CONFIG_PPP_BSDCOMP=y
diff --git a/arch/arm/configs/msm8937-perf_defconfig b/arch/arm/configs/msm8937-perf_defconfig
index f1f9cf0..e6e0b2a 100644
--- a/arch/arm/configs/msm8937-perf_defconfig
+++ b/arch/arm/configs/msm8937-perf_defconfig
@@ -58,6 +58,7 @@
CONFIG_ARCH_QCOM=y
CONFIG_ARCH_MSM8937=y
CONFIG_ARCH_MSM8917=y
+CONFIG_ARCH_QM215=y
CONFIG_ARCH_SDM439=y
CONFIG_ARCH_SDM429=y
# CONFIG_VDSO is not set
@@ -264,6 +265,7 @@
CONFIG_BLK_DEV_DM=y
CONFIG_DM_CRYPT=y
CONFIG_DM_REQ_CRYPT=y
+CONFIG_DM_DEFAULT_KEY=y
CONFIG_DM_UEVENT=y
CONFIG_DM_VERITY=y
CONFIG_DM_VERITY_FEC=y
@@ -355,10 +357,13 @@
CONFIG_POWER_SUPPLY=y
CONFIG_QPNP_FG=y
CONFIG_SMB135X_CHARGER=y
+CONFIG_SMB1360_CHARGER_FG=y
CONFIG_SMB1355_SLAVE_CHARGER=y
CONFIG_SMB1351_USB_CHARGER=y
CONFIG_QPNP_SMB5=y
CONFIG_QPNP_SMBCHARGER=y
+CONFIG_QPNP_VM_BMS=y
+CONFIG_QPNP_LINEAR_CHARGER=y
CONFIG_QPNP_TYPEC=y
CONFIG_QPNP_QG=y
CONFIG_MSM_APM=y
@@ -514,6 +519,7 @@
CONFIG_LEDS_QPNP_WLED=y
CONFIG_LEDS_QPNP_HAPTICS=y
CONFIG_LEDS_QPNP_VIBRATOR_LDO=y
+CONFIG_LEDS_QPNP_VIBRATOR=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_EDAC=y
diff --git a/arch/arm/configs/msm8937_defconfig b/arch/arm/configs/msm8937_defconfig
index 4a85408..93d4d35 100644
--- a/arch/arm/configs/msm8937_defconfig
+++ b/arch/arm/configs/msm8937_defconfig
@@ -60,6 +60,7 @@
CONFIG_ARCH_QCOM=y
CONFIG_ARCH_MSM8937=y
CONFIG_ARCH_MSM8917=y
+CONFIG_ARCH_QM215=y
CONFIG_ARCH_SDM439=y
CONFIG_ARCH_SDM429=y
# CONFIG_VDSO is not set
@@ -268,6 +269,7 @@
CONFIG_BLK_DEV_DM=y
CONFIG_DM_CRYPT=y
CONFIG_DM_REQ_CRYPT=y
+CONFIG_DM_DEFAULT_KEY=y
CONFIG_DM_UEVENT=y
CONFIG_DM_VERITY=y
CONFIG_DM_VERITY_FEC=y
@@ -361,10 +363,13 @@
CONFIG_POWER_SUPPLY=y
CONFIG_QPNP_FG=y
CONFIG_SMB135X_CHARGER=y
+CONFIG_SMB1360_CHARGER_FG=y
CONFIG_SMB1355_SLAVE_CHARGER=y
CONFIG_SMB1351_USB_CHARGER=y
CONFIG_QPNP_SMB5=y
CONFIG_QPNP_SMBCHARGER=y
+CONFIG_QPNP_VM_BMS=y
+CONFIG_QPNP_LINEAR_CHARGER=y
CONFIG_QPNP_TYPEC=y
CONFIG_QPNP_QG=y
CONFIG_MSM_APM=y
@@ -524,6 +529,7 @@
CONFIG_LEDS_QPNP_WLED=y
CONFIG_LEDS_QPNP_HAPTICS=y
CONFIG_LEDS_QPNP_VIBRATOR_LDO=y
+CONFIG_LEDS_QPNP_VIBRATOR=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_EDAC=y
diff --git a/arch/arm/configs/msm8937go-perf_defconfig b/arch/arm/configs/msm8937go-perf_defconfig
index ed23f82..3a38886 100644
--- a/arch/arm/configs/msm8937go-perf_defconfig
+++ b/arch/arm/configs/msm8937go-perf_defconfig
@@ -38,6 +38,7 @@
# CONFIG_RD_LZO is not set
# CONFIG_RD_LZ4 is not set
CONFIG_KALLSYMS_ALL=y
+# CONFIG_BASE_FULL is not set
CONFIG_BPF_SYSCALL=y
# CONFIG_MEMBARRIER is not set
CONFIG_EMBEDDED=y
@@ -58,6 +59,7 @@
CONFIG_ARCH_QCOM=y
CONFIG_ARCH_MSM8937=y
CONFIG_ARCH_MSM8917=y
+CONFIG_ARCH_QM215=y
CONFIG_ARCH_SDM439=y
CONFIG_ARCH_SDM429=y
# CONFIG_VDSO is not set
@@ -356,10 +358,15 @@
CONFIG_POWER_SUPPLY=y
CONFIG_QPNP_FG=y
CONFIG_SMB135X_CHARGER=y
+CONFIG_SMB1360_CHARGER_FG=y
CONFIG_SMB1355_SLAVE_CHARGER=y
CONFIG_SMB1351_USB_CHARGER=y
+CONFIG_QPNP_SMB5=y
CONFIG_QPNP_SMBCHARGER=y
+CONFIG_QPNP_VM_BMS=y
+CONFIG_QPNP_LINEAR_CHARGER=y
CONFIG_QPNP_TYPEC=y
+CONFIG_QPNP_QG=y
CONFIG_MSM_APM=y
CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
CONFIG_THERMAL=y
@@ -385,6 +392,7 @@
CONFIG_REGULATOR_CPR=y
CONFIG_REGULATOR_MEM_ACC=y
CONFIG_REGULATOR_QPNP_LABIBB=y
+CONFIG_REGULATOR_QPNP_LCDB=y
CONFIG_REGULATOR_QPNP=y
CONFIG_REGULATOR_RPM_SMD=y
CONFIG_REGULATOR_SPM=y
@@ -467,6 +475,7 @@
CONFIG_USB_STORAGE_CYPRESS_ATACB=y
CONFIG_USB_SERIAL=y
CONFIG_USB_EHSET_TEST_FIXTURE=y
+CONFIG_NOP_USB_XCEIV=y
CONFIG_DUAL_ROLE_USB_INTF=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_DEBUG_FILES=y
@@ -504,11 +513,16 @@
CONFIG_MMC_SDHCI_MSM=y
CONFIG_MMC_SDHCI_MSM_ICE=y
CONFIG_MMC_CQ_HCI=y
+CONFIG_LEDS_QTI_TRI_LED=y
CONFIG_LEDS_QPNP=y
CONFIG_LEDS_QPNP_FLASH=y
+CONFIG_LEDS_QPNP_FLASH_V2=y
CONFIG_LEDS_QPNP_WLED=y
CONFIG_LEDS_QPNP_HAPTICS=y
+CONFIG_LEDS_QPNP_VIBRATOR_LDO=y
+CONFIG_LEDS_QPNP_VIBRATOR=y
CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_EDAC=y
CONFIG_EDAC_MM_EDAC=y
CONFIG_RTC_CLASS=y
@@ -580,6 +594,7 @@
CONFIG_IIO=y
CONFIG_PWM=y
CONFIG_PWM_QPNP=y
+CONFIG_PWM_QTI_LPG=y
CONFIG_QCOM_SHOW_RESUME_IRQ=y
CONFIG_QTI_MPM=y
CONFIG_ANDROID=y
@@ -602,6 +617,9 @@
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
CONFIG_SDCARD_FS=y
+CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_XATTR=y
+CONFIG_SQUASHFS_LZ4=y
# CONFIG_NETWORK_FILESYSTEMS is not set
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
@@ -614,6 +632,7 @@
# CONFIG_DEBUG_PREEMPT is not set
CONFIG_IPC_LOGGING=y
CONFIG_CPU_FREQ_SWITCH_PROFILER=y
+CONFIG_DEBUG_SET_MODULE_RONX=y
CONFIG_PFK=y
CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y
CONFIG_SECURITY=y
diff --git a/arch/arm/configs/msm8937go_defconfig b/arch/arm/configs/msm8937go_defconfig
index 458f478..0f7c823 100644
--- a/arch/arm/configs/msm8937go_defconfig
+++ b/arch/arm/configs/msm8937go_defconfig
@@ -39,6 +39,7 @@
# CONFIG_RD_LZO is not set
# CONFIG_RD_LZ4 is not set
CONFIG_KALLSYMS_ALL=y
+# CONFIG_BASE_FULL is not set
CONFIG_BPF_SYSCALL=y
# CONFIG_MEMBARRIER is not set
CONFIG_EMBEDDED=y
@@ -60,6 +61,7 @@
CONFIG_ARCH_QCOM=y
CONFIG_ARCH_MSM8937=y
CONFIG_ARCH_MSM8917=y
+CONFIG_ARCH_QM215=y
CONFIG_ARCH_SDM439=y
CONFIG_ARCH_SDM429=y
# CONFIG_VDSO is not set
@@ -362,10 +364,15 @@
CONFIG_POWER_SUPPLY=y
CONFIG_QPNP_FG=y
CONFIG_SMB135X_CHARGER=y
+CONFIG_SMB1360_CHARGER_FG=y
CONFIG_SMB1355_SLAVE_CHARGER=y
CONFIG_SMB1351_USB_CHARGER=y
+CONFIG_QPNP_SMB5=y
CONFIG_QPNP_SMBCHARGER=y
+CONFIG_QPNP_VM_BMS=y
+CONFIG_QPNP_LINEAR_CHARGER=y
CONFIG_QPNP_TYPEC=y
+CONFIG_QPNP_QG=y
CONFIG_MSM_APM=y
CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
CONFIG_THERMAL=y
@@ -391,6 +398,7 @@
CONFIG_REGULATOR_CPR=y
CONFIG_REGULATOR_MEM_ACC=y
CONFIG_REGULATOR_QPNP_LABIBB=y
+CONFIG_REGULATOR_QPNP_LCDB=y
CONFIG_REGULATOR_QPNP=y
CONFIG_REGULATOR_RPM_SMD=y
CONFIG_REGULATOR_SPM=y
@@ -474,6 +482,7 @@
CONFIG_USB_STORAGE_CYPRESS_ATACB=y
CONFIG_USB_SERIAL=y
CONFIG_USB_EHSET_TEST_FIXTURE=y
+CONFIG_NOP_USB_XCEIV=y
CONFIG_DUAL_ROLE_USB_INTF=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_DEBUG_FILES=y
@@ -512,11 +521,16 @@
CONFIG_MMC_SDHCI_MSM=y
CONFIG_MMC_SDHCI_MSM_ICE=y
CONFIG_MMC_CQ_HCI=y
+CONFIG_LEDS_QTI_TRI_LED=y
CONFIG_LEDS_QPNP=y
CONFIG_LEDS_QPNP_FLASH=y
+CONFIG_LEDS_QPNP_FLASH_V2=y
CONFIG_LEDS_QPNP_WLED=y
CONFIG_LEDS_QPNP_HAPTICS=y
+CONFIG_LEDS_QPNP_VIBRATOR_LDO=y
+CONFIG_LEDS_QPNP_VIBRATOR=y
CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_EDAC=y
CONFIG_EDAC_MM_EDAC=y
CONFIG_RTC_CLASS=y
@@ -596,6 +610,7 @@
CONFIG_IIO=y
CONFIG_PWM=y
CONFIG_PWM_QPNP=y
+CONFIG_PWM_QTI_LPG=y
CONFIG_QCOM_SHOW_RESUME_IRQ=y
CONFIG_QTI_MPM=y
CONFIG_ANDROID=y
@@ -619,6 +634,9 @@
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
CONFIG_SDCARD_FS=y
+CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_XATTR=y
+CONFIG_SQUASHFS_LZ4=y
# CONFIG_NETWORK_FILESYSTEMS is not set
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
diff --git a/arch/arm/configs/sdm670-perf_defconfig b/arch/arm/configs/sdm670-perf_defconfig
index d5bbdcc..5244452 100644
--- a/arch/arm/configs/sdm670-perf_defconfig
+++ b/arch/arm/configs/sdm670-perf_defconfig
@@ -277,6 +277,7 @@
CONFIG_PPPOPNS=y
CONFIG_PPP_ASYNC=y
CONFIG_PPP_SYNC_TTY=y
+CONFIG_USB_LAN78XX=y
CONFIG_USB_USBNET=y
CONFIG_WCNSS_MEM_PRE_ALLOC=y
CONFIG_CLD_LL_CORE=y
@@ -504,7 +505,10 @@
CONFIG_QMP_DEBUGFS_CLIENT=y
CONFIG_MSM_REMOTEQDSS=y
CONFIG_QCOM_BIMC_BWMON=y
+CONFIG_ARM_MEMLAT_MON=y
+CONFIG_DEVFREQ_GOV_QCOM_BW_HWMON=y
CONFIG_DEVFREQ_GOV_QCOM_CACHE_HWMON=y
+CONFIG_DEVFREQ_GOV_MEMLAT=y
CONFIG_QCOM_DEVFREQ_DEVBW=y
CONFIG_EXTCON_USB_GPIO=y
CONFIG_IIO=y
diff --git a/arch/arm/configs/sdm670_defconfig b/arch/arm/configs/sdm670_defconfig
index baac195..bffed7c 100644
--- a/arch/arm/configs/sdm670_defconfig
+++ b/arch/arm/configs/sdm670_defconfig
@@ -284,6 +284,7 @@
CONFIG_PPPOPNS=y
CONFIG_PPP_ASYNC=y
CONFIG_PPP_SYNC_TTY=y
+CONFIG_USB_LAN78XX=y
CONFIG_USB_USBNET=y
CONFIG_WCNSS_MEM_PRE_ALLOC=y
CONFIG_CLD_LL_CORE=y
@@ -526,7 +527,10 @@
CONFIG_QMP_DEBUGFS_CLIENT=y
CONFIG_MSM_REMOTEQDSS=y
CONFIG_QCOM_BIMC_BWMON=y
+CONFIG_ARM_MEMLAT_MON=y
+CONFIG_DEVFREQ_GOV_QCOM_BW_HWMON=y
CONFIG_DEVFREQ_GOV_QCOM_CACHE_HWMON=y
+CONFIG_DEVFREQ_GOV_MEMLAT=y
CONFIG_QCOM_DEVFREQ_DEVBW=y
CONFIG_EXTCON_USB_GPIO=y
CONFIG_IIO=y
diff --git a/arch/arm/configs/sdxpoorwills-auto-perf_defconfig b/arch/arm/configs/sdxpoorwills-auto-perf_defconfig
new file mode 100644
index 0000000..e1fed15
--- /dev/null
+++ b/arch/arm/configs/sdxpoorwills-auto-perf_defconfig
@@ -0,0 +1,441 @@
+CONFIG_AUDIT=y
+# CONFIG_AUDITSYSCALL is not set
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_DEBUG=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_SCHED=y
+# CONFIG_FAIR_GROUP_SCHED is not set
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_EMBEDDED=y
+# CONFIG_SLUB_DEBUG is not set
+CONFIG_PROFILING=y
+CONFIG_CC_STACKPROTECTOR_REGULAR=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ARCH_QCOM=y
+CONFIG_ARCH_SDXPOORWILLS=y
+CONFIG_PCI_MSM=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_CMA=y
+CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
+CONFIG_CPU_BOOST=y
+CONFIG_CPU_FREQ_MSM=y
+CONFIG_CPU_IDLE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_PM_AUTOSLEEP=y
+CONFIG_PM_WAKELOCKS=y
+CONFIG_PM_WAKELOCKS_LIMIT=0
+# CONFIG_PM_WAKELOCKS_GC is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_NET_IPGRE_DEMUX=y
+CONFIG_NET_IPGRE=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_GRE=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_IPV6_MROUTE=y
+CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y
+CONFIG_IPV6_PIMSM_V2=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_DEBUG=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CONNTRACK_TIMEOUT=y
+CONFIG_NF_CONNTRACK_TIMESTAMP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
+CONFIG_NF_CONNTRACK_AMANDA=y
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_H323=y
+CONFIG_NF_CONNTRACK_IRC=y
+CONFIG_NF_CONNTRACK_NETBIOS_NS=y
+CONFIG_NF_CONNTRACK_SNMP=y
+CONFIG_NF_CONNTRACK_PPTP=y
+CONFIG_NF_CONNTRACK_SIP=y
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NF_CT_NETLINK=y
+CONFIG_NF_CT_NETLINK_TIMEOUT=y
+CONFIG_NF_CT_NETLINK_HELPER=y
+CONFIG_NETFILTER_NETLINK_GLUE_CT=y
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
+CONFIG_NETFILTER_XT_TARGET_LOG=y
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+CONFIG_NETFILTER_XT_TARGET_NFLOG=y
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=y
+CONFIG_NETFILTER_XT_TARGET_TPROXY=y
+CONFIG_NETFILTER_XT_TARGET_TRACE=y
+CONFIG_NETFILTER_XT_TARGET_SECMARK=y
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y
+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=y
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_DSCP=y
+CONFIG_NETFILTER_XT_MATCH_ESP=y
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_IP_SET=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_AH=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_IP_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_NATTYPE_MODULE=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_TARGET_ECN=y
+CONFIG_IP_NF_TARGET_TTL=y
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_SECURITY=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_NF_CONNTRACK_IPV6=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_MATCH_AH=y
+CONFIG_IP6_NF_MATCH_FRAG=y
+CONFIG_IP6_NF_MATCH_OPTS=y
+CONFIG_IP6_NF_MATCH_HL=y
+CONFIG_IP6_NF_MATCH_IPV6HEADER=y
+CONFIG_IP6_NF_MATCH_MH=y
+CONFIG_IP6_NF_MATCH_RT=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+CONFIG_BRIDGE_NF_EBTABLES=y
+CONFIG_BRIDGE_EBT_BROUTE=y
+CONFIG_BRIDGE_EBT_T_FILTER=y
+CONFIG_BRIDGE_EBT_T_NAT=y
+CONFIG_BRIDGE_EBT_ARP=y
+CONFIG_BRIDGE_EBT_IP=y
+CONFIG_BRIDGE_EBT_IP6=y
+CONFIG_BRIDGE_EBT_ARPREPLY=y
+CONFIG_BRIDGE_EBT_DNAT=y
+CONFIG_BRIDGE_EBT_SNAT=y
+CONFIG_BRIDGE=y
+CONFIG_VLAN_8021Q=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_PRIO=y
+CONFIG_RMNET_DATA=y
+CONFIG_RMNET_DATA_FC=y
+CONFIG_RMNET_DATA_DEBUG_PKT=y
+CONFIG_BT=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_H4=y
+CONFIG_MSM_BT_POWER=y
+CONFIG_CFG80211=y
+CONFIG_CFG80211_DEBUGFS=y
+CONFIG_CFG80211_INTERNAL_REGDB=y
+CONFIG_CFG80211_WEXT=y
+CONFIG_RFKILL=y
+CONFIG_IPC_ROUTER=y
+CONFIG_IPC_ROUTER_SECURITY=y
+CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=12
+CONFIG_MTD=y
+CONFIG_MTD_TESTS=m
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_MSM_QPIC_NAND=y
+CONFIG_MTD_UBI=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_QSEECOM=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_NETDEVICES=y
+CONFIG_TUN=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+CONFIG_KS8851=y
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+CONFIG_AT803X_PHY=y
+CONFIG_PPP=y
+CONFIG_PPP_ASYNC=y
+CONFIG_USB_USBNET=y
+CONFIG_USB_NET_SMSC75XX=y
+CONFIG_USB_NET_SMSC95XX=y
+CONFIG_WCNSS_MEM_PRE_ALLOC=y
+CONFIG_CNSS=y
+CONFIG_CNSS_SDIO=y
+CONFIG_CNSS_PCI=y
+CONFIG_CLD_HL_SDIO_CORE=y
+CONFIG_CLD_LL_CORE=y
+CONFIG_CNSS_LOGGER=y
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_QPNP_POWER_ON=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_INPUT_GPIO=m
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_MSM=y
+CONFIG_SERIAL_MSM_HS=y
+CONFIG_DIAG_CHAR=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_MSM_LEGACY=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MSM_V2=y
+CONFIG_SPI=y
+CONFIG_SPI_QUP=y
+CONFIG_SPI_SPIDEV=m
+CONFIG_SPMI=y
+CONFIG_SPMI_MSM_PMIC_ARB_DEBUG=y
+CONFIG_PTP_1588_CLOCK=y
+CONFIG_PINCTRL_SDXPOORWILLS=y
+CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_QCOM=y
+CONFIG_QCOM_DLOAD_MODE=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_SMB1351_USB_CHARGER=y
+CONFIG_SMB138X_CHARGER=y
+CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
+CONFIG_THERMAL=y
+CONFIG_THERMAL_WRITABLE_TRIPS=y
+CONFIG_THERMAL_GOV_USER_SPACE=y
+CONFIG_THERMAL_GOV_LOW_LIMITS=y
+CONFIG_CPU_THERMAL=y
+CONFIG_THERMAL_QPNP=y
+CONFIG_THERMAL_TSENS=y
+CONFIG_QTI_AOP_REG_COOLING_DEVICE=y
+CONFIG_QTI_QMI_COOLING_DEVICE=y
+CONFIG_REGULATOR_COOLING_DEVICE=y
+CONFIG_MFD_I2C_PMIC=y
+CONFIG_MFD_SPMI_PMIC=y
+CONFIG_MFD_SYSCON=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_QPNP=y
+CONFIG_REGULATOR_RPMH=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_DYNAMIC_MINORS=y
+CONFIG_SND_USB_AUDIO=y
+CONFIG_SND_USB_AUDIO_QMI=y
+CONFIG_SND_SOC=y
+CONFIG_UHID=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_ELECOM=y
+CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MULTITOUCH=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_ACM=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_DEBUG=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_STORAGE_ONETOUCH=y
+CONFIG_USB_STORAGE_KARMA=y
+CONFIG_USB_STORAGE_CYPRESS_ATACB=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC3_MSM=y
+CONFIG_USB_EHSET_TEST_FIXTURE=y
+CONFIG_USB_LINK_LAYER_TEST=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_USB_MSM_SSPHY_QMP=y
+CONFIG_MSM_HSUSB_PHY=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DEBUG_FILES=y
+CONFIG_USB_GADGET_VBUS_DRAW=500
+CONFIG_USB_CONFIGFS=y
+CONFIG_USB_CONFIGFS_SERIAL=y
+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
+CONFIG_USB_CONFIGFS_F_FS=y
+CONFIG_USB_CONFIGFS_UEVENT=y
+CONFIG_USB_CONFIGFS_F_UAC1=y
+CONFIG_USB_CONFIGFS_F_DIAG=y
+CONFIG_USB_CONFIGFS_F_CDEV=y
+CONFIG_USB_CONFIGFS_F_GSI=y
+CONFIG_USB_CONFIGFS_F_QDSS=y
+CONFIG_MMC=y
+CONFIG_MMC_PERF_PROFILING=y
+CONFIG_MMC_PARANOID_SD_INIT=y
+CONFIG_MMC_CLKGATE=y
+CONFIG_MMC_BLOCK_MINORS=32
+CONFIG_MMC_BLOCK_DEFERRED_RESUME=y
+CONFIG_MMC_TEST=m
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_MSM=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_QPNP=y
+CONFIG_DMADEVICES=y
+CONFIG_QCOM_SPS_DMA=y
+CONFIG_UIO=y
+CONFIG_STAGING=y
+CONFIG_ION=y
+CONFIG_ION_MSM=y
+CONFIG_GSI=y
+CONFIG_IPA3=y
+CONFIG_IPA_WDI_UNIFIED_API=y
+CONFIG_RMNET_IPA3=y
+CONFIG_ECM_IPA=y
+CONFIG_RNDIS_IPA=y
+CONFIG_IPA_UT=y
+CONFIG_SPS=y
+CONFIG_SPS_SUPPORT_NDP_BAM=y
+CONFIG_EP_PCIE=y
+CONFIG_EP_PCIE_HW=y
+CONFIG_QPNP_REVID=y
+CONFIG_MSM_MHI_DEV=y
+CONFIG_USB_BAM=y
+CONFIG_MSM_CLK_RPMH=y
+CONFIG_MSM_CLK_AOP_QMP=y
+CONFIG_MDM_GCC_SDXPOORWILLS=y
+CONFIG_MDM_CLOCK_CPU_SDXPOORWILLS=y
+CONFIG_MDM_DEBUGCC_SDXPOORWILLS=y
+CONFIG_REMOTE_SPINLOCK_MSM=y
+CONFIG_MSM_QMP=y
+CONFIG_IOMMU_IO_PGTABLE_FAST=y
+CONFIG_ARM_SMMU=y
+CONFIG_QCOM_LAZY_MAPPING=y
+CONFIG_IOMMU_DEBUG=y
+CONFIG_IOMMU_DEBUG_TRACKING=y
+CONFIG_IOMMU_TESTS=y
+CONFIG_QCOM_SCM=y
+CONFIG_MSM_BOOT_STATS=y
+CONFIG_QCOM_WATCHDOG_V2=y
+CONFIG_QCOM_MEMORY_DUMP_V2=y
+CONFIG_QCOM_BUS_SCALING=y
+CONFIG_QCOM_BUS_CONFIG_RPMH=y
+CONFIG_MSM_SMEM=y
+CONFIG_MSM_GLINK=y
+CONFIG_MSM_GLINK_LOOPBACK_SERVER=y
+CONFIG_MSM_GLINK_SMEM_NATIVE_XPRT=y
+CONFIG_TRACER_PKT=y
+CONFIG_QTI_RPMH_API=y
+CONFIG_MSM_SMP2P=y
+CONFIG_MSM_IPC_ROUTER_GLINK_XPRT=y
+CONFIG_MSM_QMI_INTERFACE=y
+CONFIG_MSM_GLINK_PKT=y
+CONFIG_MSM_SUBSYSTEM_RESTART=y
+CONFIG_MSM_PIL=y
+CONFIG_MSM_PIL_SSR_GENERIC=y
+CONFIG_QCOM_COMMAND_DB=y
+CONFIG_MSM_PM=y
+CONFIG_QCOM_DCC_V2=y
+CONFIG_QTI_RPM_STATS_LOG=y
+CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
+CONFIG_QMP_DEBUGFS_CLIENT=y
+CONFIG_ARM_MEMLAT_MON=y
+CONFIG_DEVFREQ_GOV_MEMLAT=y
+CONFIG_QCOM_DEVFREQ_DEVBW=y
+CONFIG_EXTCON_QCOM_SPMI_MISC=y
+CONFIG_IIO=y
+CONFIG_PWM=y
+CONFIG_PWM_QPNP=y
+CONFIG_QCOM_SHOW_RESUME_IRQ=y
+CONFIG_ANDROID=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_PANIC_ON_RECURSIVE_FAULT=y
+CONFIG_PANIC_TIMEOUT=5
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_SCHEDSTATS=y
+CONFIG_SCHED_STACK_END_CHECK=y
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_IPC_LOGGING=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_DEBUG_SET_MODULE_RONX=y
+CONFIG_CORESIGHT=y
+CONFIG_CORESIGHT_REMOTE_ETM=y
+CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0
+CONFIG_CORESIGHT_STM=y
+CONFIG_CORESIGHT_TPDA=y
+CONFIG_CORESIGHT_TPDM=y
+CONFIG_CORESIGHT_CTI=y
+CONFIG_CORESIGHT_EVENT=y
+CONFIG_CORESIGHT_HWEVENT=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_HARDENED_USERCOPY=y
+CONFIG_SECURITY_SELINUX=y
+# CONFIG_SECURITY_SELINUX_AVC_STATS is not set
+CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y
+CONFIG_CRYPTO_DEV_QCRYPTO=y
+CONFIG_CRYPTO_DEV_QCEDEV=y
+CONFIG_QMI_ENCDEC=y
diff --git a/arch/arm/configs/sdxpoorwills-auto_defconfig b/arch/arm/configs/sdxpoorwills-auto_defconfig
new file mode 100644
index 0000000..54072cc
--- /dev/null
+++ b/arch/arm/configs/sdxpoorwills-auto_defconfig
@@ -0,0 +1,468 @@
+CONFIG_AUDIT=y
+# CONFIG_AUDITSYSCALL is not set
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_DEBUG=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_SCHED=y
+# CONFIG_FAIR_GROUP_SCHED is not set
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZ4 is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_EMBEDDED=y
+CONFIG_PROFILING=y
+CONFIG_CC_STACKPROTECTOR_REGULAR=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ARCH_QCOM=y
+CONFIG_ARCH_SDXPOORWILLS=y
+# CONFIG_VDSO is not set
+CONFIG_PCI_MSM=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_CMA=y
+CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
+CONFIG_CPU_BOOST=y
+CONFIG_CPU_FREQ_MSM=y
+CONFIG_CPU_IDLE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_PM_AUTOSLEEP=y
+CONFIG_PM_WAKELOCKS=y
+CONFIG_PM_WAKELOCKS_LIMIT=0
+# CONFIG_PM_WAKELOCKS_GC is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_NET_IPGRE_DEMUX=y
+CONFIG_NET_IPGRE=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_GRE=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_IPV6_MROUTE=y
+CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y
+CONFIG_IPV6_PIMSM_V2=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_DEBUG=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CONNTRACK_TIMEOUT=y
+CONFIG_NF_CONNTRACK_TIMESTAMP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
+CONFIG_NF_CONNTRACK_AMANDA=y
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_H323=y
+CONFIG_NF_CONNTRACK_IRC=y
+CONFIG_NF_CONNTRACK_NETBIOS_NS=y
+CONFIG_NF_CONNTRACK_SNMP=y
+CONFIG_NF_CONNTRACK_PPTP=y
+CONFIG_NF_CONNTRACK_SIP=y
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NF_CT_NETLINK=y
+CONFIG_NF_CT_NETLINK_TIMEOUT=y
+CONFIG_NF_CT_NETLINK_HELPER=y
+CONFIG_NETFILTER_NETLINK_GLUE_CT=y
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
+CONFIG_NETFILTER_XT_TARGET_LOG=y
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+CONFIG_NETFILTER_XT_TARGET_NFLOG=y
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=y
+CONFIG_NETFILTER_XT_TARGET_TPROXY=y
+CONFIG_NETFILTER_XT_TARGET_TRACE=y
+CONFIG_NETFILTER_XT_TARGET_SECMARK=y
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y
+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=y
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_DSCP=y
+CONFIG_NETFILTER_XT_MATCH_ESP=y
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_IP_SET=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_AH=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_IP_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_NATTYPE_MODULE=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_TARGET_ECN=y
+CONFIG_IP_NF_TARGET_TTL=y
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_SECURITY=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_NF_CONNTRACK_IPV6=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_MATCH_AH=y
+CONFIG_IP6_NF_MATCH_FRAG=y
+CONFIG_IP6_NF_MATCH_OPTS=y
+CONFIG_IP6_NF_MATCH_HL=y
+CONFIG_IP6_NF_MATCH_IPV6HEADER=y
+CONFIG_IP6_NF_MATCH_MH=y
+CONFIG_IP6_NF_MATCH_RT=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+CONFIG_BRIDGE_NF_EBTABLES=y
+CONFIG_BRIDGE_EBT_BROUTE=y
+CONFIG_BRIDGE_EBT_T_FILTER=y
+CONFIG_BRIDGE_EBT_T_NAT=y
+CONFIG_BRIDGE_EBT_ARP=y
+CONFIG_BRIDGE_EBT_IP=y
+CONFIG_BRIDGE_EBT_IP6=y
+CONFIG_BRIDGE_EBT_ARPREPLY=y
+CONFIG_BRIDGE_EBT_DNAT=y
+CONFIG_BRIDGE_EBT_SNAT=y
+CONFIG_BRIDGE=y
+CONFIG_VLAN_8021Q=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_PRIO=y
+CONFIG_RMNET_DATA=y
+CONFIG_RMNET_DATA_FC=y
+CONFIG_RMNET_DATA_DEBUG_PKT=y
+CONFIG_BT=y
+CONFIG_MSM_BT_POWER=y
+CONFIG_CFG80211=y
+CONFIG_CFG80211_DEBUGFS=y
+CONFIG_CFG80211_INTERNAL_REGDB=y
+CONFIG_CFG80211_WEXT=y
+CONFIG_RFKILL=y
+CONFIG_IPC_ROUTER=y
+CONFIG_IPC_ROUTER_SECURITY=y
+CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=12
+CONFIG_MTD=y
+CONFIG_MTD_TESTS=m
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_MSM_QPIC_NAND=y
+CONFIG_MTD_UBI=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_QSEECOM=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_NETDEVICES=y
+CONFIG_TUN=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+CONFIG_KS8851=y
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+CONFIG_AT803X_PHY=y
+CONFIG_PPP=y
+CONFIG_PPP_ASYNC=y
+CONFIG_USB_USBNET=y
+CONFIG_USB_NET_SMSC75XX=y
+CONFIG_USB_NET_SMSC95XX=y
+CONFIG_WCNSS_MEM_PRE_ALLOC=y
+CONFIG_CNSS=y
+CONFIG_CNSS_SDIO=y
+CONFIG_CNSS_PCI=y
+CONFIG_CLD_HL_SDIO_CORE=y
+CONFIG_CLD_LL_CORE=y
+CONFIG_CNSS_LOGGER=y
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_QPNP_POWER_ON=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_INPUT_GPIO=m
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_MSM=y
+CONFIG_SERIAL_MSM_CONSOLE=y
+CONFIG_SERIAL_MSM_HS=y
+CONFIG_DIAG_CHAR=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_MSM_LEGACY=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MSM_V2=y
+CONFIG_SPI=y
+CONFIG_SPI_QUP=y
+CONFIG_SPI_SPIDEV=m
+CONFIG_SPMI=y
+CONFIG_SPMI_MSM_PMIC_ARB_DEBUG=y
+CONFIG_PTP_1588_CLOCK=y
+CONFIG_PINCTRL_SDXPOORWILLS=y
+CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_QCOM=y
+CONFIG_QCOM_DLOAD_MODE=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_SMB1351_USB_CHARGER=y
+CONFIG_SMB138X_CHARGER=y
+CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
+CONFIG_THERMAL=y
+CONFIG_THERMAL_WRITABLE_TRIPS=y
+CONFIG_THERMAL_GOV_USER_SPACE=y
+CONFIG_THERMAL_GOV_LOW_LIMITS=y
+CONFIG_CPU_THERMAL=y
+CONFIG_THERMAL_QPNP=y
+CONFIG_THERMAL_TSENS=y
+CONFIG_QTI_AOP_REG_COOLING_DEVICE=y
+CONFIG_QTI_QMI_COOLING_DEVICE=y
+CONFIG_REGULATOR_COOLING_DEVICE=y
+CONFIG_MFD_I2C_PMIC=y
+CONFIG_MFD_SPMI_PMIC=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MSM_CDC_PINCTRL=y
+CONFIG_MSM_CDC_SUPPLY=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_QPNP=y
+CONFIG_REGULATOR_RPMH=y
+CONFIG_REGULATOR_STUB=y
+CONFIG_FB=y
+CONFIG_FB_MSM=y
+CONFIG_FB_MSM_MDP_NONE=y
+CONFIG_FB_MSM_QPIC_PANEL_DETECT=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_DYNAMIC_MINORS=y
+CONFIG_SND_USB_AUDIO=y
+CONFIG_SND_USB_AUDIO_QMI=y
+CONFIG_SND_SOC=y
+CONFIG_UHID=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_ELECOM=y
+CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MULTITOUCH=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_ACM=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_DEBUG=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_STORAGE_ONETOUCH=y
+CONFIG_USB_STORAGE_KARMA=y
+CONFIG_USB_STORAGE_CYPRESS_ATACB=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC3_MSM=y
+CONFIG_USB_EHSET_TEST_FIXTURE=y
+CONFIG_USB_LINK_LAYER_TEST=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_USB_MSM_SSPHY_QMP=y
+CONFIG_MSM_HSUSB_PHY=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DEBUG_FILES=y
+CONFIG_USB_GADGET_DEBUG_FS=y
+CONFIG_USB_GADGET_VBUS_DRAW=500
+CONFIG_USB_CONFIGFS=y
+CONFIG_USB_CONFIGFS_SERIAL=y
+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
+CONFIG_USB_CONFIGFS_F_FS=y
+CONFIG_USB_CONFIGFS_UEVENT=y
+CONFIG_USB_CONFIGFS_F_UAC1=y
+CONFIG_USB_CONFIGFS_F_DIAG=y
+CONFIG_USB_CONFIGFS_F_CDEV=y
+CONFIG_USB_CONFIGFS_F_GSI=y
+CONFIG_USB_CONFIGFS_F_QDSS=y
+CONFIG_MMC=y
+CONFIG_MMC_PERF_PROFILING=y
+CONFIG_MMC_RING_BUFFER=y
+CONFIG_MMC_PARANOID_SD_INIT=y
+CONFIG_MMC_CLKGATE=y
+CONFIG_MMC_BLOCK_MINORS=32
+CONFIG_MMC_BLOCK_DEFERRED_RESUME=y
+CONFIG_MMC_TEST=m
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_MSM=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_QPNP=y
+CONFIG_DMADEVICES=y
+CONFIG_QCOM_SPS_DMA=y
+CONFIG_UIO=y
+CONFIG_STAGING=y
+CONFIG_ION=y
+CONFIG_ION_MSM=y
+CONFIG_GSI=y
+CONFIG_IPA3=y
+CONFIG_IPA_WDI_UNIFIED_API=y
+CONFIG_RMNET_IPA3=y
+CONFIG_ECM_IPA=y
+CONFIG_RNDIS_IPA=y
+CONFIG_IPA_UT=y
+CONFIG_SPS=y
+CONFIG_SPS_SUPPORT_NDP_BAM=y
+CONFIG_EP_PCIE=y
+CONFIG_EP_PCIE_HW=y
+CONFIG_QPNP_REVID=y
+CONFIG_MSM_MHI_DEV=y
+CONFIG_USB_BAM=y
+CONFIG_MSM_CLK_RPMH=y
+CONFIG_MSM_CLK_AOP_QMP=y
+CONFIG_MDM_GCC_SDXPOORWILLS=y
+CONFIG_MDM_CLOCK_CPU_SDXPOORWILLS=y
+CONFIG_MDM_DEBUGCC_SDXPOORWILLS=y
+CONFIG_REMOTE_SPINLOCK_MSM=y
+CONFIG_MSM_QMP=y
+CONFIG_IOMMU_IO_PGTABLE_FAST=y
+CONFIG_ARM_SMMU=y
+CONFIG_QCOM_LAZY_MAPPING=y
+CONFIG_IOMMU_DEBUG=y
+CONFIG_IOMMU_DEBUG_TRACKING=y
+CONFIG_IOMMU_TESTS=y
+CONFIG_QCOM_SCM=y
+CONFIG_MSM_BOOT_STATS=y
+CONFIG_QCOM_WATCHDOG_V2=y
+CONFIG_QCOM_MEMORY_DUMP_V2=y
+CONFIG_QCOM_BUS_SCALING=y
+CONFIG_QCOM_BUS_CONFIG_RPMH=y
+CONFIG_MSM_SMEM=y
+CONFIG_MSM_GLINK=y
+CONFIG_MSM_GLINK_LOOPBACK_SERVER=y
+CONFIG_MSM_GLINK_SMEM_NATIVE_XPRT=y
+CONFIG_TRACER_PKT=y
+CONFIG_QTI_RPMH_API=y
+CONFIG_MSM_SMP2P=y
+CONFIG_MSM_IPC_ROUTER_GLINK_XPRT=y
+CONFIG_MSM_QMI_INTERFACE=y
+CONFIG_MSM_GLINK_PKT=y
+CONFIG_MSM_SUBSYSTEM_RESTART=y
+CONFIG_MSM_PIL=y
+CONFIG_MSM_PIL_SSR_GENERIC=y
+CONFIG_QCOM_COMMAND_DB=y
+CONFIG_MSM_PM=y
+CONFIG_QCOM_DCC_V2=y
+CONFIG_QTI_RPM_STATS_LOG=y
+CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
+CONFIG_QMP_DEBUGFS_CLIENT=y
+CONFIG_ARM_MEMLAT_MON=y
+CONFIG_DEVFREQ_GOV_MEMLAT=y
+CONFIG_QCOM_DEVFREQ_DEVBW=y
+CONFIG_EXTCON_QCOM_SPMI_MISC=y
+CONFIG_IIO=y
+CONFIG_PWM=y
+CONFIG_PWM_QPNP=y
+CONFIG_QCOM_SHOW_RESUME_IRQ=y
+CONFIG_ANDROID=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_INFO=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_PAGEALLOC=y
+CONFIG_DEBUG_KMEMLEAK=y
+CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y
+CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_PANIC_ON_RECURSIVE_FAULT=y
+CONFIG_PANIC_TIMEOUT=5
+CONFIG_SCHEDSTATS=y
+CONFIG_SCHED_STACK_END_CHECK=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_ATOMIC_SLEEP=y
+CONFIG_DEBUG_LIST=y
+CONFIG_FAULT_INJECTION=y
+CONFIG_FAIL_PAGE_ALLOC=y
+CONFIG_FAULT_INJECTION_DEBUG_FS=y
+CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
+CONFIG_IPC_LOGGING=y
+CONFIG_QCOM_RTB=y
+CONFIG_IRQSOFF_TRACER=y
+CONFIG_PREEMPT_TRACER=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_SET_MODULE_RONX=y
+CONFIG_CORESIGHT=y
+CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y
+CONFIG_CORESIGHT_SOURCE_ETM3X=y
+CONFIG_CORESIGHT_REMOTE_ETM=y
+CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0
+CONFIG_CORESIGHT_QCOM_REPLICATOR=y
+CONFIG_CORESIGHT_STM=y
+CONFIG_CORESIGHT_TPDA=y
+CONFIG_CORESIGHT_TPDM=y
+CONFIG_CORESIGHT_CTI=y
+CONFIG_CORESIGHT_EVENT=y
+CONFIG_CORESIGHT_TGU=y
+CONFIG_CORESIGHT_HWEVENT=y
+CONFIG_CORESIGHT_DUMMY=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_HARDENED_USERCOPY=y
+CONFIG_SECURITY_SELINUX=y
+# CONFIG_SECURITY_SELINUX_AVC_STATS is not set
+CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y
+CONFIG_CRYPTO_DEV_QCRYPTO=y
+CONFIG_CRYPTO_DEV_QCEDEV=y
+CONFIG_XZ_DEC=y
+CONFIG_QMI_ENCDEC=y
diff --git a/arch/arm/configs/sdxpoorwills-perf_defconfig b/arch/arm/configs/sdxpoorwills-perf_defconfig
index 5ac5966..23a1364 100644
--- a/arch/arm/configs/sdxpoorwills-perf_defconfig
+++ b/arch/arm/configs/sdxpoorwills-perf_defconfig
@@ -32,6 +32,7 @@
CONFIG_PREEMPT=y
CONFIG_AEABI=y
CONFIG_CMA=y
+CONFIG_NO_VM_RECLAIM=y
CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
@@ -374,6 +375,7 @@
CONFIG_QCOM_MEMORY_DUMP_V2=y
CONFIG_QCOM_BUS_SCALING=y
CONFIG_QCOM_BUS_CONFIG_RPMH=y
+CONFIG_QCOM_EARLY_RANDOM=y
CONFIG_MSM_SMEM=y
CONFIG_MSM_GLINK=y
CONFIG_MSM_GLINK_LOOPBACK_SERVER=y
diff --git a/arch/arm/configs/sdxpoorwills_defconfig b/arch/arm/configs/sdxpoorwills_defconfig
index 137a3d5..bc75557 100644
--- a/arch/arm/configs/sdxpoorwills_defconfig
+++ b/arch/arm/configs/sdxpoorwills_defconfig
@@ -34,6 +34,7 @@
CONFIG_PREEMPT=y
CONFIG_AEABI=y
CONFIG_CMA=y
+CONFIG_NO_VM_RECLAIM=y
CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
@@ -379,6 +380,7 @@
CONFIG_QCOM_MEMORY_DUMP_V2=y
CONFIG_QCOM_BUS_SCALING=y
CONFIG_QCOM_BUS_CONFIG_RPMH=y
+CONFIG_QCOM_EARLY_RANDOM=y
CONFIG_MSM_SMEM=y
CONFIG_MSM_GLINK=y
CONFIG_MSM_GLINK_LOOPBACK_SERVER=y
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index f4dab20..0833d8a 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -327,4 +327,16 @@
return false;
}
+#define KVM_SSBD_UNKNOWN -1
+#define KVM_SSBD_FORCE_DISABLE 0
+#define KVM_SSBD_KERNEL 1
+#define KVM_SSBD_FORCE_ENABLE 2
+#define KVM_SSBD_MITIGATED 3
+
+static inline int kvm_arm_have_ssbd(void)
+{
+ /* No way to detect it yet, pretend it is not there. */
+ return KVM_SSBD_UNKNOWN;
+}
+
#endif /* __ARM_KVM_HOST_H__ */
diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
index 7f66b1b..e2f05ce 100644
--- a/arch/arm/include/asm/kvm_mmu.h
+++ b/arch/arm/include/asm/kvm_mmu.h
@@ -28,6 +28,13 @@
*/
#define kern_hyp_va(kva) (kva)
+/* Contrary to arm64, there is no need to generate a PC-relative address */
+#define hyp_symbol_addr(s) \
+ ({ \
+ typeof(s) *addr = &(s); \
+ addr; \
+ })
+
/*
* KVM_MMU_CACHE_MIN_PAGES is the number of stage2 page table translation levels.
*/
@@ -249,6 +256,11 @@
return 0;
}
+static inline int hyp_map_aux_data(void)
+{
+ return 0;
+}
+
#endif /* !__ASSEMBLY__ */
#endif /* __ARM_KVM_MMU_H__ */
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index ef6595c..2043697 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -51,8 +51,8 @@
__asm__(".arch_extension virt");
#endif
+DEFINE_PER_CPU(kvm_cpu_context_t, kvm_host_cpu_state);
static DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_page);
-static kvm_cpu_context_t __percpu *kvm_host_cpu_state;
static unsigned long hyp_default_vectors;
/* Per-CPU variable containing the currently running vcpu. */
@@ -338,7 +338,7 @@
}
vcpu->cpu = cpu;
- vcpu->arch.host_cpu_context = this_cpu_ptr(kvm_host_cpu_state);
+ vcpu->arch.host_cpu_context = this_cpu_ptr(&kvm_host_cpu_state);
kvm_arm_set_running_vcpu(vcpu);
}
@@ -1199,19 +1199,8 @@
}
#endif
-static void teardown_common_resources(void)
-{
- free_percpu(kvm_host_cpu_state);
-}
-
static int init_common_resources(void)
{
- kvm_host_cpu_state = alloc_percpu(kvm_cpu_context_t);
- if (!kvm_host_cpu_state) {
- kvm_err("Cannot allocate host CPU state\n");
- return -ENOMEM;
- }
-
/* set size of VMID supported by CPU */
kvm_vmid_bits = kvm_get_vmid_bits();
kvm_info("%d-bit VMID\n", kvm_vmid_bits);
@@ -1369,7 +1358,7 @@
for_each_possible_cpu(cpu) {
kvm_cpu_context_t *cpu_ctxt;
- cpu_ctxt = per_cpu_ptr(kvm_host_cpu_state, cpu);
+ cpu_ctxt = per_cpu_ptr(&kvm_host_cpu_state, cpu);
err = create_hyp_mappings(cpu_ctxt, cpu_ctxt + 1, PAGE_HYP);
if (err) {
@@ -1378,6 +1367,12 @@
}
}
+ err = hyp_map_aux_data();
+ if (err) {
+ kvm_err("Cannot map host auxilary data: %d\n", err);
+ goto out_err;
+ }
+
kvm_info("Hyp mode initialized successfully\n");
return 0;
@@ -1447,7 +1442,6 @@
out_hyp:
teardown_hyp_mode();
out_err:
- teardown_common_resources();
return err;
}
diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c
index 8a9c654..83365be 100644
--- a/arch/arm/kvm/psci.c
+++ b/arch/arm/kvm/psci.c
@@ -403,7 +403,7 @@
int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
{
u32 func_id = smccc_get_function(vcpu);
- u32 val = PSCI_RET_NOT_SUPPORTED;
+ u32 val = SMCCC_RET_NOT_SUPPORTED;
u32 feature;
switch (func_id) {
@@ -415,7 +415,21 @@
switch(feature) {
case ARM_SMCCC_ARCH_WORKAROUND_1:
if (kvm_arm_harden_branch_predictor())
- val = 0;
+ val = SMCCC_RET_SUCCESS;
+ break;
+ case ARM_SMCCC_ARCH_WORKAROUND_2:
+ switch (kvm_arm_have_ssbd()) {
+ case KVM_SSBD_FORCE_DISABLE:
+ case KVM_SSBD_UNKNOWN:
+ break;
+ case KVM_SSBD_KERNEL:
+ val = SMCCC_RET_SUCCESS;
+ break;
+ case KVM_SSBD_FORCE_ENABLE:
+ case KVM_SSBD_MITIGATED:
+ val = SMCCC_RET_NOT_REQUIRED;
+ break;
+ }
break;
}
break;
diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
index 4e95a7b..89a4ca7 100644
--- a/arch/arm/mach-qcom/Kconfig
+++ b/arch/arm/mach-qcom/Kconfig
@@ -126,6 +126,47 @@
select HAVE_CLK_PREPARE
select COMMON_CLK_MSM
+config ARCH_QM215
+ bool "Enable support for QM215"
+ select CPU_V7
+ select HAVE_ARM_ARCH_TIMER
+ select PINCTRL
+ select QCOM_SCM if SMP
+ select PM_DEVFREQ
+ select CLKDEV_LOOKUP
+ select HAVE_CLK
+ select HAVE_CLK_PREPARE
+ select COMMON_CLK_MSM
+
+config ARCH_MSM8940
+ bool "MSM8940"
+ select MSM_CORTEX_A53
+ select ARCH_MSM_CORTEXMP
+ select CPU_V7
+ select HAVE_SMP
+ select ARM_GIC
+ select MSM_IRQ
+ select SPARSE_IRQ
+ select MULTI_IRQ_HANDLER
+ select HAVE_ARM_ARCH_TIMER
+ select MAY_HAVE_SPARSE_IRQ
+ select PINCTRL
+ select PINCTRL_MSM_TLMM
+ select USE_PINCTRL_IRQ
+ select MSM_PM if PM
+ select QMI_ENCDEC
+ select CPU_FREQ
+ select CPU_FREQ_MSM
+ select PM_DEVFREQ
+ select MSM_DEVFREQ_DEVBW
+ select DEVFREQ_SIMPLE_DEV
+ select DEVFREQ_GOV_MSM_BW_HWMON
+ select MSM_BIMC_BWMON
+ select MSM_QDSP6V2_CODECS
+ select MSM_AUDIO_QDSP6V2 if SND_SOC
+ select ARM_HAS_SG_CHAIN
+ select MSM_JTAGV8 if CORESIGHT_ETMV4
+
config ARCH_SDM439
bool "Enable support for SDM439"
select CPU_V7
diff --git a/arch/arm/mach-qcom/Makefile b/arch/arm/mach-qcom/Makefile
index 3ef169f..f757ce0 100644
--- a/arch/arm/mach-qcom/Makefile
+++ b/arch/arm/mach-qcom/Makefile
@@ -6,6 +6,8 @@
obj-$(CONFIG_ARCH_MSM8937) += board-msm8937.o
obj-$(CONFIG_ARCH_MSM8909) += board-msm8909.o
obj-$(CONFIG_ARCH_MSM8917) += board-msm8917.o
+obj-$(CONFIG_ARCH_QM215) += board-qm215.o
+obj-$(CONFIG_ARCH_MSM8940) += board-msm8940.o
obj-$(CONFIG_ARCH_SDM429) += board-sdm429.o
obj-$(CONFIG_ARCH_SDM439) += board-sdm439.o
obj-$(CONFIG_ARCH_SDM450) += board-sdm450.o
diff --git a/arch/arm/mach-qcom/board-msm8940.c b/arch/arm/mach-qcom/board-msm8940.c
new file mode 100644
index 0000000..3e60902
--- /dev/null
+++ b/arch/arm/mach-qcom/board-msm8940.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2016, 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <asm/mach/arch.h>
+#include "board-dt.h"
+
+static const char *msm8940_dt_match[] __initconst = {
+ "qcom,msm8940",
+ NULL
+};
+
+static void __init msm8940_init(void)
+{
+ board_dt_populate(NULL);
+}
+
+DT_MACHINE_START(MSM8940_DT,
+ "Qualcomm Technologies, Inc. MSM8940-PMI8950 MTP")
+ .init_machine = msm8940_init,
+ .dt_compat = msm8940_dt_match,
+MACHINE_END
diff --git a/arch/arm/mach-qcom/board-qm215.c b/arch/arm/mach-qcom/board-qm215.c
new file mode 100644
index 0000000..62f9175
--- /dev/null
+++ b/arch/arm/mach-qcom/board-qm215.c
@@ -0,0 +1,32 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include "board-dt.h"
+#include <asm/mach/map.h>
+#include <asm/mach/arch.h>
+
+static const char *qm215_dt_match[] __initconst = {
+ "qcom,qm215",
+ NULL
+};
+
+static void __init qm215_init(void)
+{
+ board_dt_populate(NULL);
+}
+
+DT_MACHINE_START(QM215_DT,
+ "Qualcomm Technologies, Inc. QM215")
+ .init_machine = qm215_init,
+ .dt_compat = qm215_dt_match,
+MACHINE_END
diff --git a/arch/arm/mach-qcom/board-sdm450.c b/arch/arm/mach-qcom/board-sdm450.c
index 5f68ede..1c0b135 100644
--- a/arch/arm/mach-qcom/board-sdm450.c
+++ b/arch/arm/mach-qcom/board-sdm450.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -17,6 +17,7 @@
static const char *sdm450_dt_match[] __initconst = {
"qcom,sdm450",
+ "qcom,sda450",
NULL
};
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index e5a8a57..d89d0d7 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -30,6 +30,8 @@
#include <linux/cma.h>
#include <linux/msm_dma_iommu_mapping.h>
#include <linux/dma-mapping-fast.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
#include <asm/memory.h>
#include <asm/highmem.h>
@@ -122,7 +124,8 @@
static void __dma_free_remap(void *cpu_addr, size_t size, bool no_warn);
-static inline pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot);
+static inline pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot,
+ bool coherent);
static void *arm_dma_remap(struct device *dev, void *cpu_addr,
dma_addr_t handle, size_t size,
@@ -131,6 +134,30 @@
static void arm_dma_unremap(struct device *dev, void *remapped_addr,
size_t size);
+
+static pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot,
+ bool coherent)
+{
+ if (attrs & DMA_ATTR_STRONGLY_ORDERED)
+ return pgprot_stronglyordered(prot);
+ else if (!coherent || (attrs & DMA_ATTR_WRITE_COMBINE))
+ return pgprot_writecombine(prot);
+ return prot;
+}
+
+static bool is_dma_coherent(struct device *dev, unsigned long attrs,
+ bool is_coherent)
+{
+ if (attrs & DMA_ATTR_FORCE_COHERENT)
+ is_coherent = true;
+ else if (attrs & DMA_ATTR_FORCE_NON_COHERENT)
+ is_coherent = false;
+ else if (is_device_dma_coherent(dev))
+ is_coherent = true;
+
+ return is_coherent;
+}
+
/**
* arm_dma_map_page - map a portion of a page for streaming DMA
* @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
@@ -709,19 +736,6 @@
dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT);
}
-static inline pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot)
-{
- if (attrs & DMA_ATTR_WRITE_COMBINE)
- prot = pgprot_writecombine(prot);
- else if (attrs & DMA_ATTR_STRONGLY_ORDERED)
- prot = pgprot_stronglyordered(prot);
- /* if non-consistent just pass back what was given */
- else if ((attrs & DMA_ATTR_NON_CONSISTENT) == 0)
- prot = pgprot_dmacoherent(prot);
-
- return prot;
-}
-
#define nommu() 0
#else /* !CONFIG_MMU */
@@ -915,7 +929,7 @@
void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
gfp_t gfp, unsigned long attrs)
{
- pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
+ pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL, false);
return __dma_alloc(dev, size, handle, gfp, prot, false,
attrs, __builtin_return_address(0));
@@ -959,7 +973,7 @@
{
void *ptr;
struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
- pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
+ pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL, false);
unsigned long offset = handle & ~PAGE_MASK;
size = PAGE_ALIGN(size + offset);
@@ -1003,7 +1017,8 @@
unsigned long attrs)
{
#ifdef CONFIG_MMU
- vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
+ vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot,
+ false);
#endif /* CONFIG_MMU */
return __arm_dma_mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
}
@@ -1529,16 +1544,19 @@
* Create a mapping in device IO address space for specified pages
*/
static dma_addr_t
-__iommu_create_mapping(struct device *dev, struct page **pages, size_t size)
+__iommu_create_mapping(struct device *dev, struct page **pages, size_t size,
+ int coherent_flag)
{
struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
dma_addr_t dma_addr, iova;
int i;
+ int prot = IOMMU_READ | IOMMU_WRITE;
dma_addr = __alloc_iova(mapping, size);
if (dma_addr == DMA_ERROR_CODE)
return dma_addr;
+ prot |= coherent_flag ? IOMMU_CACHE : 0;
iova = dma_addr;
for (i = 0; i < count; ) {
@@ -1553,8 +1571,7 @@
break;
len = (j - i) << PAGE_SHIFT;
- ret = iommu_map(mapping->domain, iova, phys, len,
- IOMMU_READ|IOMMU_WRITE);
+ ret = iommu_map(mapping->domain, iova, phys, len, prot);
if (ret < 0)
goto fail;
iova += len;
@@ -1623,7 +1640,7 @@
if (!addr)
return NULL;
- *handle = __iommu_create_mapping(dev, &page, size);
+ *handle = __iommu_create_mapping(dev, &page, size, coherent_flag);
if (*handle == DMA_ERROR_CODE)
goto err_mapping;
@@ -1648,17 +1665,19 @@
dma_addr_t *handle, gfp_t gfp, unsigned long attrs,
int coherent_flag)
{
- pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
struct page **pages;
void *addr = NULL;
+ pgprot_t prot;
*handle = DMA_ERROR_CODE;
size = PAGE_ALIGN(size);
- if (coherent_flag == COHERENT || !gfpflags_allow_blocking(gfp))
+ if (coherent_flag == COHERENT || !gfpflags_allow_blocking(gfp))
return __iommu_alloc_simple(dev, size, gfp, handle,
coherent_flag);
+ coherent_flag = is_dma_coherent(dev, attrs, coherent_flag);
+ prot = __get_dma_pgprot(attrs, PAGE_KERNEL, coherent_flag);
/*
* Following is a work-around (a.k.a. hack) to prevent pages
* with __GFP_COMP being passed to split_page() which cannot
@@ -1672,7 +1691,7 @@
if (!pages)
return NULL;
- *handle = __iommu_create_mapping(dev, pages, size);
+ *handle = __iommu_create_mapping(dev, pages, size, coherent_flag);
if (*handle == DMA_ERROR_CODE)
goto err_buffer;
@@ -1739,7 +1758,8 @@
struct vm_area_struct *vma, void *cpu_addr,
dma_addr_t dma_addr, size_t size, unsigned long attrs)
{
- vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
+ vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot,
+ is_dma_coherent(dev, attrs, NORMAL));
return __arm_iommu_mmap_attrs(dev, vma, cpu_addr, dma_addr, size, attrs);
}
@@ -1784,7 +1804,8 @@
void arm_iommu_free_attrs(struct device *dev, size_t size,
void *cpu_addr, dma_addr_t handle, unsigned long attrs)
{
- __arm_iommu_free_attrs(dev, size, cpu_addr, handle, attrs, NORMAL);
+ __arm_iommu_free_attrs(dev, size, cpu_addr, handle, attrs,
+ is_dma_coherent(dev, attrs, NORMAL));
}
void arm_coherent_iommu_free_attrs(struct device *dev, size_t size,
@@ -1841,7 +1862,7 @@
int ret = 0;
unsigned int count;
struct scatterlist *s;
- int prot;
+ int prot = 0;
size = PAGE_ALIGN(size);
*handle = DMA_ERROR_CODE;
@@ -1850,6 +1871,11 @@
if (iova == DMA_ERROR_CODE)
return -ENOMEM;
+ /*
+ * Check for coherency.
+ */
+ prot |= is_coherent ? IOMMU_CACHE : 0;
+
for (count = 0, s = sg; count < (size >> PAGE_SHIFT); s = sg_next(s)) {
phys_addr_t phys = page_to_phys(sg_page(s));
unsigned int len = PAGE_ALIGN(s->offset + s->length);
@@ -1857,7 +1883,7 @@
if (!is_coherent && (attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0)
__dma_page_cpu_to_dev(sg_page(s), s->offset, s->length, dir);
- prot = __dma_direction_to_prot(dir);
+ prot |= __dma_direction_to_prot(dir);
ret = iommu_map(mapping->domain, iova, phys, len, prot);
if (ret < 0)
@@ -1959,14 +1985,45 @@
struct dma_iommu_mapping *mapping = dev->archdata.mapping;
unsigned int total_length = 0, current_offset = 0;
dma_addr_t iova;
+ bool coherent;
int prot = __dma_direction_to_prot(dir);
+ int upstream_hint = 0;
+ /*
+ * This is used to check if there are any unaligned offset/size
+ * given in the scatter list.
+ */
+ bool unaligned_offset_size = false;
- for_each_sg(sg, s, nents, i)
+ for_each_sg(sg, s, nents, i) {
total_length += s->length;
+ if ((s->offset & ~PAGE_MASK) || (s->length & ~PAGE_MASK)) {
+ unaligned_offset_size = true;
+ break;
+ }
+ }
+
+ /*
+ * Check for the upstream domain attribute just to catch
+ * any abusive clients who expects the unaligned offset/size
+ * support with out setting this attribute.
+ * NOTE: on future kernels, we may not have this domain
+ * attribute set where the check then will be based on just
+ * offset/size.
+ */
+ iommu_domain_get_attr(mapping->domain,
+ DOMAIN_ATTR_UPSTREAM_IOVA_ALLOCATOR,
+ &upstream_hint);
+ if (upstream_hint && unaligned_offset_size)
+ return __iommu_map_sg(dev, sg, nents, dir, attrs,
+ is_dma_coherent(dev, attrs, false));
iova = __alloc_iova(mapping, total_length);
if (iova == DMA_ERROR_CODE)
return 0;
+
+ coherent = of_dma_is_coherent(dev->of_node);
+ prot |= is_dma_coherent(dev, attrs, coherent) ? IOMMU_CACHE : 0;
+
ret = iommu_map_sg(mapping->domain, iova, sg, nents, prot);
if (ret != total_length) {
__free_iova(mapping, iova, total_length);
@@ -2053,6 +2110,12 @@
{
struct scatterlist *s;
int i;
+ struct dma_iommu_mapping *mapping = dev->archdata.mapping;
+ dma_addr_t iova = sg_dma_address(sg);
+ bool iova_coherent = iommu_is_iova_coherent(mapping->domain, iova);
+
+ if (iova_coherent)
+ return;
for_each_sg(sg, s, nents, i)
__dma_page_dev_to_cpu(sg_page(s), s->offset, s->length, dir);
@@ -2072,6 +2135,13 @@
struct scatterlist *s;
int i;
+ struct dma_iommu_mapping *mapping = dev->archdata.mapping;
+ dma_addr_t iova = sg_dma_address(sg);
+ bool iova_coherent = iommu_is_iova_coherent(mapping->domain, iova);
+
+ if (iova_coherent)
+ return;
+
for_each_sg(sg, s, nents, i)
__dma_page_cpu_to_dev(sg_page(s), s->offset, s->length, dir);
}
@@ -2130,7 +2200,8 @@
unsigned long offset, size_t size, enum dma_data_direction dir,
unsigned long attrs)
{
- if ((attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0)
+ if (!is_dma_coherent(dev, attrs, false) &&
+ !(attrs & DMA_ATTR_SKIP_CPU_SYNC))
__dma_page_cpu_to_dev(page, offset, size, dir);
return arm_coherent_iommu_map_page(dev, page, offset, size, dir, attrs);
@@ -2178,7 +2249,8 @@
if (!iova)
return;
- if ((attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0)
+ if (!(is_dma_coherent(dev, attrs, false) ||
+ (attrs & DMA_ATTR_SKIP_CPU_SYNC)))
__dma_page_dev_to_cpu(page, offset, size, dir);
iommu_unmap(mapping->domain, iova, len);
@@ -2249,8 +2321,10 @@
dma_addr_t iova = handle & PAGE_MASK;
struct page *page = phys_to_page(iommu_iova_to_phys(mapping->domain, iova));
unsigned int offset = handle & ~PAGE_MASK;
+ bool iova_coherent = iommu_is_iova_coherent(mapping->domain, handle);
- __dma_page_dev_to_cpu(page, offset, size, dir);
+ if (!iova_coherent)
+ __dma_page_dev_to_cpu(page, offset, size, dir);
}
static void arm_iommu_sync_single_for_device(struct device *dev,
@@ -2260,10 +2334,16 @@
dma_addr_t iova = handle & PAGE_MASK;
struct page *page = phys_to_page(iommu_iova_to_phys(mapping->domain, iova));
unsigned int offset = handle & ~PAGE_MASK;
+ bool iova_coherent = iommu_is_iova_coherent(mapping->domain, handle);
- __dma_page_cpu_to_dev(page, offset, size, dir);
+ if (!iova_coherent)
+ __dma_page_cpu_to_dev(page, offset, size, dir);
}
+static int arm_iommu_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+ return dma_addr == DMA_ERROR_CODE;
+}
const struct dma_map_ops iommu_ops = {
.alloc = arm_iommu_alloc_attrs,
.free = arm_iommu_free_attrs,
@@ -2282,6 +2362,8 @@
.map_resource = arm_iommu_map_resource,
.unmap_resource = arm_iommu_unmap_resource,
+
+ .mapping_error = arm_iommu_mapping_error,
};
const struct dma_map_ops iommu_coherent_ops = {
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 219aa9c..5d06273 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -1168,19 +1168,6 @@
*/
vmalloc_limit = (u64)(uintptr_t)vmalloc_min - PAGE_OFFSET + PHYS_OFFSET;
-#ifdef CONFIG_ENABLE_VMALLOC_SAVING
- struct memblock_region *prev_reg = NULL;
-
- for_each_memblock(memory, reg) {
- if (prev_reg == NULL) {
- prev_reg = reg;
- continue;
- }
- vmalloc_limit += reg->base - (prev_reg->base + prev_reg->size);
- prev_reg = reg;
- }
-#endif
-
for_each_memblock(memory, reg) {
phys_addr_t block_start = reg->base;
phys_addr_t block_end = reg->base + reg->size;
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index ac71d39..96ec05d 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -865,6 +865,15 @@
If unsure, say N.
+config ARM64_SSBD
+ bool "Speculative Store Bypass Disable" if EXPERT
+ default y
+ help
+ This enables mitigation of the bypassing of previous stores
+ by speculative loads.
+
+ If unsure, say Y.
+
menuconfig ARMV8_DEPRECATED
bool "Emulate deprecated/obsolete ARMv8 instructions"
depends on COMPAT
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 4c013ad..a1ed16b 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -166,6 +166,15 @@
This enables support for the MSM8937 chipset. If you do not
wish to build a kernel that runs on this chipset, say 'N' here.
+config ARCH_MSM8940
+ bool "Enable Support for Qualcomm Technologies Inc. MSM8940"
+ depends on ARCH_QCOM
+ select CPU_FREQ_QCOM
+ select COMMON_CLK_MSM
+ help
+ This enables support for the MSM8940 chipset. If you do not
+ wish to build a kernel that runs on this chipset, say 'N' here.
+
config ARCH_MSM8917
bool "Enable Support for Qualcomm Technologies Inc. MSM8917"
depends on ARCH_QCOM
@@ -175,6 +184,15 @@
This enables support for the MSM8917 chipset. If you do not
wish to build a kernel that runs on this chipset, say 'N' here.
+config ARCH_QM215
+ bool "Enable Support for Qualcomm Technologies Inc. QM215"
+ depends on ARCH_QCOM
+ select CPU_FREQ_QCOM
+ select COMMON_CLK_MSM
+ help
+ This enables support for the QM215 chipset. If you do not
+ wish to build a kernel that runs on this chipset, say 'N' here.
+
config ARCH_SDM450
bool "Enable Support for Qualcomm Technologies Inc. SDM450"
depends on ARCH_QCOM
diff --git a/arch/arm64/boot/dts/qcom/8909w-pm660.dtsi b/arch/arm64/boot/dts/qcom/8909w-pm660.dtsi
index 150613b..97b20af 100644
--- a/arch/arm64/boot/dts/qcom/8909w-pm660.dtsi
+++ b/arch/arm64/boot/dts/qcom/8909w-pm660.dtsi
@@ -559,6 +559,11 @@
qcom,fg-esr-pulse-thresh-ma = <40>;
qcom,fg-esr-meas-curr-ma = <60>;
qcom,fg-cutoff-current = <50>;
+
+ qcom,fg-esr-timer-shutdown = <2048 2048>;
+ qcom,fg-esr-timer-asleep = <512 512>;
+ qcom,fg-sync-sleep-threshold-ma = <30>;
+ qcom,fg-disable-in-twm;
};
&pm660_pdphy {
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index a80f478..a5f8efc 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -344,8 +344,9 @@
msm8917-rcm-overlay.dtbo \
apq8017-mtp-overlay.dtbo \
apq8017-cdp-overlay.dtbo \
- apq8017-cdp-wcd-rome-overlay.dtbo \
- qm215-qrd-overlay.dtbo
+ apq8017-cdp-wcd-rome-overlay.dtbo
+
+dtbo-$(CONFIG_ARCH_QM215) +=qm215-qrd-overlay.dtbo
dtbo-$(CONFIG_ARCH_MSM8953) += msm8953-mtp-overlay.dtbo \
msm8953-cdp-overlay.dtbo \
@@ -519,7 +520,8 @@
msm8953-pmi8937-mtp.dtb \
msm8953-pmi8940-ext-codec-mtp.dtb \
msm8953-pmi8937-ext-codec-mtp.dtb \
- msm8953-pmi632-cdp-s2.dtb
+ msm8953-pmi632-cdp-s2.dtb \
+ apq8053-batcam.dtb
dtb-$(CONFIG_ARCH_MSM8937) += msm8937-pmi8950-mtp.dtb \
msm8937-interposer-sdm439-cdp.dtb \
@@ -528,6 +530,10 @@
msm8937-interposer-sdm429-cdp.dtb \
msm8937-interposer-sdm429-mtp.dtb
+dtb-$(CONFIG_ARCH_MSM8940) += msm8940-pmi8937-mtp.dtb \
+ msm8940-pmi8950-mtp.dtb \
+ msm8940-pmi8940-mtp.dtb
+
dtb-$(CONFIG_ARCH_MSM8917) += msm8917-pmi8950-mtp.dtb \
msm8917-pmi8950-cdp.dtb \
msm8917-pmi8950-rcm.dtb \
@@ -545,10 +551,12 @@
apq8017-pmi8937-cdp-wcd-rome.dtb \
msm8917-pmi8940-mtp.dtb \
msm8917-pmi8940-cdp.dtb \
- msm8917-pmi8940-rcm.dtb \
- qm215-qrd.dtb
+ msm8917-pmi8940-rcm.dtb
-dtb-$(CONFIG_ARCH_MSM8909) += sdw3100-msm8909w-wtp.dtb \
+dtb-$(CONFIG_ARCH_QM215) += qm215-qrd.dtb
+
+dtb-$(CONFIG_ARCH_MSM8909) += msm8909-pm8916-mtp.dtb \
+ sdw3100-msm8909w-wtp.dtb \
sdw3100-apq8009w-wtp.dtb \
sdw3100-apq8009w-alpha.dtb \
apq8009-mtp-wcd9326-refboard.dtb \
diff --git a/arch/arm64/boot/dts/qcom/apq8009-dragon.dts b/arch/arm64/boot/dts/qcom/apq8009-dragon.dts
index 314af11..1ac603e 100644
--- a/arch/arm64/boot/dts/qcom/apq8009-dragon.dts
+++ b/arch/arm64/boot/dts/qcom/apq8009-dragon.dts
@@ -361,3 +361,47 @@
&blsp1_uart1 {
status = "disabled";
};
+
+&i2c_5 {
+ status = "okay";
+ goodix_ts@5d {
+ compatible = "goodix,gt9xx";
+ status = "okay";
+ reg = <0x5d>;
+ vdd_ana-supply = <&pm8916_l17>;
+ vcc_i2c-supply = <&pm8916_l6>;
+ interrupt-parent = <&msm_gpio>;
+ interrupts = <13 0x2008>;
+ pinctrl-names = "gdix_ts_int_default", "gdix_ts_int_output_low",
+ "gdix_ts_int_output_high", "gdix_ts_int_input",
+ "gdix_ts_rst_default", "gdix_ts_rst_output_low",
+ "gdix_ts_rst_output_high", "gdix_ts_rst_input";
+ pinctrl-0 = <&ts_int_default>;
+ pinctrl-1 = <&ts_int_output_low>;
+ pinctrl-2 = <&ts_int_output_high>;
+ pinctrl-3 = <&ts_int_input>;
+ pinctrl-4 = <&ts_rst_default>;
+ pinctrl-5 = <&ts_rst_output_low>;
+ pinctrl-6 = <&ts_rst_output_high>;
+ pinctrl-7 = <&ts_rst_input>;
+ reset-gpios = <&msm_gpio 16 0x00>;
+ irq-gpios = <&msm_gpio 13 0x2008>;
+ irq-flags = <2>;
+ touchscreen-max-id = <5>;
+ touchscreen-size-x = <479>;
+ touchscreen-size-y = <853>;
+ touchscreen-max-w = <1024>;
+ touchscreen-max-p = <1024>;
+ goodix,type-a-report = <0>;
+ goodix,driver-send-cfg = <1>;
+ goodix,wakeup-with-reset = <0>;
+ goodix,resume-in-workqueue = <1>;
+ goodix,int-sync = <1>;
+ goodix,swap-x2y = <0>;
+ goodix,esd-protect = <1>;
+ goodix,pen-suppress-finger = <0>;
+ goodix,auto-update = <1>;
+ goodix,auto-update-cfg = <0>;
+ goodix,power-off-sleep = <0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/apq8009-robot-pronto-refboard.dts b/arch/arm64/boot/dts/qcom/apq8009-robot-pronto-refboard.dts
index 3a421bf..648670b 100644
--- a/arch/arm64/boot/dts/qcom/apq8009-robot-pronto-refboard.dts
+++ b/arch/arm64/boot/dts/qcom/apq8009-robot-pronto-refboard.dts
@@ -18,7 +18,7 @@
#include "apq8009-memory.dtsi"
#include <dt-bindings/pinctrl/qcom,pmic-mpp.h>
#include "msm8909-pm8916-camera.dtsi"
-#include "msm8909-pm8916-camera-sensor-robot.dtsi"
+#include "msm8909-pm8916-camera-sensor-robot-pronto.dtsi"
/ {
model = "Qualcomm Technologies, Inc. APQ8009 Robot-pronto RefBoard";
@@ -409,36 +409,6 @@
};
};
-&sdhc_2 {
- /delete-property/cd-gpios;
- #address-cells = <0>;
- interrupt-parent = <&sdhc_2>;
- interrupts = <0 1 2>;
- #interrupt-cells = <1>;
- interrupt-map-mask = <0xffffffff>;
- interrupt-map = <0 &intc 0 125 0
- 1 &intc 0 221 0
- 2 &msm_gpio 38 0>;
- interrupt-names = "hc_irq", "pwr_irq", "sdiowakeup_irq";
-
- qcom,vdd-voltage-level = <1800000 2950000>;
- qcom,vdd-current-level = <15000 400000>;
-
- qcom,vdd-io-voltage-level = <1800000 1800000>;
- qcom,vdd-io-current-level = <200 50000>;
- qcom,clk-rates = <400000 25000000 50000000 100000000 200000000>;
- qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104";
-
- pinctrl-names = "active", "sleep";
- pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on
- &sdc2_wlan_gpio_on>;
- pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off
- &sdc2_wlan_gpio_off>;
- qcom,nonremovable;
- qcom,core_3_0v_support;
- status = "disabled";
-};
-
&i2c_4 {
status= "okay";
smb1360_otg_supply: smb1360-chg-fg@14 {
diff --git a/arch/arm64/boot/dts/qcom/apq8009-robot-rome-refboard.dts b/arch/arm64/boot/dts/qcom/apq8009-robot-rome-refboard.dts
index e00eb01..97123a6 100644
--- a/arch/arm64/boot/dts/qcom/apq8009-robot-rome-refboard.dts
+++ b/arch/arm64/boot/dts/qcom/apq8009-robot-rome-refboard.dts
@@ -18,7 +18,7 @@
#include "apq8009-memory.dtsi"
#include <dt-bindings/pinctrl/qcom,pmic-mpp.h>
#include "msm8909-pm8916-camera.dtsi"
-#include "msm8909-pm8916-camera-sensor-robot.dtsi"
+#include "msm8909-pm8916-camera-sensor-robot-rome.dtsi"
/ {
model = "Qualcomm Technologies, Inc. APQ8009 Robot-rome RefBoard";
diff --git a/arch/arm64/boot/dts/qcom/apq8053-batcam.dts b/arch/arm64/boot/dts/qcom/apq8053-batcam.dts
new file mode 100644
index 0000000..69c8734
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/apq8053-batcam.dts
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+#include "apq8053.dtsi"
+#include "pmi8950.dtsi"
+#include "msm8953-mtp.dtsi"
+#include "msm8953-pmi8950.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. APQ8053 + PMI8950 BATCAM";
+ compatible = "qcom,apq8053-mtp", "qcom,apq8053", "qcom,mtp";
+ qcom,board-id = <0x20 2>;
+ qcom,pmic-id = <0x010016 0x010011 0x0 0x0>;
+};
+
+&blsp2_uart0 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/qcom/apq8053-batcam.dtsi b/arch/arm64/boot/dts/qcom/apq8053-batcam.dtsi
new file mode 100644
index 0000000..3c31859
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/apq8053-batcam.dtsi
@@ -0,0 +1,448 @@
+/*
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "msm8953-pinctrl.dtsi"
+#include "apq8053-camera-sensor-dragon.dtsi"
+#include "pmi8950.dtsi"
+#include "msm8953-pmi8950.dtsi"
+
+&soc {
+ vreg_5p0: vreg_5p0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vreg_5p0";
+ status = "ok";
+ enable-active-high;
+ };
+
+ eldo_cam0_vreg: eldo_cam0_vreg {
+ compatible = "regulator-fixed";
+ regulator-name = "eldo_cam0_vreg";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ status = "ok";
+ enable-active-high;
+ vin-supply = <&pm8953_l5>;
+ };
+
+ eldo_cam1_vreg: eldo_cam1_vreg {
+ compatible = "regulator-fixed";
+ regulator-name = "eldo_cam1_vreg";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ status = "ok";
+ enable-active-high;
+ vin-supply = <&pm8953_l5>;
+ };
+
+ eldo_cam2_vreg: eldo_cam2_vreg {
+ compatible = "regulator-fixed";
+ regulator-name = "eldo_cam2_vreg";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ status = "ok";
+ enable-active-high;
+ vin-supply = <&pm8953_l5>;
+ };
+
+ eldo_cam1_vcm_vreg: eldo_cam1_vcm_vreg {
+ compatible = "regulator-fixed";
+ regulator-name = "eldo_cam1_vcm_vreg";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ status = "ok";
+ enable-active-high;
+ };
+
+ cnss_sdio: qcom,cnss_sdio {
+ compatible = "qcom,cnss_sdio";
+ subsys-name = "AR6320";
+
+ /**
+ * There is no vdd-wlan on board and this is not for DSRC.
+ * IO and XTAL share the same vreg.
+ */
+ vdd-wlan-io-supply = <&pm8953_l6>;
+ qcom,wlan-ramdump-dynamic = <0x200000>;
+ qcom,msm-bus,name = "msm-cnss";
+ qcom,msm-bus,num-cases = <4>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <79 512 0 0>, /* No vote */
+ <79 512 6250 200000>, /* 50 Mbps */
+ <79 512 25000 200000>, /* 200 Mbps */
+ <79 512 2048000 4096000>; /* MAX */
+ };
+
+ bluetooth: bt_qca9379 {
+ compatible = "qca,qca6174";
+ qca,bt-reset-gpio = <&tlmm 76 0>; /* BT_EN */
+ };
+
+ cdc_dmic_gpios: cdc_dmic_pinctrl {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&cdc_dmic0_clk_act &cdc_dmic0_data_act>;
+ pinctrl-1 = <&cdc_dmic0_clk_sus &cdc_dmic0_data_sus>;
+ };
+
+ cdc_quat_mi2s_gpios: msm_cdc_pinctrl_quat {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&sec_tlmm_lines_act>;
+ pinctrl-1 = <&sec_tlmm_lines_sus>;
+ };
+
+};
+
+&firmware {
+ android {
+ vbmeta {
+ compatible = "android,vbmeta";
+ parts = "vbmeta,boot,system,vendor,bluetooth,modem,oem";
+ };
+ fstab {
+ /delete-node/ system;
+ vendor {
+ fsmgr_flags = "wait,slotselect,avb";
+ };
+ };
+ };
+};
+
+&rpm_bus {
+ rpm-regulator-ldoa4 {
+ compatible = "qcom,rpm-smd-regulator-resource";
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <4>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ status = "okay";
+
+ pm8953_l4: regulator-l4 {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pm8953_l4";
+ qcom,set = <3>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,init-voltage = <1800000>;
+ status = "okay";
+ };
+ };
+};
+
+&int_codec {
+ status = "ok";
+ qcom,model = "msm8953-openq624-snd-card";
+
+ /delete-property/ qcom,cdc-us-euro-gpios;
+ qcom,msm-hs-micbias-type = "internal";
+
+ qcom,audio-routing =
+ "RX_BIAS", "MCLK",
+ "SPK_RX_BIAS", "MCLK",
+ "INT_LDO_H", "MCLK",
+ "MIC BIAS Internal1", "Handset Mic",
+ "MIC BIAS Internal2", "Headset Mic",
+ "MIC BIAS Internal1", "Secondary Mic",
+ "AMIC1", "MIC BIAS Internal1",
+ "AMIC2", "MIC BIAS Internal2",
+ "AMIC3", "MIC BIAS Internal1",
+ "DMIC1", "MIC BIAS Internal1",
+ "MIC BIAS Internal1", "Digital Mic1",
+ "DMIC2", "MIC BIAS Internal1",
+ "MIC BIAS Internal1", "Digital Mic2";
+
+ qcom,quat-mi2s-gpios = <&cdc_quat_mi2s_gpios>;
+ qcom,cdc-dmic-gpios = <&cdc_dmic_gpios>;
+
+ /delete-property/ asoc-wsa-codec-names;
+ /delete-property/ asoc-wsa-codec-prefixes;
+ /delete-property/ msm-vdd-wsa-switch-supply;
+ /delete-property/ qcom,msm-vdd-wsa-switch-voltage;
+ /delete-property/ qcom,msm-vdd-wsa-switch-current;
+};
+&spi_3 {
+ status = "disabled";
+};
+
+&i2c_1 {
+ status = "okay";
+};
+
+&i2c_2 {
+ status = "okay";
+};
+
+&i2c_3 {
+ status = "okay";
+ focaltech@38 {
+ compatible = "focaltech,5x06";
+ reg = <0x38>;
+ interrupt-parent = <&tlmm>;
+ interrupts = <65 0x2>;
+ vdd-supply = <&pm8953_l10>;
+ vcc_i2c-supply = <&pm8953_l5>;
+ /* pins used by touchscreen */
+ pinctrl-names = "pmx_ts_active","pmx_ts_suspend",
+ "pmx_ts_release";
+ pinctrl-0 = <&ts_int_active &ts_reset_active>;
+ pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>;
+ pinctrl-2 = <&ts_release>;
+ focaltech,name = "ft5606";
+ focaltech,family-id = <0x08>;
+ focaltech,reset-gpio = <&tlmm 64 0x0>;
+ focaltech,irq-gpio = <&tlmm 65 0x2008>;
+ focaltech,display-coords = <0 0 1919 1199>;
+ focaltech,panel-coords = <0 0 1919 1199>;
+ focaltech,no-force-update;
+ focaltech,i2c-pull-up;
+ focaltech,group-id = <1>;
+ focaltech,hard-reset-delay-ms = <20>;
+ focaltech,soft-reset-delay-ms = <200>;
+ focaltech,num-max-touches = <5>;
+ focaltech,fw-delay-aa-ms = <30>;
+ focaltech,fw-delay-55-ms = <30>;
+ focaltech,fw-upgrade-id1 = <0x79>;
+ focaltech,fw-upgrade-id2 = <0x08>;
+ focaltech,fw-delay-readid-ms = <10>;
+ focaltech,fw-delay-era-flsh-ms = <2000>;
+ focaltech,fw-auto-cal;
+ focaltech,resume-in-workqueue;
+ };
+};
+
+&soc {
+ /delete-node/ hbtp;
+};
+
+&i2c_5 {
+ status = "disabled";
+};
+
+&blsp1_uart0 {
+ status = "ok";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart_console_active>;
+};
+
+&sdhc_1 {
+ /* device core power supply */
+ vdd-supply = <&pm8953_l8>;
+ qcom,vdd-voltage-level = <2900000 2900000>;
+ qcom,vdd-current-level = <200 570000>;
+
+ /* device communication power supply */
+ vdd-io-supply = <&pm8953_l5>;
+ qcom,vdd-io-always-on;
+ qcom,vdd-io-lpm-sup;
+ qcom,vdd-io-voltage-level = <1800000 1800000>;
+ qcom,vdd-io-current-level = <200 325000>;
+
+ pinctrl-names = "active", "sleep";
+ pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on &sdc1_rclk_on>;
+ pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off &sdc1_rclk_off>;
+
+ qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 192000000
+ 384000000>;
+ qcom,nonremovable;
+ qcom,bus-speed-mode = "HS400_1p8v", "HS200_1p8v", "DDR_1p8v";
+
+ status = "ok";
+};
+
+&tlmm{
+ sdc2_wlan_gpio_on: sdc2_wlan_gpio_on {
+ mux {
+ pins = "gpio75";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio75";
+ drive-strength = <10>;
+ bias-pull-up;
+ output-high;
+ };
+ };
+ sdc2_wlan_gpio_off: sdc2_wlan_gpio_off {
+ mux {
+ pins = "gpio75";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio75";
+ drive-strength = <2>;
+ bias-disable;
+ output-low;
+ };
+ };
+};
+
+&sdhc_2 {
+ /* device communication power supply */
+ vdd-io-supply = <&pm8953_l12>;
+ qcom,vdd-io-voltage-level = <1800000 1800000>;
+ qcom,vdd-io-current-level = <200 22000>;
+
+ qcom,core_3_0v_support;
+ qcom,nonremovable;
+
+ pinctrl-names = "active", "sleep";
+ pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on
+ &sdc2_wlan_gpio_on>;
+ pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off
+ &sdc2_wlan_gpio_off>;
+
+ qcom,clk-rates = <400000 20000000 25000000 50000000>;
+ qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104";
+
+ status = "ok";
+};
+
+&spmi_bus {
+ qcom,pm8953@0 {
+ qcom,power-on@800 {
+ qcom,resin-gpiobase = <1019>;
+ qcom,pon_2 {
+ /delete-property/ linux,code;
+ };
+ };
+ };
+ qcom,pmi8950@2 {
+ qcom,leds@a100 {
+ compatible = "qcom,leds-qpnp";
+ reg = <0xa100 0x100>;
+ label = "mpp";
+
+ qcom,led_mpp_2 {
+ label = "mpp";
+ linux,name = "green";
+ linux,default-trigger = "none";
+ qcom,default-state = "off";
+ qcom,max-current = <40>;
+ qcom,current-setting = <5>;
+ qcom,id = <6>;
+ qcom,mode = "manual";
+ qcom,source-sel = <1>;
+ qcom,mode-ctrl = <0x60>;
+ };
+ };
+
+ qcom,leds@a300 {
+ compatible = "qcom,leds-qpnp";
+ reg = <0xa300 0x100>;
+ label = "mpp";
+
+ qcom,led_mpp_4 {
+ label = "mpp";
+ linux,name = "blue";
+ linux,default-trigger = "none";
+ qcom,default-state = "off";
+ qcom,max-current = <40>;
+ qcom,current-setting = <5>;
+ qcom,id = <6>;
+ qcom,mode = "manual";
+ qcom,source-sel = <1>;
+ qcom,mode-ctrl = <0x60>;
+ };
+ };
+ };
+};
+
+&pm8953_typec {
+ ss-mux-supply = <&pm8953_l13>;
+ qcom,ssmux-gpio = <&tlmm 139 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&typec_ssmux_config>;
+};
+
+/{
+ mtp_batterydata: qcom,battery-data {
+ qcom,batt-id-range-pct = <15>;
+ #include "batterydata-itech-3000mah.dtsi"
+ #include "batterydata-ascent-3450mAh.dtsi"
+ };
+};
+
+&pmi_haptic{
+ status = "disabled";
+ qcom,actuator-type = "lra";
+ qcom,lra-auto-res-mode="qwd";
+ qcom,lra-high-z="opt1";
+ qcom,lra-res-cal-period = <0>;
+ qcom,wave-play-rate-us = <4165>;
+};
+
+&flash_led {
+ status = "disabled";
+};
+
+&pm8953_pwm {
+ status = "ok";
+};
+
+&pm8953_vadc {
+ /delete-node/ chan@13;
+};
+
+&pmi8950_gpios {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmi_gpio1_default>;
+ pmi_gpio1_default: pmi8950_gpio1 {
+ pins = "gpio1";
+ function = "normal";
+ input-enable;
+ power-source = <0>;
+ status = "okay";
+ };
+};
+
+&pmi8950_mpps {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ext_fet_wled_pwr_en_default>;
+ ext_fet_wled_pwr_en_default: pmi8950_mpp3 {
+ pins = "mpp3"; /* MPP_3 */
+ function = "digital"; /* Digital */
+ output-high; /* Output */
+ drive-strength = <2>; /* 1.8 mA */
+ power-source = <1>;
+ bias-disable = <0>; /* no pull */
+ status = "okay";
+ };
+};
+
+&pm8953_gpios {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pm_gpio1_div_clk2_default>;
+ pm_gpio1_div_clk2_default: pm8953_gpio1 {
+ pins = "gpio1";
+ function = "normal";
+ output-high;
+ power-source = <1>;
+ status = "okay";
+ };
+};
+
+&pm8953_mpps {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pm_mpp4_wled_pwm_ctrl_default>;
+ pm_mpp4_wled_pwm_ctrl_default: pm8953_mpp4 {
+ pins = "mpp4"; /* WLED_PWM_CTRL */
+ function = "digital"; /* Digital */
+ output-high; /* Output */
+ drive-strength = <2>; /* 1.8 mA */
+ power-source = <0>; /* VPH_PWR */
+ qcom,dtest = <1>; /* DTEST1 */
+ bias-disable = <0>; /* no pull */
+ status = "okay";
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/apq8053-lite-dragon.dtsi b/arch/arm64/boot/dts/qcom/apq8053-lite-dragon.dtsi
index 41152d2..3f0bc28 100644
--- a/arch/arm64/boot/dts/qcom/apq8053-lite-dragon.dtsi
+++ b/arch/arm64/boot/dts/qcom/apq8053-lite-dragon.dtsi
@@ -104,22 +104,6 @@
pinctrl-1 = <&sec_tlmm_lines_sus &ext_amp_ctrl_sleep>;
};
- gpio_keys {
- compatible = "gpio-keys";
- input-name = "gpio-keys";
- pinctrl-names = "default";
- pinctrl-0 = <&gpio_key_active>;
- vol_up {
- label = "volume_up";
- gpios = <&tlmm 85 0x1>;
- linux,input-type = <1>;
- linux,code = <115>;
- debounce-interval = <15>;
- linux,can-disable;
- gpio-key,wakeup;
- };
- };
-
qcom,rmnet-ipa {
status = "disabled";
};
@@ -408,6 +392,14 @@
};
&spmi_bus {
+ qcom,pm8953@0 {
+ qcom,power-on@800 {
+ qcom,resin-gpiobase = <1019>;
+ qcom,pon_2 {
+ /delete-property/ linux,code;
+ };
+ };
+ };
qcom,pmi8950@2 {
qcom,leds@a100 {
compatible = "qcom,leds-qpnp";
diff --git a/arch/arm64/boot/dts/qcom/apq8053-lite-som.dts b/arch/arm64/boot/dts/qcom/apq8053-lite-som.dts
index fa51fd2..684833c 100644
--- a/arch/arm64/boot/dts/qcom/apq8053-lite-som.dts
+++ b/arch/arm64/boot/dts/qcom/apq8053-lite-som.dts
@@ -108,6 +108,23 @@
pinctrl-0 = <&sec_tlmm_lines_act &ext_amp_ctrl_active>;
pinctrl-1 = <&sec_tlmm_lines_sus &ext_amp_ctrl_sleep>;
};
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ input-name = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_key_active>;
+ vol_up {
+ label = "volume_up";
+ gpios = <&tlmm 85 0x1>;
+ linux,input-type = <1>;
+ linux,code = <115>;
+ debounce-interval = <15>;
+ linux,can-disable;
+ gpio-key,wakeup;
+ };
+ };
+
};
&cdc_pdm_comp_lines_act {
@@ -304,14 +321,6 @@
};
&spmi_bus {
- qcom,pm8953@0 {
- qcom,power-on@800 {
- qcom,resin-gpiobase = <1019>;
- qcom,pon_2 {
- /delete-property/ linux,code;
- };
- };
- };
qcom,pmi8950@2 {
qcom,leds@a100 {
compatible = "qcom,leds-qpnp";
diff --git a/arch/arm64/boot/dts/qcom/dsi-panel-390p-auo-cmd.dtsi b/arch/arm64/boot/dts/qcom/dsi-panel-390p-auo-cmd.dtsi
index 06fc5a4..87a5253 100644
--- a/arch/arm64/boot/dts/qcom/dsi-panel-390p-auo-cmd.dtsi
+++ b/arch/arm64/boot/dts/qcom/dsi-panel-390p-auo-cmd.dtsi
@@ -37,6 +37,7 @@
qcom,mdss-dsi-underflow-color = <0xff>;
qcom,mdss-dsi-border-color = <0>;
qcom,mdss-tear-check-frame-rate = <4500>;
+ qcom,mdss-dsi-idle-fps = <10>;
qcom,mdss-dsi-on-command = [
15 01 00 00 00 00 02 fe 01
15 01 00 00 00 00 02 0a f0
diff --git a/arch/arm64/boot/dts/qcom/dsi-panel-osd-disp-fwvga-video.dtsi b/arch/arm64/boot/dts/qcom/dsi-panel-osd-disp-fwvga-video.dtsi
new file mode 100644
index 0000000..0967a50
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/dsi-panel-osd-disp-fwvga-video.dtsi
@@ -0,0 +1,97 @@
+/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&mdss_mdp {
+ dsi_osd_disp_fwvga_video: qcom,mdss_dsi_osd_disp_fwvga_video {
+ qcom,mdss-dsi-panel-name =
+ "OSD Displays fwvga video mode dsi panel";
+ qcom,mdss-dsi-panel-controller = <&mdss_dsi0>;
+ qcom,mdss-dsi-panel-type = "dsi_video_mode";
+ qcom,mdss-dsi-panel-destination = "display_1";
+ qcom,mdss-dsi-panel-framerate = <60>;
+ qcom,mdss-dsi-virtual-channel-id = <0>;
+ qcom,mdss-dsi-stream = <0>;
+ qcom,mdss-dsi-panel-width = <480>;
+ qcom,mdss-dsi-panel-height = <854>;
+ qcom,mdss-dsi-h-front-porch = <70>;
+ qcom,mdss-dsi-h-back-porch = <70>;
+ qcom,mdss-dsi-h-pulse-width = <70>;
+ qcom,mdss-dsi-h-sync-skew = <0>;
+ qcom,mdss-dsi-v-back-porch = <10>;
+ qcom,mdss-dsi-v-front-porch = <10>;
+ qcom,mdss-dsi-v-pulse-width = <20>;
+ qcom,mdss-dsi-h-left-border = <0>;
+ qcom,mdss-dsi-h-right-border = <0>;
+ qcom,mdss-dsi-v-top-border = <0>;
+ qcom,mdss-dsi-v-bottom-border = <0>;
+ qcom,mdss-dsi-bpp = <24>;
+ qcom,mdss-dsi-color-order = <0>;
+ qcom,mdss-dsi-underflow-color = <0xff>;
+ qcom,mdss-dsi-border-color = <0>;
+ qcom,ulps-enabled;
+ qcom,mdss-dsi-on-command = [
+ 39 01 00 00 01 00 04 BF 91 61 F2
+ 39 01 00 00 01 00 03 B3 00 9B
+ 39 01 00 00 01 00 03 B4 00 9B
+ 39 01 00 00 01 00 02 C3 04
+ 39 01 00 00 01 00 07 B8 00 6F 01 00 6F 01
+ 39 01 00 00 01 00 04 BA 34 23 00
+ 39 01 00 00 01 00 03 C4 30 6A
+ 39 01 00 00 01 00 0A C7 00 01 32 05 65 2A 12 A5 A5
+ 39 01 00 00 01 00 27 C8 7F 6A 5A 4E 49 39 3B 23 37
+ 32 2F 49 35 3B 31 2B 1E 0F 00 7F 6A 5A 4E
+ 49 39 3B 23 37 32 2F 49 35 3B 31 2B 1E 0F 00
+ 39 01 00 00 01 00 11 D4 1E 1F 1F 1F 06 04 0A 08 00
+ 02 1F 1F 1F 1F 1F 1F
+ 39 01 00 00 01 00 11 D5 1E 1F 1F 1F 07 05 0B 09 01
+ 03 1F 1F 1F 1F 1F 1F
+ 39 01 00 00 01 00 11 D6 1F 1E 1F 1F 07 09 0B 05 03
+ 01 1F 1F 1F 1F 1F 1F
+ 39 01 00 00 01 00 11 D7 1F 1E 1F 1F 06 08 0A 04 02
+ 00 1F 1F 1F 1F 1F 1F
+ 39 01 00 00 01 00 15 D8 20 00 00 30 08 20 01 02 00
+ 01 02 06 7B 00 00 72 0A 0E 49 08
+ 39 01 00 00 01 00 14 D9 00 0A 0A 89 00 00 06 7B 00
+ 00 00 3B 33 1F 00 00 00 03 7B
+ 05 01 00 00 01 00 02 35 00
+ 39 01 00 00 01 00 02 BE 01
+ 39 01 00 00 01 00 02 C1 10
+ 39 01 00 00 01 00 0B CC 34 20 38 60 11 91 00 40 00 00
+ 39 01 00 00 01 00 02 BE 00
+ 05 01 00 00 01 00 02 11 00
+ 05 01 00 00 01 00 02 29 00];
+ qcom,mdss-dsi-off-command = [
+ 05 01 00 00 01 00 02 28 00
+ 05 01 00 00 01 00 02 10 00];
+ qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
+ qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
+ qcom,mdss-dsi-h-sync-pulse = <1>;
+ qcom,mdss-dsi-traffic-mode = "burst_mode";
+ qcom,mdss-dsi-bllp-eof-power-mode;
+ qcom,mdss-dsi-bllp-power-mode;
+ qcom,mdss-dsi-lane-0-state;
+ qcom,mdss-dsi-lane-1-state;
+ qcom,mdss-dsi-panel-timings =
+ [7F 1C 12 00 40 44 16 1E 17 03 04 00];
+ qcom,mdss-dsi-t-clk-post = <0x20>;
+ qcom,mdss-dsi-t-clk-pre = <0x2C>;
+ qcom,mdss-dsi-bl-min-level = <1>;
+ qcom,mdss-dsi-bl-max-level = <4095>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_pwm";
+ qcom,mdss-dsi-bl-pmic-pwm-frequency = <100>;
+ qcom,mdss-dsi-bl-pmic-bank-select = <0>;
+ qcom,mdss-dsi-pwm-gpio = <&pm8916_mpps 4 0>;
+ qcom,mdss-dsi-dma-trigger = "trigger_sw";
+ qcom,mdss-dsi-mdp-trigger = "none";
+ qcom,mdss-dsi-reset-sequence = <1 20>, <0 20>, <1 20>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/fg-gen3-batterydata-vrcamera-1300mah.dtsi b/arch/arm64/boot/dts/qcom/fg-gen3-batterydata-vrcamera-1300mah.dtsi
index 0676019..3b3cf17 100644
--- a/arch/arm64/boot/dts/qcom/fg-gen3-batterydata-vrcamera-1300mah.dtsi
+++ b/arch/arm64/boot/dts/qcom/fg-gen3-batterydata-vrcamera-1300mah.dtsi
@@ -14,10 +14,13 @@
/* #kayo_1300mah_averaged_masterslave_feb26th2018 */
qcom,max-voltage-uv = <4200000>;
qcom,nom-batt-capacity-mah = <1300>;
+ qcom,fastchg-current-ma = <2600>;
qcom,batt-id-kohm = <100>;
- qcom,jeita-fcc-ranges = <0 100 975000
- 101 450 1300000
- 451 600 1105000>;
+ qcom,jeita-fcc-ranges = <0 100 260000
+ 101 200 650000
+ 201 450 2600000
+ 451 500 650000
+ 501 600 260000>;
qcom,jeita-fv-ranges = <0 100 4000000
101 200 4100000
201 450 4200000
diff --git a/arch/arm64/boot/dts/qcom/msm-arm-smmu-8909.dtsi b/arch/arm64/boot/dts/qcom/msm-arm-smmu-8909.dtsi
index b506fb4..a6c7266 100644
--- a/arch/arm64/boot/dts/qcom/msm-arm-smmu-8909.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm-arm-smmu-8909.dtsi
@@ -36,13 +36,10 @@
<GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>;
-
- vdd-supply = <&gdsc_oxili_gx>;
- qcom,regulator-names = "vdd";
clocks =
- <&clock_gcc clk_gcc_oxili_ahb_clk>,
- <&clock_gcc clk_gcc_bimc_gfx_clk>;
- clock-names = "gpu_ahb_clk", "gcc_bimc_gfx_clk";
+ <&clock_gcc clk_gcc_smmu_cfg_clk>,
+ <&clock_gcc clk_gcc_gfx_tcu_clk>;
+ clock-names = "iface_clk", "core_clk";
};
/* A test device to test the SMMU operation */
diff --git a/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm670.dtsi b/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm670.dtsi
index 707875b..5664d3e 100644
--- a/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm670.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm670.dtsi
@@ -25,6 +25,7 @@
#global-interrupts = <2>;
qcom,regulator-names = "vdd";
vdd-supply = <&gpu_cx_gdsc>;
+ qcom,deferred-regulator-disable-delay = <80>;
interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 231 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 364 IRQ_TYPE_LEVEL_HIGH>,
@@ -324,17 +325,8 @@
};
&apps_smmu {
- qcom,actlr = <0x0880 0x8 0x103>,
- <0x0881 0x8 0x103>,
- <0x0c80 0x8 0x103>,
- <0x0c81 0x8 0x103>,
- <0x1090 0x0 0x103>,
- <0x1091 0x0 0x103>,
- <0x10a0 0x8 0x103>,
- <0x10b0 0x0 0x103>,
- <0x10a1 0x8 0x103>,
- <0x10a3 0x8 0x103>,
- <0x10a4 0x8 0x103>,
- <0x10b4 0x0 0x103>,
- <0x10a5 0x8 0x103>;
+ qcom,actlr =
+ /* HF and SF TBUs: +3 deep PF */
+ <0x0800 0x7ff 0x103>,
+ <0x1000 0x3ff 0x103>;
};
diff --git a/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm845.dtsi b/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm845.dtsi
index 0ac9c2a..38dd747 100644
--- a/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm845.dtsi
@@ -346,19 +346,11 @@
};
&apps_smmu {
- qcom,actlr = <0x0880 0x8 0x103>,
- <0x0881 0x8 0x103>,
- <0x0c80 0x8 0x103>,
- <0x0c81 0x8 0x103>,
- <0x1090 0x0 0x103>,
- <0x1091 0x0 0x103>,
- <0x10a0 0x8 0x103>,
- <0x10b0 0x0 0x103>,
- <0x10a1 0x8 0x103>,
- <0x10a3 0x8 0x103>,
- <0x10a4 0x8 0x103>,
- <0x10b4 0x0 0x103>,
- <0x10a5 0x8 0x103>;
+ qcom,actlr =
+ /* HF and SF TBUs: +3 deep PF */
+ <0x0800 0x7ff 0x103>,
+ <0x1000 0x3ff 0x103>;
+
qcom,mmu500-errata-1 = <0x800 0x3ff>,
<0xc00 0x3ff>;
};
diff --git a/arch/arm64/boot/dts/qcom/msm-qvr-external.dtsi b/arch/arm64/boot/dts/qcom/msm-qvr-external.dtsi
new file mode 100644
index 0000000..3b3fc58
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm-qvr-external.dtsi
@@ -0,0 +1,44 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&soc {
+ smp2pgpio_qvrexternal_5_in: qcom,smp2pgpio-qvrexternal-5-in {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "qvrexternal";
+ qcom,remote-pid = <5>;
+ qcom,is-inbound;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ qcom,smp2pgpio_client_qvrexternal_5_in {
+ compatible = "qcom,smp2pgpio_client_qvrexternal_5_in";
+ gpios = <&smp2pgpio_qvrexternal_5_in 0 0>;
+ };
+
+ smp2pgpio_qvrexternal_5_out: qcom,smp2pgpio-qvrexternal-5-out {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "qvrexternal";
+ qcom,remote-pid = <5>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ qcom,smp2pgpio_client_qvrexternal_5_out {
+ compatible = "qcom,smp2pgpio_client_qvrexternal_5_out";
+ gpios = <&smp2pgpio_qvrexternal_5_out 0 0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8909-gpu.dtsi b/arch/arm64/boot/dts/qcom/msm8909-gpu.dtsi
index 96d9ea7..024833a 100644
--- a/arch/arm64/boot/dts/qcom/msm8909-gpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8909-gpu.dtsi
@@ -65,6 +65,7 @@
/* Bus Scale Settings */
qcom,gpubw-dev = <&gpubw>;
+ qcom,bus-control;
qcom,msm-bus,name = "grp3d";
qcom,msm-bus,num-cases = <4>;
qcom,msm-bus,num-paths = <1>;
diff --git a/arch/arm64/boot/dts/qcom/msm8909-mdss.dtsi b/arch/arm64/boot/dts/qcom/msm8909-mdss.dtsi
index 67c6d06..725ef31 100644
--- a/arch/arm64/boot/dts/qcom/msm8909-mdss.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8909-mdss.dtsi
@@ -28,6 +28,21 @@
clock-names = "iface_clk", "bus_clk", "core_clk_src",
"core_clk", "vsync_clk";
+ qcom,regs-dump-mdp = <0x0300 0x0358>,
+ <0x10000 0x101E0>,
+ <0x20004 0x0020044>,
+ <0x90000 0x90074>;
+ qcom,regs-dump-names-mdp = "MDP_SYNC",
+ "PPP","PPP_FETCH",
+ "DMA_P";
+
+ qcom,regs-dump-vbif = <0x0004 0x0010>,
+ <0x0194 0x01b0>,
+ <0x0200 0x020c>;
+
+ qcom,regs-dump-names-vbif = "VBIF_CLK",
+ "VBIF_ERR","VBIF_XIN_HALT";
+
mdss_fb0: qcom,mdss_fb_primary {
cell-index = <0>;
compatible = "qcom,mdss-fb";
diff --git a/arch/arm64/boot/dts/qcom/msm8909-mtp_qseev4.dtsi b/arch/arm64/boot/dts/qcom/msm8909-mtp_qseev4.dtsi
new file mode 100644
index 0000000..420aff7
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8909-mtp_qseev4.dtsi
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&reserved_mem {
+ secure_display_memory: secure_region {
+ compatible = "shared-dma-pool";
+ label = "secure_display_mem";
+ size = <0 0x1400000>;
+ reusable;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8909-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/msm8909-pinctrl.dtsi
index c22259b..656385d 100644
--- a/arch/arm64/boot/dts/qcom/msm8909-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8909-pinctrl.dtsi
@@ -922,6 +922,103 @@
};
};
+ /* add pingrp for goodix touch */
+ ts_int_default: ts_int_default {
+ mux {
+ pins = "gpio13";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio13";
+ drive-strength = <16>;
+ /*bias-pull-up;*/
+ input-enable;
+ bias-disable;
+ };
+ };
+
+ ts_int_output_high: ts_int_output_high {
+ mux {
+ pins = "gpio13";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio13";
+ output-high;
+ };
+ };
+
+ ts_int_output_low: ts_int_output_low {
+ mux {
+ pins = "gpio13";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio13";
+ output-low;
+ };
+ };
+
+ ts_int_input: ts_int_input {
+ mux {
+ pins = "gpio13";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio13";
+ input-enable;
+ bias-disable;
+ };
+ };
+
+ ts_rst_default: ts_rst_default {
+ mux {
+ pins = "gpio16";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio16";
+ drive-strength = <16>;
+ /*bias-pull-up;*/
+ input-enable;
+ bias-disable;
+ };
+ };
+
+ ts_rst_output_high: ts_rst_output_high {
+ mux {
+ pins = "gpio16";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio16";
+ output-high;
+ };
+ };
+
+ ts_rst_output_low: ts_rst_output_low {
+ mux {
+ pins = "gpio16";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio16";
+ output-low;
+ };
+ };
+
+ ts_rst_input: ts_rst_input {
+ mux {
+ pins = "gpio16";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio16";
+ input-enable;
+ bias-disable;
+ };
+ };
+
/* add pingrp for touchscreen */
pmx_ts_int_active {
ts_int_active: ts_int_active {
diff --git a/arch/arm64/boot/dts/qcom/msm8909-pm8916-camera-sensor-robot-pronto.dtsi b/arch/arm64/boot/dts/qcom/msm8909-pm8916-camera-sensor-robot-pronto.dtsi
new file mode 100644
index 0000000..854965e
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8909-pm8916-camera-sensor-robot-pronto.dtsi
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&i2c_3 {
+ status = "ok";
+};
+
+&i2c_3 {
+
+ qcom,camera@1 {
+ cell-index = <1>;
+ compatible = "qcom,camera";
+ reg = <0x1>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <0>;
+ qcom,mount-angle = <90>;
+ cam_vana-supply = <&pm8916_l17>;
+ cam_vio-supply = <&pm8916_l6>;
+ qcom,cam-vreg-name = "cam_vio","cam_vana";
+ qcom,cam-vreg-min-voltage = <1800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1800000 2850000>;
+ qcom,cam-vreg-op-mode = <0 80000>;
+ qcom,cam-vreg-type = <0 0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_default
+ &cam_sensor_rear_default>;
+ pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep>;
+ gpios = <&msm_gpio 26 0>,
+ <&msm_gpio 35 0>,
+ <&msm_gpio 34 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET",
+ "CAM_STANDBY";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk0_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk0_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8909-pm8916-camera-sensor-robot-rome.dtsi b/arch/arm64/boot/dts/qcom/msm8909-pm8916-camera-sensor-robot-rome.dtsi
new file mode 100644
index 0000000..cd720fd
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8909-pm8916-camera-sensor-robot-rome.dtsi
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&i2c_3 {
+ status = "ok";
+};
+
+&i2c_3 {
+ otp_eeprom: qcom,msm_eeprom@6e{
+ status = "ok";
+ cell-index = <0>;
+ reg = <0x6e>;
+ compatible = "msm_eeprom";
+ qcom,eeprom-name = "sunny_imx241_otp";
+ qcom,slave-addr = <0x6e>;
+ qcom,i2c-freq-mode = <1>;
+
+ cam_vdig-supply = <&pm8916_l2>;
+ cam_vio-supply = <&pm8916_l6>;
+ cam_vana-supply = <&pm8916_l17>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana";
+ qcom,cam-vreg-min-voltage = <1200000 1800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 1800000 2850000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000>;
+ qcom,cam-vreg-type = <0 0 0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_default
+ &cam_sensor_rear_default>;
+ pinctrl-1 = <&cam_sensor_mclk0_sleep
+ &cam_sensor_rear_sleep>;
+ gpios = <&msm_gpio 26 0>,
+ <&msm_gpio 35 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-req-tbl-num = <0 1>;
+ qcom,gpio-req-tbl-flags = <1 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK", "CAM_RESET";
+
+ qcom,cam-power-seq-type = "sensor_vreg",
+ "sensor_vreg",
+ "sensor_vreg",
+ "sensor_gpio",
+ "sensor_clk",
+ "sensor_i2c_mux";
+ qcom,cam-power-seq-val = "cam_vana",
+ "cam_vdig",
+ "cam_vio",
+ "sensor_gpio_reset",
+ "sensor_cam_mclk",
+ "none";
+ qcom,cam-power-seq-cfg-val = <2850000 1200000
+ 1800000 1 24000000 0>;
+ qcom,cam-power-seq-delay = <1 1 1 1 1 0>;
+
+ clocks = <&clock_gcc clk_mclk0_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk0_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+
+ qcom,num-blocks = <12>;
+ qcom,page0 = <1 0x34C5 2 0x02 1 1>;
+ qcom,poll0 = <0 0x0 2 0 1 1>;
+ qcom,mem0 = <0 0x0 2 0 1 0>;
+ qcom,page1 = <1 0x34C9 2 0x02 1 10>;
+ qcom,poll1 = <0 0x0 2 0 1 1>;
+ qcom,mem1 = <8 0x3510 2 0 1 0>;
+ qcom,page2 = <1 0x34C5 2 0x03 1 1>;
+ qcom,poll2 = <0 0x0 2 0 1 1>;
+ qcom,mem2 = <0 0x0 2 0 1 0>;
+ qcom,page3 = <1 0x34C9 2 0x03 1 10>;
+ qcom,poll3 = <0 0x0 2 0 1 1>;
+ qcom,mem3 = <8 0x3518 2 0 1 0>;
+ qcom,page4 = <1 0x34C5 2 0x06 1 1>;
+ qcom,poll4 = <0 0x0 2 0 1 1>;
+ qcom,mem4 = <0 0x0 2 0 1 0>;
+ qcom,page5 = <1 0x34C9 2 0x06 1 10>;
+ qcom,poll5 = <0 0x0 2 0 1 1>;
+ qcom,mem5 = <8 0x3530 2 0 1 0>;
+ qcom,page6 = <1 0x34C5 2 0x07 1 1>;
+ qcom,poll6 = <0 0x0 2 0 1 1>;
+ qcom,mem6 = <0 0x0 2 0 1 0>;
+ qcom,page7 = <1 0x34C9 2 0x07 1 10>;
+ qcom,poll7 = <0 0x0 2 0 1 1>;
+ qcom,mem7 = <8 0x3538 2 0 1 0>;
+ qcom,page8 = <1 0x34C5 2 0x0A 1 1>;
+ qcom,poll8 = <0 0x0 2 0 1 1>;
+ qcom,mem8 = <0 0x0 2 0 1 0>;
+ qcom,page9 = <1 0x34C9 2 0x0A 1 10>;
+ qcom,poll9 = <0 0x0 2 0 1 1>;
+ qcom,mem9 = <8 0x3550 2 0 1 0>;
+ qcom,page10 = <1 0x34C5 2 0x0B 1 1>;
+ qcom,poll10 = <0 0x0 2 0 1 1>;
+ qcom,mem10 = <0 0x0 2 0 1 0>;
+ qcom,page11 = <1 0x34C9 2 0x0B 1 10>;
+ qcom,poll11 = <0 0x0 2 0 1 1>;
+ qcom,mem11 = <8 0x3558 2 0 1 0>;
+ };
+
+ qcom,camera@0 {
+ cell-index = <0>;
+ compatible = "qcom,camera";
+ reg = <0x2>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <0>;
+ qcom,mount-angle = <90>;
+ cam_vdig-supply = <&pm8916_l2>;
+ cam_vana-supply = <&pm8916_l17>;
+ cam_vio-supply = <&pm8916_l6>;
+ qcom,cam-vreg-type = <0 0 0>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana";
+ qcom,cam-vreg-min-voltage = <1200000 1800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 1800000 2850000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_default
+ &cam_sensor_rear_default>;
+ pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep>;
+ gpios = <&msm_gpio 26 0>,
+ <&msm_gpio 35 0>,
+ <&msm_gpio 34 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET",
+ "CAM_STANDBY";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
+ qcom,eeprom-src = <&otp_eeprom>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk0_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk0_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8909-pm8916-mtp.dts b/arch/arm64/boot/dts/qcom/msm8909-pm8916-mtp.dts
new file mode 100644
index 0000000..f1caab6
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8909-pm8916-mtp.dts
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2016,2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+#include "msm8909-mtp.dtsi"
+#include "8909-pm8916.dtsi"
+#include "msm8909-pm8916-mtp.dtsi"
+#include "msm8909-mtp_qseev4.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. MSM8909-PM8916 1GB MTP";
+ compatible = "qcom,msm8909-mtp", "qcom,msm8909", "qcom,mtp";
+ qcom,msm-id = <245 0x20000>, <245 0x0>;
+ qcom,board-id= <0x02010008 0x102>;
+ qcom,pmic-id = <0x1000B 0x0 0x0 0x0>;
+};
+
+&pm8916_chg {
+ status = "ok";
+};
+
+&usb_otg {
+ extcon = <&pm8916_chg>;
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8909.dtsi b/arch/arm64/boot/dts/qcom/msm8909.dtsi
index 119d2d2..73760a5 100644
--- a/arch/arm64/boot/dts/qcom/msm8909.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8909.dtsi
@@ -727,6 +727,12 @@
qcom,smdpkt-dev-name = "smdcntl8";
};
+ qcom,smdpkt-data2 {
+ qcom,smdpkt-remote = "modem";
+ qcom,smdpkt-port-name = "DATA2";
+ qcom,smdpkt-dev-name = "at_mdm0";
+ };
+
qcom,smdpkt-apr-apps2 {
qcom,smdpkt-remote = "modem";
qcom,smdpkt-port-name = "apr_apps2";
diff --git a/arch/arm64/boot/dts/qcom/msm8909w-gpu.dtsi b/arch/arm64/boot/dts/qcom/msm8909w-gpu.dtsi
index 7d42127..3bbd283 100644
--- a/arch/arm64/boot/dts/qcom/msm8909w-gpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8909w-gpu.dtsi
@@ -25,6 +25,8 @@
/* To disable GPU wake up on touch event */
qcom,disable-wake-on-touch;
+ qcom,initial-pwrlevel = <0>;
+
/* Bus Scale Settings */
qcom,msm-bus,num-cases = <3>;
qcom,msm-bus,vectors-KBps =
diff --git a/arch/arm64/boot/dts/qcom/msm8917-coresight.dtsi b/arch/arm64/boot/dts/qcom/msm8917-coresight.dtsi
index 87303c5..2ff64d6 100644
--- a/arch/arm64/boot/dts/qcom/msm8917-coresight.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8917-coresight.dtsi
@@ -11,1029 +11,34 @@
* GNU General Public License for more details.
*/
+#include "msm8937-coresight.dtsi"
+
+&funnel_apss {
+ ports {
+ /delete-node/ port@1;
+ /delete-node/ port@2;
+ /delete-node/ port@3;
+ /delete-node/ port@4;
+ };
+};
+
+&funnel_mm {
+ ports {
+ /delete-node/ port@4;
+ };
+};
+
&soc {
- tmc_etr: tmc@6028000 {
- compatible = "arm,primecell";
- reg = <0x6028000 0x1000>,
- <0x6044000 0x15000>;
- reg-names = "tmc-base", "bam-base";
+ /delete-node/ etm@619c000;
+ /delete-node/ etm@619d000;
+ /delete-node/ etm@619e000;
+ /delete-node/ etm@619f000;
+ /delete-node/ cti@6198000;
+ /delete-node/ cti@6199000;
+ /delete-node/ cti@619a000;
+ /delete-node/ cti@619b000;
+};
- interrupts = <0 166 0>;
- interrupt-names = "byte-cntr-irq";
-
- arm,buffer-size = <0x100000>;
- arm,sg-enable;
- qcom,force-reg-dump;
-
- coresight-name = "coresight-tmc-etr";
- coresight-csr = <&csr>;
- coresight-ctis = <&cti0 &cti8>;
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
-
- port {
- tmc_etr_in_replicator: endpoint {
- slave-mode;
- remote-endpoint = <&replicator_out_tmc_etr>;
- };
- };
- };
-
- replicator: replicator@6026000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b909>;
-
- reg = <0x6026000 0x1000>;
- reg-names = "replicator-base";
-
- coresight-name = "coresight-replicator";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- replicator_out_tmc_etr: endpoint {
- remote-endpoint =
- <&tmc_etr_in_replicator>;
- };
- };
-
- port@1 {
- reg = <0>;
- replicator_in_tmc_etf: endpoint {
- slave-mode;
- remote-endpoint =
- <&tmc_etf_out_replicator>;
- };
- };
- };
- };
-
- tmc_etf: tmc@6027000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b961>;
-
- reg = <0x6027000 0x1000>;
- reg-names = "tmc-base";
-
- coresight-name = "coresight-tmc-etf";
- coresight-csr = <&csr>;
-
- arm,default-sink;
- qcom,force-reg-dump;
-
- coresight-ctis = <&cti0 &cti8>;
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- tmc_etf_out_replicator:endpoint {
- remote-endpoint =
- <&replicator_in_tmc_etf>;
- };
- };
-
- port@1 {
- reg = <0>;
- tmc_etf_in_funnel_in0: endpoint {
- slave-mode;
- remote-endpoint =
- <&funnel_in0_out_tmc_etf>;
- };
- };
- };
- };
-
- funnel_in0: funnel@6021000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b908>;
-
- reg = <0x6021000 0x1000>;
- reg-names = "funnel-base";
-
- coresight-name = "coresight-funnel-in0";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- funnel_in0_out_tmc_etf: endpoint {
- remote-endpoint =
- <&tmc_etf_in_funnel_in0>;
- };
- };
-
- port@1 {
- reg = <7>;
- funnel_in0_in_stm: endpoint {
- slave-mode;
- remote-endpoint = <&stm_out_funnel_in0>;
- };
- };
-
- port@2 {
- reg = <6>;
- funnel_in0_in_tpda: endpoint {
- slave-mode;
- remote-endpoint =
- <&tpda_out_funnel_in0>;
- };
- };
-
- port@3 {
- reg = <3>;
- funnel_in0_in_funnel_center: endpoint {
- slave-mode;
- remote-endpoint =
- <&funnel_center_out_funnel_in0>;
- };
- };
-
- port@4 {
- reg = <4>;
- funnel_in0_in_funnel_right: endpoint {
- slave-mode;
- remote-endpoint =
- <&funnel_right_out_funnel_in0>;
- };
- };
-
- port@5 {
- reg = <5>;
- funnel_in0_in_funnel_mm: endpoint {
- slave-mode;
- remote-endpoint =
- <&funnel_mm_out_funnel_in0>;
- };
- };
- };
- };
-
- funnel_mm: funnel@6130000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b908>;
-
- reg = <0x6130000 0x1000>;
- reg-names = "funnel-base";
-
- coresight-name = "coresight-funnel-mm";
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- funnel_mm_out_funnel_in0: endpoint {
- remote-endpoint =
- <&funnel_in0_in_funnel_mm>;
- };
- };
-
- port@1 {
- reg = <0>;
- funnel_mm_in_wcn_etm0: endpoint {
- slave-mode;
- remote-endpoint =
- <&wcn_etm0_out_funnel_mm>;
- };
- };
-
- port@2 {
- reg = <4>;
- funnel_mm_in_funnel_cam: endpoint {
- slave-mode;
- remote-endpoint =
- <&funnel_cam_out_funnel_mm>;
- };
- };
-
- port@3 {
- reg = <5>;
- funnel_mm_in_audio_etm0: endpoint {
- slave-mode;
- remote-endpoint =
- <&audio_etm0_out_funnel_mm>;
- };
- };
- };
- };
-
- funnel_center: funnel@6100000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b908>;
-
- reg = <0x6100000 0x1000>;
- reg-names = "funnel-base";
-
- coresight-name = "coresight-funnel-center";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- funnel_center_out_funnel_in0: endpoint {
- remote-endpoint =
- <&funnel_in0_in_funnel_center>;
- };
- };
-
- port@1 {
- reg = <0>;
- funnel_center_in_rpm_etm0: endpoint {
- slave-mode;
- remote-endpoint =
- <&rpm_etm0_out_funnel_center>;
- };
- };
-
- port@2 {
- reg = <2>;
- funnel_center_in_dbgui: endpoint {
- slave-mode;
- remote-endpoint =
- <&dbgui_out_funnel_center>;
- };
- };
- };
- };
-
- funnel_right: funnel@6120000 {
- compatible = "arm,primecell";
-
- reg = <0x6120000 0x1000>;
- reg-names = "funnel-base";
-
- coresight-name = "coresight-funnel-right";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- funnel_right_out_funnel_in0: endpoint {
- remote-endpoint =
- <&funnel_in0_in_funnel_right>;
- };
- };
-
- port@1 {
- reg = <1>;
- funnel_right_in_modem_etm0: endpoint {
- slave-mode;
- remote-endpoint =
- <&modem_etm0_out_funnel_right>;
- };
- };
-
- port@2 {
- reg = <2>;
- funnel_right_in_funnel_apss: endpoint {
- slave-mode;
- remote-endpoint =
- <&funnel_apss_out_funnel_right>;
- };
- };
- };
- };
-
- funnel_cam: funnel@6132000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b908>;
-
- reg = <0x6132000 0x1000>;
- reg-names = "funnel-base";
-
- coresight-name = "coresight-funnel-cam";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
-
- port {
- funnel_cam_out_funnel_mm: endpoint {
- remote-endpoint = <&funnel_mm_in_funnel_cam>;
- };
- };
- };
-
- funnel_apss: funnel@61a1000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b908>;
-
- reg = <0x61a1000 0x1000>;
- reg-names = "funnel-base";
-
- coresight-name = "coresight-funnel-apss";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- funnel_apss_out_funnel_right: endpoint {
- remote-endpoint =
- <&funnel_right_in_funnel_apss>;
- };
- };
-
- port@1 {
- reg = <0>;
- funnel_apss0_in_etm0: endpoint {
- slave-mode;
- remote-endpoint =
- <&etm0_out_funnel_apss0>;
- };
- };
-
- port@2 {
- reg = <1>;
- funnel_apss0_in_etm1: endpoint {
- slave-mode;
- remote-endpoint =
- <&etm1_out_funnel_apss0>;
- };
- };
-
- port@3 {
- reg = <2>;
- funnel_apss0_in_etm2: endpoint {
- slave-mode;
- remote-endpoint =
- <&etm2_out_funnel_apss0>;
- };
- };
-
- port@4 {
- reg = <3>;
- funnel_apss0_in_etm3: endpoint {
- slave-mode;
- remote-endpoint =
- <&etm3_out_funnel_apss0>;
- };
- };
- };
- };
-
- etm0: etm@61bc000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x000bb95d>;
-
- reg = <0x61bc000 0x1000>;
- cpu = <&CPU0>;
- reg-names = "etm-base";
-
- coresight-name = "coresight-etm0";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
- port {
- etm0_out_funnel_apss0: endpoint {
- remote-endpoint = <&funnel_apss0_in_etm0>;
- };
- };
- };
-
- etm1: etm@61bd000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x000bb95d>;
-
- reg = <0x61bd000 0x1000>;
- cpu = <&CPU1>;
- coresight-name = "coresight-etm1";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
-
- port {
- etm1_out_funnel_apss0: endpoint {
- remote-endpoint = <&funnel_apss0_in_etm1>;
- };
- };
- };
-
- etm2: etm@61be000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x000bb95d>;
-
- reg = <0x61be000 0x1000>;
- cpu = <&CPU2>;
- coresight-name = "coresight-etm2";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
-
- port {
- etm2_out_funnel_apss0: endpoint {
- remote-endpoint = <&funnel_apss0_in_etm2>;
- };
- };
- };
-
- etm3: etm@61bf000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x000bb95d>;
-
- reg = <0x61bf000 0x1000>;
- cpu = <&CPU3>;
- coresight-name = "coresight-etm3";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
-
- port {
- etm3_out_funnel_apss0: endpoint {
- remote-endpoint = <&funnel_apss0_in_etm3>;
- };
- };
- };
-
- stm: stm@6002000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b962>;
-
- reg = <0x6002000 0x1000>,
- <0x9280000 0x180000>;
- reg-names = "stm-base", "stm-data-base";
-
- coresight-name = "coresight-stm";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
-
- port {
- stm_out_funnel_in0: endpoint {
- remote-endpoint = <&funnel_in0_in_stm>;
- };
- };
- };
-
- cti0: cti@6010000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b966>;
-
- reg = <0x6010000 0x1000>;
- reg-names = "cti-base";
-
- coresight-name = "coresight-cti0";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
- };
-
- cti1: cti@6011000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b966>;
-
- reg = <0x6011000 0x1000>;
- reg-names = "cti-base";
-
- coresight-name = "coresight-cti1";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
- };
-
- cti2: cti@6012000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b966>;
-
- reg = <0x6012000 0x1000>;
- reg-names = "cti-base";
-
- coresight-name = "coresight-cti2";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
- };
-
- cti3: cti@6013000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b966>;
-
- reg = <0x6013000 0x1000>;
- reg-names = "cti-base";
-
- coresight-name = "coresight-cti3";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
- };
-
- cti4: cti@6014000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b966>;
-
- reg = <0x6014000 0x1000>;
- reg-names = "cti-base";
-
- coresight-name = "coresight-cti4";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
- };
-
- cti5: cti@6015000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b966>;
-
- reg = <0x6015000 0x1000>;
- reg-names = "cti-base";
-
- coresight-name = "coresight-cti5";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
- };
-
- cti6: cti@6016000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b966>;
-
- reg = <0x6016000 0x1000>;
- reg-names = "cti-base";
-
- coresight-name = "coresight-cti6";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
- };
-
- cti7: cti@6017000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b966>;
-
- reg = <0x6017000 0x1000>;
- reg-names = "cti-base";
-
- coresight-name = "coresight-cti7";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
- };
-
- cti8: cti@6018000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b966>;
-
- reg = <0x6018000 0x1000>;
- reg-names = "cti-base";
-
- coresight-name = "coresight-cti8";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
- };
-
- cti9: cti@6019000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b966>;
-
- reg = <0x6019000 0x1000>;
- reg-names = "cti-base";
-
- coresight-name = "coresight-cti9";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
- };
-
- cti10: cti@601a000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b966>;
-
- reg = <0x601a000 0x1000>;
- reg-names = "cti-base";
-
- coresight-name = "coresight-cti10";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
- };
-
- cti11: cti@601b000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b966>;
-
- reg = <0x601b000 0x1000>;
- reg-names = "cti-base";
-
- coresight-name = "coresight-cti11";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
- };
-
- cti12: cti@601c000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b966>;
-
- reg = <0x601c000 0x1000>;
- reg-names = "cti-base";
-
- coresight-name = "coresight-cti12";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
- };
-
- cti13: cti@601d000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b966>;
-
- reg = <0x601d000 0x1000>;
- reg-names = "cti-base";
-
- coresight-name = "coresight-cti13";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
- };
-
- cti14: cti@601e000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b966>;
-
- reg = <0x601e000 0x1000>;
- reg-names = "cti-base";
-
- coresight-name = "coresight-cti14";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
- };
-
- cti15: cti@601f000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b966>;
-
- reg = <0x601f000 0x1000>;
- reg-names = "cti-base";
-
- coresight-name = "coresight-cti15";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
- };
-
- cti_cpu0: cti@61b8000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b966>;
-
- reg = <0x61b8000 0x1000>;
- reg-names = "cti-base";
-
- coresight-name = "coresight-cti-cpu0";
- cpu = <&CPU0>;
- qcom,cti-save;
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
- };
-
- cti_cpu1: cti@61b9000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b966>;
-
- reg = <0x61b9000 0x1000>;
- reg-names = "cti-base";
-
- coresight-name = "coresight-cti-cpu1";
- cpu = <&CPU1>;
- qcom,cti-save;
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
- };
-
- cti_cpu2: cti@61ba000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b966>;
-
- reg = <0x61ba000 0x1000>;
- reg-names = "cti-base";
-
- coresight-name = "coresight-cti-cpu2";
- cpu = <&CPU2>;
- qcom,cti-save;
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
- };
-
- cti_cpu3: cti@61bb000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b966>;
-
- reg = <0x61bb000 0x1000>;
- reg-names = "cti-base";
-
- coresight-name = "coresight-cti-cpu3";
- cpu = <&CPU3>;
- qcom,cti-save;
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
- };
-
- cti_modem_cpu0: cti@6124000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b966>;
-
- reg = <0x6124000 0x1000>;
- reg-names = "cti-base";
-
- coresight-name = "coresight-cti-modem-cpu0";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
- };
-
- /* Proto CTI */
- cti_wcn_cpu0: cti@6139000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b966>;
-
- reg = <0x6139000 0x1000>;
- reg-names = "cti-base";
-
- coresight-name = "coresight-cti-wcn-cpu0";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
- };
-
- /* Venus CTI */
- cti_video_cpu0: cti@6134000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b966>;
-
- reg = <0x6134000 0x1000>;
- reg-names = "cti-base";
-
- coresight-name = "coresight-cti-video-cpu0";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
- };
-
- /* LPASS CTI */
- cti_audio_cpu0: cti@613c000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b966>;
-
- reg = <0x613c000 0x1000>;
- reg-names = "cti-base";
-
- coresight-name = "coresight-cti-audio-cpu0";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
- };
-
- /* RPM CTI */
- cti_rpm_cpu0: cti@610c000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b966>;
-
- reg = <0x610c000 0x1000>;
- reg-names = "cti-base";
-
- coresight-name = "coresight-cti-rpm-cpu0";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
- };
-
- /* Proto ETM */
- wcn_etm0 {
- compatible = "qcom,coresight-remote-etm";
- coresight-name = "coresight-wcn-etm0";
- qcom,inst-id = <3>;
-
- port {
- wcn_etm0_out_funnel_mm: endpoint {
- remote-endpoint = <&funnel_mm_in_wcn_etm0>;
- };
- };
- };
-
- rpm_etm0 {
- compatible = "qcom,coresight-remote-etm";
- coresight-name = "coresight-rpm-etm0";
- qcom,inst-id = <4>;
-
- port {
- rpm_etm0_out_funnel_center: endpoint {
- remote-endpoint = <&funnel_center_in_rpm_etm0>;
- };
- };
- };
-
- /* LPASS ETM */
- audio_etm0 {
- compatible = "qcom,coresight-remote-etm";
- coresight-name = "coresight-audio-etm0";
- qcom,inst-id = <5>;
-
- port {
- audio_etm0_out_funnel_mm: endpoint {
- remote-endpoint = <&funnel_mm_in_audio_etm0>;
- };
- };
- };
-
- modem_etm0 {
- compatible = "qcom,coresight-remote-etm";
- coresight-name = "coresight-modem-etm0";
- qcom,inst-id = <11>;
-
- port {
- modem_etm0_out_funnel_right: endpoint {
- remote-endpoint = <&funnel_right_in_modem_etm0>;
- };
- };
- };
-
- csr: csr@6001000 {
- compatible = "qcom,coresight-csr";
- reg = <0x6001000 0x1000>;
- reg-names = "csr-base";
-
- coresight-name = "coresight-csr";
-
- qcom,usb-bam-support;
- qcom,hwctrl-set-support;
- qcom,set-byte-cntr-support;
-
- qcom,blk-size = <1>;
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
- };
-
- dbgui: dbgui@6108000 {
- compatible = "qcom,coresight-dbgui";
- reg = <0x6108000 0x1000>;
- reg-names = "dbgui-base";
-
- coresight-name = "coresight-dbgui";
-
- qcom,dbgui-addr-offset = <0x30>;
- qcom,dbgui-data-offset = <0x130>;
- qcom,dbgui-size = <32>;
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
-
- port {
- dbgui_out_funnel_center: endpoint {
- remote-endpoint = <&funnel_center_in_dbgui>;
- };
- };
- };
-
- tpda: tpda@6003000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b969>;
-
- reg = <0x6003000 0x1000>;
- reg-names = "tpda-base";
-
- coresight-name = "coresight-tpda";
-
- qcom,tpda-atid = <64>;
- qcom,cmb-elem-size = <0 32>;
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- tpda_out_funnel_in0: endpoint {
- remote-endpoint = <&funnel_in0_in_tpda>;
- };
- };
-
- port@1 {
- reg = <0>;
- tpda_in_tpdm_dcc: endpoint {
- slave-mode;
- remote-endpoint =
- <&tpdm_dcc_out_tpda>;
- };
- };
- };
- };
-
- tpdm_dcc: tpdm@6110000 {
- compatible = "arm,primecell";
- arm,primecell-periphid = <0x0003b968>;
-
- reg = <0x6110000 0x1000>;
- reg-names = "tpdm-base";
-
- coresight-name = "coresight-tpdm-dcc";
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
-
- port {
- tpdm_dcc_out_tpda: endpoint {
- remote-endpoint = <&tpda_in_tpdm_dcc>;
- };
- };
- };
-
- hwevent: hwevent@6101000 {
- compatible = "qcom,coresight-hwevent";
- reg = <0x6101000 0x148>,
- <0x6101fb0 0x4>,
- <0x6121000 0x148>,
- <0x6121fb0 0x4>,
- <0x6131000 0x148>,
- <0x6131fb0 0x4>,
- <0x78c5010 0x4>,
- <0x7885010 0x4>;
- reg-names = "center-wrapper-mux", "center-wrapper-lockaccess",
- "right-wrapper-mux", "right-wrapper-lockaccess",
- "mm-wrapper-mux", "mm-wrapper-lockaccess",
- "usbbam-mux", "blsp-mux";
-
- coresight-name = "coresight-hwevent";
- coresight-csr = <&csr>;
-
- clocks = <&clock_gcc clk_qdss_clk>,
- <&clock_gcc clk_qdss_a_clk>;
- clock-names = "apb_pclk";
- };
+&dbgui {
+ qcom,dbgui-size = <32>;
};
diff --git a/arch/arm64/boot/dts/qcom/msm8917-cpu.dtsi b/arch/arm64/boot/dts/qcom/msm8917-cpu.dtsi
index 5a242db..7eb4d38 100644
--- a/arch/arm64/boot/dts/qcom/msm8917-cpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8917-cpu.dtsi
@@ -47,7 +47,10 @@
reg = <0x100>;
enable-method = "psci";
cpu-release-addr = <0x0 0x90000000>;
+ efficiency = <1024>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
next-level-cache = <&L2_1>;
+ #cooling-cells = <2>;
L2_1: l2-cache {
compatible = "arm,arch-cache";
cache-level = <2>;
@@ -70,7 +73,10 @@
reg = <0x101>;
enable-method = "psci";
cpu-release-addr = <0x0 0x90000000>;
+ efficiency = <1024>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
next-level-cache = <&L2_1>;
+ #cooling-cells = <2>;
L1_I_101: l1-icache {
compatible = "arm,arch-cache";
qcom,dump-size = <0x8800>;
@@ -87,7 +93,10 @@
reg = <0x102>;
enable-method = "psci";
cpu-release-addr = <0x0 0x90000000>;
+ efficiency = <1024>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
next-level-cache = <&L2_1>;
+ #cooling-cells = <2>;
L1_I_102: l1-icache {
compatible = "arm,arch-cache";
qcom,dump-size = <0x8800>;
@@ -104,7 +113,10 @@
reg = <0x103>;
enable-method = "psci";
cpu-release-addr = <0x0 0x90000000>;
+ efficiency = <1024>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
next-level-cache = <&L2_1>;
+ #cooling-cells = <2>;
L1_I_103: l1-icache {
compatible = "arm,arch-cache";
qcom,dump-size = <0x8800>;
@@ -116,6 +128,35 @@
};
};
+
+ energy_costs: energy-costs {
+ compatible = "sched-energy";
+
+ CPU_COST_0: core-cost0 {
+ busy-cost-data = <
+ 960000 159
+ 1094000 207
+ 1248000 256
+ 1401000 327
+ 1497600 343
+ >;
+ idle-cost-data = <
+ 100 80 60 40
+ >;
+ };
+ CLUSTER_COST_0: cluster-cost0 {
+ busy-cost-data = <
+ 960000 53
+ 1094000 61
+ 1248000 71
+ 1401000 85
+ 1497600 88
+ >;
+ idle-cost-data = <
+ 4 3 2 1
+ >;
+ };
+ };
};
&soc {
diff --git a/arch/arm64/boot/dts/qcom/msm8917-gpu.dtsi b/arch/arm64/boot/dts/qcom/msm8917-gpu.dtsi
index 3b12ba4..6b9de2a 100644
--- a/arch/arm64/boot/dts/qcom/msm8917-gpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8917-gpu.dtsi
@@ -97,6 +97,9 @@
/* CPU latency parameter */
qcom,pm-qos-active-latency = <651>;
+ /* Enable gpu cooling device */
+ #cooling-cells = <2>;
+
/* Power levels */
qcom,gpu-pwrlevels {
#address-cells = <1>;
diff --git a/arch/arm64/boot/dts/qcom/msm8917-thermal.dtsi b/arch/arm64/boot/dts/qcom/msm8917-thermal.dtsi
index 98ad44c..4b3e834 100644
--- a/arch/arm64/boot/dts/qcom/msm8917-thermal.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8917-thermal.dtsi
@@ -12,6 +12,36 @@
#include <dt-bindings/thermal/thermal.h>
+&soc {
+ qmi-tmd-devices {
+ compatible = "qcom,qmi_cooling_devices";
+
+ modem {
+ qcom,instance-id = <0x0>;
+
+ modem_pa: modem_pa {
+ qcom,qmi-dev-name = "pa";
+ #cooling-cells = <2>;
+ };
+
+ modem_proc: modem_proc {
+ qcom,qmi-dev-name = "modem";
+ #cooling-cells = <2>;
+ };
+
+ modem_current: modem_current {
+ qcom,qmi-dev-name = "modem_current";
+ #cooling-cells = <2>;
+ };
+
+ modem_vdd: modem_vdd {
+ qcom,qmi-dev-name = "cpuv_restriction_cold";
+ #cooling-cells = <2>;
+ };
+ };
+ };
+};
+
&thermal_zones {
aoss0-usr {
polling-delay-passive = <0>;
@@ -41,7 +71,7 @@
};
};
- mdss-usr {
+ q6-usr {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-governor = "user_space";
@@ -69,7 +99,7 @@
};
};
- cpuss-0-usr {
+ cpuss-usr {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors = <&tsens0 4>;
@@ -83,7 +113,7 @@
};
};
- apc1-cpu1-usr {
+ apc1-cpu0-usr {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors = <&tsens0 5>;
@@ -97,7 +127,7 @@
};
};
- apc1-cpu2-usr {
+ apc1-cpu1-usr {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors = <&tsens0 6>;
@@ -111,7 +141,7 @@
};
};
- apc1-cpu3-usr {
+ apc1-cpu2-usr {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors = <&tsens0 7>;
@@ -125,7 +155,7 @@
};
};
- apc1-cpu4-usr {
+ apc1-cpu3-usr {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors = <&tsens0 8>;
@@ -152,4 +182,183 @@
};
};
};
+
+ penta-cpu-max-step {
+ polling-delay-passive = <50>;
+ polling-delay = <100>;
+ thermal-governor = "step_wise";
+ trips {
+ cpu_trip:cpu-trip {
+ temperature = <85000>;
+ hysteresis = <0>;
+ type = "passive";
+ };
+ };
+ cooling-maps {
+ cpu0_cdev {
+ trip = <&cpu_trip>;
+ cooling-device =
+ <&CPU0 THERMAL_NO_LIMIT
+ (THERMAL_MAX_LIMIT-1)>;
+ };
+ cpu1_cdev {
+ trip = <&cpu_trip>;
+ cooling-device =
+ <&CPU1 THERMAL_NO_LIMIT
+ (THERMAL_MAX_LIMIT-1)>;
+ };
+ cpu2_cdev {
+ trip = <&cpu_trip>;
+ cooling-device =
+ <&CPU2 THERMAL_NO_LIMIT
+ (THERMAL_MAX_LIMIT-1)>;
+ };
+ cpu3_cdev {
+ trip = <&cpu_trip>;
+ cooling-device =
+ <&CPU3 THERMAL_NO_LIMIT
+ (THERMAL_MAX_LIMIT-1)>;
+ };
+ };
+ };
+
+ gpu0-step {
+ polling-delay-passive = <250>;
+ polling-delay = <0>;
+ thermal-sensors = <&tsens0 9>;
+ thermal-governor = "step_wise";
+ trips {
+ gpu_step_trip: gpu-step-trip {
+ temperature = <95000>;
+ hysteresis = <0>;
+ type = "passive";
+ };
+ };
+ cooling-maps {
+ gpu_cdev0 {
+ trip = <&gpu_step_trip>;
+ cooling-device =
+ <&msm_gpu THERMAL_NO_LIMIT
+ THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ apc1-cpu0-step {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&tsens0 5>;
+ thermal-governor = "step_wise";
+ trips {
+ apc1_cpu0_trip: apc1-cpu0-trip {
+ temperature = <105000>;
+ hysteresis = <15000>;
+ type = "passive";
+ };
+ };
+ cooling-maps {
+ cpu0_cdev {
+ trip = <&apc1_cpu0_trip>;
+ cooling-device =
+ <&CPU0 THERMAL_MAX_LIMIT
+ THERMAL_MAX_LIMIT>;
+ };
+ };
+ };
+
+ apc1-cpu1-step {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&tsens0 6>;
+ thermal-governor = "step_wise";
+ trips {
+ apc1_cpu1_trip: apc1-cpu1--trip {
+ temperature = <105000>;
+ hysteresis = <15000>;
+ type = "passive";
+ };
+ };
+ cooling-maps {
+ cpu1_cdev {
+ trip = <&apc1_cpu1_trip>;
+ cooling-device =
+ <&CPU1 THERMAL_MAX_LIMIT
+ THERMAL_MAX_LIMIT>;
+ };
+ };
+ };
+
+ apc1-cpu2-step {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&tsens0 7>;
+ thermal-governor = "step_wise";
+ trips {
+ apc1_cpu2_trip: apc1-cpu2-trip {
+ temperature = <105000>;
+ hysteresis = <15000>;
+ type = "passive";
+ };
+ };
+ cooling-maps {
+ cpu2_cdev {
+ trip = <&apc1_cpu2_trip>;
+ cooling-device =
+ <&CPU2 THERMAL_MAX_LIMIT
+ THERMAL_MAX_LIMIT>;
+ };
+ };
+ };
+
+ apc1-cpu3-step {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&tsens0 8>;
+ thermal-governor = "step_wise";
+ trips {
+ apc1_cpu3_trip: apc1-cpu3-trip {
+ temperature = <105000>;
+ hysteresis = <15000>;
+ type = "passive";
+ };
+ };
+ cooling-maps {
+ cpu3_cdev {
+ trip = <&apc1_cpu3_trip>;
+ cooling-device =
+ <&CPU3 THERMAL_MAX_LIMIT
+ THERMAL_MAX_LIMIT>;
+ };
+ };
+ };
+
+ aoss0-lowf {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-governor = "low_limits_floor";
+ thermal-sensors = <&tsens0 0>;
+ tracks-low;
+ trips {
+ aoss_lowf: aoss-lowf {
+ temperature = <5000>;
+ hysteresis = <5000>;
+ type = "passive";
+ };
+ };
+ cooling-maps {
+ cpu0_cdev {
+ trip = <&aoss_lowf>;
+ cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2)
+ (THERMAL_MAX_LIMIT-2)>;
+ };
+ cx_vdd_cdev {
+ trip = <&aoss_lowf>;
+ cooling-device = <&pm8937_cx_cdev 0 0>;
+ };
+ modem_vdd_cdev {
+ trip = <&aoss_lowf>;
+ cooling-device = <&modem_vdd 0 0>;
+ };
+ };
+ };
};
diff --git a/arch/arm64/boot/dts/qcom/msm8917.dtsi b/arch/arm64/boot/dts/qcom/msm8917.dtsi
index cb520bd..d66aef6 100644
--- a/arch/arm64/boot/dts/qcom/msm8917.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8917.dtsi
@@ -445,6 +445,7 @@
vdd_dig-supply = <&pm8937_s2_level>;
vdd_hf_dig-supply = <&pm8937_s2_level_ao>;
vdd_hf_pll-supply = <&pm8937_l7_ao>;
+ qcom,gfx3d_clk_src-opp-store-vcorner = <&msm_gpu>;
#clock-cells = <1>;
#reset-cells = <1>;
};
@@ -490,6 +491,13 @@
< 1401000000 4>,
< 1497600000 5>;
+ qcom,speed3-bin-v0-c1 =
+ < 0 0>,
+ < 960000000 1>,
+ < 1094400000 2>,
+ < 1248000000 3>,
+ < 1305600000 4>;
+
#clock-cells = <1>;
};
@@ -506,6 +514,7 @@
< 960000 >,
< 1094400 >,
< 1248000 >,
+ < 1305600 >,
< 1401000 >,
< 1497600 >;
};
@@ -832,9 +841,9 @@
reg = <0x10 8>;
};
- dload_type@18 {
+ dload_type@1c {
compatible = "qcom,msm-imem-dload-type";
- reg = <0x18 4>;
+ reg = <0x1c 4>;
};
restart_reason@65c {
@@ -847,6 +856,11 @@
reg = <0x6b0 32>;
};
+ kaslr_offset@6d0 {
+ compatible = "qcom,msm-imem-kaslr_offset";
+ reg = <0x6d0 12>;
+ };
+
pil@94c {
compatible = "qcom,msm-imem-pil";
reg = <0x94c 200>;
@@ -1722,7 +1736,9 @@
/* GPU overrides */
&msm_gpu {
- qcom,gpu-speed-bin = <0x6018 0x80000000 31>;
+ qcom,gpu-speed-bin-vectors =
+ <0x6018 0x80000000 31>,
+ <0x0164 0x00000400 9>;
/delete-node/qcom,gpu-pwrlevels;
qcom,gpu-pwrlevel-bins {
@@ -1854,5 +1870,49 @@
qcom,bus-max = <0>;
};
};
+
+ qcom,gpu-pwrlevels-2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,speed-bin = <2>;
+ qcom,initial-pwrlevel = <1>;
+
+ /* NOM */
+ qcom,gpu-pwrlevel@0 {
+ reg = <0>;
+ qcom,gpu-freq = <465000000>;
+ qcom,bus-freq = <7>;
+ qcom,bus-min = <5>;
+ qcom,bus-max = <7>;
+ };
+
+ /* SVS+ */
+ qcom,gpu-pwrlevel@1 {
+ reg = <1>;
+ qcom,gpu-freq = <400000000>;
+ qcom,bus-freq = <4>;
+ qcom,bus-min = <3>;
+ qcom,bus-max = <5>;
+ };
+
+ /* SVS */
+ qcom,gpu-pwrlevel@2 {
+ reg = <2>;
+ qcom,gpu-freq = <270000000>;
+ qcom,bus-freq = <3>;
+ qcom,bus-min = <1>;
+ qcom,bus-max = <3>;
+ };
+
+ /* XO */
+ qcom,gpu-pwrlevel@3 {
+ reg = <3>;
+ qcom,gpu-freq = <19200000>;
+ qcom,bus-freq = <0>;
+ qcom,bus-min = <0>;
+ qcom,bus-max = <0>;
+ };
+ };
};
};
diff --git a/arch/arm64/boot/dts/qcom/msm8937-coresight.dtsi b/arch/arm64/boot/dts/qcom/msm8937-coresight.dtsi
index e599b31..8c8f175 100644
--- a/arch/arm64/boot/dts/qcom/msm8937-coresight.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8937-coresight.dtsi
@@ -853,11 +853,11 @@
clock-names = "apb_pclk";
};
- cti_cpu0: cti@6198000{
+ cti_cpu0: cti@61b8000{
compatible = "arm,primecell";
arm,primecell-periphid = <0x0003b966>;
- reg = <0x6198000 0x1000>;
+ reg = <0x61b8000 0x1000>;
reg-names = "cti-base";
coresight-name = "coresight-cti-cpu0";
cpu = <&CPU0>;
@@ -868,11 +868,11 @@
clock-names = "apb_pclk";
};
- cti_cpu1: cti@6199000{
+ cti_cpu1: cti@61b9000{
compatible = "arm,primecell";
arm,primecell-periphid = <0x0003b966>;
- reg = <0x6199000 0x1000>;
+ reg = <0x61b9000 0x1000>;
reg-names = "cti-base";
coresight-name = "coresight-cti-cpu1";
cpu = <&CPU1>;
@@ -883,11 +883,11 @@
clock-names = "apb_pclk";
};
- cti_cpu2: cti@619a000{
+ cti_cpu2: cti@61ba000{
compatible = "arm,primecell";
arm,primecell-periphid = <0x0003b966>;
- reg = <0x619a000 0x1000>;
+ reg = <0x61ba000 0x1000>;
reg-names = "cti-base";
coresight-name = "coresight-cti-cpu2";
cpu = <&CPU2>;
@@ -898,11 +898,11 @@
clock-names = "apb_pclk";
};
- cti_cpu3: cti@619b000{
+ cti_cpu3: cti@61bb000{
compatible = "arm,primecell";
arm,primecell-periphid = <0x0003b966>;
- reg = <0x619b000 0x1000>;
+ reg = <0x61bb000 0x1000>;
reg-names = "cti-base";
coresight-name = "coresight-cti-cpu3";
cpu = <&CPU3>;
@@ -913,11 +913,11 @@
clock-names = "apb_pclk";
};
- cti_cpu4: cti@61b8000{
+ cti_cpu4: cti@6198000{
compatible = "arm,primecell";
arm,primecell-periphid = <0x0003b966>;
- reg = <0x61b8000 0x1000>;
+ reg = <0x6198000 0x1000>;
reg-names = "cti-base";
coresight-name = "coresight-cti-cpu4";
cpu = <&CPU4>;
@@ -928,11 +928,11 @@
clock-names = "apb_pclk";
};
- cti_cpu5: cti@61b9000{
+ cti_cpu5: cti@6199000{
compatible = "arm,primecell";
arm,primecell-periphid = <0x0003b966>;
- reg = <0x61b9000 0x1000>;
+ reg = <0x6199000 0x1000>;
reg-names = "cti-base";
coresight-name = "coresight-cti-cpu5";
cpu = <&CPU5>;
@@ -943,11 +943,11 @@
clock-names = "apb_pclk";
};
- cti_cpu6: cti@61ba000{
+ cti_cpu6: cti@619a000{
compatible = "arm,primecell";
arm,primecell-periphid = <0x0003b966>;
- reg = <0x61ba000 0x1000>;
+ reg = <0x619a000 0x1000>;
reg-names = "cti-base";
coresight-name = "coresight-cti-cpu6";
cpu = <&CPU6>;
@@ -958,11 +958,11 @@
clock-names = "apb_pclk";
};
- cti_cpu7: cti@61bb000{
+ cti_cpu7: cti@619b000{
compatible = "arm,primecell";
arm,primecell-periphid = <0x0003b966>;
- reg = <0x61bb000 0x1000>;
+ reg = <0x619b000 0x1000>;
reg-names = "cti-base";
coresight-name = "coresight-cti-cpu7";
cpu = <&CPU7>;
@@ -1195,7 +1195,7 @@
<0x6121fb0 0x4>,
<0x6131000 0x148>,
<0x6131fb0 0x4>,
- <0x7105010 0x4>,
+ <0x78c5010 0x4>,
<0x7885010 0x4>;
reg-names = "center-wrapper-mux", "center-wrapper-lockaccess",
diff --git a/arch/arm64/boot/dts/qcom/msm8937-interposer-sdm429.dtsi b/arch/arm64/boot/dts/qcom/msm8937-interposer-sdm429.dtsi
index 433ed7c..29f008a 100644
--- a/arch/arm64/boot/dts/qcom/msm8937-interposer-sdm429.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8937-interposer-sdm429.dtsi
@@ -19,10 +19,10 @@
/delete-node/ etm@619d000;
/delete-node/ etm@619e000;
/delete-node/ etm@619f000;
- /delete-node/ cti@61b8000;
- /delete-node/ cti@61b9000;
- /delete-node/ cti@61ba000;
- /delete-node/ cti@61bb000;
+ /delete-node/ cti@6198000;
+ /delete-node/ cti@6199000;
+ /delete-node/ cti@619a000;
+ /delete-node/ cti@619b000;
/delete-node/ jtagmm@619c000;
/delete-node/ jtagmm@619d000;
/delete-node/ jtagmm@619e000;
diff --git a/arch/arm64/boot/dts/qcom/msm8937-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8937-mtp.dtsi
index 90685e9..b0cc91c 100644
--- a/arch/arm64/boot/dts/qcom/msm8937-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8937-mtp.dtsi
@@ -106,6 +106,8 @@
&dsi_truly_1080_vid {
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
qcom,mdss-dsi-pan-enable-dynamic-fps;
+ qcom,mdss-dsi-min-refresh-rate = <48>;
+ qcom,mdss-dsi-max-refresh-rate = <60>;
qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_vfp";
};
diff --git a/arch/arm64/boot/dts/qcom/msm8937.dtsi b/arch/arm64/boot/dts/qcom/msm8937.dtsi
index b440cb60..5006f28 100644
--- a/arch/arm64/boot/dts/qcom/msm8937.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8937.dtsi
@@ -1040,9 +1040,9 @@
reg = <0x10 8>;
};
- dload_type@18 {
+ dload_type@1c {
compatible = "qcom,msm-imem-dload-type";
- reg = <0x18 4>;
+ reg = <0x1c 4>;
};
restart_reason@65c {
diff --git a/arch/arm64/boot/dts/qcom/msm8940-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8940-mtp.dtsi
new file mode 100644
index 0000000..4414279
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8940-mtp.dtsi
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2016, 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "msm8937-mtp.dtsi"
+#include "msm8940-pinctrl.dtsi"
+
+&soc {
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8940-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/msm8940-pinctrl.dtsi
new file mode 100644
index 0000000..55933b9
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8940-pinctrl.dtsi
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2016, 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "msm8937-pinctrl.dtsi"
+
+&soc {
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8940-pmi8937-mtp.dts b/arch/arm64/boot/dts/qcom/msm8940-pmi8937-mtp.dts
new file mode 100644
index 0000000..386badd
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8940-pmi8937-mtp.dts
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2016, 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+#include "msm8940.dtsi"
+#include "msm8940-pmi8937-mtp.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. MSM8940-PMI8937 MTP";
+ compatible = "qcom,msm8940-mtp", "qcom,msm8940", "qcom,mtp";
+ qcom,board-id= <8 0>;
+ qcom,pmic-id = <0x10019 0x020037 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8940-pmi8937-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8940-pmi8937-mtp.dtsi
new file mode 100644
index 0000000..a1e7bcb
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8940-pmi8937-mtp.dtsi
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016, 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "pmi8937.dtsi"
+#include "msm8937-mtp.dtsi"
+#include "msm8940-mtp.dtsi"
+
+&soc {
+ led_flash0: qcom,camera-flash {
+ cell-index = <0>;
+ compatible = "qcom,camera-flash";
+ qcom,flash-type = <1>;
+ qcom,flash-source = <&pmi8937_flash0 &pmi8937_flash1>;
+ qcom,torch-source = <&pmi8937_torch0 &pmi8937_torch1>;
+ qcom,switch-source = <&pmi8937_switch>;
+ };
+};
+
+&vendor {
+ mtp_batterydata: qcom,battery-data {
+ qcom,batt-id-range-pct = <15>;
+ #include "batterydata-itech-3000mah.dtsi"
+ #include "batterydata-ascent-3450mAh.dtsi"
+ };
+};
+
+&qpnp_fg {
+ qcom,battery-data = <&mtp_batterydata>;
+};
+
+&qpnp_smbcharger {
+ qcom,battery-data = <&mtp_batterydata>;
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8940-pmi8940-mtp.dts b/arch/arm64/boot/dts/qcom/msm8940-pmi8940-mtp.dts
new file mode 100644
index 0000000..51a34d4
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8940-pmi8940-mtp.dts
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2016, 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+#include "msm8940.dtsi"
+#include "msm8940-mtp.dtsi"
+#include "msm8940-pmi8940.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. MSM8940-PMI8940 MTP";
+ compatible = "qcom,msm8940-mtp", "qcom,msm8940", "qcom,mtp";
+ qcom,board-id= <8 0>;
+ qcom,pmic-id = <0x10019 0x020040 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8940-pmi8940-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8940-pmi8940-mtp.dtsi
new file mode 100644
index 0000000..3cc12e3
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8940-pmi8940-mtp.dtsi
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2016, 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "msm8937-pmi8940-mtp.dtsi"
+#include "msm8940-mtp.dtsi"
+
+&soc {
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8940-pmi8940.dtsi b/arch/arm64/boot/dts/qcom/msm8940-pmi8940.dtsi
new file mode 100644
index 0000000..d9baeca
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8940-pmi8940.dtsi
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include "pmi8940.dtsi"
+
+&soc {
+ led_flash0: qcom,camera-flash {
+ cell-index = <0>;
+ compatible = "qcom,camera-flash";
+ qcom,flash-type = <1>;
+ qcom,flash-source = <&pmi8940_flash0 &pmi8940_flash1>;
+ qcom,torch-source = <&pmi8940_torch0 &pmi8940_torch1>;
+ qcom,switch-source = <&pmi8940_switch>;
+ };
+};
+
diff --git a/arch/arm64/boot/dts/qcom/msm8940-pmi8950-mtp.dts b/arch/arm64/boot/dts/qcom/msm8940-pmi8950-mtp.dts
new file mode 100644
index 0000000..ff6d208
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8940-pmi8950-mtp.dts
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2016, 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+#include "msm8940.dtsi"
+#include "msm8940-pmi8950-mtp.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. MSM8940-PMI8950 MTP";
+ compatible = "qcom,msm8940-mtp", "qcom,msm8940", "qcom,mtp";
+ qcom,board-id= <8 0>;
+ qcom,pmic-id = <0x10019 0x020011 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8940-pmi8950-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8940-pmi8950-mtp.dtsi
new file mode 100644
index 0000000..5f3f3b7
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8940-pmi8950-mtp.dtsi
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2016, 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "msm8937-pmi8950-mtp.dtsi"
+#include "msm8940-mtp.dtsi"
+
+&soc {
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8940.dtsi b/arch/arm64/boot/dts/qcom/msm8940.dtsi
new file mode 100644
index 0000000..b7a5e02
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8940.dtsi
@@ -0,0 +1,667 @@
+/*
+ * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "skeleton64.dtsi"
+#include "msm8937.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. MSM8940";
+ compatible = "qcom,msm8940";
+ qcom,msm-id = <313 0x0>;
+
+ soc: soc { };
+
+};
+
+&usb_otg {
+
+ /delete-property/ clocks;
+ clocks = <&clock_gcc clk_gcc_usb_hs_ahb_clk>,
+ <&clock_gcc clk_gcc_usb_hs_system_clk>,
+ <&clock_gcc clk_gcc_usb2a_phy_sleep_clk>,
+ <&clock_gcc clk_bimc_usb_clk>,
+ <&clock_gcc clk_snoc_usb_clk>,
+ <&clock_gcc clk_pnoc_usb_clk>,
+ <&clock_gcc clk_gcc_qusb2_phy_clk>,
+ <&clock_gcc clk_gcc_usb2_hs_phy_only_clk>,
+ <&clock_gcc clk_gcc_usb_hs_phy_cfg_ahb_clk>,
+ <&clock_gcc clk_xo_otg_clk>;
+
+ qcom,usbbam@78c4000 {
+ /delete-property/ qcom,reset-bam-on-disconnect;
+ /delete-node/ qcom,pipe0;
+ qcom,pipe0 {
+ label = "hsusb-ipa-out-0";
+ qcom,usb-bam-mem-type = <1>;
+ qcom,dir = <0>;
+ qcom,pipe-num = <0>;
+ qcom,peer-bam = <1>;
+ qcom,src-bam-pipe-index = <1>;
+ qcom,data-fifo-size = <0x8000>;
+ qcom,descriptor-fifo-size = <0x2000>;
+ };
+ qcom,pipe1 {
+ label = "hsusb-ipa-in-0";
+ qcom,usb-bam-mem-type = <1>;
+ qcom,dir = <1>;
+ qcom,pipe-num = <0>;
+ qcom,peer-bam = <1>;
+ qcom,dst-bam-pipe-index = <0>;
+ qcom,data-fifo-size = <0x8000>;
+ qcom,descriptor-fifo-size = <0x2000>;
+ };
+ qcom,pipe2 {
+ label = "hsusb-qdss-in-0";
+ qcom,usb-bam-mem-type = <2>;
+ qcom,dir = <1>;
+ qcom,pipe-num = <0>;
+ qcom,peer-bam = <0>;
+ qcom,peer-bam-physical-address = <0x6044000>;
+ qcom,src-bam-pipe-index = <0>;
+ qcom,dst-bam-pipe-index = <2>;
+ qcom,data-fifo-offset = <0x0>;
+ qcom,data-fifo-size = <0xe00>;
+ qcom,descriptor-fifo-offset = <0xe00>;
+ qcom,descriptor-fifo-size = <0x200>;
+ };
+ qcom,pipe3 {
+ label = "hsusb-dpl-ipa-in-1";
+ qcom,usb-bam-mem-type = <1>;
+ qcom,dir = <1>;
+ qcom,pipe-num = <1>;
+ qcom,peer-bam = <1>;
+ qcom,dst-bam-pipe-index = <3>;
+ qcom,data-fifo-size = <0x8000>;
+ qcom,descriptor-fifo-size = <0x2000>;
+ };
+ };
+};
+
+&ad_hoc_bus {
+ mas_ipa: mas-ipa {
+ cell-id = <MSM_BUS_MASTER_IPA>;
+ label = "mas-ipa";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,ap-owned;
+ qcom,qport = <14>;
+ qcom,qos-mode = "fixed";
+ qcom,connections = <&snoc_int_1 &slv_snoc_bimc_1>;
+ qcom,prio1 = <0>;
+ qcom,prio0 = <0>;
+ qcom,bus-dev = <&fab_snoc>;
+ qcom,mas-rpm-id = <ICBID_MASTER_IPA>;
+ };
+};
+
+&soc {
+ devfreq_spdm_cpu {
+ compatible = "qcom,devfreq_spdm";
+ qcom,bw-dwnstep = <4000>;
+ qcom,max-vote = <4000>;
+ };
+};
+
+&clock_gcc {
+ compatible = "qcom,gcc-8940";
+};
+
+&clock_debug {
+ compatible = "qcom,cc-debug-8940";
+};
+
+&clock_gcc_mdss {
+ compatible = "qcom,gcc-mdss-8940";
+};
+
+&bam_dmux {
+ status = "disabled";
+};
+
+&soc {
+ ipa_hw: qcom,ipa@07900000 {
+ compatible = "qcom,ipa";
+ reg = <0x07900000 0x4effc>, <0x07904000 0x26934>;
+ reg-names = "ipa-base", "bam-base";
+ interrupts = <0 228 0>,
+ <0 230 0>;
+ interrupt-names = "ipa-irq", "bam-irq";
+ qcom,ipa-hw-ver = <6>; /* IPA core version = IPAv2.6L */
+ qcom,ipa-hw-mode = <0>; /* IPA hw type = Normal */
+ qcom,wan-rx-ring-size = <192>; /* IPA WAN-rx-ring-size*/
+ qcom,lan-rx-ring-size = <192>; /* IPA LAN-rx-ring-size*/
+ clock-names = "core_clk";
+ clocks = <&clock_gcc clk_ipa_clk>;
+ qcom,ee = <0>;
+ qcom,use-ipa-tethering-bridge;
+ qcom,modem-cfg-emb-pipe-flt;
+ qcom,msm-bus,name = "ipa";
+ qcom,msm-bus,num-cases = <3>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <90 512 0 0>, /* No BIMC vote (ab=0 Mbps, ib=0 Mbps ~ 0MHZ) */
+ <90 512 100000 800000>, /* SVS (ab=100, ib=800 ~ 50MHz) */
+ <90 512 100000 1200000>; /* PERF (ab=100, ib=1200 ~ 75MHz) */
+ qcom,bus-vector-names = "MIN", "SVS", "PERF";
+ qcom,rx-polling-sleep-ms = <2>; /* Polling sleep interval */
+ qcom,ipa-polling-iteration = <5>; /* Polling Iteration */
+ };
+
+ qcom,rmnet-ipa {
+ compatible = "qcom,rmnet-ipa";
+ qcom,rmnet-ipa-ssr;
+ qcom,ipa-loaduC;
+ qcom,ipa-advertise-sg-support;
+ };
+
+ qcom,rmtfs_sharedmem@00000000 {
+ reg = <0x00000000 0x00180000>;
+ };
+
+ /* remove 8937 MEM ACC node */
+ /delete-node/ regulator@01946004;
+
+ mem_acc_vreg_corner: regulator@01946004 {
+ compatible = "qcom,mem-acc-regulator";
+ reg = <0xa4000 0x1000>;
+ reg-names = "efuse_addr";
+ regulator-name = "mem_acc_corner";
+ regulator-min-microvolt = <1>;
+ regulator-max-microvolt = <3>;
+
+ qcom,acc-reg-addr-list =
+ <0x01942138 0x01942130 0x01942120
+ 0x01942124 0x01942128>;
+
+ qcom,acc-init-reg-config = <1 0xfff>;
+
+ qcom,num-acc-corners = <3>;
+ qcom,boot-acc-corner = <2>;
+ qcom,corner1-reg-config =
+ /* SVS+ => SVS+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => NOM */
+ < 2 0x555555>, < 3 0x1041041>, < 4 0x1041041>,
+ < 5 0x0000041>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => TURBO/NOM+ */
+ < 2 0x555555 >, < 3 0x1041041>, < 4 0x1041041>,
+ < 5 0x0000041>, < 3 0x0>, < 4 0x0>,
+ < 5 0x0>;
+
+ qcom,corner2-reg-config =
+ /* NOM => SVS+ */
+ < 2 0x555555>, < 3 0x30C30C3>, < 4 0x30C30C3>,
+ < 5 0x00000C3>,
+ /* NOM => NOM */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* NOM => TURBO/NOM+ */
+ < 2 0x555555>, < 3 0x0>, < 4 0x0>,
+ < 5 0x0>;
+
+ qcom,corner3-reg-config =
+ /* TURBO/NOM+ => SVS+ */
+ < 2 0x555555>, < 3 0x1041041>, < 4 0x1041041>,
+ < 5 0x0000041>, < 3 0x30C30C3>, < 4 0x30C30C3>,
+ < 5 0x00000C3>,
+ /* TURBO/NOM+ => NOM */
+ < 2 0x555555>, < 3 0x1041041>, < 4 0x1041041>,
+ < 5 0x0000041>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* TURBO/NOM+ => TURBO/NOM+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>;
+
+ qcom,override-acc-range-fuse-list =
+ <37 40 3 0>, /* foundry id */
+ <36 30 8 0>, /* iddq apc on */
+ <67 0 6 0>; /* turbo targ volt */
+
+ qcom,override-fuse-range-map =
+ <0 0>, < 0 0>, <49 63>,
+ <1 1>, < 0 0>, <50 63>,
+ <5 5>, < 0 0>, <51 63>,
+ <0 1>, < 95 255>, < 0 63>,
+ <5 5>, <100 255>, < 0 63>;
+
+ qcom,override-corner1-addr-val-map =
+ /* 1st fuse version tuple matched */
+ /* SVS+ => SVS+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => NOM */
+ < 2 0x555555>, < 3 0x1041041>, < 4 0x1041041>,
+ < 5 0x0000041>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => TURBO/NOM+ */
+ < 2 0x555555 >, < 3 0x1041041>, < 4 0x1041041>,
+ < 5 0x0000041>, < 3 0x1>, < 4 0x1000>,
+ < 5 0x0>,
+
+ /* 2nd fuse version tuple matched */
+ /* SVS+ => SVS+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => NOM */
+ < 2 0x555555>, < 3 0x1041041>, < 4 0x1041041>,
+ < 5 0x0000041>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => TURBO/NOM+ */
+ < 2 0x555555 >, < 3 0x1041041>, < 4 0x1041041>,
+ < 5 0x0000041>, < 3 0x1>, < 4 0x1000>,
+ < 5 0x0>,
+
+ /* 3rd fuse version tuple matched */
+ /* SVS+ => SVS+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => NOM */
+ < 2 0x555555>, < 3 0x1041041>, < 4 0x1041041>,
+ < 5 0x0000041>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => TURBO/NOM+ */
+ < 2 0x555555 >, < 3 0x1041041>, < 4 0x1041041>,
+ < 5 0x0000041>, < 3 0x1>, < 4 0x1000>,
+ < 5 0x0>,
+
+ /* 4th fuse version tuple matched */
+ /* SVS+ => SVS+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => NOM */
+ < 2 0x555555>, < 3 0x1041041>, < 4 0x1041041>,
+ < 5 0x0000041>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => TURBO/NOM+ */
+ < 2 0x555555 >, < 3 0x1041041>, < 4 0x1041041>,
+ < 5 0x0000041>, < 3 0x1>, < 4 0x1000>,
+ < 5 0x0>,
+
+ /* 5th fuse version tuple matched */
+ /* SVS+ => SVS+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => NOM */
+ < 2 0x555555>, < 3 0x1041041>, < 4 0x1041041>,
+ < 5 0x0000041>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => TURBO/NOM+ */
+ < 2 0x555555 >, < 3 0x1041041>, < 4 0x1041041>,
+ < 5 0x0000041>, < 3 0x1>, < 4 0x1000>,
+ < 5 0x0>;
+
+ qcom,override-corner2-addr-val-map =
+ /* 1st fuse version tuple matched */
+ /* NOM => SVS+ */
+ < 2 0x555555>, < 3 0x30C30C3>, < 4 0x30C30C3>,
+ < 5 0x00000C3>,
+ /* NOM => NOM */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* NOM => TURBO/NOM+ */
+ < 2 0x555555>, < 3 0x1>, < 4 0x1000>,
+ < 5 0x0>,
+
+ /* 2nd fuse version tuple matched */
+ /* NOM => SVS+ */
+ < 2 0x555555>, < 3 0x30C30C3>, < 4 0x30C30C3>,
+ < 5 0x00000C3>,
+ /* NOM => NOM */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* NOM => TURBO/NOM+ */
+ < 2 0x555555>, < 3 0x1>, < 4 0x1000>,
+ < 5 0x0>,
+
+ /* 3rd fuse version tuple matched */
+ /* NOM => SVS+ */
+ < 2 0x555555>, < 3 0x30C30C3>, < 4 0x30C30C3>,
+ < 5 0x00000C3>,
+ /* NOM => NOM */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* NOM => TURBO/NOM+ */
+ < 2 0x555555>, < 3 0x1>, < 4 0x1000>,
+ < 5 0x0>,
+
+ /* 4th fuse version tuple matched */
+ /* NOM => SVS+ */
+ < 2 0x555555>, < 3 0x30C30C3>, < 4 0x30C30C3>,
+ < 5 0x00000C3>,
+ /* NOM => NOM */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* NOM => TURBO/NOM+ */
+ < 2 0x555555>, < 3 0x1>, < 4 0x1000>,
+ < 5 0x0>,
+
+ /* 5th fuse version tuple matched */
+ /* NOM => SVS+ */
+ < 2 0x555555>, < 3 0x30C30C3>, < 4 0x30C30C3>,
+ < 5 0x00000C3>,
+ /* NOM => NOM */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* NOM => TURBO/NOM+ */
+ < 2 0x555555>, < 3 0x1>, < 4 0x1000>,
+ < 5 0x0>;
+
+ qcom,override-corner3-addr-val-map =
+ /* 1st fuse version tuple matched */
+ /* TURBO/NOM+ => SVS+ */
+ < 2 0x555555>, < 3 0x1041041>, < 4 0x1041041>,
+ < 5 0x0000041>, < 3 0x30C30C3>, < 4 0x30C30C3>,
+ < 5 0x00000C3>,
+ /* TURBO/NOM+ => NOM */
+ < 2 0x555555>, < 3 0x1041041>, < 4 0x1041041>,
+ < 5 0x0000041>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* TURBO/NOM+ => TURBO/NOM+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+
+ /* 2nd fuse version tuple matched */
+ /* TURBO/NOM+ => SVS+ */
+ < 2 0x555555>, < 3 0x1041041>, < 4 0x1041041>,
+ < 5 0x0000041>, < 3 0x30C30C3>, < 4 0x30C30C3>,
+ < 5 0x00000C3>,
+ /* TURBO/NOM+ => NOM */
+ < 2 0x555555>, < 3 0x1041041>, < 4 0x1041041>,
+ < 5 0x0000041>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* TURBO/NOM+ => TURBO/NOM+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+
+ /* 3rd fuse version tuple matched */
+ /* TURBO/NOM+ => SVS+ */
+ < 2 0x555555>, < 3 0x1041041>, < 4 0x1041041>,
+ < 5 0x0000041>, < 3 0x30C30C3>, < 4 0x30C30C3>,
+ < 5 0x00000C3>,
+ /* TURBO/NOM+ => NOM */
+ < 2 0x555555>, < 3 0x1041041>, < 4 0x1041041>,
+ < 5 0x0000041>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* TURBO/NOM+ => TURBO/NOM+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+
+ /* 4th fuse version tuple matched */
+ /* TURBO/NOM+ => SVS+ */
+ < 2 0x555555>, < 3 0x1041041>, < 4 0x1041041>,
+ < 5 0x0000041>, < 3 0x30C30C3>, < 4 0x30C30C3>,
+ < 5 0x00000C3>,
+ /* TURBO/NOM+ => NOM */
+ < 2 0x555555>, < 3 0x1041041>, < 4 0x1041041>,
+ < 5 0x0000041>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* TURBO/NOM+ => TURBO/NOM+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+
+ /* 5th fuse version tuple matched */
+ /* TURBO/NOM+ => SVS+ */
+ < 2 0x555555>, < 3 0x1041041>, < 4 0x1041041>,
+ < 5 0x0000041>, < 3 0x30C30C3>, < 4 0x30C30C3>,
+ < 5 0x00000C3>,
+ /* TURBO/NOM+ => NOM */
+ < 2 0x555555>, < 3 0x1041041>, < 4 0x1041041>,
+ < 5 0x0000041>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* TURBO/NOM+ => TURBO/NOM+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>;
+ };
+};
+
+&apc_vreg_corner {
+ /delete-property/ qcom,cpr-fuse-version-map;
+ /delete-property/ qcom,cpr-quotient-adjustment;
+ /delete-property/ qcom,cpr-init-voltage-adjustment;
+ /delete-property/ qcom,cpr-enable;
+
+ qcom,pvs-version-fuse-sel = <37 40 3 0>; /* foundry */
+ qcom,cpr-speed-bin-max-corners =
+ <0 (-1) 1 2 6>,
+ <1 (-1) 1 2 7>;
+
+ qcom,cpr-fuse-version-map =
+ < 0 0 (-1) (-1) (-1) (-1)>,
+ < 0 1 (-1) (-1) (-1) (-1)>,
+ < 0 5 (-1) (-1) (-1) (-1)>,
+ < 1 0 (-1) (-1) (-1) (-1)>,
+ < 1 1 (-1) (-1) (-1) (-1)>,
+ < 1 5 (-1) (-1) (-1) (-1)>;
+
+ qcom,cpr-init-voltage-adjustment =
+ <0 0 0>,
+ <0 0 20000>,
+ <0 0 20000>,
+ <0 0 20000>,
+ <0 0 20000>,
+ <0 0 25000>;
+
+ qcom,cpr-quotient-adjustment =
+ <0 0 0>,
+ <38 0 28>, /* SVSP(20mv); TURBO(15mv); KV(1.9) */
+ <0 0 28>, /* TURBO(15mv); KV(1.9) */
+ <0 0 28>, /* TURBO(15mv); KV(1.9) */
+ <38 0 28>, /* SVSP(20mv); TURBO(15mv); KV(1.9) */
+ <0 0 38>; /* TURBO(20mv); KV(1.9) */
+
+ qcom,cpr-enable;
+};
+
+&mdss_mdp {
+ qcom,vbif-settings = <0x0d0 0x00000020>;
+};
+
+&modem_mem {
+ reg = <0x0 0x86800000 0x0 0x6a00000>;
+};
+
+&adsp_fw_mem {
+ reg = <0x0 0x8d200000 0x0 0x1100000>;
+};
+
+&wcnss_fw_mem {
+ reg = <0x0 0x8e300000 0x0 0x700000>;
+};
+
+&pil_mss {
+ /delete-property/ qcom,qdsp6v56-1-8-inrush-current;
+ qcom,qdsp6v56-1-8;
+};
+
+/* GPU overrides */
+&msm_gpu {
+
+ qcom,restrict-pwrlevel = <1>;
+ /delete-property/qcom,gpu-speed-bin;
+ qcom,gpu-speed-bin = <0x0174 0x80000000 31>;
+
+ /delete-property/qcom,initial-pwrlevel;
+ /delete-node/qcom,gpu-pwrlevel-bins;
+ /delete-node/qcom,gpu-pwrlevels;
+
+ qcom,gpu-pwrlevel-bins {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ compatible="qcom,gpu-pwrlevel-bins";
+
+ /* Power levels */
+ qcom,gpu-pwrlevels-0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,speed-bin = <0>;
+ qcom,initial-pwrlevel = <3>;
+
+ /* SUPER TURBO */
+ qcom,gpu-pwrlevel@0 {
+ reg = <0>;
+ qcom,gpu-freq = <475000000>;
+ qcom,bus-freq = <10>;
+ qcom,bus-min = <10>;
+ qcom,bus-max = <10>;
+ };
+
+ /* TURBO */
+ qcom,gpu-pwrlevel@1 {
+ reg = <1>;
+ qcom,gpu-freq = <450000000>;
+ qcom,bus-freq = <9>;
+ qcom,bus-min = <9>;
+ qcom,bus-max = <10>;
+ };
+
+ /* NOM+ */
+ qcom,gpu-pwrlevel@2 {
+ reg = <2>;
+ qcom,gpu-freq = <400000000>;
+ qcom,bus-freq = <7>;
+ qcom,bus-min = <6>;
+ qcom,bus-max = <9>;
+ };
+
+ /* NOM */
+ qcom,gpu-pwrlevel@3 {
+ reg = <3>;
+ qcom,gpu-freq = <375000000>;
+ qcom,bus-freq = <6>;
+ qcom,bus-min = <5>;
+ qcom,bus-max = <8>;
+ };
+
+ /* SVS+ */
+ qcom,gpu-pwrlevel@4 {
+ reg = <4>;
+ qcom,gpu-freq = <300000000>;
+ qcom,bus-freq = <5>;
+ qcom,bus-min = <4>;
+ qcom,bus-max = <7>;
+ };
+
+ /* SVS */
+ qcom,gpu-pwrlevel@5 {
+ reg = <5>;
+ qcom,gpu-freq = <216000000>;
+ qcom,bus-freq = <3>;
+ qcom,bus-min = <1>;
+ qcom,bus-max = <4>;
+ };
+
+ /* XO */
+ qcom,gpu-pwrlevel@6 {
+ reg = <6>;
+ qcom,gpu-freq = <19200000>;
+ qcom,bus-freq = <0>;
+ qcom,bus-min = <0>;
+ qcom,bus-max = <0>;
+ };
+ };
+
+ /* Power levels */
+ qcom,gpu-pwrlevels-1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,speed-bin = <1>;
+ qcom,initial-pwrlevel = <3>;
+
+ /* SUPER TURBO */
+ qcom,gpu-pwrlevel@0 {
+ reg = <0>;
+ qcom,gpu-freq = <500000000>;
+ qcom,bus-freq = <10>;
+ qcom,bus-min = <10>;
+ qcom,bus-max = <10>;
+ };
+
+ /* TURBO */
+ qcom,gpu-pwrlevel@1 {
+ reg = <1>;
+ qcom,gpu-freq = <450000000>;
+ qcom,bus-freq = <9>;
+ qcom,bus-min = <9>;
+ qcom,bus-max = <10>;
+ };
+
+ /* NOM+ */
+ qcom,gpu-pwrlevel@2 {
+ reg = <2>;
+ qcom,gpu-freq = <400000000>;
+ qcom,bus-freq = <7>;
+ qcom,bus-min = <6>;
+ qcom,bus-max = <9>;
+ };
+
+ /* NOM */
+ qcom,gpu-pwrlevel@3 {
+ reg = <3>;
+ qcom,gpu-freq = <375000000>;
+ qcom,bus-freq = <6>;
+ qcom,bus-min = <5>;
+ qcom,bus-max = <8>;
+ };
+
+ /* SVS+ */
+ qcom,gpu-pwrlevel@4 {
+ reg = <4>;
+ qcom,gpu-freq = <300000000>;
+ qcom,bus-freq = <5>;
+ qcom,bus-min = <4>;
+ qcom,bus-max = <7>;
+ };
+
+ /* SVS */
+ qcom,gpu-pwrlevel@5 {
+ reg = <5>;
+ qcom,gpu-freq = <216000000>;
+ qcom,bus-freq = <3>;
+ qcom,bus-min = <1>;
+ qcom,bus-max = <4>;
+ };
+
+ /* XO */
+ qcom,gpu-pwrlevel@6 {
+ reg = <6>;
+ qcom,gpu-freq = <19200000>;
+ qcom,bus-freq = <0>;
+ qcom,bus-min = <0>;
+ qcom,bus-max = <0>;
+ };
+ };
+
+ };
+};
+
+&tsens0 {
+ qcom,temp1-offset = <0 (-2) (-5) (-3) (-1) (-1) (-1) 0 1 (-1) (-6)>;
+ qcom,temp2-offset = <1 1 (-7) 5 4 7 6 2 3 1 7>;
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8953-camera-sensor-cdp.dtsi b/arch/arm64/boot/dts/qcom/msm8953-camera-sensor-cdp.dtsi
index d47dd75..c2efa2d 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-camera-sensor-cdp.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-camera-sensor-cdp.dtsi
@@ -77,58 +77,23 @@
eeprom1: qcom,eeprom@1 {
cell-index = <1>;
reg = <0x1>;
- qcom,eeprom-name = "sunny_8865";
compatible = "qcom,eeprom";
- qcom,slave-addr = <0x6c>;
- qcom,cci-master = <0>;
- qcom,num-blocks = <8>;
-
- qcom,page0 = <1 0x0100 2 0x01 1 1>;
- qcom,poll0 = <0 0x0 2 0x0 1 0>;
- qcom,mem0 = <0 0x0 2 0x0 1 0>;
-
- qcom,page1 = <1 0x5002 2 0x00 1 0>;
- qcom,poll1 = <0 0x0 2 0x0 1 0>;
- qcom,mem1 = <0 0x0 2 0x0 1 0>;
-
- qcom,page2 = <1 0x3d84 2 0xc0 1 0>;
- qcom,poll2 = <0 0x0 2 0x0 1 0>;
- qcom,mem2 = <0 0x0 2 0x0 1 0>;
-
- qcom,page3 = <1 0x3d88 2 0x70 1 0>;
- qcom,poll3 = <0 0x0 2 0x0 1 0>;
- qcom,mem3 = <0 0x0 2 0x0 1 0>;
-
- qcom,page4 = <1 0x3d89 2 0x10 1 0>;
- qcom,poll4 = <0 0x0 2 0x0 1 0>;
- qcom,mem4 = <0 0x0 2 0x0 1 0>;
-
- qcom,page5 = <1 0x3d8a 2 0x70 1 0>;
- qcom,poll5 = <0 0x0 2 0x0 1 0>;
- qcom,mem5 = <0 0x0 2 0x0 1 0>;
-
- qcom,page6 = <1 0x3d8b 2 0xf4 1 0>;
- qcom,poll6 = <0 0x0 2 0x0 1 0>;
- qcom,mem6 = <0 0x0 2 0x0 1 0>;
-
- qcom,page7 = <1 0x3d81 2 0x01 1 10>;
- qcom,poll7 = <0 0x0 2 0x0 1 1>;
- qcom,mem7 = <1536 0x7010 2 0 1 0>;
-
+ qcom,cci-master = <1>;
cam_vdig-supply = <&pm8953_l23>;
- cam_vana-supply = <&pm8953_l22>;
cam_vio-supply = <&pm8953_l6>;
+ cam_vana-supply = <&pm8953_l22>;
cam_vaf-supply = <&pm8953_l17>;
qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
- "cam_vaf";
+ "cam_vaf";
qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
qcom,gpio-no-mux = <0>;
pinctrl-names = "cam_default", "cam_suspend";
pinctrl-0 = <&cam_sensor_mclk1_default
- &cam_sensor_front1_default>;
- pinctrl-1 = <&cam_sensor_mclk1_sleep &cam_sensor_front1_sleep>;
+ &cam_sensor_front1_default>;
+ pinctrl-1 = <&cam_sensor_mclk1_sleep
+ &cam_sensor_front1_sleep>;
gpios = <&tlmm 27 0>,
<&tlmm 129 0>,
<&tlmm 130 0>;
@@ -139,14 +104,8 @@
qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
"CAM_RESET2",
"CAM_STANDBY2";
- qcom,cam-power-seq-type = "sensor_vreg", "sensor_vreg",
- "sensor_vreg",
- "sensor_gpio", "sensor_gpio" , "sensor_clk";
- qcom,cam-power-seq-val = "cam_vdig", "cam_vana", "cam_vio",
- "sensor_gpio_reset", "sensor_gpio_standby",
- "sensor_cam_mclk";
- qcom,cam-power-seq-cfg-val = <1 1 1 1 1 24000000>;
- qcom,cam-power-seq-delay = <1 1 1 30 30 5>;
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
status = "ok";
clocks = <&clock_gcc clk_mclk1_clk_src>,
<&clock_gcc clk_gcc_camss_mclk1_clk>;
diff --git a/arch/arm64/boot/dts/qcom/msm8953-camera-sensor-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8953-camera-sensor-mtp.dtsi
index d47dd75..c2efa2d 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-camera-sensor-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-camera-sensor-mtp.dtsi
@@ -77,58 +77,23 @@
eeprom1: qcom,eeprom@1 {
cell-index = <1>;
reg = <0x1>;
- qcom,eeprom-name = "sunny_8865";
compatible = "qcom,eeprom";
- qcom,slave-addr = <0x6c>;
- qcom,cci-master = <0>;
- qcom,num-blocks = <8>;
-
- qcom,page0 = <1 0x0100 2 0x01 1 1>;
- qcom,poll0 = <0 0x0 2 0x0 1 0>;
- qcom,mem0 = <0 0x0 2 0x0 1 0>;
-
- qcom,page1 = <1 0x5002 2 0x00 1 0>;
- qcom,poll1 = <0 0x0 2 0x0 1 0>;
- qcom,mem1 = <0 0x0 2 0x0 1 0>;
-
- qcom,page2 = <1 0x3d84 2 0xc0 1 0>;
- qcom,poll2 = <0 0x0 2 0x0 1 0>;
- qcom,mem2 = <0 0x0 2 0x0 1 0>;
-
- qcom,page3 = <1 0x3d88 2 0x70 1 0>;
- qcom,poll3 = <0 0x0 2 0x0 1 0>;
- qcom,mem3 = <0 0x0 2 0x0 1 0>;
-
- qcom,page4 = <1 0x3d89 2 0x10 1 0>;
- qcom,poll4 = <0 0x0 2 0x0 1 0>;
- qcom,mem4 = <0 0x0 2 0x0 1 0>;
-
- qcom,page5 = <1 0x3d8a 2 0x70 1 0>;
- qcom,poll5 = <0 0x0 2 0x0 1 0>;
- qcom,mem5 = <0 0x0 2 0x0 1 0>;
-
- qcom,page6 = <1 0x3d8b 2 0xf4 1 0>;
- qcom,poll6 = <0 0x0 2 0x0 1 0>;
- qcom,mem6 = <0 0x0 2 0x0 1 0>;
-
- qcom,page7 = <1 0x3d81 2 0x01 1 10>;
- qcom,poll7 = <0 0x0 2 0x0 1 1>;
- qcom,mem7 = <1536 0x7010 2 0 1 0>;
-
+ qcom,cci-master = <1>;
cam_vdig-supply = <&pm8953_l23>;
- cam_vana-supply = <&pm8953_l22>;
cam_vio-supply = <&pm8953_l6>;
+ cam_vana-supply = <&pm8953_l22>;
cam_vaf-supply = <&pm8953_l17>;
qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
- "cam_vaf";
+ "cam_vaf";
qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
qcom,gpio-no-mux = <0>;
pinctrl-names = "cam_default", "cam_suspend";
pinctrl-0 = <&cam_sensor_mclk1_default
- &cam_sensor_front1_default>;
- pinctrl-1 = <&cam_sensor_mclk1_sleep &cam_sensor_front1_sleep>;
+ &cam_sensor_front1_default>;
+ pinctrl-1 = <&cam_sensor_mclk1_sleep
+ &cam_sensor_front1_sleep>;
gpios = <&tlmm 27 0>,
<&tlmm 129 0>,
<&tlmm 130 0>;
@@ -139,14 +104,8 @@
qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
"CAM_RESET2",
"CAM_STANDBY2";
- qcom,cam-power-seq-type = "sensor_vreg", "sensor_vreg",
- "sensor_vreg",
- "sensor_gpio", "sensor_gpio" , "sensor_clk";
- qcom,cam-power-seq-val = "cam_vdig", "cam_vana", "cam_vio",
- "sensor_gpio_reset", "sensor_gpio_standby",
- "sensor_cam_mclk";
- qcom,cam-power-seq-cfg-val = <1 1 1 1 1 24000000>;
- qcom,cam-power-seq-delay = <1 1 1 30 30 5>;
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
status = "ok";
clocks = <&clock_gcc clk_mclk1_clk_src>,
<&clock_gcc clk_gcc_camss_mclk1_clk>;
diff --git a/arch/arm64/boot/dts/qcom/msm8953-cdp.dtsi b/arch/arm64/boot/dts/qcom/msm8953-cdp.dtsi
index 9b78253..b21983c 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-cdp.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-cdp.dtsi
@@ -151,6 +151,8 @@
&dsi_truly_1080_vid {
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
qcom,mdss-dsi-pan-enable-dynamic-fps;
+ qcom,mdss-dsi-min-refresh-rate = <48>;
+ qcom,mdss-dsi-max-refresh-rate = <60>;
qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_vfp";
};
diff --git a/arch/arm64/boot/dts/qcom/msm8953-coresight.dtsi b/arch/arm64/boot/dts/qcom/msm8953-coresight.dtsi
index d3c2e26..87684a7 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-coresight.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-coresight.dtsi
@@ -890,6 +890,7 @@
reg-names = "cti-base";
coresight-name = "coresight-cti-cpu0";
cpu = <&CPU0>;
+ qcom,cit-save;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -904,6 +905,7 @@
reg-names = "cti-base";
coresight-name = "coresight-cti-cpu1";
cpu = <&CPU1>;
+ qcom,cit-save;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -918,6 +920,7 @@
reg-names = "cti-base";
coresight-name = "coresight-cti-cpu2";
cpu = <&CPU2>;
+ qcom,cit-save;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -932,6 +935,7 @@
reg-names = "cti-base";
coresight-name = "coresight-cti-cpu3";
cpu = <&CPU3>;
+ qcom,cit-save;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -946,6 +950,7 @@
reg-names = "cti-base";
coresight-name = "coresight-cti-cpu4";
cpu = <&CPU4>;
+ qcom,cit-save;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -960,6 +965,7 @@
reg-names = "cti-base";
coresight-name = "coresight-cti-cpu5";
cpu = <&CPU5>;
+ qcom,cit-save;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -974,6 +980,7 @@
reg-names = "cti-base";
coresight-name = "coresight-cti-cpu6";
cpu = <&CPU6>;
+ qcom,cit-save;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -988,6 +995,7 @@
reg-names = "cti-base";
coresight-name = "coresight-cti-cpu7";
cpu = <&CPU7>;
+ qcom,cit-save;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
diff --git a/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi
index cc4bc7f..5655e94 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi
@@ -150,6 +150,8 @@
&dsi_truly_1080_vid {
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
qcom,mdss-dsi-pan-enable-dynamic-fps;
+ qcom,mdss-dsi-min-refresh-rate = <48>;
+ qcom,mdss-dsi-max-refresh-rate = <60>;
qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_vfp";
};
diff --git a/arch/arm64/boot/dts/qcom/msm8953.dtsi b/arch/arm64/boot/dts/qcom/msm8953.dtsi
index b7d72b7..24701bf 100644
--- a/arch/arm64/boot/dts/qcom/msm8953.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953.dtsi
@@ -1345,9 +1345,9 @@
reg = <0x10 8>;
};
- dload_type@18 {
+ dload_type@1c {
compatible = "qcom,msm-imem-dload-type";
- reg = <0x18 4>;
+ reg = <0x1c 4>;
};
restart_reason@65c {
diff --git a/arch/arm64/boot/dts/qcom/pm8916.dtsi b/arch/arm64/boot/dts/qcom/pm8916.dtsi
index 5204137..45516be 100644
--- a/arch/arm64/boot/dts/qcom/pm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8916.dtsi
@@ -80,6 +80,11 @@
"pm8916_mpp3", "pm8916_mpp4";
};
+ pm8916_coincell: qcom,coincell@2800 {
+ compatible = "qcom,qpnp-coincell";
+ reg = <0x2800 0x100>;
+ };
+
pm8916_rtc: qcom,pm8916_rtc {
compatible = "qcom,qpnp-rtc";
#address-cells = <1>;
@@ -299,12 +304,10 @@
#address-cells = <1>;
#size-cells = <1>;
- pm8916_pwm: pwm@bc00 {
- compatible = "qcom,qpnp-pwm";
+ pm8916_pwm: qcom,pwms@bc00 {
+ compatible = "qcom,pwm-lpg";
reg = <0xbc00 0x100>;
- reg-names = "qpnp-lpg-channel-base";
- qcom,channel-id = <0>;
- qcom,supported-sizes = <6>, <9>;
+ reg-names = "lpg-base";
#pwm-cells = <2>;
};
diff --git a/arch/arm64/boot/dts/qcom/pmi632.dtsi b/arch/arm64/boot/dts/qcom/pmi632.dtsi
index 93516a1..a6f29bf 100644
--- a/arch/arm64/boot/dts/qcom/pmi632.dtsi
+++ b/arch/arm64/boot/dts/qcom/pmi632.dtsi
@@ -624,6 +624,7 @@
interrupt-names = "sc-irq";
qcom,pmic-revid = <&pmi632_revid>;
+ qcom,voltage-step-ramp;
lcdb_ldo_vreg: ldo {
label = "ldo";
diff --git a/arch/arm64/boot/dts/qcom/qcs605-360camera.dtsi b/arch/arm64/boot/dts/qcom/qcs605-360camera.dtsi
index 0d47ba6..3da9825 100644
--- a/arch/arm64/boot/dts/qcom/qcs605-360camera.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcs605-360camera.dtsi
@@ -166,6 +166,9 @@
&pm660_charger {
qcom,battery-data = <&qcs_batterydata>;
+ qcom,thermal-mitigation = <2600000 2100000 1600000 1100000
+ 600000>;
+ qcom,sw-jeita-enable;
};
&int_codec {
diff --git a/arch/arm64/boot/dts/qcom/qcs605-lc-ipcamera.dtsi b/arch/arm64/boot/dts/qcom/qcs605-lc-ipcamera.dtsi
index e661e9b..0b36ffe 100644
--- a/arch/arm64/boot/dts/qcom/qcs605-lc-ipcamera.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcs605-lc-ipcamera.dtsi
@@ -66,6 +66,29 @@
bias-disable;
};
};
+
+ usb_det_default: usb_det_default {
+ usb_id_det_default: usb_id_det_default {
+ mux {
+ pins = "gpio131";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio131";
+ drive-strength = <2>;
+ bias-pull-down;
+ output-enable;
+ };
+ };
+ usb_vbus_det_default: usb_vbus_det_default {
+ config {
+ pins = "gpio26";
+ drive-strength = <2>;
+ bias-pull-up;
+ input-enable;
+ };
+ };
+ };
};
&sdhc_2 {
@@ -83,6 +106,22 @@
status = "ok";
};
+&soc {
+ extcon_usb1: extcon_usb1 {
+ compatible = "linux,extcon-usb-gpio";
+ id-gpio = <&tlmm 26 0x1>;
+ trig-gpio = <&tlmm 131 0x0>;
+ gpio-names = "gpio131";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb_vbus_det_default &usb_id_det_default>;
+ };
+};
+
+&usb0 {
+ extcon = <&extcon_usb1>;
+};
+
&msm_sdw_codec {
status = "disabled";
};
@@ -146,19 +185,23 @@
&tavil_snd {
status = "okay";
compatible = "qcom,qcs605-asoc-snd-tavil";
- qcom,model = "qcs605-tavil-snd-card";
+ qcom,model = "qcs605-ipc-tavil-snd-card";
qcom,audio-routing =
"AIF4 VI", "MCLK",
"RX_BIAS", "MCLK",
"MADINPUT", "MCLK",
+ "AMIC1", "MIC BIAS1",
+ "MIC BIAS1", "Handset Mic",
+ "AMIC2", "MIC BIAS2",
+ "MIC BIAS2", "Headset Mic",
"DMIC0", "MIC BIAS1",
"MIC BIAS1", "Digital Mic0",
"DMIC1", "MIC BIAS1",
"MIC BIAS1", "Digital Mic1",
- "DMIC2", "MIC BIAS3",
- "MIC BIAS3", "Digital Mic2",
- "DMIC3", "MIC BIAS3",
- "MIC BIAS3", "Digital Mic3",
+ "DMIC2", "MIC BIAS1",
+ "MIC BIAS1", "Digital Mic2",
+ "DMIC3", "MIC BIAS1",
+ "MIC BIAS1", "Digital Mic3",
"SpkrLeft IN", "SPK1 OUT";
qcom,wsa-max-devs = <1>;
qcom,wsa-devs = <&wsa881x_0211>, <&wsa881x_0213>;
diff --git a/arch/arm64/boot/dts/qcom/qcs605-lc-pmic-overlay.dtsi b/arch/arm64/boot/dts/qcom/qcs605-lc-pmic-overlay.dtsi
index 1264e08..bbe3fb0 100644
--- a/arch/arm64/boot/dts/qcom/qcs605-lc-pmic-overlay.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcs605-lc-pmic-overlay.dtsi
@@ -19,6 +19,8 @@
qcom,pmic-revid = <&pm660_revid>;
+ qcom,qcs605-ipc-wa;
+
io-channels = <&pm660_rradc 8>,
<&pm660_rradc 10>,
<&pm660_rradc 3>,
diff --git a/arch/arm64/boot/dts/qcom/qcs605.dtsi b/arch/arm64/boot/dts/qcom/qcs605.dtsi
index 7801775..cb46865 100644
--- a/arch/arm64/boot/dts/qcom/qcs605.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcs605.dtsi
@@ -62,6 +62,10 @@
status = "disabled";
};
+&qcom_seecom {
+ reg = <0x86d00000 0x800000>;
+};
+
&sp_mem {
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/qcom/qm215-pm8916.dtsi b/arch/arm64/boot/dts/qcom/qm215-pm8916.dtsi
index c2d9aea..7fcb9de 100644
--- a/arch/arm64/boot/dts/qcom/qm215-pm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/qm215-pm8916.dtsi
@@ -32,7 +32,22 @@
/* delete all node referring PM8937 */
&soc {
- /delete-node/ thermal-zones;
+ thermal-zones {
+ /delete-node/ pa-therm1-adc;
+ /delete-node/ xo-therm-adc;
+ /delete-node/ xo-therm-buf-adc;
+ /delete-node/ case-therm-adc;
+ /delete-node/ pa-therm0-adc;
+ /delete-node/ pm8937_tz;
+
+ aoss0-lowf {
+ cooling-maps {
+ cx_vdd_cdev {
+ /delete-property/ cooling-device;
+ };
+ };
+ };
+ };
qcom,cpu-clock-8939@b111050 {
/delete-property/ vdd-c1-supply;
@@ -56,40 +71,59 @@
/delete-property/ vdd_cx-supply;
/delete-property/ vdd_mx-supply;
/delete-property/ vdd_pll-supply;
+ vdd_mss-supply = <&pm8916_s1_level>;
+ vdd_cx-supply = <&pm8916_s1_level>;
+ vdd_mx-supply = <&pm8916_l2_level_ao>;
+ vdd_pll-supply = <&pm8916_l7>;
};
qcom,lpass@c200000 {
/delete-property/ vdd_cx-supply;
+ vdd_cx-supply = <&pm8916_s1_level>;
};
qcom,pronto@a21b000 {
/delete-property/ vdd_pronto_pll-supply;
+ vdd_pronto_pll-supply = <&pm8916_l7>;
};
qcom,wcnss-wlan@a000000 {
- /delete-property/ qcom,pronto-vddmx-supply;
- /delete-property/ qcom,pronto-vddcx-supply;
- /delete-property/ qcom,pronto-vddpx-supply;
- /delete-property/ qcom,iris-vddxo-supply;
- /delete-property/ qcom,iris-vddrfa-supply;
- /delete-property/ qcom,iris-vddpa-supply;
- /delete-property/ qcom,iris-vdddig-supply;
/delete-property/ qcom,wcnss-adc_tm;
- };
+ qcom,pronto-vddmx-supply = <&pm8916_l2_level_ao>;
+ qcom,pronto-vddcx-supply = <&pm8916_s1_level>;
+ qcom,pronto-vddpx-supply = <&pm8916_l7>;
+ qcom,iris-vddxo-supply = <&pm8916_l7>;
+ qcom,iris-vddrfa-supply = <&pm8916_l3>;
+ qcom,iris-vddpa-supply = <&pm8916_l9>;
+ qcom,iris-vdddig-supply = <&pm8916_l7>;
- /delete-node/ qcom,gcc-mdss@1800000;
+ qcom,iris-vddxo-voltage-level = <1800000 0 1800000>;
+ qcom,iris-vddrfa-voltage-level = <1325000 0 1325000>;
+ qcom,iris-vddpa-voltage-level = <3300000 0 3300000>;
+ qcom,iris-vdddig-voltage-level = <1800000 0 1800000>;
+
+ qcom,vddmx-voltage-level = <RPM_SMD_REGULATOR_LEVEL_NOM
+ RPM_SMD_REGULATOR_LEVEL_NONE
+ RPM_SMD_REGULATOR_LEVEL_TURBO>;
+ qcom,vddcx-voltage-level = <RPM_SMD_REGULATOR_LEVEL_NOM
+ RPM_SMD_REGULATOR_LEVEL_NONE
+ RPM_SMD_REGULATOR_LEVEL_TURBO>;
+ qcom,vddpx-voltage-level = <1800000 0 1800000>;
+
+ qcom,iris-vddxo-current = <10000>;
+ qcom,iris-vddrfa-current = <100000>;
+ qcom,iris-vddpa-current = <515000>;
+ qcom,iris-vdddig-current = <10000>;
+
+ qcom,pronto-vddmx-current = <0>;
+ qcom,pronto-vddcx-current = <0>;
+ qcom,pronto-vddpx-current = <0>;
+ };
/delete-node/ qcom,csid@1b30000;
/delete-node/ qcom,csid@1b30400;
/delete-node/ qcom,csid@1b30800;
- /delete-node/ qcom,mdss_mdp@1a00000;
- /delete-node/ qcom,mdss_dsi@0;
- /delete-node/ qcom,mdss_wb_panel;
- /delete-node/ qcom,mdss_rotator;
- /delete-node/ qcom,mdss_dsi_pll@1a94a00;
- /delete-node/ qcom,mdss_dsi_pll@1a96a00;
-
/* mem_acc */
/delete-node/ regulator@01946004;
/* apc vreg */
@@ -100,9 +134,352 @@
#include "pm8916-rpm-regulator.dtsi"
#include "pm8916.dtsi"
+#include "qm215-regulator.dtsi"
&spmi_bus {
pm8916@1 {
/delete-node/ msm8x16_wcd_codec@f000;
};
};
+
+&pm8916_gpios {
+ disp_vdda_en_default: disp_vdda_en_default {
+ pins = "gpio3";
+ function = "normal";
+ power-source = <0>;
+ drive-strength = <8>;
+ output-high;
+ };
+};
+
+&pm8916_mpps {
+ backlight_mpp {
+ backlight_pwm_en_default: backlight_pwm_en_default {
+ pins = "mpp4";
+ function = "digital";
+ power-source = <0>;
+ output-high;
+ };
+ };
+};
+
+&soc {
+ disp_vdda_eldo1: gpio-regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0x00 0x00>;
+ regulator-name = "disp_vdda_eldo1";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-enable-ramp-delay = <135>;
+ enable-active-high;
+ gpio = <&pm8916_gpios 3 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&disp_vdda_en_default>;
+ vin-supply = <&pm8916_s3>;
+ };
+};
+
+&mdss_dsi0_pll {
+ vddio-supply = <&pm8916_l6>;
+};
+
+&mdss_dsi0 {
+ /delete-property/ vdd-supply;
+ vddio-supply = <&pm8916_l6>;
+};
+
+&mdss_dsi {
+ vdda-supply = <&pm8916_l6>;
+ vddio-supply = <&pm8916_l6>;
+
+ qcom,phy-supply-entries {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,phy-supply-entry@0 {
+ reg = <0>;
+ qcom,supply-name = "vddio";
+ qcom,supply-min-voltage = <1744000>;
+ qcom,supply-max-voltage = <1904000>;
+ qcom,supply-enable-load = <100000>;
+ qcom,supply-disable-load = <100>;
+ };
+ };
+
+ qcom,ctrl-supply-entries {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,ctrl-supply-entry@0 {
+ reg = <0>;
+ qcom,supply-name = "vdda";
+ qcom,supply-min-voltage = <1744000>;
+ qcom,supply-max-voltage = <1904000>;
+ qcom,supply-enable-load = <100000>;
+ qcom,supply-disable-load = <100>;
+ };
+ };
+};
+
+&clock_cpu {
+ vdd-c1-supply = <&apc_vreg_corner>;
+};
+
+&clock_gcc {
+ vdd_dig-supply = <&pm8916_s1_level>;
+ vdd_hf_dig-supply = <&pm8916_s1_level_ao>;
+ vdd_hf_pll-supply = <&pm8916_l7_ao>;
+};
+
+&pm8916_vadc {
+ chan@0 {
+ label = "usb_in";
+ reg = <0>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <7>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@2 {
+ label = "ireg_fb";
+ reg = <2>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <6>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@5 {
+ label = "vcoin";
+ reg = <5>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <1>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@6 {
+ label = "vbat_sns";
+ reg = <6>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <1>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@7 {
+ label = "vph_pwr";
+ reg = <7>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <1>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@b {
+ label = "chg_temp";
+ reg = <0xb>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <3>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@11 {
+ label = "skin_therm";
+ reg = <0x11>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+
+ chan@30 {
+ label = "batt_therm";
+ reg = <0x30>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <22>;
+ qcom,hw-settle-time = <0xb>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@31 {
+ label = "batt_id";
+ reg = <0x31>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0xb>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@36 {
+ label = "pa_therm0";
+ reg = <0x36>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+
+ chan@32 {
+ label = "xo_therm";
+ reg = <0x32>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <4>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+
+ chan@3c {
+ label = "xo_therm_buf";
+ reg = <0x3c>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <4>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+};
+
+&pm8916_adc_tm {
+ /* Channel Node */
+ chan@30 {
+ label = "batt_therm";
+ reg = <0x30>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <8>;
+ qcom,hw-settle-time = <0xb>;
+ qcom,fast-avg-setup = <0x2>;
+ qcom,btm-channel-number = <0x48>;
+ };
+
+ chan@6 {
+ label = "vbat_sns";
+ reg = <0x6>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <1>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0xb>;
+ qcom,fast-avg-setup = <0x2>;
+ qcom,btm-channel-number = <0x68>;
+ };
+};
+
+&soc {
+ thermal-zones {
+ xo-therm-buf-adc {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&pm8916_vadc 0x3c>;
+ thermal-governor = "user_space";
+
+ trips {
+ active-config0 {
+ temperature = <65000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+ };
+
+ xo-therm-adc {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&pm8916_vadc 0x32>;
+ thermal-governor = "user_space";
+
+ trips {
+ active-config0 {
+ temperature = <65000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+ };
+
+ pa-therm0-adc {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&pm8916_vadc 0x36>;
+ thermal-governor = "user_space";
+
+ trips {
+ active-config0 {
+ temperature = <65000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+ };
+
+ skin-therm-adc {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&pm8916_vadc 0x11>;
+ thermal-governor = "user_space";
+
+ trips {
+ active-config0 {
+ temperature = <65000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+ };
+
+ aoss0-lowf {
+ cooling-maps {
+ cx_vdd_cdev {
+ cooling-device = <&pm8916_cx_cdev 0 0>;
+ };
+ };
+ };
+ };
+};
+
+&soc {
+ usb_vdig_supply: usb_vdig_supply {
+ compatible = "regulator-fixed";
+ regulator-name = "usb_vdig_supply";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+};
+
+&usb_otg {
+ hsusb_vdd_dig-supply = <&usb_vdig_supply>;
+ HSUSB_1p8-supply = <&pm8916_l7>;
+ HSUSB_3p3-supply = <&pm8916_l13>;
+ extcon = <&pm8916_chg>;
+};
diff --git a/arch/arm64/boot/dts/qcom/qm215-qrd.dtsi b/arch/arm64/boot/dts/qcom/qm215-qrd.dtsi
index 5731bab..6499eb9 100644
--- a/arch/arm64/boot/dts/qcom/qm215-qrd.dtsi
+++ b/arch/arm64/boot/dts/qcom/qm215-qrd.dtsi
@@ -15,6 +15,21 @@
status = "ok";
};
+&pm8916_chg{
+ status = "ok";
+ qcom,chgr-led-support;
+};
+
+&pm8916_bms{
+ status = "ok";
+ qcom,battery-data = <&qrd_batterydata>;
+ qcom,batt-aging-comp;
+};
+
+&pm8916_vib{
+ status = "ok";
+};
+
&soc {
gpio_keys {
compatible = "gpio-keys";
@@ -33,3 +48,93 @@
};
};
};
+
+&mdss_dsi_active {
+ mux {
+ pins = "gpio60", "gpio93", "gpio94";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio60", "gpio93", "gpio94";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable = <0>; /* no pull */
+ output-high;
+ };
+};
+
+&mdss_dsi_suspend {
+ mux {
+ pins = "gpio60", "gpio93", "gpio94";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio60", "gpio93", "gpio94";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down; /* pull down */
+ };
+};
+
+#include "msm8937-mdss-panels.dtsi"
+
+&mdss_mdp {
+ qcom,mdss-pref-prim-intf = "dsi";
+};
+
+&dsi_panel_pwr_supply {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,panel-supply-entry@0 {
+ reg = <1>;
+ qcom,supply-name = "vddio";
+ qcom,supply-min-voltage = <1744000>;
+ qcom,supply-max-voltage = <1904000>;
+ qcom,supply-enable-load = <100000>;
+ qcom,supply-disable-load = <100>;
+ };
+ /delete-node/ qcom,panel-supply-entry@1;
+ /delete-node/ qcom,panel-supply-entry@2;
+ /delete-node/ qcom,panel-supply-entry@3;
+};
+
+&mdss_dsi {
+ hw-config = "single_dsi";
+};
+
+&mdss_dsi0 {
+ qcom,dsi-pref-prim-pan = <&dsi_hx8399c_hd_vid>;
+ pinctrl-names = "mdss_default", "mdss_sleep";
+ pinctrl-0 = <&mdss_dsi_active &mdss_te_active
+ &backlight_pwm_en_default>;
+ pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>;
+
+ qcom,platform-te-gpio = <&tlmm 24 0>;
+ qcom,platform-reset-gpio = <&tlmm 60 0>;
+ qcom,platform-bklight-en-gpio = <&tlmm 93 0>;
+ qcom,platform-enable-gpio = <&tlmm 94 0>;
+};
+
+&dsi_hx8399c_hd_vid {
+ qcom,mdss-dsi-panel-timings =
+ [e7 1c 12 00 42 42 18 20 17 03 04 00];
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_pwm";
+ qcom,mdss-dsi-bl-pmic-pwm-frequency = <100>;
+ qcom,mdss-dsi-bl-pmic-bank-select = <0>;
+ qcom,mdss-dsi-pwm-gpio = <&pm8916_mpps 4 0>;
+ qcom,esd-check-enabled;
+ qcom,mdss-dsi-panel-status-check-mode = "reg_read";
+ qcom,mdss-dsi-panel-status-command = [06 01 00 01 00 00 01 0a];
+ qcom,mdss-dsi-panel-status-command-state = "dsi_lp_mode";
+ qcom,mdss-dsi-panel-status-value = <0x9d 0x9d 0x9d 0x9d>;
+ qcom,mdss-dsi-panel-on-check-value = <0x9d 0x9d 0x9d 0x9d>;
+ qcom,mdss-dsi-panel-status-read-length = <4>;
+ qcom,mdss-dsi-panel-max-error-count = <3>;
+ qcom,mdss-dsi-min-refresh-rate = <48>;
+ qcom,mdss-dsi-max-refresh-rate = <60>;
+ qcom,mdss-dsi-pan-enable-dynamic-fps;
+ qcom,mdss-dsi-pan-fps-update =
+ "dfps_immediate_porch_mode_vfp";
+};
diff --git a/arch/arm64/boot/dts/qcom/qm215-regulator.dtsi b/arch/arm64/boot/dts/qcom/qm215-regulator.dtsi
new file mode 100644
index 0000000..a3f522d
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qm215-regulator.dtsi
@@ -0,0 +1,555 @@
+/* Copyright (c) 2013-2015, 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/* RPM controlled regulators */
+
+&rpm_bus {
+ /* PM8916 S1 VDD_CX supply */
+ rpm-regulator-smpa1 {
+ status = "okay";
+ pm8916_s1_level: regulator-s1-level {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "8916_s1_level";
+ qcom,set = <3>;
+ regulator-min-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ regulator-max-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_BINNING>;
+ qcom,use-voltage-level;
+ };
+
+ pm8916_s1_level_ao: regulator-s1-level-ao {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "8916_s1_level_ao";
+ qcom,set = <1>;
+ regulator-min-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ regulator-max-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_BINNING>;
+ qcom,use-voltage-level;
+ };
+
+ pm8916_s1_floor_level: regulator-s1-floor-level {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "8916_s1_floor_level";
+ qcom,set = <3>;
+ regulator-min-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ regulator-max-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_BINNING>;
+ qcom,use-voltage-floor-level;
+ qcom,always-send-voltage;
+ };
+
+ pm8916_cx_cdev: regulator-cx-cdev {
+ compatible = "qcom,regulator-cooling-device";
+ regulator-cdev-supply = <&pm8916_s1_floor_level>;
+ regulator-levels = <RPM_SMD_REGULATOR_LEVEL_NOM_PLUS
+ RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ #cooling-cells = <2>;
+ };
+ };
+
+ rpm-regulator-smpa3 {
+ status = "okay";
+ pm8916_s3: regulator-s3 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1448000>;
+ qcom,init-voltage = <1000000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-smpa4 {
+ status = "okay";
+ pm8916_s4: regulator-s4 {
+ regulator-min-microvolt = <1992000>;
+ regulator-max-microvolt = <2160000>;
+ qcom,init-voltage = <1992000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa1 {
+ status = "okay";
+ pm8916_l1: regulator-l1 {
+ regulator-min-microvolt = <968000>;
+ regulator-max-microvolt = <1152000>;
+ qcom,init-voltage = <968000>;
+ status = "okay";
+ };
+ };
+
+ /* PM8916 L2 VDD_MX supply */
+ rpm-regulator-ldoa2 {
+ status = "okay";
+ pm8916_l2: regulator-l2 {
+ regulator-min-microvolt = <944000>;
+ regulator-max-microvolt = <1088000>;
+ qcom,init-voltage = <944000>;
+ status = "okay";
+ };
+
+ pm8916_l2_level_ao: regulator-l2-level-ao {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "8916_l2_level_ao";
+ qcom,set = <1>;
+ regulator-min-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ regulator-max-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_TURBO>;
+ qcom,use-voltage-level;
+ };
+
+ pm8916_l2_level_so: regulator-l2-level-so {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "8916_l2_level_so";
+ qcom,set = <2>;
+ regulator-min-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ regulator-max-microvolt =
+ <RPM_SMD_REGULATOR_LEVEL_TURBO>;
+ qcom,use-voltage-level;
+ qcom,init-voltage-level =
+ <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+ };
+ };
+
+ rpm-regulator-ldoa3 {
+ status = "okay";
+ pm8916_l3: regulator-l3 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1384000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa4 {
+ status = "okay";
+ pm8916_l4: regulator-l4 {
+ regulator-min-microvolt = <1744000>;
+ regulator-max-microvolt = <1896000>;
+ qcom,init-voltage = <1744000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa5 {
+ status = "okay";
+ pm8916_l5: regulator-l5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,init-voltage = <1800000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa6 {
+ status = "okay";
+ pm8916_l6: regulator-l6 {
+ regulator-min-microvolt = <1744000>;
+ regulator-max-microvolt = <1904000>;
+ qcom,init-voltage = <1744000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa7 {
+ status = "okay";
+ pm8916_l7: regulator-l7 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1904000>;
+ qcom,init-voltage = <1800000>;
+ status = "okay";
+ };
+
+ pm8916_l7_ao: regulator-l7-ao {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "8916_l7_ao";
+ qcom,set = <1>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1904000>;
+ qcom,init-voltage = <1800000>;
+ };
+
+ pm8916_l7_so: regulator-l7-so {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "8916_l7_so";
+ qcom,set = <2>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1904000>;
+ qcom,init-enable = <0>;
+ };
+ };
+
+ rpm-regulator-ldoa8 {
+ status = "okay";
+ pm8916_l8: regulator-l8 {
+ regulator-min-microvolt = <2696000>;
+ regulator-max-microvolt = <3600000>;
+ qcom,init-voltage = <2696000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa9 {
+ status = "okay";
+ pm8916_l9: regulator-l9 {
+ regulator-min-microvolt = <2904000>;
+ regulator-max-microvolt = <3376000>;
+ qcom,init-voltage = <2904000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa10 {
+ status = "okay";
+ pm8916_l10: regulator-l10 {
+ regulator-min-microvolt = <2704000>;
+ regulator-max-microvolt = <3000000>;
+ qcom,init-voltage = <2704000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa11 {
+ status = "okay";
+ pm8916_l11: regulator-l11 {
+ regulator-min-microvolt = <2696000>;
+ regulator-max-microvolt = <3600000>;
+ qcom,init-voltage = <2696000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa12 {
+ status = "okay";
+ pm8916_l12: regulator-l12 {
+ regulator-min-microvolt = <1648000>;
+ regulator-max-microvolt = <3104000>;
+ qcom,init-voltage = <1648000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa13 {
+ status = "okay";
+ pm8916_l13: regulator-l13 {
+ regulator-min-microvolt = <2968000>;
+ regulator-max-microvolt = <3080000>;
+ qcom,init-voltage = <2968000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa14 {
+ status = "okay";
+ pm8916_l14: regulator-l14 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3056000>;
+ qcom,init-voltage = <1800000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa15 {
+ status = "okay";
+ pm8916_l15: regulator-l15 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3056000>;
+ qcom,init-voltage = <1800000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa16 {
+ status = "okay";
+ pm8916_l16: regulator-l16 {
+ regulator-min-microvolt = <2696000>;
+ regulator-max-microvolt = <2840000>;
+ qcom,init-voltage = <2696000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa17 {
+ status = "okay";
+ pm8916_l17: regulator-l17 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3300000>;
+ qcom,init-voltage = <3000000>;
+ status = "okay";
+ };
+ };
+
+ rpm-regulator-ldoa18 {
+ status = "okay";
+ pm8916_l18: regulator-l18 {
+ regulator-min-microvolt = <2600000>;
+ regulator-max-microvolt = <2800000>;
+ qcom,init-voltage = <2600000>;
+ status = "okay";
+ };
+ };
+};
+
+/* SPM controlled regulators */
+&spmi_bus {
+ pm8916@1 {
+ pm8916_s2: spm-regulator@1700 {
+ compatible = "qcom,spm-regulator";
+ regulator-name = "8916_s2";
+ reg = <0x1700 0x100>;
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1350000>;
+ };
+ };
+};
+
+/* CPR controlled regulator */
+
+&soc {
+ mem_acc_vreg_corner: regulator@01946004 {
+ compatible = "qcom,mem-acc-regulator";
+ reg = <0xa4000 0x1000>;
+ reg-names = "efuse_addr";
+ regulator-name = "mem_acc_corner";
+ regulator-min-microvolt = <1>;
+ regulator-max-microvolt = <3>;
+
+ qcom,acc-reg-addr-list =
+ <0x01942138 0x01942130 0x01942120 0x01942124>;
+
+ qcom,acc-init-reg-config = <1 0xff>, <2 0x5555>;
+
+ qcom,num-acc-corners = <3>;
+ qcom,boot-acc-corner = <2>;
+ qcom,corner1-reg-config =
+ /* SVS+ => SVS+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => NOM */
+ < 3 0x1041041>, < 4 0x1041>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => TURBO/NOM+ */
+ < 3 0x1041041>, < 4 0x1041>, < 3 0x0>,
+ < 4 0x0>;
+
+ qcom,corner2-reg-config =
+ /* NOM => SVS+ */
+ < 3 0x30c30c3>, < 4 0x30c3>,
+ /* NOM => NOM */
+ <(-1) (-1)>, <(-1) (-1)>,
+ /* NOM => TURBO/NOM+ */
+ < 3 0x0>, < 4 0x0>;
+
+ qcom,corner3-reg-config =
+ /* TURBO/NOM+ => SVS+ */
+ < 3 0x1041041>, < 4 0x1041>, < 3 0x30c30c3>,
+ < 4 0x30c3>,
+ /* TURBO/NOM+ => NOM */
+ < 3 0x1041041>, < 4 0x1041>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* TURBO/NOM+ => TURBO/NOM+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>;
+
+ qcom,override-acc-fuse-sel = <71 17 3 0>;
+ qcom,override-fuse-version-map = <1>,
+ <2>,
+ <3>,
+ <4>;
+ qcom,override-corner1-addr-val-map =
+ /* 1st fuse version tuple matched */
+ /* SVS+ => SVS+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => NOM */
+ < 3 0x1041041>, < 4 0x1041>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => TURBO/NOM+ */
+ < 3 0x1041041>, < 4 0x1041>, < 3 0x1>,
+ < 4 0x0>,
+
+ /* 2nd fuse version tuple matched */
+ /* SVS+ => SVS+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => NOM */
+ < 3 0x1041041>, < 4 0x1041>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => TURBO/NOM+ */
+ < 3 0x1041041>, < 4 0x1041>, < 3 0x3>,
+ < 4 0x0>,
+
+ /* 3rd fuse version tuple matched */
+ /* SVS+ => SVS+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => NOM */
+ < 3 0x1041043>, < 4 0x1041>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => TURBO/NOM+ */
+ < 3 0x1041041>, < 4 0x1041>, < 3 0x0>,
+ < 4 0x0>,
+
+ /* 4th fuse version tuple matched */
+ /* SVS+ => SVS+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => NOM */
+ < 3 0x1041043>, < 4 0x1041>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* SVS+ => TURBO/NOM+ */
+ < 3 0x1041041>, < 4 0x1041>, < 3 0x1>,
+ < 4 0x0>;
+
+ qcom,override-corner2-addr-val-map =
+ /* 1st fuse version tuple matched */
+ /* NOM => SVS+ */
+ < 3 0x30c30c3>, < 4 0x30c3>,
+ /* NOM => NOM */
+ <(-1) (-1)>, <(-1) (-1)>,
+ /* NOM => TURBO/NOM+ */
+ < 3 0x1>, < 4 0x0>,
+
+ /* 2nd fuse version tuple matched */
+ /* NOM => SVS+ */
+ < 3 0x30c30c3>, < 4 0x30c3>,
+ /* NOM => NOM */
+ <(-1) (-1)>, <(-1) (-1)>,
+ /* NOM => TURBO/NOM+ */
+ < 3 0x3>, < 4 0x0>,
+
+ /* 3rd fuse version tuple matched */
+ /* NOM => SVS+ */
+ < 3 0x30c30c3>, < 4 0x30c3>,
+ /* NOM => NOM */
+ <(-1) (-1)>, <(-1) (-1)>,
+ /* NOM => TURBO/NOM+ */
+ < 3 0x0>, < 4 0x0>,
+
+ /* 4th fuse version tuple matched */
+ /* NOM => SVS+ */
+ < 3 0x30c30c3>, < 4 0x30c3>,
+ /* NOM => NOM */
+ <(-1) (-1)>, <(-1) (-1)>,
+ /* NOM => TURBO/NOM+ */
+ < 3 0x1>, < 4 0x0>;
+
+ qcom,override-corner3-addr-val-map =
+ /* 1st fuse version tuple matched */
+ /* TURBO/NOM+ => SVS+ */
+ < 3 0x1041041>, < 4 0x1041>, < 3 0x30c30c3>,
+ < 4 0x30c3>,
+ /* TURBO/NOM+ => NOM */
+ < 3 0x1041041>, < 4 0x1041>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* TURBO/NOM+ => TURBO/NOM+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+
+ /* 2nd fuse version tuple matched */
+ /* TURBO/NOM+ => SVS+ */
+ < 3 0x1041041>, < 4 0x1041>, < 3 0x30c30c3>,
+ < 4 0x30c3>,
+ /* TURBO/NOM+ => NOM */
+ < 3 0x1041041>, < 4 0x1041>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* TURBO/NOM+ => TURBO/NOM+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+
+ /* 3rd fuse version tuple matched */
+ /* TURBO/NOM+ => SVS+ */
+ < 3 0x1041041>, < 4 0x1041>, < 3 0x30c30c3>,
+ < 4 0x30c3>,
+ /* TURBO/NOM+ => NOM */
+ < 3 0x1041043>, < 4 0x1041>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* TURBO/NOM+ => TURBO/NOM+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>,
+
+ /* 4th fuse version tuple matched */
+ /* TURBO/NOM+ => SVS+ */
+ < 3 0x1041041>, < 4 0x1041>, < 3 0x30c30c3>,
+ < 4 0x30c3>,
+ /* TURBO/NOM+ => NOM */
+ < 3 0x1041043>, < 4 0x1041>, <(-1) (-1)>,
+ <(-1) (-1)>,
+ /* TURBO/NOM+ => TURBO/NOM+ */
+ <(-1) (-1)>, <(-1) (-1)>, <(-1) (-1)>,
+ <(-1) (-1)>;
+ };
+
+ apc_vreg_corner: regulator@b018000 {
+ compatible = "qcom,cpr-regulator";
+ reg = <0xb018000 0x1000>, <0xb011064 4>, <0xa4000 0x1000>;
+ reg-names = "rbcpr", "rbcpr_clk", "efuse_addr";
+ interrupts = <0 15 0>;
+ regulator-name = "apc_corner";
+ regulator-min-microvolt = <1>;
+ regulator-max-microvolt = <5>;
+
+ qcom,cpr-fuse-corners = <3>;
+ qcom,cpr-voltage-ceiling = <1155000 1225000 1350000>;
+ qcom,cpr-voltage-floor = <1050000 1050000 1090000>;
+ vdd-apc-supply = <&pm8916_s2>;
+
+ mem-acc-supply = <&mem_acc_vreg_corner>;
+
+ qcom,cpr-ref-clk = <19200>;
+ qcom,cpr-timer-delay = <5000>;
+ qcom,cpr-timer-cons-up = <0>;
+ qcom,cpr-timer-cons-down = <2>;
+ qcom,cpr-irq-line = <0>;
+ qcom,cpr-step-quotient = <26>;
+ qcom,cpr-up-threshold = <0>;
+ qcom,cpr-down-threshold = <2>;
+ qcom,cpr-idle-clocks = <15>;
+ qcom,cpr-gcnt-time = <1>;
+ qcom,vdd-apc-step-up-limit = <1>;
+ qcom,vdd-apc-step-down-limit = <1>;
+ qcom,cpr-apc-volt-step = <12500>;
+
+ qcom,cpr-fuse-row = <67 0>;
+ qcom,cpr-fuse-target-quot = <42 24 6>;
+ qcom,cpr-fuse-ro-sel = <60 57 54>;
+ qcom,cpr-init-voltage-ref = <1155000 1225000 1350000>;
+ qcom,cpr-fuse-init-voltage =
+ <67 36 6 0>,
+ <67 18 6 0>,
+ <67 0 6 0>;
+ qcom,cpr-fuse-quot-offset =
+ <71 26 6 0>,
+ <71 20 6 0>,
+ <70 54 7 0>;
+ qcom,cpr-fuse-quot-offset-scale = <5 5 5>;
+ qcom,cpr-init-voltage-step = <10000>;
+ qcom,cpr-corner-map = <1 2 3 3 3>;
+ qcom,cpr-corner-frequency-map =
+ <1 960000000>,
+ <2 1094400000>,
+ <3 1248000000>,
+ <4 1305600000>,
+ <5 1401000000>;
+ qcom,speed-bin-fuse-sel = <37 34 3 0>;
+ qcom,cpr-speed-bin-max-corners =
+ <0 (-1) 1 2 5>,
+ <3 (-1) 1 2 5>;
+ qcom,cpr-quot-adjust-scaling-factor-max = <0 1400 1400>;
+ qcom,cpr-voltage-scaling-factor-max = <0 2000 2000>;
+ qcom,cpr-scaled-init-voltage-as-ceiling;
+ qcom,cpr-fuse-revision = <69 39 3 0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/qm215.dts b/arch/arm64/boot/dts/qcom/qm215.dts
index 3fd0064..3f0b68e 100644
--- a/arch/arm64/boot/dts/qcom/qm215.dts
+++ b/arch/arm64/boot/dts/qcom/qm215.dts
@@ -17,6 +17,7 @@
#include "qm215-pm8916.dtsi"
/ {
- model = "Qualcomm Technologies, Inc. QM215 QRD";
+ model = "Qualcomm Technologies, Inc. QM215";
compatible = "qcom,qm215";
+ qcom,pmic-name = "PM8916";
};
diff --git a/arch/arm64/boot/dts/qcom/qm215.dtsi b/arch/arm64/boot/dts/qcom/qm215.dtsi
index 2d5dd3f..c16774b 100644
--- a/arch/arm64/boot/dts/qcom/qm215.dtsi
+++ b/arch/arm64/boot/dts/qcom/qm215.dtsi
@@ -16,4 +16,21 @@
model = "Qualcomm Technologies, Inc. QM215";
compatible = "qcom,qm215";
qcom,msm-id = <386 0x0>;
+ qcom,msm-name = "QM215";
+};
+
+/ {
+ qrd_batterydata: qcom,batterydata {
+ qcom,rpull-up-kohm = <100>;
+ qcom,vref-batt-therm = <1800000>;
+
+ #include "vbms-batterydata-mlp356477-2800mah.dtsi"
+ };
+};
+
+&soc {
+ qcom,vidc@1d00000 {
+ qcom,allowed-clock-rates = <329140000 329140000
+ 308570000 270000000 200000000>;
+ };
};
diff --git a/arch/arm64/boot/dts/qcom/sda845-svr.dtsi b/arch/arm64/boot/dts/qcom/sda845-svr.dtsi
index f6bf107d..2426b47 100644
--- a/arch/arm64/boot/dts/qcom/sda845-svr.dtsi
+++ b/arch/arm64/boot/dts/qcom/sda845-svr.dtsi
@@ -576,5 +576,6 @@
};
&wil6210 {
+ qcom,wigig-dc = <&tlmm 81 0>;
status = "ok";
};
diff --git a/arch/arm64/boot/dts/qcom/sdm429-cpu.dtsi b/arch/arm64/boot/dts/qcom/sdm429-cpu.dtsi
index 6c4ea9f..de0730d 100644
--- a/arch/arm64/boot/dts/qcom/sdm429-cpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm429-cpu.dtsi
@@ -134,6 +134,7 @@
1708800 327
1804800 343
1958400 445
+ 2016000 470
>;
idle-cost-data = <
100 80 60 40
@@ -147,6 +148,7 @@
1708800 85
1804800 88
1958400 110
+ 2016000 120
>;
idle-cost-data = <
4 3 2 1
diff --git a/arch/arm64/boot/dts/qcom/sdm429.dtsi b/arch/arm64/boot/dts/qcom/sdm429.dtsi
index 0a8aab3..8366032 100644
--- a/arch/arm64/boot/dts/qcom/sdm429.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm429.dtsi
@@ -24,10 +24,10 @@
/delete-node/ etm@619d000;
/delete-node/ etm@619e000;
/delete-node/ etm@619f000;
- /delete-node/ cti@61b8000;
- /delete-node/ cti@61b9000;
- /delete-node/ cti@61ba000;
- /delete-node/ cti@61bb000;
+ /delete-node/ cti@6198000;
+ /delete-node/ cti@6199000;
+ /delete-node/ cti@619a000;
+ /delete-node/ cti@619b000;
/delete-node/ jtagmm@619c000;
/delete-node/ jtagmm@619d000;
/delete-node/ jtagmm@619e000;
@@ -218,6 +218,10 @@
status = "disabled";
};
+&qseecom_ta_mem {
+ size = <0 0x400000>;
+};
+
&clock_gcc_mdss {
compatible = "qcom,gcc-mdss-sdm429";
clocks = <&mdss_dsi0_pll clk_dsi0pll_pixel_clk_src>,
diff --git a/arch/arm64/boot/dts/qcom/sdm439-regulator.dtsi b/arch/arm64/boot/dts/qcom/sdm439-regulator.dtsi
index 42c3e83..750cedb 100644
--- a/arch/arm64/boot/dts/qcom/sdm439-regulator.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm439-regulator.dtsi
@@ -378,12 +378,12 @@
reg = <0x2000 0x100>;
regulator-name = "pm8953_s5";
regulator-min-microvolt = <490000>;
- regulator-max-microvolt = <960000>;
+ regulator-max-microvolt = <980000>;
pm8953_s5_limit: avs-limit-regulator {
regulator-name = "pm8953_s5_avs_limit";
regulator-min-microvolt = <490000>;
- regulator-max-microvolt = <960000>;
+ regulator-max-microvolt = <980000>;
};
};
};
@@ -418,14 +418,14 @@
interrupts = <0 15 0>;
regulator-name = "apc_corner";
regulator-min-microvolt = <1>;
- regulator-max-microvolt = <5>;
+ regulator-max-microvolt = <6>;
qcom,cpr-fuse-corners = <3>;
- qcom,cpr-voltage-ceiling = <810000 845000 960000>;
+ qcom,cpr-voltage-ceiling = <810000 845000 980000>;
qcom,cpr-voltage-floor = <700000 700000 790000>;
vdd-apc-supply = <&pm8953_s5>;
mem-acc-supply = <&apc_mem_acc_vreg>;
- qcom,mem-acc-corner-map = <1 1 1 1 2>;
+ qcom,mem-acc-corner-map = <1 1 1 1 2 2>;
qcom,cpr-ref-clk = <19200>;
qcom,cpr-timer-delay = <5000>;
@@ -455,15 +455,19 @@
<70 54 7 0>;
qcom,cpr-fuse-quot-offset-scale = <5 5 5>;
qcom,cpr-init-voltage-step = <10000>;
- qcom,cpr-corner-map = <1 2 3 3 3>;
+ qcom,cpr-corner-map = <1 2 3 3 3 3>;
qcom,cpr-corner-frequency-map =
<1 1305600000>,
<2 1497600000>,
<3 1708800000>,
<4 1804800000>,
- <5 1958400000>;
+ <5 1958400000>,
+ <6 2016000000>;
qcom,speed-bin-fuse-sel = <37 34 3 0>;
- qcom,cpr-speed-bin-max-corners = <(-1) (-1) 1 2 5>;
+ qcom,cpr-speed-bin-max-corners =
+ <0 (-1) 1 2 5>,
+ <1 (-1) 1 2 5>,
+ <4 (-1) 1 2 6>;
qcom,cpr-fuse-revision = <69 39 3 0>;
qcom,cpr-quot-adjust-scaling-factor-max = <0 1400 1400>;
qcom,cpr-voltage-scaling-factor-max = <0 2000 2000>;
@@ -481,17 +485,17 @@
<0 0 0>;
qcom,cpr-floor-to-ceiling-max-range =
- <50000 50000 65000 65000 65000>,
- <50000 50000 65000 65000 65000>,
- <50000 50000 65000 65000 65000>;
+ <50000 50000 65000 65000 65000 65000>,
+ <50000 50000 65000 65000 65000 65000>,
+ <50000 50000 65000 65000 65000 65000>;
qcom,cpr-voltage-ceiling-override =
- <(-1) (-1) 810000 845000 885000 960000 960000>;
+ <(-1) (-1) 810000 845000 885000 980000 980000 980000>;
qcom,cpr-virtual-corner-quotient-adjustment =
- <0 0 0 0 0>,
- <0 0 (-22) 0 0>, /* NOMP: -10 mV */
- <0 0 0 0 0>;
+ <0 0 0 0 0 0>,
+ <0 0 (-22) 0 0 0>, /* NOMP: -10 mV */
+ <0 0 0 0 0 0>;
qcom,cpr-enable;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm439.dtsi b/arch/arm64/boot/dts/qcom/sdm439.dtsi
index ef22440..dc651d3 100644
--- a/arch/arm64/boot/dts/qcom/sdm439.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm439.dtsi
@@ -179,6 +179,7 @@
1708800 327
1804800 343
1958400 445
+ 2016000 470
>;
idle-cost-data = <
100 80 60 40
@@ -204,6 +205,7 @@
1708800 85
1804800 88
1958400 110
+ 2016000 120
>;
idle-cost-data = <
4 3 2 1
@@ -663,5 +665,5 @@
};
&usb_otg {
- qcom,hsusb-otg-phy-init-seq = <0x06 0x82 0xffffffff>;
+ qcom,hsusb-otg-phy-init-seq = <0x43 0x80 0x06 0x82 0xffffffff>;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm632-coresight.dtsi b/arch/arm64/boot/dts/qcom/sdm632-coresight.dtsi
index 62eeb65..2e19b67 100644
--- a/arch/arm64/boot/dts/qcom/sdm632-coresight.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm632-coresight.dtsi
@@ -104,6 +104,7 @@
reg-names = "cti-base";
coresight-name = "coresight-cti-cpu4";
cpu = <&CPU4>;
+ qcom,cti-save;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -118,7 +119,7 @@
reg-names = "cti-base";
coresight-name = "coresight-cti-cpu5";
cpu = <&CPU5>;
-
+ qcom,cti-save;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
clock-names = "apb_pclk";
@@ -132,6 +133,7 @@
reg-names = "cti-base";
coresight-name = "coresight-cti-cpu6";
cpu = <&CPU6>;
+ qcom,cti-save;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -146,6 +148,7 @@
reg-names = "cti-base";
coresight-name = "coresight-cti-cpu7";
cpu = <&CPU7>;
+ qcom,cti-save;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
diff --git a/arch/arm64/boot/dts/qcom/sdm670-gpu.dtsi b/arch/arm64/boot/dts/qcom/sdm670-gpu.dtsi
index e86117d..5324581 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-gpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-gpu.dtsi
@@ -49,9 +49,11 @@
status = "ok";
reg = <0x5000000 0x40000>,
<0x5061000 0x800>,
+ <0x509e000 0x1000>,
<0x780000 0x6300>;
reg-names = "kgsl_3d0_reg_memory",
"kgsl_3d0_cx_dbgc_memory",
+ "cx_misc",
"qfprom_memory";
interrupts = <0 300 0>;
interrupt-names = "kgsl_3d0_irq";
@@ -583,6 +585,79 @@
qcom,bus-max = <0>;
};
};
+
+ qcom,gpu-pwrlevels-5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,speed-bin = <128>;
+
+ qcom,initial-pwrlevel = <5>;
+ qcom,ca-target-pwrlevel = <3>;
+
+ /* NOM_L1 */
+ qcom,gpu-pwrlevel@0 {
+ reg = <0>;
+ qcom,gpu-freq = <610000000>;
+ qcom,bus-freq = <11>;
+ qcom,bus-min = <10>;
+ qcom,bus-max = <11>;
+ };
+
+ /* NOM */
+ qcom,gpu-pwrlevel@1 {
+ reg = <1>;
+ qcom,gpu-freq = <504000000>;
+ qcom,bus-freq = <11>;
+ qcom,bus-min = <9>;
+ qcom,bus-max = <11>;
+ };
+
+ /* SVS_L1 */
+ qcom,gpu-pwrlevel@2 {
+ reg = <2>;
+ qcom,gpu-freq = <430000000>;
+ qcom,bus-freq = <11>;
+ qcom,bus-min = <8>;
+ qcom,bus-max = <11>;
+ };
+
+ /* SVS */
+ qcom,gpu-pwrlevel@3 {
+ reg = <3>;
+ qcom,gpu-freq = <355000000>;
+ qcom,bus-freq = <8>;
+ qcom,bus-min = <5>;
+ qcom,bus-max = <9>;
+ };
+
+ /* LOW SVS */
+ qcom,gpu-pwrlevel@4 {
+ reg = <4>;
+ qcom,gpu-freq = <267000000>;
+ qcom,bus-freq = <6>;
+ qcom,bus-min = <4>;
+ qcom,bus-max = <8>;
+ };
+
+ /* MIN SVS */
+ qcom,gpu-pwrlevel@5 {
+ reg = <5>;
+ qcom,gpu-freq = <180000000>;
+ qcom,bus-freq = <4>;
+ qcom,bus-min = <3>;
+ qcom,bus-max = <4>;
+ };
+
+ /* XO */
+ qcom,gpu-pwrlevel@6 {
+ reg = <6>;
+ qcom,gpu-freq = <0>;
+ qcom,bus-freq = <0>;
+ qcom,bus-min = <0>;
+ qcom,bus-max = <0>;
+ };
+ };
};
};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
index cfd96cb3..59fb78e 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
@@ -98,6 +98,35 @@
};
};
+ micbias_supply_en_pins: micbias_supply_en_pins {
+ micbias_supply_en_active: micbias_supply_en_active {
+ mux {
+ pins = "gpio126";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio126";
+ drive-strength = <16>;
+ output-high;
+ };
+ };
+
+ micbias_supply_en_sleep: micbias_supply_en_sleep {
+ mux {
+ pins = "gpio126";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio126";
+ drive-strength = <16>;
+ bias-disable;
+ output-low;
+ };
+ };
+ };
+
qupv3_se0_spi_pins: qupv3_se0_spi_pins {
qupv3_se0_spi_active: qupv3_se0_spi_active {
mux {
diff --git a/arch/arm64/boot/dts/qcom/sdm670-usb.dtsi b/arch/arm64/boot/dts/qcom/sdm670-usb.dtsi
index 1e84e2c..10fcc14 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-usb.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-usb.dtsi
@@ -83,4 +83,5 @@
&usb_qmp_dp_phy {
vdd-supply = <&pm660l_l1>; /* 0.88v */
core-supply = <&pm660_l1>; /* 1.2v */
+ extcon = <&pm660_pdphy>;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi
index 5c40ecc..2bad8c37 100644
--- a/arch/arm64/boot/dts/qcom/sdm670.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi
@@ -357,7 +357,7 @@
1708800 139
>;
idle-cost-data = <
- 12 10 8 6
+ 12 10 8 6 4
>;
};
CPU_COST_1: core-cost1 {
@@ -383,12 +383,12 @@
2611200 1400
>;
idle-cost-data = <
- 100 80 60 40
+ 100 80 60 40 20
>;
};
CLUSTER_COST_0: cluster-cost0 {
busy-cost-data = <
- 300000 5
+ 300000 6
576000 7
748800 8
998400 9
@@ -399,7 +399,7 @@
1708800 19
>;
idle-cost-data = <
- 4 3 2 1
+ 5 4 3 2 1
>;
};
CLUSTER_COST_1: cluster-cost1 {
@@ -425,7 +425,7 @@
2611200 140
>;
idle-cost-data = <
- 4 3 2 1
+ 5 4 3 2 1
>;
};
};
@@ -1875,7 +1875,7 @@
ufs-qcom-crypto = <&ufs_ice>;
lanes-per-direction = <1>;
-
+ spm-level = <5>;
dev-ref-clk-freq = <0>; /* 19.2 MHz */
clock-names =
diff --git a/arch/arm64/boot/dts/qcom/sdm710-aqt1000-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-aqt1000-cdp-overlay.dts
index 31c99de..c482acc 100644
--- a/arch/arm64/boot/dts/qcom/sdm710-aqt1000-cdp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm710-aqt1000-cdp-overlay.dts
@@ -26,7 +26,8 @@
/ {
model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L AQT CDP";
compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
- qcom,msm-id = <360 0x0>;
+ qcom,msm-id = <360 0x0>,
+ <393 0x0>;
qcom,board-id = <1 4>;
qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
<0x0001001b 0x0102001a 0x0 0x0>,
diff --git a/arch/arm64/boot/dts/qcom/sdm710-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-cdp-overlay.dts
index a61d714..d0be6b0 100644
--- a/arch/arm64/boot/dts/qcom/sdm710-cdp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm710-cdp-overlay.dts
@@ -25,7 +25,8 @@
/ {
model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L CDP";
compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
- qcom,msm-id = <360 0x0>;
+ qcom,msm-id = <360 0x0>,
+ <393 0x0>;
qcom,board-id = <1 0>;
qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
<0x0001001b 0x0102001a 0x0 0x0>,
diff --git a/arch/arm64/boot/dts/qcom/sdm710-external-codec-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-external-codec-cdp-overlay.dts
index c64e623..8b1dfc7 100644
--- a/arch/arm64/boot/dts/qcom/sdm710-external-codec-cdp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm710-external-codec-cdp-overlay.dts
@@ -25,7 +25,8 @@
/ {
model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L Ext. Audio Codec CDP";
compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
- qcom,msm-id = <360 0x0>;
+ qcom,msm-id = <360 0x0>,
+ <393 0x0>;
qcom,board-id = <1 1>;
qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
<0x0001001b 0x0102001a 0x0 0x0>,
diff --git a/arch/arm64/boot/dts/qcom/sdm710-external-codec-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-external-codec-mtp-overlay.dts
index 058a3f1..59b02bb 100644
--- a/arch/arm64/boot/dts/qcom/sdm710-external-codec-mtp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm710-external-codec-mtp-overlay.dts
@@ -25,7 +25,8 @@
/ {
model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L Ext. Audio Codec MTP";
compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
- qcom,msm-id = <360 0x0>;
+ qcom,msm-id = <360 0x0>,
+ <393 0x0>;
qcom,board-id = <8 1>;
qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
<0x0001001b 0x0102001a 0x0 0x0>,
diff --git a/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-cdp-overlay.dts
index 408a376..3981c83 100644
--- a/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-cdp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-cdp-overlay.dts
@@ -26,7 +26,8 @@
/ {
model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A Ext. Audio Codec CDP";
compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
- qcom,msm-id = <360 0x0>;
+ qcom,msm-id = <360 0x0>,
+ <393 0x0>;
qcom,board-id = <1 1>;
qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
<0x0001001b 0x0002001a 0x0 0x0>,
diff --git a/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-mtp-overlay.dts
index 9a41edd..e4b3c27 100644
--- a/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-mtp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-mtp-overlay.dts
@@ -26,7 +26,8 @@
/ {
model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A Ext. Audio Codec MTP";
compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
- qcom,msm-id = <360 0x0>;
+ qcom,msm-id = <360 0x0>,
+ <393 0x0>;
qcom,board-id = <8 1>;
qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
<0x0001001b 0x0002001a 0x0 0x0>,
diff --git a/arch/arm64/boot/dts/qcom/sdm710-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-mtp-overlay.dts
index aa8ba6a..5128e3c 100644
--- a/arch/arm64/boot/dts/qcom/sdm710-mtp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm710-mtp-overlay.dts
@@ -25,7 +25,8 @@
/ {
model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L MTP";
compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
- qcom,msm-id = <360 0x0>;
+ qcom,msm-id = <360 0x0>,
+ <393 0x0>;
qcom,board-id = <8 0>;
qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
<0x0001001b 0x0102001a 0x0 0x0>,
diff --git a/arch/arm64/boot/dts/qcom/sdm710-pm660a-aqt1000-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-pm660a-aqt1000-cdp-overlay.dts
index 50b3470..052f582 100644
--- a/arch/arm64/boot/dts/qcom/sdm710-pm660a-aqt1000-cdp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm710-pm660a-aqt1000-cdp-overlay.dts
@@ -27,7 +27,8 @@
/ {
model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A AQT CDP";
compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
- qcom,msm-id = <360 0x0>;
+ qcom,msm-id = <360 0x0>,
+ <393 0x0>;
qcom,board-id = <1 4>;
qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
<0x0001001b 0x0002001a 0x0 0x0>,
diff --git a/arch/arm64/boot/dts/qcom/sdm710-pm660a-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-pm660a-cdp-overlay.dts
index 66afaad..f187cbf 100644
--- a/arch/arm64/boot/dts/qcom/sdm710-pm660a-cdp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm710-pm660a-cdp-overlay.dts
@@ -26,7 +26,8 @@
/ {
model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A CDP";
compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
- qcom,msm-id = <360 0x0>;
+ qcom,msm-id = <360 0x0>,
+ <393 0x0>;
qcom,board-id = <1 0>;
qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
<0x0001001b 0x0002001a 0x0 0x0>,
diff --git a/arch/arm64/boot/dts/qcom/sdm710-pm660a-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-pm660a-mtp-overlay.dts
index d9b055d..f9b79e6 100644
--- a/arch/arm64/boot/dts/qcom/sdm710-pm660a-mtp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm710-pm660a-mtp-overlay.dts
@@ -26,7 +26,8 @@
/ {
model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A MTP";
compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
- qcom,msm-id = <360 0x0>;
+ qcom,msm-id = <360 0x0>,
+ <393 0x0>;
qcom,board-id = <8 0>;
qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
<0x0001001b 0x0002001a 0x0 0x0>,
diff --git a/arch/arm64/boot/dts/qcom/sdm710-pm660a-tasha-codec-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-pm660a-tasha-codec-cdp-overlay.dts
index 7e9eaa7..da332ce 100644
--- a/arch/arm64/boot/dts/qcom/sdm710-pm660a-tasha-codec-cdp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm710-pm660a-tasha-codec-cdp-overlay.dts
@@ -26,7 +26,8 @@
/ {
model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A + Tasha Codec CDP";
compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
- qcom,msm-id = <360 0x0>;
+ qcom,msm-id = <360 0x0>,
+ <393 0x0>;
qcom,board-id = <1 5>;
qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
<0x0001001b 0x0002001a 0x0 0x0>,
diff --git a/arch/arm64/boot/dts/qcom/sdm710-qrd-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-qrd-overlay.dts
index 91139ba..a2213b2 100644
--- a/arch/arm64/boot/dts/qcom/sdm710-qrd-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm710-qrd-overlay.dts
@@ -23,7 +23,8 @@
/ {
model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L QRD";
compatible = "qcom,sdm670-qrd", "qcom,sdm670", "qcom,qrd";
- qcom,msm-id = <360 0x0>;
+ qcom,msm-id = <360 0x0>,
+ <393 0x0>;
qcom,board-id = <0x0002000b 0>;
qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
<0x0001001b 0x0102001a 0x0 0x0>,
diff --git a/arch/arm64/boot/dts/qcom/sdm710-qrd-sku2-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-qrd-sku2-overlay.dts
index 526fe6b..48dbd1f 100644
--- a/arch/arm64/boot/dts/qcom/sdm710-qrd-sku2-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm710-qrd-sku2-overlay.dts
@@ -23,7 +23,8 @@
/ {
model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L QRD SKU2";
compatible = "qcom,sdm670-qrd", "qcom,sdm670", "qcom,qrd";
- qcom,msm-id = <360 0x0>;
+ qcom,msm-id = <360 0x0>,
+ <393 0x0>;
qcom,board-id = <0x0012000b 0>;
qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
<0x0001001b 0x0102001a 0x0 0x0>,
diff --git a/arch/arm64/boot/dts/qcom/sdm710-tasha-codec-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-tasha-codec-cdp-overlay.dts
index 1632ebf..abfb46c 100644
--- a/arch/arm64/boot/dts/qcom/sdm710-tasha-codec-cdp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm710-tasha-codec-cdp-overlay.dts
@@ -25,7 +25,8 @@
/ {
model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L Tasha Codec CDP";
compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
- qcom,msm-id = <360 0x0>;
+ qcom,msm-id = <360 0x0>,
+ <393 0x0>;
qcom,board-id = <1 5>;
qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
<0x0001001b 0x0102001a 0x0 0x0>,
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-cdp-overlay.dts
index fe05472..078088f 100644
--- a/arch/arm64/boot/dts/qcom/sdm710-usbc-cdp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-cdp-overlay.dts
@@ -25,7 +25,8 @@
/ {
model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L, USB-C Audio, CDP";
compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
- qcom,msm-id = <360 0x0>;
+ qcom,msm-id = <360 0x0>,
+ <393 0x0>;
qcom,board-id = <1 2>;
qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
<0x0001001b 0x0102001a 0x0 0x0>,
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-cdp-overlay.dts
index 846bee4..f466ab9 100644
--- a/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-cdp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-cdp-overlay.dts
@@ -26,7 +26,8 @@
/ {
model = "Qualcomm Technologies, Inc. SDM710 PM660+PM660L, USB-C Audio, Ext. Audio Codec CDP";
compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
- qcom,msm-id = <360 0x0>;
+ qcom,msm-id = <360 0x0>,
+ <393 0x0>;
qcom,board-id = <1 3>;
qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
<0x0001001b 0x0102001a 0x0 0x0>,
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-mtp-overlay.dts
index bfc9a7f..2354504 100644
--- a/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-mtp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-mtp-overlay.dts
@@ -25,7 +25,8 @@
/ {
model = "Qualcomm Technologies, Inc. SDM710 PM660+PM660L, USB-C Audio, Ext. Audio Codec MTP";
compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
- qcom,msm-id = <360 0x0>;
+ qcom,msm-id = <360 0x0>,
+ <393 0x0>;
qcom,board-id = <8 3>;
qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
<0x0001001b 0x0102001a 0x0 0x0>,
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-cdp-overlay.dts
index f8642bb..ef8f6a3 100644
--- a/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-cdp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-cdp-overlay.dts
@@ -27,7 +27,8 @@
/ {
model = "Qualcomm Technologies, Inc. SDM710 PM660+PM660A, USB-C Audio, Ext. Audio Codec CDP";
compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
- qcom,msm-id = <360 0x0>;
+ qcom,msm-id = <360 0x0>,
+ <393 0x0>;
qcom,board-id = <1 3>;
qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
<0x0001001b 0x0002001a 0x0 0x0>,
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-mtp-overlay.dts
index c820950..fac39cc 100644
--- a/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-mtp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-mtp-overlay.dts
@@ -27,7 +27,8 @@
/ {
model = "Qualcomm Technologies, Inc. SDM710 PM660+PM660A, USB-C Audio, Ext. Audio Codec MTP";
compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
- qcom,msm-id = <360 0x0>;
+ qcom,msm-id = <360 0x0>,
+ <393 0x0>;
qcom,board-id = <8 3>;
qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
<0x0001001b 0x0002001a 0x0 0x0>,
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-mtp-overlay.dts
index a40ab83..dc5c80c 100644
--- a/arch/arm64/boot/dts/qcom/sdm710-usbc-mtp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-mtp-overlay.dts
@@ -25,7 +25,8 @@
/ {
model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L, USB-C Audio, MTP";
compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
- qcom,msm-id = <360 0x0>;
+ qcom,msm-id = <360 0x0>,
+ <393 0x0>;
qcom,board-id = <8 2>;
qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
<0x0001001b 0x0102001a 0x0 0x0>,
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-cdp-overlay.dts
index df4c2b9..51313c1 100644
--- a/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-cdp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-cdp-overlay.dts
@@ -26,7 +26,8 @@
/ {
model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A, USB-C Audio, CDP";
compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
- qcom,msm-id = <360 0x0>;
+ qcom,msm-id = <360 0x0>,
+ <393 0x0>;
qcom,board-id = <1 2>;
qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
<0x0001001b 0x0002001a 0x0 0x0>,
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-mtp-overlay.dts
index 35f9570..f9179c3 100644
--- a/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-mtp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-mtp-overlay.dts
@@ -26,7 +26,8 @@
/ {
model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A, USB-C Audio, MTP";
compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
- qcom,msm-id = <360 0x0>;
+ qcom,msm-id = <360 0x0>,
+ <393 0x0>;
qcom,board-id = <8 2>;
qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
<0x0001001b 0x0002001a 0x0 0x0>,
diff --git a/arch/arm64/boot/dts/qcom/sdm710.dtsi b/arch/arm64/boot/dts/qcom/sdm710.dtsi
index 347e846..3039d58 100644
--- a/arch/arm64/boot/dts/qcom/sdm710.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm710.dtsi
@@ -15,7 +15,8 @@
/ {
model = "Qualcomm Technologies, Inc. SDM710";
compatible = "qcom,sdm670";
- qcom,msm-id = <360 0x0>;
+ qcom,msm-id = <360 0x0>,
+ <393 0x0>;
};
&msm_gpu {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi b/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi
index e8f85a9..36f556f 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi
@@ -48,8 +48,10 @@
label = "kgsl-3d0";
compatible = "qcom,kgsl-3d0", "qcom,kgsl-3d";
status = "ok";
- reg = <0x5000000 0x40000>, <0x5061000 0x800>;
- reg-names = "kgsl_3d0_reg_memory", "kgsl_3d0_cx_dbgc_memory";
+ reg = <0x5000000 0x40000>, <0x5061000 0x800>,
+ <0x509e000 0x1000>;
+ reg-names = "kgsl_3d0_reg_memory", "kgsl_3d0_cx_dbgc_memory",
+ "cx_misc";
interrupts = <0 300 0>;
interrupt-names = "kgsl_3d0_irq";
qcom,id = <0>;
diff --git a/arch/arm64/boot/dts/qcom/sdw3100-apq8009w-alpha.dts b/arch/arm64/boot/dts/qcom/sdw3100-apq8009w-alpha.dts
index be8416f..63638fc 100644
--- a/arch/arm64/boot/dts/qcom/sdw3100-apq8009w-alpha.dts
+++ b/arch/arm64/boot/dts/qcom/sdw3100-apq8009w-alpha.dts
@@ -15,6 +15,7 @@
#include "msm8909-mtp.dtsi"
#include "msm8909w.dtsi"
+#include "msm8909w-gpu.dtsi"
#include "8909w-pm660.dtsi"
#include "apq8009w-bg-memory.dtsi"
#include "msm8909-audio-bg_codec.dtsi"
@@ -116,6 +117,13 @@
qcom,glinkpkt-ch-name = "RSB_CTRL";
qcom,glinkpkt-dev-name = "glink_pkt_bg_rsb_ctrl";
};
+
+ qcom,glinkpkt-bg-sso-ctrl {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "sso-ctrl";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_sso_ctrl";
+ };
};
spi@78B8000 { /* BLSP1 QUP4 */
diff --git a/arch/arm64/boot/dts/qcom/sdw3100-apq8009w-wtp.dts b/arch/arm64/boot/dts/qcom/sdw3100-apq8009w-wtp.dts
index 1457b92..1938875 100644
--- a/arch/arm64/boot/dts/qcom/sdw3100-apq8009w-wtp.dts
+++ b/arch/arm64/boot/dts/qcom/sdw3100-apq8009w-wtp.dts
@@ -15,6 +15,7 @@
#include "msm8909-mtp.dtsi"
#include "msm8909w.dtsi"
+#include "msm8909w-gpu.dtsi"
#include "8909w-pm660.dtsi"
#include "apq8009w-bg-memory.dtsi"
#include "msm8909-audio-bg_codec.dtsi"
@@ -134,6 +135,13 @@
qcom,glinkpkt-ch-name = "RSB_CTRL";
qcom,glinkpkt-dev-name = "glink_pkt_bg_rsb_ctrl";
};
+
+ qcom,glinkpkt-bg-sso-ctrl {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "sso-ctrl";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_sso_ctrl";
+ };
};
spi@78B8000 { /* BLSP1 QUP4 */
diff --git a/arch/arm64/boot/dts/qcom/sdw3100-msm8909w-1gb-wtp.dts b/arch/arm64/boot/dts/qcom/sdw3100-msm8909w-1gb-wtp.dts
index a66387e..b702ad0 100644
--- a/arch/arm64/boot/dts/qcom/sdw3100-msm8909w-1gb-wtp.dts
+++ b/arch/arm64/boot/dts/qcom/sdw3100-msm8909w-1gb-wtp.dts
@@ -137,6 +137,13 @@
qcom,glinkpkt-ch-name = "RSB_CTRL";
qcom,glinkpkt-dev-name = "glink_pkt_bg_rsb_ctrl";
};
+
+ qcom,glinkpkt-bg-sso-ctrl {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "sso-ctrl";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_sso_ctrl";
+ };
};
spi@78B8000 { /* BLSP1 QUP4 */
diff --git a/arch/arm64/boot/dts/qcom/sdw3100-msm8909w-wtp.dts b/arch/arm64/boot/dts/qcom/sdw3100-msm8909w-wtp.dts
index 761879f..d51e6da 100644
--- a/arch/arm64/boot/dts/qcom/sdw3100-msm8909w-wtp.dts
+++ b/arch/arm64/boot/dts/qcom/sdw3100-msm8909w-wtp.dts
@@ -136,6 +136,13 @@
qcom,glinkpkt-ch-name = "RSB_CTRL";
qcom,glinkpkt-dev-name = "glink_pkt_bg_rsb_ctrl";
};
+
+ qcom,glinkpkt-bg-sso-ctrl {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "sso-ctrl";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_sso_ctrl";
+ };
};
spi@78B8000 { /* BLSP1 QUP4 */
diff --git a/arch/arm64/boot/dts/qcom/sxr1120-audio-overlay.dtsi b/arch/arm64/boot/dts/qcom/sxr1120-audio-overlay.dtsi
index 0038ae7..9f42e38 100644
--- a/arch/arm64/boot/dts/qcom/sxr1120-audio-overlay.dtsi
+++ b/arch/arm64/boot/dts/qcom/sxr1120-audio-overlay.dtsi
@@ -115,6 +115,14 @@
compatible = "qcom,wcd-dsp-glink";
};
+ micbias_supply_en_gpio: msm_cdc_pinctrl@126 {
+ status = "okay";
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&micbias_supply_en_active>;
+ pinctrl-1 = <&micbias_supply_en_sleep>;
+ };
+
};
&slim_aud {
@@ -152,6 +160,9 @@
qcom,wdsp-cmpnt-dev-name = "tavil_codec";
+ qcom,has-micbias-supply-en-gpio;
+ qcom,micbias-supply-en-gpio-node = <&micbias_supply_en_gpio>;
+
wcd_spi_0: wcd_spi {
compatible = "qcom,wcd-spi-v2";
qcom,master-bus-num = <0>;
diff --git a/arch/arm64/boot/dts/qcom/sxr1120-lc-external-codec-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sxr1120-lc-external-codec-cdp-overlay.dts
index 315f43c..0c36abe 100644
--- a/arch/arm64/boot/dts/qcom/sxr1120-lc-external-codec-cdp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sxr1120-lc-external-codec-cdp-overlay.dts
@@ -30,3 +30,7 @@
qcom,msm-id = <370 0x0>;
qcom,board-id = <1 1>;
};
+
+&int_codec {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/qcom/sxr1120-lc-external-codec-cdp.dts b/arch/arm64/boot/dts/qcom/sxr1120-lc-external-codec-cdp.dts
index 7d5b715..3f1214b 100644
--- a/arch/arm64/boot/dts/qcom/sxr1120-lc-external-codec-cdp.dts
+++ b/arch/arm64/boot/dts/qcom/sxr1120-lc-external-codec-cdp.dts
@@ -24,3 +24,7 @@
compatible = "qcom,sxr1120-cdp", "qcom,sxr1120", "qcom,cdp";
qcom,board-id = <1 1>;
};
+
+&int_codec {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/qcom/sxr1120-lc-external-codec-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sxr1120-lc-external-codec-mtp-overlay.dts
index 4242d5e..e03506a 100644
--- a/arch/arm64/boot/dts/qcom/sxr1120-lc-external-codec-mtp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sxr1120-lc-external-codec-mtp-overlay.dts
@@ -31,3 +31,7 @@
qcom,msm-id = <370 0x0>;
qcom,board-id = <8 9>;
};
+
+&int_codec {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/qcom/sxr1120-lc-external-codec-mtp.dts b/arch/arm64/boot/dts/qcom/sxr1120-lc-external-codec-mtp.dts
index 164ef61..64866b2 100644
--- a/arch/arm64/boot/dts/qcom/sxr1120-lc-external-codec-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/sxr1120-lc-external-codec-mtp.dts
@@ -24,3 +24,7 @@
compatible = "qcom,sxr1120-mtp", "qcom,sxr1120", "qcom,mtp";
qcom,board-id = <8 9>;
};
+
+&int_codec {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/qcom/sxr1130.dtsi b/arch/arm64/boot/dts/qcom/sxr1130.dtsi
index 75707b1..bfab826 100644
--- a/arch/arm64/boot/dts/qcom/sxr1130.dtsi
+++ b/arch/arm64/boot/dts/qcom/sxr1130.dtsi
@@ -12,6 +12,7 @@
*/
#include "qcs605.dtsi"
+#include "msm-qvr-external.dtsi"
/ {
model = "Qualcomm Technologies, Inc. SXR1130";
diff --git a/arch/arm64/boot/dts/qcom/vbms-batterydata-mlp356477-2800mah.dtsi b/arch/arm64/boot/dts/qcom/vbms-batterydata-mlp356477-2800mah.dtsi
new file mode 100644
index 0000000..d3dd995
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/vbms-batterydata-mlp356477-2800mah.dtsi
@@ -0,0 +1,118 @@
+/* Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+qcom,mlp356477_2800mah {
+ qcom,fcc-mah = <4200>;
+ qcom,batt-id-kohm = <82>;
+ qcom,rbatt-capacitive-mohm = <50>;
+ qcom,default-rbatt-mohm = <148>;
+ qcom,max-voltage-uv = <4400000>;
+ qcom,v-cutoff-uv = <3400000>;
+ qcom,chg-term-ua = <100000>;
+ qcom,battery-type = "mlp356477_2800mah";
+
+ qcom,fcc-temp-lut {
+ qcom,lut-col-legend = <(-20) 0 25 40 60>;
+ qcom,lut-data = <2863 2856 2854 2852 2841>;
+ };
+
+ qcom,ibat-acc-lut {
+ qcom,lut-col-legend = <(-20) 0 25>;
+ qcom,lut-row-legend = <0 250 500 1000>;
+ qcom,lut-data = <2792 2798 2797>,
+ <618 2712 2780>,
+ <128 2440 2766>,
+ <14 1806 2724>;
+ };
+
+ qcom,pc-temp-ocv-lut {
+ qcom,lut-col-legend = <(-20) 0 25 40 60>;
+ qcom,lut-row-legend = <100 95 90 85 80>,
+ <75 70 65 60 55>,
+ <50 45 40 35 30>,
+ <25 20 16 13 11>,
+ <10 9 8 7 6>,
+ <5 4 3 2 1>,
+ <0>;
+ qcom,lut-data = <4390 4384 4378 4374 4366>,
+ <4252 4302 4314 4313 4307>,
+ <4160 4238 4256 4255 4250>,
+ <4103 4179 4200 4198 4194>,
+ <4014 4126 4144 4144 4138>,
+ <3962 4077 4092 4090 4086>,
+ <3913 4022 4042 4042 4037>,
+ <3875 3960 3993 3995 3992>,
+ <3850 3914 3946 3948 3946>,
+ <3832 3872 3892 3894 3892>,
+ <3816 3839 3858 3860 3859>,
+ <3802 3814 3832 3834 3832>,
+ <3787 3798 3810 3812 3811>,
+ <3771 3785 3792 3794 3792>,
+ <3754 3772 3774 3774 3768>,
+ <3734 3756 3756 3749 3738>,
+ <3712 3734 3734 3726 3714>,
+ <3692 3712 3712 3704 3690>,
+ <3672 3698 3692 3684 3674>,
+ <3656 3689 3686 3680 3669>,
+ <3646 3685 3685 3679 3668>,
+ <3634 3681 3683 3678 3666>,
+ <3620 3676 3680 3676 3664>,
+ <3604 3668 3676 3670 3654>,
+ <3580 3651 3660 3652 3630>,
+ <3550 3620 3625 3614 3590>,
+ <3508 3574 3575 3565 3538>,
+ <3445 3510 3510 3500 3470>,
+ <3350 3420 3421 3413 3377>,
+ <3182 3274 3282 3266 3232>,
+ <3000 3000 3000 3000 3000>;
+ };
+
+ qcom,rbatt-sf-lut {
+ qcom,lut-col-legend = <(-20) 0 25 40 60>;
+ qcom,lut-row-legend = <100 95 90 85 80>,
+ <75 70 65 60 55>,
+ <50 45 40 35 30>,
+ <25 20 16 13 11>,
+ <10 9 8 7 6>,
+ <5 4 3 2 1>;
+ qcom,lut-data = <1593 376 99 75 68>,
+ <1591 376 99 75 68>,
+ <1455 370 99 75 68>,
+ <1391 362 99 76 67>,
+ <1280 358 99 76 69>,
+ <1245 363 102 78 70>,
+ <1213 358 107 80 72>,
+ <1200 330 112 84 74>,
+ <1207 322 116 89 77>,
+ <1228 311 97 76 68>,
+ <1261 309 94 74 68>,
+ <1309 312 94 74 68>,
+ <1411 320 96 76 70>,
+ <1588 337 97 78 72>,
+ <1827 364 99 79 71>,
+ <2133 397 97 75 69>,
+ <2536 438 97 74 69>,
+ <2964 476 100 76 68>,
+ <3313 509 100 74 68>,
+ <3539 520 100 76 68>,
+ <3793 536 101 76 70>,
+ <4098 558 104 78 72>,
+ <4461 581 108 82 76>,
+ <4893 605 112 84 77>,
+ <5421 626 114 82 72>,
+ <6107 646 111 79 72>,
+ <7007 676 114 80 72>,
+ <8309 727 119 82 76>,
+ <10285 857 130 89 84>,
+ <14336 1715 261 178 168>;
+ };
+};
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index dab2cb0..b4c4d82 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -260,6 +260,8 @@
CONFIG_GPIO_PCA953X=y
CONFIG_GPIO_PCA953X_IRQ=y
CONFIG_GPIO_MAX77620=y
+CONFIG_POWER_AVS=y
+CONFIG_ROCKCHIP_IODOMAIN=y
CONFIG_POWER_RESET_MSM=y
CONFIG_BATTERY_BQ27XXX=y
CONFIG_POWER_RESET_XGENE=y
diff --git a/arch/arm64/configs/msm8937-perf_defconfig b/arch/arm64/configs/msm8937-perf_defconfig
index 1e16d20..40064cb 100644
--- a/arch/arm64/configs/msm8937-perf_defconfig
+++ b/arch/arm64/configs/msm8937-perf_defconfig
@@ -57,6 +57,7 @@
CONFIG_ARCH_QCOM=y
CONFIG_ARCH_MSM8937=y
CONFIG_ARCH_MSM8917=y
+CONFIG_ARCH_QM215=y
CONFIG_ARCH_SDM429=y
CONFIG_ARCH_SDM439=y
# CONFIG_ARM64_ERRATUM_1024718 is not set
@@ -263,6 +264,7 @@
CONFIG_BLK_DEV_DM=y
CONFIG_DM_CRYPT=y
CONFIG_DM_REQ_CRYPT=y
+CONFIG_DM_DEFAULT_KEY=y
CONFIG_DM_UEVENT=y
CONFIG_DM_VERITY=y
CONFIG_DM_VERITY_FEC=y
@@ -352,10 +354,13 @@
CONFIG_QCOM_DLOAD_MODE=y
CONFIG_QPNP_FG=y
CONFIG_SMB135X_CHARGER=y
+CONFIG_SMB1360_CHARGER_FG=y
CONFIG_SMB1355_SLAVE_CHARGER=y
CONFIG_SMB1351_USB_CHARGER=y
CONFIG_QPNP_SMB5=y
CONFIG_QPNP_SMBCHARGER=y
+CONFIG_QPNP_VM_BMS=y
+CONFIG_QPNP_LINEAR_CHARGER=y
CONFIG_QPNP_TYPEC=y
CONFIG_QPNP_QG=y
CONFIG_MSM_APM=y
@@ -509,6 +514,7 @@
CONFIG_LEDS_QPNP_WLED=y
CONFIG_LEDS_QPNP_HAPTICS=y
CONFIG_LEDS_QPNP_VIBRATOR_LDO=y
+CONFIG_LEDS_QPNP_VIBRATOR=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_EDAC=y
diff --git a/arch/arm64/configs/msm8937_defconfig b/arch/arm64/configs/msm8937_defconfig
index e4ca873..fda1429 100644
--- a/arch/arm64/configs/msm8937_defconfig
+++ b/arch/arm64/configs/msm8937_defconfig
@@ -58,6 +58,7 @@
CONFIG_ARCH_QCOM=y
CONFIG_ARCH_MSM8937=y
CONFIG_ARCH_MSM8917=y
+CONFIG_ARCH_QM215=y
CONFIG_ARCH_SDM429=y
CONFIG_ARCH_SDM439=y
# CONFIG_ARM64_ERRATUM_1024718 is not set
@@ -269,6 +270,7 @@
CONFIG_BLK_DEV_DM=y
CONFIG_DM_CRYPT=y
CONFIG_DM_REQ_CRYPT=y
+CONFIG_DM_DEFAULT_KEY=y
CONFIG_DM_UEVENT=y
CONFIG_DM_VERITY=y
CONFIG_DM_VERITY_FEC=y
@@ -359,10 +361,13 @@
CONFIG_QCOM_DLOAD_MODE=y
CONFIG_QPNP_FG=y
CONFIG_SMB135X_CHARGER=y
+CONFIG_SMB1360_CHARGER_FG=y
CONFIG_SMB1355_SLAVE_CHARGER=y
CONFIG_SMB1351_USB_CHARGER=y
CONFIG_QPNP_SMB5=y
CONFIG_QPNP_SMBCHARGER=y
+CONFIG_QPNP_VM_BMS=y
+CONFIG_QPNP_LINEAR_CHARGER=y
CONFIG_QPNP_TYPEC=y
CONFIG_QPNP_QG=y
CONFIG_MSM_APM=y
@@ -520,6 +525,7 @@
CONFIG_LEDS_QPNP_WLED=y
CONFIG_LEDS_QPNP_HAPTICS=y
CONFIG_LEDS_QPNP_VIBRATOR_LDO=y
+CONFIG_LEDS_QPNP_VIBRATOR=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_EDAC=y
diff --git a/arch/arm64/configs/msm8953-perf_defconfig b/arch/arm64/configs/msm8953-perf_defconfig
index a66ea31..3039177 100644
--- a/arch/arm64/configs/msm8953-perf_defconfig
+++ b/arch/arm64/configs/msm8953-perf_defconfig
@@ -265,6 +265,7 @@
CONFIG_BLK_DEV_DM=y
CONFIG_DM_CRYPT=y
CONFIG_DM_REQ_CRYPT=y
+CONFIG_DM_DEFAULT_KEY=y
CONFIG_DM_UEVENT=y
CONFIG_DM_VERITY=y
CONFIG_DM_VERITY_FEC=y
diff --git a/arch/arm64/configs/msm8953_defconfig b/arch/arm64/configs/msm8953_defconfig
index 34d16db..4620bec 100644
--- a/arch/arm64/configs/msm8953_defconfig
+++ b/arch/arm64/configs/msm8953_defconfig
@@ -271,6 +271,7 @@
CONFIG_BLK_DEV_DM=y
CONFIG_DM_CRYPT=y
CONFIG_DM_REQ_CRYPT=y
+CONFIG_DM_DEFAULT_KEY=y
CONFIG_DM_UEVENT=y
CONFIG_DM_VERITY=y
CONFIG_DM_VERITY_FEC=y
diff --git a/arch/arm64/configs/sdm670-perf_defconfig b/arch/arm64/configs/sdm670-perf_defconfig
index fcecc6b..d1ede86f 100644
--- a/arch/arm64/configs/sdm670-perf_defconfig
+++ b/arch/arm64/configs/sdm670-perf_defconfig
@@ -361,7 +361,6 @@
CONFIG_MFD_SPMI_PMIC=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_PROXY_CONSUMER=y
-CONFIG_REGULATOR_CPRH_KBSS=y
CONFIG_REGULATOR_QPNP_LABIBB=y
CONFIG_REGULATOR_QPNP_LCDB=y
CONFIG_REGULATOR_QPNP_OLEDB=y
diff --git a/arch/arm64/configs/sdm670_defconfig b/arch/arm64/configs/sdm670_defconfig
index fa802d2..747d373 100644
--- a/arch/arm64/configs/sdm670_defconfig
+++ b/arch/arm64/configs/sdm670_defconfig
@@ -369,7 +369,6 @@
CONFIG_MFD_SPMI_PMIC=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_PROXY_CONSUMER=y
-CONFIG_REGULATOR_CPRH_KBSS=y
CONFIG_REGULATOR_QPNP_LABIBB=y
CONFIG_REGULATOR_QPNP_LCDB=y
CONFIG_REGULATOR_QPNP_OLEDB=y
@@ -625,6 +624,7 @@
CONFIG_NLS_ISO8859_1=y
CONFIG_PRINTK_TIME=y
CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_MODULE_LOAD_INFO=y
CONFIG_DEBUG_INFO=y
CONFIG_PAGE_OWNER=y
CONFIG_PAGE_OWNER_ENABLE_DEFAULT=y
diff --git a/arch/arm64/configs/sdm845_defconfig b/arch/arm64/configs/sdm845_defconfig
index c9f60b5..d3ad4ef 100644
--- a/arch/arm64/configs/sdm845_defconfig
+++ b/arch/arm64/configs/sdm845_defconfig
@@ -620,6 +620,7 @@
CONFIG_NLS_ISO8859_1=y
CONFIG_PRINTK_TIME=y
CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_MODULE_LOAD_INFO=y
CONFIG_DEBUG_INFO=y
CONFIG_PAGE_OWNER=y
CONFIG_PAGE_OWNER_ENABLE_DEFAULT=y
diff --git a/arch/arm64/include/asm/alternative.h b/arch/arm64/include/asm/alternative.h
index 6e1cb8c..7e842dc 100644
--- a/arch/arm64/include/asm/alternative.h
+++ b/arch/arm64/include/asm/alternative.h
@@ -4,6 +4,8 @@
#include <asm/cpucaps.h>
#include <asm/insn.h>
+#define ARM64_CB_PATCH ARM64_NCAPS
+
#ifndef __ASSEMBLY__
#include <linux/init.h>
@@ -11,6 +13,8 @@
#include <linux/stddef.h>
#include <linux/stringify.h>
+extern int alternatives_applied;
+
struct alt_instr {
s32 orig_offset; /* offset to original instruction */
s32 alt_offset; /* offset to replacement instruction */
@@ -19,12 +23,19 @@
u8 alt_len; /* size of new instruction(s), <= orig_len */
};
+typedef void (*alternative_cb_t)(struct alt_instr *alt,
+ __le32 *origptr, __le32 *updptr, int nr_inst);
+
void __init apply_alternatives_all(void);
void apply_alternatives(void *start, size_t length);
-#define ALTINSTR_ENTRY(feature) \
+#define ALTINSTR_ENTRY(feature,cb) \
" .word 661b - .\n" /* label */ \
+ " .if " __stringify(cb) " == 0\n" \
" .word 663f - .\n" /* new instruction */ \
+ " .else\n" \
+ " .word " __stringify(cb) "- .\n" /* callback */ \
+ " .endif\n" \
" .hword " __stringify(feature) "\n" /* feature bit */ \
" .byte 662b-661b\n" /* source len */ \
" .byte 664f-663f\n" /* replacement len */
@@ -42,15 +53,18 @@
* but most assemblers die if insn1 or insn2 have a .inst. This should
* be fixed in a binutils release posterior to 2.25.51.0.2 (anything
* containing commit 4e4d08cf7399b606 or c1baaddf8861).
+ *
+ * Alternatives with callbacks do not generate replacement instructions.
*/
-#define __ALTERNATIVE_CFG(oldinstr, newinstr, feature, cfg_enabled) \
+#define __ALTERNATIVE_CFG(oldinstr, newinstr, feature, cfg_enabled, cb) \
".if "__stringify(cfg_enabled)" == 1\n" \
"661:\n\t" \
oldinstr "\n" \
"662:\n" \
".pushsection .altinstructions,\"a\"\n" \
- ALTINSTR_ENTRY(feature) \
+ ALTINSTR_ENTRY(feature,cb) \
".popsection\n" \
+ " .if " __stringify(cb) " == 0\n" \
".pushsection .altinstr_replacement, \"a\"\n" \
"663:\n\t" \
newinstr "\n" \
@@ -58,11 +72,17 @@
".popsection\n\t" \
".org . - (664b-663b) + (662b-661b)\n\t" \
".org . - (662b-661b) + (664b-663b)\n" \
+ ".else\n\t" \
+ "663:\n\t" \
+ "664:\n\t" \
+ ".endif\n" \
".endif\n"
#define _ALTERNATIVE_CFG(oldinstr, newinstr, feature, cfg, ...) \
- __ALTERNATIVE_CFG(oldinstr, newinstr, feature, IS_ENABLED(cfg))
+ __ALTERNATIVE_CFG(oldinstr, newinstr, feature, IS_ENABLED(cfg), 0)
+#define ALTERNATIVE_CB(oldinstr, cb) \
+ __ALTERNATIVE_CFG(oldinstr, "NOT_AN_INSTRUCTION", ARM64_CB_PATCH, 1, cb)
#else
#include <asm/assembler.h>
@@ -129,6 +149,14 @@
661:
.endm
+.macro alternative_cb cb
+ .set .Lasm_alt_mode, 0
+ .pushsection .altinstructions, "a"
+ altinstruction_entry 661f, \cb, ARM64_CB_PATCH, 662f-661f, 0
+ .popsection
+661:
+.endm
+
/*
* Provide the other half of the alternative code sequence.
*/
@@ -155,6 +183,13 @@
.endm
/*
+ * Callback-based alternative epilogue
+ */
+.macro alternative_cb_end
+662:
+.endm
+
+/*
* Provides a trivial alternative or default sequence consisting solely
* of NOPs. The number of NOPs is chosen automatically to match the
* previous case.
diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index c7749d8..8351201 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -266,7 +266,11 @@
*/
.macro adr_this_cpu, dst, sym, tmp
adr_l \dst, \sym
+alternative_if_not ARM64_HAS_VIRT_HOST_EXTN
mrs \tmp, tpidr_el1
+alternative_else
+ mrs \tmp, tpidr_el2
+alternative_endif
add \dst, \dst, \tmp
.endm
@@ -277,7 +281,11 @@
*/
.macro ldr_this_cpu dst, sym, tmp
adr_l \dst, \sym
+alternative_if_not ARM64_HAS_VIRT_HOST_EXTN
mrs \tmp, tpidr_el1
+alternative_else
+ mrs \tmp, tpidr_el2
+alternative_endif
ldr \dst, [\dst, \tmp]
.endm
diff --git a/arch/arm64/include/asm/cmpxchg.h b/arch/arm64/include/asm/cmpxchg.h
index ae852ad..0f2e1ab 100644
--- a/arch/arm64/include/asm/cmpxchg.h
+++ b/arch/arm64/include/asm/cmpxchg.h
@@ -229,7 +229,9 @@
unsigned long tmp; \
\
asm volatile( \
- " ldxr" #sz "\t%" #w "[tmp], %[v]\n" \
+ " sevl\n" \
+ " wfe\n" \
+ " ldxr" #sz "\t%" #w "[tmp], %[v]\n" \
" eor %" #w "[tmp], %" #w "[tmp], %" #w "[val]\n" \
" cbnz %" #w "[tmp], 1f\n" \
" wfe\n" \
diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
index d64bf94..7010779a 100644
--- a/arch/arm64/include/asm/cpucaps.h
+++ b/arch/arm64/include/asm/cpucaps.h
@@ -34,11 +34,10 @@
#define ARM64_HAS_32BIT_EL0 13
#define ARM64_HYP_OFFSET_LOW 14
#define ARM64_MISMATCHED_CACHE_LINE_SIZE 15
-
#define ARM64_UNMAP_KERNEL_AT_EL0 16
-
#define ARM64_HARDEN_BRANCH_PREDICTOR 17
+#define ARM64_SSBD 18
-#define ARM64_NCAPS 18
+#define ARM64_NCAPS 19
#endif /* __ASM_CPUCAPS_H */
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 829331c..ddaeb43 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -229,6 +229,28 @@
!cpus_have_cap(ARM64_HAS_PAN);
}
+#define ARM64_SSBD_UNKNOWN -1
+#define ARM64_SSBD_FORCE_DISABLE 0
+#define ARM64_SSBD_KERNEL 1
+#define ARM64_SSBD_FORCE_ENABLE 2
+#define ARM64_SSBD_MITIGATED 3
+
+static inline int arm64_get_ssbd_state(void)
+{
+#ifdef CONFIG_ARM64_SSBD
+ extern int ssbd_state;
+ return ssbd_state;
+#else
+ return ARM64_SSBD_UNKNOWN;
+#endif
+}
+
+#ifdef CONFIG_ARM64_SSBD
+void arm64_set_ssbd_mitigation(bool state);
+#else
+static inline void arm64_set_ssbd_mitigation(bool state) {}
+#endif
+
#endif /* __ASSEMBLY__ */
#endif
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index ec3553eb..8f5cf83 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -33,6 +33,10 @@
#define KVM_ARM64_DEBUG_DIRTY_SHIFT 0
#define KVM_ARM64_DEBUG_DIRTY (1 << KVM_ARM64_DEBUG_DIRTY_SHIFT)
+#define VCPU_WORKAROUND_2_FLAG_SHIFT 0
+#define VCPU_WORKAROUND_2_FLAG (_AC(1, UL) << VCPU_WORKAROUND_2_FLAG_SHIFT)
+
+/* Translate a kernel address of @sym into its equivalent linear mapping */
#define kvm_ksym_ref(sym) \
({ \
void *val = &sym; \
@@ -65,6 +69,43 @@
extern u32 __init_stage2_translation(void);
+/* Home-grown __this_cpu_{ptr,read} variants that always work at HYP */
+#define __hyp_this_cpu_ptr(sym) \
+ ({ \
+ void *__ptr = hyp_symbol_addr(sym); \
+ __ptr += read_sysreg(tpidr_el2); \
+ (typeof(&sym))__ptr; \
+ })
+
+#define __hyp_this_cpu_read(sym) \
+ ({ \
+ *__hyp_this_cpu_ptr(sym); \
+ })
+
+#else /* __ASSEMBLY__ */
+
+.macro hyp_adr_this_cpu reg, sym, tmp
+ adr_l \reg, \sym
+ mrs \tmp, tpidr_el2
+ add \reg, \reg, \tmp
+.endm
+
+.macro hyp_ldr_this_cpu reg, sym, tmp
+ adr_l \reg, \sym
+ mrs \tmp, tpidr_el2
+ ldr \reg, [\reg, \tmp]
+.endm
+
+.macro get_host_ctxt reg, tmp
+ hyp_adr_this_cpu \reg, kvm_host_cpu_state, \tmp
+.endm
+
+.macro get_vcpu_ptr vcpu, ctxt
+ get_host_ctxt \ctxt, \vcpu
+ ldr \vcpu, [\ctxt, #HOST_CONTEXT_VCPU]
+ kern_hyp_va \vcpu
+.endm
+
#endif
#endif /* __ARM_KVM_ASM_H__ */
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 2abb449..4cdfbd0 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -197,6 +197,8 @@
u64 sys_regs[NR_SYS_REGS];
u32 copro[NR_COPRO_REGS];
};
+
+ struct kvm_vcpu *__hyp_running_vcpu;
};
typedef struct kvm_cpu_context kvm_cpu_context_t;
@@ -211,6 +213,9 @@
/* Exception Information */
struct kvm_vcpu_fault_info fault;
+ /* State of various workarounds, see kvm_asm.h for bit assignment */
+ u64 workaround_flags;
+
/* Guest debug state */
u64 debug_flags;
@@ -354,10 +359,15 @@
struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
+void __kvm_set_tpidr_el2(u64 tpidr_el2);
+DECLARE_PER_CPU(kvm_cpu_context_t, kvm_host_cpu_state);
+
static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
unsigned long hyp_stack_ptr,
unsigned long vector_ptr)
{
+ u64 tpidr_el2;
+
/*
* Call initialization code, and switch to the full blown HYP code.
* If the cpucaps haven't been finalized yet, something has gone very
@@ -366,6 +376,16 @@
*/
BUG_ON(!static_branch_likely(&arm64_const_caps_ready));
__kvm_call_hyp((void *)pgd_ptr, hyp_stack_ptr, vector_ptr);
+
+ /*
+ * Calculate the raw per-cpu offset without a translation from the
+ * kernel's mapping to the linear mapping, and store it in tpidr_el2
+ * so that we can use adr_l to access per-cpu variables in EL2.
+ */
+ tpidr_el2 = (u64)this_cpu_ptr(&kvm_host_cpu_state)
+ - (u64)kvm_ksym_ref(kvm_host_cpu_state);
+
+ kvm_call_hyp(__kvm_set_tpidr_el2, tpidr_el2);
}
void __kvm_hyp_teardown(void);
@@ -405,4 +425,27 @@
return cpus_have_const_cap(ARM64_HARDEN_BRANCH_PREDICTOR);
}
+#define KVM_SSBD_UNKNOWN -1
+#define KVM_SSBD_FORCE_DISABLE 0
+#define KVM_SSBD_KERNEL 1
+#define KVM_SSBD_FORCE_ENABLE 2
+#define KVM_SSBD_MITIGATED 3
+
+static inline int kvm_arm_have_ssbd(void)
+{
+ switch (arm64_get_ssbd_state()) {
+ case ARM64_SSBD_FORCE_DISABLE:
+ return KVM_SSBD_FORCE_DISABLE;
+ case ARM64_SSBD_KERNEL:
+ return KVM_SSBD_KERNEL;
+ case ARM64_SSBD_FORCE_ENABLE:
+ return KVM_SSBD_FORCE_ENABLE;
+ case ARM64_SSBD_MITIGATED:
+ return KVM_SSBD_MITIGATED;
+ case ARM64_SSBD_UNKNOWN:
+ default:
+ return KVM_SSBD_UNKNOWN;
+ }
+}
+
#endif /* __ARM64_KVM_HOST_H__ */
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index ecc2ae6..4287acb 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -131,6 +131,26 @@
#define kern_hyp_va(v) ((typeof(v))(__kern_hyp_va((unsigned long)(v))))
/*
+ * Obtain the PC-relative address of a kernel symbol
+ * s: symbol
+ *
+ * The goal of this macro is to return a symbol's address based on a
+ * PC-relative computation, as opposed to a loading the VA from a
+ * constant pool or something similar. This works well for HYP, as an
+ * absolute VA is guaranteed to be wrong. Only use this if trying to
+ * obtain the address of a symbol (i.e. not something you obtained by
+ * following a pointer).
+ */
+#define hyp_symbol_addr(s) \
+ ({ \
+ typeof(s) *addr; \
+ asm("adrp %0, %1\n" \
+ "add %0, %0, :lo12:%1\n" \
+ : "=r" (addr) : "S" (&s)); \
+ addr; \
+ })
+
+/*
* We currently only support a 40bit IPA.
*/
#define KVM_PHYS_SHIFT (40)
@@ -367,5 +387,29 @@
}
#endif
+#ifdef CONFIG_ARM64_SSBD
+DECLARE_PER_CPU_READ_MOSTLY(u64, arm64_ssbd_callback_required);
+
+static inline int hyp_map_aux_data(void)
+{
+ int cpu, err;
+
+ for_each_possible_cpu(cpu) {
+ u64 *ptr;
+
+ ptr = per_cpu_ptr(&arm64_ssbd_callback_required, cpu);
+ err = create_hyp_mappings(ptr, ptr + 1, PAGE_HYP);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+#else
+static inline int hyp_map_aux_data(void)
+{
+ return 0;
+}
+#endif
+
#endif /* __ASSEMBLY__ */
#endif /* __ARM64_KVM_MMU_H__ */
diff --git a/arch/arm64/include/asm/percpu.h b/arch/arm64/include/asm/percpu.h
index d7a3c62..a2f6bd2 100644
--- a/arch/arm64/include/asm/percpu.h
+++ b/arch/arm64/include/asm/percpu.h
@@ -17,10 +17,14 @@
#define __ASM_PERCPU_H
#include <asm/stack_pointer.h>
+#include <asm/alternative.h>
static inline void set_my_cpu_offset(unsigned long off)
{
- asm volatile("msr tpidr_el1, %0" :: "r" (off) : "memory");
+ asm volatile(ALTERNATIVE("msr tpidr_el1, %0",
+ "msr tpidr_el2, %0",
+ ARM64_HAS_VIRT_HOST_EXTN)
+ :: "r" (off) : "memory");
}
static inline unsigned long __my_cpu_offset(void)
@@ -31,7 +35,10 @@
* We want to allow caching the value, so avoid using volatile and
* instead use a fake stack read to hazard against barrier().
*/
- asm("mrs %0, tpidr_el1" : "=r" (off) :
+ asm(ALTERNATIVE("mrs %0, tpidr_el1",
+ "mrs %0, tpidr_el2",
+ ARM64_HAS_VIRT_HOST_EXTN)
+ : "=r" (off) :
"Q" (*(const unsigned long *)current_stack_pointer));
return off;
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index ba3a69a..b57a191 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -89,6 +89,7 @@
#define TIF_RESTORE_SIGMASK 20
#define TIF_SINGLESTEP 21
#define TIF_32BIT 22 /* 32bit process */
+#define TIF_SSBD 23 /* Wants SSB mitigation */
#define TIF_MM_RELEASED 24
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 446eabd..cc3c030 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -51,6 +51,7 @@
arm64-obj-$(CONFIG_HIBERNATION) += hibernate.o hibernate-asm.o
arm64-obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o \
cpu-reset.o
+arm64-obj-$(CONFIG_ARM64_SSBD) += ssbd.o
ifeq ($(CONFIG_KVM),y)
arm64-obj-$(CONFIG_HARDEN_BRANCH_PREDICTOR) += bpi.o
diff --git a/arch/arm64/kernel/alternative.c b/arch/arm64/kernel/alternative.c
index 06d650f..0917480 100644
--- a/arch/arm64/kernel/alternative.c
+++ b/arch/arm64/kernel/alternative.c
@@ -28,10 +28,12 @@
#include <asm/sections.h>
#include <linux/stop_machine.h>
-#define __ALT_PTR(a,f) (u32 *)((void *)&(a)->f + (a)->f)
+#define __ALT_PTR(a,f) ((void *)&(a)->f + (a)->f)
#define ALT_ORIG_PTR(a) __ALT_PTR(a, orig_offset)
#define ALT_REPL_PTR(a) __ALT_PTR(a, alt_offset)
+int alternatives_applied;
+
struct alt_region {
struct alt_instr *begin;
struct alt_instr *end;
@@ -105,31 +107,52 @@
return insn;
}
+static void patch_alternative(struct alt_instr *alt,
+ __le32 *origptr, __le32 *updptr, int nr_inst)
+{
+ __le32 *replptr;
+ int i;
+
+ replptr = ALT_REPL_PTR(alt);
+ for (i = 0; i < nr_inst; i++) {
+ u32 insn;
+
+ insn = get_alt_insn(alt, origptr + i, replptr + i);
+ updptr[i] = cpu_to_le32(insn);
+ }
+}
+
static void __apply_alternatives(void *alt_region)
{
struct alt_instr *alt;
struct alt_region *region = alt_region;
- u32 *origptr, *replptr;
+ __le32 *origptr;
+ alternative_cb_t alt_cb;
for (alt = region->begin; alt < region->end; alt++) {
- u32 insn;
- int i, nr_inst;
+ int nr_inst;
- if (!cpus_have_cap(alt->cpufeature))
+ /* Use ARM64_CB_PATCH as an unconditional patch */
+ if (alt->cpufeature < ARM64_CB_PATCH &&
+ !cpus_have_cap(alt->cpufeature))
continue;
- BUG_ON(alt->alt_len != alt->orig_len);
+ if (alt->cpufeature == ARM64_CB_PATCH)
+ BUG_ON(alt->alt_len != 0);
+ else
+ BUG_ON(alt->alt_len != alt->orig_len);
pr_info_once("patching kernel code\n");
origptr = ALT_ORIG_PTR(alt);
- replptr = ALT_REPL_PTR(alt);
- nr_inst = alt->alt_len / sizeof(insn);
+ nr_inst = alt->orig_len / AARCH64_INSN_SIZE;
- for (i = 0; i < nr_inst; i++) {
- insn = get_alt_insn(alt, origptr + i, replptr + i);
- *(origptr + i) = cpu_to_le32(insn);
- }
+ if (alt->cpufeature < ARM64_CB_PATCH)
+ alt_cb = patch_alternative;
+ else
+ alt_cb = ALT_REPL_PTR(alt);
+
+ alt_cb(alt, origptr, origptr, nr_inst);
flush_icache_range((uintptr_t)origptr,
(uintptr_t)(origptr + nr_inst));
@@ -142,7 +165,6 @@
*/
static int __apply_alternatives_multi_stop(void *unused)
{
- static int patched = 0;
struct alt_region region = {
.begin = (struct alt_instr *)__alt_instructions,
.end = (struct alt_instr *)__alt_instructions_end,
@@ -150,14 +172,14 @@
/* We always have a CPU 0 at this point (__init) */
if (smp_processor_id()) {
- while (!READ_ONCE(patched))
+ while (!READ_ONCE(alternatives_applied))
cpu_relax();
isb();
} else {
- BUG_ON(patched);
+ BUG_ON(alternatives_applied);
__apply_alternatives(®ion);
/* Barriers provided by the cache flushing */
- WRITE_ONCE(patched, 1);
+ WRITE_ONCE(alternatives_applied, 1);
}
return 0;
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 5d2d356..61ae19e 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -130,11 +130,13 @@
BLANK();
#ifdef CONFIG_KVM_ARM_HOST
DEFINE(VCPU_CONTEXT, offsetof(struct kvm_vcpu, arch.ctxt));
+ DEFINE(VCPU_WORKAROUND_FLAGS, offsetof(struct kvm_vcpu, arch.workaround_flags));
DEFINE(CPU_GP_REGS, offsetof(struct kvm_cpu_context, gp_regs));
DEFINE(CPU_USER_PT_REGS, offsetof(struct kvm_regs, regs));
DEFINE(CPU_FP_REGS, offsetof(struct kvm_regs, fp_regs));
DEFINE(VCPU_FPEXC32_EL2, offsetof(struct kvm_vcpu, arch.ctxt.sys_regs[FPEXC32_EL2]));
DEFINE(VCPU_HOST_CONTEXT, offsetof(struct kvm_vcpu, arch.host_cpu_context));
+ DEFINE(HOST_CONTEXT_VCPU, offsetof(struct kvm_cpu_context, __hyp_running_vcpu));
#endif
#ifdef CONFIG_CPU_PM
DEFINE(CPU_SUSPEND_SZ, sizeof(struct cpu_suspend_ctx));
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index e7908c9..eca708b 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -20,6 +20,9 @@
#include <asm/cpu.h>
#include <asm/cputype.h>
#include <asm/cpufeature.h>
+#include <uapi/linux/psci.h>
+#include <linux/arm-smccc.h>
+#include <linux/psci.h>
static bool __maybe_unused
is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope)
@@ -132,10 +135,6 @@
__install_bp_hardening_cb(fn, hyp_vecs_start, hyp_vecs_end);
}
-#include <uapi/linux/psci.h>
-#include <linux/arm-smccc.h>
-#include <linux/psci.h>
-
#ifdef CONFIG_PSCI_BP_HARDENING
static int enable_psci_bp_hardening(void *data)
{
@@ -204,6 +203,178 @@
}
#endif /* CONFIG_HARDEN_BRANCH_PREDICTOR */
+#ifdef CONFIG_ARM64_SSBD
+DEFINE_PER_CPU_READ_MOSTLY(u64, arm64_ssbd_callback_required);
+
+int ssbd_state __read_mostly = ARM64_SSBD_KERNEL;
+
+static const struct ssbd_options {
+ const char *str;
+ int state;
+} ssbd_options[] = {
+ { "force-on", ARM64_SSBD_FORCE_ENABLE, },
+ { "force-off", ARM64_SSBD_FORCE_DISABLE, },
+ { "kernel", ARM64_SSBD_KERNEL, },
+};
+
+static int __init ssbd_cfg(char *buf)
+{
+ int i;
+
+ if (!buf || !buf[0])
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(ssbd_options); i++) {
+ int len = strlen(ssbd_options[i].str);
+
+ if (strncmp(buf, ssbd_options[i].str, len))
+ continue;
+
+ ssbd_state = ssbd_options[i].state;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+early_param("ssbd", ssbd_cfg);
+
+void __init arm64_update_smccc_conduit(struct alt_instr *alt,
+ __le32 *origptr, __le32 *updptr,
+ int nr_inst)
+{
+ u32 insn;
+
+ BUG_ON(nr_inst != 1);
+
+ switch (psci_ops.conduit) {
+ case PSCI_CONDUIT_HVC:
+ insn = aarch64_insn_get_hvc_value();
+ break;
+ case PSCI_CONDUIT_SMC:
+ insn = aarch64_insn_get_smc_value();
+ break;
+ default:
+ return;
+ }
+
+ *updptr = cpu_to_le32(insn);
+}
+
+void __init arm64_enable_wa2_handling(struct alt_instr *alt,
+ __le32 *origptr, __le32 *updptr,
+ int nr_inst)
+{
+ BUG_ON(nr_inst != 1);
+ /*
+ * Only allow mitigation on EL1 entry/exit and guest
+ * ARCH_WORKAROUND_2 handling if the SSBD state allows it to
+ * be flipped.
+ */
+ if (arm64_get_ssbd_state() == ARM64_SSBD_KERNEL)
+ *updptr = cpu_to_le32(aarch64_insn_gen_nop());
+}
+
+void arm64_set_ssbd_mitigation(bool state)
+{
+ switch (psci_ops.conduit) {
+ case PSCI_CONDUIT_HVC:
+ arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_WORKAROUND_2, state, NULL);
+ break;
+
+ case PSCI_CONDUIT_SMC:
+ arm_smccc_1_1_smc(ARM_SMCCC_ARCH_WORKAROUND_2, state, NULL);
+ break;
+
+ default:
+ WARN_ON_ONCE(1);
+ break;
+ }
+}
+
+static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry,
+ int scope)
+{
+ struct arm_smccc_res res;
+ bool required = true;
+ s32 val;
+
+ WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
+
+ if (psci_ops.smccc_version == SMCCC_VERSION_1_0) {
+ ssbd_state = ARM64_SSBD_UNKNOWN;
+ return false;
+ }
+
+ switch (psci_ops.conduit) {
+ case PSCI_CONDUIT_HVC:
+ arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
+ ARM_SMCCC_ARCH_WORKAROUND_2, &res);
+ break;
+
+ case PSCI_CONDUIT_SMC:
+ arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
+ ARM_SMCCC_ARCH_WORKAROUND_2, &res);
+ break;
+
+ default:
+ ssbd_state = ARM64_SSBD_UNKNOWN;
+ return false;
+ }
+
+ val = (s32)res.a0;
+
+ switch (val) {
+ case SMCCC_RET_NOT_SUPPORTED:
+ ssbd_state = ARM64_SSBD_UNKNOWN;
+ return false;
+
+ case SMCCC_RET_NOT_REQUIRED:
+ pr_info_once("%s mitigation not required\n", entry->desc);
+ ssbd_state = ARM64_SSBD_MITIGATED;
+ return false;
+
+ case SMCCC_RET_SUCCESS:
+ required = true;
+ break;
+
+ case 1: /* Mitigation not required on this CPU */
+ required = false;
+ break;
+
+ default:
+ WARN_ON(1);
+ return false;
+ }
+
+ switch (ssbd_state) {
+ case ARM64_SSBD_FORCE_DISABLE:
+ pr_info_once("%s disabled from command-line\n", entry->desc);
+ arm64_set_ssbd_mitigation(false);
+ required = false;
+ break;
+
+ case ARM64_SSBD_KERNEL:
+ if (required) {
+ __this_cpu_write(arm64_ssbd_callback_required, 1);
+ arm64_set_ssbd_mitigation(true);
+ }
+ break;
+
+ case ARM64_SSBD_FORCE_ENABLE:
+ pr_info_once("%s forced from command-line\n", entry->desc);
+ arm64_set_ssbd_mitigation(true);
+ required = true;
+ break;
+
+ default:
+ WARN_ON(1);
+ break;
+ }
+
+ return required;
+}
+#endif /* CONFIG_ARM64_SSBD */
+
#define MIDR_RANGE(model, min, max) \
.def_scope = SCOPE_LOCAL_CPU, \
.matches = is_affected_midr_range, \
@@ -348,6 +519,14 @@
.enable = enable_smccc_arch_workaround_1,
},
#endif
+#ifdef CONFIG_ARM64_SSBD
+ {
+ .desc = "Speculative Store Bypass Disable",
+ .def_scope = SCOPE_LOCAL_CPU,
+ .capability = ARM64_SSBD,
+ .matches = has_ssbd_mitigation,
+ },
+#endif
{
}
};
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 2eea592..1f0faeb 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -828,6 +828,22 @@
early_param("kpti", parse_kpti);
#endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */
+static int cpu_copy_el2regs(void *__unused)
+{
+ /*
+ * Copy register values that aren't redirected by hardware.
+ *
+ * Before code patching, we only set tpidr_el1, all CPUs need to copy
+ * this value to tpidr_el2 before we patch the code. Once we've done
+ * that, freshly-onlined CPUs will set tpidr_el2, so we don't need to
+ * do anything here.
+ */
+ if (!alternatives_applied)
+ write_sysreg(read_sysreg(tpidr_el1), tpidr_el2);
+
+ return 0;
+}
+
static const struct arm64_cpu_capabilities arm64_features[] = {
{
.desc = "GIC system register CPU interface",
@@ -894,6 +910,7 @@
.capability = ARM64_HAS_VIRT_HOST_EXTN,
.def_scope = SCOPE_SYSTEM,
.matches = runs_at_el2,
+ .enable = cpu_copy_el2regs,
},
{
.desc = "32-bit EL0 Support",
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 7613ed1..58dec4b 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -18,6 +18,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <linux/arm-smccc.h>
#include <linux/init.h>
#include <linux/linkage.h>
@@ -97,6 +98,25 @@
add \dst, \dst, #(\sym - .entry.tramp.text)
.endm
+ // This macro corrupts x0-x3. It is the caller's duty
+ // to save/restore them if required.
+ .macro apply_ssbd, state, targ, tmp1, tmp2
+#ifdef CONFIG_ARM64_SSBD
+alternative_cb arm64_enable_wa2_handling
+ b \targ
+alternative_cb_end
+ ldr_this_cpu \tmp2, arm64_ssbd_callback_required, \tmp1
+ cbz \tmp2, \targ
+ ldr \tmp2, [tsk, #TSK_TI_FLAGS]
+ tbnz \tmp2, #TIF_SSBD, \targ
+ mov w0, #ARM_SMCCC_ARCH_WORKAROUND_2
+ mov w1, #\state
+alternative_cb arm64_update_smccc_conduit
+ nop // Patched to SMC/HVC #0
+alternative_cb_end
+#endif
+ .endm
+
.macro kernel_entry, el, regsize = 64
.if \regsize == 32
mov w0, w0 // zero upper 32 bits of x0
@@ -123,6 +143,14 @@
ldr x19, [tsk, #TSK_TI_FLAGS] // since we can unmask debug
disable_step_tsk x19, x20 // exceptions when scheduling.
+ apply_ssbd 1, 1f, x22, x23
+
+#ifdef CONFIG_ARM64_SSBD
+ ldp x0, x1, [sp, #16 * 0]
+ ldp x2, x3, [sp, #16 * 1]
+#endif
+1:
+
mov x29, xzr // fp pointed to user-space
.else
add x21, sp, #S_FRAME_SIZE
@@ -251,6 +279,8 @@
alternative_else_nop_endif
#endif
3:
+ apply_ssbd 0, 5f, x0, x1
+5:
.endif
msr elr_el1, x21 // set up the return data
diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c
index 8bed26a..db603cd 100644
--- a/arch/arm64/kernel/hibernate.c
+++ b/arch/arm64/kernel/hibernate.c
@@ -305,6 +305,17 @@
sleep_cpu = -EINVAL;
__cpu_suspend_exit();
+
+ /*
+ * Just in case the boot kernel did turn the SSBD
+ * mitigation off behind our back, let's set the state
+ * to what we expect it to be.
+ */
+ switch (arm64_get_ssbd_state()) {
+ case ARM64_SSBD_FORCE_ENABLE:
+ case ARM64_SSBD_KERNEL:
+ arm64_set_ssbd_mitigation(true);
+ }
}
local_dbg_restore(flags);
diff --git a/arch/arm64/kernel/ssbd.c b/arch/arm64/kernel/ssbd.c
new file mode 100644
index 0000000..0560738
--- /dev/null
+++ b/arch/arm64/kernel/ssbd.c
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 ARM Ltd, All Rights Reserved.
+ */
+
+#include <linux/errno.h>
+#include <linux/prctl.h>
+#include <linux/sched.h>
+#include <linux/thread_info.h>
+
+#include <asm/cpufeature.h>
+
+/*
+ * prctl interface for SSBD
+ */
+static int ssbd_prctl_set(struct task_struct *task, unsigned long ctrl)
+{
+ int state = arm64_get_ssbd_state();
+
+ /* Unsupported */
+ if (state == ARM64_SSBD_UNKNOWN)
+ return -EINVAL;
+
+ /* Treat the unaffected/mitigated state separately */
+ if (state == ARM64_SSBD_MITIGATED) {
+ switch (ctrl) {
+ case PR_SPEC_ENABLE:
+ return -EPERM;
+ case PR_SPEC_DISABLE:
+ case PR_SPEC_FORCE_DISABLE:
+ return 0;
+ }
+ }
+
+ /*
+ * Things are a bit backward here: the arm64 internal API
+ * *enables the mitigation* when the userspace API *disables
+ * speculation*. So much fun.
+ */
+ switch (ctrl) {
+ case PR_SPEC_ENABLE:
+ /* If speculation is force disabled, enable is not allowed */
+ if (state == ARM64_SSBD_FORCE_ENABLE ||
+ task_spec_ssb_force_disable(task))
+ return -EPERM;
+ task_clear_spec_ssb_disable(task);
+ clear_tsk_thread_flag(task, TIF_SSBD);
+ break;
+ case PR_SPEC_DISABLE:
+ if (state == ARM64_SSBD_FORCE_DISABLE)
+ return -EPERM;
+ task_set_spec_ssb_disable(task);
+ set_tsk_thread_flag(task, TIF_SSBD);
+ break;
+ case PR_SPEC_FORCE_DISABLE:
+ if (state == ARM64_SSBD_FORCE_DISABLE)
+ return -EPERM;
+ task_set_spec_ssb_disable(task);
+ task_set_spec_ssb_force_disable(task);
+ set_tsk_thread_flag(task, TIF_SSBD);
+ break;
+ default:
+ return -ERANGE;
+ }
+
+ return 0;
+}
+
+int arch_prctl_spec_ctrl_set(struct task_struct *task, unsigned long which,
+ unsigned long ctrl)
+{
+ switch (which) {
+ case PR_SPEC_STORE_BYPASS:
+ return ssbd_prctl_set(task, ctrl);
+ default:
+ return -ENODEV;
+ }
+}
+
+static int ssbd_prctl_get(struct task_struct *task)
+{
+ switch (arm64_get_ssbd_state()) {
+ case ARM64_SSBD_UNKNOWN:
+ return -EINVAL;
+ case ARM64_SSBD_FORCE_ENABLE:
+ return PR_SPEC_DISABLE;
+ case ARM64_SSBD_KERNEL:
+ if (task_spec_ssb_force_disable(task))
+ return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE;
+ if (task_spec_ssb_disable(task))
+ return PR_SPEC_PRCTL | PR_SPEC_DISABLE;
+ return PR_SPEC_PRCTL | PR_SPEC_ENABLE;
+ case ARM64_SSBD_FORCE_DISABLE:
+ return PR_SPEC_ENABLE;
+ default:
+ return PR_SPEC_NOT_AFFECTED;
+ }
+}
+
+int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which)
+{
+ switch (which) {
+ case PR_SPEC_STORE_BYPASS:
+ return ssbd_prctl_get(task);
+ default:
+ return -ENODEV;
+ }
+}
diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c
index 1e3be90..e12f2d0 100644
--- a/arch/arm64/kernel/suspend.c
+++ b/arch/arm64/kernel/suspend.c
@@ -61,6 +61,14 @@
*/
if (hw_breakpoint_restore)
hw_breakpoint_restore(cpu);
+
+ /*
+ * On resume, firmware implementing dynamic mitigation will
+ * have turned the mitigation on. If the user has forcefully
+ * disabled it, make sure their wishes are obeyed.
+ */
+ if (arm64_get_ssbd_state() == ARM64_SSBD_FORCE_DISABLE)
+ arm64_set_ssbd_mitigation(false);
}
/*
diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
index 4bbff90..db5efaf 100644
--- a/arch/arm64/kvm/hyp-init.S
+++ b/arch/arm64/kvm/hyp-init.S
@@ -118,6 +118,10 @@
kern_hyp_va x2
msr vbar_el2, x2
+ /* copy tpidr_el1 into tpidr_el2 for use by HYP */
+ mrs x1, tpidr_el1
+ msr tpidr_el2, x1
+
/* Hello, World! */
eret
ENDPROC(__kvm_hyp_init)
diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S
index 12ee62d..a360ac6 100644
--- a/arch/arm64/kvm/hyp/entry.S
+++ b/arch/arm64/kvm/hyp/entry.S
@@ -62,9 +62,6 @@
// Store the host regs
save_callee_saved_regs x1
- // Store the host_ctxt for use at exit time
- str x1, [sp, #-16]!
-
add x18, x0, #VCPU_CONTEXT
// Restore guest regs x0-x17
@@ -118,8 +115,7 @@
// Store the guest regs x19-x29, lr
save_callee_saved_regs x1
- // Restore the host_ctxt from the stack
- ldr x2, [sp], #16
+ get_host_ctxt x2, x3
// Now restore the host regs
restore_callee_saved_regs x2
@@ -159,6 +155,10 @@
ENDPROC(__guest_exit)
ENTRY(__fpsimd_guest_restore)
+ // x0: esr
+ // x1: vcpu
+ // x2-x29,lr: vcpu regs
+ // vcpu x0-x1 on the stack
stp x2, x3, [sp, #-16]!
stp x4, lr, [sp, #-16]!
@@ -173,7 +173,7 @@
alternative_endif
isb
- mrs x3, tpidr_el2
+ mov x3, x1
ldr x0, [x3, #VCPU_HOST_CONTEXT]
kern_hyp_va x0
diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S
index 4e9d50c..bf4988f 100644
--- a/arch/arm64/kvm/hyp/hyp-entry.S
+++ b/arch/arm64/kvm/hyp/hyp-entry.S
@@ -72,13 +72,8 @@
el1_sync: // Guest trapped into EL2
stp x0, x1, [sp, #-16]!
-alternative_if_not ARM64_HAS_VIRT_HOST_EXTN
- mrs x1, esr_el2
-alternative_else
- mrs x1, esr_el1
-alternative_endif
- lsr x0, x1, #ESR_ELx_EC_SHIFT
-
+ mrs x0, esr_el2
+ lsr x0, x0, #ESR_ELx_EC_SHIFT
cmp x0, #ESR_ELx_EC_HVC64
ccmp x0, #ESR_ELx_EC_HVC32, #4, ne
b.ne el1_trap
@@ -112,33 +107,73 @@
*/
ldr x1, [sp] // Guest's x0
eor w1, w1, #ARM_SMCCC_ARCH_WORKAROUND_1
+ cbz w1, wa_epilogue
+
+ /* ARM_SMCCC_ARCH_WORKAROUND_2 handling */
+ eor w1, w1, #(ARM_SMCCC_ARCH_WORKAROUND_1 ^ \
+ ARM_SMCCC_ARCH_WORKAROUND_2)
cbnz w1, el1_trap
- mov x0, x1
+
+#ifdef CONFIG_ARM64_SSBD
+alternative_cb arm64_enable_wa2_handling
+ b wa2_end
+alternative_cb_end
+ get_vcpu_ptr x2, x0
+ ldr x0, [x2, #VCPU_WORKAROUND_FLAGS]
+
+ // Sanitize the argument and update the guest flags
+ ldr x1, [sp, #8] // Guest's x1
+ clz w1, w1 // Murphy's device:
+ lsr w1, w1, #5 // w1 = !!w1 without using
+ eor w1, w1, #1 // the flags...
+ bfi x0, x1, #VCPU_WORKAROUND_2_FLAG_SHIFT, #1
+ str x0, [x2, #VCPU_WORKAROUND_FLAGS]
+
+ /* Check that we actually need to perform the call */
+ hyp_ldr_this_cpu x0, arm64_ssbd_callback_required, x2
+ cbz x0, wa2_end
+
+ mov w0, #ARM_SMCCC_ARCH_WORKAROUND_2
+ smc #0
+
+ /* Don't leak data from the SMC call */
+ mov x3, xzr
+wa2_end:
+ mov x2, xzr
+ mov x1, xzr
+#endif
+
+wa_epilogue:
+ mov x0, xzr
add sp, sp, #16
eret
el1_trap:
+ get_vcpu_ptr x1, x0
+
+ mrs x0, esr_el2
+ lsr x0, x0, #ESR_ELx_EC_SHIFT
/*
* x0: ESR_EC
+ * x1: vcpu pointer
*/
/* Guest accessed VFP/SIMD registers, save host, restore Guest */
cmp x0, #ESR_ELx_EC_FP_ASIMD
b.eq __fpsimd_guest_restore
- mrs x1, tpidr_el2
mov x0, #ARM_EXCEPTION_TRAP
b __guest_exit
el1_irq:
stp x0, x1, [sp, #-16]!
- mrs x1, tpidr_el2
+ get_vcpu_ptr x1, x0
mov x0, #ARM_EXCEPTION_IRQ
b __guest_exit
el1_error:
stp x0, x1, [sp, #-16]!
- mrs x1, tpidr_el2
+ get_vcpu_ptr x1, x0
mov x0, #ARM_EXCEPTION_EL1_SERROR
b __guest_exit
@@ -173,6 +208,11 @@
eret
ENDPROC(__hyp_do_panic)
+ENTRY(__hyp_panic)
+ get_host_ctxt x0, x1
+ b hyp_panic
+ENDPROC(__hyp_panic)
+
.macro invalid_vector label, target = __hyp_panic
.align 2
\label:
diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index 849ee8a..c6a76ea 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -15,6 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <linux/arm-smccc.h>
#include <linux/types.h>
#include <linux/jump_label.h>
#include <uapi/linux/psci.h>
@@ -267,6 +268,39 @@
write_sysreg_el2(*vcpu_pc(vcpu), elr);
}
+static inline bool __hyp_text __needs_ssbd_off(struct kvm_vcpu *vcpu)
+{
+ if (!cpus_have_cap(ARM64_SSBD))
+ return false;
+
+ return !(vcpu->arch.workaround_flags & VCPU_WORKAROUND_2_FLAG);
+}
+
+static void __hyp_text __set_guest_arch_workaround_state(struct kvm_vcpu *vcpu)
+{
+#ifdef CONFIG_ARM64_SSBD
+ /*
+ * The host runs with the workaround always present. If the
+ * guest wants it disabled, so be it...
+ */
+ if (__needs_ssbd_off(vcpu) &&
+ __hyp_this_cpu_read(arm64_ssbd_callback_required))
+ arm_smccc_1_1_smc(ARM_SMCCC_ARCH_WORKAROUND_2, 0, NULL);
+#endif
+}
+
+static void __hyp_text __set_host_arch_workaround_state(struct kvm_vcpu *vcpu)
+{
+#ifdef CONFIG_ARM64_SSBD
+ /*
+ * If the guest has disabled the workaround, bring it back on.
+ */
+ if (__needs_ssbd_off(vcpu) &&
+ __hyp_this_cpu_read(arm64_ssbd_callback_required))
+ arm_smccc_1_1_smc(ARM_SMCCC_ARCH_WORKAROUND_2, 1, NULL);
+#endif
+}
+
int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
{
struct kvm_cpu_context *host_ctxt;
@@ -275,9 +309,9 @@
u64 exit_code;
vcpu = kern_hyp_va(vcpu);
- write_sysreg(vcpu, tpidr_el2);
host_ctxt = kern_hyp_va(vcpu->arch.host_cpu_context);
+ host_ctxt->__hyp_running_vcpu = vcpu;
guest_ctxt = &vcpu->arch.ctxt;
__sysreg_save_host_state(host_ctxt);
@@ -297,6 +331,8 @@
__sysreg_restore_guest_state(guest_ctxt);
__debug_restore_state(vcpu, kern_hyp_va(vcpu->arch.debug_ptr), guest_ctxt);
+ __set_guest_arch_workaround_state(vcpu);
+
/* Jump in the fire! */
again:
exit_code = __guest_enter(vcpu, host_ctxt);
@@ -353,6 +389,8 @@
}
}
+ __set_host_arch_workaround_state(vcpu);
+
fp_enabled = __fpsimd_enabled();
__sysreg_save_guest_state(guest_ctxt);
@@ -378,7 +416,8 @@
static const char __hyp_panic_string[] = "HYP panic:\nPS:%08llx PC:%016llx ESR:%08llx\nFAR:%016llx HPFAR:%016llx PAR:%016llx\nVCPU:%p\n";
-static void __hyp_text __hyp_call_panic_nvhe(u64 spsr, u64 elr, u64 par)
+static void __hyp_text __hyp_call_panic_nvhe(u64 spsr, u64 elr, u64 par,
+ struct kvm_vcpu *vcpu)
{
unsigned long str_va;
@@ -392,35 +431,32 @@
__hyp_do_panic(str_va,
spsr, elr,
read_sysreg(esr_el2), read_sysreg_el2(far),
- read_sysreg(hpfar_el2), par,
- (void *)read_sysreg(tpidr_el2));
+ read_sysreg(hpfar_el2), par, vcpu);
}
-static void __hyp_text __hyp_call_panic_vhe(u64 spsr, u64 elr, u64 par)
+static void __hyp_text __hyp_call_panic_vhe(u64 spsr, u64 elr, u64 par,
+ struct kvm_vcpu *vcpu)
{
panic(__hyp_panic_string,
spsr, elr,
read_sysreg_el2(esr), read_sysreg_el2(far),
- read_sysreg(hpfar_el2), par,
- (void *)read_sysreg(tpidr_el2));
+ read_sysreg(hpfar_el2), par, vcpu);
}
static hyp_alternate_select(__hyp_call_panic,
__hyp_call_panic_nvhe, __hyp_call_panic_vhe,
ARM64_HAS_VIRT_HOST_EXTN);
-void __hyp_text __noreturn __hyp_panic(void)
+void __hyp_text __noreturn hyp_panic(struct kvm_cpu_context *host_ctxt)
{
+ struct kvm_vcpu *vcpu = NULL;
+
u64 spsr = read_sysreg_el2(spsr);
u64 elr = read_sysreg_el2(elr);
u64 par = read_sysreg(par_el1);
if (read_sysreg(vttbr_el2)) {
- struct kvm_vcpu *vcpu;
- struct kvm_cpu_context *host_ctxt;
-
- vcpu = (struct kvm_vcpu *)read_sysreg(tpidr_el2);
- host_ctxt = kern_hyp_va(vcpu->arch.host_cpu_context);
+ vcpu = host_ctxt->__hyp_running_vcpu;
__timer_save_state(vcpu);
__deactivate_traps(vcpu);
__deactivate_vm(vcpu);
@@ -428,7 +464,7 @@
}
/* Call panic for real */
- __hyp_call_panic()(spsr, elr, par);
+ __hyp_call_panic()(spsr, elr, par, vcpu);
unreachable();
}
diff --git a/arch/arm64/kvm/hyp/sysreg-sr.c b/arch/arm64/kvm/hyp/sysreg-sr.c
index 9341376..e19d89c 100644
--- a/arch/arm64/kvm/hyp/sysreg-sr.c
+++ b/arch/arm64/kvm/hyp/sysreg-sr.c
@@ -27,8 +27,8 @@
/*
* Non-VHE: Both host and guest must save everything.
*
- * VHE: Host must save tpidr*_el[01], actlr_el1, mdscr_el1, sp0, pc,
- * pstate, and guest must save everything.
+ * VHE: Host must save tpidr*_el0, actlr_el1, mdscr_el1, sp_el0,
+ * and guest must save everything.
*/
static void __hyp_text __sysreg_save_common_state(struct kvm_cpu_context *ctxt)
@@ -36,11 +36,8 @@
ctxt->sys_regs[ACTLR_EL1] = read_sysreg(actlr_el1);
ctxt->sys_regs[TPIDR_EL0] = read_sysreg(tpidr_el0);
ctxt->sys_regs[TPIDRRO_EL0] = read_sysreg(tpidrro_el0);
- ctxt->sys_regs[TPIDR_EL1] = read_sysreg(tpidr_el1);
ctxt->sys_regs[MDSCR_EL1] = read_sysreg(mdscr_el1);
ctxt->gp_regs.regs.sp = read_sysreg(sp_el0);
- ctxt->gp_regs.regs.pc = read_sysreg_el2(elr);
- ctxt->gp_regs.regs.pstate = read_sysreg_el2(spsr);
}
static void __hyp_text __sysreg_save_state(struct kvm_cpu_context *ctxt)
@@ -62,10 +59,13 @@
ctxt->sys_regs[AMAIR_EL1] = read_sysreg_el1(amair);
ctxt->sys_regs[CNTKCTL_EL1] = read_sysreg_el1(cntkctl);
ctxt->sys_regs[PAR_EL1] = read_sysreg(par_el1);
+ ctxt->sys_regs[TPIDR_EL1] = read_sysreg(tpidr_el1);
ctxt->gp_regs.sp_el1 = read_sysreg(sp_el1);
ctxt->gp_regs.elr_el1 = read_sysreg_el1(elr);
ctxt->gp_regs.spsr[KVM_SPSR_EL1]= read_sysreg_el1(spsr);
+ ctxt->gp_regs.regs.pc = read_sysreg_el2(elr);
+ ctxt->gp_regs.regs.pstate = read_sysreg_el2(spsr);
}
static hyp_alternate_select(__sysreg_call_save_host_state,
@@ -89,11 +89,8 @@
write_sysreg(ctxt->sys_regs[ACTLR_EL1], actlr_el1);
write_sysreg(ctxt->sys_regs[TPIDR_EL0], tpidr_el0);
write_sysreg(ctxt->sys_regs[TPIDRRO_EL0], tpidrro_el0);
- write_sysreg(ctxt->sys_regs[TPIDR_EL1], tpidr_el1);
write_sysreg(ctxt->sys_regs[MDSCR_EL1], mdscr_el1);
write_sysreg(ctxt->gp_regs.regs.sp, sp_el0);
- write_sysreg_el2(ctxt->gp_regs.regs.pc, elr);
- write_sysreg_el2(ctxt->gp_regs.regs.pstate, spsr);
}
static void __hyp_text __sysreg_restore_state(struct kvm_cpu_context *ctxt)
@@ -115,10 +112,13 @@
write_sysreg_el1(ctxt->sys_regs[AMAIR_EL1], amair);
write_sysreg_el1(ctxt->sys_regs[CNTKCTL_EL1], cntkctl);
write_sysreg(ctxt->sys_regs[PAR_EL1], par_el1);
+ write_sysreg(ctxt->sys_regs[TPIDR_EL1], tpidr_el1);
write_sysreg(ctxt->gp_regs.sp_el1, sp_el1);
write_sysreg_el1(ctxt->gp_regs.elr_el1, elr);
write_sysreg_el1(ctxt->gp_regs.spsr[KVM_SPSR_EL1],spsr);
+ write_sysreg_el2(ctxt->gp_regs.regs.pc, elr);
+ write_sysreg_el2(ctxt->gp_regs.regs.pstate, spsr);
}
static hyp_alternate_select(__sysreg_call_restore_host_state,
@@ -183,3 +183,8 @@
if (vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY)
write_sysreg(sysreg[DBGVCR32_EL2], dbgvcr32_el2);
}
+
+void __hyp_text __kvm_set_tpidr_el2(u64 tpidr_el2)
+{
+ asm("msr tpidr_el2, %0": : "r" (tpidr_el2));
+}
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 5bc4608..29a27a0 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -135,6 +135,10 @@
/* Reset PMU */
kvm_pmu_vcpu_reset(vcpu);
+ /* Default workaround setup is enabled (if supported) */
+ if (kvm_arm_have_ssbd() == KVM_SSBD_KERNEL)
+ vcpu->arch.workaround_flags |= VCPU_WORKAROUND_2_FLAG;
+
/* Reset timer */
return kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
}
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 2b35b67..31fe1cd 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -471,11 +471,13 @@
BUILD_BUG_ON(TASK_SIZE_32 > TASK_SIZE_64);
#endif
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
/*
* Make sure we chose the upper bound of sizeof(struct page)
- * correctly.
+ * correctly when sizing the VMEMMAP array.
*/
BUILD_BUG_ON(sizeof(struct page) > (1 << STRUCT_PAGE_MAX_SHIFT));
+#endif
if (PAGE_SIZE >= 16384 && get_num_physpages() <= 128) {
extern int sysctl_overcommit_memory;
diff --git a/arch/microblaze/boot/Makefile b/arch/microblaze/boot/Makefile
index 91d2068..0f3fe6a 100644
--- a/arch/microblaze/boot/Makefile
+++ b/arch/microblaze/boot/Makefile
@@ -21,17 +21,19 @@
quiet_cmd_cp = CP $< $@$2
cmd_cp = cat $< >$@$2 || (rm -f $@ && echo false)
-quiet_cmd_strip = STRIP $@
+quiet_cmd_strip = STRIP $< $@$2
cmd_strip = $(STRIP) -K microblaze_start -K _end -K __log_buf \
- -K _fdt_start vmlinux -o $@
+ -K _fdt_start $< -o $@$2
UIMAGE_LOADADDR = $(CONFIG_KERNEL_BASE_ADDR)
+UIMAGE_IN = $@
+UIMAGE_OUT = $@.ub
$(obj)/simpleImage.%: vmlinux FORCE
$(call if_changed,cp,.unstrip)
$(call if_changed,objcopy)
$(call if_changed,uimage)
- $(call if_changed,strip)
- @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
+ $(call if_changed,strip,.strip)
+ @echo 'Kernel: $(UIMAGE_OUT) is ready' ' (#'`cat .version`')'
clean-files += simpleImage.*.unstrip linux.bin.ub dts/*.dtb
diff --git a/arch/mips/ath79/common.c b/arch/mips/ath79/common.c
index d071a3a..fc97a11 100644
--- a/arch/mips/ath79/common.c
+++ b/arch/mips/ath79/common.c
@@ -58,7 +58,7 @@
void ath79_ddr_wb_flush(u32 reg)
{
- void __iomem *flush_reg = ath79_ddr_wb_flush_base + reg;
+ void __iomem *flush_reg = ath79_ddr_wb_flush_base + (reg * 4);
/* Flush the DDR write buffer. */
__raw_writel(0x1, flush_reg);
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index ebb575c..513a63b 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -26,6 +26,7 @@
#include <linux/kallsyms.h>
#include <linux/random.h>
#include <linux/prctl.h>
+#include <linux/nmi.h>
#include <asm/asm.h>
#include <asm/bootinfo.h>
@@ -633,28 +634,42 @@
return sp & ALMASK;
}
-static void arch_dump_stack(void *info)
+static DEFINE_PER_CPU(struct call_single_data, backtrace_csd);
+static struct cpumask backtrace_csd_busy;
+
+static void handle_backtrace(void *info)
{
- struct pt_regs *regs;
+ nmi_cpu_backtrace(get_irq_regs());
+ cpumask_clear_cpu(smp_processor_id(), &backtrace_csd_busy);
+}
- regs = get_irq_regs();
+static void raise_backtrace(cpumask_t *mask)
+{
+ struct call_single_data *csd;
+ int cpu;
- if (regs)
- show_regs(regs);
+ for_each_cpu(cpu, mask) {
+ /*
+ * If we previously sent an IPI to the target CPU & it hasn't
+ * cleared its bit in the busy cpumask then it didn't handle
+ * our previous IPI & it's not safe for us to reuse the
+ * call_single_data_t.
+ */
+ if (cpumask_test_and_set_cpu(cpu, &backtrace_csd_busy)) {
+ pr_warn("Unable to send backtrace IPI to CPU%u - perhaps it hung?\n",
+ cpu);
+ continue;
+ }
- dump_stack();
+ csd = &per_cpu(backtrace_csd, cpu);
+ csd->func = handle_backtrace;
+ smp_call_function_single_async(cpu, csd);
+ }
}
void arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self)
{
- long this_cpu = get_cpu();
-
- if (cpumask_test_cpu(this_cpu, mask) && !exclude_self)
- dump_stack();
-
- smp_call_function_many(mask, arch_dump_stack, NULL, 1);
-
- put_cpu();
+ nmi_trigger_cpumask_backtrace(mask, exclude_self, raise_backtrace);
}
int mips_get_process_fp_mode(struct task_struct *task)
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index bb1d9ff..8e07496 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -351,6 +351,7 @@
void show_regs(struct pt_regs *regs)
{
__show_regs((struct pt_regs *)regs);
+ dump_stack();
}
void show_registers(struct pt_regs *regs)
diff --git a/arch/mips/mm/ioremap.c b/arch/mips/mm/ioremap.c
index 1f18962..0dbcd90b 100644
--- a/arch/mips/mm/ioremap.c
+++ b/arch/mips/mm/ioremap.c
@@ -9,6 +9,7 @@
#include <linux/export.h>
#include <asm/addrspace.h>
#include <asm/byteorder.h>
+#include <linux/ioport.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
@@ -97,6 +98,20 @@
return error;
}
+static int __ioremap_check_ram(unsigned long start_pfn, unsigned long nr_pages,
+ void *arg)
+{
+ unsigned long i;
+
+ for (i = 0; i < nr_pages; i++) {
+ if (pfn_valid(start_pfn + i) &&
+ !PageReserved(pfn_to_page(start_pfn + i)))
+ return 1;
+ }
+
+ return 0;
+}
+
/*
* Generic mapping function (not visible outside):
*/
@@ -115,8 +130,8 @@
void __iomem * __ioremap(phys_addr_t phys_addr, phys_addr_t size, unsigned long flags)
{
+ unsigned long offset, pfn, last_pfn;
struct vm_struct * area;
- unsigned long offset;
phys_addr_t last_addr;
void * addr;
@@ -136,18 +151,16 @@
return (void __iomem *) CKSEG1ADDR(phys_addr);
/*
- * Don't allow anybody to remap normal RAM that we're using..
+ * Don't allow anybody to remap RAM that may be allocated by the page
+ * allocator, since that could lead to races & data clobbering.
*/
- if (phys_addr < virt_to_phys(high_memory)) {
- char *t_addr, *t_end;
- struct page *page;
-
- t_addr = __va(phys_addr);
- t_end = t_addr + (size - 1);
-
- for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++)
- if(!PageReserved(page))
- return NULL;
+ pfn = PFN_DOWN(phys_addr);
+ last_pfn = PFN_DOWN(last_addr);
+ if (walk_system_ram_range(pfn, last_pfn - pfn + 1, NULL,
+ __ioremap_check_ram) == 1) {
+ WARN_ONCE(1, "ioremap on RAM at %pa - %pa\n",
+ &phys_addr, &last_addr);
+ return NULL;
}
/*
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
index f6325fa..64ae8c0 100644
--- a/arch/mips/pci/pci.c
+++ b/arch/mips/pci/pci.c
@@ -55,7 +55,7 @@
phys_addr_t size = resource_size(rsrc);
*start = fixup_bigphys_addr(rsrc->start, size);
- *end = rsrc->start + size;
+ *end = rsrc->start + size - 1;
}
int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
index 27843665..620e08d 100644
--- a/arch/powerpc/kernel/eeh_driver.c
+++ b/arch/powerpc/kernel/eeh_driver.c
@@ -450,9 +450,11 @@
driver = eeh_pcid_get(dev);
if (driver) {
- eeh_pcid_put(dev);
- if (driver->err_handler)
+ if (driver->err_handler) {
+ eeh_pcid_put(dev);
return NULL;
+ }
+ eeh_pcid_put(dev);
}
#ifdef CONFIG_PPC_POWERNV
@@ -489,17 +491,19 @@
if (eeh_dev_removed(edev))
return NULL;
- driver = eeh_pcid_get(dev);
- if (driver) {
- eeh_pcid_put(dev);
- if (removed &&
- eeh_pe_passed(edev->pe))
+ if (removed) {
+ if (eeh_pe_passed(edev->pe))
return NULL;
- if (removed &&
- driver->err_handler &&
- driver->err_handler->error_detected &&
- driver->err_handler->slot_reset)
- return NULL;
+ driver = eeh_pcid_get(dev);
+ if (driver) {
+ if (driver->err_handler &&
+ driver->err_handler->error_detected &&
+ driver->err_handler->slot_reset) {
+ eeh_pcid_put(dev);
+ return NULL;
+ }
+ eeh_pcid_put(dev);
+ }
}
/* Remove it from PCI subsystem */
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index fb133a1..2274be5 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -769,7 +769,7 @@
tovirt(r6,r6)
lis r5, abatron_pteptrs@h
ori r5, r5, abatron_pteptrs@l
- stw r5, 0xf0(r0) /* Must match your Abatron config file */
+ stw r5, 0xf0(0) /* Must match your Abatron config file */
tophys(r5,r5)
stw r6, 0(r5)
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index 678f87a..97b02b8 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -11,6 +11,7 @@
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/bootmem.h>
+#include <linux/syscalls.h>
#include <linux/irq.h>
#include <linux/list.h>
#include <linux/of.h>
diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c
index 48fc28b..64c9a91 100644
--- a/arch/powerpc/mm/slb.c
+++ b/arch/powerpc/mm/slb.c
@@ -68,14 +68,14 @@
* updating it. No write barriers are needed here, provided
* we only update the current CPU's SLB shadow buffer.
*/
- p->save_area[index].esid = 0;
- p->save_area[index].vsid = cpu_to_be64(mk_vsid_data(ea, ssize, flags));
- p->save_area[index].esid = cpu_to_be64(mk_esid_data(ea, ssize, index));
+ WRITE_ONCE(p->save_area[index].esid, 0);
+ WRITE_ONCE(p->save_area[index].vsid, cpu_to_be64(mk_vsid_data(ea, ssize, flags)));
+ WRITE_ONCE(p->save_area[index].esid, cpu_to_be64(mk_esid_data(ea, ssize, index)));
}
static inline void slb_shadow_clear(enum slb_index index)
{
- get_slb_shadow()->save_area[index].esid = 0;
+ WRITE_ONCE(get_slb_shadow()->save_area[index].esid, 0);
}
static inline void create_shadowed_slbe(unsigned long ea, int ssize,
diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c
index be9d968..c0e817f 100644
--- a/arch/powerpc/net/bpf_jit_comp64.c
+++ b/arch/powerpc/net/bpf_jit_comp64.c
@@ -207,25 +207,37 @@
static void bpf_jit_emit_func_call(u32 *image, struct codegen_context *ctx, u64 func)
{
+ unsigned int i, ctx_idx = ctx->idx;
+
+ /* Load function address into r12 */
+ PPC_LI64(12, func);
+
+ /* For bpf-to-bpf function calls, the callee's address is unknown
+ * until the last extra pass. As seen above, we use PPC_LI64() to
+ * load the callee's address, but this may optimize the number of
+ * instructions required based on the nature of the address.
+ *
+ * Since we don't want the number of instructions emitted to change,
+ * we pad the optimized PPC_LI64() call with NOPs to guarantee that
+ * we always have a five-instruction sequence, which is the maximum
+ * that PPC_LI64() can emit.
+ */
+ for (i = ctx->idx - ctx_idx; i < 5; i++)
+ PPC_NOP();
+
#ifdef PPC64_ELF_ABI_v1
- /* func points to the function descriptor */
- PPC_LI64(b2p[TMP_REG_2], func);
- /* Load actual entry point from function descriptor */
- PPC_BPF_LL(b2p[TMP_REG_1], b2p[TMP_REG_2], 0);
- /* ... and move it to LR */
- PPC_MTLR(b2p[TMP_REG_1]);
/*
* Load TOC from function descriptor at offset 8.
* We can clobber r2 since we get called through a
* function pointer (so caller will save/restore r2)
* and since we don't use a TOC ourself.
*/
- PPC_BPF_LL(2, b2p[TMP_REG_2], 8);
-#else
- /* We can clobber r12 */
- PPC_FUNC_ADDR(12, func);
- PPC_MTLR(12);
+ PPC_BPF_LL(2, 12, 8);
+ /* Load actual entry point from function descriptor */
+ PPC_BPF_LL(12, 12, 0);
#endif
+
+ PPC_MTLR(12);
PPC_BLRL();
}
diff --git a/arch/powerpc/platforms/chrp/time.c b/arch/powerpc/platforms/chrp/time.c
index f803f4b..8608e35 100644
--- a/arch/powerpc/platforms/chrp/time.c
+++ b/arch/powerpc/platforms/chrp/time.c
@@ -27,6 +27,8 @@
#include <asm/sections.h>
#include <asm/time.h>
+#include <platforms/chrp/chrp.h>
+
extern spinlock_t rtc_lock;
#define NVRAM_AS0 0x74
@@ -62,7 +64,7 @@
return 0;
}
-int chrp_cmos_clock_read(int addr)
+static int chrp_cmos_clock_read(int addr)
{
if (nvram_as1 != 0)
outb(addr>>8, nvram_as1);
@@ -70,7 +72,7 @@
return (inb(nvram_data));
}
-void chrp_cmos_clock_write(unsigned long val, int addr)
+static void chrp_cmos_clock_write(unsigned long val, int addr)
{
if (nvram_as1 != 0)
outb(addr>>8, nvram_as1);
diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
index 89c54de..bf4a125 100644
--- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
@@ -35,6 +35,8 @@
*/
#define HW_BROADWAY_ICR 0x00
#define HW_BROADWAY_IMR 0x04
+#define HW_STARLET_ICR 0x08
+#define HW_STARLET_IMR 0x0c
/*
@@ -74,6 +76,9 @@
void __iomem *io_base = irq_data_get_irq_chip_data(d);
setbits32(io_base + HW_BROADWAY_IMR, 1 << irq);
+
+ /* Make sure the ARM (aka. Starlet) doesn't handle this interrupt. */
+ clrbits32(io_base + HW_STARLET_IMR, 1 << irq);
}
diff --git a/arch/powerpc/platforms/powermac/bootx_init.c b/arch/powerpc/platforms/powermac/bootx_init.c
index c3c9bbb..ba0964c 100644
--- a/arch/powerpc/platforms/powermac/bootx_init.c
+++ b/arch/powerpc/platforms/powermac/bootx_init.c
@@ -468,7 +468,7 @@
boot_infos_t *bi = (boot_infos_t *) r4;
unsigned long hdr;
unsigned long space;
- unsigned long ptr, x;
+ unsigned long ptr;
char *model;
unsigned long offset = reloc_offset();
@@ -562,6 +562,8 @@
* MMU switched OFF, so this should not be useful anymore.
*/
if (bi->version < 4) {
+ unsigned long x __maybe_unused;
+
bootx_printf("Touching pages...\n");
/*
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index 6b4e9d18..4929dd4 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -352,6 +352,7 @@
}
machine_late_initcall(powermac, pmac_late_init);
+void note_bootable_part(dev_t dev, int part, int goodness);
/*
* This is __ref because we check for "initializing" before
* touching any of the __init sensitive things and "initializing"
diff --git a/arch/s390/include/asm/cpu_mf.h b/arch/s390/include/asm/cpu_mf.h
index 0351647..ee64e62 100644
--- a/arch/s390/include/asm/cpu_mf.h
+++ b/arch/s390/include/asm/cpu_mf.h
@@ -113,7 +113,7 @@
struct hws_diag_entry {
unsigned int def:16; /* 0-15 Data Entry Format */
- unsigned int R:14; /* 16-19 and 20-30 reserved */
+ unsigned int R:15; /* 16-19 and 20-30 reserved */
unsigned int I:1; /* 31 entry valid or invalid */
u8 data[]; /* Machine-dependent sample data */
} __packed;
@@ -129,7 +129,9 @@
unsigned int f:1; /* 0 - Block Full Indicator */
unsigned int a:1; /* 1 - Alert request control */
unsigned int t:1; /* 2 - Timestamp format */
- unsigned long long:61; /* 3 - 63: Reserved */
+ unsigned int :29; /* 3 - 31: Reserved */
+ unsigned int bsdes:16; /* 32-47: size of basic SDE */
+ unsigned int dsdes:16; /* 48-63: size of diagnostic SDE */
};
unsigned long long flags; /* 0 - 63: All indicators */
};
diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig
index 308aac3..e985b3c 100644
--- a/arch/x86/configs/x86_64_cuttlefish_defconfig
+++ b/arch/x86/configs/x86_64_cuttlefish_defconfig
@@ -224,7 +224,9 @@
CONFIG_DM_ZERO=y
CONFIG_DM_UEVENT=y
CONFIG_DM_VERITY=y
+CONFIG_DM_VERITY_HASH_PREFETCH_MIN_SIZE=1
CONFIG_DM_VERITY_FEC=y
+CONFIG_DM_ANDROID_VERITY=y
CONFIG_NETDEVICES=y
CONFIG_NETCONSOLE=y
CONFIG_NETCONSOLE_DYNAMIC=y
@@ -460,5 +462,11 @@
CONFIG_HARDENED_USERCOPY=y
CONFIG_SECURITY_SELINUX=y
CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+CONFIG_CRYPTO_RSA=y
# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
CONFIG_CRYPTO_SHA512=y
+CONFIG_ASYMMETRIC_KEY_TYPE=y
+CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
+CONFIG_X509_CERTIFICATE_PARSER=y
+CONFIG_SYSTEM_TRUSTED_KEYRING=y
+CONFIG_SYSTEM_TRUSTED_KEYS="verity_dev_keys.x509"
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index aec6cc9..4f36526 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -212,7 +212,7 @@
u64 prev_count, new_count, delta;
int shift;
- if (event->hw.idx >= UNCORE_PMC_IDX_FIXED)
+ if (event->hw.idx == UNCORE_PMC_IDX_FIXED)
shift = 64 - uncore_fixed_ctr_bits(box);
else
shift = 64 - uncore_perf_ctr_bits(box);
diff --git a/arch/x86/events/intel/uncore_nhmex.c b/arch/x86/events/intel/uncore_nhmex.c
index cda5693..83e2188 100644
--- a/arch/x86/events/intel/uncore_nhmex.c
+++ b/arch/x86/events/intel/uncore_nhmex.c
@@ -245,7 +245,7 @@
{
struct hw_perf_event *hwc = &event->hw;
- if (hwc->idx >= UNCORE_PMC_IDX_FIXED)
+ if (hwc->idx == UNCORE_PMC_IDX_FIXED)
wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0);
else if (box->pmu->type->event_mask & NHMEX_PMON_CTL_EN_BIT0)
wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT22);
diff --git a/arch/x86/include/asm/apm.h b/arch/x86/include/asm/apm.h
index 46e40ae..93eebc63 100644
--- a/arch/x86/include/asm/apm.h
+++ b/arch/x86/include/asm/apm.h
@@ -6,8 +6,6 @@
#ifndef _ASM_X86_MACH_DEFAULT_APM_H
#define _ASM_X86_MACH_DEFAULT_APM_H
-#include <asm/nospec-branch.h>
-
#ifdef APM_ZERO_SEGS
# define APM_DO_ZERO_SEGS \
"pushl %%ds\n\t" \
@@ -33,7 +31,6 @@
* N.B. We do NOT need a cld after the BIOS call
* because we always save and restore the flags.
*/
- firmware_restrict_branch_speculation_start();
__asm__ __volatile__(APM_DO_ZERO_SEGS
"pushl %%edi\n\t"
"pushl %%ebp\n\t"
@@ -46,7 +43,6 @@
"=S" (*esi)
: "a" (func), "b" (ebx_in), "c" (ecx_in)
: "memory", "cc");
- firmware_restrict_branch_speculation_end();
}
static inline bool apm_bios_call_simple_asm(u32 func, u32 ebx_in,
@@ -59,7 +55,6 @@
* N.B. We do NOT need a cld after the BIOS call
* because we always save and restore the flags.
*/
- firmware_restrict_branch_speculation_start();
__asm__ __volatile__(APM_DO_ZERO_SEGS
"pushl %%edi\n\t"
"pushl %%ebp\n\t"
@@ -72,7 +67,6 @@
"=S" (si)
: "a" (func), "b" (ebx_in), "c" (ecx_in)
: "memory", "cc");
- firmware_restrict_branch_speculation_end();
return error;
}
diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h
index 8d8c24f..742712b 100644
--- a/arch/x86/include/asm/asm.h
+++ b/arch/x86/include/asm/asm.h
@@ -45,6 +45,65 @@
#define _ASM_SI __ASM_REG(si)
#define _ASM_DI __ASM_REG(di)
+#ifndef __x86_64__
+/* 32 bit */
+
+#define _ASM_ARG1 _ASM_AX
+#define _ASM_ARG2 _ASM_DX
+#define _ASM_ARG3 _ASM_CX
+
+#define _ASM_ARG1L eax
+#define _ASM_ARG2L edx
+#define _ASM_ARG3L ecx
+
+#define _ASM_ARG1W ax
+#define _ASM_ARG2W dx
+#define _ASM_ARG3W cx
+
+#define _ASM_ARG1B al
+#define _ASM_ARG2B dl
+#define _ASM_ARG3B cl
+
+#else
+/* 64 bit */
+
+#define _ASM_ARG1 _ASM_DI
+#define _ASM_ARG2 _ASM_SI
+#define _ASM_ARG3 _ASM_DX
+#define _ASM_ARG4 _ASM_CX
+#define _ASM_ARG5 r8
+#define _ASM_ARG6 r9
+
+#define _ASM_ARG1Q rdi
+#define _ASM_ARG2Q rsi
+#define _ASM_ARG3Q rdx
+#define _ASM_ARG4Q rcx
+#define _ASM_ARG5Q r8
+#define _ASM_ARG6Q r9
+
+#define _ASM_ARG1L edi
+#define _ASM_ARG2L esi
+#define _ASM_ARG3L edx
+#define _ASM_ARG4L ecx
+#define _ASM_ARG5L r8d
+#define _ASM_ARG6L r9d
+
+#define _ASM_ARG1W di
+#define _ASM_ARG2W si
+#define _ASM_ARG3W dx
+#define _ASM_ARG4W cx
+#define _ASM_ARG5W r8w
+#define _ASM_ARG6W r9w
+
+#define _ASM_ARG1B dil
+#define _ASM_ARG2B sil
+#define _ASM_ARG3B dl
+#define _ASM_ARG4B cl
+#define _ASM_ARG5B r8b
+#define _ASM_ARG6B r9b
+
+#endif
+
/*
* Macros to generate condition code outputs from inline assembly,
* The output operand must be type "bool".
diff --git a/arch/x86/include/asm/irqflags.h b/arch/x86/include/asm/irqflags.h
index ac7692d..8a8a6c6 100644
--- a/arch/x86/include/asm/irqflags.h
+++ b/arch/x86/include/asm/irqflags.h
@@ -12,7 +12,7 @@
* Interrupt control:
*/
-static inline unsigned long native_save_fl(void)
+extern inline unsigned long native_save_fl(void)
{
unsigned long flags;
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 4c9c615..a9ba968 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -56,6 +56,7 @@
obj-y += tsc.o tsc_msr.o io_delay.o rtc.o
obj-y += pci-iommu_table.o
obj-y += resource.o
+obj-y += irqflags.o
obj-y += process.o
obj-y += fpu/
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index 51287cd..313a85a 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -239,6 +239,7 @@
#include <asm/olpc.h>
#include <asm/paravirt.h>
#include <asm/reboot.h>
+#include <asm/nospec-branch.h>
#if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
extern int (*console_blank_hook)(int);
@@ -613,11 +614,13 @@
gdt[0x40 / 8] = bad_bios_desc;
apm_irq_save(flags);
+ firmware_restrict_branch_speculation_start();
APM_DO_SAVE_SEGS;
apm_bios_call_asm(call->func, call->ebx, call->ecx,
&call->eax, &call->ebx, &call->ecx, &call->edx,
&call->esi);
APM_DO_RESTORE_SEGS;
+ firmware_restrict_branch_speculation_end();
apm_irq_restore(flags);
gdt[0x40 / 8] = save_desc_40;
put_cpu();
@@ -689,10 +692,12 @@
gdt[0x40 / 8] = bad_bios_desc;
apm_irq_save(flags);
+ firmware_restrict_branch_speculation_start();
APM_DO_SAVE_SEGS;
error = apm_bios_call_simple_asm(call->func, call->ebx, call->ecx,
&call->eax);
APM_DO_RESTORE_SEGS;
+ firmware_restrict_branch_speculation_end();
apm_irq_restore(flags);
gdt[0x40 / 8] = save_desc_40;
put_cpu();
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index c49e146..7e6163c 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -2397,9 +2397,6 @@
if (check_interval == old_check_interval)
return ret;
- if (check_interval < 1)
- check_interval = 1;
-
mutex_lock(&mce_sysfs_mutex);
mce_restart();
mutex_unlock(&mce_sysfs_mutex);
diff --git a/arch/x86/kernel/irqflags.S b/arch/x86/kernel/irqflags.S
new file mode 100644
index 0000000..ddeeaac
--- /dev/null
+++ b/arch/x86/kernel/irqflags.S
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <asm/asm.h>
+#include <asm/export.h>
+#include <linux/linkage.h>
+
+/*
+ * unsigned long native_save_fl(void)
+ */
+ENTRY(native_save_fl)
+ pushf
+ pop %_ASM_AX
+ ret
+ENDPROC(native_save_fl)
+EXPORT_SYMBOL(native_save_fl)
+
+/*
+ * void native_restore_fl(unsigned long flags)
+ * %eax/%rdi: flags
+ */
+ENTRY(native_restore_fl)
+ push %_ASM_ARG1
+ popf
+ ret
+ENDPROC(native_restore_fl)
+EXPORT_SYMBOL(native_restore_fl)
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
index 495c776..e78a6b1 100644
--- a/arch/x86/kernel/uprobes.c
+++ b/arch/x86/kernel/uprobes.c
@@ -290,7 +290,7 @@
insn_init(insn, auprobe->insn, sizeof(auprobe->insn), x86_64);
/* has the side-effect of processing the entire instruction */
insn_get_length(insn);
- if (WARN_ON_ONCE(!insn_complete(insn)))
+ if (!insn_complete(insn))
return -ENOEXEC;
if (is_prefix_bad(insn))
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index a16c066..8a4d6bc 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -698,7 +698,7 @@
if (cache->nobjs >= min)
return 0;
while (cache->nobjs < ARRAY_SIZE(cache->objects)) {
- page = (void *)__get_free_page(GFP_KERNEL);
+ page = (void *)__get_free_page(GFP_KERNEL_ACCOUNT);
if (!page)
return -ENOMEM;
cache->objects[cache->nobjs++] = page;
diff --git a/block/bio.c b/block/bio.c
index a4c8c99..a44b525 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -568,8 +568,11 @@
static inline void bio_clone_crypt_key(struct bio *dst, const struct bio *src)
{
#ifdef CONFIG_PFK
- dst->bi_crypt_key = src->bi_crypt_key;
dst->bi_iter.bi_dun = src->bi_iter.bi_dun;
+#ifdef CONFIG_DM_DEFAULT_KEY
+ dst->bi_crypt_key = src->bi_crypt_key;
+ dst->bi_crypt_skip = src->bi_crypt_skip;
+#endif
dst->bi_dio_inode = src->bi_dio_inode;
#endif
}
diff --git a/block/blk-core.c b/block/blk-core.c
index 68ec55a..91a0bf2 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -636,7 +636,6 @@
int blk_queue_enter(struct request_queue *q, bool nowait)
{
while (true) {
- int ret;
if (percpu_ref_tryget_live(&q->q_usage_counter))
return 0;
@@ -644,13 +643,11 @@
if (nowait)
return -EBUSY;
- ret = wait_event_interruptible(q->mq_freeze_wq,
- !atomic_read(&q->mq_freeze_depth) ||
- blk_queue_dying(q));
+ wait_event(q->mq_freeze_wq,
+ !atomic_read(&q->mq_freeze_depth) ||
+ blk_queue_dying(q));
if (blk_queue_dying(q))
return -ENODEV;
- if (ret)
- return ret;
}
}
diff --git a/certs/system_keyring.c b/certs/system_keyring.c
index 50979d6..4a34e41 100644
--- a/certs/system_keyring.c
+++ b/certs/system_keyring.c
@@ -240,5 +240,46 @@
return ret;
}
EXPORT_SYMBOL_GPL(verify_pkcs7_signature);
-
#endif /* CONFIG_SYSTEM_DATA_VERIFICATION */
+
+/**
+ * verify_signature_one - Verify a signature with keys from given keyring
+ * @sig: The signature to be verified
+ * @trusted_keys: Trusted keys to use (NULL for builtin trusted keys only,
+ * (void *)1UL for all trusted keys).
+ * @keyid: key description (not partial)
+ */
+int verify_signature_one(const struct public_key_signature *sig,
+ struct key *trusted_keys, const char *keyid)
+{
+ key_ref_t ref;
+ struct key *key;
+ int ret;
+
+ if (!sig)
+ return -EBADMSG;
+ if (!trusted_keys) {
+ trusted_keys = builtin_trusted_keys;
+ } else if (trusted_keys == (void *)1UL) {
+#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
+ trusted_keys = secondary_trusted_keys;
+#else
+ trusted_keys = builtin_trusted_keys;
+#endif
+ }
+
+ ref = keyring_search(make_key_ref(trusted_keys, 1),
+ &key_type_asymmetric, keyid);
+ if (IS_ERR(ref)) {
+ pr_err("Asymmetric key (%s) not found in keyring(%s)\n",
+ keyid, trusted_keys->description);
+ return -ENOKEY;
+ }
+
+ key = key_ref_to_ptr(ref);
+ ret = verify_signature(key, sig);
+ key_put(key);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(verify_signature_one);
+
diff --git a/crypto/authenc.c b/crypto/authenc.c
index a7e1ac7..c3180eb 100644
--- a/crypto/authenc.c
+++ b/crypto/authenc.c
@@ -108,6 +108,7 @@
CRYPTO_TFM_RES_MASK);
out:
+ memzero_explicit(&keys, sizeof(keys));
return err;
badkey:
diff --git a/crypto/authencesn.c b/crypto/authencesn.c
index 18c94e1..49e7e85 100644
--- a/crypto/authencesn.c
+++ b/crypto/authencesn.c
@@ -90,6 +90,7 @@
CRYPTO_TFM_RES_MASK);
out:
+ memzero_explicit(&keys, sizeof(keys));
return err;
badkey:
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index bf601d4..b66815f 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -472,9 +472,11 @@
}
control = OSC_PCI_EXPRESS_CAPABILITY_CONTROL
- | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL
| OSC_PCI_EXPRESS_PME_CONTROL;
+ if (IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE))
+ control |= OSC_PCI_EXPRESS_NATIVE_HP_CONTROL;
+
if (pci_aer_available()) {
if (aer_acpi_firmware_first())
dev_info(&device->dev,
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 957eb3c..c6d909e1 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -142,7 +142,7 @@
};
static uint32_t binder_debug_mask = BINDER_DEBUG_USER_ERROR |
BINDER_DEBUG_FAILED_TRANSACTION | BINDER_DEBUG_DEAD_TRANSACTION;
-module_param_named(debug_mask, binder_debug_mask, uint, S_IWUSR | S_IRUGO);
+module_param_named(debug_mask, binder_debug_mask, uint, 0644);
static char *binder_devices_param = CONFIG_ANDROID_BINDER_DEVICES;
module_param_named(devices, binder_devices_param, charp, S_IRUGO);
@@ -161,7 +161,7 @@
return ret;
}
module_param_call(stop_on_user_error, binder_set_stop_on_user_error,
- param_get_int, &binder_stop_on_user_error, S_IWUSR | S_IRUGO);
+ param_get_int, &binder_stop_on_user_error, 0644);
#define binder_debug(mask, x...) \
do { \
@@ -250,7 +250,7 @@
unsigned int cur = atomic_inc_return(&log->cur);
if (cur >= ARRAY_SIZE(log->entry))
- log->full = 1;
+ log->full = true;
e = &log->entry[cur % ARRAY_SIZE(log->entry)];
WRITE_ONCE(e->debug_id_done, 0);
/*
@@ -465,8 +465,9 @@
};
enum binder_deferred_state {
- BINDER_DEFERRED_FLUSH = 0x01,
- BINDER_DEFERRED_RELEASE = 0x02,
+ BINDER_DEFERRED_PUT_FILES = 0x01,
+ BINDER_DEFERRED_FLUSH = 0x02,
+ BINDER_DEFERRED_RELEASE = 0x04,
};
/**
@@ -503,6 +504,9 @@
* (invariant after initialized)
* @tsk task_struct for group_leader of process
* (invariant after initialized)
+ * @files files_struct for process
+ * (protected by @files_lock)
+ * @files_lock mutex to protect @files
* @deferred_work_node: element for binder_deferred_list
* (protected by binder_deferred_lock)
* @deferred_work: bitmap of deferred work to perform
@@ -547,6 +551,8 @@
struct list_head waiting_threads;
int pid;
struct task_struct *tsk;
+ struct files_struct *files;
+ struct mutex files_lock;
struct hlist_node deferred_work_node;
int deferred_work;
bool is_dead;
@@ -941,33 +947,27 @@
static void binder_free_proc(struct binder_proc *proc);
static void binder_inc_node_tmpref_ilocked(struct binder_node *node);
-struct files_struct *binder_get_files_struct(struct binder_proc *proc)
-{
- return get_files_struct(proc->tsk);
-}
-
static int task_get_unused_fd_flags(struct binder_proc *proc, int flags)
{
- struct files_struct *files;
unsigned long rlim_cur;
unsigned long irqs;
int ret;
- files = binder_get_files_struct(proc);
- if (files == NULL)
- return -ESRCH;
-
+ mutex_lock(&proc->files_lock);
+ if (proc->files == NULL) {
+ ret = -ESRCH;
+ goto err;
+ }
if (!lock_task_sighand(proc->tsk, &irqs)) {
ret = -EMFILE;
goto err;
}
-
rlim_cur = task_rlimit(proc->tsk, RLIMIT_NOFILE);
unlock_task_sighand(proc->tsk, &irqs);
- ret = __alloc_fd(files, 0, rlim_cur, flags);
+ ret = __alloc_fd(proc->files, 0, rlim_cur, flags);
err:
- put_files_struct(files);
+ mutex_unlock(&proc->files_lock);
return ret;
}
@@ -977,12 +977,10 @@
static void task_fd_install(
struct binder_proc *proc, unsigned int fd, struct file *file)
{
- struct files_struct *files = binder_get_files_struct(proc);
-
- if (files) {
- __fd_install(files, fd, file);
- put_files_struct(files);
- }
+ mutex_lock(&proc->files_lock);
+ if (proc->files)
+ __fd_install(proc->files, fd, file);
+ mutex_unlock(&proc->files_lock);
}
/*
@@ -990,21 +988,22 @@
*/
static long task_close_fd(struct binder_proc *proc, unsigned int fd)
{
- struct files_struct *files = binder_get_files_struct(proc);
int retval;
- if (files == NULL)
- return -ESRCH;
-
- retval = __close_fd(files, fd);
+ mutex_lock(&proc->files_lock);
+ if (proc->files == NULL) {
+ retval = -ESRCH;
+ goto err;
+ }
+ retval = __close_fd(proc->files, fd);
/* can't restart close syscall because file table entry was cleared */
if (unlikely(retval == -ERESTARTSYS ||
retval == -ERESTARTNOINTR ||
retval == -ERESTARTNOHAND ||
retval == -ERESTART_RESTARTBLOCK))
retval = -EINTR;
- put_files_struct(files);
-
+err:
+ mutex_unlock(&proc->files_lock);
return retval;
}
@@ -2214,8 +2213,8 @@
struct binder_object_header *hdr;
size_t object_size = 0;
- if (offset > buffer->data_size - sizeof(*hdr) ||
- buffer->data_size < sizeof(*hdr) ||
+ if (buffer->data_size < sizeof(*hdr) ||
+ offset > buffer->data_size - sizeof(*hdr) ||
!IS_ALIGNED(offset, sizeof(u32)))
return 0;
@@ -2355,7 +2354,7 @@
int debug_id = buffer->debug_id;
binder_debug(BINDER_DEBUG_TRANSACTION,
- "%d buffer release %d, size %zd-%zd, failed at %p\n",
+ "%d buffer release %d, size %zd-%zd, failed at %pK\n",
proc->pid, buffer->debug_id,
buffer->data_size, buffer->offsets_size, failed_at);
@@ -2804,7 +2803,7 @@
if (node->has_async_transaction) {
pending_async = true;
} else {
- node->has_async_transaction = 1;
+ node->has_async_transaction = true;
}
}
@@ -3669,7 +3668,7 @@
w = binder_dequeue_work_head_ilocked(
&buf_node->async_todo);
if (!w) {
- buf_node->has_async_transaction = 0;
+ buf_node->has_async_transaction = false;
} else {
binder_enqueue_work_ilocked(
w, &proc->todo);
@@ -3891,7 +3890,7 @@
}
}
binder_debug(BINDER_DEBUG_DEAD_BINDER,
- "%d:%d BC_DEAD_BINDER_DONE %016llx found %p\n",
+ "%d:%d BC_DEAD_BINDER_DONE %016llx found %pK\n",
proc->pid, thread->pid, (u64)cookie,
death);
if (death == NULL) {
@@ -4097,6 +4096,7 @@
binder_inner_proc_unlock(proc);
if (put_user(e->cmd, (uint32_t __user *)ptr))
return -EFAULT;
+ cmd = e->cmd;
e->cmd = BR_OK;
ptr += sizeof(uint32_t);
@@ -4865,6 +4865,7 @@
(vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
(unsigned long)pgprot_val(vma->vm_page_prot));
binder_alloc_vma_close(&proc->alloc);
+ binder_defer_work(proc, BINDER_DEFERRED_PUT_FILES);
}
static int binder_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
@@ -4901,16 +4902,22 @@
failure_string = "bad vm_flags";
goto err_bad_arg;
}
- vma->vm_flags = (vma->vm_flags | VM_DONTCOPY) & ~VM_MAYWRITE;
+ vma->vm_flags |= VM_DONTCOPY | VM_MIXEDMAP;
+ vma->vm_flags &= ~VM_MAYWRITE;
+
vma->vm_ops = &binder_vm_ops;
vma->vm_private_data = proc;
ret = binder_alloc_mmap_handler(&proc->alloc, vma);
-
- return ret;
+ if (ret)
+ return ret;
+ mutex_lock(&proc->files_lock);
+ proc->files = get_files_struct(current);
+ mutex_unlock(&proc->files_lock);
+ return 0;
err_bad_arg:
- pr_err("binder_mmap: %d %lx-%lx %s failed %d\n",
+ pr_err("%s: %d %lx-%lx %s failed %d\n", __func__,
proc->pid, vma->vm_start, vma->vm_end, failure_string, ret);
return ret;
}
@@ -4920,7 +4927,7 @@
struct binder_proc *proc;
struct binder_device *binder_dev;
- binder_debug(BINDER_DEBUG_OPEN_CLOSE, "binder_open: %d:%d\n",
+ binder_debug(BINDER_DEBUG_OPEN_CLOSE, "%s: %d:%d\n", __func__,
current->group_leader->pid, current->pid);
proc = kzalloc(sizeof(*proc), GFP_KERNEL);
@@ -4930,6 +4937,7 @@
spin_lock_init(&proc->outer_lock);
get_task_struct(current->group_leader);
proc->tsk = current->group_leader;
+ mutex_init(&proc->files_lock);
INIT_LIST_HEAD(&proc->todo);
if (binder_supported_policy(current->policy)) {
proc->default_priority.sched_policy = current->policy;
@@ -4965,7 +4973,7 @@
* anyway print all contexts that a given PID has, so this
* is not a problem.
*/
- proc->debugfs_entry = debugfs_create_file(strbuf, S_IRUGO,
+ proc->debugfs_entry = debugfs_create_file(strbuf, 0444,
binder_debugfs_dir_entry_proc,
(void *)(unsigned long)proc->pid,
&binder_proc_fops);
@@ -5086,6 +5094,8 @@
struct rb_node *n;
int threads, nodes, incoming_refs, outgoing_refs, active_transactions;
+ BUG_ON(proc->files);
+
mutex_lock(&binder_procs_lock);
hlist_del(&proc->proc_node);
mutex_unlock(&binder_procs_lock);
@@ -5167,6 +5177,8 @@
static void binder_deferred_func(struct work_struct *work)
{
struct binder_proc *proc;
+ struct files_struct *files;
+
int defer;
do {
@@ -5183,11 +5195,23 @@
}
mutex_unlock(&binder_deferred_lock);
+ files = NULL;
+ if (defer & BINDER_DEFERRED_PUT_FILES) {
+ mutex_lock(&proc->files_lock);
+ files = proc->files;
+ if (files)
+ proc->files = NULL;
+ mutex_unlock(&proc->files_lock);
+ }
+
if (defer & BINDER_DEFERRED_FLUSH)
binder_deferred_flush(proc);
if (defer & BINDER_DEFERRED_RELEASE)
binder_deferred_release(proc); /* frees proc */
+
+ if (files)
+ put_files_struct(files);
} while (proc);
}
static DECLARE_WORK(binder_deferred_work, binder_deferred_func);
@@ -5216,7 +5240,7 @@
spin_lock(&t->lock);
to_proc = t->to_proc;
seq_printf(m,
- "%s %d: %p from %d:%d to %d:%d code %x flags %x pri %d:%d r%d",
+ "%s %d: %pK from %d:%d to %d:%d code %x flags %x pri %d:%d r%d",
prefix, t->debug_id, t,
t->from ? t->from->proc->pid : 0,
t->from ? t->from->pid : 0,
@@ -5241,7 +5265,7 @@
}
if (buffer->target_node)
seq_printf(m, " node %d", buffer->target_node->debug_id);
- seq_printf(m, " size %zd:%zd data %p\n",
+ seq_printf(m, " size %zd:%zd data %pK\n",
buffer->data_size, buffer->offsets_size,
buffer->data);
}
@@ -5776,11 +5800,13 @@
static int __init binder_init(void)
{
int ret;
- char *device_name, *device_names;
+ char *device_name, *device_names, *device_tmp;
struct binder_device *device;
struct hlist_node *tmp;
- binder_alloc_shrinker_init();
+ ret = binder_alloc_shrinker_init();
+ if (ret)
+ return ret;
atomic_set(&binder_transaction_log.cur, ~0U);
atomic_set(&binder_transaction_log_failed.cur, ~0U);
@@ -5792,27 +5818,27 @@
if (binder_debugfs_dir_entry_root) {
debugfs_create_file("state",
- S_IRUGO,
+ 0444,
binder_debugfs_dir_entry_root,
NULL,
&binder_state_fops);
debugfs_create_file("stats",
- S_IRUGO,
+ 0444,
binder_debugfs_dir_entry_root,
NULL,
&binder_stats_fops);
debugfs_create_file("transactions",
- S_IRUGO,
+ 0444,
binder_debugfs_dir_entry_root,
NULL,
&binder_transactions_fops);
debugfs_create_file("transaction_log",
- S_IRUGO,
+ 0444,
binder_debugfs_dir_entry_root,
&binder_transaction_log,
&binder_transaction_log_fops);
debugfs_create_file("failed_transaction_log",
- S_IRUGO,
+ 0444,
binder_debugfs_dir_entry_root,
&binder_transaction_log_failed,
&binder_transaction_log_fops);
@@ -5829,7 +5855,8 @@
}
strcpy(device_names, binder_devices_param);
- while ((device_name = strsep(&device_names, ","))) {
+ device_tmp = device_names;
+ while ((device_name = strsep(&device_tmp, ","))) {
ret = init_binder_device(device_name);
if (ret)
goto err_init_binder_device_failed;
@@ -5843,6 +5870,9 @@
hlist_del(&device->hlist);
kfree(device);
}
+
+ kfree(device_names);
+
err_alloc_device_names_failed:
debugfs_remove_recursive(binder_debugfs_dir_entry_root);
diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c
index abb56a9..bec6c0a 100644
--- a/drivers/android/binder_alloc.c
+++ b/drivers/android/binder_alloc.c
@@ -219,7 +219,7 @@
mm = alloc->vma_vm_mm;
if (mm) {
- down_write(&mm->mmap_sem);
+ down_read(&mm->mmap_sem);
vma = alloc->vma;
}
@@ -288,7 +288,7 @@
/* vm_insert_page does not seem to increment the refcount */
}
if (mm) {
- up_write(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
mmput(mm);
}
return 0;
@@ -321,17 +321,18 @@
}
err_no_vma:
if (mm) {
- up_write(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
mmput(mm);
}
return vma ? -ENOMEM : -ESRCH;
}
-struct binder_buffer *binder_alloc_new_buf_locked(struct binder_alloc *alloc,
- size_t data_size,
- size_t offsets_size,
- size_t extra_buffers_size,
- int is_async)
+static struct binder_buffer *binder_alloc_new_buf_locked(
+ struct binder_alloc *alloc,
+ size_t data_size,
+ size_t offsets_size,
+ size_t extra_buffers_size,
+ int is_async)
{
struct rb_node *n = alloc->free_buffers.rb_node;
struct binder_buffer *buffer;
@@ -1008,8 +1009,14 @@
INIT_LIST_HEAD(&alloc->buffers);
}
-void binder_alloc_shrinker_init(void)
+int binder_alloc_shrinker_init(void)
{
- list_lru_init(&binder_alloc_lru);
- register_shrinker(&binder_shrinker);
+ int ret = list_lru_init(&binder_alloc_lru);
+
+ if (ret == 0) {
+ ret = register_shrinker(&binder_shrinker);
+ if (ret)
+ list_lru_destroy(&binder_alloc_lru);
+ }
+ return ret;
}
diff --git a/drivers/android/binder_alloc.h b/drivers/android/binder_alloc.h
index 0b14530..9ef64e5 100644
--- a/drivers/android/binder_alloc.h
+++ b/drivers/android/binder_alloc.h
@@ -130,7 +130,7 @@
size_t extra_buffers_size,
int is_async);
extern void binder_alloc_init(struct binder_alloc *alloc);
-void binder_alloc_shrinker_init(void);
+extern int binder_alloc_shrinker_init(void);
extern void binder_alloc_vma_close(struct binder_alloc *alloc);
extern struct binder_buffer *
binder_alloc_prepare_to_free(struct binder_alloc *alloc,
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 4d4b5f6..faa91f8 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -1260,6 +1260,59 @@
return strcmp(buf, dmi->driver_data) < 0;
}
+static bool ahci_broken_lpm(struct pci_dev *pdev)
+{
+ static const struct dmi_system_id sysids[] = {
+ /* Various Lenovo 50 series have LPM issues with older BIOSen */
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X250"),
+ },
+ .driver_data = "20180406", /* 1.31 */
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L450"),
+ },
+ .driver_data = "20180420", /* 1.28 */
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T450s"),
+ },
+ .driver_data = "20180315", /* 1.33 */
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad W541"),
+ },
+ /*
+ * Note date based on release notes, 2.35 has been
+ * reported to be good, but I've been unable to get
+ * a hold of the reporter to get the DMI BIOS date.
+ * TODO: fix this.
+ */
+ .driver_data = "20180310", /* 2.35 */
+ },
+ { } /* terminate list */
+ };
+ const struct dmi_system_id *dmi = dmi_first_match(sysids);
+ int year, month, date;
+ char buf[9];
+
+ if (!dmi)
+ return false;
+
+ dmi_get_date(DMI_BIOS_DATE, &year, &month, &date);
+ snprintf(buf, sizeof(buf), "%04d%02d%02d", year, month, date);
+
+ return strcmp(buf, dmi->driver_data) < 0;
+}
+
static bool ahci_broken_online(struct pci_dev *pdev)
{
#define ENCODE_BUSDEVFN(bus, slot, func) \
@@ -1626,6 +1679,12 @@
"quirky BIOS, skipping spindown on poweroff\n");
}
+ if (ahci_broken_lpm(pdev)) {
+ pi.flags |= ATA_FLAG_NO_LPM;
+ dev_warn(&pdev->dev,
+ "BIOS update required for Link Power Management support\n");
+ }
+
if (ahci_broken_suspend(pdev)) {
hpriv->flags |= AHCI_HFLAG_NO_SUSPEND;
dev_warn(&pdev->dev,
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 82c59a1..73d636d 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -2385,6 +2385,9 @@
(id[ATA_ID_SATA_CAPABILITY] & 0xe) == 0x2)
dev->horkage |= ATA_HORKAGE_NOLPM;
+ if (ap->flags & ATA_FLAG_NO_LPM)
+ dev->horkage |= ATA_HORKAGE_NOLPM;
+
if (dev->horkage & ATA_HORKAGE_NOLPM) {
ata_dev_warn(dev, "LPM support broken, forcing max_power\n");
dev->link->ap->target_lpm_policy = ATA_LPM_MAX_POWER;
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 6475a13..90c3877 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -2282,12 +2282,16 @@
if (qc->err_mask & ~AC_ERR_OTHER)
qc->err_mask &= ~AC_ERR_OTHER;
- /* SENSE_VALID trumps dev/unknown error and revalidation */
+ /*
+ * SENSE_VALID trumps dev/unknown error and revalidation. Upper
+ * layers will determine whether the command is worth retrying
+ * based on the sense data and device class/type. Otherwise,
+ * determine directly if the command is worth retrying using its
+ * error mask and flags.
+ */
if (qc->flags & ATA_QCFLAG_SENSE_VALID)
qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER);
-
- /* determine whether the command is worth retrying */
- if (ata_eh_worth_retry(qc))
+ else if (ata_eh_worth_retry(qc))
qc->flags |= ATA_QCFLAG_RETRY;
/* accumulate error info */
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index fb2c00f..a3d60cc 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3772,10 +3772,20 @@
*/
goto invalid_param_len;
}
- if (block > dev->n_sectors)
- goto out_of_range;
all = cdb[14] & 0x1;
+ if (all) {
+ /*
+ * Ignore the block address (zone ID) as defined by ZBC.
+ */
+ block = 0;
+ } else if (block >= dev->n_sectors) {
+ /*
+ * Block must be a valid zone ID (a zone start LBA).
+ */
+ fp = 2;
+ goto invalid_fld;
+ }
if (ata_ncq_enabled(qc->dev) &&
ata_fpdma_zac_mgmt_out_supported(qc->dev)) {
@@ -3804,10 +3814,6 @@
invalid_fld:
ata_scsi_set_invalid_field(qc->dev, scmd, fp, 0xff);
return 1;
- out_of_range:
- /* "Logical Block Address out of range" */
- ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x21, 0x00);
- return 1;
invalid_param_len:
/* "Parameter list length error" */
ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x1a, 0x0);
diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c
index d0fac64..a0b88f1 100644
--- a/drivers/atm/zatm.c
+++ b/drivers/atm/zatm.c
@@ -1483,6 +1483,8 @@
return -EFAULT;
if (pool < 0 || pool > ZATM_LAST_POOL)
return -EINVAL;
+ pool = array_index_nospec(pool,
+ ZATM_LAST_POOL + 1);
if (copy_from_user(&info,
&((struct zatm_pool_req __user *) arg)->info,
sizeof(info))) return -EFAULT;
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index f95593a..a7baf3c 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -384,14 +384,6 @@
goto probe_failed;
}
- /*
- * Ensure devices are listed in devices_kset in correct order
- * It's important to move Dev to the end of devices_kset before
- * calling .probe, because it could be recursive and parent Dev
- * should always go first
- */
- devices_kset_move_last(dev);
-
if (dev->bus->probe) {
ret = dev->bus->probe(dev);
if (ret)
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index ff1c4d7..9f840d9 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -640,6 +640,36 @@
__func__, lo->lo_number, lo->lo_file_name, rc);
}
+static inline int is_loop_device(struct file *file)
+{
+ struct inode *i = file->f_mapping->host;
+
+ return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR;
+}
+
+static int loop_validate_file(struct file *file, struct block_device *bdev)
+{
+ struct inode *inode = file->f_mapping->host;
+ struct file *f = file;
+
+ /* Avoid recursion */
+ while (is_loop_device(f)) {
+ struct loop_device *l;
+
+ if (f->f_mapping->host->i_bdev == bdev)
+ return -EBADF;
+
+ l = f->f_mapping->host->i_bdev->bd_disk->private_data;
+ if (l->lo_state == Lo_unbound) {
+ return -EINVAL;
+ }
+ f = l->lo_backing_file;
+ }
+ if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))
+ return -EINVAL;
+ return 0;
+}
+
/*
* loop_change_fd switched the backing store of a loopback device to
* a new file. This is useful for operating system installers to free up
@@ -669,14 +699,15 @@
if (!file)
goto out;
+ error = loop_validate_file(file, bdev);
+ if (error)
+ goto out_putf;
+
inode = file->f_mapping->host;
old_file = lo->lo_backing_file;
error = -EINVAL;
- if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))
- goto out_putf;
-
/* size of the new backing store needs to be the same */
if (get_loop_size(lo, file) != get_loop_size(lo, old_file))
goto out_putf;
@@ -697,13 +728,6 @@
return error;
}
-static inline int is_loop_device(struct file *file)
-{
- struct inode *i = file->f_mapping->host;
-
- return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR;
-}
-
/* loop sysfs attributes */
static ssize_t loop_attr_show(struct device *dev, char *page,
@@ -800,16 +824,17 @@
.attrs= loop_attrs,
};
-static int loop_sysfs_init(struct loop_device *lo)
+static void loop_sysfs_init(struct loop_device *lo)
{
- return sysfs_create_group(&disk_to_dev(lo->lo_disk)->kobj,
- &loop_attribute_group);
+ lo->sysfs_inited = !sysfs_create_group(&disk_to_dev(lo->lo_disk)->kobj,
+ &loop_attribute_group);
}
static void loop_sysfs_exit(struct loop_device *lo)
{
- sysfs_remove_group(&disk_to_dev(lo->lo_disk)->kobj,
- &loop_attribute_group);
+ if (lo->sysfs_inited)
+ sysfs_remove_group(&disk_to_dev(lo->lo_disk)->kobj,
+ &loop_attribute_group);
}
static void loop_config_discard(struct loop_device *lo)
@@ -861,7 +886,7 @@
static int loop_set_fd(struct loop_device *lo, fmode_t mode,
struct block_device *bdev, unsigned int arg)
{
- struct file *file, *f;
+ struct file *file;
struct inode *inode;
struct address_space *mapping;
unsigned lo_blocksize;
@@ -881,29 +906,13 @@
if (lo->lo_state != Lo_unbound)
goto out_putf;
- /* Avoid recursion */
- f = file;
- while (is_loop_device(f)) {
- struct loop_device *l;
-
- if (f->f_mapping->host->i_bdev == bdev)
- goto out_putf;
-
- l = f->f_mapping->host->i_bdev->bd_disk->private_data;
- if (l->lo_state == Lo_unbound) {
- error = -EINVAL;
- goto out_putf;
- }
- f = l->lo_backing_file;
- }
+ error = loop_validate_file(file, bdev);
+ if (error)
+ goto out_putf;
mapping = file->f_mapping;
inode = mapping->host;
- error = -EINVAL;
- if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))
- goto out_putf;
-
if (!(file->f_mode & FMODE_WRITE) || !(mode & FMODE_WRITE) ||
!file->f_op->write_iter)
lo_flags |= LO_FLAGS_READ_ONLY;
diff --git a/drivers/block/loop.h b/drivers/block/loop.h
index fb2237c..60f0fd2 100644
--- a/drivers/block/loop.h
+++ b/drivers/block/loop.h
@@ -59,6 +59,7 @@
struct kthread_worker worker;
struct task_struct *worker_task;
bool use_dio;
+ bool sysfs_inited;
struct request_queue *lo_queue;
struct blk_mq_tag_set tag_set;
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index bff67c5..44bccb1 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -348,6 +348,9 @@
/* Additional Realtek 8723BU Bluetooth devices */
{ USB_DEVICE(0x7392, 0xa611), .driver_info = BTUSB_REALTEK },
+ /* Additional Realtek 8723DE Bluetooth devices */
+ { USB_DEVICE(0x2ff8, 0xb011), .driver_info = BTUSB_REALTEK },
+
/* Additional Realtek 8821AE Bluetooth devices */
{ USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK },
{ USB_DEVICE(0x13d3, 0x3414), .driver_info = BTUSB_REALTEK },
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 3a8b9ae..0986c32 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -884,7 +884,7 @@
*/
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(msecs_to_jiffies(BAUDRATE_SETTLE_TIMEOUT_MS));
- set_current_state(TASK_INTERRUPTIBLE);
+ set_current_state(TASK_RUNNING);
return 0;
}
diff --git a/drivers/bus/arm-ccn.c b/drivers/bus/arm-ccn.c
index 45d7ecc..4e9e9e6 100644
--- a/drivers/bus/arm-ccn.c
+++ b/drivers/bus/arm-ccn.c
@@ -736,7 +736,7 @@
ccn = pmu_to_arm_ccn(event->pmu);
if (hw->sample_period) {
- dev_warn(ccn->dev, "Sampling not supported!\n");
+ dev_dbg(ccn->dev, "Sampling not supported!\n");
return -EOPNOTSUPP;
}
@@ -744,12 +744,12 @@
event->attr.exclude_kernel || event->attr.exclude_hv ||
event->attr.exclude_idle || event->attr.exclude_host ||
event->attr.exclude_guest) {
- dev_warn(ccn->dev, "Can't exclude execution levels!\n");
+ dev_dbg(ccn->dev, "Can't exclude execution levels!\n");
return -EINVAL;
}
if (event->cpu < 0) {
- dev_warn(ccn->dev, "Can't provide per-task data!\n");
+ dev_dbg(ccn->dev, "Can't provide per-task data!\n");
return -EOPNOTSUPP;
}
/*
@@ -771,13 +771,13 @@
switch (type) {
case CCN_TYPE_MN:
if (node_xp != ccn->mn_id) {
- dev_warn(ccn->dev, "Invalid MN ID %d!\n", node_xp);
+ dev_dbg(ccn->dev, "Invalid MN ID %d!\n", node_xp);
return -EINVAL;
}
break;
case CCN_TYPE_XP:
if (node_xp >= ccn->num_xps) {
- dev_warn(ccn->dev, "Invalid XP ID %d!\n", node_xp);
+ dev_dbg(ccn->dev, "Invalid XP ID %d!\n", node_xp);
return -EINVAL;
}
break;
@@ -785,11 +785,11 @@
break;
default:
if (node_xp >= ccn->num_nodes) {
- dev_warn(ccn->dev, "Invalid node ID %d!\n", node_xp);
+ dev_dbg(ccn->dev, "Invalid node ID %d!\n", node_xp);
return -EINVAL;
}
if (!arm_ccn_pmu_type_eq(type, ccn->node[node_xp].type)) {
- dev_warn(ccn->dev, "Invalid type 0x%x for node %d!\n",
+ dev_dbg(ccn->dev, "Invalid type 0x%x for node %d!\n",
type, node_xp);
return -EINVAL;
}
@@ -808,19 +808,19 @@
if (event_id != e->event)
continue;
if (e->num_ports && port >= e->num_ports) {
- dev_warn(ccn->dev, "Invalid port %d for node/XP %d!\n",
+ dev_dbg(ccn->dev, "Invalid port %d for node/XP %d!\n",
port, node_xp);
return -EINVAL;
}
if (e->num_vcs && vc >= e->num_vcs) {
- dev_warn(ccn->dev, "Invalid vc %d for node/XP %d!\n",
+ dev_dbg(ccn->dev, "Invalid vc %d for node/XP %d!\n",
vc, node_xp);
return -EINVAL;
}
valid = 1;
}
if (!valid) {
- dev_warn(ccn->dev, "Invalid event 0x%x for node/XP %d!\n",
+ dev_dbg(ccn->dev, "Invalid event 0x%x for node/XP %d!\n",
event_id, node_xp);
return -EINVAL;
}
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index 034bd9d..67677ea 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -2734,6 +2734,7 @@
goto bail;
map->raddr = raddr;
}
+ ud->vaddrout = raddr;
bail:
if (err && map) {
mutex_lock(&fl->fl_map_mutex);
@@ -3433,7 +3434,7 @@
if (err)
return err;
snprintf(strpid, PID_SIZE, "%d", current->pid);
- buf_size = strlen(current->comm) + strlen(strpid) + 1;
+ buf_size = strlen(current->comm) + strlen("_") + strlen(strpid) + 1;
fl->debug_buf = kzalloc(buf_size, GFP_KERNEL);
snprintf(fl->debug_buf, UL_SIZE, "%.10s%s%d",
current->comm, "_", current->pid);
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 131a050..c613667 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -3227,13 +3227,13 @@
mutex_lock(&apps_data_mutex);
mutex_lock(&driver->hdlc_disable_mutex);
hdlc_disabled = driver->p_hdlc_disabled[APPS_DATA];
+ mutex_unlock(&driver->hdlc_disable_mutex);
if (hdlc_disabled)
ret = diag_process_apps_data_non_hdlc(user_space_data, len,
pkt_type);
else
ret = diag_process_apps_data_hdlc(user_space_data, len,
pkt_type);
- mutex_unlock(&driver->hdlc_disable_mutex);
mutex_unlock(&apps_data_mutex);
diagmem_free(driver, user_space_data, mempool);
diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c
index a6d5ca8..7a7d0fc 100644
--- a/drivers/char/diag/diagfwd_cntl.c
+++ b/drivers/char/diag/diagfwd_cntl.c
@@ -619,7 +619,12 @@
}
if (range->ssid_last >= mask->ssid_last) {
temp_range = range->ssid_last - mask->ssid_first + 1;
- mask->ssid_last = range->ssid_last;
+ if (temp_range > MAX_SSID_PER_RANGE) {
+ temp_range = MAX_SSID_PER_RANGE;
+ mask->ssid_last = mask->ssid_first + temp_range - 1;
+ } else
+ mask->ssid_last = range->ssid_last;
+ mask->ssid_last_tools = mask->ssid_last;
mask->range = temp_range;
}
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 1b3c731..464b95a 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1826,14 +1826,22 @@
write_pool(struct entropy_store *r, const char __user *buffer, size_t count)
{
size_t bytes;
- __u32 buf[16];
+ __u32 t, buf[16];
const char __user *p = buffer;
while (count > 0) {
+ int b, i = 0;
+
bytes = min(count, sizeof(buf));
if (copy_from_user(&buf, p, bytes))
return -EFAULT;
+ for (b = bytes ; b > 0 ; b -= sizeof(__u32), i++) {
+ if (!arch_get_random_int(&t))
+ break;
+ buf[i] ^= t;
+ }
+
count -= bytes;
p += bytes;
diff --git a/drivers/clk/msm/clock-gcc-8952.c b/drivers/clk/msm/clock-gcc-8952.c
index 47619f5..3c989eb 100644
--- a/drivers/clk/msm/clock-gcc-8952.c
+++ b/drivers/clk/msm/clock-gcc-8952.c
@@ -840,6 +840,7 @@
F_SLEW( 270000000, FIXED_CLK_SRC, gpll6_aux, 4, 0, 0),
F_SLEW( 320000000, FIXED_CLK_SRC, gpll0, 2.5, 0, 0),
F_SLEW( 400000000, FIXED_CLK_SRC, gpll0, 2, 0, 0),
+ F_SLEW( 465000000, 930000000, gpll3, 1, 0, 0),
F_SLEW( 484800000, 969600000, gpll3, 1, 0, 0),
F_SLEW( 523200000, 1046400000, gpll3, 1, 0, 0),
F_SLEW( 550000000, 1100000000, gpll3, 1, 0, 0),
@@ -860,6 +861,7 @@
F_SLEW( 270000000, FIXED_CLK_SRC, gpll6_aux, 4, 0, 0),
F_SLEW( 320000000, FIXED_CLK_SRC, gpll0, 2.5, 0, 0),
F_SLEW( 400000000, FIXED_CLK_SRC, gpll0, 2, 0, 0),
+ F_SLEW( 465000000, 930000000, gpll3, 1, 0, 0),
F_SLEW( 484800000, 969600000, gpll3, 1, 0, 0),
F_SLEW( 523200000, 1046400000, gpll3, 1, 0, 0),
F_SLEW( 550000000, 1100000000, gpll3, 1, 0, 0),
diff --git a/drivers/cpufreq/cpufreq_times.c b/drivers/cpufreq/cpufreq_times.c
index 6254f45..0e8754b6 100644
--- a/drivers/cpufreq/cpufreq_times.c
+++ b/drivers/cpufreq/cpufreq_times.c
@@ -234,16 +234,19 @@
void cpufreq_task_times_init(struct task_struct *p)
{
- void *temp;
unsigned long flags;
- unsigned int max_state;
spin_lock_irqsave(&task_time_in_state_lock, flags);
p->time_in_state = NULL;
spin_unlock_irqrestore(&task_time_in_state_lock, flags);
p->max_state = 0;
+}
- max_state = READ_ONCE(next_offset);
+void cpufreq_task_times_alloc(struct task_struct *p)
+{
+ void *temp;
+ unsigned long flags;
+ unsigned int max_state = READ_ONCE(next_offset);
/* We use one array to avoid multiple allocs per task */
temp = kcalloc(max_state, sizeof(p->time_in_state[0]), GFP_ATOMIC);
diff --git a/drivers/cpuidle/lpm-levels.c b/drivers/cpuidle/lpm-levels.c
index 3c75997..ae72206 100644
--- a/drivers/cpuidle/lpm-levels.c
+++ b/drivers/cpuidle/lpm-levels.c
@@ -1776,7 +1776,7 @@
md_entry.virt_addr = (uintptr_t)lpm_debug;
md_entry.phys_addr = lpm_debug_phys;
md_entry.size = size;
- if (msm_minidump_add_region(&md_entry))
+ if (msm_minidump_add_region(&md_entry) < 0)
pr_info("Failed to add lpm_debug in Minidump\n");
return 0;
diff --git a/drivers/crypto/amcc/crypto4xx_core.c b/drivers/crypto/amcc/crypto4xx_core.c
index dae1e39..c7524bb 100644
--- a/drivers/crypto/amcc/crypto4xx_core.c
+++ b/drivers/crypto/amcc/crypto4xx_core.c
@@ -208,7 +208,7 @@
dev->pdr_pa);
return -ENOMEM;
}
- memset(dev->pdr, 0, sizeof(struct ce_pd) * PPC4XX_NUM_PD);
+ memset(dev->pdr, 0, sizeof(struct ce_pd) * PPC4XX_NUM_PD);
dev->shadow_sa_pool = dma_alloc_coherent(dev->core_dev->device,
256 * PPC4XX_NUM_PD,
&dev->shadow_sa_pool_pa,
@@ -241,13 +241,15 @@
static void crypto4xx_destroy_pdr(struct crypto4xx_device *dev)
{
- if (dev->pdr != NULL)
+ if (dev->pdr)
dma_free_coherent(dev->core_dev->device,
sizeof(struct ce_pd) * PPC4XX_NUM_PD,
dev->pdr, dev->pdr_pa);
+
if (dev->shadow_sa_pool)
dma_free_coherent(dev->core_dev->device, 256 * PPC4XX_NUM_PD,
dev->shadow_sa_pool, dev->shadow_sa_pool_pa);
+
if (dev->shadow_sr_pool)
dma_free_coherent(dev->core_dev->device,
sizeof(struct sa_state_record) * PPC4XX_NUM_PD,
@@ -417,12 +419,12 @@
static void crypto4xx_destroy_sdr(struct crypto4xx_device *dev)
{
- if (dev->sdr != NULL)
+ if (dev->sdr)
dma_free_coherent(dev->core_dev->device,
sizeof(struct ce_sd) * PPC4XX_NUM_SD,
dev->sdr, dev->sdr_pa);
- if (dev->scatter_buffer_va != NULL)
+ if (dev->scatter_buffer_va)
dma_free_coherent(dev->core_dev->device,
dev->scatter_buffer_size * PPC4XX_NUM_SD,
dev->scatter_buffer_va,
@@ -1034,12 +1036,10 @@
break;
}
- if (rc) {
- list_del(&alg->entry);
+ if (rc)
kfree(alg);
- } else {
+ else
list_add_tail(&alg->entry, &sec_dev->alg_list);
- }
}
return 0;
@@ -1193,7 +1193,7 @@
rc = crypto4xx_build_gdr(core_dev->dev);
if (rc)
- goto err_build_gdr;
+ goto err_build_pdr;
rc = crypto4xx_build_sdr(core_dev->dev);
if (rc)
@@ -1236,12 +1236,11 @@
err_request_irq:
irq_dispose_mapping(core_dev->irq);
tasklet_kill(&core_dev->tasklet);
- crypto4xx_destroy_sdr(core_dev->dev);
err_build_sdr:
+ crypto4xx_destroy_sdr(core_dev->dev);
crypto4xx_destroy_gdr(core_dev->dev);
-err_build_gdr:
- crypto4xx_destroy_pdr(core_dev->dev);
err_build_pdr:
+ crypto4xx_destroy_pdr(core_dev->dev);
kfree(core_dev->dev);
err_alloc_dev:
kfree(core_dev);
diff --git a/drivers/devfreq/governor_bw_hwmon.c b/drivers/devfreq/governor_bw_hwmon.c
index cb04014..d0be577 100644
--- a/drivers/devfreq/governor_bw_hwmon.c
+++ b/drivers/devfreq/governor_bw_hwmon.c
@@ -74,6 +74,7 @@
struct bw_hwmon *hw;
struct devfreq_governor *gov;
struct attribute_group *attr_grp;
+ struct mutex mon_lock;
};
#define UP_WAKE 1
@@ -511,8 +512,11 @@
if (!node)
return -ENODEV;
- if (!node->mon_started)
+ mutex_lock(&node->mon_lock);
+ if (!node->mon_started) {
+ mutex_unlock(&node->mon_lock);
return -EBUSY;
+ }
dev_dbg(df->dev.parent, "Got update request\n");
devfreq_monitor_stop(df);
@@ -526,6 +530,7 @@
devfreq_monitor_start(df);
+ mutex_unlock(&node->mon_lock);
return 0;
}
@@ -572,7 +577,9 @@
struct hwmon_node *node = df->data;
struct bw_hwmon *hw = node->hw;
+ mutex_lock(&node->mon_lock);
node->mon_started = false;
+ mutex_unlock(&node->mon_lock);
if (init) {
devfreq_monitor_stop(df);
@@ -932,6 +939,8 @@
node->mbps_zones[0] = 0;
node->hw = hwmon;
+ mutex_init(&node->mon_lock);
+
mutex_lock(&list_lock);
list_add_tail(&node->list, &hwmon_list);
mutex_unlock(&list_lock);
diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c
index 61262a7..b0bd0f6 100644
--- a/drivers/edac/altera_edac.c
+++ b/drivers/edac/altera_edac.c
@@ -1111,7 +1111,7 @@
static void ocram_free_mem(void *p, size_t size, void *other)
{
- gen_pool_free((struct gen_pool *)other, (u32)p, size);
+ gen_pool_free((struct gen_pool *)other, (unsigned long)p, size);
}
static const struct edac_device_prv_data ocramecc_data = {
diff --git a/drivers/extcon/extcon-usb-gpio.c b/drivers/extcon/extcon-usb-gpio.c
index 2b108fa..a7a29fb 100644
--- a/drivers/extcon/extcon-usb-gpio.c
+++ b/drivers/extcon/extcon-usb-gpio.c
@@ -27,6 +27,7 @@
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/acpi.h>
+#include <linux/delay.h>
#define USB_GPIO_DEBOUNCE_MS 20 /* ms */
@@ -36,6 +37,7 @@
struct gpio_desc *id_gpiod;
struct gpio_desc *vbus_gpiod;
+ struct gpio_desc *trig_gpiod;
int id_irq;
int vbus_irq;
@@ -87,6 +89,12 @@
if (!id) {
extcon_set_state_sync(info->edev, EXTCON_USB_HOST, true);
+ if (info->trig_gpiod) {
+ gpiod_set_value(info->trig_gpiod, 1);
+ msleep(20);
+ gpiod_set_value(info->trig_gpiod, 0);
+ msleep(20);
+ }
} else {
if (vbus)
extcon_set_state_sync(info->edev, EXTCON_USB, true);
@@ -109,6 +117,7 @@
struct device_node *np = dev->of_node;
struct usb_extcon_info *info;
int ret;
+ const char *name = NULL;
if (!np && !ACPI_HANDLE(dev))
return -EINVAL;
@@ -121,6 +130,8 @@
info->id_gpiod = devm_gpiod_get_optional(&pdev->dev, "id", GPIOD_IN);
info->vbus_gpiod = devm_gpiod_get_optional(&pdev->dev, "vbus",
GPIOD_IN);
+ info->trig_gpiod = devm_gpiod_get_optional(&pdev->dev, "trig",
+ GPIOD_OUT_LOW);
if (!info->id_gpiod && !info->vbus_gpiod) {
dev_err(dev, "failed to get gpios\n");
@@ -133,6 +144,9 @@
if (IS_ERR(info->vbus_gpiod))
return PTR_ERR(info->vbus_gpiod);
+ if (IS_ERR(info->trig_gpiod))
+ return PTR_ERR(info->trig_gpiod);
+
info->edev = devm_extcon_dev_allocate(dev, usb_extcon_cable);
if (IS_ERR(info->edev)) {
dev_err(dev, "failed to allocate extcon device\n");
@@ -145,6 +159,25 @@
return ret;
}
+ if (info->trig_gpiod) {
+ ret = of_property_read_string_index(np, "gpio-names", 0, &name);
+ if (ret) {
+ dev_err(dev, "Could not get gpio name\n");
+ return ret;
+ }
+
+ ret = gpiod_export(info->trig_gpiod, 0);
+ if (ret) {
+ dev_err(dev, "failed to export gpio\n");
+ return ret;
+ }
+
+ ret = gpiod_export_link(dev, name, info->trig_gpiod);
+ if (ret) {
+ dev_err(dev, "failed to export gpio link\n");
+ return ret;
+ }
+ }
if (info->id_gpiod)
ret = gpiod_set_debounce(info->id_gpiod,
USB_GPIO_DEBOUNCE_MS * 1000);
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 33778bf..4e4043f 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1134,7 +1134,9 @@
{
struct drm_plane *plane = plane_state->plane;
struct drm_crtc_state *crtc_state;
-
+ /* Nothing to do for same crtc*/
+ if (plane_state->crtc == crtc)
+ return 0;
if (plane_state->crtc) {
crtc_state = drm_atomic_get_crtc_state(plane_state->state,
plane_state->crtc);
diff --git a/drivers/gpu/drm/gma500/psb_intel_drv.h b/drivers/gpu/drm/gma500/psb_intel_drv.h
index 2a3b7c6..fbd3fa3 100644
--- a/drivers/gpu/drm/gma500/psb_intel_drv.h
+++ b/drivers/gpu/drm/gma500/psb_intel_drv.h
@@ -255,7 +255,7 @@
extern bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
-extern int psb_intel_lvds_mode_valid(struct drm_connector *connector,
+extern enum drm_mode_status psb_intel_lvds_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode);
extern int psb_intel_lvds_set_property(struct drm_connector *connector,
struct drm_property *property,
diff --git a/drivers/gpu/drm/gma500/psb_intel_lvds.c b/drivers/gpu/drm/gma500/psb_intel_lvds.c
index 79e9d36..e2c6ba3 100644
--- a/drivers/gpu/drm/gma500/psb_intel_lvds.c
+++ b/drivers/gpu/drm/gma500/psb_intel_lvds.c
@@ -343,7 +343,7 @@
}
}
-int psb_intel_lvds_mode_valid(struct drm_connector *connector,
+enum drm_mode_status psb_intel_lvds_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct drm_psb_private *dev_priv = connector->dev->dev_private;
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 02908e3..279d1e0 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1684,10 +1684,38 @@
static u32 i9xx_hpd_irq_ack(struct drm_i915_private *dev_priv)
{
- u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT);
+ u32 hotplug_status = 0, hotplug_status_mask;
+ int i;
- if (hotplug_status)
+ if (IS_G4X(dev_priv) ||
+ IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+ hotplug_status_mask = HOTPLUG_INT_STATUS_G4X |
+ DP_AUX_CHANNEL_MASK_INT_STATUS_G4X;
+ else
+ hotplug_status_mask = HOTPLUG_INT_STATUS_I915;
+
+ /*
+ * We absolutely have to clear all the pending interrupt
+ * bits in PORT_HOTPLUG_STAT. Otherwise the ISR port
+ * interrupt bit won't have an edge, and the i965/g4x
+ * edge triggered IIR will not notice that an interrupt
+ * is still pending. We can't use PORT_HOTPLUG_EN to
+ * guarantee the edge as the act of toggling the enable
+ * bits can itself generate a new hotplug interrupt :(
+ */
+ for (i = 0; i < 10; i++) {
+ u32 tmp = I915_READ(PORT_HOTPLUG_STAT) & hotplug_status_mask;
+
+ if (tmp == 0)
+ return hotplug_status;
+
+ hotplug_status |= tmp;
I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status);
+ }
+
+ WARN_ONCE(1,
+ "PORT_HOTPLUG_STAT did not clear (0x%08x)\n",
+ I915_READ(PORT_HOTPLUG_STAT));
return hotplug_status;
}
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
index 9e251da..dbc94a1 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
@@ -5219,13 +5219,13 @@
mutex_lock(&display->display_lock);
+ if (display->modes)
+ goto exit;
+
rc = dsi_display_get_mode_count_no_lock(display, &total_mode_count);
if (rc)
goto error;
- /* free any previously probed modes */
- kfree(display->modes);
-
display->modes = kcalloc(total_mode_count, sizeof(*display->modes),
GFP_KERNEL);
if (!display->modes) {
@@ -5304,6 +5304,7 @@
}
}
+exit:
*out_modes = display->modes;
rc = 0;
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c b/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c
index 250314b..1278d59 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c
@@ -602,14 +602,20 @@
{
struct drm_display_mode *drm_mode;
struct dsi_display_mode dsi_mode;
+ struct dsi_display *dsi_display;
if (!connector || !display)
return;
- list_for_each_entry(drm_mode, &connector->modes, head) {
+ list_for_each_entry(drm_mode, &connector->modes, head) {
convert_to_dsi_mode(drm_mode, &dsi_mode);
dsi_display_put_mode(display, &dsi_mode);
}
+
+ /* free the display structure modes also */
+ dsi_display = display;
+ kfree(dsi_display->modes);
+ dsi_display->modes = NULL;
}
int dsi_connector_get_modes(struct drm_connector *connector,
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
index 2a70155..61c3fcb 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
@@ -1958,6 +1958,7 @@
{
int rc = 0;
const char *bl_type;
+ const char *data;
u32 val = 0;
bl_type = of_get_property(of_node,
@@ -1977,6 +1978,17 @@
panel->bl_config.type = DSI_BACKLIGHT_UNKNOWN;
}
+ data = of_get_property(of_node, "qcom,bl-update-flag", NULL);
+ if (!data) {
+ panel->bl_config.bl_update = BL_UPDATE_NONE;
+ } else if (!strcmp(data, "delay_until_first_frame")) {
+ panel->bl_config.bl_update = BL_UPDATE_DELAY_UNTIL_FIRST_FRAME;
+ } else {
+ pr_debug("[%s] No valid bl-update-flag: %s\n",
+ panel->name, data);
+ panel->bl_config.bl_update = BL_UPDATE_NONE;
+ }
+
panel->bl_config.bl_scale = MAX_BL_SCALE_LEVEL;
panel->bl_config.bl_scale_ad = MAX_AD_BL_SCALE_LEVEL;
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h
index f6a9c60..fef7d3f 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h
@@ -51,6 +51,11 @@
DSI_BACKLIGHT_MAX,
};
+enum bl_update_flag {
+ BL_UPDATE_DELAY_UNTIL_FIRST_FRAME,
+ BL_UPDATE_NONE,
+};
+
enum {
MODE_GPIO_NOT_VALID = 0,
MODE_SEL_DUAL_PORT,
@@ -85,6 +90,7 @@
struct dsi_backlight_config {
enum dsi_backlight_type type;
+ enum bl_update_flag bl_update;
u32 bl_min_level;
u32 bl_max_level;
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw_v3_0.c b/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw_v3_0.c
index 5015806..1d4f2ab 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw_v3_0.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw_v3_0.c
@@ -363,7 +363,8 @@
pr_debug("%s: polling for lanes to be in stop state, mask=0x%08x\n",
__func__, stop_state_mask);
rc = readl_poll_timeout(phy->base + DSIPHY_CMN_LANE_STATUS1, val,
- (val == stop_state_mask), sleep_us, timeout_us);
+ ((val & stop_state_mask) == stop_state_mask),
+ sleep_us, timeout_us);
if (rc) {
pr_err("%s: lanes not in stop state, LANE_STATUS=0x%08x\n",
__func__, val);
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 0f565d3..c564a09 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -201,62 +201,46 @@
return val;
}
-struct vblank_event {
- struct list_head node;
+struct vblank_work {
+ struct kthread_work work;
int crtc_id;
bool enable;
+ struct msm_drm_private *priv;
};
static void vblank_ctrl_worker(struct kthread_work *work)
{
- struct msm_vblank_ctrl *vbl_ctrl = container_of(work,
- struct msm_vblank_ctrl, work);
- struct msm_drm_private *priv = container_of(vbl_ctrl,
- struct msm_drm_private, vblank_ctrl);
+ struct vblank_work *cur_work = container_of(work,
+ struct vblank_work, work);
+ struct msm_drm_private *priv = cur_work->priv;
struct msm_kms *kms = priv->kms;
- struct vblank_event *vbl_ev, *tmp;
- unsigned long flags;
- LIST_HEAD(tmp_head);
- spin_lock_irqsave(&vbl_ctrl->lock, flags);
- list_for_each_entry_safe(vbl_ev, tmp, &vbl_ctrl->event_list, node) {
- list_del(&vbl_ev->node);
- list_add_tail(&vbl_ev->node, &tmp_head);
- }
- spin_unlock_irqrestore(&vbl_ctrl->lock, flags);
+ if (cur_work->enable)
+ kms->funcs->enable_vblank(kms, priv->crtcs[cur_work->crtc_id]);
+ else
+ kms->funcs->disable_vblank(kms, priv->crtcs[cur_work->crtc_id]);
- list_for_each_entry_safe(vbl_ev, tmp, &tmp_head, node) {
- if (vbl_ev->enable)
- kms->funcs->enable_vblank(kms,
- priv->crtcs[vbl_ev->crtc_id]);
- else
- kms->funcs->disable_vblank(kms,
- priv->crtcs[vbl_ev->crtc_id]);
-
- kfree(vbl_ev);
- }
+ kfree(cur_work);
}
static int vblank_ctrl_queue_work(struct msm_drm_private *priv,
int crtc_id, bool enable)
{
- struct msm_vblank_ctrl *vbl_ctrl = &priv->vblank_ctrl;
- struct vblank_event *vbl_ev;
- unsigned long flags;
+ struct vblank_work *cur_work;
- vbl_ev = kzalloc(sizeof(*vbl_ev), GFP_ATOMIC);
- if (!vbl_ev)
+ if (!priv || crtc_id >= priv->num_crtcs)
+ return -EINVAL;
+
+ cur_work = kzalloc(sizeof(*cur_work), GFP_ATOMIC);
+ if (!cur_work)
return -ENOMEM;
- vbl_ev->crtc_id = crtc_id;
- vbl_ev->enable = enable;
+ kthread_init_work(&cur_work->work, vblank_ctrl_worker);
+ cur_work->crtc_id = crtc_id;
+ cur_work->enable = enable;
+ cur_work->priv = priv;
- spin_lock_irqsave(&vbl_ctrl->lock, flags);
- list_add_tail(&vbl_ev->node, &vbl_ctrl->event_list);
- spin_unlock_irqrestore(&vbl_ctrl->lock, flags);
-
- kthread_queue_work(&priv->disp_thread[crtc_id].worker,
- &vbl_ctrl->work);
+ kthread_queue_work(&priv->disp_thread[crtc_id].worker, &cur_work->work);
return 0;
}
@@ -268,20 +252,8 @@
struct msm_drm_private *priv = ddev->dev_private;
struct msm_kms *kms = priv->kms;
struct msm_gpu *gpu = priv->gpu;
- struct msm_vblank_ctrl *vbl_ctrl = &priv->vblank_ctrl;
- struct vblank_event *vbl_ev, *tmp;
int i;
- /* We must cancel and cleanup any pending vblank enable/disable
- * work before drm_irq_uninstall() to avoid work re-enabling an
- * irq after uninstall has disabled it.
- */
- kthread_flush_work(&vbl_ctrl->work);
- list_for_each_entry_safe(vbl_ev, tmp, &vbl_ctrl->event_list, node) {
- list_del(&vbl_ev->node);
- kfree(vbl_ev);
- }
-
/* clean up display commit/event worker threads */
for (i = 0; i < priv->num_crtcs; i++) {
if (priv->disp_thread[i].thread) {
@@ -522,9 +494,6 @@
INIT_LIST_HEAD(&priv->client_event_list);
INIT_LIST_HEAD(&priv->inactive_list);
- INIT_LIST_HEAD(&priv->vblank_ctrl.event_list);
- kthread_init_work(&priv->vblank_ctrl.work, vblank_ctrl_worker);
- spin_lock_init(&priv->vblank_ctrl.lock);
ret = sde_power_resource_init(pdev, &priv->phandle);
if (ret) {
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 978aba2..83e100c 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -198,12 +198,6 @@
CONNECTOR_PROP_COUNT
};
-struct msm_vblank_ctrl {
- struct kthread_work work;
- struct list_head event_list;
- spinlock_t lock;
-};
-
#define MAX_H_TILES_PER_DISPLAY 2
/**
@@ -615,8 +609,6 @@
struct notifier_block vmap_notifier;
struct shrinker shrinker;
- struct msm_vblank_ctrl vblank_ctrl;
-
/* task holding struct_mutex.. currently only used in submit path
* to detect and reject faults from copy_from_user() for submit
* ioctl.
diff --git a/drivers/gpu/drm/msm/sde/sde_color_processing.c b/drivers/gpu/drm/msm/sde/sde_color_processing.c
index 8680449b..378847d 100644
--- a/drivers/gpu/drm/msm/sde/sde_color_processing.c
+++ b/drivers/gpu/drm/msm/sde/sde_color_processing.c
@@ -1862,24 +1862,29 @@
node = container_of(ad_irq, struct sde_crtc_irq_info, irq);
+ /* deregister AD irq */
if (!en) {
spin_lock_irqsave(&node->state_lock, flags);
if (node->state == IRQ_ENABLED) {
+ node->state = IRQ_DISABLING;
+ spin_unlock_irqrestore(&node->state_lock, flags);
ret = sde_core_irq_disable(kms, &irq_idx, 1);
- if (ret)
+ spin_lock_irqsave(&node->state_lock, flags);
+ if (ret) {
DRM_ERROR("disable irq %d error %d\n",
irq_idx, ret);
- else
- node->state = IRQ_NOINIT;
- } else {
- node->state = IRQ_NOINIT;
+ node->state = IRQ_ENABLED;
+ } else {
+ node->state = IRQ_DISABLED;
+ }
}
spin_unlock_irqrestore(&node->state_lock, flags);
+
sde_core_irq_unregister_callback(kms, irq_idx, ad_irq);
- ret = 0;
goto exit;
}
+ /* register AD irq */
ad_irq->arg = crtc;
ad_irq->func = sde_cp_ad_interrupt_cb;
ret = sde_core_irq_register_callback(kms, irq_idx, ad_irq);
@@ -1889,11 +1894,15 @@
}
spin_lock_irqsave(&node->state_lock, flags);
- if (node->state == IRQ_DISABLED || node->state == IRQ_NOINIT) {
+ if (node->state == IRQ_DISABLED) {
+ node->state = IRQ_ENABLING;
+ spin_unlock_irqrestore(&node->state_lock, flags);
ret = sde_core_irq_enable(kms, &irq_idx, 1);
+ spin_lock_irqsave(&node->state_lock, flags);
if (ret) {
DRM_ERROR("enable irq %d error %d\n", irq_idx, ret);
sde_core_irq_unregister_callback(kms, irq_idx, ad_irq);
+ node->state = IRQ_DISABLED;
} else {
node->state = IRQ_ENABLED;
}
@@ -2138,15 +2147,10 @@
irq_idx, ret);
node->state = IRQ_ENABLED;
} else {
- node->state = IRQ_NOINIT;
+ node->state = IRQ_DISABLED;
}
- spin_unlock_irqrestore(&node->state_lock, flags);
- } else if (node->state == IRQ_DISABLED) {
- node->state = IRQ_NOINIT;
- spin_unlock_irqrestore(&node->state_lock, flags);
- } else {
- spin_unlock_irqrestore(&node->state_lock, flags);
}
+ spin_unlock_irqrestore(&node->state_lock, flags);
sde_core_irq_unregister_callback(kms, irq_idx, hist_irq);
goto exit;
@@ -2162,12 +2166,16 @@
}
spin_lock_irqsave(&node->state_lock, flags);
- if (node->state == IRQ_DISABLED || node->state == IRQ_NOINIT) {
+ if (node->state == IRQ_DISABLED) {
+ node->state = IRQ_ENABLING;
+ spin_unlock_irqrestore(&node->state_lock, flags);
ret = sde_core_irq_enable(kms, &irq_idx, 1);
+ spin_lock_irqsave(&node->state_lock, flags);
if (ret) {
DRM_ERROR("enable irq %d error %d\n", irq_idx, ret);
sde_core_irq_unregister_callback(kms,
irq_idx, hist_irq);
+ node->state = IRQ_DISABLED;
} else {
node->state = IRQ_ENABLED;
}
diff --git a/drivers/gpu/drm/msm/sde/sde_connector.c b/drivers/gpu/drm/msm/sde/sde_connector.c
index 9d7d1e0..04f16ca 100644
--- a/drivers/gpu/drm/msm/sde/sde_connector.c
+++ b/drivers/gpu/drm/msm/sde/sde_connector.c
@@ -89,12 +89,19 @@
if (!bl_lvl && brightness)
bl_lvl = 1;
+ if (display->panel->bl_config.bl_update ==
+ BL_UPDATE_DELAY_UNTIL_FIRST_FRAME && !c_conn->allow_bl_update) {
+ c_conn->unset_bl_level = bl_lvl;
+ return 0;
+ }
+
if (c_conn->ops.set_backlight) {
event.type = DRM_EVENT_SYS_BACKLIGHT;
event.length = sizeof(u32);
msm_mode_object_event_notify(&c_conn->base.base,
c_conn->base.dev, &event, (u8 *)&brightness);
rc = c_conn->ops.set_backlight(c_conn->display, bl_lvl);
+ c_conn->unset_bl_level = 0;
}
return rc;
@@ -519,6 +526,15 @@
bl_config = &dsi_display->panel->bl_config;
+ if (dsi_display->panel->bl_config.bl_update ==
+ BL_UPDATE_DELAY_UNTIL_FIRST_FRAME && !c_conn->allow_bl_update) {
+ c_conn->unset_bl_level = bl_config->bl_level;
+ return 0;
+ }
+
+ if (c_conn->unset_bl_level)
+ bl_config->bl_level = c_conn->unset_bl_level;
+
if (c_conn->bl_scale > MAX_BL_SCALE_LEVEL)
bl_config->bl_scale = MAX_BL_SCALE_LEVEL;
else
@@ -533,6 +549,7 @@
bl_config->bl_scale, bl_config->bl_scale_ad,
bl_config->bl_level);
rc = c_conn->ops.set_backlight(dsi_display, bl_config->bl_level);
+ c_conn->unset_bl_level = 0;
return rc;
}
@@ -572,8 +589,11 @@
}
}
- /* Special handling for postproc properties */
- if (c_conn->bl_scale_dirty) {
+ /*
+ * Special handling for postproc properties and
+ * for updating backlight if any unset backlight level is present
+ */
+ if (c_conn->bl_scale_dirty || c_conn->unset_bl_level) {
_sde_connector_update_bl_scale(c_conn);
c_conn->bl_scale_dirty = false;
}
@@ -639,29 +659,44 @@
sde_connector_schedule_status_work(connector, false);
c_conn = to_sde_connector(connector);
- if (c_conn->panel_dead) {
+ if (c_conn->bl_device) {
c_conn->bl_device->props.power = FB_BLANK_POWERDOWN;
c_conn->bl_device->props.state |= BL_CORE_FBBLANK;
backlight_update_status(c_conn->bl_device);
}
+
+ c_conn->allow_bl_update = false;
}
void sde_connector_helper_bridge_enable(struct drm_connector *connector)
{
struct sde_connector *c_conn = NULL;
+ struct dsi_display *display;
if (!connector)
return;
c_conn = to_sde_connector(connector);
+ display = (struct dsi_display *) c_conn->display;
- /* Special handling for ESD recovery case */
- if (c_conn->panel_dead) {
+ /*
+ * Special handling for some panels which need atleast
+ * one frame to be transferred to GRAM before enabling backlight.
+ * So delay backlight update to these panels until the
+ * first frame commit is received from the HW.
+ */
+ if (display->panel->bl_config.bl_update ==
+ BL_UPDATE_DELAY_UNTIL_FIRST_FRAME)
+ sde_encoder_wait_for_event(c_conn->encoder,
+ MSM_ENC_TX_COMPLETE);
+ c_conn->allow_bl_update = true;
+
+ if (c_conn->bl_device) {
c_conn->bl_device->props.power = FB_BLANK_UNBLANK;
c_conn->bl_device->props.state &= ~BL_CORE_FBBLANK;
backlight_update_status(c_conn->bl_device);
- c_conn->panel_dead = false;
}
+ c_conn->panel_dead = false;
}
int sde_connector_clk_ctrl(struct drm_connector *connector, bool enable)
diff --git a/drivers/gpu/drm/msm/sde/sde_connector.h b/drivers/gpu/drm/msm/sde/sde_connector.h
index 51dc92d..0ae6a91 100644
--- a/drivers/gpu/drm/msm/sde/sde_connector.h
+++ b/drivers/gpu/drm/msm/sde/sde_connector.h
@@ -329,7 +329,9 @@
* @bl_scale_dirty: Flag to indicate PP BL scale value(s) is changed
* @bl_scale: BL scale value for ABA feature
* @bl_scale_ad: BL scale value for AD feature
- * last_cmd_tx_sts: status of the last command transfer
+ * @unset_bl_level: BL level that needs to be set later
+ * @allow_bl_update: Flag to indicate if BL update is allowed currently or not
+ * @last_cmd_tx_sts: status of the last command transfer
*/
struct sde_connector {
struct drm_connector base;
@@ -373,6 +375,8 @@
bool bl_scale_dirty;
u32 bl_scale;
u32 bl_scale_ad;
+ u32 unset_bl_level;
+ bool allow_bl_update;
bool last_cmd_tx_sts;
};
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c
index cb4e82d..73829da 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.c
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.c
@@ -6215,7 +6215,7 @@
INIT_LIST_HEAD(&node->list);
node->func = custom_events[i].func;
node->event = event;
- node->state = IRQ_NOINIT;
+ node->state = IRQ_DISABLED;
spin_lock_init(&node->state_lock);
break;
}
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.h b/drivers/gpu/drm/msm/sde/sde_crtc.h
index 709a51f..4700a6c 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.h
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.h
@@ -430,7 +430,7 @@
};
enum sde_crtc_irq_state {
- IRQ_NOINIT,
+ IRQ_ENABLING,
IRQ_ENABLED,
IRQ_DISABLING,
IRQ_DISABLED,
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.c b/drivers/gpu/drm/msm/sde/sde_encoder.c
index a1986db..0f5e127 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder.c
@@ -1454,7 +1454,7 @@
struct msm_mode_info mode_info;
int i, rc = 0;
- if (!sde_enc || !disp_info) {
+ if (!sde_enc || !sde_enc->cur_master || !disp_info) {
SDE_ERROR("invalid param sde_enc:%d or disp_info:%d\n",
sde_enc != NULL, disp_info != NULL);
return;
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c b/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c
index 74bf518..455e25c 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c
@@ -744,11 +744,10 @@
sde_encoder_phys_vid_setup_timing_engine(phys_enc);
/*
- * For single flush cases (dual-ctl or pp-split), skip setting the
- * flush bit for the slave intf, since both intfs use same ctl
- * and HW will only flush the master.
+ * For pp-split, skip setting the flush bit for the slave intf,
+ * since both intfs use same ctl and HW will only flush the master.
*/
- if (sde_encoder_phys_vid_needs_single_flush(phys_enc) &&
+ if (_sde_encoder_phys_is_ppsplit(phys_enc) &&
!sde_encoder_phys_vid_is_master(phys_enc))
goto skip_flush;
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index f416f5c..c5e1aa5 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -850,7 +850,7 @@
return ret;
}
-static int radeon_lvds_mode_valid(struct drm_connector *connector,
+static enum drm_mode_status radeon_lvds_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct drm_encoder *encoder = radeon_best_single_encoder(connector);
@@ -1010,7 +1010,7 @@
return ret;
}
-static int radeon_vga_mode_valid(struct drm_connector *connector,
+static enum drm_mode_status radeon_vga_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct drm_device *dev = connector->dev;
@@ -1154,7 +1154,7 @@
return 1;
}
-static int radeon_tv_mode_valid(struct drm_connector *connector,
+static enum drm_mode_status radeon_tv_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
if ((mode->hdisplay > 1024) || (mode->vdisplay > 768))
@@ -1496,7 +1496,7 @@
radeon_connector->use_digital = true;
}
-static int radeon_dvi_mode_valid(struct drm_connector *connector,
+static enum drm_mode_status radeon_dvi_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct drm_device *dev = connector->dev;
@@ -1798,7 +1798,7 @@
return ret;
}
-static int radeon_dp_mode_valid(struct drm_connector *connector,
+static enum drm_mode_status radeon_dp_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct drm_device *dev = connector->dev;
diff --git a/drivers/gpu/msm/a6xx_reg.h b/drivers/gpu/msm/a6xx_reg.h
index ef0d7f1..e3a664e 100644
--- a/drivers/gpu/msm/a6xx_reg.h
+++ b/drivers/gpu/msm/a6xx_reg.h
@@ -1070,5 +1070,16 @@
#define PDC_GPU_TCS3_CMD0_DATA 0x215DB
#define PDC_GPU_SEQ_MEM_0 0xA0000
+/* GPU CX_MISC registers */
+#define A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_0 0x1
+#define A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_1 0x2
+#define A6XX_LLC_NUM_GPU_SCIDS 5
+#define A6XX_GPU_LLC_SCID_NUM_BITS 5
+#define A6XX_GPU_LLC_SCID_MASK \
+ ((1 << (A6XX_LLC_NUM_GPU_SCIDS * A6XX_GPU_LLC_SCID_NUM_BITS)) - 1)
+#define A6XX_GPUHTW_LLC_SCID_SHIFT 25
+#define A6XX_GPUHTW_LLC_SCID_MASK \
+ (((1 << A6XX_GPU_LLC_SCID_NUM_BITS) - 1) << A6XX_GPUHTW_LLC_SCID_SHIFT)
+
#endif /* _A6XX_REG_H */
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 7c219fa..ea2240c 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -1262,6 +1262,22 @@
KGSL_DRV_WARN(device, "cx_dbgc ioremap failed\n");
}
+static void adreno_cx_misc_probe(struct kgsl_device *device)
+{
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+ struct resource *res;
+
+ res = platform_get_resource_byname(device->pdev, IORESOURCE_MEM,
+ "cx_misc");
+
+ if (res == NULL)
+ return;
+
+ adreno_dev->cx_misc_len = resource_size(res);
+ adreno_dev->cx_misc_virt = devm_ioremap(device->dev,
+ res->start, adreno_dev->cx_misc_len);
+}
+
static void adreno_efuse_read_soc_hw_rev(struct adreno_device *adreno_dev)
{
unsigned int val;
@@ -1382,6 +1398,9 @@
/* Probe for the optional CX_DBGC block */
adreno_cx_dbgc_probe(device);
+ /* Probe for the optional CX_MISC block */
+ adreno_cx_misc_probe(device);
+
/*
* qcom,iommu-secure-id is used to identify MMUs that can handle secure
* content but that is only part of the story - the GPU also has to be
@@ -1851,7 +1870,7 @@
status = kgsl_mmu_start(device);
if (status)
- goto error_pwr_off;
+ goto error_boot_oob_clear;
_set_secvid(device);
@@ -2072,6 +2091,12 @@
error_mmu_off:
kgsl_mmu_stop(&device->mmu);
+error_boot_oob_clear:
+ if (gpudev->oob_clear &&
+ ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_HFI_USE_REG))
+ gpudev->oob_clear(adreno_dev,
+ OOB_BOOT_SLUMBER_CLEAR_MASK);
+
error_pwr_off:
/* set the state back to original state */
kgsl_pwrctrl_change_state(device, state);
@@ -3296,6 +3321,54 @@
__raw_writel(value, adreno_dev->cx_dbgc_virt + cx_dbgc_offset);
}
+void adreno_cx_misc_regread(struct adreno_device *adreno_dev,
+ unsigned int offsetwords, unsigned int *value)
+{
+ unsigned int cx_misc_offset;
+
+ cx_misc_offset = (offsetwords << 2);
+ if (!adreno_dev->cx_misc_virt ||
+ (cx_misc_offset >= adreno_dev->cx_misc_len))
+ return;
+
+ *value = __raw_readl(adreno_dev->cx_misc_virt + cx_misc_offset);
+
+ /*
+ * ensure this read finishes before the next one.
+ * i.e. act like normal readl()
+ */
+ rmb();
+}
+
+void adreno_cx_misc_regwrite(struct adreno_device *adreno_dev,
+ unsigned int offsetwords, unsigned int value)
+{
+ unsigned int cx_misc_offset;
+
+ cx_misc_offset = (offsetwords << 2);
+ if (!adreno_dev->cx_misc_virt ||
+ (cx_misc_offset >= adreno_dev->cx_misc_len))
+ return;
+
+ /*
+ * ensure previous writes post before this one,
+ * i.e. act like normal writel()
+ */
+ wmb();
+ __raw_writel(value, adreno_dev->cx_misc_virt + cx_misc_offset);
+}
+
+void adreno_cx_misc_regrmw(struct adreno_device *adreno_dev,
+ unsigned int offsetwords,
+ unsigned int mask, unsigned int bits)
+{
+ unsigned int val = 0;
+
+ adreno_cx_misc_regread(adreno_dev, offsetwords, &val);
+ val &= ~mask;
+ adreno_cx_misc_regwrite(adreno_dev, offsetwords, val | bits);
+}
+
/**
* adreno_waittimestamp - sleep while waiting for the specified timestamp
* @device - pointer to a KGSL device structure
@@ -3772,7 +3845,6 @@
.device_private_create = adreno_device_private_create,
.device_private_destroy = adreno_device_private_destroy,
/* Optional functions */
- .snapshot_gmu = adreno_snapshot_gmu,
.drawctxt_create = adreno_drawctxt_create,
.drawctxt_detach = adreno_drawctxt_detach,
.drawctxt_destroy = adreno_drawctxt_destroy,
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 555856a..3b5dd88d 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -429,6 +429,8 @@
* @chipid: Chip ID specific to the GPU
* @gmem_base: Base physical address of GMEM
* @gmem_size: GMEM size
+ * @cx_misc_len: Length of the CX MISC register block
+ * @cx_misc_virt: Pointer where the CX MISC block is mapped
* @gpucore: Pointer to the adreno_gpu_core structure
* @pfp_fw: Buffer which holds the pfp ucode
* @pfp_fw_size: Size of pfp ucode buffer
@@ -509,6 +511,8 @@
unsigned long cx_dbgc_base;
unsigned int cx_dbgc_len;
void __iomem *cx_dbgc_virt;
+ unsigned int cx_misc_len;
+ void __iomem *cx_misc_virt;
const struct adreno_gpu_core *gpucore;
struct adreno_firmware fw[2];
size_t gpmu_cmds_size;
@@ -941,7 +945,6 @@
/* GPU specific function hooks */
void (*irq_trace)(struct adreno_device *, unsigned int status);
void (*snapshot)(struct adreno_device *, struct kgsl_snapshot *);
- void (*snapshot_gmu)(struct adreno_device *, struct kgsl_snapshot *);
void (*platform_setup)(struct adreno_device *);
void (*init)(struct adreno_device *);
void (*remove)(struct adreno_device *);
@@ -1123,9 +1126,6 @@
struct kgsl_snapshot *snapshot,
struct kgsl_context *context);
-void adreno_snapshot_gmu(struct kgsl_device *device,
- struct kgsl_snapshot *snapshot);
-
int adreno_reset(struct kgsl_device *device, int fault);
void adreno_fault_skipcmd_detached(struct adreno_device *adreno_dev,
@@ -1170,6 +1170,14 @@
unsigned int offsetwords, unsigned int *value);
void adreno_cx_dbgc_regwrite(struct kgsl_device *device,
unsigned int offsetwords, unsigned int value);
+void adreno_cx_misc_regread(struct adreno_device *adreno_dev,
+ unsigned int offsetwords, unsigned int *value);
+void adreno_cx_misc_regwrite(struct adreno_device *adreno_dev,
+ unsigned int offsetwords, unsigned int value);
+void adreno_cx_misc_regrmw(struct adreno_device *adreno_dev,
+ unsigned int offsetwords,
+ unsigned int mask, unsigned int bits);
+
#define ADRENO_TARGET(_name, _id) \
static inline int adreno_is_##_name(struct adreno_device *adreno_dev) \
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index 4f98912..e1f32e8 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -156,6 +156,12 @@
unsigned int speed_bin[3];
struct kgsl_device *device = &adreno_dev->dev;
+ if (of_get_property(device->pdev->dev.of_node,
+ "qcom,gpu-speed-bin-vectors", NULL)) {
+ adreno_efuse_speed_bin_array(adreno_dev);
+ return;
+ }
+
if (of_property_read_u32_array(device->pdev->dev.of_node,
"qcom,gpu-speed-bin", speed_bin, 3))
return;
diff --git a/drivers/gpu/msm/adreno_a6xx.c b/drivers/gpu/msm/adreno_a6xx.c
index 517b813..b74d48c 100644
--- a/drivers/gpu/msm/adreno_a6xx.c
+++ b/drivers/gpu/msm/adreno_a6xx.c
@@ -32,17 +32,6 @@
#define MIN_HBB 13
-#define A6XX_LLC_NUM_GPU_SCIDS 5
-#define A6XX_GPU_LLC_SCID_NUM_BITS 5
-#define A6XX_GPU_LLC_SCID_MASK \
- ((1 << (A6XX_LLC_NUM_GPU_SCIDS * A6XX_GPU_LLC_SCID_NUM_BITS)) - 1)
-#define A6XX_GPUHTW_LLC_SCID_SHIFT 25
-#define A6XX_GPUHTW_LLC_SCID_MASK \
- (((1 << A6XX_GPU_LLC_SCID_NUM_BITS) - 1) << A6XX_GPUHTW_LLC_SCID_SHIFT)
-
-#define A6XX_GPU_CX_REG_BASE 0x509E000
-#define A6XX_GPU_CX_REG_SIZE 0x1000
-
#define GPU_LIMIT_THRESHOLD_ENABLE BIT(31)
static int _load_gmu_firmware(struct kgsl_device *device);
@@ -2522,24 +2511,6 @@
}
}
-/* GPU System Cache control registers */
-#define A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_0 0x4
-#define A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_1 0x8
-
-static inline void _reg_rmw(void __iomem *regaddr,
- unsigned int mask, unsigned int bits)
-{
- unsigned int val = 0;
-
- val = __raw_readl(regaddr);
- /* Make sure the above read completes before we proceed */
- rmb();
- val &= ~mask;
- __raw_writel(val | bits, regaddr);
- /* Make sure the above write posts before we proceed*/
- wmb();
-}
-
/*
* a6xx_llc_configure_gpu_scid() - Program the sub-cache ID for all GPU blocks
* @adreno_dev: The adreno device pointer
@@ -2549,17 +2520,15 @@
uint32_t gpu_scid;
uint32_t gpu_cntl1_val = 0;
int i;
- void __iomem *gpu_cx_reg;
gpu_scid = adreno_llc_get_scid(adreno_dev->gpu_llc_slice);
for (i = 0; i < A6XX_LLC_NUM_GPU_SCIDS; i++)
gpu_cntl1_val = (gpu_cntl1_val << A6XX_GPU_LLC_SCID_NUM_BITS)
| gpu_scid;
- gpu_cx_reg = ioremap(A6XX_GPU_CX_REG_BASE, A6XX_GPU_CX_REG_SIZE);
- _reg_rmw(gpu_cx_reg + A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_1,
+ adreno_cx_misc_regrmw(adreno_dev,
+ A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_1,
A6XX_GPU_LLC_SCID_MASK, gpu_cntl1_val);
- iounmap(gpu_cx_reg);
}
/*
@@ -2569,15 +2538,13 @@
static void a6xx_llc_configure_gpuhtw_scid(struct adreno_device *adreno_dev)
{
uint32_t gpuhtw_scid;
- void __iomem *gpu_cx_reg;
gpuhtw_scid = adreno_llc_get_scid(adreno_dev->gpuhtw_llc_slice);
- gpu_cx_reg = ioremap(A6XX_GPU_CX_REG_BASE, A6XX_GPU_CX_REG_SIZE);
- _reg_rmw(gpu_cx_reg + A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_1,
+ adreno_cx_misc_regrmw(adreno_dev,
+ A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_1,
A6XX_GPUHTW_LLC_SCID_MASK,
gpuhtw_scid << A6XX_GPUHTW_LLC_SCID_SHIFT);
- iounmap(gpu_cx_reg);
}
/*
@@ -2586,19 +2553,14 @@
*/
static void a6xx_llc_enable_overrides(struct adreno_device *adreno_dev)
{
- void __iomem *gpu_cx_reg;
-
/*
* 0x3: readnoallocoverrideen=0
* read-no-alloc=0 - Allocate lines on read miss
* writenoallocoverrideen=1
* write-no-alloc=1 - Do not allocates lines on write miss
*/
- gpu_cx_reg = ioremap(A6XX_GPU_CX_REG_BASE, A6XX_GPU_CX_REG_SIZE);
- __raw_writel(0x3, gpu_cx_reg + A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_0);
- /* Make sure the above write posts before we proceed*/
- wmb();
- iounmap(gpu_cx_reg);
+ adreno_cx_misc_regwrite(adreno_dev,
+ A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_0, 0x3);
}
static const char *fault_block[8] = {
@@ -3909,7 +3871,6 @@
.reg_offsets = &a6xx_reg_offsets,
.start = a6xx_start,
.snapshot = a6xx_snapshot,
- .snapshot_gmu = a6xx_snapshot_gmu,
.irq = &a6xx_irq,
.snapshot_data = &a6xx_snapshot_data,
.irq_trace = trace_kgsl_a5xx_irq_status,
diff --git a/drivers/gpu/msm/adreno_a6xx.h b/drivers/gpu/msm/adreno_a6xx.h
index bf1111c..3267213 100644
--- a/drivers/gpu/msm/adreno_a6xx.h
+++ b/drivers/gpu/msm/adreno_a6xx.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -129,8 +129,5 @@
void a6xx_snapshot(struct adreno_device *adreno_dev,
struct kgsl_snapshot *snapshot);
-void a6xx_snapshot_gmu(struct adreno_device *adreno_dev,
- struct kgsl_snapshot *snapshot);
-
void a6xx_crashdump_init(struct adreno_device *adreno_dev);
#endif
diff --git a/drivers/gpu/msm/adreno_a6xx_snapshot.c b/drivers/gpu/msm/adreno_a6xx_snapshot.c
index 7376a38..d3f13d4 100644
--- a/drivers/gpu/msm/adreno_a6xx_snapshot.c
+++ b/drivers/gpu/msm/adreno_a6xx_snapshot.c
@@ -1456,7 +1456,7 @@
* This is where all of the A6XX GMU specific bits and pieces are grabbed
* into the snapshot memory
*/
-void a6xx_snapshot_gmu(struct adreno_device *adreno_dev,
+static void a6xx_snapshot_gmu(struct adreno_device *adreno_dev,
struct kgsl_snapshot *snapshot)
{
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
@@ -1479,8 +1479,6 @@
a6xx_gmu_gx_registers,
ARRAY_SIZE(a6xx_gmu_gx_registers) / 2);
}
-
- a6xx_snapshot_debugbus(device, snapshot);
}
/* a6xx_snapshot_sqe() - Dump SQE data in snapshot */
@@ -1571,6 +1569,15 @@
/* GMU TCM data dumped through AHB */
a6xx_snapshot_gmu(adreno_dev, snapshot);
+ /*
+ * Dump debugbus data here to capture it for both
+ * GMU and GPU snapshot. Debugbus data can be accessed
+ * even if the gx headswitch or sptprac is off. If gx
+ * headswitch is off, data for gx blocks will show as
+ * 0x5c00bd00.
+ */
+ a6xx_snapshot_debugbus(device, snapshot);
+
sptprac_on = gpudev->sptprac_is_on(adreno_dev);
/* Return if the GX is off */
diff --git a/drivers/gpu/msm/adreno_dispatch.c b/drivers/gpu/msm/adreno_dispatch.c
index a634d98..e7e0aae 100644
--- a/drivers/gpu/msm/adreno_dispatch.c
+++ b/drivers/gpu/msm/adreno_dispatch.c
@@ -1716,8 +1716,9 @@
ib2base, ib2sz, drawctxt->rb->id);
pr_fault(device, drawobj,
- "gpu fault ctx %d ts %d status %8.8X rb %4.4x/%4.4x ib1 %16.16llX/%4.4x ib2 %16.16llX/%4.4x\n",
- drawobj->context->id, drawobj->timestamp, status,
+ "gpu fault ctx %d ctx_type %s ts %d status %8.8X rb %4.4x/%4.4x ib1 %16.16llX/%4.4x ib2 %16.16llX/%4.4x\n",
+ drawobj->context->id, get_api_type_str(drawctxt->type),
+ drawobj->timestamp, status,
rptr, wptr, ib1base, ib1sz, ib2base, ib2sz);
if (rb != NULL)
diff --git a/drivers/gpu/msm/adreno_drawctxt.h b/drivers/gpu/msm/adreno_drawctxt.h
index eef506f..466d1e2 100644
--- a/drivers/gpu/msm/adreno_drawctxt.h
+++ b/drivers/gpu/msm/adreno_drawctxt.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2002,2007-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -139,4 +139,16 @@
void adreno_drawctxt_dump(struct kgsl_device *device,
struct kgsl_context *context);
+static struct adreno_context_type ctxt_type_table[] = {KGSL_CONTEXT_TYPES};
+
+static inline const char *get_api_type_str(unsigned int type)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ctxt_type_table) - 1; i++) {
+ if (ctxt_type_table[i].type == type)
+ return ctxt_type_table[i].str;
+ }
+ return "UNKNOWN";
+}
#endif /* __ADRENO_DRAWCTXT_H */
diff --git a/drivers/gpu/msm/adreno_profile.c b/drivers/gpu/msm/adreno_profile.c
index 2985f24..3b85129 100644
--- a/drivers/gpu/msm/adreno_profile.c
+++ b/drivers/gpu/msm/adreno_profile.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -77,19 +77,6 @@
#define SIZE_PIPE_ENTRY(cnt) (50 + (cnt) * 62)
#define SIZE_LOG_ENTRY(cnt) (6 + (cnt) * 5)
-static struct adreno_context_type ctxt_type_table[] = {KGSL_CONTEXT_TYPES};
-
-static const char *get_api_type_str(unsigned int type)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(ctxt_type_table) - 1; i++) {
- if (ctxt_type_table[i].type == type)
- return ctxt_type_table[i].str;
- }
- return "UNKNOWN";
-}
-
static inline uint _ib_start(struct adreno_device *adreno_dev,
unsigned int *cmds)
{
diff --git a/drivers/gpu/msm/adreno_snapshot.c b/drivers/gpu/msm/adreno_snapshot.c
index 2293919..b93ee9c 100644
--- a/drivers/gpu/msm/adreno_snapshot.c
+++ b/drivers/gpu/msm/adreno_snapshot.c
@@ -946,24 +946,6 @@
}
-/* adreno_snapshot_gmu - Snapshot the Adreno GMU state
- * @device - KGSL device to snapshot
- * @snapshot - Pointer to the snapshot instance
- * This is a hook function called by kgsl_snapshot to snapshot the
- * Adreno specific information for the GMU snapshot. In turn, this function
- * calls the GMU specific snapshot function to get core specific information.
- */
-void adreno_snapshot_gmu(struct kgsl_device *device,
- struct kgsl_snapshot *snapshot)
-{
- struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
- struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
-
- /* Add GMU specific sections */
- if (gpudev->snapshot_gmu)
- gpudev->snapshot_gmu(adreno_dev, snapshot);
-}
-
/*
* adreno_snapshot_cp_roq - Dump CP merciu data in snapshot
* @device: Device being snapshotted
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index 4a98a24..6ae38a3 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -97,7 +97,8 @@
{ KGSL_CONTEXT_TYPE_GL, "GL" }, \
{ KGSL_CONTEXT_TYPE_CL, "CL" }, \
{ KGSL_CONTEXT_TYPE_C2D, "C2D" }, \
- { KGSL_CONTEXT_TYPE_RS, "RS" }
+ { KGSL_CONTEXT_TYPE_RS, "RS" }, \
+ { KGSL_CONTEXT_TYPE_VK, "VK" }
#define KGSL_CONTEXT_ID(_context) \
((_context != NULL) ? (_context)->id : KGSL_MEMSTORE_GLOBAL)
@@ -152,8 +153,6 @@
unsigned int (*gpuid)(struct kgsl_device *device, unsigned int *chipid);
void (*snapshot)(struct kgsl_device *device,
struct kgsl_snapshot *snapshot, struct kgsl_context *context);
- void (*snapshot_gmu)(struct kgsl_device *device,
- struct kgsl_snapshot *snapshot);
irqreturn_t (*irq_handler)(struct kgsl_device *device);
int (*drain)(struct kgsl_device *device);
struct kgsl_device_private * (*device_private_create)(void);
diff --git a/drivers/gpu/msm/kgsl_gmu.c b/drivers/gpu/msm/kgsl_gmu.c
index 6e31964..a49dc3b 100644
--- a/drivers/gpu/msm/kgsl_gmu.c
+++ b/drivers/gpu/msm/kgsl_gmu.c
@@ -450,7 +450,7 @@
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
int perf_idx = INVALID_DCVS_IDX, bw_idx = INVALID_DCVS_IDX;
- int ret;
+ int ret = 0;
if (gpu_pwrlevel < gmu->num_gpupwrlevels - 1)
perf_idx = gmu->num_gpupwrlevels - gpu_pwrlevel - 1;
@@ -462,23 +462,22 @@
(bw_idx == INVALID_DCVS_IDX))
return -EINVAL;
- if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_HFI_USE_REG)) {
+ if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_HFI_USE_REG))
ret = gpudev->rpmh_gpu_pwrctrl(adreno_dev,
GMU_DCVS_NOHFI, perf_idx, bw_idx);
+ else if (test_bit(GMU_HFI_ON, &gmu->flags))
+ ret = hfi_send_dcvs_vote(gmu, perf_idx, bw_idx, ACK_NONBLOCK);
- if (ret) {
- dev_err_ratelimited(&gmu->pdev->dev,
- "Failed to set GPU perf idx %d, bw idx %d\n",
- perf_idx, bw_idx);
+ if (ret) {
+ dev_err_ratelimited(&gmu->pdev->dev,
+ "Failed to set GPU perf idx %d, bw idx %d\n",
+ perf_idx, bw_idx);
- adreno_set_gpu_fault(adreno_dev, ADRENO_GMU_FAULT);
- adreno_dispatcher_schedule(device);
- }
-
- return ret;
+ adreno_set_gpu_fault(adreno_dev, ADRENO_GMU_FAULT);
+ adreno_dispatcher_schedule(device);
}
- return hfi_send_dcvs_vote(gmu, perf_idx, bw_idx, ACK_NONBLOCK);
+ return ret;
}
struct rpmh_arc_vals {
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index 3539cda..4cf6250 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -836,11 +836,21 @@
no_page_fault_log = kgsl_mmu_log_fault_addr(mmu, ptbase, addr);
if (!no_page_fault_log && __ratelimit(&_rs)) {
+ const char *api_str;
+
+ if (context != NULL) {
+ struct adreno_context *drawctxt =
+ ADRENO_CONTEXT(context);
+
+ api_str = get_api_type_str(drawctxt->type);
+ } else
+ api_str = "UNKNOWN";
+
KGSL_MEM_CRIT(ctx->kgsldev,
"GPU PAGE FAULT: addr = %lX pid= %d\n", addr, ptname);
KGSL_MEM_CRIT(ctx->kgsldev,
- "context=%s TTBR0=0x%llx CIDR=0x%x (%s %s fault)\n",
- ctx->name, ptbase, contextidr,
+ "context=%s ctx_type=%s TTBR0=0x%llx CIDR=0x%x (%s %s fault)\n",
+ ctx->name, api_str, ptbase, contextidr,
write ? "write" : "read", fault_type);
if (gpudev->iommu_fault_block) {
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 2a149ac..b2679b3 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -2760,6 +2760,12 @@
status = gmu_start(device);
break;
case KGSL_STATE_INIT:
+ /* if GMU already in FAULT */
+ if (kgsl_gmu_isenabled(device) &&
+ test_bit(GMU_FAULT, &gmu->flags)) {
+ status = -EINVAL;
+ break;
+ }
status = kgsl_pwrctrl_enable(device);
break;
/* The following 3 cases shouldn't occur, but don't panic. */
diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c
index 0ed17d8..009cbbb 100644
--- a/drivers/gpu/msm/kgsl_snapshot.c
+++ b/drivers/gpu/msm/kgsl_snapshot.c
@@ -704,22 +704,20 @@
snapshot->size += sizeof(*header);
/* Build the Linux specific header */
- /* We either want to only dump GMU, or we want to dump GPU and GMU */
- if (gmu_fault) {
- /* Dump only the GMU */
+ if (gmu_fault)
kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_OS,
- snapshot, snapshot_os_no_ctxt, NULL);
-
- if (device->ftbl->snapshot_gmu)
- device->ftbl->snapshot_gmu(device, snapshot);
- } else {
- /* Dump GPU and GMU */
+ snapshot, snapshot_os_no_ctxt, NULL);
+ else
kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_OS,
- snapshot, snapshot_os, NULL);
+ snapshot, snapshot_os, NULL);
- if (device->ftbl->snapshot)
- device->ftbl->snapshot(device, snapshot, context);
- }
+ /*
+ * Trigger both GPU and GMU snapshot. GPU specific code
+ * will take care of whether to dumps full state or only
+ * GMU state based on current GPU power state.
+ */
+ if (device->ftbl->snapshot)
+ device->ftbl->snapshot(device, snapshot, context);
/*
* The timestamp is the seconds since boot so it is easier to match to
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 8eed456..9deed4f 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -966,6 +966,13 @@
Say Y here if you have a Alps touchpads over i2c-hid or usbhid
and want support for its special functionalities.
+config HID_QVR
+ tristate "QVR support"
+ depends on HID
+ ---help---
+ Say 'Y' or 'M' if you want to connect an external device to
+ stream IMU data for QVR support.
+
endmenu
endif # HID
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 86b2b57..95c3235 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -78,6 +78,7 @@
obj-$(CONFIG_HID_PLANTRONICS) += hid-plantronics.o
obj-$(CONFIG_HID_PRIMAX) += hid-primax.o
+obj-$(CONFIG_HID_QVR) += hid-qvr.o hid-trace.o
obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \
hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \
hid-roccat-koneplus.o hid-roccat-konepure.o hid-roccat-kovaplus.o \
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index aea6267..350f2ba 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -2018,6 +2018,9 @@
{ HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) },
{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) },
+#if IS_ENABLED(CONFIG_HID_QVR)
+ { HID_USB_DEVICE(USB_VENDOR_ID_QVR5, USB_DEVICE_ID_QVR5) },
+#endif
{ HID_USB_DEVICE(USB_VENDOR_ID_RISO_KAGAKU, USB_DEVICE_ID_RI_KA_WEBMAIL) },
#if IS_ENABLED(CONFIG_HID_ROCCAT)
{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 9347b37..ad9f230 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -549,6 +549,9 @@
#define USB_VENDOR_ID_IRTOUCHSYSTEMS 0x6615
#define USB_DEVICE_ID_IRTOUCH_INFRARED_USB 0x0070
+#define USB_VENDOR_ID_INNOMEDIA 0x1292
+#define USB_DEVICE_ID_INNEX_GENESIS_ATARI 0x4745
+
#define USB_VENDOR_ID_ITE 0x048d
#define USB_DEVICE_ID_ITE_LENOVO_YOGA 0x8386
#define USB_DEVICE_ID_ITE_LENOVO_YOGA2 0x8350
@@ -1125,4 +1128,7 @@
#define USB_VENDOR_ID_UGTIZER 0x2179
#define USB_DEVICE_ID_UGTIZER_TABLET_GP0610 0x0053
+#define USB_VENDOR_ID_QVR5 0x045e
+#define USB_DEVICE_ID_QVR5 0x0659
+
#endif
diff --git a/drivers/hid/hid-plantronics.c b/drivers/hid/hid-plantronics.c
index febb21e..584b10d 100644
--- a/drivers/hid/hid-plantronics.c
+++ b/drivers/hid/hid-plantronics.c
@@ -2,7 +2,7 @@
* Plantronics USB HID Driver
*
* Copyright (c) 2014 JD Cole <jd.cole@plantronics.com>
- * Copyright (c) 2015 Terry Junge <terry.junge@plantronics.com>
+ * Copyright (c) 2015-2018 Terry Junge <terry.junge@plantronics.com>
*/
/*
@@ -48,6 +48,10 @@
unsigned short mapped_key;
unsigned long plt_type = (unsigned long)hid_get_drvdata(hdev);
+ /* special case for PTT products */
+ if (field->application == HID_GD_JOYSTICK)
+ goto defaulted;
+
/* handle volume up/down mapping */
/* non-standard types or multi-HID interfaces - plt_type is PID */
if (!(plt_type & HID_USAGE_PAGE)) {
diff --git a/drivers/hid/hid-qvr.c b/drivers/hid/hid-qvr.c
new file mode 100644
index 0000000..766b15d
--- /dev/null
+++ b/drivers/hid/hid-qvr.c
@@ -0,0 +1,418 @@
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kobject.h>
+#include <linux/string.h>
+#include <linux/sysfs.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/msm_ion.h>
+#include <linux/usb.h>
+#include <linux/slab.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/input.h>
+#include <linux/hiddev.h>
+#include <linux/hid-debug.h>
+#include <linux/hidraw.h>
+#include <linux/device.h>
+#include <linux/of_gpio.h>
+#include <linux/of_irq.h>
+#include <linux/gpio.h>
+#include <linux/timekeeping.h>
+#include <linux/ion.h>
+#include "../soc/qcom/smp2p_private.h"
+#include "hid-ids.h"
+#include "hid-qvr.h"
+#include "hid-trace.h"
+
+static struct ion_handle *handle;
+static struct ion_client *client;
+static void *vaddr;
+static size_t vsize;
+static uint64_t ts_base;
+static uint64_t ts_offset;
+static int msg_size = 368;
+
+struct gpio_info {
+ int gpio_base_id;
+ int irq_base_id;
+};
+
+
+/* GPIO Inbound/Outbound callback info */
+struct gpio_inout {
+ struct gpio_info in;
+ struct gpio_info out;
+};
+
+static struct gpio_inout gpio_info[SMP2P_NUM_PROCS];
+static struct gpio_info *in_gpio_info_ptr;
+static struct gpio_info *out_gpio_info_ptr;
+
+
+static struct hid_driver qvr_external_sensor_driver;
+static int fd;
+
+
+struct ion_handle {
+ struct kref ref;
+ unsigned int user_ref_count;
+ struct ion_client *client;
+ struct ion_buffer *buffer;
+ struct rb_node node;
+ unsigned int kmap_cnt;
+ int id;
+};
+
+struct qvr_buf_index {
+ int most_recent_index;
+ uint8_t padding[60];
+};
+
+struct qvr_sensor_t {
+ uint64_t gts;
+ uint64_t ats;
+ uint64_t mts;
+ s32 gx;
+ s32 gy;
+ s32 gz;
+ s32 ax;
+ s32 ay;
+ s32 az;
+ s32 mx;
+ s32 my;
+ s32 mz;
+ uint8_t padding[4];
+};
+
+
+int qvr_send_package_wrap(u8 *message, int msize, struct hid_device *hid)
+{
+ struct qvr_sensor_t *sensor_buf;
+ struct qvr_sensor_t *data;
+ static int buf_index;
+ struct external_imu_format imuData = { 0 };
+ struct qvr_buf_index *index_buf;
+
+ /*
+ * Actual message size is 369 bytes
+ * to make it 8 byte aligned we created a structure of size 368 bytes.
+ * Ignoring the first byte 'report id' (which is always 1)
+ *
+ */
+ memcpy((void *)&imuData, (void *)message + 1, msg_size);
+
+ if (!ts_base)
+ ts_base = ktime_to_ns(ktime_get_boottime());
+ if (!ts_offset)
+ ts_offset = imuData.gts0;
+ index_buf = (struct qvr_buf_index *)
+ ((uintptr_t)vaddr + (vsize / 2) + (8 * sizeof(*sensor_buf)));
+ sensor_buf = (struct qvr_sensor_t *)((uintptr_t)vaddr + (vsize / 2));
+
+ data = (struct qvr_sensor_t *)&(sensor_buf[buf_index]);
+ if (ts_offset > imuData.gts0)
+ data->ats = ts_base + ((ts_offset - imuData.gts0) * 100);
+ else
+ data->ats = ts_base + ((imuData.gts0 - ts_offset) * 100);
+ if (imuData.mts0 == 0)
+ data->mts = 0;
+ else
+ data->mts = data->ats;
+ data->gts = data->ats;
+ data->ax = -imuData.ax0;
+ data->ay = imuData.ay0;
+ data->az = -imuData.az0;
+ data->gx = -imuData.gx0;
+ data->gy = imuData.gy0;
+ data->gz = -imuData.gz0;
+ data->mx = -imuData.mx0;
+ data->my = imuData.my0;
+ data->mz = -imuData.mz0;
+
+ trace_qvr_recv_sensor("gyro", data->gts, data->gx, data->gy, data->gz);
+ trace_qvr_recv_sensor("accel", data->ats, data->ax, data->ay, data->az);
+
+ pr_debug("%s: gts= %llu, gx= %d, gy=%d, gz=%d", __func__,
+ data->gts, data->gx, data->gy, data->gz);
+ pr_debug("%s: ats= %llu, ax= %d, ay=%d, az=%d", __func__,
+ data->ats, data->ax, data->ay, data->az);
+ pr_debug("%s: mts= %llu, mx= %d, my=%d, mz=%d", __func__,
+ data->mts, data->mx, data->my, data->mz);
+
+ index_buf->most_recent_index = buf_index;
+ buf_index = (buf_index == (8 - 1)) ? 0 : buf_index + 1;
+ return 0;
+}
+
+static int register_smp2p(char *node_name, struct gpio_info *gpio_info_ptr)
+{
+ struct device_node *node = NULL;
+ int cnt = 0;
+ int id = 0;
+
+ node = of_find_compatible_node(NULL, NULL, node_name);
+ if (node) {
+ cnt = of_gpio_count(node);
+ if (cnt && gpio_info_ptr) {
+ id = of_get_gpio(node, 0);
+ if (id == -EPROBE_DEFER)
+ return id;
+ gpio_info_ptr->gpio_base_id = id;
+ gpio_info_ptr->irq_base_id = gpio_to_irq(id);
+ return 0;
+ }
+ }
+ return -EINVAL;
+}
+
+
+
+static int kernel_map_gyro_buffer(int fd)
+{
+ handle = ion_import_dma_buf_fd(client, fd);
+ if (IS_ERR(handle)) {
+ pr_err("%s: ion_import_dma_buf_fd failed\n", __func__);
+ return -EINVAL;
+ }
+
+ if (ion_handle_get_size(client, handle, &vsize)) {
+ pr_err("%s: Could not dma buf %d size\n", __func__, fd);
+ return -EINVAL;
+ }
+
+ vaddr = ion_map_kernel(client, handle);
+ if (IS_ERR_OR_NULL(vaddr)) {
+ ion_free(client, handle);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+
+static void kernel_unmap_gyro_buffer(void)
+{
+ if (!IS_ERR_OR_NULL(vaddr)) {
+ ion_unmap_kernel(client, handle);
+ ion_free(client, handle);
+ vaddr = NULL;
+ }
+}
+
+static ssize_t fd_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ return snprintf(buf, 16, "%d\n", fd);
+}
+
+static ssize_t fd_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ ret = kstrtoint(buf, 10, &fd);
+ if (ret < 0)
+ return ret;
+ if (fd == -1)
+ kernel_unmap_gyro_buffer();
+ else
+ kernel_map_gyro_buffer(fd);
+ ts_base = 0;
+ ts_offset = 0;
+
+ return count;
+}
+
+static ssize_t ts_base_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ return snprintf(buf, 16, "%lld\n", ts_base);
+}
+
+static ssize_t ts_base_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ return 0;
+}
+
+static ssize_t ts_offset_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ return snprintf(buf, 16, "%lld\n", ts_offset * 100);
+}
+
+static ssize_t ts_offset_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ return 0;
+}
+
+static struct kobj_attribute fd_attribute = __ATTR(fd, 0664,
+ fd_show,
+ fd_store);
+static struct kobj_attribute ts_base_attribute = __ATTR(ts_base, 0664,
+ ts_base_show,
+ ts_base_store);
+static struct kobj_attribute ts_offset_attribute = __ATTR(ts_offset, 0664,
+ ts_offset_show,
+ ts_offset_store);
+
+static struct attribute *attrs[] = {
+ &fd_attribute.attr,
+ &ts_base_attribute.attr,
+ &ts_offset_attribute.attr,
+ NULL,
+};
+
+static struct attribute_group attr_group = {
+ .attrs = attrs,
+};
+
+static struct kobject *qvr_external_sensor_kobj;
+
+static int qvr_external_sensor_probe(struct hid_device *hdev,
+ const struct hid_device_id *id)
+{
+ int ret;
+ char *in_node_name = "qcom,smp2pgpio_client_qvrexternal_5_in";
+ char *out_node_name = "qcom,smp2pgpio_client_qvrexternal_5_out";
+ __u8 hid_buf[255] = { 0 };
+ size_t hid_count = 64;
+
+ ret = register_smp2p(in_node_name, in_gpio_info_ptr);
+ if (ret) {
+ pr_err("%s: register_smp2p failed", __func__);
+ goto err_free;
+ }
+ ret = register_smp2p(out_node_name, out_gpio_info_ptr);
+ if (ret) {
+ pr_err("%s: register_smp2p failed", __func__);
+ goto err_free;
+ }
+ ret = hid_open_report(hdev);
+ if (ret) {
+ pr_err("%s: hid_open_report failed", __func__);
+ goto err_free;
+ }
+ ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+ if (ret) {
+ pr_err("%s: hid_hw_start failed", __func__);
+ goto err_free;
+ }
+ if (hdev->vendor == USB_VENDOR_ID_QVR5) {
+ hid_buf[0] = 2;
+ hid_buf[1] = 7;
+ ret = hid_hw_raw_request(hdev, hid_buf[0],
+ hid_buf,
+ hid_count,
+ HID_FEATURE_REPORT,
+ HID_REQ_SET_REPORT);
+ }
+ return 0;
+err_free:
+ return ret;
+
+}
+
+static int qvr_external_sensor_raw_event(struct hid_device *hid,
+ struct hid_report *report,
+ u8 *data, int size)
+{
+ int val;
+ int ret = -1;
+
+ if ((hid->vendor == USB_VENDOR_ID_QVR5) && (vaddr != NULL)) {
+ ret = qvr_send_package_wrap(data/*hid_value*/, size, hid);
+ if (ret != 0) {
+ pr_err("%s: qvr_send_package_wrap failed", __func__);
+ return ret;
+ }
+ val = 1 ^ gpio_get_value(out_gpio_info_ptr->gpio_base_id + 0);
+ gpio_set_value(out_gpio_info_ptr->gpio_base_id + 0, val);
+ ret = -1;
+ }
+ return ret;
+}
+
+static void qvr_external_sensor_device_remove(struct hid_device *hdev)
+{
+ hid_hw_stop(hdev);
+}
+
+static struct hid_device_id qvr_external_sensor_table[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_QVR5, USB_DEVICE_ID_QVR5) },
+ { }
+};
+MODULE_DEVICE_TABLE(hid, qvr_external_sensor_table);
+
+static struct hid_driver qvr_external_sensor_driver = {
+ .name = "qvr_external_sensor",
+ .id_table = qvr_external_sensor_table,
+ .probe = qvr_external_sensor_probe,
+ .raw_event = qvr_external_sensor_raw_event,
+ .remove = qvr_external_sensor_device_remove,
+};
+
+module_hid_driver(qvr_external_sensor_driver);
+
+static int __init qvr_external_sensor_init(void)
+{
+ const char *device_name = "aoe";
+ int ret = 0;
+
+ in_gpio_info_ptr = &gpio_info[SMP2P_CDSP_PROC].in;
+ in_gpio_info_ptr->gpio_base_id = -1;
+ out_gpio_info_ptr = &gpio_info[SMP2P_CDSP_PROC].out;
+ out_gpio_info_ptr->gpio_base_id = -1;
+
+
+ qvr_external_sensor_kobj =
+ kobject_create_and_add("qvr_external_sensor", kernel_kobj);
+
+ if (!qvr_external_sensor_kobj) {
+ pr_err("%s: kobject_create_and_add() fail\n", __func__);
+ return -ENOMEM;
+ }
+
+ ret = sysfs_create_group(qvr_external_sensor_kobj, &attr_group);
+ if (ret) {
+ pr_err("%s: can't register sysfs\n", __func__);
+ return -ENOMEM;
+ }
+
+ client = msm_ion_client_create(device_name);
+ if (client == NULL) {
+ pr_err("msm_ion_client_create failed in %s", __func__);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static void __exit qvr_external_sensor_exit(void)
+{
+ kobject_put(qvr_external_sensor_kobj);
+}
+
+module_init(qvr_external_sensor_init);
+module_exit(qvr_external_sensor_exit);
+MODULE_LICENSE("GPL v2");
+
diff --git a/drivers/hid/hid-qvr.h b/drivers/hid/hid-qvr.h
new file mode 100644
index 0000000..3507d07
--- /dev/null
+++ b/drivers/hid/hid-qvr.h
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef HID_QVR_H_FILE
+#define HID_QVR_H_FILE
+
+#define USB_VENDOR_ID_QVR5 0x045e
+#define USB_DEVICE_ID_QVR5 0x0659
+#define QVR_EXTERNAL_SENSOR_REPORT_ID 0x1
+
+struct external_imu_format {
+ s16 temp0;
+ s16 temp1;
+ s16 temp2;
+ s16 temp3;
+ u64 gts0;
+ u64 gts1;
+ u64 gts2;
+ u64 gts3;
+ s16 gx0;
+ s16 gx1;
+ s16 gx2;
+ s16 gx3;
+ s16 gx4;
+ s16 gx5;
+ s16 gx6;
+ s16 gx7;
+ s16 gx8;
+ s16 gx9;
+ s16 gx10;
+ s16 gx11;
+ s16 gx12;
+ s16 gx13;
+ s16 gx14;
+ s16 gx15;
+ s16 gx16;
+ s16 gx17;
+ s16 gx18;
+ s16 gx19;
+ s16 gx20;
+ s16 gx21;
+ s16 gx22;
+ s16 gx23;
+ s16 gx24;
+ s16 gx25;
+ s16 gx26;
+ s16 gx27;
+ s16 gx28;
+ s16 gx29;
+ s16 gx30;
+ s16 gx31;
+ s16 gy0;
+ s16 gy1;
+ s16 gy2;
+ s16 gy3;
+ s16 gy4;
+ s16 gy5;
+ s16 gy6;
+ s16 gy7;
+ s16 gy8;
+ s16 gy9;
+ s16 gy10;
+ s16 gy11;
+ s16 gy12;
+ s16 gy13;
+ s16 gy14;
+ s16 gy15;
+ s16 gy16;
+ s16 gy17;
+ s16 gy18;
+ s16 gy19;
+ s16 gy20;
+ s16 gy21;
+ s16 gy22;
+ s16 gy23;
+ s16 gy24;
+ s16 gy25;
+ s16 gy26;
+ s16 gy27;
+ s16 gy28;
+ s16 gy29;
+ s16 gy30;
+ s16 gy31;
+ s16 gz0;
+ s16 gz1;
+ s16 gz2;
+ s16 gz3;
+ s16 gz4;
+ s16 gz5;
+ s16 gz6;
+ s16 gz7;
+ s16 gz8;
+ s16 gz9;
+ s16 gz10;
+ s16 gz11;
+ s16 gz12;
+ s16 gz13;
+ s16 gz14;
+ s16 gz15;
+ s16 gz16;
+ s16 gz17;
+ s16 gz18;
+ s16 gz19;
+ s16 gz20;
+ s16 gz21;
+ s16 gz22;
+ s16 gz23;
+ s16 gz24;
+ s16 gz25;
+ s16 gz26;
+ s16 gz27;
+ s16 gz28;
+ s16 gz29;
+ s16 gz30;
+ s16 gz31;
+ u64 ats0;
+ u64 ats1;
+ u64 ats2;
+ u64 ats3;
+ s32 ax0;
+ s32 ax1;
+ s32 ax2;
+ s32 ax3;
+ s32 ay0;
+ s32 ay1;
+ s32 ay2;
+ s32 ay3;
+ s32 az0;
+ s32 az1;
+ s32 az2;
+ s32 az3;
+ u64 mts0;
+ u64 mts1;
+ u64 mts2;
+ u64 mts3;
+ s16 mx0;
+ s16 mx1;
+ s16 mx2;
+ s16 mx3;
+ s16 my0;
+ s16 my1;
+ s16 my2;
+ s16 my3;
+ s16 mz0;
+ s16 mz1;
+ s16 mz2;
+ s16 mz3;//368 bytes
+};
+
+int qvr_send_package_wrap(u8 *message, int msize, struct hid_device *hid);
+void qvr_clear_def_parmeter(void);
+void qvr_init(struct hid_device *hdev);
+int qvr_input_init(void);
+void qvr_input_remove(void);
+
+#endif
diff --git a/drivers/hid/hid-trace.c b/drivers/hid/hid-trace.c
new file mode 100644
index 0000000..b3afcb7
--- /dev/null
+++ b/drivers/hid/hid-trace.c
@@ -0,0 +1,17 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+
+/* Instantiate tracepoints */
+#define CREATE_TRACE_POINTS
+#include "hid-trace.h"
diff --git a/drivers/hid/hid-trace.h b/drivers/hid/hid-trace.h
new file mode 100644
index 0000000..4415055
--- /dev/null
+++ b/drivers/hid/hid-trace.h
@@ -0,0 +1,56 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#if !defined(_HID_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _HID_TRACE_H
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM hid
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE hid-trace
+
+#include <linux/tracepoint.h>
+
+TRACE_EVENT(qvr_recv_sensor,
+ TP_PROTO(char *sensor, uint64_t ts, s32 x, s32 y, s32 z),
+ TP_ARGS(sensor, ts, x, y, z),
+ TP_STRUCT__entry(
+ __field(char *, sensor)
+ __field(uint64_t, ts)
+ __field(int, x)
+ __field(int, y)
+ __field(int, z)
+ ),
+ TP_fast_assign(
+ __entry->sensor = sensor;
+ __entry->ts = ts;
+ __entry->x = x;
+ __entry->y = y;
+ __entry->z = z;
+ ),
+ TP_printk(
+ "%s - ts=%llu x=%d y=%d z=%d",
+ __entry->sensor,
+ __entry->ts,
+ __entry->x,
+ __entry->y,
+ __entry->z
+ )
+ );
+
+#endif /* _HID_TRACE_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
index 00bce00..ce2b800 100644
--- a/drivers/hid/i2c-hid/i2c-hid.c
+++ b/drivers/hid/i2c-hid/i2c-hid.c
@@ -1101,6 +1101,14 @@
pm_runtime_enable(&client->dev);
device_enable_async_suspend(&client->dev);
+ /* Make sure there is something at this address */
+ ret = i2c_smbus_read_byte(client);
+ if (ret < 0) {
+ dev_dbg(&client->dev, "nothing at this address: %d\n", ret);
+ ret = -ENXIO;
+ goto err_pm;
+ }
+
ret = i2c_hid_fetch_hid_descriptor(ihid);
if (ret < 0)
goto err_pm;
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 1916f80..a57654a 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -170,6 +170,8 @@
{ USB_VENDOR_ID_MULTIPLE_1781, USB_DEVICE_ID_RAPHNET_4NES4SNES_OLD, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_2NES2SNES, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_4NES4SNES, HID_QUIRK_MULTI_INPUT },
+ { USB_VENDOR_ID_QVR5, USB_DEVICE_ID_QVR5, HID_QUIRK_HIDINPUT_FORCE },
+ { USB_VENDOR_ID_INNOMEDIA, USB_DEVICE_ID_INNEX_GENESIS_ATARI, HID_QUIRK_MULTI_INPUT },
{ 0, 0 }
};
diff --git a/drivers/hwmon/qpnp-adc-common.c b/drivers/hwmon/qpnp-adc-common.c
index b900f76..c5653fe 100644
--- a/drivers/hwmon/qpnp-adc-common.c
+++ b/drivers/hwmon/qpnp-adc-common.c
@@ -1263,6 +1263,19 @@
qpnp_adc_map_voltage_temp(adcmap_batt_therm_qrd,
ARRAY_SIZE(adcmap_batt_therm_qrd),
batt_thm_voltage, &adc_chan_result->physical);
+ } else {
+
+ qpnp_adc_scale_with_calib_param(adc_code,
+ adc_properties, chan_properties, &batt_thm_voltage);
+
+ adc_chan_result->measurement = batt_thm_voltage;
+
+ return qpnp_adc_map_voltage_temp(
+ adcmap_batt_therm_qrd,
+ ARRAY_SIZE(adcmap_batt_therm_qrd),
+ batt_thm_voltage,
+ &adc_chan_result->physical);
+
}
return 0;
}
@@ -2152,6 +2165,64 @@
}
EXPORT_SYMBOL(qpnp_adc_qrd_skut1_btm_scaler);
+int32_t qpnp_adc_qrd_215_btm_scaler(struct qpnp_vadc_chip *chip,
+ struct qpnp_adc_tm_btm_param *param,
+ uint32_t *low_threshold, uint32_t *high_threshold)
+{
+ struct qpnp_vadc_linear_graph btm_param;
+ int64_t low_output = 0, high_output = 0;
+ int rc = 0;
+
+ if (param->adc_tm_hc) {
+ pr_debug("Update scaling for VADC_TM_HC\n");
+ return -EINVAL;
+ }
+
+ qpnp_get_vadc_gain_and_offset(chip, &btm_param, CALIB_RATIOMETRIC);
+
+ pr_debug("warm_temp:%d and cool_temp:%d\n", param->high_temp,
+ param->low_temp);
+ rc = qpnp_adc_map_voltage_temp(
+ adcmap_batt_therm_qrd,
+ ARRAY_SIZE(adcmap_batt_therm_qrd),
+ (param->low_temp),
+ &low_output);
+ if (rc) {
+ pr_debug("low_temp mapping failed with %d\n", rc);
+ return rc;
+ }
+
+ pr_debug("low_output:%lld\n", low_output);
+ low_output *= btm_param.dy;
+ low_output = div64_s64(low_output, btm_param.adc_vref);
+ low_output += btm_param.adc_gnd;
+
+ rc = qpnp_adc_map_voltage_temp(
+ adcmap_batt_therm_qrd,
+ ARRAY_SIZE(adcmap_batt_therm_qrd),
+ (param->high_temp),
+ &high_output);
+ if (rc) {
+ pr_debug("high temp mapping failed with %d\n", rc);
+ return rc;
+ }
+
+ pr_debug("high_output:%lld\n", high_output);
+ high_output *= btm_param.dy;
+ high_output = div64_s64(high_output, btm_param.adc_vref);
+ high_output += btm_param.adc_gnd;
+
+ /* btm low temperature correspondes to high voltage threshold */
+ *low_threshold = high_output;
+ /* btm high temperature correspondes to low voltage threshold */
+ *high_threshold = low_output;
+
+ pr_debug("high_volt:%d, low_volt:%d\n", *high_threshold,
+ *low_threshold);
+ return 0;
+}
+EXPORT_SYMBOL(qpnp_adc_qrd_215_btm_scaler);
+
int32_t qpnp_adc_smb_btm_rscaler(struct qpnp_vadc_chip *chip,
struct qpnp_adc_tm_btm_param *param,
uint32_t *low_threshold, uint32_t *high_threshold)
diff --git a/drivers/hwtracing/coresight/coresight-cti.c b/drivers/hwtracing/coresight/coresight-cti.c
index 621e08f..066072a 100644
--- a/drivers/hwtracing/coresight/coresight-cti.c
+++ b/drivers/hwtracing/coresight/coresight-cti.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -166,14 +166,19 @@
out:
spin_lock_irqsave(&drvdata->spinlock, flag);
drvdata->l2_off = true;
- drvdata->state->cticontrol = cti_readl(drvdata, CTICONTROL);
- drvdata->state->ctiappset = cti_readl(drvdata, CTIAPPSET);
- drvdata->state->ctigate = cti_readl(drvdata, CTIGATE);
- for (trig = 0; trig < CTI_MAX_TRIGGERS; trig++) {
- drvdata->state->ctiinen[trig] =
- cti_readl(drvdata, CTIINEN(trig));
- drvdata->state->ctiouten[trig] =
- cti_readl(drvdata, CTIOUTEN(trig));
+ if (drvdata->refcnt) {
+ drvdata->state->cticontrol =
+ cti_readl(drvdata, CTICONTROL);
+ drvdata->state->ctiappset =
+ cti_readl(drvdata, CTIAPPSET);
+ drvdata->state->ctigate =
+ cti_readl(drvdata, CTIGATE);
+ for (trig = 0; trig < CTI_MAX_TRIGGERS; trig++) {
+ drvdata->state->ctiinen[trig] =
+ cti_readl(drvdata, CTIINEN(trig));
+ drvdata->state->ctiouten[trig] =
+ cti_readl(drvdata, CTIOUTEN(trig));
+ }
}
spin_unlock_irqrestore(&drvdata->spinlock, flag);
}
@@ -209,17 +214,22 @@
continue;
out:
spin_lock_irqsave(&drvdata->spinlock, flag);
- CTI_UNLOCK(drvdata);
- cti_writel(drvdata, drvdata->state->ctiappset, CTIAPPSET);
- cti_writel(drvdata, drvdata->state->ctigate, CTIGATE);
- for (trig = 0; trig < CTI_MAX_TRIGGERS; trig++) {
- cti_writel(drvdata, drvdata->state->ctiinen[trig],
- CTIINEN(trig));
- cti_writel(drvdata, drvdata->state->ctiouten[trig],
- CTIOUTEN(trig));
+ if (drvdata->refcnt) {
+ CTI_UNLOCK(drvdata);
+ cti_writel(drvdata, drvdata->state->ctiappset,
+ CTIAPPSET);
+ cti_writel(drvdata, drvdata->state->ctigate,
+ CTIGATE);
+ for (trig = 0; trig < CTI_MAX_TRIGGERS; trig++) {
+ cti_writel(drvdata,
+ drvdata->state->ctiinen[trig], CTIINEN(trig));
+ cti_writel(drvdata,
+ drvdata->state->ctiouten[trig], CTIOUTEN(trig));
+ }
+ cti_writel(drvdata, drvdata->state->cticontrol,
+ CTICONTROL);
+ CTI_LOCK(drvdata);
}
- cti_writel(drvdata, drvdata->state->cticontrol, CTICONTROL);
- CTI_LOCK(drvdata);
drvdata->l2_off = false;
spin_unlock_irqrestore(&drvdata->spinlock, flag);
}
@@ -380,8 +390,10 @@
*/
if (drvdata->refcnt == 0) {
ret = pm_runtime_get_sync(drvdata->dev);
- if (ret)
+ if (ret < 0) {
+ pm_runtime_put(drvdata->dev);
goto err1;
+ }
}
spin_lock_irqsave(&drvdata->spinlock, flag);
@@ -464,8 +476,10 @@
*/
if (drvdata->refcnt == 0) {
ret = pm_runtime_get_sync(drvdata->dev);
- if (ret)
+ if (ret < 0) {
+ pm_runtime_put(drvdata->dev);
goto err1;
+ }
}
spin_lock_irqsave(&drvdata->spinlock, flag);
@@ -1472,8 +1486,10 @@
}
if (drvdata->cti_save && !drvdata->cti_hwclk) {
ret = pm_runtime_get_sync(drvdata->dev);
- if (ret)
+ if (ret < 0) {
+ pm_runtime_put(drvdata->dev);
return ret;
+ }
}
mutex_lock(&cti_lock);
diff --git a/drivers/i2c/busses/i2c-msm-v2.c b/drivers/i2c/busses/i2c-msm-v2.c
index 99e7c97..631169b 100644
--- a/drivers/i2c/busses/i2c-msm-v2.c
+++ b/drivers/i2c/busses/i2c-msm-v2.c
@@ -2321,6 +2321,12 @@
struct i2c_msm_ctrl *ctrl = i2c_get_adapdata(adap);
struct i2c_msm_xfer *xfer = &ctrl->xfer;
+ if (num < 1) {
+ dev_err(ctrl->dev,
+ "error on number of msgs(%d) received\n", num);
+ return -EINVAL;
+ }
+
if (IS_ERR_OR_NULL(msgs)) {
dev_err(ctrl->dev, " error on msgs Accessing invalid pointer location\n");
return PTR_ERR(msgs);
diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
index abe1798..ec37ff0 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -121,6 +121,7 @@
struct msm_gpi_dma_async_tx_cb_param tx_cb;
struct msm_gpi_dma_async_tx_cb_param rx_cb;
enum i2c_se_mode se_mode;
+ bool autosuspend_disable;
};
struct geni_i2c_err_log {
@@ -641,6 +642,7 @@
{
struct geni_i2c_dev *gi2c = i2c_get_adapdata(adap);
int i, ret = 0, timeout = 0;
+ int ref = 0;
gi2c->err = 0;
gi2c->cur = &msgs[0];
@@ -654,6 +656,12 @@
pm_runtime_set_suspended(gi2c->dev);
return ret;
}
+ ref = atomic_read(&gi2c->dev->power.usage_count);
+ if (ref <= 0) {
+ GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev,
+ "resume usage count mismatch:%d\n", ref);
+ }
+
if (gi2c->se_mode == GSI_ONLY) {
ret = geni_i2c_gsi_xfer(adap, msgs, num);
goto geni_i2c_txn_ret;
@@ -759,8 +767,17 @@
if (ret == 0)
ret = num;
- pm_runtime_mark_last_busy(gi2c->dev);
- pm_runtime_put_autosuspend(gi2c->dev);
+ if (gi2c->autosuspend_disable) {
+ pm_runtime_put_sync(gi2c->dev);
+ ref = atomic_read(&gi2c->dev->power.usage_count);
+ if (ref < 0)
+ GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev,
+ "suspend usage count mismatch:%d\n", ref);
+ } else {
+ pm_runtime_mark_last_busy(gi2c->dev);
+ pm_runtime_put_autosuspend(gi2c->dev);
+ }
+
gi2c->cur = NULL;
gi2c->err = 0;
dev_dbg(gi2c->dev, "i2c txn ret:%d\n", ret);
@@ -874,6 +891,9 @@
gi2c->i2c_rsc.clk_freq_out = KHz(400);
}
+ gi2c->autosuspend_disable = of_property_read_bool(pdev->dev.of_node,
+ "qcom,disable-autosuspend");
+
gi2c->irq = platform_get_irq(pdev, 0);
if (gi2c->irq < 0) {
dev_err(gi2c->dev, "IRQ error for i2c-geni\n");
@@ -905,8 +925,11 @@
strlcpy(gi2c->adap.name, "Geni-I2C", sizeof(gi2c->adap.name));
pm_runtime_set_suspended(gi2c->dev);
- pm_runtime_set_autosuspend_delay(gi2c->dev, I2C_AUTO_SUSPEND_DELAY);
- pm_runtime_use_autosuspend(gi2c->dev);
+ if (!gi2c->autosuspend_disable) {
+ pm_runtime_set_autosuspend_delay(gi2c->dev,
+ I2C_AUTO_SUSPEND_DELAY);
+ pm_runtime_use_autosuspend(gi2c->dev);
+ }
pm_runtime_enable(gi2c->dev);
i2c_add_adapter(&gi2c->adap);
@@ -994,6 +1017,9 @@
"i2c fifo/se-dma mode. fifo depth:%d\n",
gi2c_tx_depth);
}
+ if (gi2c->autosuspend_disable)
+ GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev,
+ "i2c in autosuspend disable mode\n");
}
if (gi2c->se_mode == FIFO_SE_DMA)
enable_irq(gi2c->irq);
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 4af9bba..586e557 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -547,6 +547,14 @@
{
u32 cnfg;
+ /*
+ * NACK interrupt is generated before the I2C controller generates
+ * the STOP condition on the bus. So wait for 2 clock periods
+ * before disabling the controller so that the STOP condition has
+ * been delivered properly.
+ */
+ udelay(DIV_ROUND_UP(2 * 1000000, i2c_dev->bus_clk_rate));
+
cnfg = i2c_readl(i2c_dev, I2C_CNFG);
if (cnfg & I2C_CNFG_PACKET_MODE_EN)
i2c_writel(i2c_dev, cnfg & ~I2C_CNFG_PACKET_MODE_EN, I2C_CNFG);
@@ -708,15 +716,6 @@
if (likely(i2c_dev->msg_err == I2C_ERR_NONE))
return 0;
- /*
- * NACK interrupt is generated before the I2C controller generates
- * the STOP condition on the bus. So wait for 2 clock periods
- * before resetting the controller so that the STOP condition has
- * been delivered properly.
- */
- if (i2c_dev->msg_err == I2C_ERR_NO_ACK)
- udelay(DIV_ROUND_UP(2 * 1000000, i2c_dev->bus_clk_rate));
-
tegra_i2c_init(i2c_dev);
if (i2c_dev->msg_err == I2C_ERR_NO_ACK) {
if (msg->flags & I2C_M_IGNORE_NAK)
diff --git a/drivers/iio/imu/inv_mpu/Kconfig b/drivers/iio/imu/inv_mpu/Kconfig
new file mode 100644
index 0000000..7505454
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu/Kconfig
@@ -0,0 +1,63 @@
+#
+# inv-mpu-iio driver for Invensense MPU devices
+#
+
+config INV_MPU_IIO
+ tristate
+ select IIO_BUFFER
+ select IIO_KFIFO_BUF
+ select IIO_TRIGGER
+ select CRC32
+
+choice
+ prompt "Chip name"
+ depends on INV_MPU_IIO
+
+config INV_MPU_IIO_ICM20648
+ bool "ICM20648/ICM20948"
+ help
+ Select this if you are using a ICM20648/ICM20948 chip.
+
+config INV_MPU_IIO_ICM20608D
+ bool "ICM20608D/ICM20609/ICM20689"
+ help
+ Select this if you are using a ICM20608D/ICM20609/ICM20689 chip.
+
+config INV_MPU_IIO_ICM20602
+ bool "ICM20602"
+ help
+ Select this if you are using a ICM20602 chip.
+
+config INV_MPU_IIO_ICM20690
+ bool "ICM20690"
+ help
+ Select this if you are using a ICM20690 chip.
+
+config INV_MPU_IIO_IAM20680
+ bool "IAM20680"
+ help
+ Select this if you are using a IAM20680 chip.
+
+endchoice
+
+config INV_MPU_IIO_I2C
+ tristate "Invensense ICM20xxx devices (I2C)"
+ depends on I2C && !INV_MPU6050_IIO
+ select INV_MPU_IIO
+ default n
+ help
+ This driver supports Invensense ICM20xxx devices over I2C.
+ This driver can be built as a module. The module will be called
+ inv-mpu-iio-i2c.
+
+config INV_MPU_IIO_SPI
+ tristate "Invensense ICM20xxx devices (SPI)"
+ depends on SPI_MASTER && !INV_MPU6050_IIO
+ select INV_MPU_IIO
+ default n
+ help
+ This driver supports Invensense ICM20xxx devices over SPI.
+ This driver can be built as a module. The module will be called
+ inv-mpu-iio-spi.
+
+source "drivers/iio/imu/inv_mpu/inv_test/Kconfig"
diff --git a/drivers/iio/imu/inv_mpu/Makefile b/drivers/iio/imu/inv_mpu/Makefile
new file mode 100644
index 0000000..dfc4c25
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu/Makefile
@@ -0,0 +1,61 @@
+#
+# Makefile for Invensense inv-mpu-iio device.
+#
+
+obj-$(CONFIG_INV_MPU_IIO) += inv-mpu-iio.o
+
+inv-mpu-iio-objs += inv_mpu_common.o
+inv-mpu-iio-objs += inv_mpu_ring.o
+inv-mpu-iio-objs += inv_mpu_timestamp.o
+inv-mpu-iio-objs += inv_mpu_dts.o
+
+# chip support
+ifeq ($(CONFIG_INV_MPU_IIO_ICM20648), y)
+inv-mpu-iio-objs += icm20648/inv_mpu_init.o
+inv-mpu-iio-objs += icm20648/inv_mpu_core.o
+inv-mpu-iio-objs += icm20648/inv_mpu_parsing.o
+inv-mpu-iio-objs += icm20648/inv_mpu_setup.o
+inv-mpu-iio-objs += icm20648/inv_mpu_dmp_fifo.o
+inv-mpu-iio-objs += icm20648/inv_slave_compass.o
+inv-mpu-iio-objs += icm20648/inv_slave_pressure.o
+inv-mpu-iio-objs += icm20648/inv_slave_als.o
+inv-mpu-iio-objs += icm20648/inv_mpu_load_dmp.o
+inv-mpu-iio-objs += icm20648/inv_mpu_selftest.o
+inv-mpu-iio-objs += dmp_support/inv_mpu_misc.o
+else ifeq ($(CONFIG_INV_MPU_IIO_ICM20690), y)
+inv-mpu-iio-objs += icm20690/inv_mpu_init_20690.o
+inv-mpu-iio-objs += icm20690/inv_mpu_core_20690.o
+inv-mpu-iio-objs += icm20690/inv_mpu_parsing_20690.o
+inv-mpu-iio-objs += icm20690/inv_mpu_setup_20690.o
+inv-mpu-iio-objs += icm20690/inv_mpu_selftest_20690.o
+inv-mpu-iio-objs += icm20690/inv_slave_compass.o
+else ifeq ($(CONFIG_INV_MPU_IIO_ICM20602), y)
+inv-mpu-iio-objs += icm20602/inv_mpu_init_20602.o
+inv-mpu-iio-objs += icm20602/inv_mpu_core_20602.o
+inv-mpu-iio-objs += icm20602/inv_mpu_parsing_20602.o
+inv-mpu-iio-objs += icm20602/inv_mpu_setup_20602.o
+inv-mpu-iio-objs += icm20602/inv_mpu_selftest_20602.o
+else ifeq ($(CONFIG_INV_MPU_IIO_ICM20608D), y)
+inv-mpu-iio-objs += icm20608d/inv_mpu_init_20608.o
+inv-mpu-iio-objs += icm20608d/inv_mpu_core_20608.o
+inv-mpu-iio-objs += icm20608d/inv_mpu_parsing_20608.o
+inv-mpu-iio-objs += icm20608d/inv_mpu_setup_20608D.o
+inv-mpu-iio-objs += icm20608d/inv_mpu_dmp_fifo.o
+inv-mpu-iio-objs += icm20608d/inv_mpu_load_dmp.o
+inv-mpu-iio-objs += icm20608d/inv_mpu_selftest_20608.o
+inv-mpu-iio-objs += dmp_support/inv_mpu_misc.o
+else ifeq ($(CONFIG_INV_MPU_IIO_IAM20680), y)
+inv-mpu-iio-objs += iam20680/inv_mpu_init_20680.o
+inv-mpu-iio-objs += iam20680/inv_mpu_core_20680.o
+inv-mpu-iio-objs += iam20680/inv_mpu_parsing_20680.o
+inv-mpu-iio-objs += iam20680/inv_mpu_setup_20680.o
+inv-mpu-iio-objs += iam20680/inv_mpu_selftest_20680.o
+endif
+
+# Bus support
+obj-$(CONFIG_INV_MPU_IIO_I2C) += inv-mpu-iio-i2c.o
+inv-mpu-iio-i2c-objs := inv_mpu_i2c.o
+obj-$(CONFIG_INV_MPU_IIO_SPI) += inv-mpu-iio-spi.o
+inv-mpu-iio-spi-objs := inv_mpu_spi.o
+
+obj-y += inv_test/
diff --git a/drivers/iio/imu/inv_mpu/README b/drivers/iio/imu/inv_mpu/README
new file mode 100644
index 0000000..47ff502
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu/README
@@ -0,0 +1,117 @@
+Kernel driver inv-mpu-iio
+Author: InvenSense, Inc.
+
+
+Table of Contents
+=================
+- Description
+- Integrating the Driver in the Linux Kernel
+- Dts file
+- Communicating with the Driver in Userspace
+
+
+Description
+===========
+This document describes how to install the Invensense device driver into a
+Linux kernel. The supported chips are listed in Kconfig and user selects an
+appropriate one from .e.g. menuconfig.
+
+
+Integrating the Driver in the Linux Kernel
+==========================================
+Please add the files as follows (kernel 3.10):
+- Copy mpu.h to <kernel_root>/include/linux/iio/imu/
+- Copy inv_mpu folder under <kernel_root>/drivers/iio/imu/
+
+In order to see the driver in menuconfig when building the kernel, please
+make modifications as shown below:
+
+ add "source "drivers/iio/imu/inv_mpu/Kconfig""
+ in <kernel_root>/drivers/iio/imu/Kconfig
+
+ add "obj-y += inv_mpu/"
+ in <kernel_root>/drivers/iio/imu/Makefile
+
+
+
+Dts file
+========
+In order to recognize the Invensense device on the I2C/SPI bus, dts(or dtsi)
+file must be modified.
+
+Example)
+ICM20648 + AK09911/BMP280/APDS9930 on AUX I2C
+
+ i2c@f9968000 {
+ /* Invensense */
+ mpu6515_acc@68 {
+ compatible = "inven,icm20648";
+ reg = <0x68>;
+ interrupt-parent = <&msmgpio>;
+ interrupts = <73 0x2>;
+ inven,vdd_ana-supply = <&pm8941_l17>;
+ inven,vcc_i2c-supply = <&pm8941_lvs1>;
+ inven,gpio_int1 = <&msmgpio 73 0x00>;
+ fs_range = <0x00>;
+ /* mount matrix */
+ axis_map_x = <1>;
+ axis_map_y = <0>;
+ axis_map_z = <2>;
+ negate_x = <0>;
+ negate_y = <0>;
+ negate_z = <1>;
+ poll_interval = <200>;
+ min_interval = <5>;
+ inven,secondary_reg = <0x0c>;
+ /* If no compass sensor,
+ * replace "compass" with "none"
+ */
+ inven,secondary_type = "compass";
+ inven,secondary_name = "ak09911";
+ inven,secondary_axis_map_x = <1>;
+ inven,secondary_axis_map_y = <0>;
+ inven,secondary_axis_map_z = <2>;
+ inven,secondary_negate_x = <1>;
+ inven,secondary_negate_y = <1>;
+ inven,secondary_negate_z = <1>;
+ /* If no pressure sensor,
+ * replace "pressure" with "none"
+ */
+ inven,aux_type = "pressure";
+ inven,aux_name = "bmp280";
+ inven,aux_reg = <0x76>;
+ /* If no ALS sensor
+ * replace "als" with "none"
+ */
+ inven,read_only_slave_type = "als";
+ inven,read_only_slave_name = "apds9930";
+ inven,read_only_slave_reg = <0x39>;
+ };
+ };
+
+
+Communicating with the Driver in Userspace
+==========================================
+The driver generates several files in sysfs upon installation.
+These files are used to communicate with the driver. The files can be found at:
+
+(I2C) /sys/devices/*.i2c/i2c-*/*-*/iio:device*
+(SPI) /sys/devices/*.spi/spi_master/spi*/spi*.*/iio:device*
+
+Group and Owner for all entries should be updated to system/system at
+boot time to allow userspace to access properly.
+
+
+License
+=======
+Copyright (C) 2018 InvenSense, Inc.
+
+This software is licensed under the terms of the GNU General Public
+License version 2, as published by the Free Software Foundation, and
+may be copied, distributed, and modified under those terms.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
diff --git a/drivers/iio/imu/inv_mpu/iam20680/inv_mpu_core_20680.c b/drivers/iio/imu/inv_mpu/iam20680/inv_mpu_core_20680.c
new file mode 100644
index 0000000..b429f57
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu/iam20680/inv_mpu_core_20680.c
@@ -0,0 +1,1072 @@
+/*
+ * Copyright (C) 2017-2018 InvenSense, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#define pr_fmt(fmt) "inv_mpu: " fmt
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/sysfs.h>
+#include <linux/jiffies.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/kfifo.h>
+#include <linux/poll.h>
+#include <linux/miscdevice.h>
+#include <linux/spinlock.h>
+#include <linux/spi/spi.h>
+#include <linux/i2c.h>
+
+#include "../inv_mpu_iio.h"
+
+static const struct inv_hw_s hw_info[INV_NUM_PARTS] = {
+ {128, "ICM20608D"},
+ {128, "ICM20690"},
+ {128, "ICM20602"},
+ {128, "IAM20680"},
+};
+
+#ifndef SUPPORT_ONLY_BASIC_FEATURES
+static char debug_reg_addr = 0x6;
+#endif
+
+const char sensor_l_info[][30] = {
+ "SENSOR_L_ACCEL",
+ "SENSOR_L_GYRO",
+ "SENSOR_L_MAG",
+ "SENSOR_L_ALS",
+ "SENSOR_L_SIXQ",
+ "SENSOR_L_THREEQ",
+ "SENSOR_L_NINEQ",
+ "SENSOR_L_PEDQ",
+ "SENSOR_L_GEOMAG",
+ "SENSOR_L_PRESSURE",
+ "SENSOR_L_GYRO_CAL",
+ "SENSOR_L_MAG_CAL",
+ "SENSOR_L_EIS_GYRO",
+ "SENSOR_L_ACCEL_WAKE",
+ "SENSOR_L_GYRO_WAKE",
+ "SENSOR_L_MAG_WAKE",
+ "SENSOR_L_ALS_WAKE",
+ "SENSOR_L_SIXQ_WAKE",
+ "SENSOR_L_NINEQ_WAKE",
+ "SENSOR_L_PEDQ_WAKE",
+ "SENSOR_L_GEOMAG_WAKE",
+ "SENSOR_L_PRESSURE_WAKE",
+ "SENSOR_L_GYRO_CAL_WAKE",
+ "SENSOR_L_MAG_CAL_WAKE",
+ "SENSOR_L_NUM_MAX",
+};
+
+static int inv_set_accel_bias_reg(struct inv_mpu_state *st,
+ int accel_bias, int axis)
+{
+ int accel_reg_bias;
+ u8 addr;
+ u8 d[2];
+ int result = 0;
+
+ switch (axis) {
+ case 0:
+ /* X */
+ addr = REG_XA_OFFS_H;
+ break;
+ case 1:
+ /* Y */
+ addr = REG_YA_OFFS_H;
+ break;
+ case 2:
+ /* Z* */
+ addr = REG_ZA_OFFS_H;
+ break;
+ default:
+ result = -EINVAL;
+ goto accel_bias_set_err;
+ }
+
+ result = inv_plat_read(st, addr, 2, d);
+ if (result)
+ goto accel_bias_set_err;
+ accel_reg_bias = ((int)d[0] << 8) | d[1];
+
+ /* accel_bias is 2g scaled by 1<<16.
+ * Convert to 16g, and mask bit0 */
+ accel_reg_bias -= ((accel_bias / 8 / 65536) & ~1);
+
+ d[0] = (accel_reg_bias >> 8) & 0xff;
+ d[1] = (accel_reg_bias) & 0xff;
+ result = inv_plat_single_write(st, addr, d[0]);
+ if (result)
+ goto accel_bias_set_err;
+ result = inv_plat_single_write(st, addr + 1, d[1]);
+ if (result)
+ goto accel_bias_set_err;
+
+accel_bias_set_err:
+ return result;
+}
+
+static int inv_set_gyro_bias_reg(struct inv_mpu_state *st,
+ const int gyro_bias, int axis)
+{
+ int gyro_reg_bias;
+ u8 addr;
+ u8 d[2];
+ int result = 0;
+
+ switch (axis) {
+ case 0:
+ /* X */
+ addr = REG_XG_OFFS_USR_H;
+ break;
+ case 1:
+ /* Y */
+ addr = REG_YG_OFFS_USR_H;
+ break;
+ case 2:
+ /* Z */
+ addr = REG_ZG_OFFS_USR_H;
+ break;
+ default:
+ result = -EINVAL;
+ goto gyro_bias_set_err;
+ }
+
+ /* gyro_bias is 2000dps scaled by 1<<16.
+ * Convert to 1000dps */
+ gyro_reg_bias = (-gyro_bias * 2 / 65536);
+
+ d[0] = (gyro_reg_bias >> 8) & 0xff;
+ d[1] = (gyro_reg_bias) & 0xff;
+ result = inv_plat_single_write(st, addr, d[0]);
+ if (result)
+ goto gyro_bias_set_err;
+ result = inv_plat_single_write(st, addr + 1, d[1]);
+ if (result)
+ goto gyro_bias_set_err;
+
+gyro_bias_set_err:
+ return result;
+}
+
+static int _bias_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct inv_mpu_state *st = iio_priv(indio_dev);
+ struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+ int result, data;
+
+ result = inv_switch_power_in_lp(st, true);
+ if (result)
+ return result;
+
+ result = kstrtoint(buf, 10, &data);
+ if (result)
+ goto bias_store_fail;
+ switch (this_attr->address) {
+ case ATTR_ACCEL_X_OFFSET:
+ result = inv_set_accel_bias_reg(st, data, 0);
+ if (result)
+ goto bias_store_fail;
+ st->input_accel_bias[0] = data;
+ break;
+ case ATTR_ACCEL_Y_OFFSET:
+ result = inv_set_accel_bias_reg(st, data, 1);
+ if (result)
+ goto bias_store_fail;
+ st->input_accel_bias[1] = data;
+ break;
+ case ATTR_ACCEL_Z_OFFSET:
+ result = inv_set_accel_bias_reg(st, data, 2);
+ if (result)
+ goto bias_store_fail;
+ st->input_accel_bias[2] = data;
+ break;
+ case ATTR_GYRO_X_OFFSET:
+ result = inv_set_gyro_bias_reg(st, data, 0);
+ if (result)
+ goto bias_store_fail;
+ st->input_gyro_bias[0] = data;
+ break;
+ case ATTR_GYRO_Y_OFFSET:
+ result = inv_set_gyro_bias_reg(st, data, 1);
+ if (result)
+ goto bias_store_fail;
+ st->input_gyro_bias[1] = data;
+ break;
+ case ATTR_GYRO_Z_OFFSET:
+ result = inv_set_gyro_bias_reg(st, data, 2);
+ if (result)
+ goto bias_store_fail;
+ st->input_gyro_bias[2] = data;
+ break;
+ default:
+ break;
+ }
+
+bias_store_fail:
+ if (result)
+ return result;
+ result = inv_switch_power_in_lp(st, false);
+ if (result)
+ return result;
+
+ return count;
+}
+
+static ssize_t inv_bias_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ int result;
+
+ mutex_lock(&indio_dev->mlock);
+ result = _bias_store(dev, attr, buf, count);
+ mutex_unlock(&indio_dev->mlock);
+
+ return result;
+}
+
+#ifndef SUPPORT_ONLY_BASIC_FEATURES
+static ssize_t inv_debug_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct inv_mpu_state *st = iio_priv(indio_dev);
+ struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+ int result, data;
+
+ result = kstrtoint(buf, 10, &data);
+ if (result)
+ return result;
+ switch (this_attr->address) {
+ case ATTR_DMP_LP_EN_OFF:
+ st->chip_config.lp_en_mode_off = !!data;
+ inv_switch_power_in_lp(st, !!data);
+ break;
+ case ATTR_DMP_CLK_SEL:
+ st->chip_config.clk_sel = !!data;
+ inv_switch_power_in_lp(st, !!data);
+ break;
+ case ATTR_DEBUG_REG_ADDR:
+ debug_reg_addr = data;
+ break;
+ case ATTR_DEBUG_REG_WRITE:
+ inv_plat_single_write(st, debug_reg_addr, data);
+ break;
+ }
+ return count;
+}
+#endif
+
+static int _misc_attr_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct inv_mpu_state *st = iio_priv(indio_dev);
+ struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+ int result, data;
+
+ result = inv_switch_power_in_lp(st, true);
+ if (result)
+ return result;
+ result = kstrtoint(buf, 10, &data);
+ if (result)
+ return result;
+ switch (this_attr->address) {
+ case ATTR_GYRO_SCALE:
+ if (data > 3)
+ return -EINVAL;
+ st->chip_config.fsr = data;
+ result = inv_set_gyro_sf(st);
+ return result;
+ case ATTR_ACCEL_SCALE:
+ if (data > 3)
+ return -EINVAL;
+ st->chip_config.accel_fs = data;
+ result = inv_set_accel_sf(st);
+ return result;
+ default:
+ return -EINVAL;
+ }
+ st->trigger_state = MISC_TRIGGER;
+ result = set_inv_enable(indio_dev);
+
+ return result;
+}
+
+/*
+ * inv_misc_attr_store() - calling this function
+ */
+static ssize_t inv_misc_attr_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ int result;
+
+ mutex_lock(&indio_dev->mlock);
+ result = _misc_attr_store(dev, attr, buf, count);
+ mutex_unlock(&indio_dev->mlock);
+ if (result)
+ return result;
+
+ return count;
+}
+
+static ssize_t inv_sensor_rate_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct inv_mpu_state *st = iio_priv(indio_dev);
+ struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+ return snprintf(buf, MAX_WR_SZ, "%d\n",
+ st->sensor_l[this_attr->address].rate);
+}
+
+static ssize_t inv_sensor_rate_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct inv_mpu_state *st = iio_priv(indio_dev);
+ struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+ int data, rate, ind;
+ int result;
+
+ result = kstrtoint(buf, 10, &data);
+ if (result)
+ return -EINVAL;
+ if (data <= 0) {
+ pr_err("sensor_rate_store: invalid data=%d\n", data);
+ return -EINVAL;
+ }
+ ind = this_attr->address;
+ rate = inv_rate_convert(st, ind, data);
+
+ pr_debug("sensor [%s] requested rate %d input [%d]\n",
+ sensor_l_info[ind], rate, data);
+
+ if (rate == st->sensor_l[ind].rate)
+ return count;
+ mutex_lock(&indio_dev->mlock);
+ st->sensor_l[ind].rate = rate;
+ st->trigger_state = DATA_TRIGGER;
+ inv_check_sensor_on(st);
+ result = set_inv_enable(indio_dev);
+ pr_debug("%s rate %d div %d\n", sensor_l_info[ind],
+ st->sensor_l[ind].rate, st->sensor_l[ind].div);
+ mutex_unlock(&indio_dev->mlock);
+
+ return count;
+}
+
+static ssize_t inv_sensor_on_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct inv_mpu_state *st = iio_priv(indio_dev);
+ struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+ return snprintf(buf, MAX_WR_SZ, "%d\n", st->sensor_l[this_attr->address].on);
+}
+
+static ssize_t inv_sensor_on_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct inv_mpu_state *st = iio_priv(indio_dev);
+ struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+ int data, on, ind;
+ int result;
+
+ result = kstrtoint(buf, 10, &data);
+ if (result)
+ return -EINVAL;
+ if (data < 0) {
+ pr_err("sensor_on_store: invalid data=%d\n", data);
+ return -EINVAL;
+ }
+ ind = this_attr->address;
+ on = !!data;
+
+ pr_debug("sensor [%s] requested %s, input [%d]\n",
+ sensor_l_info[ind], (on == 1) ? "On" : "Off", data);
+
+ if (on == st->sensor_l[ind].on) {
+ pr_debug("sensor [%s] is already %s, input [%d]\n",
+ sensor_l_info[ind], (on == 1) ? "On" : "Off", data);
+ return count;
+ }
+
+ mutex_lock(&indio_dev->mlock);
+ st->sensor_l[ind].on = on;
+ st->trigger_state = RATE_TRIGGER;
+ inv_check_sensor_on(st);
+ result = set_inv_enable(indio_dev);
+ mutex_unlock(&indio_dev->mlock);
+ if (result)
+ return result;
+
+ pr_debug("Sensor [%s] is %s by sysfs\n",
+ sensor_l_info[ind], (on == 1) ? "On" : "Off");
+ return count;
+}
+
+static int inv_check_l_step(struct inv_mpu_state *st)
+{
+ if (st->step_counter_l_on || st->step_counter_wake_l_on)
+ st->ped.on = true;
+ else
+ st->ped.on = false;
+
+ return 0;
+}
+
+static int _basic_attr_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct inv_mpu_state *st = iio_priv(indio_dev);
+ struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+ int data;
+ int result;
+ u32 power_on_data;
+
+ result = kstrtoint(buf, 10, &data);
+ if (result || (data < 0))
+ return -EINVAL;
+
+ switch (this_attr->address) {
+ case ATTR_DMP_PED_ON:
+ if ((!!data) == st->ped.on)
+ return count;
+ st->ped.on = !!data;
+ break;
+ case ATTR_DMP_TILT_ENABLE:
+ if ((!!data) == st->chip_config.tilt_enable)
+ return count;
+ st->chip_config.tilt_enable = !!data;
+ pr_info("Tile %s\n",
+ st->chip_config.tilt_enable ==
+ 1 ? "Enabled" : "Disabled");
+ break;
+ case ATTR_DMP_PICK_UP_ENABLE:
+ if ((!!data) == st->chip_config.pick_up_enable) {
+ pr_info("Pick_up enable already %s\n",
+ st->chip_config.pick_up_enable ==
+ 1 ? "Enabled" : "Disabled");
+ return count;
+ }
+ st->chip_config.pick_up_enable = !!data;
+ pr_info("Pick up %s\n",
+ st->chip_config.pick_up_enable ==
+ 1 ? "Enable" : "Disable");
+ break;
+ case ATTR_IN_POWER_ON:
+ {
+ u8 p0[2];
+ u8 p1[2];
+
+ power_on_data = (u32)data;
+ p0[0] = (power_on_data & 0xff);
+ p0[1] = ((power_on_data >> 8) & 0xff);
+ p1[0] = ((power_on_data >> 16) & 0xff);
+ p1[1] = ((power_on_data >> 24) & 0xff);
+
+ if (st->bus_type == BUS_SPI) {
+ struct spi_transfer power_on;
+ struct spi_message msg;
+
+ memset(&power_on, 0, sizeof(struct spi_transfer));
+
+ power_on.bits_per_word = 8;
+ power_on.len = 2;
+
+ power_on.tx_buf = p0;
+ power_on.rx_buf = p1;
+ spi_message_init(&msg);
+ spi_message_add_tail(&power_on, &msg);
+ spi_sync(to_spi_device(st->dev), &msg);
+
+ } else if (st->bus_type == BUS_I2C) {
+ struct i2c_msg msgs[2];
+
+ p0[0] &= 0x7f;
+
+ msgs[0].addr = st->i2c_addr;
+ msgs[0].flags = 0; /* write */
+ msgs[0].buf = &p0[0];
+ msgs[0].len = 1;
+
+ msgs[1].addr = st->i2c_addr;
+ msgs[1].flags = I2C_M_RD;
+ msgs[1].buf = &p1[1];
+ msgs[1].len = 1;
+
+ result = i2c_transfer(st->sl_handle, msgs, 2);
+ if (result < 2)
+ return -EIO;
+ }
+ st->power_on_data = ((p0[0] << 24) | (p0[1] << 16) |
+ (p1[0] << 8) | p1[1]);
+ return count;
+ }
+ case ATTR_DMP_EIS_ENABLE:
+ if ((!!data) == st->chip_config.eis_enable)
+ return count;
+ st->chip_config.eis_enable = !!data;
+ pr_info("Eis %s\n",
+ st->chip_config.eis_enable == 1 ? "Enable" : "Disable");
+ break;
+ case ATTR_DMP_STEP_DETECTOR_ON:
+ st->step_detector_l_on = !!data;
+ break;
+ case ATTR_DMP_STEP_DETECTOR_WAKE_ON:
+ st->step_detector_wake_l_on = !!data;
+ break;
+ case ATTR_DMP_STEP_COUNTER_ON:
+ st->step_counter_l_on = !!data;
+ break;
+ case ATTR_DMP_STEP_COUNTER_WAKE_ON:
+ st->step_counter_wake_l_on = !!data;
+ break;
+ case ATTR_DMP_BATCHMODE_TIMEOUT:
+ if (data == st->batch.timeout)
+ return count;
+ st->batch.timeout = data;
+ break;
+ default:
+ return -EINVAL;
+ };
+ inv_check_l_step(st);
+ inv_check_sensor_on(st);
+
+ st->trigger_state = EVENT_TRIGGER;
+ result = set_inv_enable(indio_dev);
+ if (result)
+ return result;
+
+ return count;
+}
+
+/*
+ * inv_basic_attr_store()
+ */
+static ssize_t inv_basic_attr_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ int result;
+
+ mutex_lock(&indio_dev->mlock);
+ result = _basic_attr_store(dev, attr, buf, count);
+
+ mutex_unlock(&indio_dev->mlock);
+
+ return result;
+}
+
+/*
+ * inv_attr_show()
+ */
+static ssize_t inv_attr_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct inv_mpu_state *st = iio_priv(indio_dev);
+ struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+ s8 *m;
+
+ switch (this_attr->address) {
+ case ATTR_GYRO_SCALE:
+ {
+ const s16 gyro_scale[] = { 250, 500, 1000, 2000 };
+
+ return snprintf(buf, MAX_WR_SZ, "%d\n",
+ gyro_scale[st->chip_config.fsr]);
+ }
+ case ATTR_ACCEL_SCALE:
+ {
+ const s16 accel_scale[] = { 2, 4, 8, 16 };
+ return snprintf(buf, MAX_WR_SZ, "%d\n",
+ accel_scale[st->chip_config.accel_fs]);
+ }
+ case ATTR_GYRO_ENABLE:
+ return snprintf(buf, MAX_WR_SZ, "%d\n", st->chip_config.gyro_enable);
+ case ATTR_ACCEL_ENABLE:
+ return snprintf(buf, MAX_WR_SZ, "%d\n", st->chip_config.accel_enable);
+ case ATTR_IN_POWER_ON:
+ return snprintf(buf, MAX_WR_SZ, "%d\n", st->power_on_data);
+ case ATTR_DMP_BATCHMODE_TIMEOUT:
+ return snprintf(buf, MAX_WR_SZ, "%d\n", st->batch.timeout);
+ case ATTR_DMP_PED_ON:
+ return snprintf(buf, MAX_WR_SZ, "%d\n", st->ped.on);
+ case ATTR_DMP_TILT_ENABLE:
+ return snprintf(buf, MAX_WR_SZ, "%d\n",
+ st->chip_config.tilt_enable);
+ case ATTR_DMP_PICK_UP_ENABLE:
+ return snprintf(buf, MAX_WR_SZ, "%d\n",
+ st->chip_config.pick_up_enable);
+ case ATTR_DMP_EIS_ENABLE:
+ return snprintf(buf, MAX_WR_SZ, "%d\n", st->chip_config.eis_enable);
+ case ATTR_DMP_LP_EN_OFF:
+ return snprintf(buf, MAX_WR_SZ, "%d\n",
+ st->chip_config.lp_en_mode_off);
+ case ATTR_DMP_STEP_COUNTER_ON:
+ return snprintf(buf, MAX_WR_SZ, "%d\n", st->step_counter_l_on);
+ case ATTR_DMP_STEP_COUNTER_WAKE_ON:
+ return snprintf(buf, MAX_WR_SZ, "%d\n", st->step_counter_wake_l_on);
+ case ATTR_DMP_STEP_DETECTOR_ON:
+ return snprintf(buf, MAX_WR_SZ, "%d\n", st->step_detector_l_on);
+ case ATTR_DMP_STEP_DETECTOR_WAKE_ON:
+ return snprintf(buf, MAX_WR_SZ, "%d\n", st->step_detector_wake_l_on);
+ case ATTR_GYRO_MATRIX:
+ m = st->plat_data.orientation;
+ return snprintf(buf, MAX_WR_SZ, "%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
+ m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7],
+ m[8]);
+ case ATTR_ACCEL_MATRIX:
+ m = st->plat_data.orientation;
+ return snprintf(buf, MAX_WR_SZ, "%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
+ m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7],
+ m[8]);
+ case ATTR_GYRO_SF:
+ return snprintf(buf, MAX_WR_SZ, "%d\n", st->gyro_sf);
+ case ATTR_ANGLVEL_X_ST_CALIBBIAS:
+ return snprintf(buf, MAX_WR_SZ, "%d\n", st->gyro_st_bias[0]);
+ case ATTR_ANGLVEL_Y_ST_CALIBBIAS:
+ return snprintf(buf, MAX_WR_SZ, "%d\n", st->gyro_st_bias[1]);
+ case ATTR_ANGLVEL_Z_ST_CALIBBIAS:
+ return snprintf(buf, MAX_WR_SZ, "%d\n", st->gyro_st_bias[2]);
+ case ATTR_ACCEL_X_ST_CALIBBIAS:
+ return snprintf(buf, MAX_WR_SZ, "%d\n", st->accel_st_bias[0]);
+ case ATTR_ACCEL_Y_ST_CALIBBIAS:
+ return snprintf(buf, MAX_WR_SZ, "%d\n", st->accel_st_bias[1]);
+ case ATTR_ACCEL_Z_ST_CALIBBIAS:
+ return snprintf(buf, MAX_WR_SZ, "%d\n", st->accel_st_bias[2]);
+ case ATTR_GYRO_X_OFFSET:
+ return snprintf(buf, MAX_WR_SZ, "%d\n", st->input_gyro_bias[0]);
+ case ATTR_GYRO_Y_OFFSET:
+ return snprintf(buf, MAX_WR_SZ, "%d\n", st->input_gyro_bias[1]);
+ case ATTR_GYRO_Z_OFFSET:
+ return snprintf(buf, MAX_WR_SZ, "%d\n", st->input_gyro_bias[2]);
+ case ATTR_ACCEL_X_OFFSET:
+ return snprintf(buf, MAX_WR_SZ, "%d\n", st->input_accel_bias[0]);
+ case ATTR_ACCEL_Y_OFFSET:
+ return snprintf(buf, MAX_WR_SZ, "%d\n", st->input_accel_bias[1]);
+ case ATTR_ACCEL_Z_OFFSET:
+ return snprintf(buf, MAX_WR_SZ, "%d\n", st->input_accel_bias[2]);
+ default:
+ return -EPERM;
+ }
+}
+
+static ssize_t inv_self_test(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct inv_mpu_state *st = iio_priv(indio_dev);
+ int res;
+
+ mutex_lock(&indio_dev->mlock);
+ res = inv_hw_self_test(st);
+ set_inv_enable(indio_dev);
+ mutex_unlock(&indio_dev->mlock);
+
+ return snprintf(buf, MAX_WR_SZ, "%d\n", res);
+}
+
+
+/*
+ * inv_temperature_show() - Read temperature data directly from registers.
+ */
+static ssize_t inv_temperature_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct inv_mpu_state *st = iio_priv(indio_dev);
+
+ u8 data[2];
+ s32 temp;
+ int res;
+
+ mutex_lock(&indio_dev->mlock);
+ res = inv_plat_read(st, REG_RAW_TEMP, 2, data);
+ if (res)
+ return res;
+ mutex_unlock(&indio_dev->mlock);
+
+ temp = (s32)be16_to_cpup((__be16 *)(data)) * 10000;
+ temp = temp / TEMP_SENSITIVITY + TEMP_OFFSET;
+
+ return snprintf(buf, MAX_WR_SZ, "%d %lld\n", temp, get_time_ns());
+}
+
+/*
+ * inv_reg_dump_show() - Register dump for testing.
+ */
+static ssize_t inv_reg_dump_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int ii;
+ char data;
+ int bytes_printed = 0;
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct inv_mpu_state *st = iio_priv(indio_dev);
+
+ mutex_lock(&indio_dev->mlock);
+ bytes_printed += snprintf(buf + bytes_printed, MAX_WR_SZ, "bank 0\n");
+
+ for (ii = 0; ii < 0x7F; ii++) {
+ /* don't read fifo r/w register */
+ if ((ii == REG_MEM_R_W) || (ii == REG_FIFO_R_W))
+ data = 0;
+ else
+ inv_plat_read(st, ii, 1, &data);
+ bytes_printed += snprintf(buf + bytes_printed, MAX_WR_SZ,
+ "%#2x: %#2x\n", ii, data);
+ }
+ set_inv_enable(indio_dev);
+ mutex_unlock(&indio_dev->mlock);
+
+ return bytes_printed;
+}
+
+static ssize_t inv_flush_batch_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ int result, data;
+
+ result = kstrtoint(buf, 10, &data);
+ if (result)
+ return result;
+
+ mutex_lock(&indio_dev->mlock);
+ result = inv_flush_batch_data(indio_dev, data);
+ mutex_unlock(&indio_dev->mlock);
+
+ return count;
+}
+
+static const struct iio_chan_spec inv_mpu_channels[] = {
+ IIO_CHAN_SOFT_TIMESTAMP(INV_MPU_SCAN_TIMESTAMP),
+};
+
+/* special run time sysfs entry, read only */
+static DEVICE_ATTR(debug_reg_dump, S_IRUGO | S_IWUSR, inv_reg_dump_show, NULL);
+static DEVICE_ATTR(out_temperature, S_IRUGO | S_IWUSR,
+ inv_temperature_show, NULL);
+static DEVICE_ATTR(misc_self_test, S_IRUGO | S_IWUSR, inv_self_test, NULL);
+
+static IIO_DEVICE_ATTR(info_anglvel_matrix, S_IRUGO, inv_attr_show, NULL,
+ ATTR_GYRO_MATRIX);
+static IIO_DEVICE_ATTR(info_accel_matrix, S_IRUGO, inv_attr_show, NULL,
+ ATTR_ACCEL_MATRIX);
+
+static IIO_DEVICE_ATTR(info_gyro_sf, S_IRUGO, inv_attr_show, NULL,
+ ATTR_GYRO_SF);
+/* write only sysfs */
+static DEVICE_ATTR(misc_flush_batch, S_IWUSR, NULL, inv_flush_batch_store);
+
+/* sensor on/off sysfs control */
+static IIO_DEVICE_ATTR(in_accel_enable, S_IRUGO | S_IWUSR,
+ inv_sensor_on_show, inv_sensor_on_store, SENSOR_L_ACCEL);
+static IIO_DEVICE_ATTR(in_anglvel_enable, S_IRUGO | S_IWUSR,
+ inv_sensor_on_show, inv_sensor_on_store, SENSOR_L_GYRO);
+#ifndef SUPPORT_ONLY_BASIC_FEATURES
+static IIO_DEVICE_ATTR(in_eis_enable, S_IRUGO | S_IWUSR,
+ inv_sensor_on_show, inv_sensor_on_store,
+ SENSOR_L_EIS_GYRO);
+#endif
+static IIO_DEVICE_ATTR(in_accel_wake_enable, S_IRUGO | S_IWUSR,
+ inv_sensor_on_show, inv_sensor_on_store,
+ SENSOR_L_ACCEL_WAKE);
+static IIO_DEVICE_ATTR(in_anglvel_wake_enable, S_IRUGO | S_IWUSR,
+ inv_sensor_on_show, inv_sensor_on_store,
+ SENSOR_L_GYRO_WAKE);
+
+/* sensor rate sysfs control */
+static IIO_DEVICE_ATTR(in_accel_rate, S_IRUGO | S_IWUSR,
+ inv_sensor_rate_show, inv_sensor_rate_store,
+ SENSOR_L_ACCEL);
+static IIO_DEVICE_ATTR(in_anglvel_rate, S_IRUGO | S_IWUSR, inv_sensor_rate_show,
+ inv_sensor_rate_store, SENSOR_L_GYRO);
+#ifndef SUPPORT_ONLY_BASIC_FEATURES
+static IIO_DEVICE_ATTR(in_eis_rate, S_IRUGO | S_IWUSR,
+ inv_sensor_rate_show, inv_sensor_rate_store,
+ SENSOR_L_EIS_GYRO);
+#endif
+static IIO_DEVICE_ATTR(in_accel_wake_rate, S_IRUGO | S_IWUSR,
+ inv_sensor_rate_show, inv_sensor_rate_store,
+ SENSOR_L_ACCEL_WAKE);
+static IIO_DEVICE_ATTR(in_anglvel_wake_rate, S_IRUGO | S_IWUSR,
+ inv_sensor_rate_show, inv_sensor_rate_store,
+ SENSOR_L_GYRO_WAKE);
+
+static IIO_DEVICE_ATTR(misc_batchmode_timeout, S_IRUGO | S_IWUSR,
+ inv_attr_show, inv_basic_attr_store,
+ ATTR_DMP_BATCHMODE_TIMEOUT);
+
+/* engine scale */
+static IIO_DEVICE_ATTR(in_accel_scale, S_IRUGO | S_IWUSR, inv_attr_show,
+ inv_misc_attr_store, ATTR_ACCEL_SCALE);
+static IIO_DEVICE_ATTR(in_anglvel_scale, S_IRUGO | S_IWUSR, inv_attr_show,
+ inv_misc_attr_store, ATTR_GYRO_SCALE);
+
+
+#ifndef SUPPORT_ONLY_BASIC_FEATURES
+static IIO_DEVICE_ATTR(debug_lp_en_off, S_IRUGO | S_IWUSR, inv_attr_show,
+ inv_debug_store, ATTR_DMP_LP_EN_OFF);
+static IIO_DEVICE_ATTR(debug_clock_sel, S_IRUGO | S_IWUSR, inv_attr_show,
+ inv_debug_store, ATTR_DMP_CLK_SEL);
+static IIO_DEVICE_ATTR(debug_reg_write, S_IRUGO | S_IWUSR, inv_attr_show,
+ inv_debug_store, ATTR_DEBUG_REG_WRITE);
+static IIO_DEVICE_ATTR(debug_reg_write_addr, S_IRUGO | S_IWUSR, inv_attr_show,
+ inv_debug_store, ATTR_DEBUG_REG_ADDR);
+#endif
+
+static IIO_DEVICE_ATTR(in_accel_x_st_calibbias, S_IRUGO | S_IWUSR,
+ inv_attr_show, NULL, ATTR_ACCEL_X_ST_CALIBBIAS);
+static IIO_DEVICE_ATTR(in_accel_y_st_calibbias, S_IRUGO | S_IWUSR,
+ inv_attr_show, NULL, ATTR_ACCEL_Y_ST_CALIBBIAS);
+static IIO_DEVICE_ATTR(in_accel_z_st_calibbias, S_IRUGO | S_IWUSR,
+ inv_attr_show, NULL, ATTR_ACCEL_Z_ST_CALIBBIAS);
+
+static IIO_DEVICE_ATTR(in_anglvel_x_st_calibbias, S_IRUGO | S_IWUSR,
+ inv_attr_show, NULL, ATTR_ANGLVEL_X_ST_CALIBBIAS);
+static IIO_DEVICE_ATTR(in_anglvel_y_st_calibbias, S_IRUGO | S_IWUSR,
+ inv_attr_show, NULL, ATTR_ANGLVEL_Y_ST_CALIBBIAS);
+static IIO_DEVICE_ATTR(in_anglvel_z_st_calibbias, S_IRUGO | S_IWUSR,
+ inv_attr_show, NULL, ATTR_ANGLVEL_Z_ST_CALIBBIAS);
+
+static IIO_DEVICE_ATTR(in_accel_x_offset, S_IRUGO | S_IWUSR,
+ inv_attr_show, inv_bias_store, ATTR_ACCEL_X_OFFSET);
+static IIO_DEVICE_ATTR(in_accel_y_offset, S_IRUGO | S_IWUSR,
+ inv_attr_show, inv_bias_store, ATTR_ACCEL_Y_OFFSET);
+static IIO_DEVICE_ATTR(in_accel_z_offset, S_IRUGO | S_IWUSR,
+ inv_attr_show, inv_bias_store, ATTR_ACCEL_Z_OFFSET);
+
+static IIO_DEVICE_ATTR(in_anglvel_x_offset, S_IRUGO | S_IWUSR,
+ inv_attr_show, inv_bias_store, ATTR_GYRO_X_OFFSET);
+static IIO_DEVICE_ATTR(in_anglvel_y_offset, S_IRUGO | S_IWUSR,
+ inv_attr_show, inv_bias_store, ATTR_GYRO_Y_OFFSET);
+static IIO_DEVICE_ATTR(in_anglvel_z_offset, S_IRUGO | S_IWUSR,
+ inv_attr_show, inv_bias_store, ATTR_GYRO_Z_OFFSET);
+
+#ifndef SUPPORT_ONLY_BASIC_FEATURES
+static IIO_DEVICE_ATTR(in_step_detector_enable, S_IRUGO | S_IWUSR,
+ inv_attr_show, inv_basic_attr_store,
+ ATTR_DMP_STEP_DETECTOR_ON);
+static IIO_DEVICE_ATTR(in_step_detector_wake_enable, S_IRUGO | S_IWUSR,
+ inv_attr_show, inv_basic_attr_store,
+ ATTR_DMP_STEP_DETECTOR_WAKE_ON);
+static IIO_DEVICE_ATTR(in_step_counter_enable, S_IRUGO | S_IWUSR, inv_attr_show,
+ inv_basic_attr_store, ATTR_DMP_STEP_COUNTER_ON);
+static IIO_DEVICE_ATTR(in_step_counter_wake_enable, S_IRUGO | S_IWUSR,
+ inv_attr_show, inv_basic_attr_store,
+ ATTR_DMP_STEP_COUNTER_WAKE_ON);
+
+static IIO_DEVICE_ATTR(event_tilt_enable, S_IRUGO | S_IWUSR,
+ inv_attr_show, inv_basic_attr_store,
+ ATTR_DMP_TILT_ENABLE);
+
+static IIO_DEVICE_ATTR(event_eis_enable, S_IRUGO | S_IWUSR,
+ inv_attr_show, inv_basic_attr_store,
+ ATTR_DMP_EIS_ENABLE);
+
+static IIO_DEVICE_ATTR(event_pick_up_enable, S_IRUGO | S_IWUSR,
+ inv_attr_show, inv_basic_attr_store,
+ ATTR_DMP_PICK_UP_ENABLE);
+
+static IIO_DEVICE_ATTR(in_power_on, S_IRUGO | S_IWUSR,
+ inv_attr_show, inv_basic_attr_store,
+ ATTR_IN_POWER_ON);
+#endif
+
+static const struct attribute *inv_raw_attributes[] = {
+ &dev_attr_debug_reg_dump.attr,
+ &dev_attr_out_temperature.attr,
+ &dev_attr_misc_flush_batch.attr,
+ &dev_attr_misc_self_test.attr,
+#ifndef SUPPORT_ONLY_BASIC_FEATURES
+ &iio_dev_attr_in_power_on.dev_attr.attr,
+#endif
+ &iio_dev_attr_in_accel_enable.dev_attr.attr,
+ &iio_dev_attr_in_accel_wake_enable.dev_attr.attr,
+ &iio_dev_attr_info_accel_matrix.dev_attr.attr,
+ &iio_dev_attr_in_accel_scale.dev_attr.attr,
+ &iio_dev_attr_misc_batchmode_timeout.dev_attr.attr,
+ &iio_dev_attr_in_accel_rate.dev_attr.attr,
+ &iio_dev_attr_in_accel_wake_rate.dev_attr.attr,
+};
+
+#ifndef SUPPORT_ONLY_BASIC_FEATURES
+static const struct attribute *inv_debug_attributes[] = {
+ &iio_dev_attr_debug_lp_en_off.dev_attr.attr,
+ &iio_dev_attr_debug_clock_sel.dev_attr.attr,
+ &iio_dev_attr_debug_reg_write.dev_attr.attr,
+ &iio_dev_attr_debug_reg_write_addr.dev_attr.attr,
+};
+#endif
+
+static const struct attribute *inv_gyro_attributes[] = {
+ &iio_dev_attr_info_anglvel_matrix.dev_attr.attr,
+ &iio_dev_attr_in_anglvel_enable.dev_attr.attr,
+ &iio_dev_attr_in_anglvel_rate.dev_attr.attr,
+#ifndef SUPPORT_ONLY_BASIC_FEATURES
+ &iio_dev_attr_in_eis_enable.dev_attr.attr,
+#endif
+ &iio_dev_attr_in_anglvel_wake_enable.dev_attr.attr,
+ &iio_dev_attr_in_anglvel_scale.dev_attr.attr,
+#ifndef SUPPORT_ONLY_BASIC_FEATURES
+ &iio_dev_attr_in_eis_rate.dev_attr.attr,
+#endif
+ &iio_dev_attr_in_anglvel_wake_rate.dev_attr.attr,
+ &iio_dev_attr_info_gyro_sf.dev_attr.attr,
+};
+
+static const struct attribute *inv_bias_attributes[] = {
+ &iio_dev_attr_in_accel_x_st_calibbias.dev_attr.attr,
+ &iio_dev_attr_in_accel_y_st_calibbias.dev_attr.attr,
+ &iio_dev_attr_in_accel_z_st_calibbias.dev_attr.attr,
+ &iio_dev_attr_in_accel_x_offset.dev_attr.attr,
+ &iio_dev_attr_in_accel_y_offset.dev_attr.attr,
+ &iio_dev_attr_in_accel_z_offset.dev_attr.attr,
+ &iio_dev_attr_in_anglvel_x_st_calibbias.dev_attr.attr,
+ &iio_dev_attr_in_anglvel_y_st_calibbias.dev_attr.attr,
+ &iio_dev_attr_in_anglvel_z_st_calibbias.dev_attr.attr,
+ &iio_dev_attr_in_anglvel_x_offset.dev_attr.attr,
+ &iio_dev_attr_in_anglvel_y_offset.dev_attr.attr,
+ &iio_dev_attr_in_anglvel_z_offset.dev_attr.attr,
+};
+
+#ifndef SUPPORT_ONLY_BASIC_FEATURES
+static const struct attribute *inv_pedometer_attributes[] = {
+ &iio_dev_attr_event_tilt_enable.dev_attr.attr,
+ &iio_dev_attr_event_eis_enable.dev_attr.attr,
+ &iio_dev_attr_event_pick_up_enable.dev_attr.attr,
+ &iio_dev_attr_in_step_counter_enable.dev_attr.attr,
+ &iio_dev_attr_in_step_counter_wake_enable.dev_attr.attr,
+ &iio_dev_attr_in_step_detector_enable.dev_attr.attr,
+ &iio_dev_attr_in_step_detector_wake_enable.dev_attr.attr,
+};
+#endif
+
+static struct attribute *inv_attributes[ARRAY_SIZE(inv_raw_attributes) +
+#ifndef SUPPORT_ONLY_BASIC_FEATURES
+ ARRAY_SIZE(inv_debug_attributes) +
+#endif
+ ARRAY_SIZE(inv_gyro_attributes) +
+ ARRAY_SIZE(inv_bias_attributes) +
+#ifndef SUPPORT_ONLY_BASIC_FEATURES
+ ARRAY_SIZE(inv_pedometer_attributes) +
+#endif
+ + 1];
+
+static const struct attribute_group inv_attribute_group = {
+ .name = "mpu",
+ .attrs = inv_attributes
+};
+
+static const struct iio_info mpu_info = {
+ .driver_module = THIS_MODULE,
+ .attrs = &inv_attribute_group,
+};
+
+/*
+ * inv_check_chip_type() - check and setup chip type.
+ */
+int inv_check_chip_type(struct iio_dev *indio_dev, const char *name)
+{
+ int result;
+ int t_ind;
+ struct inv_chip_config_s *conf;
+ struct mpu_platform_data *plat;
+ struct inv_mpu_state *st;
+
+ st = iio_priv(indio_dev);
+ conf = &st->chip_config;
+ plat = &st->plat_data;
+
+ if (!strcmp(name, "iam20680"))
+ st->chip_type = IAM20680;
+ else
+ return -EPERM;
+ st->chip_config.has_gyro = 1;
+
+ st->hw = &hw_info[st->chip_type];
+ result = inv_mpu_initialize(st);
+ if (result)
+ return result;
+
+ t_ind = 0;
+ memcpy(&inv_attributes[t_ind], inv_raw_attributes,
+ sizeof(inv_raw_attributes));
+ t_ind += ARRAY_SIZE(inv_raw_attributes);
+
+#ifndef SUPPORT_ONLY_BASIC_FEATURES
+ memcpy(&inv_attributes[t_ind], inv_pedometer_attributes,
+ sizeof(inv_pedometer_attributes));
+ t_ind += ARRAY_SIZE(inv_pedometer_attributes);
+#endif
+
+ memcpy(&inv_attributes[t_ind], inv_gyro_attributes,
+ sizeof(inv_gyro_attributes));
+ t_ind += ARRAY_SIZE(inv_gyro_attributes);
+
+ memcpy(&inv_attributes[t_ind], inv_bias_attributes,
+ sizeof(inv_bias_attributes));
+ t_ind += ARRAY_SIZE(inv_bias_attributes);
+
+#ifndef SUPPORT_ONLY_BASIC_FEATURES
+ memcpy(&inv_attributes[t_ind], inv_debug_attributes,
+ sizeof(inv_debug_attributes));
+ t_ind += ARRAY_SIZE(inv_debug_attributes);
+#endif
+
+ inv_attributes[t_ind] = NULL;
+
+ indio_dev->channels = inv_mpu_channels;
+ indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels);
+
+ indio_dev->info = &mpu_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->currentmode = INDIO_DIRECT_MODE;
+
+ return result;
+}
+EXPORT_SYMBOL_GPL(inv_check_chip_type);
+
+int inv_create_dmp_sysfs(struct iio_dev *ind)
+{
+ // dummy
+ return 0;
+}
+EXPORT_SYMBOL_GPL(inv_create_dmp_sysfs);
+
+MODULE_AUTHOR("Invensense Corporation");
+MODULE_DESCRIPTION("Invensense device ICM20xxx driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/imu/inv_mpu/iam20680/inv_mpu_iio_reg_20680.h b/drivers/iio/imu/inv_mpu/iam20680/inv_mpu_iio_reg_20680.h
new file mode 100644
index 0000000..3f8ce71
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu/iam20680/inv_mpu_iio_reg_20680.h
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2017-2018 InvenSense, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _INV_MPU_IIO_REG_20680_H_
+#define _INV_MPU_IIO_REG_20680_H_
+
+/* Uncomment when HAL does not support the algorithm library
+ * for calibration and sensor fusion not to expose unused
+ * sysfs entries */
+#define SUPPORT_ONLY_BASIC_FEATURES
+
+/* Uncomment to read data registers for sensor data instead of FIFO */
+//#define SENSOR_DATA_FROM_REGISTERS
+
+/* Uncomment to enable timer based batching */
+#define TIMER_BASED_BATCHING
+
+/* Polling (batch mode) can be enabled only when FIFO read */
+#if defined(SENSOR_DATA_FROM_REGISTERS)
+#undef TIMER_BASED_BATCHING
+#endif
+
+/*register and associated bit definition*/
+#define REG_XA_OFFS_H 0x77
+#define REG_YA_OFFS_H 0x7A
+#define REG_ZA_OFFS_H 0x7D
+#define REG_XG_OFFS_USR_H 0x13
+#define REG_YG_OFFS_USR_H 0x15
+#define REG_ZG_OFFS_USR_H 0x17
+#define REG_SAMPLE_RATE_DIV 0x19
+
+#define REG_CONFIG 0x1A
+#define EXT_SYNC_SET 8
+
+#define REG_GYRO_CONFIG 0x1B
+#define BITS_SELF_TEST_EN 0xE0
+#define SHIFT_GYRO_FS_SEL 0x03
+
+#define REG_ACCEL_CONFIG 0x1C
+#define SHIFT_ACCEL_FS 0x03
+
+#define REG_LP_MODE_CTRL 0x1E
+#define BIT_GYRO_CYCLE_EN 0x80
+
+#define REG_ACCEL_WOM_THR 0x1F
+#define REG_ACCEL_WOM_X_THR 0x20
+#define REG_ACCEL_WOM_Y_THR 0x21
+#define REG_ACCEL_WOM_Z_THR 0x22
+
+#define REG_ACCEL_MOT_THR 0x1F
+#define REG_ACCEL_MOT_DUR 0x20
+
+#define REG_ACCEL_CONFIG_2 0x1D
+#define BIT_ACCEL_FCHOCIE_B 0x08
+
+#define REG_FIFO_EN 0x23
+#define BITS_GYRO_FIFO_EN 0x70
+#define BIT_ACCEL_FIFO_EN 0x08
+
+#define REG_FSYNC_INT 0x36
+#define BIT_FSYNC_INT 0x80
+
+#define REG_INT_PIN_CFG 0x37
+
+#define REG_INT_ENABLE 0x38
+#define BIT_WOM_X_INT_EN 0x80
+#define BIT_WOM_Y_INT_EN 0x40
+#define BIT_WOM_Z_INT_EN 0x20
+#define BIT_WOM_ALL_INT_EN 0xE0
+#define BIT_FSYNC_INT_EN 0x8
+#define BIT_DATA_RDY_EN 0x1
+
+#define REG_INT_STATUS 0x3A
+#define BIT_WOM_X_INT 0x80
+#define BIT_WOM_Y_INT 0x40
+#define BIT_WOM_Z_INT 0x20
+
+#define REG_RAW_ACCEL 0x3B
+#define REG_RAW_TEMP 0x41
+#define REG_RAW_GYRO 0x43
+#define REG_EXT_SENS_DATA_00 0x49
+#define REG_EXT_SENS_DATA_08 0x51
+#define REG_EXT_SENS_DATA_09 0x52
+
+#define REG_ACCEL_INTEL_CTRL 0x69
+#define BIT_ACCEL_INTEL_EN 0x80
+#define BIT_ACCEL_INTEL_MODE 0x40
+
+#define REG_USER_CTRL 0x6A
+#define BIT_COND_RST 0x01
+#define BIT_FIFO_RST 0x04
+#define BIT_FIFO_EN 0x40
+
+#define REG_PWR_MGMT_1 0x6B
+#define BIT_H_RESET 0x80
+#define BIT_SLEEP 0x40
+#define BIT_LP_EN 0x20
+#define BIT_CLK_PLL 0x01
+#define BIT_CLK_MASK 0x07
+
+#define REG_PWR_MGMT_2 0x6C
+#define BIT_PWR_ACCEL_STBY 0x38
+#define BIT_PWR_GYRO_STBY 0x07
+#define BIT_PWR_ALL_OFF 0x3F
+#define BIT_FIFO_LP_EN 0x80
+
+#define REG_MEM_BANK_SEL 0x6D
+#define REG_MEM_START_ADDR 0x6E
+#define REG_MEM_R_W 0x6F
+
+#define REG_FIFO_COUNT_H 0x72
+#define REG_FIFO_R_W 0x74
+#define REG_WHO_AM_I 0x75
+
+#define REG_6500_XG_ST_DATA 0x50
+#define REG_6500_XA_ST_DATA 0xD
+#define REG_6500_XA_OFFS_H 0x77
+#define REG_6500_YA_OFFS_H 0x7A
+#define REG_6500_ZA_OFFS_H 0x7D
+#define REG_6500_ACCEL_CONFIG2 0x1D
+#define BIT_ACCEL_FCHOCIE_B 0x08
+#define BIT_FIFO_SIZE_1K 0x40
+
+#define REG_LP_MODE_CFG 0x1E
+
+#define REG_6500_LP_ACCEL_ODR 0x1E
+#define REG_6500_ACCEL_WOM_THR 0x1F
+
+/* data output control reg 2 */
+#define ACCEL_ACCURACY_SET 0x4000
+#define GYRO_ACCURACY_SET 0x2000
+#define CPASS_ACCURACY_SET 0x1000
+
+/* data definitions */
+#define ACCEL_COVARIANCE 0
+#define BYTES_PER_SENSOR 6
+#define BYTES_FOR_TEMP 2
+#define FIFO_COUNT_BYTE 2
+#define HARDWARE_FIFO_SIZE 512
+#define FIFO_SIZE (HARDWARE_FIFO_SIZE * 7 / 10)
+#define POWER_UP_TIME 100
+#define REG_UP_TIME_USEC 100
+#define LEFT_OVER_BYTES 128
+#define IIO_BUFFER_BYTES 8
+#define BASE_SAMPLE_RATE 1000
+#define DRY_RUN_TIME 50
+#define INV_IAM20680_GYRO_START_TIME 35
+#define INV_IAM20680_ACCEL_START_TIME 30
+#define MODE_1K_INIT_SAMPLE 5
+#define FIRST_SAMPLE_BUF_MS 30
+
+#ifdef BIAS_CONFIDENCE_HIGH
+#define DEFAULT_ACCURACY 3
+#else
+#define DEFAULT_ACCURACY 1
+#endif
+
+/* temperature */
+#define TEMP_SENSITIVITY 32680 // 326.8 LSB/degC * 100
+#define TEMP_OFFSET 2500 // 25 degC * 100
+
+/* enum for sensor */
+enum INV_SENSORS {
+ SENSOR_ACCEL = 0,
+ SENSOR_TEMP,
+ SENSOR_GYRO,
+ SENSOR_COMPASS,
+ SENSOR_NUM_MAX,
+ SENSOR_INVALID,
+};
+
+enum inv_filter_e {
+ INV_FILTER_256HZ_NOLPF2 = 0,
+ INV_FILTER_188HZ,
+ INV_FILTER_98HZ,
+ INV_FILTER_42HZ,
+ INV_FILTER_20HZ,
+ INV_FILTER_10HZ,
+ INV_FILTER_5HZ,
+ INV_FILTER_2100HZ_NOLPF,
+ NUM_FILTER
+};
+
+#define MPU_DEFAULT_DMP_FREQ 200
+#define PEDOMETER_FREQ (MPU_DEFAULT_DMP_FREQ >> 2)
+#define SENSOR_FUSION_MIN_RATE 100
+#define GESTURE_ACCEL_RATE 50
+#define ESI_GYRO_RATE 1000
+#define MAX_FIFO_PACKET_READ 6
+#define MAX_BATCH_FIFO_SIZE FIFO_SIZE
+
+#define MIN_MST_ODR_CONFIG 4
+#define MAX_MST_ODR_CONFIG 5
+/* initial rate is important. For non-DMP mode, it is set as 4 1000/256*/
+#define MPU_INIT_SENSOR_RATE 4
+#define MAX_MST_NON_COMPASS_ODR_CONFIG 7
+#define THREE_AXES 3
+#define NINE_ELEM (THREE_AXES * THREE_AXES)
+#define MPU_TEMP_SHIFT 16
+
+#define DMP_DIVIDER (BASE_SAMPLE_RATE / MPU_DEFAULT_DMP_FREQ)
+#define DEFAULT_BATCH_RATE 400
+#define DEFAULT_BATCH_TIME (MSEC_PER_SEC / DEFAULT_BATCH_RATE)
+
+#define TEMPERATURE_SCALE 3340827L
+#define TEMPERATURE_OFFSET 1376256L
+#define SECONDARY_INIT_WAIT 100
+#define MPU_SOFT_REV_ADDR 0x86
+#define MPU_SOFT_REV_MASK 0xf
+#define SW_REV_LP_EN_MODE 4
+
+/* data limit definitions */
+#define MIN_FIFO_RATE 4
+#define MAX_FIFO_RATE MPU_DEFAULT_DMP_FREQ
+
+#define MAX_MPU_MEM 8192
+#define MAX_PRS_RATE 281
+
+enum inv_devices {
+ ICM20608D,
+ ICM20690,
+ ICM20602,
+ IAM20680,
+ INV_NUM_PARTS,
+};
+#endif
diff --git a/drivers/iio/imu/inv_mpu/iam20680/inv_mpu_init_20680.c b/drivers/iio/imu/inv_mpu/iam20680/inv_mpu_init_20680.c
new file mode 100644
index 0000000..58bd8d0
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu/iam20680/inv_mpu_init_20680.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2017-2018 InvenSense, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#define pr_fmt(fmt) "inv_mpu: " fmt
+#include "../inv_mpu_iio.h"
+
+static int inv_calc_gyro_sf(s8 pll)
+{
+ int a, r;
+ int value, t;
+
+ t = 102870L + 81L * pll;
+ a = (1L << 30) / t;
+ r = (1L << 30) - a * t;
+ value = a * 797 * DMP_DIVIDER;
+ value += (s64) ((a * 1011387LL * DMP_DIVIDER) >> 20);
+ value += r * 797L * DMP_DIVIDER / t;
+ value += (s32) ((s64) ((r * 1011387LL * DMP_DIVIDER) >> 20)) / t;
+ value <<= 1;
+
+ return value;
+}
+
+static int inv_read_timebase(struct inv_mpu_state *st)
+{
+
+ inv_plat_single_write(st, REG_CONFIG, 3);
+
+ st->eng_info[ENGINE_ACCEL].base_time = NSEC_PER_SEC;
+ st->eng_info[ENGINE_ACCEL].base_time_1k = NSEC_PER_SEC;
+ /* talor expansion to calculate base time unit */
+ st->eng_info[ENGINE_GYRO].base_time = NSEC_PER_SEC;
+ st->eng_info[ENGINE_GYRO].base_time_1k = NSEC_PER_SEC;
+ st->eng_info[ENGINE_I2C].base_time = NSEC_PER_SEC;
+ st->eng_info[ENGINE_I2C].base_time_1k = NSEC_PER_SEC;
+
+ st->eng_info[ENGINE_ACCEL].orig_rate = BASE_SAMPLE_RATE;
+ st->eng_info[ENGINE_GYRO].orig_rate = BASE_SAMPLE_RATE;
+ st->eng_info[ENGINE_I2C].orig_rate = BASE_SAMPLE_RATE;
+
+ st->gyro_sf = inv_calc_gyro_sf(0);
+
+ return 0;
+}
+
+int inv_set_gyro_sf(struct inv_mpu_state *st)
+{
+ int result;
+
+ result = inv_plat_single_write(st, REG_GYRO_CONFIG,
+ st->chip_config.fsr << SHIFT_GYRO_FS_SEL);
+
+ return result;
+}
+
+int inv_set_accel_sf(struct inv_mpu_state *st)
+{
+ int result;
+
+ result = inv_plat_single_write(st, REG_ACCEL_CONFIG,
+ st->chip_config.accel_fs << SHIFT_ACCEL_FS);
+ return result;
+}
+
+// dummy for 20602
+int inv_set_accel_intel(struct inv_mpu_state *st)
+{
+ return 0;
+}
+
+static void inv_init_sensor_struct(struct inv_mpu_state *st)
+{
+ int i;
+
+ for (i = 0; i < SENSOR_NUM_MAX; i++)
+ st->sensor[i].rate = MPU_INIT_SENSOR_RATE;
+
+ st->sensor[SENSOR_ACCEL].sample_size = BYTES_PER_SENSOR;
+ st->sensor[SENSOR_TEMP].sample_size = BYTES_FOR_TEMP;
+ st->sensor[SENSOR_GYRO].sample_size = BYTES_PER_SENSOR;
+
+ st->sensor_l[SENSOR_L_SIXQ].base = SENSOR_GYRO;
+ st->sensor_l[SENSOR_L_PEDQ].base = SENSOR_GYRO;
+
+ st->sensor_l[SENSOR_L_SIXQ_WAKE].base = SENSOR_GYRO;
+ st->sensor_l[SENSOR_L_PEDQ_WAKE].base = SENSOR_GYRO;
+
+ st->sensor[SENSOR_ACCEL].a_en = true;
+ st->sensor[SENSOR_GYRO].a_en = false;
+
+ st->sensor[SENSOR_ACCEL].g_en = false;
+ st->sensor[SENSOR_GYRO].g_en = true;
+
+ st->sensor[SENSOR_ACCEL].c_en = false;
+ st->sensor[SENSOR_GYRO].c_en = false;
+
+ st->sensor[SENSOR_ACCEL].p_en = false;
+ st->sensor[SENSOR_GYRO].p_en = false;
+
+ st->sensor[SENSOR_ACCEL].engine_base = ENGINE_ACCEL;
+ st->sensor[SENSOR_GYRO].engine_base = ENGINE_GYRO;
+
+ st->sensor_l[SENSOR_L_ACCEL].base = SENSOR_ACCEL;
+ st->sensor_l[SENSOR_L_GESTURE_ACCEL].base = SENSOR_ACCEL;
+ st->sensor_l[SENSOR_L_GYRO].base = SENSOR_GYRO;
+ st->sensor_l[SENSOR_L_GYRO_CAL].base = SENSOR_GYRO;
+ st->sensor_l[SENSOR_L_EIS_GYRO].base = SENSOR_GYRO;
+
+ st->sensor_l[SENSOR_L_ACCEL_WAKE].base = SENSOR_ACCEL;
+ st->sensor_l[SENSOR_L_GYRO_WAKE].base = SENSOR_GYRO;
+
+ st->sensor_l[SENSOR_L_GYRO_CAL_WAKE].base = SENSOR_GYRO;
+
+ st->sensor_l[SENSOR_L_ACCEL].header = ACCEL_HDR;
+ st->sensor_l[SENSOR_L_GESTURE_ACCEL].header = ACCEL_HDR;
+ st->sensor_l[SENSOR_L_GYRO].header = GYRO_HDR;
+ st->sensor_l[SENSOR_L_GYRO_CAL].header = GYRO_CALIB_HDR;
+
+ st->sensor_l[SENSOR_L_EIS_GYRO].header = EIS_GYRO_HDR;
+ st->sensor_l[SENSOR_L_SIXQ].header = SIXQUAT_HDR;
+ st->sensor_l[SENSOR_L_THREEQ].header = LPQ_HDR;
+ st->sensor_l[SENSOR_L_NINEQ].header = NINEQUAT_HDR;
+ st->sensor_l[SENSOR_L_PEDQ].header = PEDQUAT_HDR;
+
+ st->sensor_l[SENSOR_L_ACCEL_WAKE].header = ACCEL_WAKE_HDR;
+ st->sensor_l[SENSOR_L_GYRO_WAKE].header = GYRO_WAKE_HDR;
+ st->sensor_l[SENSOR_L_GYRO_CAL_WAKE].header = GYRO_CALIB_WAKE_HDR;
+ st->sensor_l[SENSOR_L_MAG_WAKE].header = COMPASS_WAKE_HDR;
+ st->sensor_l[SENSOR_L_MAG_CAL_WAKE].header = COMPASS_CALIB_WAKE_HDR;
+ st->sensor_l[SENSOR_L_SIXQ_WAKE].header = SIXQUAT_WAKE_HDR;
+ st->sensor_l[SENSOR_L_NINEQ_WAKE].header = NINEQUAT_WAKE_HDR;
+ st->sensor_l[SENSOR_L_PEDQ_WAKE].header = PEDQUAT_WAKE_HDR;
+
+ st->sensor_l[SENSOR_L_ACCEL].wake_on = false;
+ st->sensor_l[SENSOR_L_GYRO].wake_on = false;
+ st->sensor_l[SENSOR_L_GYRO_CAL].wake_on = false;
+ st->sensor_l[SENSOR_L_MAG].wake_on = false;
+ st->sensor_l[SENSOR_L_MAG_CAL].wake_on = false;
+ st->sensor_l[SENSOR_L_EIS_GYRO].wake_on = false;
+ st->sensor_l[SENSOR_L_SIXQ].wake_on = false;
+ st->sensor_l[SENSOR_L_NINEQ].wake_on = false;
+ st->sensor_l[SENSOR_L_PEDQ].wake_on = false;
+
+ st->sensor_l[SENSOR_L_ACCEL_WAKE].wake_on = true;
+ st->sensor_l[SENSOR_L_GYRO_WAKE].wake_on = true;
+ st->sensor_l[SENSOR_L_GYRO_CAL_WAKE].wake_on = true;
+ st->sensor_l[SENSOR_L_MAG_WAKE].wake_on = true;
+ st->sensor_l[SENSOR_L_SIXQ_WAKE].wake_on = true;
+ st->sensor_l[SENSOR_L_NINEQ_WAKE].wake_on = true;
+ st->sensor_l[SENSOR_L_PEDQ_WAKE].wake_on = true;
+}
+
+static int inv_init_config(struct inv_mpu_state *st)
+{
+ int res, i;
+
+ st->batch.overflow_on = 0;
+ st->chip_config.fsr = MPU_INIT_GYRO_SCALE;
+ st->chip_config.accel_fs = MPU_INIT_ACCEL_SCALE;
+ st->ped.int_thresh = MPU_INIT_PED_INT_THRESH;
+ st->ped.step_thresh = MPU_INIT_PED_STEP_THRESH;
+ st->chip_config.low_power_gyro_on = 1;
+ st->eis.count_precision = NSEC_PER_MSEC;
+ st->firmware = 0;
+ st->fifo_count_mode = BYTE_MODE;
+#ifdef TIMER_BASED_BATCHING
+ st->batch_timeout = 0;
+ st->is_batch_timer_running = false;
+#endif
+
+ st->eng_info[ENGINE_GYRO].base_time = NSEC_PER_SEC;
+ st->eng_info[ENGINE_ACCEL].base_time = NSEC_PER_SEC;
+
+ inv_init_sensor_struct(st);
+ res = inv_read_timebase(st);
+ if (res)
+ return res;
+
+ res = inv_set_gyro_sf(st);
+ if (res)
+ return res;
+ res = inv_set_accel_sf(st);
+ if (res)
+ return res;
+ res = inv_set_accel_intel(st);
+ if (res)
+ return res;
+
+ for (i = 0; i < SENSOR_NUM_MAX; i++)
+ st->sensor[i].ts = 0;
+
+ for (i = 0; i < SENSOR_NUM_MAX; i++)
+ st->sensor[i].previous_ts = 0;
+
+ return res;
+}
+
+int inv_mpu_initialize(struct inv_mpu_state *st)
+{
+ u8 v;
+ int result;
+ struct inv_chip_config_s *conf;
+ struct mpu_platform_data *plat;
+
+ conf = &st->chip_config;
+ plat = &st->plat_data;
+
+ /* verify whoami */
+ result = inv_plat_read(st, REG_WHO_AM_I, 1, &v);
+ if (result)
+ return result;
+ pr_info("whoami= %x\n", v);
+ if (v == 0x00 || v == 0xff)
+ return -ENODEV;
+
+ /* reset to make sure previous state are not there */
+ result = inv_plat_single_write(st, REG_PWR_MGMT_1, BIT_H_RESET);
+ if (result)
+ return result;
+ usleep_range(REG_UP_TIME_USEC, REG_UP_TIME_USEC);
+ msleep(100);
+ /* toggle power state */
+ result = inv_set_power(st, false);
+ if (result)
+ return result;
+ result = inv_set_power(st, true);
+ if (result)
+ return result;
+
+ result = inv_plat_single_write(st, REG_USER_CTRL, st->i2c_dis);
+ if (result)
+ return result;
+ result = inv_init_config(st);
+ if (result)
+ return result;
+
+ result = mem_r(MPU_SOFT_REV_ADDR, 1, &v);
+ pr_info("sw_rev=%x, res=%d\n", v, result);
+ if (result)
+ return result;
+ st->chip_config.lp_en_mode_off = 0;
+
+ pr_info("%s: Mask %X, v = %X, lp mode = %d\n", __func__,
+ MPU_SOFT_REV_MASK, v, st->chip_config.lp_en_mode_off);
+ result = inv_set_power(st, false);
+
+ pr_info("%s: initialize result is %d....\n", __func__, result);
+ return 0;
+}
diff --git a/drivers/iio/imu/inv_mpu/iam20680/inv_mpu_parsing_20680.c b/drivers/iio/imu/inv_mpu/iam20680/inv_mpu_parsing_20680.c
new file mode 100644
index 0000000..0f17b6d
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu/iam20680/inv_mpu_parsing_20680.c
@@ -0,0 +1,421 @@
+/*
+ * Copyright (C) 2017-2018 InvenSense, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#define pr_fmt(fmt) "inv_mpu: " fmt
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/sysfs.h>
+#include <linux/jiffies.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/kfifo.h>
+#include <linux/poll.h>
+#include <linux/miscdevice.h>
+#include <linux/math64.h>
+
+#include "../inv_mpu_iio.h"
+
+static char iden[] = { 1, 0, 0, 0, 1, 0, 0, 0, 1 };
+
+static int inv_process_gyro(struct inv_mpu_state *st, u8 *d, u64 t)
+{
+ s16 raw[3];
+ s32 calib[3];
+ int i;
+#define BIAS_UNIT 2859
+
+ for (i = 0; i < 3; i++)
+ raw[i] = be16_to_cpup((__be16 *) (d + i * 2));
+
+ for (i = 0; i < 3; i++)
+ calib[i] = (raw[i] << 15);
+
+
+ inv_push_gyro_data(st, raw, calib, t);
+
+ return 0;
+}
+
+static int inv_check_fsync(struct inv_mpu_state *st, u8 fsync_status)
+{
+ u8 data[1];
+
+ if (!st->chip_config.eis_enable)
+ return 0;
+ inv_plat_read(st, REG_FSYNC_INT, 1, data);
+ if (data[0] & BIT_FSYNC_INT) {
+ pr_debug("fsync\n");
+ st->eis.eis_triggered = true;
+ st->eis.fsync_delay = 1;
+ st->eis.prev_state = 1;
+ st->eis.frame_count++;
+ st->eis.eis_frame = true;
+ }
+ st->header_count--;
+
+ return 0;
+}
+
+static int inv_push_sensor(struct inv_mpu_state *st, int ind, u64 t, u8 *d)
+{
+#ifdef ACCEL_BIAS_TEST
+ s16 acc[3], avg[3];
+#endif
+
+ switch (ind) {
+ case SENSOR_ACCEL:
+ inv_convert_and_push_8bytes(st, ind, d, t, iden);
+#ifdef ACCEL_BIAS_TEST
+ acc[0] = be16_to_cpup((__be16 *) (d));
+ acc[1] = be16_to_cpup((__be16 *) (d + 2));
+ acc[2] = be16_to_cpup((__be16 *) (d + 4));
+ if(inv_get_3axis_average(acc, avg, 0)){
+ pr_debug("accel 200 samples average = %5d, %5d, %5d\n", avg[0], avg[1], avg[2]);
+ }
+#endif
+ break;
+ case SENSOR_TEMP:
+ inv_check_fsync(st, d[1]);
+ break;
+ case SENSOR_GYRO:
+ inv_process_gyro(st, d, t);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int inv_push_20680_data(struct inv_mpu_state *st, u8 *d)
+{
+ u8 *dptr;
+ int i;
+
+ dptr = d;
+
+ for (i = 0; i < SENSOR_NUM_MAX; i++) {
+ if (st->sensor[i].on) {
+ inv_get_dmp_ts(st, i);
+ if (st->sensor[i].send && (!st->ts_algo.first_sample)) {
+ st->sensor[i].sample_calib++;
+ inv_push_sensor(st, i, st->sensor[i].ts, dptr);
+ }
+ dptr += st->sensor[i].sample_size;
+ }
+ }
+ if (st->ts_algo.first_sample)
+ st->ts_algo.first_sample--;
+ st->header_count--;
+
+ return 0;
+}
+
+static int inv_process_20680_data(struct inv_mpu_state *st)
+{
+ int total_bytes, tmp, res, fifo_count, pk_size, i;
+ u8 *dptr, *d;
+ u8 data[14];
+ bool done_flag;
+ u8 v;
+#ifdef SENSOR_DATA_FROM_REGISTERS
+ u8 reg;
+ int len;
+#endif
+
+ if(st->gesture_only_on && (!st->batch.timeout)) {
+ res = inv_plat_read(st, REG_INT_STATUS, 1, data);
+ if (res)
+ return res;
+ pr_debug("ges cnt=%d, statu=%x\n",
+ st->gesture_int_count, data[0]);
+ if (data[0] & (BIT_WOM_ALL_INT_EN)) {
+ if (!st->gesture_int_count) {
+ inv_switch_power_in_lp(st, true);
+ res = inv_plat_single_write(st, REG_INT_ENABLE,
+ BIT_WOM_ALL_INT_EN | BIT_DATA_RDY_EN);
+ if (res)
+ return res;
+ v = 0;
+ if (st->chip_config.gyro_enable)
+ v |= BITS_GYRO_FIFO_EN;
+
+ if (st->chip_config.accel_enable)
+ v |= BIT_ACCEL_FIFO_EN;
+ res = inv_plat_single_write(st, REG_FIFO_EN, v);
+ if (res)
+ return res;
+ /* First time wake up from WOM.
+ We don't need data in the FIFO */
+ res = inv_reset_fifo(st, true);
+ if (res)
+ return res;
+ res = inv_switch_power_in_lp(st, false);
+ st->gesture_int_count = WOM_DELAY_THRESHOLD;
+
+ return res;
+ }
+ st->gesture_int_count = WOM_DELAY_THRESHOLD;
+ } else {
+ if (!st->gesture_int_count) {
+ inv_switch_power_in_lp(st, true);
+ res = inv_plat_single_write(st, REG_FIFO_EN, 0);
+ res = inv_plat_single_write(st, REG_INT_ENABLE,
+ BIT_WOM_ALL_INT_EN);
+ inv_switch_power_in_lp(st, false);
+
+ return res;
+ }
+ st->gesture_int_count--;
+ }
+ }
+
+ fifo_count = inv_get_last_run_time_non_dmp_record_mode(st);
+ pr_debug("fifc= %d\n", fifo_count);
+ if (!fifo_count) {
+ pr_debug("REG_FIFO_COUNT_H size is 0\n");
+ return 0;
+ }
+ pk_size = st->batch.pk_size;
+ if (!pk_size)
+ return -EINVAL;
+
+ if (fifo_count >= (HARDWARE_FIFO_SIZE / st->batch.pk_size)) {
+ pr_warn("fifo overflow pkt count=%d pkt sz=%d\n", fifo_count, st->batch.pk_size);
+ return -EOVERFLOW;
+ }
+
+ fifo_count *= st->batch.pk_size;
+ st->fifo_count = fifo_count;
+ d = st->fifo_data_store;
+ dptr = d;
+ total_bytes = fifo_count;
+
+#ifdef SENSOR_DATA_FROM_REGISTERS
+ len = 0;
+ if (st->sensor[SENSOR_GYRO].on) {
+ reg = REG_RAW_GYRO;
+ len += BYTES_PER_SENSOR;
+ if (st->sensor[SENSOR_ACCEL].on && !st->sensor[SENSOR_TEMP].on)
+ len += BYTES_FOR_TEMP;
+ }
+ if (st->sensor[SENSOR_TEMP].on) {
+ reg = REG_RAW_TEMP;
+ len += BYTES_FOR_TEMP;
+ }
+ if (st->sensor[SENSOR_ACCEL].on) {
+ reg = REG_RAW_ACCEL;
+ len += BYTES_PER_SENSOR;
+ }
+
+ if (len == 0) {
+ pr_debug("No sensor is enabled\n");
+ return 0;
+ }
+
+ /* read data registers */
+ res = inv_plat_read(st, reg, len, data);
+ if (res < 0) {
+ pr_err("read data registers is failed\n");
+ return res;
+ }
+
+ /* copy sensor data to buffer as FIFO data format */
+ tmp = 0;
+ if (st->sensor[SENSOR_ACCEL].on) {
+ for (i = 0; i < BYTES_PER_SENSOR; i++)
+ dptr[i] = data[tmp + i];
+ dptr += BYTES_PER_SENSOR;
+ tmp += BYTES_PER_SENSOR;
+ }
+
+ if (st->sensor[SENSOR_TEMP].on) {
+ for (i = 0; i < BYTES_FOR_TEMP; i++)
+ dptr[i] = data[tmp + i];
+ dptr += BYTES_FOR_TEMP;
+ tmp += BYTES_FOR_TEMP;
+ }
+
+ if (st->sensor[SENSOR_GYRO].on) {
+ if (st->sensor[SENSOR_ACCEL].on && !st->sensor[SENSOR_TEMP].on)
+ tmp += BYTES_FOR_TEMP;
+ for (i = 0; i < BYTES_PER_SENSOR; i++)
+ dptr[i] = data[tmp + i];
+ }
+#else
+ while (total_bytes > 0) {
+ if (total_bytes < pk_size * MAX_FIFO_PACKET_READ)
+ tmp = total_bytes;
+ else
+ tmp = pk_size * MAX_FIFO_PACKET_READ;
+ res = inv_plat_read(st, REG_FIFO_R_W, tmp, dptr);
+ if (res < 0) {
+ pr_err("read REG_FIFO_R_W is failed\n");
+ return res;
+ }
+ pr_debug("inside: %x, %x, %x, %x, %x, %x, %x, %x\n", dptr[0], dptr[1], dptr[2],
+ dptr[3], dptr[4], dptr[5], dptr[6], dptr[7]);
+ pr_debug("insid2: %x, %x, %x, %x, %x, %x, %x, %x\n", dptr[8], dptr[9], dptr[10],
+ dptr[11], dptr[12], dptr[13], dptr[14], dptr[15]);
+
+ dptr += tmp;
+ total_bytes -= tmp;
+ }
+#endif /* SENSOR_DATA_FROM_REGISTERS */
+ dptr = d;
+ pr_debug("dd: %x, %x, %x, %x, %x, %x, %x, %x\n", d[0], d[1], d[2],
+ d[3], d[4], d[5], d[6], d[7]);
+ pr_debug("dd2: %x, %x, %x, %x, %x, %x, %x, %x\n", d[8], d[9], d[10],
+ d[11], d[12], d[13], d[14], d[15]);
+ total_bytes = fifo_count;
+
+ for (i = 0; i < SENSOR_NUM_MAX; i++) {
+ if (st->sensor[i].on) {
+ st->sensor[i].count = total_bytes / pk_size;
+ }
+ }
+ st->header_count = 0;
+ for (i = 0; i < SENSOR_NUM_MAX; i++) {
+ if (st->sensor[i].on)
+ st->header_count = max(st->header_count,
+ st->sensor[i].count);
+ }
+
+ st->ts_algo.calib_counter++;
+ inv_bound_timestamp(st);
+
+ dptr = d;
+ done_flag = false;
+
+ while (!done_flag) {
+ pr_debug("total%d, pk=%d\n", total_bytes, pk_size);
+ if (total_bytes >= pk_size) {
+ res = inv_push_20680_data(st, dptr);
+ if (res)
+ return res;
+ total_bytes -= pk_size;
+ dptr += pk_size;
+ } else {
+ done_flag = true;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * _inv_read_fifo() - Transfer data from FIFO to ring buffer.
+ */
+static void _inv_read_fifo(struct inv_mpu_state *st)
+{
+ struct iio_dev *indio_dev = iio_priv_to_dev(st);
+ int result;
+
+ result = wait_event_interruptible_timeout(st->wait_queue,
+ st->resume_state, msecs_to_jiffies(300));
+ if (result <= 0)
+ return;
+ mutex_lock(&indio_dev->mlock);
+#ifdef TIMER_BASED_BATCHING
+ if (st->batch_timeout) {
+ if (inv_plat_single_write(st, REG_INT_ENABLE, st->int_en))
+ pr_err("REG_INT_ENABLE write error\n");
+ }
+#endif
+ st->wake_sensor_received = false;
+ result = inv_process_20680_data(st);
+ if (result)
+ goto err_reset_fifo;
+ mutex_unlock(&indio_dev->mlock);
+
+ if (st->wake_sensor_received)
+#ifdef CONFIG_HAS_WAKELOCK
+ wake_lock_timeout(&st->wake_lock, msecs_to_jiffies(200));
+#else
+ __pm_wakeup_event(&st->wake_lock, 200); /* 200 msecs */
+#endif
+ return;
+
+err_reset_fifo:
+ if ((!st->chip_config.gyro_enable) &&
+ (!st->chip_config.accel_enable) &&
+ (!st->chip_config.slave_enable) &&
+ (!st->chip_config.pressure_enable)) {
+ inv_switch_power_in_lp(st, false);
+ mutex_unlock(&indio_dev->mlock);
+
+ return;
+ }
+
+ pr_err("error to reset fifo\n");
+ inv_switch_power_in_lp(st, true);
+ inv_reset_fifo(st, true);
+ inv_switch_power_in_lp(st, false);
+ mutex_unlock(&indio_dev->mlock);
+
+ return;
+}
+
+irqreturn_t inv_read_fifo(int irq, void *dev_id)
+{
+ struct inv_mpu_state *st = (struct inv_mpu_state *)dev_id;
+
+ _inv_read_fifo(st);
+
+ return IRQ_HANDLED;
+}
+
+#ifdef TIMER_BASED_BATCHING
+void inv_batch_work(struct work_struct *work)
+{
+ struct inv_mpu_state *st =
+ container_of(work, struct inv_mpu_state, batch_work);
+ struct iio_dev *indio_dev = iio_priv_to_dev(st);
+
+ mutex_lock(&indio_dev->mlock);
+ if (inv_plat_single_write(st, REG_INT_ENABLE, st->int_en | BIT_DATA_RDY_EN))
+ pr_err("REG_INT_ENABLE write error\n");
+ mutex_unlock(&indio_dev->mlock);
+
+ return;
+}
+#endif
+
+int inv_flush_batch_data(struct iio_dev *indio_dev, int data)
+{
+ struct inv_mpu_state *st = iio_priv(indio_dev);
+
+#ifndef SENSOR_DATA_FROM_REGISTERS
+ if (st->chip_config.gyro_enable ||
+ st->chip_config.accel_enable ||
+ st->chip_config.slave_enable ||
+ st->chip_config.pressure_enable) {
+ st->wake_sensor_received = 0;
+ inv_process_20680_data(st);
+ if (st->wake_sensor_received)
+#ifdef CONFIG_HAS_WAKELOCK
+ wake_lock_timeout(&st->wake_lock, msecs_to_jiffies(200));
+#else
+ __pm_wakeup_event(&st->wake_lock, 200); /* 200 msecs */
+#endif
+ inv_switch_power_in_lp(st, false);
+ }
+#endif /* SENSOR_DATA_FROM_REGISTERS */
+ inv_push_marker_to_buffer(st, END_MARKER, data);
+
+ return 0;
+}
+
diff --git a/drivers/iio/imu/inv_mpu/iam20680/inv_mpu_selftest_20680.c b/drivers/iio/imu/inv_mpu/iam20680/inv_mpu_selftest_20680.c
new file mode 100644
index 0000000..7a90b4d
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu/iam20680/inv_mpu_selftest_20680.c
@@ -0,0 +1,752 @@
+/*
+* Copyright (C) 2017-2018 InvenSense, Inc.
+*
+* This software is licensed under the terms of the GNU General Public
+* License version 2, as published by the Free Software Foundation, and
+* may be copied, distributed, and modified under those terms.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*/
+#define pr_fmt(fmt) "inv_mpu: " fmt
+
+#include "../inv_mpu_iio.h"
+
+/* register settings */
+#define DEF_SELFTEST_GYRO_SENS (32768 / 250)
+/* wait time before collecting data */
+#define MAX_PACKETS 20
+#define SELFTEST_WAIT_TIME (MAX_PACKETS * 10)
+#define DEF_ST_STABLE_TIME 20
+#define DEF_GYRO_SCALE 131
+#define DEF_ST_PRECISION 1000
+#define DEF_ST_ACCEL_FS_MG 2000UL
+#define DEF_ST_SCALE 32768
+#define DEF_ST_TRY_TIMES 2
+#define DEF_ST_ACCEL_RESULT_SHIFT 1
+#define DEF_ST_SAMPLES 200
+
+#define DEF_ACCEL_ST_SHIFT_DELTA_MIN 500
+#define DEF_ACCEL_ST_SHIFT_DELTA_MAX 1500
+#define DEF_GYRO_CT_SHIFT_DELTA 500
+
+#define SENSOR_UP_TIME 30
+#define REG_UP_TIME 2
+
+#define DEF_ST_ACCEL_FS_MG 2000UL
+#define DEF_ACCEL_ST_SHIFT_DELTA 500
+#define ACCEL_ST_AL_MIN ((DEF_ACCEL_ST_AL_MIN * DEF_ST_SCALE \
+ / DEF_ST_ACCEL_FS_MG) * DEF_ST_PRECISION)
+#define ACCEL_ST_AL_MAX ((DEF_ACCEL_ST_AL_MAX * DEF_ST_SCALE \
+ / DEF_ST_ACCEL_FS_MG) * DEF_ST_PRECISION)
+
+#define THREE_AXIS 3
+#define DEF_ST_MPU6500_ACCEL_LPF 2
+#define DEF_SELFTEST_SAMPLE_RATE 0 /* 1000Hz */
+#define DEF_SELFTEST_SAMPLE_RATE_LP 3 /* 250Hz */
+#define DEF_SELFTEST_SAMPLE_RATE_ACC_LP 10 /* 250Hz LPOSC_CLKSEL */
+#define INV_MPU_SAMPLE_RATE_CHANGE_STABLE 50
+#define DEF_SELFTEST_6500_ACCEL_FS (0 << 3)
+#define DEF_SELFTEST_GYRO_FS (0 << 3)
+#define DEF_ST_6500_STABLE_TIME 20
+#define BIT_ACCEL_OUT 0x08
+#define BITS_GYRO_OUT 0x70
+#define THREE_AXIS 3
+#define DEF_GYRO_WAIT_TIME 10
+#define DEF_GYRO_WAIT_TIME_LP 50
+
+/* Gyro Offset Max Value (dps) */
+#define DEF_GYRO_OFFSET_MAX 20
+/* Gyro Self Test Absolute Limits ST_AL (dps) */
+#define DEF_GYRO_ST_AL 60
+/* Accel Self Test Absolute Limits ST_AL (mg) */
+#define DEF_ACCEL_ST_AL_MIN 225
+#define DEF_ACCEL_ST_AL_MAX 675
+
+struct recover_regs {
+ u8 int_enable; /* REG_INT_ENABLE */
+ u8 fifo_en; /* REG_FIFO_EN */
+ u8 user_ctrl; /* REG_USER_CTRL */
+ u8 config; /* REG_CONFIG */
+ u8 gyro_config; /* REG_GYRO_CONFIG */
+ u8 accel_config; /* REG_ACCEL_CONFIG */
+ u8 accel_config_2; /* REG_ACCEL_CONFIG_2 */
+ u8 smplrt_div; /* REG_SAMPLE_RATE_DIV */
+ u8 lp_mode; /* REG_LP_MODE_CTRL */
+ u8 pwr_mgmt_1; /* REG_PWR_MGMT_1 */
+ u8 pwr_mgmt_2; /* REG_PWR_MGMT_2 */
+};
+
+static struct recover_regs saved_regs;
+
+static const u16 mpu_st_tb[256] = {
+ 2620, 2646, 2672, 2699, 2726, 2753, 2781, 2808,
+ 2837, 2865, 2894, 2923, 2952, 2981, 3011, 3041,
+ 3072, 3102, 3133, 3165, 3196, 3228, 3261, 3293,
+ 3326, 3359, 3393, 3427, 3461, 3496, 3531, 3566,
+ 3602, 3638, 3674, 3711, 3748, 3786, 3823, 3862,
+ 3900, 3939, 3979, 4019, 4059, 4099, 4140, 4182,
+ 4224, 4266, 4308, 4352, 4395, 4439, 4483, 4528,
+ 4574, 4619, 4665, 4712, 4759, 4807, 4855, 4903,
+ 4953, 5002, 5052, 5103, 5154, 5205, 5257, 5310,
+ 5363, 5417, 5471, 5525, 5581, 5636, 5693, 5750,
+ 5807, 5865, 5924, 5983, 6043, 6104, 6165, 6226,
+ 6289, 6351, 6415, 6479, 6544, 6609, 6675, 6742,
+ 6810, 6878, 6946, 7016, 7086, 7157, 7229, 7301,
+ 7374, 7448, 7522, 7597, 7673, 7750, 7828, 7906,
+ 7985, 8065, 8145, 8227, 8309, 8392, 8476, 8561,
+ 8647, 8733, 8820, 8909, 8998, 9088, 9178, 9270,
+ 9363, 9457, 9551, 9647, 9743, 9841, 9939, 10038,
+ 10139, 10240, 10343, 10446, 10550, 10656, 10763, 10870,
+ 10979, 11089, 11200, 11312, 11425, 11539, 11654, 11771,
+ 11889, 12008, 12128, 12249, 12371, 12495, 12620, 12746,
+ 12874, 13002, 13132, 13264, 13396, 13530, 13666, 13802,
+ 13940, 14080, 14221, 14363, 14506, 14652, 14798, 14946,
+ 15096, 15247, 15399, 15553, 15709, 15866, 16024, 16184,
+ 16346, 16510, 16675, 16842, 17010, 17180, 17352, 17526,
+ 17701, 17878, 18057, 18237, 18420, 18604, 18790, 18978,
+ 19167, 19359, 19553, 19748, 19946, 20145, 20347, 20550,
+ 20756, 20963, 21173, 21385, 21598, 21814, 22033, 22253,
+ 22475, 22700, 22927, 23156, 23388, 23622, 23858, 24097,
+ 24338, 24581, 24827, 25075, 25326, 25579, 25835, 26093,
+ 26354, 26618, 26884, 27153, 27424, 27699, 27976, 28255,
+ 28538, 28823, 29112, 29403, 29697, 29994, 30294, 30597,
+ 30903, 31212, 31524, 31839, 32157, 32479, 32804
+};
+
+static void inv_show_saved_setting(struct inv_mpu_state *st)
+{
+ pr_debug(" REG_INT_ENABLE : 0x%02X\n", saved_regs.int_enable);
+ pr_debug(" REG_FIFO_EN : 0x%02X\n", saved_regs.fifo_en);
+ pr_debug(" REG_USER_CTRL : 0x%02X\n", saved_regs.user_ctrl);
+ pr_debug(" REG_CONFIG : 0x%02X\n", saved_regs.config);
+ pr_debug(" REG_GYRO_CONFIG : 0x%02X\n", saved_regs.gyro_config);
+ pr_debug(" REG_ACCEL_CONFIG : 0x%02X\n", saved_regs.accel_config);
+ pr_debug(" REG_ACCEL_CONFIG_2 : 0x%02X\n", saved_regs.accel_config_2);
+ pr_debug(" REG_SAMPLE_RATE_DIV : 0x%02X\n", saved_regs.smplrt_div);
+ pr_debug(" REG_LP_MODE_CTRL : 0x%02X\n", saved_regs.lp_mode);
+ pr_debug(" REG_PWR_MGMT_1 : 0x%02X\n", saved_regs.pwr_mgmt_1);
+ pr_debug(" REG_PWR_MGMT_2 : 0x%02X\n", saved_regs.pwr_mgmt_2);
+}
+
+static int inv_save_setting(struct inv_mpu_state *st)
+{
+ int result;
+
+ result = inv_plat_read(st, REG_PWR_MGMT_1, 1,
+ &saved_regs.pwr_mgmt_1);
+ if (result)
+ return result;
+
+ /* wake up */
+ result = inv_plat_single_write(st, REG_PWR_MGMT_1,
+ (saved_regs.pwr_mgmt_1 & ~BIT_SLEEP));
+ if (result)
+ return result;
+
+ result = inv_plat_read(st, REG_INT_ENABLE, 1,
+ &saved_regs.int_enable);
+ if (result)
+ return result;
+ result = inv_plat_read(st, REG_FIFO_EN, 1,
+ &saved_regs.fifo_en);
+ if (result)
+ return result;
+ result = inv_plat_read(st, REG_USER_CTRL, 1,
+ &saved_regs.user_ctrl);
+ if (result)
+ return result;
+ result = inv_plat_read(st, REG_CONFIG, 1,
+ &saved_regs.config);
+ if (result)
+ return result;
+ result = inv_plat_read(st, REG_GYRO_CONFIG, 1,
+ &saved_regs.gyro_config);
+ if (result)
+ return result;
+ result = inv_plat_read(st, REG_ACCEL_CONFIG, 1,
+ &saved_regs.accel_config);
+ if (result)
+ return result;
+ result = inv_plat_read(st, REG_ACCEL_CONFIG_2, 1,
+ &saved_regs.accel_config_2);
+ if (result)
+ return result;
+ result = inv_plat_read(st, REG_SAMPLE_RATE_DIV, 1,
+ &saved_regs.smplrt_div);
+ if (result)
+ return result;
+ result = inv_plat_read(st, REG_LP_MODE_CTRL, 1,
+ &saved_regs.lp_mode);
+ if (result)
+ return result;
+ result = inv_plat_read(st, REG_PWR_MGMT_2, 1,
+ &saved_regs.pwr_mgmt_2);
+ if (result)
+ return result;
+
+ inv_show_saved_setting(st);
+
+ return result;
+}
+
+static int inv_recover_setting(struct inv_mpu_state *st)
+{
+ int result;
+ /* Stop sensors */
+ result = inv_plat_single_write(st, REG_PWR_MGMT_2,
+ BIT_PWR_ACCEL_STBY | BIT_PWR_GYRO_STBY);
+ if (result)
+ return result;
+
+ /* Restore sensor configurations */
+ result = inv_plat_single_write(st, REG_INT_ENABLE,
+ saved_regs.int_enable);
+ if (result)
+ return result;
+ result = inv_plat_single_write(st, REG_FIFO_EN,
+ saved_regs.fifo_en);
+ if (result)
+ return result;
+ result = inv_plat_single_write(st, REG_USER_CTRL,
+ saved_regs.user_ctrl);
+ if (result)
+ return result;
+ result = inv_plat_single_write(st, REG_CONFIG,
+ saved_regs.config);
+ if (result)
+ return result;
+ result = inv_plat_single_write(st, REG_GYRO_CONFIG,
+ saved_regs.gyro_config);
+ if (result)
+ return result;
+ result = inv_plat_single_write(st, REG_ACCEL_CONFIG,
+ saved_regs.accel_config);
+ if (result)
+ return result;
+ result = inv_plat_single_write(st, REG_ACCEL_CONFIG_2,
+ saved_regs.accel_config_2);
+ if (result)
+ return result;
+ result = inv_plat_single_write(st, REG_SAMPLE_RATE_DIV,
+ saved_regs.smplrt_div);
+ if (result)
+ return result;
+ result = inv_plat_single_write(st, REG_LP_MODE_CTRL,
+ saved_regs.lp_mode);
+ if (result)
+ return result;
+ result = inv_plat_single_write(st, REG_PWR_MGMT_1,
+ saved_regs.pwr_mgmt_1);
+ if (result)
+ return result;
+
+ result = inv_plat_single_write(st, REG_PWR_MGMT_2,
+ saved_regs.pwr_mgmt_2);
+ if (result)
+ return result;
+
+ return result;
+}
+
+int inv_switch_engine(struct inv_mpu_state *st, bool en, u32 mask)
+{
+ u8 data, mgmt_1;
+ int result;
+
+ if (BIT_PWR_GYRO_STBY == mask) {
+ result = inv_plat_read(st, REG_PWR_MGMT_1, 1, &mgmt_1);
+ if (result)
+ return result;
+ mgmt_1 &= ~BIT_CLK_MASK;
+ }
+
+ if ((BIT_PWR_GYRO_STBY == mask) && (!en)) {
+ result = inv_plat_single_write(st, REG_PWR_MGMT_1, mgmt_1);
+ if (result)
+ return result;
+ }
+
+ result = inv_plat_read(st, REG_PWR_MGMT_2, 1, &data);
+ if (result)
+ return result;
+ if (en)
+ data &= (~mask);
+ else
+ data |= mask;
+ data |= BIT_FIFO_LP_EN;
+ result = inv_plat_single_write(st, REG_PWR_MGMT_2, data);
+ if (result)
+ return result;
+
+ if ((BIT_PWR_GYRO_STBY == mask) && en) {
+ /* only gyro on needs sensor up time */
+ msleep(SENSOR_UP_TIME);
+ /* after gyro is on & stable, switch internal clock to PLL */
+ mgmt_1 |= BIT_CLK_PLL;
+ result = inv_plat_single_write(st, REG_PWR_MGMT_1, mgmt_1);
+ if (result)
+ return result;
+ }
+ if ((BIT_PWR_ACCEL_STBY == mask) && en)
+ msleep(REG_UP_TIME);
+
+ return 0;
+}
+
+int inv_set_offset_reg(struct inv_mpu_state *st, int reg, int val)
+{
+ int result;
+ u8 d;
+
+ d = ((val >> 8) & 0xff);
+ result = inv_plat_single_write(st, reg, d);
+ if (result)
+ return result;
+
+ d = (val & 0xff);
+ result = inv_plat_single_write(st, reg + 1, d);
+
+ return result;
+}
+
+/**
+* inv_check_gyro_self_test() - check gyro self test. this function
+* returns zero as success. A non-zero return
+* value indicates failure in self test.
+* @*st: main data structure.
+* @*reg_avg: average value of normal test.
+* @*st_avg: average value of self test
+*/
+int inv_check_gyro_self_test(struct inv_mpu_state *st,
+ int *reg_avg, int *st_avg) {
+ u8 regs[3];
+ int ret_val, result;
+ int otp_value_zero = 0;
+ int st_shift_prod[3], st_shift_cust[3], i;
+
+ ret_val = 0;
+ result = inv_plat_read(st, REG_6500_XG_ST_DATA, 3, regs);
+ if (result)
+ return result;
+ pr_debug("%s self_test gyro shift_code - %02x %02x %02x\n",
+ st->hw->name, regs[0], regs[1], regs[2]);
+
+ for (i = 0; i < 3; i++) {
+ if (regs[i] != 0) {
+ st_shift_prod[i] = mpu_st_tb[regs[i] - 1];
+ } else {
+ st_shift_prod[i] = 0;
+ otp_value_zero = 1;
+ }
+ }
+ pr_debug("%s self_test gyro st_shift_prod - %+d %+d %+d\n",
+ st->hw->name, st_shift_prod[0], st_shift_prod[1],
+ st_shift_prod[2]);
+
+ for (i = 0; i < 3; i++) {
+ st_shift_cust[i] = st_avg[i] - reg_avg[i];
+ if (!otp_value_zero) {
+ /* Self Test Pass/Fail Criteria A */
+ if (st_shift_cust[i] < DEF_GYRO_CT_SHIFT_DELTA
+ * st_shift_prod[i])
+ ret_val = 1;
+ } else {
+ /* Self Test Pass/Fail Criteria B */
+ if (st_shift_cust[i] < DEF_GYRO_ST_AL *
+ DEF_SELFTEST_GYRO_SENS *
+ DEF_ST_PRECISION)
+ ret_val = 1;
+ }
+ }
+ pr_debug("%s self_test gyro st_shift_cust - %+d %+d %+d\n",
+ st->hw->name, st_shift_cust[0], st_shift_cust[1],
+ st_shift_cust[2]);
+
+ if (ret_val == 0) {
+ /* Self Test Pass/Fail Criteria C */
+ for (i = 0; i < 3; i++)
+ if (abs(reg_avg[i]) > DEF_GYRO_OFFSET_MAX *
+ DEF_SELFTEST_GYRO_SENS *
+ DEF_ST_PRECISION)
+ ret_val = 1;
+ }
+
+ return ret_val;
+}
+
+/**
+* inv_check_accel_self_test() - check 6500 accel self test. this function
+* returns zero as success. A non-zero return
+* value indicates failure in self test.
+* @*st: main data structure.
+* @*reg_avg: average value of normal test.
+* @*st_avg: average value of self test
+*/
+int inv_check_accel_self_test(struct inv_mpu_state *st,
+ int *reg_avg, int *st_avg) {
+ int ret_val, result;
+ int st_shift_prod[3], st_shift_cust[3], st_shift_ratio[3], i;
+ u8 regs[3];
+ int otp_value_zero = 0;
+
+ ret_val = 0;
+ result = inv_plat_read(st, REG_6500_XA_ST_DATA, 3, regs);
+ if (result)
+ return result;
+ pr_debug("%s self_test accel shift_code - %02x %02x %02x\n",
+ st->hw->name, regs[0], regs[1], regs[2]);
+
+ for (i = 0; i < 3; i++) {
+ if (regs[i] != 0) {
+ st_shift_prod[i] = mpu_st_tb[regs[i] - 1];
+ } else {
+ st_shift_prod[i] = 0;
+ otp_value_zero = 1;
+ }
+ }
+ pr_debug("%s self_test accel st_shift_prod - %+d %+d %+d\n",
+ st->hw->name, st_shift_prod[0], st_shift_prod[1],
+ st_shift_prod[2]);
+
+ if (!otp_value_zero) {
+ /* Self Test Pass/Fail Criteria A */
+ for (i = 0; i < 3; i++) {
+ st_shift_cust[i] = st_avg[i] - reg_avg[i];
+ st_shift_ratio[i] = abs(st_shift_cust[i] /
+ st_shift_prod[i] - DEF_ST_PRECISION);
+ if (st_shift_ratio[i] > DEF_ACCEL_ST_SHIFT_DELTA)
+ ret_val = 1;
+ }
+ } else {
+ /* Self Test Pass/Fail Criteria B */
+ for (i = 0; i < 3; i++) {
+ st_shift_cust[i] = abs(st_avg[i] - reg_avg[i]);
+ if (st_shift_cust[i] < ACCEL_ST_AL_MIN ||
+ st_shift_cust[i] > ACCEL_ST_AL_MAX)
+ ret_val = 1;
+ }
+ }
+ pr_debug("%s self_test accel st_shift_cust - %+d %+d %+d\n",
+ st->hw->name, st_shift_cust[0], st_shift_cust[1],
+ st_shift_cust[2]);
+
+ return ret_val;
+}
+
+/*
+ * inv_do_test() - do the actual test of self testing
+ */
+int inv_do_test(struct inv_mpu_state *st, int self_test_flag,
+ int *gyro_result, int *accel_result, int lp_mode)
+{
+ int result, i, j, packet_size;
+ u8 data[BYTES_PER_SENSOR * 2], d, dd;
+ int fifo_count, packet_count, ind, s;
+
+ packet_size = BYTES_PER_SENSOR * 2;
+
+ /* disable interrupt */
+ result = inv_plat_single_write(st, REG_INT_ENABLE, 0);
+ if (result)
+ return result;
+ /* disable the sensor output to FIFO */
+ result = inv_plat_single_write(st, REG_FIFO_EN, 0);
+ if (result)
+ return result;
+ /* disable fifo reading */
+ result = inv_plat_single_write(st, REG_USER_CTRL, 0);
+ if (result)
+ return result;
+ /* clear FIFO */
+ result = inv_plat_single_write(st, REG_USER_CTRL, BIT_FIFO_RST);
+ if (result)
+ return result;
+ /* setup parameters */
+ result = inv_plat_single_write(st, REG_CONFIG, INV_FILTER_98HZ);
+ if (result)
+ return result;
+
+ /* gyro lp mode */
+ if (lp_mode == 1)
+ d = BIT_GYRO_CYCLE_EN;
+ else if (lp_mode == 2)
+ d = DEF_SELFTEST_SAMPLE_RATE_ACC_LP;
+ else
+ d = 0;
+ result = inv_plat_single_write(st, REG_LP_MODE_CTRL, d);
+ if (result)
+ return result;
+
+ /* config accel LPF register */
+ if (lp_mode == 2)
+ d = BIT_ACCEL_FCHOCIE_B;
+ else
+ d = DEF_ST_MPU6500_ACCEL_LPF;
+ result = inv_plat_single_write(st, REG_6500_ACCEL_CONFIG2, d);
+ if (result)
+ return result;
+
+ if (lp_mode) {
+ result = inv_plat_single_write(st, REG_SAMPLE_RATE_DIV,
+ DEF_SELFTEST_SAMPLE_RATE_LP);
+ } else {
+ result = inv_plat_single_write(st, REG_SAMPLE_RATE_DIV,
+ DEF_SELFTEST_SAMPLE_RATE);
+ }
+ if (result)
+ return result;
+ /* wait for the sampling rate change to stabilize */
+ mdelay(INV_MPU_SAMPLE_RATE_CHANGE_STABLE);
+ result = inv_plat_single_write(st, REG_GYRO_CONFIG,
+ self_test_flag | DEF_SELFTEST_GYRO_FS);
+ if (result)
+ return result;
+
+ d = DEF_SELFTEST_6500_ACCEL_FS;
+ d |= self_test_flag;
+ result = inv_plat_single_write(st, REG_ACCEL_CONFIG, d);
+ if (result)
+ return result;
+
+ /* wait for the output to get stable */
+ msleep(DEF_ST_6500_STABLE_TIME);
+
+ /* enable FIFO reading */
+ result = inv_plat_single_write(st, REG_USER_CTRL, BIT_FIFO_EN);
+ if (result)
+ return result;
+ /* enable sensor output to FIFO */
+ d = BITS_GYRO_OUT | BIT_ACCEL_OUT;
+ for (i = 0; i < THREE_AXIS; i++) {
+ gyro_result[i] = 0;
+ accel_result[i] = 0;
+ }
+ s = 0;
+ while (s < 200 /*st->self_test.samples*/) {
+ /* Stop FIFO */
+ result = inv_plat_single_write(st, REG_USER_CTRL, 0);
+ if (result)
+ return result;
+ /* clear FIFO */
+ result = inv_plat_single_write(st, REG_USER_CTRL, BIT_FIFO_RST);
+ if (result)
+ return result;
+ /* enable FIFO reading */
+ result = inv_plat_single_write(st, REG_USER_CTRL, BIT_FIFO_EN);
+ if (result)
+ return result;
+
+ /* accel lp mode */
+ dd = BIT_CLK_PLL;
+ if (lp_mode == 2)
+ dd |= BIT_LP_EN;
+ else
+ dd &= ~BIT_LP_EN;
+ result = inv_plat_single_write(st, REG_PWR_MGMT_1, dd);
+ if (result)
+ return result;
+
+ result = inv_plat_single_write(st, REG_FIFO_EN, d);
+ if (result)
+ return result;
+ if (lp_mode)
+ mdelay(DEF_GYRO_WAIT_TIME_LP);
+ else
+ mdelay(DEF_GYRO_WAIT_TIME);
+
+ result = inv_plat_single_write(st, REG_FIFO_EN, 0);
+ if (result)
+ return result;
+
+ result = inv_plat_read(st, REG_FIFO_COUNT_H,
+ FIFO_COUNT_BYTE, data);
+ if (result)
+ return result;
+ fifo_count = be16_to_cpup((__be16 *)(&data[0]));
+ pr_debug("%s self_test fifo_count - %d\n",
+ st->hw->name, fifo_count);
+ packet_count = fifo_count / packet_size;
+ i = 0;
+ while ((i < packet_count) && (s < 200 /*st->self_test.samples*/)) {
+ short vals[3];
+ result = inv_plat_read(st, REG_FIFO_R_W,
+ packet_size, data);
+ if (result)
+ return result;
+ ind = 0;
+
+ for (j = 0; j < THREE_AXIS; j++) {
+ vals[j] = (short)be16_to_cpup(
+ (__be16 *)(&data[ind + 2 * j]));
+ accel_result[j] += vals[j];
+ }
+ ind += BYTES_PER_SENSOR;
+ pr_debug(
+ "%s self_test accel data - %d %+d %+d %+d",
+ st->hw->name, s, vals[0], vals[1], vals[2]);
+
+ for (j = 0; j < THREE_AXIS; j++) {
+ vals[j] = (short)be16_to_cpup(
+ (__be16 *)(&data[ind + 2 * j]));
+ gyro_result[j] += vals[j];
+ }
+ pr_debug("%s self_test gyro data - %d %+d %+d %+d",
+ st->hw->name, s, vals[0], vals[1], vals[2]);
+
+ s++;
+ i++;
+ }
+ }
+
+ for (j = 0; j < THREE_AXIS; j++) {
+ accel_result[j] = accel_result[j] / s;
+ accel_result[j] *= DEF_ST_PRECISION;
+ }
+ for (j = 0; j < THREE_AXIS; j++) {
+ gyro_result[j] = gyro_result[j] / s;
+ gyro_result[j] *= DEF_ST_PRECISION;
+ }
+
+ return 0;
+}
+
+
+int inv_power_up_self_test(struct inv_mpu_state *st)
+{
+ int result;
+
+ result = inv_switch_power_in_lp(st, true);
+
+ /* make sure no interrupts */
+ result = inv_plat_single_write(st, REG_INT_ENABLE, 0);
+ if (result)
+ return result;
+
+ if (result)
+ return result;
+ result = inv_switch_engine(st, true, BIT_PWR_ACCEL_STBY);
+ if (result)
+ return result;
+ result = inv_switch_engine(st, true, BIT_PWR_GYRO_STBY);
+ if (result)
+ return result;
+
+ return 0;
+}
+
+/*
+ * inv_hw_self_test() - main function to do hardware self test
+ */
+int inv_hw_self_test(struct inv_mpu_state *st)
+{
+ int result;
+ int gyro_bias_st[THREE_AXIS], gyro_bias_regular[THREE_AXIS];
+ int accel_bias_st[THREE_AXIS], accel_bias_regular[THREE_AXIS];
+#if 0
+ int gyro_bias_regular_lp[THREE_AXIS];
+ int accel_bias_regular_lp[THREE_AXIS];
+ int dummy_bias_regular[THREE_AXIS];
+#endif
+ int test_times, i;
+ char accel_result, gyro_result;
+
+ result = inv_save_setting(st);
+ if (result)
+ return result;
+
+ result = inv_power_up_self_test(st);
+ if (result)
+ return result;
+ accel_result = 0;
+ gyro_result = 0;
+ test_times = DEF_ST_TRY_TIMES;
+ while (test_times > 0) {
+ result = inv_do_test(st, 0, gyro_bias_regular,
+ accel_bias_regular, 0);
+ if (result == -EAGAIN)
+ test_times--;
+ else
+ test_times = 0;
+ }
+ if (result)
+ goto test_fail;
+ pr_debug("%s self_test accel bias_regular - %+d %+d %+d\n",
+ st->hw->name, accel_bias_regular[0],
+ accel_bias_regular[1], accel_bias_regular[2]);
+ pr_debug("%s self_test gyro bias_regular - %+d %+d %+d\n",
+ st->hw->name, gyro_bias_regular[0], gyro_bias_regular[1],
+ gyro_bias_regular[2]);
+
+ test_times = DEF_ST_TRY_TIMES;
+ while (test_times > 0) {
+ result = inv_do_test(st, BITS_SELF_TEST_EN, gyro_bias_st,
+ accel_bias_st, 0);
+ if (result == -EAGAIN)
+ test_times--;
+ else
+ break;
+ }
+ if (result)
+ goto test_fail;
+ pr_debug("%s self_test accel bias_st - %+d %+d %+d\n",
+ st->hw->name, accel_bias_st[0], accel_bias_st[1],
+ accel_bias_st[2]);
+ pr_debug("%s self_test gyro bias_st - %+d %+d %+d\n",
+ st->hw->name, gyro_bias_st[0], gyro_bias_st[1],
+ gyro_bias_st[2]);
+
+#if 0
+ /* lp gyro mode */
+ test_times = DEF_ST_TRY_TIMES;
+ while (test_times > 0) {
+ result = inv_do_test(st, 0, gyro_bias_regular_lp,
+ dummy_bias_regular, 1);
+ if (result == -EAGAIN)
+ test_times--;
+ else
+ test_times = 0;
+ }
+ if (result)
+ goto test_fail;
+ pr_debug("%s self_test gyro bias_regular lp - %+d %+d %+d\n",
+ st->hw->name, gyro_bias_regular_lp[0], gyro_bias_regular_lp[1],
+ gyro_bias_regular_lp[2]);
+
+ /* lp accel mode */
+ test_times = DEF_ST_TRY_TIMES;
+ while (test_times > 0) {
+ result = inv_do_test(st, 0, dummy_bias_regular,
+ accel_bias_regular_lp, 2);
+ if (result == -EAGAIN)
+ test_times--;
+ else
+ test_times = 0;
+ }
+ if (result)
+ goto test_fail;
+ pr_debug("%s self_test accel bias_regular lp - %+d %+d %+d\n",
+ st->hw->name, accel_bias_regular_lp[0],
+ accel_bias_regular_lp[1], accel_bias_regular_lp[2]);
+#endif
+
+ /* copy bias */
+ for (i = 0; i < 3; i++) {
+ /* gyro : LN bias as LN is default mode */
+ st->gyro_st_bias[i] = gyro_bias_regular[i] / DEF_ST_PRECISION;
+ /* accel : LN bias as LN is default mode */
+ st->accel_st_bias[i] = accel_bias_regular[i] / DEF_ST_PRECISION;
+ }
+
+ /* Check is done on continuous mode data */
+ accel_result = !inv_check_accel_self_test(st,
+ accel_bias_regular, accel_bias_st);
+ gyro_result = !inv_check_gyro_self_test(st,
+ gyro_bias_regular, gyro_bias_st);
+
+test_fail:
+ inv_recover_setting(st);
+ return (accel_result << DEF_ST_ACCEL_RESULT_SHIFT) | gyro_result;
+}
diff --git a/drivers/iio/imu/inv_mpu/iam20680/inv_mpu_setup_20680.c b/drivers/iio/imu/inv_mpu/iam20680/inv_mpu_setup_20680.c
new file mode 100644
index 0000000..5e9cf89
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu/iam20680/inv_mpu_setup_20680.c
@@ -0,0 +1,466 @@
+/*
+* Copyright (C) 2017-2018 InvenSense, Inc.
+*
+* This software is licensed under the terms of the GNU General Public
+* License version 2, as published by the Free Software Foundation, and
+* may be copied, distributed, and modified under those terms.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*/
+#define pr_fmt(fmt) "inv_mpu: " fmt
+#include "../inv_mpu_iio.h"
+
+/* set LN mode for gyro regardless of conditions */
+#define USE_GYRO_LN_MODE
+
+static int inv_calc_engine_dur(struct inv_engine_info *ei)
+{
+ if (!ei->running_rate)
+ return -EINVAL;
+ ei->dur = ei->base_time / ei->orig_rate;
+ ei->dur *= ei->divider;
+
+ return 0;
+}
+
+static int inv_turn_on_fifo(struct inv_mpu_state *st)
+{
+ u8 int_en, fifo_en, mode, user;
+ int r;
+
+ r = inv_plat_single_write(st, REG_FIFO_EN, 0);
+ if (r)
+ return r;
+ r = inv_plat_single_write(st, REG_USER_CTRL, BIT_FIFO_RST);
+ if (r)
+ return r;
+ fifo_en = 0;
+ int_en = 0;
+
+ if (st->gesture_only_on && (!st->batch.timeout)) {
+ st->gesture_int_count = WOM_DELAY_THRESHOLD;
+ int_en |= BIT_WOM_ALL_INT_EN;
+ }
+#ifdef TIMER_BASED_BATCHING
+ if (st->chip_config.eis_enable)
+ int_en |= BIT_FSYNC_INT_EN;
+ if (!st->batch_timeout) {
+ int_en |= BIT_DATA_RDY_EN;
+ }
+#else
+ if (st->batch.timeout) {
+ if(!st->batch.fifo_wm_th)
+ int_en = BIT_DATA_RDY_EN;
+ } else {
+ int_en = BIT_DATA_RDY_EN;
+ if (st->chip_config.eis_enable)
+ int_en |= BIT_FSYNC_INT_EN;
+ }
+#endif
+ if (st->sensor[SENSOR_GYRO].on)
+ fifo_en |= BITS_GYRO_FIFO_EN;
+
+ if (st->sensor[SENSOR_ACCEL].on)
+ fifo_en |= BIT_ACCEL_FIFO_EN;
+ r = inv_plat_single_write(st, REG_FIFO_EN, fifo_en);
+ if (r)
+ return r;
+ st->int_en = int_en;
+ r = inv_plat_single_write(st, REG_INT_ENABLE, int_en);
+ if (r)
+ return r;
+ if (st->gesture_only_on && (!st->batch.timeout)) {
+ mode = BIT_ACCEL_INTEL_EN | BIT_ACCEL_INTEL_MODE;
+ } else {
+ mode = 0;
+ }
+ r = inv_plat_single_write(st, REG_ACCEL_INTEL_CTRL, mode);
+#ifdef SENSOR_DATA_FROM_REGISTERS
+ user = 0;
+#else
+ user = BIT_FIFO_EN;
+#endif
+ r = inv_plat_single_write(st, REG_USER_CTRL, user | st->i2c_dis);
+#ifdef TIMER_BASED_BATCHING
+ if (fifo_en && st->batch_timeout) {
+ if (st->is_batch_timer_running)
+ hrtimer_cancel(&st ->hr_batch_timer);
+ st->is_batch_timer_running = true;
+ hrtimer_start(&st ->hr_batch_timer,
+ ns_to_ktime(st->batch_timeout), HRTIMER_MODE_REL);
+ } else {
+ if (st->is_batch_timer_running)
+ hrtimer_cancel(&st ->hr_batch_timer);
+ st->is_batch_timer_running = false;
+ }
+#endif
+
+ return r;
+}
+
+/*
+ * inv_reset_fifo() - Reset FIFO related registers.
+ */
+int inv_reset_fifo(struct inv_mpu_state *st, bool turn_off)
+{
+ int r, i;
+ struct inv_timestamp_algo *ts_algo = &st->ts_algo;
+ int dur_ms;
+
+ r = inv_turn_on_fifo(st);
+ if (r)
+ return r;
+
+ ts_algo->last_run_time = get_time_ns();
+ ts_algo->reset_ts = ts_algo->last_run_time;
+ if (st->mode_1k_on)
+ ts_algo->first_sample = MODE_1K_INIT_SAMPLE;
+ else
+ ts_algo->first_sample = 1;
+
+ dur_ms = st->smplrt_div + 1;
+ if ((ts_algo->first_sample * dur_ms) < FIRST_SAMPLE_BUF_MS)
+ ts_algo->first_sample = FIRST_SAMPLE_BUF_MS / dur_ms;
+ if (ts_algo->first_sample == 0)
+ ts_algo->first_sample = 1;
+
+ st->last_temp_comp_time = ts_algo->last_run_time;
+ st->left_over_size = 0;
+ for (i = 0; i < SENSOR_NUM_MAX; i++) {
+ st->sensor[i].calib_flag = 0;
+ st->sensor[i].sample_calib = 0;
+ st->sensor[i].time_calib = ts_algo->last_run_time;
+ }
+
+ ts_algo->calib_counter = 0;
+
+ return 0;
+}
+
+static int inv_turn_on_engine(struct inv_mpu_state *st)
+{
+ u8 v, w;
+ int r;
+ unsigned int wait_ms;
+
+ if (st->chip_config.gyro_enable | st->chip_config.accel_enable) {
+ w = 0;
+ if (!st->chip_config.gyro_enable)
+ w |= BIT_PWR_GYRO_STBY;
+ if (!st->chip_config.accel_enable)
+ w |= BIT_PWR_ACCEL_STBY;
+ } else if (st->chip_config.compass_enable) {
+ w = BIT_PWR_GYRO_STBY;
+ } else {
+ w = (BIT_PWR_GYRO_STBY | BIT_PWR_ACCEL_STBY);
+ }
+
+ r = inv_plat_read(st, REG_PWR_MGMT_2, 1, &v);
+ if (r)
+ return r;
+ r = inv_plat_single_write(st, REG_PWR_MGMT_2, w);
+ if (r)
+ return r;
+
+ wait_ms = 0;
+ if (st->chip_config.gyro_enable
+ && (v & BIT_PWR_GYRO_STBY)) {
+ wait_ms = INV_IAM20680_GYRO_START_TIME;
+ }
+ if (st->chip_config.accel_enable
+ && (v & BIT_PWR_ACCEL_STBY)) {
+ if (INV_IAM20680_ACCEL_START_TIME > wait_ms)
+ wait_ms = INV_IAM20680_ACCEL_START_TIME;
+ }
+ if (wait_ms)
+ msleep(wait_ms);
+
+ if (st->chip_config.has_compass) {
+ if (st->chip_config.compass_enable)
+ r = st->slave_compass->resume(st);
+ else
+ r = st->slave_compass->suspend(st);
+ if (r)
+ return r;
+ }
+
+ return 0;
+}
+
+static int inv_setup_dmp_rate(struct inv_mpu_state *st)
+{
+ int i;
+
+ for (i = 0; i < SENSOR_NUM_MAX; i++) {
+ if (st->sensor[i].on) {
+ st->cntl |= st->sensor[i].output;
+ st->sensor[i].dur =
+ st->eng_info[st->sensor[i].engine_base].dur;
+ st->sensor[i].div = 1;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * inv_set_lpf() - set low pass filer based on fifo rate.
+ */
+static int inv_set_lpf(struct inv_mpu_state *st, int rate)
+{
+ const short hz[] = {188, 98, 42, 20, 10, 5};
+ const int d[] = {INV_FILTER_188HZ, INV_FILTER_98HZ,
+ INV_FILTER_42HZ, INV_FILTER_20HZ,
+ INV_FILTER_10HZ, INV_FILTER_5HZ};
+ int i, h, data, result;
+
+#ifdef USE_GYRO_LN_MODE
+ if (1) {
+#else
+ if (st->chip_config.eis_enable || st->ois.en || st->mode_1k_on) {
+#endif
+ h = (rate >> 1);
+ i = 0;
+ while ((h < hz[i]) && (i < ARRAY_SIZE(d) - 1))
+ i++;
+ data = d[i];
+ data |= EXT_SYNC_SET;
+ result = inv_plat_single_write(st, REG_CONFIG, data);
+ if (result)
+ return result;
+
+ st->chip_config.lpf = data;
+ result = inv_plat_single_write(st, REG_LP_MODE_CTRL, 0);
+ } else {
+ result = inv_plat_single_write(st, REG_LP_MODE_CTRL,
+ BIT_GYRO_CYCLE_EN);
+ if (result)
+ return result;
+ data = 0;
+ result = inv_plat_single_write(st, REG_CONFIG, data | 3);
+ }
+
+ return result;
+}
+
+static int inv_set_div(struct inv_mpu_state *st, int a_d, int g_d)
+{
+ int result, div;
+
+ if (st->chip_config.gyro_enable)
+ div = g_d;
+ else
+ div = a_d;
+ if (st->chip_config.eis_enable)
+ div = 0;
+
+ st->smplrt_div = div;
+ pr_debug("div= %d\n", div);
+ result = inv_plat_single_write(st, REG_SAMPLE_RATE_DIV, div);
+
+ return result;
+}
+
+// 20680 does not support batching
+static int inv_set_batch(struct inv_mpu_state *st)
+{
+#ifdef TIMER_BASED_BATCHING
+ u64 timeout;
+ int required_fifo_size;
+
+ if (st->batch.timeout) {
+ required_fifo_size = st->batch.timeout * st->eng_info[ENGINE_GYRO].running_rate
+ * st->batch.pk_size / 1000;
+ if (required_fifo_size > MAX_BATCH_FIFO_SIZE) {
+ required_fifo_size = MAX_BATCH_FIFO_SIZE;
+ timeout = (required_fifo_size / st->batch.pk_size) * (1000 / st->eng_info[ENGINE_GYRO].running_rate);
+ } else {
+ timeout = st->batch.timeout;
+ }
+ } else {
+ timeout = 1000 / st->eng_info[ENGINE_GYRO].running_rate;
+ }
+ if (timeout <= 1000 / st->eng_info[ENGINE_GYRO].running_rate)
+ st->batch_timeout = 0;
+ else
+ st->batch_timeout = timeout * 1000000; // ms to ns
+#endif
+ st->batch.fifo_wm_th = 0;
+
+ return 0;
+}
+
+static int inv_set_rate(struct inv_mpu_state *st)
+{
+ int g_d, a_d, result, i;
+
+ result = inv_setup_dmp_rate(st);
+ if (result)
+ return result;
+
+ g_d = st->eng_info[ENGINE_GYRO].divider - 1;
+ a_d = st->eng_info[ENGINE_ACCEL].divider - 1;
+ result = inv_set_div(st, a_d, g_d);
+ if (result)
+ return result;
+ result = inv_set_lpf(st, st->eng_info[ENGINE_GYRO].running_rate);
+ if (result)
+ return result;
+ // set ADLPF at this point not to change after accel is enabled
+ result = inv_set_accel_config2(st, false);
+ st->batch.pk_size = 0;
+ for (i = 0; i < SENSOR_NUM_MAX; i++) {
+ if (st->sensor[i].on)
+ st->batch.pk_size += st->sensor[i].sample_size;
+ }
+
+ inv_set_batch(st);
+
+ return result;
+}
+
+static int inv_determine_engine(struct inv_mpu_state *st)
+{
+ int i;
+ bool a_en, g_en;
+ int accel_rate, gyro_rate;
+
+ a_en = false;
+ g_en = false;
+ gyro_rate = MPU_INIT_SENSOR_RATE;
+ accel_rate = MPU_INIT_SENSOR_RATE;
+ /* loop the streaming sensors to see which engine needs to be turned on
+ */
+ for (i = 0; i < SENSOR_NUM_MAX; i++) {
+ if (st->sensor[i].on) {
+ a_en |= st->sensor[i].a_en;
+ g_en |= st->sensor[i].g_en;
+ }
+ }
+
+ if (st->chip_config.eis_enable) {
+ g_en = true;
+ st->eis.frame_count = 0;
+ st->eis.fsync_delay = 0;
+ st->eis.gyro_counter = 0;
+ st->eis.voting_count = 0;
+ st->eis.voting_count_sub = 0;
+ gyro_rate = BASE_SAMPLE_RATE;
+ } else {
+ st->eis.eis_triggered = false;
+ st->eis.prev_state = false;
+ }
+
+ accel_rate = st->sensor[SENSOR_ACCEL].rate;
+ gyro_rate = max(gyro_rate, st->sensor[SENSOR_GYRO].rate);
+
+ st->ts_algo.clock_base = ENGINE_ACCEL;
+
+ if (g_en) {
+ /* gyro engine needs to be fastest */
+ if (a_en)
+ gyro_rate = max(gyro_rate, accel_rate);
+ accel_rate = gyro_rate;
+ st->ts_algo.clock_base = ENGINE_GYRO;
+ } else if (a_en) {
+ /* accel engine needs to be fastest if gyro engine is off */
+ gyro_rate = accel_rate;
+ st->ts_algo.clock_base = ENGINE_ACCEL;
+ }
+
+ st->eng_info[ENGINE_GYRO].running_rate = gyro_rate;
+ st->eng_info[ENGINE_ACCEL].running_rate = accel_rate;
+ if ((gyro_rate >= BASE_SAMPLE_RATE) ||
+ (accel_rate >= BASE_SAMPLE_RATE))
+ st->mode_1k_on = true;
+ else
+ st->mode_1k_on = false;
+ /* engine divider for pressure and compass is set later */
+ if (st->chip_config.eis_enable || st->mode_1k_on) {
+ st->eng_info[ENGINE_GYRO].divider = 1;
+ st->eng_info[ENGINE_ACCEL].divider = 1;
+ // need to update rate and div for 1khz mode
+ for ( i = 0 ; i < SENSOR_L_NUM_MAX ; i++ ) {
+ if (st->sensor_l[i].on) {
+ st->sensor_l[i].counter = 0;
+ if (st->sensor_l[i].rate)
+ st->sensor_l[i].div =
+ BASE_SAMPLE_RATE
+ / st->sensor_l[i].rate;
+ else
+ st->sensor_l[i].div = 0xffff;
+ }
+ }
+ } else {
+ st->eng_info[ENGINE_GYRO].divider = BASE_SAMPLE_RATE /
+ st->eng_info[ENGINE_GYRO].running_rate;
+ st->eng_info[ENGINE_ACCEL].divider = BASE_SAMPLE_RATE /
+ st->eng_info[ENGINE_ACCEL].running_rate;
+ }
+
+ for ( i = 0 ; i < SENSOR_L_NUM_MAX ; i++ )
+ st->sensor_l[i].counter = 0;
+
+ inv_calc_engine_dur(&st->eng_info[ENGINE_GYRO]);
+ inv_calc_engine_dur(&st->eng_info[ENGINE_ACCEL]);
+
+ pr_debug("gen: %d aen: %d grate: %d arate: %d\n",
+ g_en, a_en, gyro_rate, accel_rate);
+
+ st->chip_config.gyro_enable = g_en;
+ st->chip_config.accel_enable = a_en;
+
+ return 0;
+}
+
+/*
+ * set_inv_enable() - enable function.
+ */
+int set_inv_enable(struct iio_dev *indio_dev)
+{
+ int result;
+ struct inv_mpu_state *st = iio_priv(indio_dev);
+
+ result = inv_switch_power_in_lp(st, true);
+ if (result)
+ return result;
+ inv_stop_interrupt(st);
+ inv_determine_engine(st);
+ result = inv_set_rate(st);
+ if (result) {
+ pr_err("inv_set_rate error\n");
+ return result;
+ }
+ result = inv_turn_on_engine(st);
+ if (result) {
+ pr_err("inv_turn_on_engine error\n");
+ return result;
+ }
+ result = inv_reset_fifo(st, false);
+ if (result)
+ return result;
+ result = inv_switch_power_in_lp(st, false);
+ if ((!st->chip_config.gyro_enable) &&
+ (!st->chip_config.accel_enable)) {
+ inv_set_power(st, false);
+ return 0;
+ }
+
+ return result;
+}
+/* dummy function for 20608D */
+int inv_enable_pedometer_interrupt(struct inv_mpu_state *st, bool en)
+{
+ return 0;
+}
+int inv_dmp_read(struct inv_mpu_state *st, int off, int size, u8 *buf)
+{
+ return 0;
+}
+int inv_firmware_load(struct inv_mpu_state *st)
+{
+ return 0;
+}
diff --git a/drivers/iio/imu/inv_mpu/inv_mpu_common.c b/drivers/iio/imu/inv_mpu/inv_mpu_common.c
new file mode 100644
index 0000000..33db034
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu/inv_mpu_common.c
@@ -0,0 +1,988 @@
+/*
+ * Copyright (C) 2012-2017 InvenSense, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#define pr_fmt(fmt) "inv_mpu: " fmt
+#include "inv_mpu_iio.h"
+#ifdef CONFIG_RTC_INTF_ALARM
+#include <linux/android_alarm.h>
+#endif
+#include <linux/export.h>
+
+#ifdef CONFIG_RTC_INTF_ALARM
+s64 get_time_ns(void)
+{
+ struct timespec ts;
+
+ /* get_monotonic_boottime(&ts); */
+
+ /* Workaround for some platform on which monotonic clock and
+ * Android SystemClock has a gap.
+ * Use ktime_to_timespec(alarm_get_elapsed_realtime()) instead of
+ * get_monotonic_boottime() for these platform
+ */
+
+ ts = ktime_to_timespec(alarm_get_elapsed_realtime());
+
+ return timespec_to_ns(&ts);
+}
+#else
+s64 get_time_ns(void)
+{
+ struct timespec ts;
+
+ get_monotonic_boottime(&ts);
+
+ /* Workaround for some platform on which monotonic clock and
+ * Android SystemClock has a gap.
+ * Use ktime_to_timespec(alarm_get_elapsed_realtime()) instead of
+ * get_monotonic_boottime() for these platform
+ */
+ return timespec_to_ns(&ts);
+}
+
+#endif
+
+#ifdef ACCEL_BIAS_TEST
+int inv_get_3axis_average(s16 src[], s16 dst[], s16 reset)
+{
+#define BUFFER_SIZE 200
+ static s16 buffer[BUFFER_SIZE][3];
+ static s16 current_position = 0;
+ static s16 ready = 0;
+ int sum[3]= {0,};
+ int i;
+
+ if(reset){
+ current_position = 0;
+ ready = 0;
+ }
+ buffer[current_position][0] = src[0];
+ buffer[current_position][1] = src[1];
+ buffer[current_position][2] = src[2];
+ current_position++;
+ if(current_position == BUFFER_SIZE){
+ ready = 1;
+ current_position = 0;
+ }
+ if(ready){
+ for(i = 0 ; i < BUFFER_SIZE ; i++){
+ sum[0] += buffer[i][0];
+ sum[1] += buffer[i][1];
+ sum[2] += buffer[i][2];
+ }
+ dst[0] = sum[0]/BUFFER_SIZE;
+ dst[1] = sum[1]/BUFFER_SIZE;
+ dst[2] = sum[2]/BUFFER_SIZE;
+ return 1;
+ }
+ return 0;
+}
+#endif
+
+int inv_q30_mult(int a, int b)
+{
+#define DMP_MULTI_SHIFT 30
+ u64 temp;
+ int result;
+
+ temp = ((u64)a) * b;
+ result = (int)(temp >> DMP_MULTI_SHIFT);
+
+ return result;
+}
+#if defined(CONFIG_INV_MPU_IIO_ICM20648) || \
+ defined(CONFIG_INV_MPU_IIO_ICM20690)
+/* inv_read_secondary(): set secondary registers for reading.
+ The chip must be set as bank 3 before calling.
+ */
+int inv_read_secondary(struct inv_mpu_state *st, int ind, int addr,
+ int reg, int len)
+{
+ int result;
+
+ result = inv_plat_single_write(st, st->slv_reg[ind].addr,
+ INV_MPU_BIT_I2C_READ | addr);
+ if (result)
+ return result;
+ result = inv_plat_single_write(st, st->slv_reg[ind].reg, reg);
+ if (result)
+ return result;
+ result = inv_plat_single_write(st, st->slv_reg[ind].ctrl,
+ INV_MPU_BIT_SLV_EN | len);
+
+ return result;
+}
+
+int inv_execute_read_secondary(struct inv_mpu_state *st, int ind, int addr,
+ int reg, int len, u8 *d)
+{
+ int result;
+
+ inv_set_bank(st, BANK_SEL_3);
+ result = inv_read_secondary(st, ind, addr, reg, len);
+ if (result)
+ return result;
+ inv_set_bank(st, BANK_SEL_0);
+ result = inv_plat_single_write(st, REG_USER_CTRL, st->i2c_dis |
+ BIT_I2C_MST_EN);
+ msleep(SECONDARY_INIT_WAIT);
+ result = inv_plat_single_write(st, REG_USER_CTRL, st->i2c_dis);
+ if (result)
+ return result;
+ result = inv_plat_read(st, REG_EXT_SLV_SENS_DATA_00, len, d);
+
+ return result;
+}
+
+/* inv_write_secondary(): set secondary registers for writing.
+ The chip must be set as bank 3 before calling.
+ */
+int inv_write_secondary(struct inv_mpu_state *st, int ind, int addr,
+ int reg, int v)
+{
+ int result;
+
+ result = inv_plat_single_write(st, st->slv_reg[ind].addr, addr);
+ if (result)
+ return result;
+ result = inv_plat_single_write(st, st->slv_reg[ind].reg, reg);
+ if (result)
+ return result;
+ result = inv_plat_single_write(st, st->slv_reg[ind].ctrl,
+ INV_MPU_BIT_SLV_EN | 1);
+
+ result = inv_plat_single_write(st, st->slv_reg[ind].d0, v);
+
+ return result;
+}
+
+int inv_execute_write_secondary(struct inv_mpu_state *st, int ind, int addr,
+ int reg, int v)
+{
+ int result;
+
+ inv_set_bank(st, BANK_SEL_3);
+ result = inv_write_secondary(st, ind, addr, reg, v);
+ if (result)
+ return result;
+ inv_set_bank(st, BANK_SEL_0);
+ result = inv_plat_single_write(st, REG_USER_CTRL, st->i2c_dis |
+ BIT_I2C_MST_EN);
+ msleep(SECONDARY_INIT_WAIT);
+ result = inv_plat_single_write(st, REG_USER_CTRL, st->i2c_dis);
+
+ return result;
+}
+
+int inv_set_bank(struct inv_mpu_state *st, u8 bank)
+{
+#ifdef CONFIG_INV_MPU_IIO_ICM20648
+ int r;
+
+ r = inv_plat_single_write(st, REG_BANK_SEL, bank);
+
+ return r;
+#else
+ return 0;
+#endif
+}
+#endif
+
+#ifdef CONFIG_INV_MPU_IIO_ICM20648
+/**
+ * inv_write_cntl() - Write control word to designated address.
+ * @st: Device driver instance.
+ * @wd: control word.
+ * @en: enable/disable.
+ * @cntl: control address to be written.
+ */
+int inv_write_cntl(struct inv_mpu_state *st, u16 wd, bool en, int cntl)
+{
+ int result;
+ u8 reg[2], d_out[2];
+
+ result = mem_r(cntl, 2, d_out);
+ if (result)
+ return result;
+ reg[0] = ((wd >> 8) & 0xff);
+ reg[1] = (wd & 0xff);
+ if (!en) {
+ d_out[0] &= ~reg[0];
+ d_out[1] &= ~reg[1];
+ } else {
+ d_out[0] |= reg[0];
+ d_out[1] |= reg[1];
+ }
+ result = mem_w(cntl, 2, d_out);
+
+ return result;
+}
+#endif
+
+int inv_set_power(struct inv_mpu_state *st, bool power_on)
+{
+ u8 d;
+ int r;
+
+ if ((!power_on) == st->chip_config.is_asleep)
+ return 0;
+
+ d = BIT_CLK_PLL;
+ if (!power_on)
+ d |= BIT_SLEEP;
+
+ r = inv_plat_single_write(st, REG_PWR_MGMT_1, d);
+ if (r)
+ return r;
+
+ if (power_on)
+ usleep_range(REG_UP_TIME_USEC, REG_UP_TIME_USEC);
+
+ st->chip_config.is_asleep = !power_on;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(inv_set_power);
+
+int inv_stop_interrupt(struct inv_mpu_state *st)
+{
+ int res;
+#if defined(CONFIG_INV_MPU_IIO_ICM20648)
+ /* disable_irq_wake alone should work already. However,
+ it might need system configuration change. From driver side,
+ we will disable IRQ altogether for non-wakeup sensors. */
+ res = inv_plat_read(st, REG_INT_ENABLE, 1, &st->int_en);
+ if (res)
+ return res;
+ res = inv_plat_read(st, REG_INT_ENABLE_2, 1, &st->int_en_2);
+ if (res)
+ return res;
+ res = inv_plat_single_write(st, REG_INT_ENABLE, 0);
+ if (res)
+ return res;
+ res = inv_plat_single_write(st, REG_INT_ENABLE_2, 0);
+ if (res)
+ return res;
+#endif
+#if defined(CONFIG_INV_MPU_IIO_ICM20608D)
+ res = inv_plat_read(st, REG_INT_ENABLE, 1, &st->int_en);
+ if (res)
+ return res;
+ res = inv_plat_single_write(st, REG_INT_ENABLE, 0);
+ if (res)
+ return res;
+#endif
+#if defined(CONFIG_INV_MPU_IIO_ICM20602) \
+ || defined(CONFIG_INV_MPU_IIO_ICM20690) \
+ || defined(CONFIG_INV_MPU_IIO_IAM20680)
+ res = inv_plat_read(st, REG_INT_ENABLE, 1, &st->int_en);
+ if (res)
+ return res;
+ res = inv_plat_single_write(st, REG_INT_ENABLE, 0);
+ if (res)
+ return res;
+#endif
+ return 0;
+}
+int inv_reenable_interrupt(struct inv_mpu_state *st)
+{
+ int res = 0;
+#if defined(CONFIG_INV_MPU_IIO_ICM20648)
+ res = inv_plat_single_write(st, REG_INT_ENABLE, st->int_en);
+ if (res)
+ return res;
+ res = inv_plat_single_write(st, REG_INT_ENABLE_2, st->int_en_2);
+ if (res)
+ return res;
+#elif defined(CONFIG_INV_MPU_IIO_ICM20608D)
+ res = inv_plat_single_write(st, REG_INT_ENABLE, st->int_en);
+ if (res)
+ return res;
+#endif
+#if defined(CONFIG_INV_MPU_IIO_ICM20602) \
+ || defined(CONFIG_INV_MPU_IIO_ICM20690) \
+ || defined(CONFIG_INV_MPU_IIO_IAM20680)
+ res = inv_plat_single_write(st, REG_INT_ENABLE, st->int_en);
+ if (res)
+ return res;
+#endif
+ return res;
+}
+
+static int inv_lp_en_off_mode(struct inv_mpu_state *st, bool on)
+{
+ int r;
+
+ if (!st->chip_config.is_asleep)
+ return 0;
+
+ r = inv_plat_single_write(st, REG_PWR_MGMT_1, BIT_CLK_PLL);
+ st->chip_config.is_asleep = 0;
+
+ return r;
+}
+#ifdef CONFIG_INV_MPU_IIO_ICM20648
+static int inv_lp_en_on_mode(struct inv_mpu_state *st, bool on)
+{
+ int r = 0;
+ u8 w;
+
+ if ((!st->chip_config.is_asleep) &&
+ ((!on) == st->chip_config.lp_en_set))
+ return 0;
+
+ w = BIT_CLK_PLL;
+ if ((!on) && (!st->eis.eis_triggered))
+ w |= BIT_LP_EN;
+ r = inv_plat_single_write(st, REG_PWR_MGMT_1, w);
+ st->chip_config.is_asleep = 0;
+ st->chip_config.lp_en_set = (!on);
+ return r;
+}
+#endif
+#if defined(CONFIG_INV_MPU_IIO_ICM20602) \
+ || defined(CONFIG_INV_MPU_IIO_ICM20690) \
+ || defined(CONFIG_INV_MPU_IIO_IAM20680)
+int inv_set_accel_config2(struct inv_mpu_state *st, bool cycle_mode)
+{
+ int cycle_freq[] = {275, 192, 111, 59};
+ int cont_freq[] = {219, 219, 99, 45, 22, 11, 6};
+ int i, r, rate;
+ u8 v;
+
+ v = 0;
+#ifdef CONFIG_INV_MPU_IIO_ICM20690
+ v |= BIT_FIFO_SIZE_1K;
+#endif
+ if (cycle_mode) {
+ rate = (st->eng_info[ENGINE_ACCEL].running_rate << 1);
+ i = ARRAY_SIZE(cycle_freq) - 1;
+ while (i > 0) {
+ if (rate < cycle_freq[i]) {
+ break;
+ }
+ i--;
+ }
+ r = inv_plat_single_write(st, REG_ACCEL_CONFIG_2, v |
+ (i << 4) | 7);
+ if (r)
+ return r;
+ } else {
+ rate = (st->eng_info[ENGINE_ACCEL].running_rate >> 1);
+ for (i = 1; i < ARRAY_SIZE(cont_freq); i++) {
+ if (rate >= cont_freq[i])
+ break;
+ }
+ if (i > 6)
+ i = 6;
+ r = inv_plat_single_write(st, REG_ACCEL_CONFIG_2, v | i);
+ if (r)
+ return r;
+ }
+
+ return 0;
+}
+static int inv_lp_en_on_mode(struct inv_mpu_state *st, bool on)
+{
+ int r = 0;
+ u8 w;
+ bool cond_check;
+
+ if ((!st->chip_config.is_asleep) &&
+ ((!on) == st->chip_config.lp_en_set))
+ return 0;
+ cond_check = (!on) && st->cycle_on;
+
+ w = BIT_CLK_PLL;
+ r = inv_plat_single_write(st, REG_PWR_MGMT_1, w);
+ if (cond_check) {
+ w |= BIT_LP_EN;
+ inv_set_accel_config2(st, true);
+ st->chip_config.lp_en_set = true;
+ r = inv_plat_single_write(st, REG_PWR_MGMT_1, w);
+ } else {
+ inv_set_accel_config2(st, false);
+#ifdef CONFIG_INV_MPU_IIO_ICM20690
+ r = inv_plat_single_write(st, REG_PWR_MGMT_1, w | BIT_SLEEP);
+ if (r)
+ return r;
+#endif
+ st->chip_config.lp_en_set = false;
+ r = inv_plat_single_write(st, REG_PWR_MGMT_1, w);
+ msleep(10);
+ }
+ st->chip_config.is_asleep = 0;
+
+ return r;
+}
+#endif
+#ifdef CONFIG_INV_MPU_IIO_ICM20608D
+static int inv_set_accel_config2(struct inv_mpu_state *st)
+{
+ int cont_freq[] = {219, 219, 99, 45, 22, 11, 6};
+ int dec2_cfg = 0;
+ int i, r, rate;
+
+ rate = (st->eng_info[ENGINE_ACCEL].running_rate << 1);
+ i = 0;
+ if (!st->chip_config.eis_enable){
+ while ((rate < cont_freq[i]) && (i < ARRAY_SIZE(cont_freq) - 1))
+ i++;
+ dec2_cfg = 2<<4; //4x
+ }
+ r = inv_plat_single_write(st, REG_ACCEL_CONFIG_2, i | dec2_cfg);
+ if (r)
+ return r;
+ return 0;
+}
+static int inv_lp_en_on_mode(struct inv_mpu_state *st, bool on)
+{
+ int r = 0;
+ u8 w;
+
+ w = BIT_CLK_PLL;
+ if ((!on) && (!st->chip_config.eis_enable))
+ w |= BIT_LP_EN;
+ inv_set_accel_config2(st);
+ r = inv_plat_single_write(st, REG_PWR_MGMT_1, w);
+
+ return r;
+}
+#endif
+int inv_switch_power_in_lp(struct inv_mpu_state *st, bool on)
+{
+ int r;
+
+ if (st->chip_config.lp_en_mode_off)
+ r = inv_lp_en_off_mode(st, on);
+ else
+ r = inv_lp_en_on_mode(st, on);
+
+ return r;
+}
+EXPORT_SYMBOL_GPL(inv_switch_power_in_lp);
+
+int write_be16_to_mem(struct inv_mpu_state *st, u16 data, int addr)
+{
+ u8 d[2];
+
+ d[0] = (data >> 8) & 0xff;
+ d[1] = data & 0xff;
+
+ return mem_w(addr, sizeof(d), d);
+}
+
+int write_be32_to_mem(struct inv_mpu_state *st, u32 data, int addr)
+{
+ cpu_to_be32s(&data);
+ return mem_w(addr, sizeof(data), (u8 *)&data);
+}
+
+int read_be16_from_mem(struct inv_mpu_state *st, u16 *o, int addr)
+{
+ int result;
+ u8 d[2];
+
+ result = mem_r(addr, 2, (u8 *) &d);
+ *o = d[0] << 8 | d[1];
+
+ return result;
+}
+
+int read_be32_from_mem(struct inv_mpu_state *st, u32 *o, int addr)
+{
+ int result;
+ u32 d = 0;
+
+ result = mem_r(addr, 4, (u8 *) &d);
+ *o = be32_to_cpup((__be32 *)(&d));
+
+ return result;
+}
+
+int be32_to_int(u8 *d)
+{
+ return (d[0] << 24) | (d[1] << 16) | (d[2] << 8) | d[3];
+}
+
+u32 inv_get_cntr_diff(u32 curr_counter, u32 prev)
+{
+ u32 diff;
+
+ if (curr_counter > prev)
+ diff = curr_counter - prev;
+ else
+ diff = 0xffffffff - prev + curr_counter + 1;
+
+ return diff;
+}
+
+int inv_write_2bytes(struct inv_mpu_state *st, int addr, int data)
+{
+ u8 d[2];
+
+ if (data < 0 || data > USHRT_MAX)
+ return -EINVAL;
+
+ d[0] = (u8) ((data >> 8) & 0xff);
+ d[1] = (u8) (data & 0xff);
+
+ return mem_w(addr, ARRAY_SIZE(d), d);
+}
+
+
+
+int inv_process_eis(struct inv_mpu_state *st, u16 delay)
+{
+ int tmp1, tmp2, tmp3;
+
+ switch (st->eis.voting_state) {
+ case 0:
+ st->eis.gyro_counter_s[0] = st->eis.gyro_counter;
+ st->eis.fsync_delay_s[0] = delay - st->eis.fsync_delay;
+ st->eis.voting_count = 1;
+ st->eis.voting_count_sub = 0;
+ st->eis.voting_state = 1;
+ break;
+ case 1:
+ if (abs(st->eis.gyro_counter_s[0] -
+ st->eis.gyro_counter) <= 1) {
+ st->eis.voting_count++;
+ } else {
+ st->eis.gyro_counter_s[2] = st->eis.gyro_counter;
+ st->eis.voting_count_sub++;
+ st->eis.voting_state = 2;
+ }
+ if (st->eis.voting_count > 5)
+ st->eis.voting_state = 3;
+ break;
+ case 2:
+ tmp1 = abs(st->eis.gyro_counter_s[0] - st->eis.gyro_counter);
+ tmp2 = abs(st->eis.gyro_counter_s[2] - st->eis.gyro_counter);
+
+ if ((tmp1 < tmp2) && (tmp1 <= 1))
+ st->eis.voting_count++;
+ else
+ st->eis.voting_count_sub++;
+ if (st->eis.voting_count > 5) {
+ st->eis.voting_state = 3;
+ st->eis.voting_count = 0;
+ st->eis.voting_count_sub = 0;
+ }
+
+ if (st->eis.voting_count_sub > 5) {
+ st->eis.gyro_counter_s[0] = st->eis.gyro_counter;
+ st->eis.fsync_delay_s[0] = delay - st->eis.fsync_delay;
+ st->eis.voting_state = 1;
+ st->eis.voting_count = 1;
+ st->eis.voting_count_sub = 0;
+ }
+ break;
+ case 3:
+ tmp1 = abs(st->eis.gyro_counter_s[0] - st->eis.gyro_counter);
+ if (tmp1 == 1) {
+ st->eis.gyro_counter_s[1] = st->eis.gyro_counter;
+ st->eis.fsync_delay_s[1] = delay - st->eis.fsync_delay;
+ st->eis.voting_state = 4;
+ st->eis.voting_count_sub = 1;
+ st->eis.voting_count = 1;
+ }
+ break;
+ case 4:
+ if (st->eis.gyro_counter == st->eis.gyro_counter_s[0]) {
+ tmp1 = delay - st->eis.fsync_delay;
+ tmp2 = abs(tmp1 - st->eis.fsync_delay_s[0]);
+ if (tmp2 < 3) {
+ st->eis.voting_count++;
+ } else {
+ st->eis.fsync_delay_s[2] = tmp1;
+ st->eis.voting_count_sub = 1;
+ st->eis.voting_state = 5;
+ }
+ if (st->eis.voting_count > 5) {
+ st->eis.voting_count = 1;
+ st->eis.voting_state = 6;
+ }
+ }
+ break;
+ case 5:
+ if (st->eis.gyro_counter == st->eis.gyro_counter_s[0]) {
+ tmp1 = delay - st->eis.fsync_delay;
+
+ tmp2 = abs(tmp1 - st->eis.fsync_delay_s[0]);
+ tmp3 = abs(tmp1 - st->eis.fsync_delay_s[2]);
+ if ((tmp2 < tmp3) && (tmp2 < 3))
+ st->eis.voting_count++;
+ else
+ st->eis.voting_count_sub++;
+ if ((st->eis.voting_count > 5) &&
+ (st->eis.voting_count_sub
+ < st->eis.voting_count)) {
+ st->eis.voting_state = 6;
+ st->eis.voting_count = 1;
+ } else if (st->eis.voting_count_sub > 5) {
+ st->eis.fsync_delay_s[0] = tmp1;
+ st->eis.voting_state = 4;
+ st->eis.voting_count = 1;
+ }
+
+ }
+ break;
+ case 6:
+ if (st->eis.gyro_counter == st->eis.gyro_counter_s[1]) {
+ tmp1 = delay - st->eis.fsync_delay;
+ tmp2 = abs(tmp1 - st->eis.fsync_delay_s[1]);
+ if (tmp2 < 3) {
+ st->eis.voting_count++;
+ } else {
+ st->eis.fsync_delay_s[2] = tmp1;
+ st->eis.voting_count_sub = 1;
+ st->eis.voting_count = 1;
+ st->eis.voting_state = 7;
+ }
+ if (st->eis.voting_count > 5)
+ st->eis.voting_state = 8;
+ }
+ break;
+ case 7:
+ if (st->eis.gyro_counter == st->eis.gyro_counter_s[1]) {
+ tmp1 = delay - st->eis.fsync_delay;
+
+ tmp2 = abs(tmp1 - st->eis.fsync_delay_s[1]);
+ tmp3 = abs(tmp1 - st->eis.fsync_delay_s[2]);
+ if ((tmp2 < tmp3) && (tmp2 < 3))
+ st->eis.voting_count++;
+ else
+ st->eis.voting_count_sub++;
+ if ((st->eis.voting_count > 5) &&
+ (st->eis.voting_count_sub
+ < st->eis.voting_count)) {
+ st->eis.voting_state = 8;
+ } else if (st->eis.voting_count_sub > 5) {
+ st->eis.fsync_delay_s[1] = tmp1;
+ st->eis.voting_state = 6;
+ st->eis.voting_count = 1;
+ }
+
+ }
+ break;
+ default:
+ break;
+ }
+
+ pr_debug("de= %d gc= %d\n", delay, st->eis.gyro_counter);
+ st->eis.fsync_delay = delay;
+ st->eis.gyro_counter = 0;
+
+ pr_debug("state=%d g1= %d d1= %d g2= %d d2= %d\n",
+ st->eis.voting_state,
+ st->eis.gyro_counter_s[0],
+ st->eis.fsync_delay_s[0],
+ st->eis.gyro_counter_s[1],
+ st->eis.fsync_delay_s[1]);
+
+ return 0;
+}
+
+int inv_rate_convert(struct inv_mpu_state *st, int ind, int data)
+{
+ int t, out, out1, out2;
+ int base_freq;
+
+ if (data <= MPU_DEFAULT_DMP_FREQ)
+ base_freq = MPU_DEFAULT_DMP_FREQ;
+ else
+ base_freq = BASE_SAMPLE_RATE;
+
+ t = base_freq / data;
+ if (!t)
+ t = 1;
+ out1 = base_freq / (t + 1);
+ out2 = base_freq / t;
+ if ((data - out1) * INV_ODR_BUFFER_MULTI < data)
+ out = out1;
+ else
+ out = out2;
+
+ return out;
+}
+
+static void inv_check_wake_non_wake(struct inv_mpu_state *st,
+ enum SENSOR_L wake, enum SENSOR_L non_wake)
+{
+ int tmp_rate;
+
+ if (!st->sensor_l[wake].on && !st->sensor_l[non_wake].on)
+ return;
+
+ tmp_rate = MPU_INIT_SENSOR_RATE;
+ if (st->sensor_l[wake].on)
+ tmp_rate = st->sensor_l[wake].rate;
+ if (st->sensor_l[non_wake].on)
+ tmp_rate = max(tmp_rate, st->sensor_l[non_wake].rate);
+ st->sensor_l[wake].rate = tmp_rate;
+ st->sensor_l[non_wake].rate = tmp_rate;
+}
+
+static void inv_check_wake_non_wake_divider(struct inv_mpu_state *st,
+ enum SENSOR_L wake, enum SENSOR_L non_wake)
+{
+ if (st->sensor_l[wake].on && st->sensor_l[non_wake].on)
+ st->sensor_l[non_wake].div = 0xffff;
+
+}
+
+#if defined(CONFIG_INV_MPU_IIO_ICM20602) \
+ || defined(CONFIG_INV_MPU_IIO_ICM20690) \
+ || defined(CONFIG_INV_MPU_IIO_IAM20680)
+int inv_check_sensor_on(struct inv_mpu_state *st)
+{
+ int i, max_rate;
+ enum SENSOR_L wake[] = {SENSOR_L_GYRO_WAKE, SENSOR_L_ACCEL_WAKE,
+ SENSOR_L_MAG_WAKE};
+ enum SENSOR_L non_wake[] = {SENSOR_L_GYRO, SENSOR_L_ACCEL,
+ SENSOR_L_MAG};
+
+ st->sensor_l[SENSOR_L_GESTURE_ACCEL].rate = GESTURE_ACCEL_RATE;
+ for (i = 0; i < SENSOR_NUM_MAX; i++)
+ st->sensor[i].on = false;
+ for (i = 0; i < SENSOR_NUM_MAX; i++)
+ st->sensor[i].rate = MPU_INIT_SENSOR_RATE;
+
+ if ((st->step_detector_l_on
+ || st->step_detector_wake_l_on
+ || st->step_counter_l_on
+ || st->step_counter_wake_l_on
+ || st->chip_config.pick_up_enable
+ || st->chip_config.tilt_enable)
+ && (!st->sensor_l[SENSOR_L_ACCEL].on)
+ && (!st->sensor_l[SENSOR_L_ACCEL_WAKE].on))
+ st->sensor_l[SENSOR_L_GESTURE_ACCEL].on = true;
+ else
+ st->sensor_l[SENSOR_L_GESTURE_ACCEL].on = false;
+
+
+ st->chip_config.wake_on = false;
+ for (i = 0; i < SENSOR_L_NUM_MAX; i++) {
+ if (st->sensor_l[i].on && st->sensor_l[i].rate) {
+ st->sensor[st->sensor_l[i].base].on = true;
+ st->chip_config.wake_on |= st->sensor_l[i].wake_on;
+ }
+ }
+ if (st->sensor_l[SENSOR_L_GESTURE_ACCEL].on &&
+ (!st->sensor[SENSOR_GYRO].on) &&
+ (!st->sensor[SENSOR_COMPASS].on))
+ st->gesture_only_on = true;
+ else
+ st->gesture_only_on = false;
+
+ for (i = 0; i < SENSOR_L_NUM_MAX; i++) {
+ if (st->sensor_l[i].on) {
+ st->sensor[st->sensor_l[i].base].rate =
+ max(st->sensor[st->sensor_l[i].base].rate,
+ st->sensor_l[i].rate);
+ }
+ }
+ max_rate = MPU_INIT_SENSOR_RATE;
+ if (st->chip_config.eis_enable) {
+ max_rate = ESI_GYRO_RATE;
+ st->sensor_l[SENSOR_L_EIS_GYRO].rate = ESI_GYRO_RATE;
+ }
+
+ for (i = 0; i < SENSOR_NUM_MAX; i++) {
+ if (st->sensor[i].on) {
+ max_rate = max(max_rate, st->sensor[i].rate);
+ }
+ }
+ for (i = 0; i < SENSOR_NUM_MAX; i++) {
+ if (st->sensor[i].on) {
+ st->sensor[i].rate = max_rate;
+ }
+ }
+ for (i = 0; i < ARRAY_SIZE(wake); i++)
+ inv_check_wake_non_wake(st, wake[i], non_wake[i]);
+
+ for (i = 0; i < SENSOR_L_NUM_MAX; i++) {
+ if (st->sensor_l[i].on) {
+ if (st->sensor_l[i].rate)
+ st->sensor_l[i].div =
+ st->sensor[st->sensor_l[i].base].rate
+ / st->sensor_l[i].rate;
+ else
+ st->sensor_l[i].div = 0xffff;
+ pr_debug("sensor= %d, div= %d\n",
+ i, st->sensor_l[i].div);
+ }
+ }
+ for (i = 0; i < ARRAY_SIZE(wake); i++)
+ inv_check_wake_non_wake_divider(st, wake[i], non_wake[i]);
+
+ if (st->step_detector_wake_l_on ||
+ st->step_counter_wake_l_on ||
+ st->chip_config.pick_up_enable ||
+ st->chip_config.tilt_enable)
+ st->chip_config.wake_on = true;
+
+ return 0;
+}
+#else
+static void inv_do_check_sensor_on(struct inv_mpu_state *st,
+ enum SENSOR_L *wake,
+ enum SENSOR_L *non_wake, int sensor_size)
+{
+ int i;
+
+ for (i = 0; i < SENSOR_NUM_MAX; i++)
+ st->sensor[i].on = false;
+
+ for (i = 0; i < SENSOR_NUM_MAX; i++)
+ st->sensor[i].rate = MPU_INIT_SENSOR_RATE;
+
+ st->chip_config.wake_on = false;
+ for (i = 0; i < SENSOR_L_NUM_MAX; i++) {
+ if (st->sensor_l[i].on && st->sensor_l[i].rate) {
+ st->sensor[st->sensor_l[i].base].on = true;
+ st->chip_config.wake_on |= st->sensor_l[i].wake_on;
+ }
+ }
+
+ for (i = 0; i < SENSOR_L_NUM_MAX; i++) {
+ if (st->sensor_l[i].on) {
+ st->sensor[st->sensor_l[i].base].rate =
+ max(st->sensor[st->sensor_l[i].base].rate,
+ st->sensor_l[i].rate);
+ }
+ }
+ for (i = 0; i < sensor_size; i++)
+ inv_check_wake_non_wake(st, wake[i], non_wake[i]);
+
+ for (i = 0; i < SENSOR_L_NUM_MAX; i++) {
+ if (st->sensor_l[i].on) {
+ if (st->sensor_l[i].rate)
+ st->sensor_l[i].div =
+ st->sensor[st->sensor_l[i].base].rate
+ / st->sensor_l[i].rate;
+ else
+ st->sensor_l[i].div = 0xffff;
+ }
+ }
+ for (i = 0; i < sensor_size; i++)
+ inv_check_wake_non_wake_divider(st, wake[i], non_wake[i]);
+
+ if (st->step_detector_wake_l_on ||
+ st->step_counter_wake_l_on ||
+ st->chip_config.pick_up_enable ||
+ st->chip_config.tilt_enable ||
+ st->smd.on)
+ st->chip_config.wake_on = true;
+
+}
+#endif
+
+#if defined(CONFIG_INV_MPU_IIO_ICM20608D)
+int inv_check_sensor_on(struct inv_mpu_state *st)
+{
+ enum SENSOR_L wake[] = {SENSOR_L_GYRO_WAKE, SENSOR_L_ACCEL_WAKE,
+ SENSOR_L_SIXQ_WAKE, SENSOR_L_PEDQ_WAKE,
+ SENSOR_L_GYRO_CAL_WAKE};
+ enum SENSOR_L non_wake[] = {SENSOR_L_GYRO, SENSOR_L_ACCEL,
+ SENSOR_L_SIXQ, SENSOR_L_PEDQ,
+ SENSOR_L_GYRO_CAL};
+
+ inv_do_check_sensor_on(st, wake, non_wake, ARRAY_SIZE(wake));
+
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_INV_MPU_IIO_ICM20648)
+int inv_check_sensor_on(struct inv_mpu_state *st)
+{
+ enum SENSOR_L wake[] = {SENSOR_L_GYRO_WAKE, SENSOR_L_ACCEL_WAKE,
+ SENSOR_L_MAG_WAKE, SENSOR_L_ALS_WAKE,
+ SENSOR_L_SIXQ_WAKE, SENSOR_L_PEDQ_WAKE,
+ SENSOR_L_NINEQ_WAKE, SENSOR_L_GEOMAG_WAKE,
+ SENSOR_L_PRESSURE_WAKE,
+ SENSOR_L_GYRO_CAL_WAKE,
+ SENSOR_L_MAG_CAL_WAKE};
+ enum SENSOR_L non_wake[] = {SENSOR_L_GYRO, SENSOR_L_ACCEL,
+ SENSOR_L_MAG, SENSOR_L_ALS,
+ SENSOR_L_SIXQ, SENSOR_L_PEDQ,
+ SENSOR_L_NINEQ, SENSOR_L_GEOMAG,
+ SENSOR_L_PRESSURE,
+ SENSOR_L_GYRO_CAL,
+ SENSOR_L_MAG_CAL};
+
+ inv_do_check_sensor_on(st, wake, non_wake, ARRAY_SIZE(wake));
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+int inv_mpu_suspend(struct iio_dev *indio_dev)
+{
+ struct inv_mpu_state *st = iio_priv(indio_dev);
+
+ /* add code according to different request Start */
+ dev_info(st->dev, "%s suspend\n", st->hw->name);
+ mutex_lock(&indio_dev->mlock);
+
+ st->resume_state = false;
+ if (st->chip_config.wake_on) {
+ enable_irq_wake(st->irq);
+ } else {
+ inv_stop_interrupt(st);
+ }
+
+ mutex_unlock(&indio_dev->mlock);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(inv_mpu_suspend);
+
+/*
+ * inv_mpu_complete(): complete method for this driver.
+ * This method can be modified according to the request of different
+ * customers. It basically undo everything suspend is doing
+ * and recover the chip to what it was before suspend. We use complete to
+ * make sure that alarm clock resume is finished. If we use resume, the
+ * alarm clock may not resume yet and get incorrect clock reading.
+ */
+void inv_mpu_complete(struct iio_dev *indio_dev)
+{
+ struct inv_mpu_state *st = iio_priv(indio_dev);
+
+ dev_info(st->dev, "%s resume\n", st->hw->name);
+ if (st->resume_state)
+ return;
+
+ mutex_lock(&indio_dev->mlock);
+
+ if (!st->chip_config.wake_on) {
+ inv_reenable_interrupt(st);
+ } else {
+ disable_irq_wake(st->irq);
+ }
+ /* resume state is used to synchronize read_fifo such that it won't
+ proceed unless resume is finished. */
+ st->resume_state = true;
+ /* resume flag is indicating that current clock reading is from resume,
+ it has up to 1 second drift and should do proper processing */
+ st->ts_algo.resume_flag = true;
+ mutex_unlock(&indio_dev->mlock);
+ wake_up_interruptible(&st->wait_queue);
+
+ return;
+}
+EXPORT_SYMBOL_GPL(inv_mpu_complete);
+#endif
diff --git a/drivers/iio/imu/inv_mpu/inv_mpu_dts.c b/drivers/iio/imu/inv_mpu/inv_mpu_dts.c
new file mode 100644
index 0000000..0b8b3fc
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu/inv_mpu_dts.c
@@ -0,0 +1,343 @@
+/*
+ * Copyright (C) 2012-2017 InvenSense, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/of_gpio.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/export.h>
+
+#include <linux/iio/imu/mpu.h>
+#include "inv_mpu_dts.h"
+#include "inv_mpu_iio.h"
+
+#ifdef CONFIG_OF
+
+static int inv_mpu_power_on(struct mpu_platform_data *pdata)
+{
+ int err;
+
+ if (!IS_ERR(pdata->vdd_ana)) {
+ err = regulator_enable(pdata->vdd_ana);
+ if (err)
+ return err;
+ }
+ if (!IS_ERR(pdata->vdd_i2c)) {
+ err = regulator_enable(pdata->vdd_i2c);
+ if (err)
+ goto error_disable_vdd_ana;
+ }
+
+ return 0;
+
+error_disable_vdd_ana:
+ regulator_disable(pdata->vdd_ana);
+ return err;
+}
+
+static int inv_mpu_power_off(struct mpu_platform_data *pdata)
+{
+ if (!IS_ERR(pdata->vdd_ana))
+ regulator_disable(pdata->vdd_ana);
+ if (!IS_ERR(pdata->vdd_i2c))
+ regulator_disable(pdata->vdd_i2c);
+
+ return 0;
+}
+
+static int inv_parse_orientation_matrix(struct device *dev, s8 *orient)
+{
+ int rc, i;
+ struct device_node *np = dev->of_node;
+ u32 temp_val, temp_val2;
+
+ for (i = 0; i < 9; i++)
+ orient[i] = 0;
+
+ /* parsing axis x orientation matrix */
+ rc = of_property_read_u32(np, "axis_map_x", &temp_val);
+ if (rc) {
+ dev_err(dev, "Unable to read axis_map_x\n");
+ return rc;
+ }
+ rc = of_property_read_u32(np, "negate_x", &temp_val2);
+ if (rc) {
+ dev_err(dev, "Unable to read negate_x\n");
+ return rc;
+ }
+ if (temp_val2)
+ orient[temp_val] = -1;
+ else
+ orient[temp_val] = 1;
+
+ /* parsing axis y orientation matrix */
+ rc = of_property_read_u32(np, "axis_map_y", &temp_val);
+ if (rc) {
+ dev_err(dev, "Unable to read axis_map_y\n");
+ return rc;
+ }
+ rc = of_property_read_u32(np, "negate_y", &temp_val2);
+ if (rc) {
+ dev_err(dev, "Unable to read negate_y\n");
+ return rc;
+ }
+ if (temp_val2)
+ orient[3 + temp_val] = -1;
+ else
+ orient[3 + temp_val] = 1;
+
+ /* parsing axis z orientation matrix */
+ rc = of_property_read_u32(np, "axis_map_z", &temp_val);
+ if (rc) {
+ dev_err(dev, "Unable to read axis_map_z\n");
+ return rc;
+ }
+ rc = of_property_read_u32(np, "negate_z", &temp_val2);
+ if (rc) {
+ dev_err(dev, "Unable to read negate_z\n");
+ return rc;
+ }
+ if (temp_val2)
+ orient[6 + temp_val] = -1;
+ else
+ orient[6 + temp_val] = 1;
+
+ return 0;
+}
+
+static int inv_parse_secondary_orientation_matrix(struct device *dev,
+ s8 *orient)
+{
+ int rc, i;
+ struct device_node *np = dev->of_node;
+ u32 temp_val, temp_val2;
+
+ for (i = 0; i < 9; i++)
+ orient[i] = 0;
+
+ /* parsing axis x orientation matrix */
+ rc = of_property_read_u32(np, "inven,secondary_axis_map_x", &temp_val);
+ if (rc) {
+ dev_err(dev, "Unable to read secondary axis_map_x\n");
+ return rc;
+ }
+ rc = of_property_read_u32(np, "inven,secondary_negate_x", &temp_val2);
+ if (rc) {
+ dev_err(dev, "Unable to read secondary negate_x\n");
+ return rc;
+ }
+ if (temp_val2)
+ orient[temp_val] = -1;
+ else
+ orient[temp_val] = 1;
+
+ /* parsing axis y orientation matrix */
+ rc = of_property_read_u32(np, "inven,secondary_axis_map_y", &temp_val);
+ if (rc) {
+ dev_err(dev, "Unable to read secondary axis_map_y\n");
+ return rc;
+ }
+ rc = of_property_read_u32(np, "inven,secondary_negate_y", &temp_val2);
+ if (rc) {
+ dev_err(dev, "Unable to read secondary negate_y\n");
+ return rc;
+ }
+ if (temp_val2)
+ orient[3 + temp_val] = -1;
+ else
+ orient[3 + temp_val] = 1;
+
+ /* parsing axis z orientation matrix */
+ rc = of_property_read_u32(np, "inven,secondary_axis_map_z", &temp_val);
+ if (rc) {
+ dev_err(dev, "Unable to read secondary axis_map_z\n");
+ return rc;
+ }
+ rc = of_property_read_u32(np, "inven,secondary_negate_z", &temp_val2);
+ if (rc) {
+ dev_err(dev, "Unable to read secondary negate_z\n");
+ return rc;
+ }
+ if (temp_val2)
+ orient[6 + temp_val] = -1;
+ else
+ orient[6 + temp_val] = 1;
+
+ return 0;
+}
+
+static int inv_parse_secondary(struct device *dev,
+ struct mpu_platform_data *pdata)
+{
+ int rc;
+ struct device_node *np = dev->of_node;
+ u32 temp_val;
+ const char *name;
+
+ if (of_property_read_string(np, "inven,secondary_type", &name)) {
+ dev_err(dev, "Missing secondary type.\n");
+ return -EINVAL;
+ }
+ if (!strcmp(name, "compass")) {
+ pdata->sec_slave_type = SECONDARY_SLAVE_TYPE_COMPASS;
+ } else if (!strcmp(name, "none")) {
+ pdata->sec_slave_type = SECONDARY_SLAVE_TYPE_NONE;
+ return 0;
+ } else {
+ return -EINVAL;
+ }
+
+ if (of_property_read_string(np, "inven,secondary_name", &name)) {
+ dev_err(dev, "Missing secondary name.\n");
+ return -EINVAL;
+ }
+ if (!strcmp(name, "ak8963"))
+ pdata->sec_slave_id = COMPASS_ID_AK8963;
+ else if (!strcmp(name, "ak8975"))
+ pdata->sec_slave_id = COMPASS_ID_AK8975;
+ else if (!strcmp(name, "ak8972"))
+ pdata->sec_slave_id = COMPASS_ID_AK8972;
+ else if (!strcmp(name, "ak09911"))
+ pdata->sec_slave_id = COMPASS_ID_AK09911;
+ else if (!strcmp(name, "ak09912"))
+ pdata->sec_slave_id = COMPASS_ID_AK09912;
+ else if (!strcmp(name, "ak09916"))
+ pdata->sec_slave_id = COMPASS_ID_AK09916;
+ else
+ return -EINVAL;
+ rc = of_property_read_u32(np, "inven,secondary_reg", &temp_val);
+ if (rc) {
+ dev_err(dev, "Unable to read secondary register\n");
+ return rc;
+ }
+ pdata->secondary_i2c_addr = temp_val;
+ rc = inv_parse_secondary_orientation_matrix(dev,
+ pdata->
+ secondary_orientation);
+
+ return rc;
+}
+
+static int inv_parse_aux(struct device *dev, struct mpu_platform_data *pdata)
+{
+ int rc;
+ struct device_node *np = dev->of_node;
+ u32 temp_val;
+ const char *name;
+
+ if (of_property_read_string(np, "inven,aux_type", &name)) {
+ dev_err(dev, "Missing aux type.\n");
+ return -EINVAL;
+ }
+ if (!strcmp(name, "pressure")) {
+ pdata->aux_slave_type = SECONDARY_SLAVE_TYPE_PRESSURE;
+ } else if (!strcmp(name, "none")) {
+ pdata->aux_slave_type = SECONDARY_SLAVE_TYPE_NONE;
+ return 0;
+ } else {
+ return -EINVAL;
+ }
+
+ if (of_property_read_string(np, "inven,aux_name", &name)) {
+ dev_err(dev, "Missing aux name.\n");
+ return -EINVAL;
+ }
+ if (!strcmp(name, "bmp280"))
+ pdata->aux_slave_id = PRESSURE_ID_BMP280;
+ else
+ return -EINVAL;
+
+ rc = of_property_read_u32(np, "inven,aux_reg", &temp_val);
+ if (rc) {
+ dev_err(dev, "Unable to read aux register\n");
+ return rc;
+ }
+ pdata->aux_i2c_addr = temp_val;
+
+ return 0;
+}
+
+static int inv_parse_readonly_secondary(struct device *dev,
+ struct mpu_platform_data *pdata)
+{
+ int rc;
+ struct device_node *np = dev->of_node;
+ u32 temp_val;
+ const char *name;
+
+ if (of_property_read_string(np, "inven,read_only_slave_type", &name)) {
+ dev_err(dev, "Missing read only slave type type.\n");
+ return -EINVAL;
+ }
+ if (!strcmp(name, "als")) {
+ pdata->read_only_slave_type = SECONDARY_SLAVE_TYPE_ALS;
+ } else if (!strcmp(name, "none")) {
+ pdata->read_only_slave_type = SECONDARY_SLAVE_TYPE_NONE;
+ return 0;
+ } else {
+ return -EINVAL;
+ }
+
+ if (of_property_read_string(np, "inven,read_only_slave_name", &name)) {
+ dev_err(dev, "Missing read only slave type name.\n");
+ return -EINVAL;
+ }
+ if (!strcmp(name, "apds9930"))
+ pdata->read_only_slave_id = ALS_ID_APDS_9930;
+ else
+ return -EINVAL;
+
+ rc = of_property_read_u32(np, "inven,read_only_slave_reg", &temp_val);
+ if (rc) {
+ dev_err(dev, "Unable to read read only slave reg register\n");
+ return rc;
+ }
+ pdata->read_only_i2c_addr = temp_val;
+
+ return 0;
+}
+
+int invensense_mpu_parse_dt(struct device *dev, struct mpu_platform_data *pdata)
+{
+ int rc;
+
+ rc = inv_parse_orientation_matrix(dev, pdata->orientation);
+ if (rc)
+ return rc;
+ rc = inv_parse_secondary(dev, pdata);
+ if (rc)
+ return rc;
+ inv_parse_aux(dev, pdata);
+
+ inv_parse_readonly_secondary(dev, pdata);
+
+ pdata->vdd_ana = regulator_get(dev, "inven,vdd_ana");
+ if (IS_ERR(pdata->vdd_ana)) {
+ rc = PTR_ERR(pdata->vdd_ana);
+ dev_warn(dev, "regulator get failed vdd_ana-supply rc=%d\n", rc);
+ }
+ pdata->vdd_i2c = regulator_get(dev, "inven,vcc_i2c");
+ if (IS_ERR(pdata->vdd_i2c)) {
+ rc = PTR_ERR(pdata->vdd_i2c);
+ dev_warn(dev, "regulator get failed vcc-i2c-supply rc=%d\n", rc);
+ }
+ pdata->power_on = inv_mpu_power_on;
+ pdata->power_off = inv_mpu_power_off;
+ dev_dbg(dev, "parse dt complete\n");
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(invensense_mpu_parse_dt);
+
+#endif /* CONFIG_OF */
diff --git a/drivers/iio/imu/inv_mpu/inv_mpu_dts.h b/drivers/iio/imu/inv_mpu/inv_mpu_dts.h
new file mode 100644
index 0000000..90966fe
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu/inv_mpu_dts.h
@@ -0,0 +1,25 @@
+/*
+* Copyright (C) 2012-2017 InvenSense, Inc.
+*
+* This software is licensed under the terms of the GNU General Public
+* License version 2, as published by the Free Software Foundation, and
+* may be copied, distributed, and modified under those terms.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*/
+
+#ifndef _INV_MPU_DTS_H_
+#define _INV_MPU_DTS_H_
+
+#include <linux/kernel.h>
+#include <linux/iio/imu/mpu.h>
+
+#ifdef CONFIG_OF
+int invensense_mpu_parse_dt(struct device *dev,
+ struct mpu_platform_data *pdata);
+#endif
+
+#endif /* #ifndef _INV_MPU_DTS_H_ */
diff --git a/drivers/iio/imu/inv_mpu/inv_mpu_i2c.c b/drivers/iio/imu/inv_mpu/inv_mpu_i2c.c
new file mode 100644
index 0000000..e7838fc
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu/inv_mpu_i2c.c
@@ -0,0 +1,556 @@
+/*
+* Copyright (C) 2012-2018 InvenSense, Inc.
+*
+* This software is licensed under the terms of the GNU General Public
+* License version 2, as published by the Free Software Foundation, and
+* may be copied, distributed, and modified under those terms.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*/
+#define pr_fmt(fmt) "inv_mpu: " fmt
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/sysfs.h>
+#include <linux/jiffies.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/kfifo.h>
+#include <linux/poll.h>
+#include <linux/miscdevice.h>
+#include <linux/spinlock.h>
+
+#include "inv_mpu_iio.h"
+#include "inv_mpu_dts.h"
+
+#define CONFIG_DYNAMIC_DEBUG_I2C 0
+
+/**
+ * inv_i2c_read_base() - Read one or more bytes from the device registers.
+ * @st: Device driver instance.
+ * @i2c_addr: i2c address of device.
+ * @reg: First device register to be read from.
+ * @length: Number of bytes to read.
+ * @data: Data read from device.
+ * NOTE:This is not re-implementation of i2c_smbus_read because i2c
+ * address could be specified in this case. We could have two different
+ * i2c address due to secondary i2c interface.
+ */
+int inv_i2c_read_base(struct inv_mpu_state *st, u16 i2c_addr,
+ u8 reg, u16 length, u8 *data)
+{
+ struct i2c_msg msgs[2];
+ int res;
+
+ if (!data)
+ return -EINVAL;
+
+ msgs[0].addr = i2c_addr;
+ msgs[0].flags = 0; /* write */
+ msgs[0].buf = ®
+ msgs[0].len = 1;
+
+ msgs[1].addr = i2c_addr;
+ msgs[1].flags = I2C_M_RD;
+ msgs[1].buf = data;
+ msgs[1].len = length;
+
+ res = i2c_transfer(st->sl_handle, msgs, 2);
+
+ if (res < 2) {
+ if (res >= 0)
+ res = -EIO;
+ } else
+ res = 0;
+ INV_I2C_INC_MPUWRITE(3);
+ INV_I2C_INC_MPUREAD(length);
+
+ return res;
+}
+
+/**
+ * inv_i2c_single_write_base() - Write a byte to a device register.
+ * @st: Device driver instance.
+ * @i2c_addr: I2C address of the device.
+ * @reg: Device register to be written to.
+ * @data: Byte to write to device.
+ * NOTE:This is not re-implementation of i2c_smbus_write because i2c
+ * address could be specified in this case. We could have two different
+ * i2c address due to secondary i2c interface.
+ */
+int inv_i2c_single_write_base(struct inv_mpu_state *st,
+ u16 i2c_addr, u8 reg, u8 data)
+{
+ u8 tmp[2];
+ struct i2c_msg msg;
+ int res;
+
+ tmp[0] = reg;
+ tmp[1] = data;
+
+ msg.addr = i2c_addr;
+ msg.flags = 0; /* write */
+ msg.buf = tmp;
+ msg.len = 2;
+
+ INV_I2C_INC_MPUWRITE(3);
+
+ res = i2c_transfer(st->sl_handle, &msg, 1);
+ if (res < 1) {
+ if (res == 0)
+ res = -EIO;
+ return res;
+ } else
+ return 0;
+}
+
+static int inv_i2c_single_write(struct inv_mpu_state *st, u8 reg, u8 data)
+{
+ return inv_i2c_single_write_base(st, st->i2c_addr, reg, data);
+}
+
+static int inv_i2c_read(struct inv_mpu_state *st, u8 reg, int len, u8 *data)
+{
+ return inv_i2c_read_base(st, st->i2c_addr, reg, len, data);
+}
+
+static int _memory_write(struct inv_mpu_state *st, u8 mpu_addr, u16 mem_addr,
+ u32 len, u8 const *data)
+{
+ u8 bank[2];
+ u8 addr[2];
+ u8 buf[513];
+
+ struct i2c_msg msgs[3];
+ int res;
+
+ if (!data || !st)
+ return -EINVAL;
+
+ if (len >= (sizeof(buf) - 1))
+ return -ENOMEM;
+
+ bank[0] = REG_MEM_BANK_SEL;
+ bank[1] = mem_addr >> 8;
+
+ addr[0] = REG_MEM_START_ADDR;
+ addr[1] = mem_addr & 0xFF;
+
+ buf[0] = REG_MEM_R_W;
+ memcpy(buf + 1, data, len);
+
+ /* write message */
+ msgs[0].addr = mpu_addr;
+ msgs[0].flags = 0;
+ msgs[0].buf = bank;
+ msgs[0].len = sizeof(bank);
+
+ msgs[1].addr = mpu_addr;
+ msgs[1].flags = 0;
+ msgs[1].buf = addr;
+ msgs[1].len = sizeof(addr);
+
+ msgs[2].addr = mpu_addr;
+ msgs[2].flags = 0;
+ msgs[2].buf = (u8 *) buf;
+ msgs[2].len = len + 1;
+
+ INV_I2C_INC_MPUWRITE(3 + 3 + (2 + len));
+
+#if CONFIG_DYNAMIC_DEBUG_I2C
+ {
+ char *write = 0;
+ pr_debug("%s WM%02X%02X%02X%s%s - %d\n", st->hw->name,
+ mpu_addr, bank[1], addr[1],
+ wr_pr_debug_begin(data, len, write),
+ wr_pr_debug_end(write), len);
+ }
+#endif
+
+ res = i2c_transfer(st->sl_handle, msgs, 3);
+ if (res != 3) {
+ if (res >= 0)
+ res = -EIO;
+ return res;
+ } else {
+ return 0;
+ }
+}
+
+static int inv_i2c_mem_write(struct inv_mpu_state *st, u8 mpu_addr, u16 mem_addr,
+ u32 len, u8 const *data)
+{
+ int r, i, j;
+#define DMP_MEM_CMP_SIZE 16
+ u8 w[DMP_MEM_CMP_SIZE];
+ bool retry;
+
+ j = 0;
+ retry = true;
+ while ((j < 3) && retry) {
+ retry = false;
+ r = _memory_write(st, mpu_addr, mem_addr, len, data);
+ if (len < DMP_MEM_CMP_SIZE) {
+ r = mem_r(mem_addr, len, w);
+ for (i = 0; i < len; i++) {
+ if (data[i] != w[i]) {
+ pr_debug
+ ("error write=%x, len=%d,data=%x, w=%x, i=%d\n",
+ mem_addr, len, data[i], w[i], i);
+ retry = true;
+ }
+ }
+ }
+ j++;
+ }
+
+ return r;
+}
+
+static int inv_i2c_mem_read(struct inv_mpu_state *st, u8 mpu_addr, u16 mem_addr,
+ u32 len, u8 *data)
+{
+ u8 bank[2];
+ u8 addr[2];
+ u8 buf;
+
+ struct i2c_msg msgs[4];
+ int res;
+
+ if (!data || !st)
+ return -EINVAL;
+
+ bank[0] = REG_MEM_BANK_SEL;
+ bank[1] = mem_addr >> 8;
+
+ addr[0] = REG_MEM_START_ADDR;
+ addr[1] = mem_addr & 0xFF;
+
+ buf = REG_MEM_R_W;
+
+ /* write message */
+ msgs[0].addr = mpu_addr;
+ msgs[0].flags = 0;
+ msgs[0].buf = bank;
+ msgs[0].len = sizeof(bank);
+
+ msgs[1].addr = mpu_addr;
+ msgs[1].flags = 0;
+ msgs[1].buf = addr;
+ msgs[1].len = sizeof(addr);
+
+ msgs[2].addr = mpu_addr;
+ msgs[2].flags = 0;
+ msgs[2].buf = &buf;
+ msgs[2].len = 1;
+
+ msgs[3].addr = mpu_addr;
+ msgs[3].flags = I2C_M_RD;
+ msgs[3].buf = data;
+ msgs[3].len = len;
+
+ res = i2c_transfer(st->sl_handle, msgs, 4);
+ if (res != 4) {
+ if (res >= 0)
+ res = -EIO;
+ } else
+ res = 0;
+ INV_I2C_INC_MPUWRITE(3 + 3 + 3);
+ INV_I2C_INC_MPUREAD(len);
+
+#if CONFIG_DYNAMIC_DEBUG_I2C
+ {
+ char *read = 0;
+ pr_debug("%s RM%02X%02X%02X%02X - %s%s\n", st->hw->name,
+ mpu_addr, bank[1], addr[1], len,
+ wr_pr_debug_begin(data, len, read),
+ wr_pr_debug_end(read));
+ }
+#endif
+
+ return res;
+}
+
+/*
+ * inv_mpu_probe() - probe function.
+ */
+static int inv_mpu_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct inv_mpu_state *st;
+ struct iio_dev *indio_dev;
+ int result;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ result = -ENOSYS;
+ pr_err("I2c function error\n");
+ goto out_no_free;
+ }
+
+#ifdef KERNEL_VERSION_4_X
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
+ if (indio_dev == NULL) {
+ pr_err("memory allocation failed\n");
+ result = -ENOMEM;
+ goto out_no_free;
+ }
+#else
+ indio_dev = iio_device_alloc(sizeof(*st));
+ if (indio_dev == NULL) {
+ pr_err("memory allocation failed\n");
+ result = -ENOMEM;
+ goto out_no_free;
+ }
+#endif
+ st = iio_priv(indio_dev);
+ st->client = client;
+ st->sl_handle = client->adapter;
+ st->i2c_addr = client->addr;
+ st->write = inv_i2c_single_write;
+ st->read = inv_i2c_read;
+ st->mem_write = inv_i2c_mem_write;
+ st->mem_read = inv_i2c_mem_read;
+ st->dev = &client->dev;
+ st->bus_type = BUS_I2C;
+#ifdef CONFIG_OF
+ result = invensense_mpu_parse_dt(st->dev, &st->plat_data);
+ if (result)
+# ifdef KERNEL_VERSION_4_X
+ return -ENODEV;
+# else
+ goto out_free;
+# endif
+
+ /* Power on device */
+ if (st->plat_data.power_on) {
+ result = st->plat_data.power_on(&st->plat_data);
+ if (result < 0) {
+ dev_err(st->dev, "power_on failed: %d\n", result);
+# ifdef KERNEL_VERSION_4_X
+ return -ENODEV;
+# else
+ goto out_free;
+# endif
+ }
+ pr_info("%s: power on here.\n", __func__);
+ }
+ pr_info("%s: power on.\n", __func__);
+
+ msleep(100);
+#else
+ if (dev_get_platdata(st->dev) == NULL)
+# ifdef KERNEL_VERSION_4_X
+ return -ENODEV;
+# else
+ goto out_free;
+# endif
+ st->plat_data = *(struct mpu_platform_data *)dev_get_platdata(st->dev);
+#endif
+
+ /* power is turned on inside check chip type */
+ result = inv_check_chip_type(indio_dev, id->name);
+ if (result)
+#ifdef KERNEL_VERSION_4_X
+ return -ENODEV;
+#else
+ goto out_free;
+#endif
+
+ /* Make state variables available to all _show and _store functions. */
+ i2c_set_clientdata(client, indio_dev);
+ indio_dev->dev.parent = st->dev;
+ indio_dev->name = id->name;
+
+ st->irq = client->irq;
+
+ result = inv_mpu_configure_ring(indio_dev);
+ if (result) {
+ pr_err("configure ring buffer fail\n");
+ goto out_free;
+ }
+#ifdef KERNEL_VERSION_4_X
+ INV_I2C_SETIRQ(IRQ_MPU, st->irq);
+ result = devm_iio_device_register(st->dev, indio_dev);
+ if (result) {
+ pr_err("IIO device register fail\n");
+ goto out_unreg_ring;
+ }
+#else
+ result = iio_buffer_register(indio_dev, indio_dev->channels,
+ indio_dev->num_channels);
+ if (result) {
+ pr_err("ring buffer register fail\n");
+ goto out_unreg_ring;
+ }
+ INV_I2C_SETIRQ(IRQ_MPU, client->irq);
+ result = iio_device_register(indio_dev);
+ if (result) {
+ pr_err("IIO device register fail\n");
+ goto out_remove_ring;
+ }
+#endif
+
+ result = inv_create_dmp_sysfs(indio_dev);
+ if (result) {
+ pr_err("create dmp sysfs failed\n");
+ goto out_unreg_iio;
+ }
+ init_waitqueue_head(&st->wait_queue);
+ st->resume_state = true;
+#ifdef CONFIG_HAS_WAKELOCK
+ wake_lock_init(&st->wake_lock, WAKE_LOCK_SUSPEND, "inv_mpu");
+#else
+ wakeup_source_init(&st->wake_lock, "inv_mpu");
+#endif
+ dev_info(st->dev, "%s ma-kernel-%s is ready to go!\n",
+ indio_dev->name, INVENSENSE_DRIVER_VERSION);
+
+#ifdef SENSOR_DATA_FROM_REGISTERS
+ pr_info("Data read from registers\n");
+#else
+ pr_info("Data read from FIFO\n");
+#endif
+#ifdef TIMER_BASED_BATCHING
+ pr_info("Timer based batching\n");
+#endif
+
+ return 0;
+#ifdef KERNEL_VERSION_4_X
+out_unreg_iio:
+ devm_iio_device_unregister(st->dev, indio_dev);
+out_unreg_ring:
+ inv_mpu_unconfigure_ring(indio_dev);
+out_free:
+ devm_iio_device_free(st->dev, indio_dev);
+out_no_free:
+#else
+out_unreg_iio:
+ iio_device_unregister(indio_dev);
+out_remove_ring:
+ iio_buffer_unregister(indio_dev);
+out_unreg_ring:
+ inv_mpu_unconfigure_ring(indio_dev);
+out_free:
+ iio_device_free(indio_dev);
+out_no_free:
+#endif
+ dev_err(st->dev, "%s failed %d\n", __func__, result);
+
+ return -EIO;
+}
+
+static void inv_mpu_shutdown(struct i2c_client *client)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct inv_mpu_state *st = iio_priv(indio_dev);
+ int result;
+
+ mutex_lock(&indio_dev->mlock);
+ inv_switch_power_in_lp(st, true);
+ dev_dbg(st->dev, "Shutting down %s...\n", st->hw->name);
+
+ /* reset to make sure previous state are not there */
+ result = inv_plat_single_write(st, REG_PWR_MGMT_1, BIT_H_RESET);
+ if (result)
+ dev_err(st->dev, "Failed to reset %s\n",
+ st->hw->name);
+ msleep(POWER_UP_TIME);
+ /* turn off power to ensure gyro engine is off */
+ result = inv_set_power(st, false);
+ if (result)
+ dev_err(st->dev, "Failed to turn off %s\n",
+ st->hw->name);
+ inv_switch_power_in_lp(st, false);
+ mutex_unlock(&indio_dev->mlock);
+}
+
+/*
+ * inv_mpu_remove() - remove function.
+ */
+static int inv_mpu_remove(struct i2c_client *client)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct inv_mpu_state *st = iio_priv(indio_dev);
+
+#ifdef KERNEL_VERSION_4_X
+ devm_iio_device_unregister(st->dev, indio_dev);
+#else
+ iio_device_unregister(indio_dev);
+ iio_buffer_unregister(indio_dev);
+#endif
+ inv_mpu_unconfigure_ring(indio_dev);
+#ifdef KERNEL_VERSION_4_X
+ devm_iio_device_free(st->dev, indio_dev);
+#else
+ iio_device_free(indio_dev);
+#endif
+ dev_info(st->dev, "inv-mpu-iio module removed.\n");
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int inv_mpu_i2c_suspend(struct device *dev)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+
+ return inv_mpu_suspend(indio_dev);
+}
+
+static void inv_mpu_i2c_complete(struct device *dev)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+
+ inv_mpu_complete(indio_dev);
+}
+#endif
+
+static const struct dev_pm_ops inv_mpu_i2c_pmops = {
+#ifdef CONFIG_PM_SLEEP
+ .suspend = inv_mpu_i2c_suspend,
+ .complete = inv_mpu_i2c_complete,
+#endif
+};
+
+/* device id table is used to identify what device can be
+ * supported by this driver
+ */
+static const struct i2c_device_id inv_mpu_id[] = {
+#ifdef CONFIG_INV_MPU_IIO_ICM20648
+ {"icm20645", ICM20645},
+ {"icm10340", ICM10340},
+ {"icm20648", ICM20648},
+#else
+ {"icm20608d", ICM20608D},
+ {"icm20690", ICM20690},
+ {"icm20602", ICM20602},
+ {"iam20680", IAM20680},
+#endif
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, inv_mpu_id);
+
+static struct i2c_driver inv_mpu_driver = {
+ .probe = inv_mpu_probe,
+ .remove = inv_mpu_remove,
+ .shutdown = inv_mpu_shutdown,
+ .id_table = inv_mpu_id,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "inv-mpu-iio-i2c",
+ .pm = &inv_mpu_i2c_pmops,
+ },
+};
+module_i2c_driver(inv_mpu_driver);
+
+MODULE_AUTHOR("Invensense Corporation");
+MODULE_DESCRIPTION("Invensense I2C device driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/imu/inv_mpu/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu/inv_mpu_iio.h
new file mode 100644
index 0000000..9e73165
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu/inv_mpu_iio.h
@@ -0,0 +1,1138 @@
+/*
+ * Copyright (C) 2012-2018 InvenSense, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _INV_MPU_IIO_H_
+#define _INV_MPU_IIO_H_
+
+#include <linux/version.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0))
+#define KERNEL_VERSION_4_X
+#endif
+
+#include <linux/i2c.h>
+#include <linux/kfifo.h>
+#include <linux/miscdevice.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/iio/imu/mpu.h>
+#include <linux/interrupt.h>
+#include <linux/semaphore.h>
+#ifdef CONFIG_HAS_WAKELOCK
+#include <linux/wakelock.h>
+#else
+#include <linux/pm_wakeup.h>
+#endif
+#include <linux/wait.h>
+
+#include <linux/iio/sysfs.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/kfifo_buf.h>
+
+#ifdef CONFIG_INV_MPU_IIO_ICM20648
+#include "icm20648/dmp3Default.h"
+#endif
+#ifdef CONFIG_INV_MPU_IIO_ICM20608D
+#include "icm20608d/dmp3Default_20608D.h"
+#endif
+
+#include "inv_test/inv_counters.h"
+
+#if defined(CONFIG_INV_MPU_IIO_ICM20648)
+#include "icm20648/inv_mpu_iio_reg_20648.h"
+#elif defined(CONFIG_INV_MPU_IIO_ICM20602)
+#include "icm20602/inv_mpu_iio_reg_20602.h"
+#elif defined(CONFIG_INV_MPU_IIO_ICM20608D)
+#include "icm20608d/inv_mpu_iio_reg_20608.h"
+#elif defined(CONFIG_INV_MPU_IIO_ICM20690)
+#include "icm20690/inv_mpu_iio_reg_20690.h"
+#elif defined(CONFIG_INV_MPU_IIO_IAM20680)
+#include "iam20680/inv_mpu_iio_reg_20680.h"
+#endif
+
+#define INVENSENSE_DRIVER_VERSION "8.1.2-simple-test1"
+
+/* #define DEBUG */
+
+/* #define ACCEL_BIAS_TEST */
+
+/* #define BIAS_CONFIDENCE_HIGH 1 */
+
+#define MAX_FIFO_READ_SIZE 128
+#define MAX_DMP_READ_SIZE 16
+
+/* data header defines */
+#define WAKE_HDR 0x8000
+
+#define ACCEL_HDR 1
+#define GYRO_HDR 2
+#define COMPASS_HDR 3
+#define ALS_HDR 4
+#define SIXQUAT_HDR 5
+#define NINEQUAT_HDR 6
+#define PEDQUAT_HDR 7
+#define GEOMAG_HDR 8
+#define PRESSURE_HDR 9
+#define GYRO_CALIB_HDR 10
+#define COMPASS_CALIB_HDR 11
+#define STEP_COUNTER_HDR 12
+#define STEP_DETECTOR_HDR 13
+#define STEP_COUNT_HDR 14
+#define ACTIVITY_HDR 15
+#define PICK_UP_HDR 16
+#define EMPTY_MARKER 17
+#define END_MARKER 18
+#define COMPASS_ACCURACY_HDR 19
+#define ACCEL_ACCURACY_HDR 20
+#define GYRO_ACCURACY_HDR 21
+#define EIS_GYRO_HDR 36
+#define EIS_CALIB_HDR 37
+#define LPQ_HDR 38
+
+#define ACCEL_WAKE_HDR (ACCEL_HDR | WAKE_HDR)
+#define GYRO_WAKE_HDR (GYRO_HDR | WAKE_HDR)
+#define COMPASS_WAKE_HDR (COMPASS_HDR | WAKE_HDR)
+#define ALS_WAKE_HDR (ALS_HDR | WAKE_HDR)
+#define SIXQUAT_WAKE_HDR (SIXQUAT_HDR | WAKE_HDR)
+#define NINEQUAT_WAKE_HDR (NINEQUAT_HDR | WAKE_HDR)
+#define PEDQUAT_WAKE_HDR (PEDQUAT_HDR | WAKE_HDR)
+#define GEOMAG_WAKE_HDR (GEOMAG_HDR | WAKE_HDR)
+#define PRESSURE_WAKE_HDR (PRESSURE_HDR | WAKE_HDR)
+#define GYRO_CALIB_WAKE_HDR (GYRO_CALIB_HDR | WAKE_HDR)
+#define COMPASS_CALIB_WAKE_HDR (COMPASS_CALIB_HDR | WAKE_HDR)
+#define STEP_COUNTER_WAKE_HDR (STEP_COUNTER_HDR | WAKE_HDR)
+#define STEP_DETECTOR_WAKE_HDR (STEP_DETECTOR_HDR | WAKE_HDR)
+
+/* init parameters */
+#define MPU_INIT_SMD_THLD 1500
+#define MPU_INIT_GYRO_SCALE 3
+#define MPU_INIT_ACCEL_SCALE 2
+#define MPU_INIT_PED_INT_THRESH 2
+#define MPU_INIT_PED_STEP_THRESH 6
+#define MPU_4X_TS_GYRO_SHIFT (3160000 / 2)
+#define DMP_START_ADDR_20645 0x900
+#define DMP_START_ADDR_20648 0x1000
+#define DMP_START_ADDR_10340 0x0a60
+#define DMP_START_ADDR_20608D 0x4B0
+#define MAX_WR_SZ 100
+#define WOM_DELAY_THRESHOLD 200
+#define INV_ODR_BUFFER_MULTI 20
+#define INV_ODR_OVER_FACTOR 20
+
+#define COVARIANCE_SIZE 14
+#define ACCEL_COVARIANCE_SIZE (COVARIANCE_SIZE * sizeof(int))
+
+enum inv_bus_type {
+ BUS_I2C = 0,
+ BUS_SPI,
+};
+
+struct inv_mpu_state;
+
+enum INV_ENGINE {
+ ENGINE_GYRO = 0,
+ ENGINE_ACCEL,
+ ENGINE_PRESSURE,
+ ENGINE_I2C,
+ ENGINE_NUM_MAX,
+};
+
+/**
+ * struct inv_hw_s - Other important hardware information.
+ * @num_reg: Number of registers on device.
+ * @name: name of the chip
+ */
+struct inv_hw_s {
+ u8 num_reg;
+ u8 *name;
+};
+
+/**
+ * struct inv_sensor - information for each sensor.
+ * @ts: this sensors timestamp.
+ * @ts_adj: sensor timestamp adjustment.
+ * @previous_ts: previous timestamp for this sensor.
+ * @dur: duration between samples in ns.
+ * @rate: sensor data rate.
+ * @sample_size: number of bytes for the sensor.
+ * @odr_addr: output data rate address in DMP.
+ * @counter_addr: output counter address in DMP.
+ * @output: output on/off control word.
+ * @time_calib: calibrate timestamp.
+ * @sample_calib: calibrate bytes accumulated.
+ * @div: divider in DMP mode.
+ * @calib_flag: calibrate flag used to improve the accuracy of estimation.
+ * @on: sensor on/off.
+ * @a_en: accel engine requirement.
+ * @g_en: gyro engine requirement.
+ * @c_en: compass_engine requirement.
+ * @p_en: pressure engine requirement.
+ * @engine_base: engine base for this sensor.
+ * @count: number of samples in one session.
+ * @send: decide whether to send this sample or not.
+ */
+struct inv_sensor {
+ u64 ts;
+ s64 ts_adj;
+ u64 previous_ts;
+ int dur;
+ int rate;
+ u8 sample_size;
+ int odr_addr;
+ int counter_addr;
+ u16 output;
+ u64 time_calib;
+ u32 sample_calib;
+ int div;
+ bool calib_flag;
+ bool on;
+ bool a_en;
+ bool g_en;
+ bool c_en;
+ bool p_en;
+ enum INV_ENGINE engine_base;
+ int count;
+ bool send;
+};
+
+/**
+ * struct inv_sensor - information for each sensor.
+ * @sample_size: number of bytes for the sensor.
+ * @output: output on/off control word.
+ * @on: sensor on/off.
+ * @header: accuracy header for communicate with HAL
+ *dd @count: number of samples in one session.
+ */
+struct inv_sensor_accuracy {
+ u16 output;
+ u8 sample_size;
+ bool on;
+ u16 header;
+};
+
+enum SENSOR_ACCURACY {
+ SENSOR_ACCEL_ACCURACY = 0,
+ SENSOR_GYRO_ACCURACY,
+ SENSOR_COMPASS_ACCURACY,
+ SENSOR_ACCURACY_NUM_MAX,
+};
+
+enum SENSOR_L {
+ SENSOR_L_ACCEL = 0,
+ SENSOR_L_GYRO,
+ SENSOR_L_MAG,
+ SENSOR_L_ALS,
+ SENSOR_L_SIXQ,
+ SENSOR_L_THREEQ,
+ SENSOR_L_NINEQ,
+ SENSOR_L_PEDQ,
+ SENSOR_L_GEOMAG,
+ SENSOR_L_PRESSURE,
+ SENSOR_L_GYRO_CAL,
+ SENSOR_L_MAG_CAL,
+ SENSOR_L_EIS_GYRO,
+ /*wake sensors */
+ SENSOR_L_ACCEL_WAKE = 13,
+ SENSOR_L_GYRO_WAKE,
+ SENSOR_L_MAG_WAKE,
+ SENSOR_L_ALS_WAKE,
+ SENSOR_L_SIXQ_WAKE,
+ SENSOR_L_NINEQ_WAKE,
+ SENSOR_L_PEDQ_WAKE,
+ SENSOR_L_GEOMAG_WAKE,
+ SENSOR_L_PRESSURE_WAKE,
+ SENSOR_L_GYRO_CAL_WAKE,
+ SENSOR_L_MAG_CAL_WAKE,
+ SENSOR_L_GESTURE_ACCEL,
+ SENSOR_L_NUM_MAX,
+};
+
+/**
+ * struct android_l_sensor - information for each android sensor.
+ * @ts: this sensors timestamp.
+ * @base: android sensor based on invensense sensor.
+ * @rate: output rate.
+ * @on: sensor on/off.
+ * @wake_on: wake on sensor is on/off.
+ * @div: divider for the output.
+ * @counter: counter works with the divider.
+ * @header: header for the output.
+ */
+struct android_l_sensor {
+ u64 ts;
+ enum INV_SENSORS base;
+ int rate;
+ bool on;
+ bool wake_on;
+ int div;
+ int counter;
+ u16 header;
+};
+
+/**
+ * struct inv_batch - information for batchmode.
+ * @on: normal batch mode on.
+ * @default_on: default batch on. This is optimization option.
+ * @overflow_on: overflow mode for batchmode.
+ * @wake_fifo_on: overflow for suspend mode.
+ * @step_only: mean only step detector data is batched.
+ * @post_isr_run: mean post isr has runned once.
+ * @counter: counter for batch mode.
+ * @timeout: nominal timeout value for batchmode in milliseconds.
+ * @max_rate: max rate for all batched sensors.
+ * @pk_size: packet size;
+ * @engine_base: engine base batch mode should stick to.
+ */
+struct inv_batch {
+ bool on;
+ bool default_on;
+ bool overflow_on;
+ bool wake_fifo_on;
+ bool step_only;
+ bool post_isr_run;
+ u32 counter;
+ u32 timeout;
+ u32 max_rate;
+ u32 pk_size;
+ u32 fifo_wm_th;
+ enum INV_ENGINE engine_base;
+};
+
+/**
+ * struct inv_chip_config_s - Cached chip configuration data.
+ * @fsr: Full scale range.
+ * @lpf: Digital low pass filter frequency.
+ * @accel_fs: accel full scale range.
+ * @accel_enable: enable accel functionality
+ * @gyro_enable: enable gyro functionality
+ * @compass_enable: enable compass functinality.
+ * @geomag_enable: enable geomag sensor functions.
+ * @als_enable: enable ALS functionality.
+ * @pressure_enable: eanble pressure functionality.
+ * @secondary_enable: secondary I2C bus enabled or not.
+ * @has_gyro: has gyro or not.
+ * @has_compass: has secondary I2C compass or not.
+ * @has_pressure: has secondary I2C pressure or not.
+ * @has_als: has secondary I2C als or not.
+ * @slave_enable: secondary I2C interface enabled or not.
+ * @normal_compass_measure: discard first compass data after reset.
+ * @is_asleep: 1 if chip is powered down.
+ * @lp_en_set: 1 if LP_EN bit is set;
+ * @lp_en_mode_off: debug mode that turns off LP_EN mode off.
+ * @clk_sel: debug_mode that turns on/off clock selection.
+ * @dmp_on: dmp is on/off.
+ * @dmp_event_int_on: dmp event interrupt on/off.
+ * @wom_on: WOM interrupt on. This is an internal variable.
+ * @step_indicator_on: step indicate bit added to the sensor or not.
+ * @tilt_enable: tilt enable.
+ * @pick_up_enable: pick up gesture enable.
+ * @step_detector_on: step detector on or not.
+ * @activity_on: turn on/off activity.
+ * @activity_eng_on: activity engine on/off.
+ * @firmware_loaded: flag indicate firmware loaded or not.
+ * @low_power_gyro_on: flag indicating low power gyro on/off.
+ * @wake_on: any wake on sensor is on/off.
+ * @compass_rate: compass engine rate. Determined by underlying data.
+ */
+struct inv_chip_config_s {
+ u32 fsr:2;
+ u32 lpf:3;
+ u32 accel_fs:2;
+ u32 accel_enable:1;
+ u32 gyro_enable:1;
+ u32 compass_enable:1;
+ u32 geomag_enable:1;
+ u32 als_enable:1;
+ u32 prox_enable:1;
+ u32 pressure_enable:1;
+ u32 has_gyro:1;
+ u32 has_compass:1;
+ u32 has_pressure:1;
+ u32 has_als:1;
+ u32 slave_enable:1;
+ u32 normal_compass_measure:1;
+ u32 is_asleep:1;
+ u32 lp_en_set:1;
+ u32 lp_en_mode_off:1;
+ u32 clk_sel:1;
+ u32 dmp_on:1;
+ u32 dmp_event_int_on:1;
+ u32 wom_on:1;
+ u32 step_indicator_on:1;
+ u32 tilt_enable:1;
+ u32 pick_up_enable:1;
+ u32 eis_enable:1;
+ u32 step_detector_on:1;
+ u32 activity_on:1;
+ u32 activity_eng_on:1;
+ u32 firmware_loaded:1;
+ u32 low_power_gyro_on:1;
+ u32 wake_on:1;
+ int compass_rate;
+};
+
+/**
+ * struct inv_temp_comp - temperature compensation structure.
+ * @t_lo: raw temperature in low temperature.
+ * @t_hi: raw temperature in high temperature.
+ * @b_lo: gyro bias in low temperature.
+ * @b_hi: gyro bias in high temperature.
+ * @has_low: flag indicate low temperature parameters is updated.
+ * @has_high: flag indicates high temperature parameters is updated.
+ * @slope: slope for temperature compensation.
+ */
+struct inv_temp_comp {
+ int t_lo;
+ int t_hi;
+ int b_lo[3];
+ int b_hi[3];
+ bool has_low;
+ bool has_high;
+ int slope[3];
+};
+
+/**
+ * struct inv_chip_info_s - Chip related information.
+ * @product_id: Product id.
+ * @product_revision: Product revision.
+ * @silicon_revision: Silicon revision.
+ * @software_revision: software revision.
+ * @compass_sens: compass sensitivity.
+ * @gyro_sens_trim: Gyro sensitivity trim factor.
+ * @accel_sens_trim: accel sensitivity trim factor.
+ */
+struct inv_chip_info_s {
+ u8 product_id;
+ u8 product_revision;
+ u8 silicon_revision;
+ u8 software_revision;
+ u8 compass_sens[3];
+ u32 gyro_sens_trim;
+ u32 accel_sens_trim;
+};
+
+/**
+ * struct inv_smd significant motion detection structure.
+ * @threshold: accel threshold for motion detection.
+ * @delay: delay time to confirm 2nd motion.
+ * @delay2: delay window parameter.
+ * @on: smd on/off.
+ */
+struct inv_smd {
+ u32 threshold;
+ u32 delay;
+ u32 delay2;
+ bool on;
+};
+
+/**
+ * struct inv_ped pedometer related data structure.
+ * @step: steps taken.
+ * @time: time taken during the period.
+ * @last_step_time: last time the step is taken.
+ * @step_thresh: step threshold to show steps.
+ * @int_thresh: step threshold to generate interrupt.
+ * @int_on: pedometer interrupt enable/disable.
+ * @on: pedometer on/off.
+ * @engine_on: pedometer engine on/off.
+ */
+struct inv_ped {
+ u64 step;
+ u64 time;
+ u64 last_step_time;
+ u16 step_thresh;
+ u16 int_thresh;
+ bool int_on;
+ bool on;
+ bool engine_on;
+};
+
+/**
+ * struct inv_eis EIS related data structure.
+ * @prev_gyro: latest gyro data just before FSYNC triggerd
+ * @prev_timestamp: latest gyro timestamp just before FSYNC triggered
+ * @current_gyro: gyro data just after FSYNC triggerd
+ * @current_timestamp: gyro timestamp just after FSYNC triggered
+ * @fsync_timestamp: timestamp of FSYNC event
+ * @fsync_delay: delay time of FSYNC and Gyro data. DMP data of FSYNC event
+ * @eis_triggered: check fsync event is triggered or not.
+ * @eis_frame: current frame is eis frame;
+ * @current_sync: current frame contains fsync counter.
+ * @frame_count: frame count for synchronization.
+ */
+struct inv_eis {
+ int prev_gyro[3];
+ u64 prev_timestamp;
+ int current_gyro[3];
+ u64 current_timestamp;
+ u32 frame_dur;
+ u64 slope[3];
+ u64 fsync_timestamp;
+ u64 last_fsync_timestamp;
+ u16 fsync_delay;
+ bool eis_triggered;
+ bool eis_frame;
+ bool current_sync;
+ bool prev_state;
+ u32 frame_count;
+ int gyro_counter;
+ int gyro_counter_s[3];
+ int fsync_delay_s[3];
+ int voting_count;
+ int voting_count_sub;
+ int voting_state;
+ int count_precision;
+};
+
+enum TRIGGER_STATE {
+ DATA_TRIGGER = 0,
+ RATE_TRIGGER,
+ EVENT_TRIGGER,
+ MISC_TRIGGER,
+ DEBUG_TRIGGER,
+};
+
+enum inv_fifo_count_mode {
+ BYTE_MODE,
+ RECORD_MODE
+};
+
+/**
+ * struct inv_secondary_reg - secondary registers data structure.
+ * @addr: address of the slave.
+ * @reg: register address of slave.
+ * @ctrl: control register.
+ * @d0: data out register.
+ */
+struct inv_secondary_reg {
+ u8 addr;
+ u8 reg;
+ u8 ctrl;
+ u8 d0;
+};
+
+struct inv_secondary_set {
+ u8 delay_enable;
+ u8 delay_time;
+ u8 odr_config;
+};
+/**
+ * struct inv_engine_info - data structure for engines.
+ * @base_time: base time for each engine.
+ * @base_time_1k: base time when chip is running at 1K;
+ * @divider: divider used to downsample engine rate from original rate.
+ * @running_rate: the actually running rate of engine.
+ * @orig_rate: original rate for each engine before downsample.
+ * @dur: duration for one tick.
+ * @last_update_time: last update time.
+ */
+struct inv_engine_info {
+ u32 base_time;
+ u32 base_time_1k;
+ u32 divider;
+ u32 running_rate;
+ u32 orig_rate;
+ u32 dur;
+ u64 last_update_time;
+};
+
+struct inv_ois {
+ int gyro_fs;
+ int accel_fs;
+ bool en;
+};
+
+/**
+ * struct inv_timestamp_algo - timestamp algorithm .
+ * @last_run_time: last time the post ISR runs.
+ * @ts_for_calib: ts storage for calibration.
+ * @reset_ts: reset time.
+ * @dmp_ticks: dmp ticks storage for calibration.
+ * @start_dmp_counter: dmp counter when start a new session.
+ * @calib_counter: calibration counter for timestamp.
+ * @resume_flag: flag to indicate this is the first time after resume. time
+ could have up to 1 seconds difference.
+ * @clock_base: clock base to calculate the timestamp.
+ * @gyro_ts_shift: 9 K counter for EIS.
+ * @first_sample: first of 1K running should be dropped it affects timing
+ */
+struct inv_timestamp_algo {
+ u64 last_run_time;
+ u64 ts_for_calib;
+ u64 reset_ts;
+ u32 dmp_ticks;
+ u32 start_dmp_counter;
+ int calib_counter;
+ bool resume_flag;
+ enum INV_ENGINE clock_base;
+ u32 gyro_ts_shift;
+ u32 first_sample;
+};
+
+struct inv_mpu_slave;
+/**
+ * struct inv_mpu_state - Driver state variables.
+ * @dev: device address of the current bus, i2c or spi.
+ * @chip_config: Cached attribute information.
+ * @chip_info: Chip information from read-only registers.
+ * @smd: SMD data structure.
+ * @ped: pedometer data structure.
+ * @batch: batchmode data structure.
+ * @temp_comp: gyro temperature compensation structure.
+ * @slave_compass: slave compass.
+ * @slave_pressure: slave pressure.
+ * @slave_als: slave als.
+ * @slv_reg: slave register data structure.
+ * @ts_algo: timestamp algorithm data structure.
+ * @sec_set: slave register odr config.
+ * @eng_info: information for each engine.
+ * @hw: Other hardware-specific information.
+ * @chip_type: chip type.
+ * @suspend_resume_sema: semaphore for suspend/resume.
+ * @wake_lock: wake lock of the system.
+ * @client: i2c client handle.
+ * @plat_data: platform data.
+ * @sl_handle: Handle to I2C port.
+ * @sensor{SENSOR_NUM_MAX]: sensor individual properties.
+ * @sensor_l[SENSOR_L_NUM_MAX]: android L sensors properties.
+ * @sensor_accuracy[SENSOR_ACCURACY_NUM_MAX]: sensor accuracy.
+ * @sensor_acurracy_flag: flag indiciate whether to check output accuracy.
+ * @irq: irq number store.
+ * @accel_bias: accel bias store.
+ * @gyro_bias: gyro bias store.
+ * @accel_st_bias: accel bias store, result of self-test.
+ * @gyro_st_bias: gyro bias store, result of self-test.
+ * @gyro_ois_st_bias: gyro bias store from ois self test result.
+ * @input_accel_dmp_bias[3]: accel bias for dmp.
+ * @input_gyro_dmp_bias[3]: gyro bias for dmp.
+ * @input_compass_dmp_bias[3]: compass bias for dmp.
+ * @input_accel_bias[3]: accel bias for offset register.
+ * @input_gyro_bias[3]: gyro bias for offset register.
+ * @fifo_data[8]: fifo data storage.
+ * @i2c_addr: i2c address.
+ * @header_count: header count in current FIFO.
+ * @step_det_count: number of step detectors in one batch.
+ * @gyro_sf: gyro scale factor.
+ * @left_over[LEFT_OVER_BYTES]: left over bytes storage.
+ * @left_over_size: left over size.
+ * @fifo_count: current fifo_count;
+ * @wake_sensor_received: wake up sensor received.
+ * @accel_cal_enable: accel calibration on/off
+ * @gyro_cal_enable: gyro calibration on/off
+ * @calib_compass_on: calibrate compass on.
+ * @debug_determine_engine_on: determine engine on/off.
+ * @poke_mode_on: poke mode on/off.
+ * @mode_1k_on: indicate 1K Hz mode is on.
+ * @poke_ts: time stamp for poke feature.
+ * @step_detector_base_ts: base time stamp for step detector calculation.
+ * @last_temp_comp_time: last time temperature compensation is done.
+ * @i2c_dis: disable I2C interface or not.
+ * @name: name for the chip.
+ * @gyro_st_data: gyro self test data.
+ * @accel_st_data: accel self test data.
+ * @secondary_name: name for the slave device in the secondary I2C.
+ * @compass_var: compass variance from DMP.
+ * @current_compass_matrix: matrix compass data multiplied to before soft iron.
+ * @final_compass_matrix: matrix compass data multiplied to before soft iron.
+ * @trigger_state: information that which part triggers set_inv_enable.
+ * @firmware: firmware data pointer.
+ * @accel_calib_threshold: accel calibration threshold;
+ * @accel_calib_rate: divider for accel calibration rate.
+ * @accel_covariance[COVARIANCE_SIZE]: accel covariance data;
+ * @kf: kfifo for activity store.
+ * @activity_size: size for activity.
+ * @cntl: control word for sensor enable.
+ * @cntl2: control word for sensor extension.
+ * @motion_event_cntl: control word for events.
+ * @dmp_image_size: dmp image size.
+ * @dmp_start_address: start address of dmp.
+ * @step_counter_l_on: step counter android L sensor on/off.
+ * @step_counter_wake_l_on: step counter android L sensor wake on/off .
+ * @step_detector_l_on: step detector android L sensor on/off.
+ * @step_detector_wake_l_on: step detector android L sensor wake on/off .
+ * @gesture_only_on: indicate it is gesture only.
+ * @mag_divider: mag divider when gyro/accel is faster than mag maximum rate.
+ * @special_mag_mode: for 20690, there is special mag mode need to be handled.
+ * @mag_start_flag: when mag divider is non zero, need to check the start.
+ * @prev_steps: previous steps sent to the user.
+ * @aut_key_in: authentication key input.
+ * @aut_key_out: authentication key output.
+ * @suspend_state: state variable to indicate that we are in suspend state.
+ * @secondary_gyro_on: DMP out signal to turn on gyro.
+ * @secondary_mag_on: DMP out signal to turn on mag.
+ * @secondary_prox_on: DMP out signal to turn on proximity.
+ * @secondary_switch: showing this setup is triggerred by secondary switch.
+ * @send_calib_gyro: flag to indicate to send calibrated gyro.
+ * @send_raw_compass: flag to send raw compass.
+ * @resume_state: flag to synchronize the processing of inv_read_fifo()
+ * @cycle_on: variable indicate accel cycle mode is on.
+ * @secondary_switch_data: secondary switch data for activity.
+ * @raw_gyro_data[6]: save raw gyro data.
+ * @raw_compass_data[3]: save raw compass data.
+ * @wait_queue: wait queue to wake up inv_read_fifo()
+ * @bac_drive_conf: bac drive configuration.
+ * @bac_walk_conf: bac walk configuration.
+ * @bac_smd_conf: bac smd configuration.
+ * @bac_bike_conf: bac bike configuration.
+ * @bac_run_conf: bac run configuration.
+ * @bac_still_conf: back still configuration.
+ * @power_on_data: power on data.
+ * @fifo_data_store: store of FIFO data.
+ * @int_en: store interrupt enable register data.
+ * @int_en2: store interrupt enable register 2 data.
+ * @gesture_int_count: interrupt count for gesture only mode.
+ * @smplrt_div: SMPLRT_DIV register value.
+ */
+struct inv_mpu_state {
+ struct device *dev;
+ int (*write)(struct inv_mpu_state *st, u8 reg, u8 data);
+ int (*read)(struct inv_mpu_state *st, u8 reg, int len, u8 *data);
+ int (*mem_write)(struct inv_mpu_state *st, u8 mpu_addr, u16 mem_addr,
+ u32 len, u8 const *data);
+ int (*mem_read)(struct inv_mpu_state *st, u8 mpu_addr, u16 mem_addr,
+ u32 len, u8 *data);
+ struct inv_chip_config_s chip_config;
+ struct inv_chip_info_s chip_info;
+ struct inv_smd smd;
+ struct inv_ped ped;
+ struct inv_eis eis;
+ struct inv_batch batch;
+ struct inv_temp_comp temp_comp;
+ struct inv_mpu_slave *slave_compass;
+ struct inv_mpu_slave *slave_pressure;
+ struct inv_mpu_slave *slave_als;
+ struct inv_secondary_reg slv_reg[4];
+ struct inv_timestamp_algo ts_algo;
+ struct inv_secondary_set sec_set;
+ struct inv_engine_info eng_info[ENGINE_NUM_MAX];
+ const struct inv_hw_s *hw;
+ enum inv_devices chip_type;
+ enum inv_bus_type bus_type;
+ enum inv_fifo_count_mode fifo_count_mode;
+#ifdef CONFIG_HAS_WAKELOCK
+ struct wake_lock wake_lock;
+#else
+ struct wakeup_source wake_lock;
+#endif
+#ifdef TIMER_BASED_BATCHING
+ struct hrtimer hr_batch_timer;
+ u64 batch_timeout;
+ bool is_batch_timer_running;
+ struct work_struct batch_work;
+#endif
+ struct i2c_client *client;
+ struct mpu_platform_data plat_data;
+ void *sl_handle;
+ struct inv_sensor sensor[SENSOR_NUM_MAX];
+ struct android_l_sensor sensor_l[SENSOR_L_NUM_MAX];
+ struct inv_sensor_accuracy sensor_accuracy[SENSOR_ACCURACY_NUM_MAX];
+ struct inv_ois ois;
+ bool sensor_acurracy_flag[SENSOR_ACCURACY_NUM_MAX];
+ short irq;
+ int accel_bias[3];
+ int gyro_bias[3];
+ int accel_st_bias[3];
+ int accel_ois_st_bias[3];
+ int gyro_st_bias[3];
+ int gyro_ois_st_bias[3];
+ int input_accel_dmp_bias[3];
+ int input_gyro_dmp_bias[3];
+ int input_compass_dmp_bias[3];
+ int input_accel_bias[3];
+ int input_gyro_bias[3];
+ u8 fifo_data[8];
+ u8 i2c_addr;
+ int header_count;
+ int step_det_count;
+ s32 gyro_sf;
+ u8 left_over[LEFT_OVER_BYTES];
+ u32 left_over_size;
+ u32 fifo_count;
+ bool wake_sensor_received;
+ bool accel_cal_enable;
+ bool gyro_cal_enable;
+ bool calib_compass_on;
+ bool debug_determine_engine_on;
+ bool poke_mode_on;
+ bool mode_1k_on;
+ u64 poke_ts;
+ u64 step_detector_base_ts;
+ u64 last_temp_comp_time;
+ u8 i2c_dis;
+ u8 name[20];
+ u8 gyro_st_data[3];
+ u8 accel_st_data[3];
+ u8 secondary_name[20];
+ s32 compass_var;
+ int current_compass_matrix[9];
+ int final_compass_matrix[9];
+ enum TRIGGER_STATE trigger_state;
+ u8 *firmware;
+ int accel_calib_threshold;
+ int accel_calib_rate;
+ u32 accel_covariance[COVARIANCE_SIZE];
+ DECLARE_KFIFO(kf, u8, 128);
+ u32 activity_size;
+ int wom_thld;
+ u16 cntl;
+ u16 cntl2;
+ u16 motion_event_cntl;
+ int dmp_image_size;
+ int dmp_start_address;
+ bool step_counter_l_on;
+ bool step_counter_wake_l_on;
+ bool step_detector_l_on;
+ bool step_detector_wake_l_on;
+ bool gesture_only_on;
+ bool mag_start_flag;
+ int mag_divider;
+ bool special_mag_mode;
+ int prev_steps;
+ u32 curr_steps;
+ int aut_key_in;
+ int aut_key_out;
+ bool secondary_gyro_on;
+ bool secondary_mag_on;
+ bool secondary_prox_on;
+ bool secondary_switch;
+ bool send_calib_gyro;
+ bool send_raw_compass;
+ bool send_raw_gyro;
+ bool resume_state;
+ bool cycle_on;
+ int secondary_switch_data;
+ u8 raw_gyro_data[6];
+ u32 raw_compass_data[3];
+ wait_queue_head_t wait_queue;
+ u32 bac_drive_conf;
+ u32 bac_walk_conf;
+ u32 bac_smd_conf;
+ u32 bac_bike_conf;
+ u32 bac_run_conf;
+ u32 bac_still_conf;
+ u32 power_on_data;
+ u8 fifo_data_store[HARDWARE_FIFO_SIZE + LEFT_OVER_BYTES];
+ u8 int_en;
+ u8 int_en_2;
+ u8 gesture_int_count;
+ u8 smplrt_div;
+};
+
+/**
+ * struct inv_mpu_slave - MPU slave structure.
+ * @st_upper: compass self test upper limit.
+ * @st_lower: compass self test lower limit.
+ * @scale: compass scale.
+ * @rate_scale: decide how fast a compass can read.
+ * @min_read_time: minimum time between each reading.
+ * @self_test: self test method of the slave.
+ * @set_scale: set scale of slave
+ * @get_scale: read scale back of the slave.
+ * @suspend: suspend operation.
+ * @resume: resume operation.
+ * @setup: setup chip. initialization.
+ * @combine_data: combine raw data into meaningful data.
+ * @read_data: read external sensor and output
+ * @get_mode: get current chip mode.
+ * @set_lpf: set low pass filter.
+ * @set_fs: set full scale
+ * @prev_ts: last time it is read.
+ */
+struct inv_mpu_slave {
+ const short *st_upper;
+ const short *st_lower;
+ int scale;
+ int rate_scale;
+ int min_read_time;
+ int (*self_test) (struct inv_mpu_state *);
+ int (*set_scale) (struct inv_mpu_state *, int scale);
+ int (*get_scale) (struct inv_mpu_state *, int *val);
+ int (*suspend) (struct inv_mpu_state *);
+ int (*resume) (struct inv_mpu_state *);
+ int (*setup) (struct inv_mpu_state *);
+ int (*combine_data) (u8 *in, short *out);
+ int (*read_data) (struct inv_mpu_state *, short *out);
+ int (*get_mode) (void);
+ int (*set_lpf) (struct inv_mpu_state *, int rate);
+ int (*set_fs) (struct inv_mpu_state *, int fs);
+ u64 prev_ts;
+};
+
+/* scan element definition */
+enum inv_mpu_scan {
+ INV_MPU_SCAN_TIMESTAMP,
+};
+
+/* IIO attribute address */
+enum MPU_IIO_ATTR_ADDR {
+ ATTR_DMP_GYRO_X_DMP_BIAS,
+ ATTR_DMP_GYRO_Y_DMP_BIAS,
+ ATTR_DMP_GYRO_Z_DMP_BIAS,
+ ATTR_DMP_GYRO_CAL_ENABLE,
+ ATTR_DMP_ACCEL_X_DMP_BIAS,
+ ATTR_DMP_ACCEL_Y_DMP_BIAS,
+ ATTR_DMP_ACCEL_Z_DMP_BIAS,
+ ATTR_DMP_MAGN_X_DMP_BIAS,
+ ATTR_DMP_MAGN_Y_DMP_BIAS,
+ ATTR_DMP_MAGN_Z_DMP_BIAS,
+ ATTR_DMP_MAGN_ACCURACY,
+ ATTR_GYRO_X_OFFSET,
+ ATTR_GYRO_Y_OFFSET,
+ ATTR_GYRO_Z_OFFSET,
+ ATTR_ACCEL_X_OFFSET,
+ ATTR_ACCEL_Y_OFFSET,
+ ATTR_ACCEL_Z_OFFSET,
+ ATTR_DMP_SC_AUTH,
+ ATTR_DMP_EIS_AUTH,
+ ATTR_DMP_ACCEL_CAL_ENABLE,
+ ATTR_DMP_PED_INT_ON,
+ ATTR_DMP_PED_STEP_THRESH,
+ ATTR_DMP_PED_INT_THRESH,
+ ATTR_DMP_PED_ON,
+ ATTR_DMP_SMD_ENABLE,
+ ATTR_DMP_TILT_ENABLE,
+ ATTR_DMP_PICK_UP_ENABLE,
+ ATTR_DMP_EIS_ENABLE,
+ ATTR_DMP_PEDOMETER_STEPS,
+ ATTR_DMP_PEDOMETER_TIME,
+ ATTR_DMP_PEDOMETER_COUNTER,
+ ATTR_DMP_LOW_POWER_GYRO_ON,
+ ATTR_DMP_LP_EN_OFF,
+ ATTR_DMP_CLK_SEL,
+ ATTR_DMP_DEBUG_MEM_READ,
+ ATTR_DMP_DEBUG_MEM_WRITE,
+ ATTR_DEBUG_REG_WRITE,
+ ATTR_DEBUG_WRITE_CFG,
+ ATTR_DEBUG_REG_ADDR,
+ ATTR_WOM_THLD,
+ /* *****above this line, are DMP features, power needs on/off */
+ /* *****below this line, are DMP features, no power needed */
+ ATTR_IN_POWER_ON,
+ ATTR_DMP_ON,
+ ATTR_DMP_EVENT_INT_ON,
+ ATTR_DMP_STEP_COUNTER_ON,
+ ATTR_DMP_STEP_COUNTER_WAKE_ON,
+ ATTR_DMP_BATCHMODE_TIMEOUT,
+ ATTR_DMP_BATCHMODE_WAKE_FIFO_FULL,
+ ATTR_DMP_STEP_DETECTOR_ON,
+ ATTR_DMP_STEP_DETECTOR_WAKE_ON,
+ ATTR_DMP_ACTIVITY_ON,
+ ATTR_DMP_IN_ANGLVEL_ACCURACY_ENABLE,
+ ATTR_DMP_IN_ACCEL_ACCURACY_ENABLE,
+ ATTR_DMP_DEBUG_DETERMINE_ENGINE_ON,
+ ATTR_DMP_MISC_GYRO_RECALIBRATION,
+ ATTR_DMP_MISC_ACCEL_RECALIBRATION,
+ ATTR_DMP_PARAMS_ACCEL_CALIBRATION_THRESHOLD,
+ ATTR_DMP_PARAMS_ACCEL_CALIBRATION_RATE,
+ ATTR_GYRO_SCALE,
+ ATTR_ACCEL_SCALE,
+ ATTR_COMPASS_SCALE,
+ ATTR_COMPASS_SENSITIVITY_X,
+ ATTR_COMPASS_SENSITIVITY_Y,
+ ATTR_COMPASS_SENSITIVITY_Z,
+ ATTR_GYRO_ENABLE,
+ ATTR_ACCEL_ENABLE,
+ ATTR_COMPASS_ENABLE,
+ ATTR_FIRMWARE_LOADED,
+ ATTR_POKE_MODE,
+ ATTR_ANGLVEL_X_CALIBBIAS,
+ ATTR_ANGLVEL_Y_CALIBBIAS,
+ ATTR_ANGLVEL_Z_CALIBBIAS,
+ ATTR_ACCEL_X_CALIBBIAS,
+ ATTR_ACCEL_Y_CALIBBIAS,
+ ATTR_ACCEL_Z_CALIBBIAS,
+ ATTR_ANGLVEL_X_ST_CALIBBIAS,
+ ATTR_ANGLVEL_Y_ST_CALIBBIAS,
+ ATTR_ANGLVEL_Z_ST_CALIBBIAS,
+ ATTR_ANGLVEL_X_OIS_ST_CALIBBIAS,
+ ATTR_ANGLVEL_Y_OIS_ST_CALIBBIAS,
+ ATTR_ANGLVEL_Z_OIS_ST_CALIBBIAS,
+ ATTR_ACCEL_X_ST_CALIBBIAS,
+ ATTR_ACCEL_Y_ST_CALIBBIAS,
+ ATTR_ACCEL_Z_ST_CALIBBIAS,
+ ATTR_ACCEL_X_OIS_ST_CALIBBIAS,
+ ATTR_ACCEL_Y_OIS_ST_CALIBBIAS,
+ ATTR_ACCEL_Z_OIS_ST_CALIBBIAS,
+ ATTR_GYRO_MATRIX,
+ ATTR_ACCEL_MATRIX,
+ ATTR_COMPASS_MATRIX,
+ ATTR_FSYNC_FRAME_COUNT,
+ ATTR_SECONDARY_NAME,
+ ATTR_GYRO_SF,
+ ATTR_BAC_DRIVE_CONFIDENCE,
+ ATTR_BAC_WALK_CONFIDENCE,
+ ATTR_BAC_SMD_CONFIDENCE,
+ ATTR_BAC_BIKE_CONFIDENCE,
+ ATTR_BAC_STILL_CONFIDENCE,
+ ATTR_BAC_RUN_CONFIDENCE,
+ IN_OIS_ACCEL_FS,
+ IN_OIS_GYRO_FS,
+ IN_OIS_ENABLE,
+};
+
+int inv_mpu_configure_ring(struct iio_dev *indio_dev);
+int inv_mpu_probe_trigger(struct iio_dev *indio_dev);
+void inv_mpu_unconfigure_ring(struct iio_dev *indio_dev);
+void inv_mpu_remove_trigger(struct iio_dev *indio_dev);
+#ifdef CONFIG_PM_SLEEP
+int inv_mpu_suspend(struct iio_dev *indio_dev);
+void inv_mpu_complete(struct iio_dev *indio_dev);
+#endif
+
+int inv_get_pedometer_steps(struct inv_mpu_state *st, int *ped);
+int inv_get_pedometer_time(struct inv_mpu_state *st, int *ped);
+int inv_read_pedometer_counter(struct inv_mpu_state *st);
+
+int inv_dmp_read(struct inv_mpu_state *st, int off, int size, u8 *buf);
+int inv_firmware_load(struct inv_mpu_state *st);
+
+int set_inv_enable(struct iio_dev *indio_dev);
+
+int inv_mpu_setup_compass_slave(struct inv_mpu_state *st);
+int inv_mpu_setup_pressure_slave(struct inv_mpu_state *st);
+int inv_mpu_setup_als_slave(struct inv_mpu_state *st);
+int inv_mpu_initialize(struct inv_mpu_state *st);
+int inv_set_accel_sf(struct inv_mpu_state *st);
+int inv_set_gyro_sf(struct inv_mpu_state *st);
+s64 get_time_ns(void);
+int inv_i2c_read_base(struct inv_mpu_state *st, u16 i, u8 r, u16 l, u8 *d);
+int inv_i2c_single_write_base(struct inv_mpu_state *st, u16 i, u8 r, u8 d);
+int write_be32_to_mem(struct inv_mpu_state *st, u32 data, int addr);
+int write_be16_to_mem(struct inv_mpu_state *st, u16 data, int addr);
+int read_be32_from_mem(struct inv_mpu_state *st, u32 *o, int addr);
+int read_be16_from_mem(struct inv_mpu_state *st, u16 *o, int addr);
+u32 inv_get_cntr_diff(u32 curr_counter, u32 prev);
+int inv_write_2bytes(struct inv_mpu_state *st, int k, int data);
+int inv_set_bank(struct inv_mpu_state *st, u8 bank);
+int inv_set_power(struct inv_mpu_state *st, bool power_on);
+int inv_switch_power_in_lp(struct inv_mpu_state *st, bool on);
+#ifndef CONFIG_INV_MPU_IIO_ICM20608D
+int inv_set_accel_config2(struct inv_mpu_state *st, bool cycle_mode);
+#endif
+int inv_stop_dmp(struct inv_mpu_state *st);
+int inv_reset_fifo(struct inv_mpu_state *st, bool turn_off);
+int inv_create_dmp_sysfs(struct iio_dev *ind);
+int inv_check_chip_type(struct iio_dev *indio_dev, const char *name);
+int inv_write_compass_matrix(struct inv_mpu_state *st, int *adj);
+irqreturn_t inv_read_fifo(int irq, void *dev_id);
+#ifdef TIMER_BASED_BATCHING
+void inv_batch_work(struct work_struct *work);
+#endif
+int inv_flush_batch_data(struct iio_dev *indio_dev, int data);
+static inline int mpu_memory_write(struct inv_mpu_state *st, u8 mpu_addr,
+ u16 mem_addr, u32 len, u8 const *data)
+{
+ int ret = -1;
+
+ if (st->mem_write)
+ ret = st->mem_write(st, mpu_addr, mem_addr, len, data);
+
+ return ret;
+}
+static inline int mpu_memory_read(struct inv_mpu_state *st, u8 mpu_addr,
+ u16 mem_addr, u32 len, u8 *data)
+{
+ int ret = -1;
+
+ if (st->mem_read)
+ ret = st->mem_read(st, mpu_addr, mem_addr, len, data);
+
+ return ret;
+}
+int inv_read_secondary(struct inv_mpu_state *st, int ind, int addr,
+ int reg, int len);
+int inv_write_secondary(struct inv_mpu_state *st, int ind, int addr,
+ int reg, int v);
+int inv_execute_write_secondary(struct inv_mpu_state *st, int ind, int addr,
+ int reg, int v);
+int inv_execute_read_secondary(struct inv_mpu_state *st, int ind, int addr,
+ int reg, int len, u8 *d);
+
+int inv_push_16bytes_buffer(struct inv_mpu_state *st, u16 hdr,
+ u64 t, int *q, s16 accur);
+int inv_push_gyro_data(struct inv_mpu_state *st, s16 *raw, s32 *calib, u64 t);
+int inv_push_8bytes_buffer(struct inv_mpu_state *st, u16 hdr, u64 t, s16 *d);
+int inv_push_8bytes_kf(struct inv_mpu_state *st, u16 hdr, u64 t, s16 *d);
+
+void inv_push_step_indicator(struct inv_mpu_state *st, u64 t);
+int inv_send_steps(struct inv_mpu_state *st, int step, u64 t);
+int inv_push_marker_to_buffer(struct inv_mpu_state *st, u16 hdr, int data);
+
+int inv_check_sensor_on(struct inv_mpu_state *st);
+int inv_write_cntl(struct inv_mpu_state *st, u16 wd, bool en, int cntl);
+
+int inv_get_packet_size(struct inv_mpu_state *st, u16 hdr,
+ u32 *pk_size, u8 *dptr);
+int inv_parse_packet(struct inv_mpu_state *st, u16 hdr, u8 *dptr);
+int inv_pre_parse_packet(struct inv_mpu_state *st, u16 hdr, u8 *dptr);
+int inv_process_dmp_data(struct inv_mpu_state *st);
+
+int be32_to_int(u8 *d);
+void inv_convert_and_push_16bytes(struct inv_mpu_state *st, u16 hdr,
+ u8 *d, u64 t, s8 *m);
+void inv_convert_and_push_8bytes(struct inv_mpu_state *st, u16 hdr,
+ u8 *d, u64 t, s8 *m);
+int inv_get_dmp_ts(struct inv_mpu_state *st, int i);
+int inv_process_step_det(struct inv_mpu_state *st, u8 *dptr);
+int inv_process_eis(struct inv_mpu_state *st, u16 delay);
+int inv_rate_convert(struct inv_mpu_state *st, int ind, int data);
+
+int inv_setup_dmp_firmware(struct inv_mpu_state *st);
+/* used to print i2c data using pr_debug */
+char *wr_pr_debug_begin(u8 const *data, u32 len, char *string);
+char *wr_pr_debug_end(char *string);
+
+int inv_hw_self_test(struct inv_mpu_state *st);
+int inv_q30_mult(int a, int b);
+#ifdef ACCEL_BIAS_TEST
+int inv_get_3axis_average(s16 src[], s16 dst[], s16 reset);
+#endif
+
+static inline int inv_plat_single_write(struct inv_mpu_state *st,
+ u8 reg, u8 data)
+{
+ int ret = -1;
+
+ if (st->write)
+ ret = st->write(st, reg, data);
+
+ return ret;
+}
+static inline int inv_plat_read(struct inv_mpu_state *st, u8 reg,
+ int len, u8 *data)
+{
+ int ret = -1;
+
+ if (st->read)
+ ret = st->read(st, reg, len, data);
+
+ return ret;
+}
+irqreturn_t inv_read_fifo(int , void *);
+
+int inv_stop_interrupt(struct inv_mpu_state *st);
+int inv_reenable_interrupt(struct inv_mpu_state *st);
+
+int inv_enable_pedometer_interrupt(struct inv_mpu_state *st, bool en);
+int inv_dataout_control1(struct inv_mpu_state *st, u16 cntl1);
+int inv_dataout_control2(struct inv_mpu_state *st, u16 cntl2);
+int inv_motion_interrupt_control(struct inv_mpu_state *st,
+ u16 motion_event_cntl);
+
+int inv_bound_timestamp(struct inv_mpu_state *st);
+int inv_update_dmp_ts(struct inv_mpu_state *st, int ind);
+int inv_get_last_run_time_non_dmp_record_mode(struct inv_mpu_state *st);
+
+#define mem_w(a, b, c) mpu_memory_write(st, st->i2c_addr, a, b, c)
+#define mem_r(a, b, c) mpu_memory_read(st, st->i2c_addr, a, b, c)
+
+#endif /* #ifndef _INV_MPU_IIO_H_ */
diff --git a/drivers/iio/imu/inv_mpu/inv_mpu_ring.c b/drivers/iio/imu/inv_mpu/inv_mpu_ring.c
new file mode 100644
index 0000000..3e5bccbe
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu/inv_mpu_ring.c
@@ -0,0 +1,643 @@
+/*
+* Copyright (C) 2012-2018 InvenSense, Inc.
+*
+* This software is licensed under the terms of the GNU General Public
+* License version 2, as published by the Free Software Foundation, and
+* may be copied, distributed, and modified under those terms.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*/
+#define pr_fmt(fmt) "inv_mpu: " fmt
+
+#include <linux/export.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/sysfs.h>
+#include <linux/jiffies.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/kfifo.h>
+#include <linux/poll.h>
+#include <linux/math64.h>
+#include <linux/miscdevice.h>
+
+#include "inv_mpu_iio.h"
+
+static void inv_push_timestamp(struct iio_dev *indio_dev, u64 t)
+{
+ u8 buf[IIO_BUFFER_BYTES];
+ struct inv_mpu_state *st;
+
+ st = iio_priv(indio_dev);
+ if (st->poke_mode_on)
+ memcpy(buf, &st->poke_ts, sizeof(t));
+ else
+ memcpy(buf, &t, sizeof(t));
+ iio_push_to_buffers(indio_dev, buf);
+}
+
+int inv_push_marker_to_buffer(struct inv_mpu_state *st, u16 hdr, int data)
+{
+ struct iio_dev *indio_dev = iio_priv_to_dev(st);
+ u8 buf[IIO_BUFFER_BYTES];
+
+ memcpy(buf, &hdr, sizeof(hdr));
+ memcpy(&buf[4], &data, sizeof(data));
+ iio_push_to_buffers(indio_dev, buf);
+
+ return 0;
+}
+static int inv_calc_precision(struct inv_mpu_state *st)
+{
+ int diff;
+ int init;
+
+ if (st->eis.voting_state != 8)
+ return 0;
+ diff = abs(st->eis.fsync_delay_s[1] - st->eis.fsync_delay_s[0]);
+ init = 0;
+ if (diff)
+ init = st->sensor[SENSOR_GYRO].dur / diff;
+
+ if (abs(init - NSEC_PER_USEC) < (NSEC_PER_USEC >> 3))
+ st->eis.count_precision = init;
+ else
+ st->eis.voting_state = 0;
+
+ pr_debug("dur= %d prc= %d\n", st->sensor[SENSOR_GYRO].dur,
+ st->eis.count_precision);
+
+ return 0;
+}
+
+static s64 calc_frame_ave(struct inv_mpu_state *st, int delay)
+{
+ s64 ts;
+
+ ts = st->eis.current_timestamp - delay;
+#if defined(CONFIG_INV_MPU_IIO_ICM20648) | defined(CONFIG_INV_MPU_IIO_ICM20690)
+ ts -= st->ts_algo.gyro_ts_shift;
+#endif
+ pr_debug("shift= %d ts = %lld\n", st->ts_algo.gyro_ts_shift, ts);
+
+ return ts;
+}
+
+static void inv_push_eis_ring(struct inv_mpu_state *st, int *q, bool sync,
+ s64 t)
+{
+ struct iio_dev *indio_dev = iio_priv_to_dev(st);
+ struct inv_eis *eis = &st->eis;
+ u8 buf[IIO_BUFFER_BYTES];
+ int tmp, ii;
+
+ buf[0] = (EIS_GYRO_HDR & 0xff);
+ buf[1] = (EIS_GYRO_HDR >> 8);
+ memcpy(buf + 4, &q[0], sizeof(q[0]));
+ iio_push_to_buffers(indio_dev, buf);
+ for (ii = 0; ii < 2; ii++)
+ memcpy(buf + 4 * ii, &q[ii + 1], sizeof(q[ii]));
+ iio_push_to_buffers(indio_dev, buf);
+ tmp = eis->frame_count;
+ if (sync)
+ tmp |= 0x80000000;
+ memcpy(buf, &tmp, sizeof(tmp));
+ iio_push_to_buffers(indio_dev, buf);
+ inv_push_timestamp(indio_dev, t);
+}
+static int inv_do_interpolation_gyro(struct inv_mpu_state *st, int *prev,
+ s64 prev_t, int *curr, s64 curr_t, s64 t, bool trigger)
+{
+ int i;
+ int out[3];
+#if defined(CONFIG_INV_MPU_IIO_ICM20648) | defined(CONFIG_INV_MPU_IIO_ICM20690)
+ prev_t -= st->ts_algo.gyro_ts_shift;
+ prev_t += MPU_4X_TS_GYRO_SHIFT;
+ curr_t -= st->ts_algo.gyro_ts_shift;
+ curr_t += MPU_4X_TS_GYRO_SHIFT;
+#endif
+ if ((t > prev_t) && (t < curr_t)) {
+ for (i = 0; i < 3; i++)
+ out[i] = (int)div_s64((s64)(curr[i] - prev[i]) *
+ (s64)(t - prev_t), curr_t - prev_t) + prev[i];
+ } else if (t < prev_t) {
+ for (i = 0; i < 3; i++)
+ out[i] = prev[i];
+ } else {
+ for (i = 0; i < 3; i++)
+ out[i] = curr[i];
+ }
+ pr_debug("prev= %lld t = %lld curr= %lld\n", prev_t, t, curr_t);
+ pr_debug("prev = %d, %d, %d\n", prev[0], prev[1], prev[2]);
+ pr_debug("curr = %d, %d, %d\n", curr[0], curr[1], curr[2]);
+ pr_debug("out = %d, %d, %d\n", out[0], out[1], out[2]);
+ inv_push_eis_ring(st, out, trigger, t);
+
+ return 0;
+}
+#if defined(CONFIG_INV_MPU_IIO_ICM20648) | defined(CONFIG_INV_MPU_IIO_ICM20690)
+static void inv_handle_triggered_eis(struct inv_mpu_state *st)
+{
+ struct inv_eis *eis = &st->eis;
+ int delay;
+
+ if (st->eis.eis_frame) {
+ inv_calc_precision(st);
+ delay = ((int)st->eis.fsync_delay) * st->eis.count_precision;
+ eis->fsync_timestamp = calc_frame_ave(st, delay);
+ inv_do_interpolation_gyro(st,
+ st->eis.prev_gyro, st->eis.prev_timestamp,
+ st->eis.current_gyro, st->eis.current_timestamp,
+ eis->fsync_timestamp, true);
+ pr_debug("fsync=%lld, curr=%lld, delay=%d\n",
+ eis->fsync_timestamp, eis->current_timestamp, delay);
+ inv_push_eis_ring(st, st->eis.current_gyro, false,
+ st->eis.current_timestamp - st->ts_algo.gyro_ts_shift
+ + MPU_4X_TS_GYRO_SHIFT);
+ eis->last_fsync_timestamp = eis->fsync_timestamp;
+ } else {
+ pr_debug("cur= %lld\n", st->eis.current_timestamp);
+ inv_push_eis_ring(st, st->eis.current_gyro, false,
+ st->eis.current_timestamp - st->ts_algo.gyro_ts_shift
+ + MPU_4X_TS_GYRO_SHIFT);
+ }
+}
+#else
+static void inv_handle_triggered_eis(struct inv_mpu_state *st)
+{
+ struct inv_eis *eis = &st->eis;
+ int delay;
+
+ if ((st->eis.eis_frame && (st->eis.fsync_delay != 5)) ||
+ (st->eis.eis_frame && (st->eis.fsync_delay == 5) &&
+ (!st->eis.current_sync))
+ ) {
+ inv_calc_precision(st);
+ delay = ((int)st->eis.fsync_delay) * st->eis.count_precision;
+ eis->fsync_timestamp = calc_frame_ave(st, delay);
+ inv_do_interpolation_gyro(st,
+ st->eis.prev_gyro, st->eis.prev_timestamp,
+ st->eis.current_gyro, st->eis.current_timestamp,
+ eis->fsync_timestamp, true);
+ pr_debug("fsync=%lld, curr=%lld, delay=%d\n",
+ eis->fsync_timestamp, eis->current_timestamp, delay);
+ inv_push_eis_ring(st, st->eis.current_gyro, false,
+ st->eis.current_timestamp);
+ eis->last_fsync_timestamp = eis->fsync_timestamp;
+ st->eis.eis_frame = false;
+ } else {
+ st->eis.current_sync = false;
+ pr_debug("cur= %lld\n", st->eis.current_timestamp);
+ inv_push_eis_ring(st, st->eis.current_gyro, false,
+ st->eis.current_timestamp);
+ }
+}
+#endif
+static void inv_push_eis_buffer(struct inv_mpu_state *st, u64 t, int *q)
+{
+ int ii;
+
+ if (st->eis.eis_triggered) {
+ for (ii = 0; ii < 3; ii++)
+ st->eis.prev_gyro[ii] = st->eis.current_gyro[ii];
+ st->eis.prev_timestamp = st->eis.current_timestamp;
+
+ for (ii = 0; ii < 3; ii++)
+ st->eis.current_gyro[ii] = q[ii];
+ st->eis.current_timestamp = t;
+ inv_handle_triggered_eis(st);
+ } else {
+ for (ii = 0; ii < 3; ii++)
+ st->eis.current_gyro[ii] = q[ii];
+ st->eis.current_timestamp = t;
+ }
+}
+static int inv_push_16bytes_final(struct inv_mpu_state *st, int j,
+ s32 *q, u64 t, s16 accur)
+{
+ struct iio_dev *indio_dev = iio_priv_to_dev(st);
+ u8 buf[IIO_BUFFER_BYTES];
+ int ii;
+
+ memcpy(buf, &st->sensor_l[j].header, sizeof(st->sensor_l[j].header));
+ memcpy(buf + 2, &accur, sizeof(accur));
+ memcpy(buf + 4, &q[0], sizeof(q[0]));
+ iio_push_to_buffers(indio_dev, buf);
+ for (ii = 0; ii < 2; ii++)
+ memcpy(buf + 4 * ii, &q[ii + 1], sizeof(q[ii]));
+ iio_push_to_buffers(indio_dev, buf);
+ inv_push_timestamp(indio_dev, t);
+ st->sensor_l[j].counter = 0;
+ if (st->sensor_l[j].wake_on)
+ st->wake_sensor_received = true;
+
+ return 0;
+}
+int inv_push_16bytes_buffer(struct inv_mpu_state *st, u16 sensor,
+ u64 t, int *q, s16 accur)
+{
+ int j;
+
+ for (j = 0; j < SENSOR_L_NUM_MAX; j++) {
+ if (st->sensor_l[j].on && (st->sensor_l[j].base == sensor)) {
+ st->sensor_l[j].counter++;
+ if ((st->sensor_l[j].div != 0xffff) &&
+ (st->sensor_l[j].counter >=
+ st->sensor_l[j].div)) {
+ pr_debug(
+ "Sensor_l = %d sensor = %d header [%04X] div [%d] ts [%lld] %d %d %d\n",
+ j, sensor,
+ st->sensor_l[j].header,
+ st->sensor_l[j].div,
+ t, q[0], q[1], q[2]);
+ inv_push_16bytes_final(st, j, q, t, accur);
+ }
+ }
+ }
+ return 0;
+}
+
+void inv_convert_and_push_16bytes(struct inv_mpu_state *st, u16 hdr,
+ u8 *d, u64 t, s8 *m)
+{
+ int i, j;
+ s32 in[3], out[3];
+
+ for (i = 0; i < 3; i++)
+ in[i] = be32_to_int(d + i * 4);
+ /* multiply with orientation matrix can be optimized like this */
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 3; j++)
+ if (m[i * 3 + j])
+ out[i] = in[j] * m[i * 3 + j];
+
+ inv_push_16bytes_buffer(st, hdr, t, out, 0);
+}
+
+void inv_convert_and_push_8bytes(struct inv_mpu_state *st, u16 hdr,
+ u8 *d, u64 t, s8 *m)
+{
+ int i, j;
+ s16 in[3], out[3];
+
+ for (i = 0; i < 3; i++)
+ in[i] = be16_to_cpup((__be16 *) (d + i * 2));
+
+ /* multiply with orientation matrix can be optimized like this */
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 3; j++)
+ if (m[i * 3 + j])
+ out[i] = in[j] * m[i * 3 + j];
+
+ inv_push_8bytes_buffer(st, hdr, t, out);
+}
+
+int inv_push_special_8bytes_buffer(struct inv_mpu_state *st,
+ u16 hdr, u64 t, s16 *d)
+{
+ struct iio_dev *indio_dev = iio_priv_to_dev(st);
+ u8 buf[IIO_BUFFER_BYTES];
+ int j;
+
+ memcpy(buf, &hdr, sizeof(hdr));
+ memcpy(&buf[2], &d[0], sizeof(d[0]));
+ for (j = 0; j < 2; j++)
+ memcpy(&buf[4 + j * 2], &d[j + 1], sizeof(d[j]));
+ iio_push_to_buffers(indio_dev, buf);
+ inv_push_timestamp(indio_dev, t);
+
+ return 0;
+}
+
+static int inv_s16_gyro_push(struct inv_mpu_state *st, int i, s16 *raw, u64 t)
+{
+ if (st->sensor_l[i].on) {
+ st->sensor_l[i].counter++;
+ if ((st->sensor_l[i].div != 0xffff) &&
+ (st->sensor_l[i].counter >= st->sensor_l[i].div)) {
+ inv_push_special_8bytes_buffer(st,
+ st->sensor_l[i].header, t, raw);
+ st->sensor_l[i].counter = 0;
+ if (st->sensor_l[i].wake_on)
+ st->wake_sensor_received = true;
+ }
+ }
+
+ return 0;
+}
+
+static int inv_s32_gyro_push(struct inv_mpu_state *st, int i, s32 *calib, u64 t)
+{
+ if (st->sensor_l[i].on) {
+ st->sensor_l[i].counter++;
+ if ((st->sensor_l[i].div != 0xffff) &&
+ (st->sensor_l[i].counter >= st->sensor_l[i].div)) {
+ inv_push_16bytes_final(st, i, calib, t, 0);
+ st->sensor_l[i].counter = 0;
+ if (st->sensor_l[i].wake_on)
+ st->wake_sensor_received = true;
+ }
+ }
+
+ return 0;
+}
+
+int inv_push_gyro_data(struct inv_mpu_state *st, s16 *raw, s32 *calib, u64 t)
+{
+ int gyro_data[] = {SENSOR_L_GYRO, SENSOR_L_GYRO_WAKE};
+ int calib_data[] = {SENSOR_L_GYRO_CAL, SENSOR_L_GYRO_CAL_WAKE};
+ int i;
+
+ if (st->sensor_l[SENSOR_L_EIS_GYRO].on)
+ inv_push_eis_buffer(st, t, calib);
+
+ for (i = 0; i < 2; i++)
+ inv_s16_gyro_push(st, gyro_data[i], raw, t);
+ for (i = 0; i < 2; i++)
+ inv_s32_gyro_push(st, calib_data[i], calib, t);
+
+ return 0;
+}
+int inv_push_8bytes_buffer(struct inv_mpu_state *st, u16 sensor, u64 t, s16 *d)
+{
+ struct iio_dev *indio_dev = iio_priv_to_dev(st);
+ u8 buf[IIO_BUFFER_BYTES];
+ int ii, j;
+
+ if ((sensor == STEP_DETECTOR_HDR) ||
+ (sensor == STEP_DETECTOR_WAKE_HDR)) {
+ memcpy(buf, &sensor, sizeof(sensor));
+ memcpy(&buf[2], &d[0], sizeof(d[0]));
+ for (j = 0; j < 2; j++)
+ memcpy(&buf[4 + j * 2], &d[j + 1], sizeof(d[j]));
+ iio_push_to_buffers(indio_dev, buf);
+ inv_push_timestamp(indio_dev, t);
+ if (sensor == STEP_DETECTOR_WAKE_HDR)
+ st->wake_sensor_received = true;
+ return 0;
+ }
+ for (ii = 0; ii < SENSOR_L_NUM_MAX; ii++) {
+ if (st->sensor_l[ii].on &&
+ (st->sensor_l[ii].base == sensor) &&
+ (st->sensor_l[ii].div != 0xffff)) {
+ st->sensor_l[ii].counter++;
+ if (st->sensor_l[ii].counter >= st->sensor_l[ii].div) {
+ pr_debug(
+ "Sensor_l = %d sensor = %d header [%04X] div [%d] ts [%lld] %d %d %d\n",
+ ii, sensor, st->sensor_l[ii].header,
+ st->sensor_l[ii].div, t, d[0], d[1], d[2]);
+
+ memcpy(buf, &st->sensor_l[ii].header,
+ sizeof(st->sensor_l[ii].header));
+ memcpy(&buf[2], &d[0], sizeof(d[0]));
+ for (j = 0; j < 2; j++)
+ memcpy(&buf[4 + j * 2], &d[j + 1],
+ sizeof(d[j]));
+
+ iio_push_to_buffers(indio_dev, buf);
+ inv_push_timestamp(indio_dev, t);
+ st->sensor_l[ii].counter = 0;
+ if (st->sensor_l[ii].wake_on)
+ st->wake_sensor_received = true;
+ }
+ }
+ }
+
+ return 0;
+}
+#ifdef CONFIG_INV_MPU_IIO_ICM20648
+/* Implemented activity to string function for BAC test */
+#define TILT_DETECTED 0x1000
+#define NONE 0x00
+#define DRIVE 0x01
+#define WALK 0x02
+#define RUN 0x04
+#define BIKE 0x08
+#define TILT 0x10
+#define STILL 0x20
+#define DRIVE_WALK (DRIVE | WALK)
+#define DRIVE_RUN (DRIVE | RUN)
+
+char *act_string(s16 data)
+{
+ data &= (~TILT);
+ switch (data) {
+ case NONE:
+ return "None";
+ case DRIVE:
+ return "Drive";
+ case WALK:
+ return "Walk";
+ case RUN:
+ return "Run";
+ case BIKE:
+ return "Bike";
+ case STILL:
+ return "Still";
+ case DRIVE_WALK:
+ return "drive and walk";
+ case DRIVE_RUN:
+ return "drive and run";
+ default:
+ return "Unknown";
+ }
+ return "Unknown";
+}
+
+char *inv_tilt_check(s16 data)
+{
+ if (data & TILT)
+ return "Tilt";
+ else
+ return "None";
+}
+
+int inv_push_8bytes_kf(struct inv_mpu_state *st, u16 hdr, u64 t, s16 *d)
+{
+ struct iio_dev *indio_dev = iio_priv_to_dev(st);
+ u8 buf[IIO_BUFFER_BYTES];
+ int i;
+
+ if (st->chip_config.activity_on) {
+ memcpy(buf, &hdr, sizeof(hdr));
+ for (i = 0; i < 3; i++)
+ memcpy(&buf[2 + i * 2], &d[i], sizeof(d[i]));
+
+ kfifo_in(&st->kf, buf, IIO_BUFFER_BYTES);
+ memcpy(buf, &t, sizeof(t));
+ kfifo_in(&st->kf, buf, IIO_BUFFER_BYTES);
+ st->activity_size += IIO_BUFFER_BYTES * 2;
+ }
+ if (st->chip_config.tilt_enable) {
+ pr_debug("d[0] = %04X, [%X : %s] to [%X : %s]",
+ d[0], d[0] & 0x00FF,
+ inv_tilt_check(d[0] & 0x00FF),
+ (d[0] & 0xFF00) >> 8, inv_tilt_check((d[0] & 0xFF00) >> 8));
+ sysfs_notify(&indio_dev->dev.kobj, NULL, "poll_tilt");
+ }
+
+ pr_debug("d[0] = %04X, [%X : %s] to [%X : %s]", d[0], d[0] & 0x00FF,
+ act_string(d[0] & 0x00FF),
+ (d[0] & 0xFF00) >> 8, act_string((d[0] & 0xFF00) >> 8));
+
+ read_be32_from_mem(st, &st->bac_drive_conf, BAC_DRIVE_CONFIDENCE);
+ read_be32_from_mem(st, &st->bac_walk_conf, BAC_WALK_CONFIDENCE);
+ read_be32_from_mem(st, &st->bac_smd_conf, BAC_SMD_CONFIDENCE);
+ read_be32_from_mem(st, &st->bac_bike_conf, BAC_BIKE_CONFIDENCE);
+ read_be32_from_mem(st, &st->bac_still_conf, BAC_STILL_CONFIDENCE);
+ read_be32_from_mem(st, &st->bac_run_conf, BAC_RUN_CONFIDENCE);
+
+ return 0;
+}
+#endif
+
+int inv_send_steps(struct inv_mpu_state *st, int step, u64 ts)
+{
+ s16 s[3];
+
+ s[0] = 0;
+ s[1] = (s16) (step & 0xffff);
+ s[2] = (s16) ((step >> 16) & 0xffff);
+ if (st->step_counter_l_on)
+ inv_push_special_8bytes_buffer(st, STEP_COUNTER_HDR, ts, s);
+ if (st->step_counter_wake_l_on) {
+ inv_push_special_8bytes_buffer(st, STEP_COUNTER_WAKE_HDR,
+ ts, s);
+ st->wake_sensor_received = true;
+ }
+ return 0;
+}
+
+void inv_push_step_indicator(struct inv_mpu_state *st, u64 t)
+{
+ s16 sen[3];
+#define STEP_INDICATOR_HEADER 0x0001
+
+ sen[0] = 0;
+ sen[1] = 0;
+ sen[2] = 0;
+ inv_push_8bytes_buffer(st, STEP_INDICATOR_HEADER, t, sen);
+}
+
+/*
+ * inv_irq_handler() - Cache a timestamp at each data ready interrupt.
+ */
+static irqreturn_t inv_irq_handler(int irq, void *dev_id)
+{
+ return IRQ_WAKE_THREAD;
+}
+
+#ifdef TIMER_BASED_BATCHING
+static enum hrtimer_restart inv_batch_timer_handler(struct hrtimer *timer)
+{
+ struct inv_mpu_state *st =
+ container_of(timer, struct inv_mpu_state, hr_batch_timer);
+
+ if (st->chip_config.gyro_enable || st->chip_config.accel_enable) {
+ hrtimer_forward_now(&st->hr_batch_timer,
+ ns_to_ktime(st->batch_timeout));
+ schedule_work(&st->batch_work);
+ return HRTIMER_RESTART;
+ }
+ st->is_batch_timer_running = 0;
+ return HRTIMER_NORESTART;
+}
+#endif
+
+void inv_mpu_unconfigure_ring(struct iio_dev *indio_dev)
+{
+ struct inv_mpu_state *st = iio_priv(indio_dev);
+#ifdef KERNEL_VERSION_4_X
+ devm_free_irq(st->dev, st->irq, st);
+ devm_iio_kfifo_free(st->dev, indio_dev->buffer);
+#else
+ free_irq(st->irq, st);
+ iio_kfifo_free(indio_dev->buffer);
+#endif
+};
+EXPORT_SYMBOL_GPL(inv_mpu_unconfigure_ring);
+
+#ifndef KERNEL_VERSION_4_X
+static int inv_predisable(struct iio_dev *indio_dev)
+{
+ return 0;
+}
+
+static int inv_preenable(struct iio_dev *indio_dev)
+{
+ return 0;
+}
+
+static const struct iio_buffer_setup_ops inv_mpu_ring_setup_ops = {
+ .preenable = &inv_preenable,
+ .predisable = &inv_predisable,
+};
+#endif
+
+int inv_mpu_configure_ring(struct iio_dev *indio_dev)
+{
+ int ret;
+ struct inv_mpu_state *st = iio_priv(indio_dev);
+ struct iio_buffer *ring;
+
+#ifdef TIMER_BASED_BATCHING
+ /* configure hrtimer */
+ hrtimer_init(&st->hr_batch_timer, CLOCK_BOOTTIME, HRTIMER_MODE_REL);
+ st->hr_batch_timer.function = inv_batch_timer_handler;
+ INIT_WORK(&st->batch_work, inv_batch_work);
+#endif
+#ifdef KERNEL_VERSION_4_X
+ ring = devm_iio_kfifo_allocate(st->dev);
+ if (!ring)
+ return -ENOMEM;
+ ring->scan_timestamp = true;
+ iio_device_attach_buffer(indio_dev, ring);
+ ret = devm_request_threaded_irq(st->dev,
+ st->irq,
+ inv_irq_handler,
+ inv_read_fifo,
+ IRQF_TRIGGER_RISING | IRQF_SHARED,
+ "inv_irq",
+ st);
+ if (ret) {
+ devm_iio_kfifo_free(st->dev, ring);
+ return ret;
+ }
+
+ // this mode does not use ops
+ indio_dev->modes = INDIO_ALL_BUFFER_MODES;
+
+ return ret;
+#else
+ ring = iio_kfifo_allocate(indio_dev);
+ if (!ring)
+ return -ENOMEM;
+ indio_dev->buffer = ring;
+ /* setup ring buffer */
+ ring->scan_timestamp = true;
+ indio_dev->setup_ops = &inv_mpu_ring_setup_ops;
+ ret = request_threaded_irq(st->irq,
+ inv_irq_handler,
+ inv_read_fifo,
+ IRQF_TRIGGER_RISING | IRQF_SHARED,
+ "inv_irq",
+ st);
+ if (ret)
+ goto error_iio_sw_rb_free;
+
+ indio_dev->modes |= INDIO_BUFFER_HARDWARE;
+
+ return 0;
+error_iio_sw_rb_free:
+ iio_kfifo_free(indio_dev->buffer);
+
+ return ret;
+#endif
+}
+EXPORT_SYMBOL_GPL(inv_mpu_configure_ring);
diff --git a/drivers/iio/imu/inv_mpu/inv_mpu_spi.c b/drivers/iio/imu/inv_mpu/inv_mpu_spi.c
new file mode 100644
index 0000000..fb91678
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu/inv_mpu_spi.c
@@ -0,0 +1,410 @@
+/*
+* Copyright (C) 2012-2018 InvenSense, Inc.
+*
+* This software is licensed under the terms of the GNU General Public
+* License version 2, as published by the Free Software Foundation, and
+* may be copied, distributed, and modified under those terms.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*/
+#define pr_fmt(fmt) "inv_mpu: " fmt
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/sysfs.h>
+#include <linux/jiffies.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/kfifo.h>
+#include <linux/poll.h>
+#include <linux/miscdevice.h>
+#include <linux/spinlock.h>
+
+#include "inv_mpu_iio.h"
+#include "inv_mpu_dts.h"
+
+#define INV_SPI_READ 0x80
+
+static int inv_spi_single_write(struct inv_mpu_state *st, u8 reg, u8 data)
+{
+ struct spi_message msg;
+ int res;
+ u8 d[2];
+ struct spi_transfer xfers = {
+ .tx_buf = d,
+ .bits_per_word = 8,
+ .len = 2,
+ };
+
+ pr_debug("reg_write: reg=0x%x data=0x%x\n", reg, data);
+ d[0] = reg;
+ d[1] = data;
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfers, &msg);
+ res = spi_sync(to_spi_device(st->dev), &msg);
+
+ return res;
+}
+
+static int inv_spi_read(struct inv_mpu_state *st, u8 reg, int len, u8 *data)
+{
+ struct spi_message msg;
+ int res;
+ u8 d[1];
+ struct spi_transfer xfers[] = {
+ {
+ .tx_buf = d,
+ .bits_per_word = 8,
+ .len = 1,
+ },
+ {
+ .rx_buf = data,
+ .bits_per_word = 8,
+ .len = len,
+ }
+ };
+
+ if (!data)
+ return -EINVAL;
+
+ d[0] = (reg | INV_SPI_READ);
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfers[0], &msg);
+ spi_message_add_tail(&xfers[1], &msg);
+ res = spi_sync(to_spi_device(st->dev), &msg);
+
+ if (len ==1)
+ pr_debug("reg_read: reg=0x%x length=%d data=0x%x\n",
+ reg, len, data[0]);
+ else
+ pr_debug("reg_read: reg=0x%x length=%d d0=0x%x d1=0x%x\n",
+ reg, len, data[0], data[1]);
+
+ return res;
+
+}
+
+static int inv_spi_mem_write(struct inv_mpu_state *st, u8 mpu_addr, u16 mem_addr,
+ u32 len, u8 const *data)
+{
+ struct spi_message msg;
+ u8 buf[258];
+ int res;
+
+ struct spi_transfer xfers = {
+ .tx_buf = buf,
+ .bits_per_word = 8,
+ .len = len + 1,
+ };
+
+ if (!data || !st)
+ return -EINVAL;
+
+ if (len > (sizeof(buf) - 1))
+ return -ENOMEM;
+
+ inv_plat_single_write(st, REG_MEM_BANK_SEL, mem_addr >> 8);
+ inv_plat_single_write(st, REG_MEM_START_ADDR, mem_addr & 0xFF);
+
+ buf[0] = REG_MEM_R_W;
+ memcpy(buf + 1, data, len);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfers, &msg);
+ res = spi_sync(to_spi_device(st->dev), &msg);
+
+ return res;
+}
+
+static int inv_spi_mem_read(struct inv_mpu_state *st, u8 mpu_addr, u16 mem_addr,
+ u32 len, u8 *data)
+{
+ int res;
+
+ if (!data || !st)
+ return -EINVAL;
+
+ if (len > 256)
+ return -EINVAL;
+
+ res = inv_plat_single_write(st, REG_MEM_BANK_SEL, mem_addr >> 8);
+ res = inv_plat_single_write(st, REG_MEM_START_ADDR, mem_addr & 0xFF);
+ res = inv_plat_read(st, REG_MEM_R_W, len, data);
+
+ return res;
+}
+
+/*
+ * inv_mpu_probe() - probe function.
+ */
+static int inv_mpu_probe(struct spi_device *spi)
+{
+ const struct spi_device_id *id = spi_get_device_id(spi);
+ struct inv_mpu_state *st;
+ struct iio_dev *indio_dev;
+ int result;
+
+#ifdef KERNEL_VERSION_4_X
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (indio_dev == NULL) {
+ pr_err("memory allocation failed\n");
+ result = -ENOMEM;
+ goto out_no_free;
+ }
+#else
+ indio_dev = iio_device_alloc(sizeof(*st));
+ if (indio_dev == NULL) {
+ pr_err("memory allocation failed\n");
+ result = -ENOMEM;
+ goto out_no_free;
+ }
+#endif
+ st = iio_priv(indio_dev);
+ st->write = inv_spi_single_write;
+ st->read = inv_spi_read;
+ st->mem_write = inv_spi_mem_write;
+ st->mem_read = inv_spi_mem_read;
+ st->dev = &spi->dev;
+ st->irq = spi->irq;
+#if !defined(CONFIG_INV_MPU_IIO_ICM20602) \
+ && !defined(CONFIG_INV_MPU_IIO_IAM20680)
+ st->i2c_dis = BIT_I2C_IF_DIS;
+#endif
+ st->bus_type = BUS_SPI;
+ spi_set_drvdata(spi, indio_dev);
+ indio_dev->dev.parent = &spi->dev;
+ indio_dev->name = id->name;
+
+#ifdef CONFIG_OF
+ result = invensense_mpu_parse_dt(st->dev, &st->plat_data);
+ if (result)
+# ifdef KERNEL_VERSION_4_X
+ return -ENODEV;
+# else
+ goto out_free;
+# endif
+ /* Power on device */
+ if (st->plat_data.power_on) {
+ result = st->plat_data.power_on(&st->plat_data);
+ if (result < 0) {
+ dev_err(st->dev, "power_on failed: %d\n", result);
+# ifdef KERNEL_VERSION_4_X
+ return -ENODEV;
+# else
+ goto out_free;
+# endif
+ }
+ pr_info("%s: power on here.\n", __func__);
+ }
+ pr_info("%s: power on.\n", __func__);
+
+ msleep(100);
+#else
+ if (dev_get_platdata(st->dev) == NULL)
+# ifdef KERNEL_VERSION_4_X
+ return -ENODEV;
+# else
+ goto out_free;
+# endif
+ st->plat_data = *(struct mpu_platform_data *)dev_get_platdata(st->dev);
+#endif
+
+ /* power is turned on inside check chip type */
+ result = inv_check_chip_type(indio_dev, id->name);
+ if (result)
+#ifdef KERNEL_VERSION_4_X
+ return -ENODEV;
+#else
+ goto out_free;
+#endif
+
+ result = inv_mpu_configure_ring(indio_dev);
+ if (result) {
+ pr_err("configure ring buffer fail\n");
+ goto out_free;
+ }
+#ifdef KERNEL_VERSION_4_X
+ result = devm_iio_device_register(st->dev, indio_dev);
+ if (result) {
+ pr_err("IIO device register fail\n");
+ goto out_unreg_ring;
+ }
+#else
+ result = iio_buffer_register(indio_dev, indio_dev->channels,
+ indio_dev->num_channels);
+ if (result) {
+ pr_err("ring buffer register fail\n");
+ goto out_unreg_ring;
+ }
+
+ result = iio_device_register(indio_dev);
+ if (result) {
+ pr_err("IIO device register fail\n");
+ goto out_remove_ring;
+ }
+#endif
+
+ result = inv_create_dmp_sysfs(indio_dev);
+ if (result) {
+ pr_err("create dmp sysfs failed\n");
+ goto out_unreg_iio;
+ }
+ init_waitqueue_head(&st->wait_queue);
+ st->resume_state = true;
+#ifdef CONFIG_HAS_WAKELOCK
+ wake_lock_init(&st->wake_lock, WAKE_LOCK_SUSPEND, "inv_mpu");
+#else
+ wakeup_source_init(&st->wake_lock, "inv_mpu");
+#endif
+ dev_info(st->dev, "%s ma-kernel-%s is ready to go!\n",
+ indio_dev->name, INVENSENSE_DRIVER_VERSION);
+
+#ifdef SENSOR_DATA_FROM_REGISTERS
+ pr_info("Data read from registers\n");
+#else
+ pr_info("Data read from FIFO\n");
+#endif
+#ifdef TIMER_BASED_BATCHING
+ pr_info("Timer based batching\n");
+#endif
+
+ return 0;
+#ifdef KERNEL_VERSION_4_X
+out_unreg_iio:
+ devm_iio_device_unregister(st->dev, indio_dev);
+out_unreg_ring:
+ inv_mpu_unconfigure_ring(indio_dev);
+out_free:
+ devm_iio_device_free(st->dev, indio_dev);
+out_no_free:
+#else
+out_unreg_iio:
+ iio_device_unregister(indio_dev);
+out_remove_ring:
+ iio_buffer_unregister(indio_dev);
+out_unreg_ring:
+ inv_mpu_unconfigure_ring(indio_dev);
+out_free:
+ iio_device_free(indio_dev);
+out_no_free:
+#endif
+ dev_err(st->dev, "%s failed %d\n", __func__, result);
+
+ return -EIO;
+}
+
+static void inv_mpu_shutdown(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev = spi_get_drvdata(spi);
+ struct inv_mpu_state *st = iio_priv(indio_dev);
+ int result;
+
+ mutex_lock(&indio_dev->mlock);
+ inv_switch_power_in_lp(st, true);
+ dev_dbg(st->dev, "Shutting down %s...\n", st->hw->name);
+
+ /* reset to make sure previous state are not there */
+ result = inv_plat_single_write(st, REG_PWR_MGMT_1, BIT_H_RESET);
+ if (result)
+ dev_err(st->dev, "Failed to reset %s\n",
+ st->hw->name);
+ msleep(POWER_UP_TIME);
+ /* turn off power to ensure gyro engine is off */
+ result = inv_set_power(st, false);
+ if (result)
+ dev_err(st->dev, "Failed to turn off %s\n",
+ st->hw->name);
+ inv_switch_power_in_lp(st, false);
+ mutex_unlock(&indio_dev->mlock);
+}
+
+/*
+ * inv_mpu_remove() - remove function.
+ */
+static int inv_mpu_remove(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev = spi_get_drvdata(spi);
+ struct inv_mpu_state *st = iio_priv(indio_dev);
+
+#ifdef KERNEL_VERSION_4_X
+ devm_iio_device_unregister(st->dev, indio_dev);
+#else
+ iio_device_unregister(indio_dev);
+ iio_buffer_unregister(indio_dev);
+#endif
+ inv_mpu_unconfigure_ring(indio_dev);
+#ifdef KERNEL_VERSION_4_X
+ devm_iio_device_free(st->dev, indio_dev);
+#else
+ iio_device_free(indio_dev);
+#endif
+ dev_info(st->dev, "inv-mpu-iio module removed.\n");
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int inv_mpu_spi_suspend(struct device *dev)
+{
+ struct iio_dev *indio_dev = spi_get_drvdata(to_spi_device(dev));
+
+ return inv_mpu_suspend(indio_dev);
+}
+
+static void inv_mpu_spi_complete(struct device *dev)
+{
+ struct iio_dev *indio_dev = spi_get_drvdata(to_spi_device(dev));
+
+ inv_mpu_complete(indio_dev);
+}
+#endif
+
+static const struct dev_pm_ops inv_mpu_spi_pmops = {
+#ifdef CONFIG_PM_SLEEP
+ .suspend = inv_mpu_spi_suspend,
+ .complete = inv_mpu_spi_complete,
+#endif
+};
+
+/* device id table is used to identify what device can be
+ * supported by this driver
+ */
+static const struct spi_device_id inv_mpu_id[] = {
+#ifdef CONFIG_INV_MPU_IIO_ICM20648
+ {"icm20645", ICM20645},
+ {"icm10340", ICM10340},
+ {"icm20648", ICM20648},
+#else
+ {"icm20608d", ICM20608D},
+ {"icm20690", ICM20690},
+ {"icm20602", ICM20602},
+ {"iam20680", IAM20680},
+#endif
+ {}
+};
+
+MODULE_DEVICE_TABLE(spi, inv_mpu_id);
+
+static struct spi_driver inv_mpu_driver = {
+ .probe = inv_mpu_probe,
+ .remove = inv_mpu_remove,
+ .shutdown = inv_mpu_shutdown,
+ .id_table = inv_mpu_id,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "inv-mpu-iio-spi",
+ .pm = &inv_mpu_spi_pmops,
+ },
+};
+module_spi_driver(inv_mpu_driver);
+
+MODULE_AUTHOR("Invensense Corporation");
+MODULE_DESCRIPTION("Invensense SPI device driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/imu/inv_mpu/inv_mpu_timestamp.c b/drivers/iio/imu/inv_mpu/inv_mpu_timestamp.c
new file mode 100644
index 0000000..2cc721b
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu/inv_mpu_timestamp.c
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2012-2018 InvenSense, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#define pr_fmt(fmt) "inv_mpu: " fmt
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/sysfs.h>
+#include <linux/jiffies.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/kfifo.h>
+#include <linux/poll.h>
+#include <linux/miscdevice.h>
+#include <linux/math64.h>
+
+#include "inv_mpu_iio.h"
+
+#define INV_TIME_CALIB_THRESHOLD_1 2
+
+#define MIN_DELAY (3 * NSEC_PER_MSEC)
+#define JITTER_THRESH ( 1 * NSEC_PER_MSEC)
+
+int inv_update_dmp_ts(struct inv_mpu_state *st, int ind)
+{
+ int i;
+ u32 counter;
+ u64 ts;
+ enum INV_ENGINE en_ind;
+ struct inv_timestamp_algo *ts_algo = &st->ts_algo;
+ u32 base_time;
+ u64 cal_period;
+
+ if (st->mode_1k_on)
+ cal_period = (NSEC_PER_SEC >> 2);
+ else
+ cal_period = 2 * NSEC_PER_SEC;
+
+ ts = ts_algo->last_run_time - st->sensor[ind].time_calib;
+ counter = st->sensor[ind].sample_calib;
+ en_ind = st->sensor[ind].engine_base;
+ if (en_ind != ts_algo->clock_base)
+ return 0;
+ /* we average over 2 seconds period to do the timestamp calculation */
+ if (ts < cal_period)
+ return 0;
+ /* this is the first time we do timestamp averaging, return */
+ /* after resume from suspend, the clock of linux has up to 1 seconds
+ drift. We should start from the resume clock instead of using clock
+ before resume */
+ if ((!st->sensor[ind].calib_flag) || ts_algo->resume_flag) {
+ st->sensor[ind].sample_calib = 0;
+ st->sensor[ind].time_calib = ts_algo->last_run_time;
+ st->sensor[ind].calib_flag = 1;
+ ts_algo->resume_flag = false;
+
+ return 0;
+ }
+ /* if the sample number in current FIFO is not zero and between now and
+ last update time is more than 2 seconds, we do calculation */
+ if ((counter > 0) &&
+ (ts_algo->last_run_time - st->eng_info[en_ind].last_update_time >
+ cal_period)) {
+ /* duration for each sensor */
+ st->sensor[ind].dur = (u32) div_u64(ts, counter);
+ /* engine duration derived from each sensor */
+ if (st->sensor[ind].div)
+ st->eng_info[en_ind].dur = st->sensor[ind].dur /
+ st->sensor[ind].div;
+ else
+ pr_err("sensor %d divider zero!\n", ind);
+ /* update base time for each sensor */
+ if (st->eng_info[en_ind].divider) {
+ base_time = (st->eng_info[en_ind].dur /
+ st->eng_info[en_ind].divider) *
+ st->eng_info[en_ind].orig_rate;
+ if (st->mode_1k_on)
+ st->eng_info[en_ind].base_time_1k = base_time;
+ else
+ st->eng_info[en_ind].base_time = base_time;
+ } else {
+ pr_err("engine %d divider zero!\n", en_ind);
+ }
+
+ st->eng_info[en_ind].last_update_time = ts_algo->last_run_time;
+ /* update all the sensors duration based on the same engine */
+ for (i = 0; i < SENSOR_NUM_MAX; i++) {
+ if (st->sensor[i].on &&
+ (st->sensor[i].engine_base == en_ind))
+ st->sensor[i].dur = st->sensor[i].div *
+ st->eng_info[en_ind].dur;
+ }
+
+ }
+ st->sensor[ind].sample_calib = 0;
+ st->sensor[ind].time_calib = ts_algo->last_run_time;
+
+ return 0;
+}
+/**
+ * int inv_get_last_run_time_non_dmp_record_mode(struct inv_mpu_state *st)
+ * This is the function to get last run time in non dmp and record mode.
+ * This function will update the last_run_time, which is important parameter
+ * in overall timestamp algorithm.
+ * return value: this function returns fifo count value.
+*/
+int inv_get_last_run_time_non_dmp_record_mode(struct inv_mpu_state *st)
+{
+ long long t_pre, t_post, dur;
+ int fifo_count;
+#ifndef SENSOR_DATA_FROM_REGISTERS
+ int res;
+ u8 data[2];
+#endif
+
+ t_pre = get_time_ns();
+#ifndef SENSOR_DATA_FROM_REGISTERS
+ res = inv_plat_read(st, REG_FIFO_COUNT_H, FIFO_COUNT_BYTE, data);
+ if (res) {
+ pr_info("read REG_FIFO_COUNT_H failed= %d\n", res);
+ return 0;
+ }
+#endif
+ t_post = get_time_ns();
+
+#ifdef SENSOR_DATA_FROM_REGISTERS
+ if (st->fifo_count_mode == BYTE_MODE)
+ fifo_count = st->batch.pk_size;
+ else
+ fifo_count = 1;
+#else
+ fifo_count = be16_to_cpup((__be16 *) (data));
+#endif
+ pr_debug("fifc=%d\n", fifo_count);
+ if (!fifo_count)
+ return 0;
+ if (st->special_mag_mode && (fifo_count == 2)) {
+ pr_debug("special trigger\n");
+ fifo_count = 1;
+ }
+
+ /* In non DMP mode, either gyro or accel duration is the duration
+ for each sample */
+ if (st->chip_config.gyro_enable)
+ dur = st->eng_info[ENGINE_GYRO].dur;
+ else
+ dur = st->eng_info[ENGINE_ACCEL].dur;
+
+ if (st->fifo_count_mode == BYTE_MODE) {
+ fifo_count /= st->batch.pk_size;
+ }
+
+ /* In record mode, each number in fifo_count is 1 record or 1 sample */
+ st->ts_algo.last_run_time += dur * fifo_count;
+ if (st->ts_algo.last_run_time < t_pre)
+ st->ts_algo.last_run_time = t_pre;
+ if (st->ts_algo.last_run_time > t_post)
+ st->ts_algo.last_run_time = t_post;
+
+ return fifo_count;
+}
+
+int inv_get_dmp_ts(struct inv_mpu_state *st, int i)
+{
+ u64 current_time;
+ int expected_lower_duration, expected_upper_duration;
+
+ current_time = get_time_ns();
+
+ st->sensor[i].ts += st->sensor[i].dur + st->sensor[i].ts_adj;
+
+ if (st->sensor[i].ts < st->sensor[i].previous_ts)
+ st->sensor[i].ts = st->sensor[i].previous_ts + st->sensor[i].dur;
+
+ //hifi sensor limits ts jitter to +/- 2%
+ expected_upper_duration = st->eng_info[st->sensor[i].engine_base].divider * 1020000;
+ expected_lower_duration = st->eng_info[st->sensor[i].engine_base].divider * 980000;
+#if defined(CONFIG_INV_MPU_IIO_ICM20602) || defined(CONFIG_INV_MPU_IIO_ICM20690) || defined(CONFIG_INV_MPU_IIO_IAM20680)
+ if (st->sensor[i].ts < st->sensor[i].previous_ts + expected_lower_duration)
+ st->sensor[i].ts = st->sensor[i].previous_ts + expected_lower_duration;
+ if (st->sensor[i].ts > st->sensor[i].previous_ts + expected_upper_duration)
+ st->sensor[i].ts = st->sensor[i].previous_ts + expected_upper_duration;
+#endif
+ if (st->sensor[i].ts > current_time )
+ st->sensor[i].ts = current_time;
+
+ st->sensor[i].previous_ts = st->sensor[i].ts;
+
+ pr_debug("ts=%lld, reset=%lld\n", st->sensor[i].ts, st->ts_algo.reset_ts);
+ if (st->sensor[i].ts < st->ts_algo.reset_ts) {
+ pr_debug("less than reset\n");
+ st->sensor[i].send = false;
+ } else {
+ st->sensor[i].send = true;
+ }
+
+ if (st->header_count == 1)
+ inv_update_dmp_ts(st, i);
+
+ return 0;
+}
+
+static void process_sensor_bounding(struct inv_mpu_state *st, int i)
+{
+ s64 elaps_time, thresh1, thresh2;
+ struct inv_timestamp_algo *ts_algo = &st->ts_algo;
+ u32 dur;
+
+ elaps_time = ((u64) (st->sensor[i].dur)) * st->sensor[i].count;
+ thresh1 = ts_algo->last_run_time - elaps_time;
+
+ dur = max(st->sensor[i].dur, (int)MIN_DELAY);
+ thresh2 = thresh1 - dur;
+ if (thresh1 < 0)
+ thresh1 = 0;
+ if (thresh2 < 0)
+ thresh2 = 0;
+ st->sensor[i].ts_adj = 0;
+ if ((ts_algo->calib_counter >= INV_TIME_CALIB_THRESHOLD_1) &&
+ (!ts_algo->resume_flag)) {
+ if (st->sensor[i].ts < thresh2)
+ st->sensor[i].ts_adj = thresh2 - st->sensor[i].ts;
+ } else if ((ts_algo->calib_counter >=
+ INV_TIME_CALIB_THRESHOLD_1) && ts_algo->resume_flag) {
+ if (st->sensor[i].ts < thresh2)
+ st->sensor[i].ts = ts_algo->last_run_time -
+ elaps_time - JITTER_THRESH;
+ } else {
+ st->sensor[i].ts = ts_algo->last_run_time - elaps_time -
+ JITTER_THRESH;
+ st->sensor[i].previous_ts = st->sensor[i].ts;
+ }
+
+ if (st->sensor[i].ts > thresh1)
+ st->sensor[i].ts_adj = thresh1 - st->sensor[i].ts;
+ pr_debug("cali=%d\n", st->ts_algo.calib_counter);
+ pr_debug("adj= %lld\n", st->sensor[i].ts_adj);
+ pr_debug("dur= %d count= %d last= %lld\n", st->sensor[i].dur,
+ st->sensor[i].count, ts_algo->last_run_time);
+ if (st->sensor[i].ts_adj && (st->sensor[i].count > 1))
+ st->sensor[i].ts_adj = div_s64(st->sensor[i].ts_adj,
+ st->sensor[i].count);
+}
+/* inv_bound_timestamp (struct inv_mpu_state *st)
+ The purpose this function is to give a generic bound to each
+ sensor timestamp. The timestamp cannot exceed current time.
+ The timestamp cannot backwards one sample time either, otherwise, there
+ would be another sample in between. Using this principle, we can bound
+ the sensor samples */
+int inv_bound_timestamp(struct inv_mpu_state *st)
+{
+ int i;
+ struct inv_timestamp_algo *ts_algo = &st->ts_algo;
+
+ for (i = 0; i < SENSOR_NUM_MAX; i++) {
+ if (st->sensor[i].on) {
+ if (st->sensor[i].count) {
+ process_sensor_bounding(st, i);
+ } else if (ts_algo->calib_counter <
+ INV_TIME_CALIB_THRESHOLD_1) {
+ st->sensor[i].ts = ts_algo->reset_ts;
+ st->sensor[i].previous_ts = st->sensor[i].ts;
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/drivers/iio/imu/inv_mpu/inv_test/Kconfig b/drivers/iio/imu/inv_mpu/inv_test/Kconfig
new file mode 100644
index 0000000..a4dfd95
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu/inv_test/Kconfig
@@ -0,0 +1,13 @@
+#
+# Kconfig for Invensense IIO testing hooks
+#
+
+config INV_TESTING
+ boolean "Invensense IIO testing hooks"
+ depends on INV_MPU_IIO || INV_AMI306_IIO || INV_YAS530 || INV_HUB_IIO
+ default n
+ help
+ This flag enables display of additional testing information from the
+ Invensense IIO drivers
+ It also enables the I2C counters facility to perform IO profiling.
+ Some additional sysfs entries will appear when this flag is enabled.
diff --git a/drivers/iio/imu/inv_mpu/inv_test/Makefile b/drivers/iio/imu/inv_mpu/inv_test/Makefile
new file mode 100644
index 0000000..4f0edd3
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu/inv_test/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for Invensense IIO testing hooks.
+#
+
+obj-$(CONFIG_INV_TESTING) += inv_counters.o
+
diff --git a/drivers/iio/imu/inv_mpu/inv_test/inv_counters.c b/drivers/iio/imu/inv_mpu/inv_test/inv_counters.c
new file mode 100644
index 0000000..f60337c
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu/inv_test/inv_counters.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2012-2017 InvenSense, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/miscdevice.h>
+#include <linux/err.h>
+#include <linux/sysfs.h>
+#include <linux/kdev_t.h>
+#include <linux/string.h>
+#include <linux/jiffies.h>
+#include <linux/spinlock.h>
+#include <linux/kernel_stat.h>
+
+#include "inv_counters.h"
+
+static int mpu_irq;
+static int accel_irq;
+static int compass_irq;
+
+struct inv_counters {
+ uint32_t i2c_tempreads;
+ uint32_t i2c_mpureads;
+ uint32_t i2c_mpuwrites;
+ uint32_t i2c_accelreads;
+ uint32_t i2c_accelwrites;
+ uint32_t i2c_compassreads;
+ uint32_t i2c_compasswrites;
+ uint32_t i2c_compassirq;
+ uint32_t i2c_accelirq;
+};
+
+static struct inv_counters Counters;
+
+static ssize_t i2c_counters_show(struct class *cls,
+ struct class_attribute *attr, char *buf)
+{
+ return scnprintf(buf, PAGE_SIZE,
+ "%ld.%03ld %u %u %u %u %u %u %u %u %u %u\n",
+ jiffies / HZ, ((jiffies % HZ) * (1024 / HZ)),
+ mpu_irq ? kstat_irqs(mpu_irq) : 0,
+ Counters.i2c_tempreads,
+ Counters.i2c_mpureads, Counters.i2c_mpuwrites,
+ accel_irq ? kstat_irqs(accel_irq) : Counters.i2c_accelirq,
+ Counters.i2c_accelreads, Counters.i2c_accelwrites,
+ compass_irq ? kstat_irqs(compass_irq) : Counters.i2c_compassirq,
+ Counters.i2c_compassreads, Counters.i2c_compasswrites);
+}
+
+void inv_iio_counters_set_i2cirq(enum irqtype type, int irq)
+{
+ switch (type) {
+ case IRQ_MPU:
+ mpu_irq = irq;
+ break;
+ case IRQ_ACCEL:
+ accel_irq = irq;
+ break;
+ case IRQ_COMPASS:
+ compass_irq = irq;
+ break;
+ }
+}
+EXPORT_SYMBOL_GPL(inv_iio_counters_set_i2cirq);
+
+void inv_iio_counters_tempread(int count)
+{
+ Counters.i2c_tempreads += count;
+}
+EXPORT_SYMBOL_GPL(inv_iio_counters_tempread);
+
+void inv_iio_counters_mpuread(int count)
+{
+ Counters.i2c_mpureads += count;
+}
+EXPORT_SYMBOL_GPL(inv_iio_counters_mpuread);
+
+void inv_iio_counters_mpuwrite(int count)
+{
+ Counters.i2c_mpuwrites += count;
+}
+EXPORT_SYMBOL_GPL(inv_iio_counters_mpuwrite);
+
+void inv_iio_counters_accelread(int count)
+{
+ Counters.i2c_accelreads += count;
+}
+EXPORT_SYMBOL_GPL(inv_iio_counters_accelread);
+
+void inv_iio_counters_accelwrite(int count)
+{
+ Counters.i2c_accelwrites += count;
+}
+EXPORT_SYMBOL_GPL(inv_iio_counters_accelwrite);
+
+void inv_iio_counters_compassread(int count)
+{
+ Counters.i2c_compassreads += count;
+}
+EXPORT_SYMBOL_GPL(inv_iio_counters_compassread);
+
+void inv_iio_counters_compasswrite(int count)
+{
+ Counters.i2c_compasswrites += count;
+}
+EXPORT_SYMBOL_GPL(inv_iio_counters_compasswrite);
+
+void inv_iio_counters_compassirq(void)
+{
+ Counters.i2c_compassirq++;
+}
+EXPORT_SYMBOL_GPL(inv_iio_counters_compassirq);
+
+void inv_iio_counters_accelirq(void)
+{
+ Counters.i2c_accelirq++;
+}
+EXPORT_SYMBOL_GPL(inv_iio_counters_accelirq);
+
+static struct class_attribute inv_class_attr[] = {
+ __ATTR(i2c_counter, S_IRUGO, i2c_counters_show, NULL),
+ __ATTR_NULL
+};
+
+static struct class inv_counters_class = {
+ .name = "inv_counters",
+ .owner = THIS_MODULE,
+ .class_attrs = (struct class_attribute *) &inv_class_attr
+};
+
+static int __init inv_counters_init(void)
+{
+ memset(&Counters, 0, sizeof(Counters));
+
+ return class_register(&inv_counters_class);
+}
+
+static void __exit inv_counters_exit(void)
+{
+ class_unregister(&inv_counters_class);
+}
+
+module_init(inv_counters_init);
+module_exit(inv_counters_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("GESL");
+MODULE_DESCRIPTION("inv_counters debug support");
+
diff --git a/drivers/iio/imu/inv_mpu/inv_test/inv_counters.h b/drivers/iio/imu/inv_mpu/inv_test/inv_counters.h
new file mode 100644
index 0000000..62f7627
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu/inv_test/inv_counters.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2012-2017 InvenSense, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef _INV_COUNTERS_H_
+#define _INV_COUNTERS_H_
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/sysfs.h>
+#include <linux/string.h>
+#include <linux/jiffies.h>
+#include <linux/spinlock.h>
+
+#ifdef CONFIG_INV_TESTING
+
+enum irqtype {
+ IRQ_MPU,
+ IRQ_ACCEL,
+ IRQ_COMPASS
+};
+
+#define INV_I2C_INC_MPUREAD(x) inv_iio_counters_mpuread(x)
+#define INV_I2C_INC_MPUWRITE(x) inv_iio_counters_mpuwrite(x)
+#define INV_I2C_INC_ACCELREAD(x) inv_iio_counters_accelread(x)
+#define INV_I2C_INC_ACCELWRITE(x) inv_iio_counters_accelwrite(x)
+#define INV_I2C_INC_COMPASSREAD(x) inv_iio_counters_compassread(x)
+#define INV_I2C_INC_COMPASSWRITE(x) inv_iio_counters_compasswrite(x)
+
+#define INV_I2C_INC_TEMPREAD(x) inv_iio_counters_tempread(x)
+
+#define INV_I2C_SETIRQ(type, irq) inv_iio_counters_set_i2cirq(type, irq)
+#define INV_I2C_INC_COMPASSIRQ() inv_iio_counters_compassirq()
+#define INV_I2C_INC_ACCELIRQ() inv_iio_counters_accelirq()
+
+void inv_iio_counters_mpuread(int count);
+void inv_iio_counters_mpuwrite(int count);
+void inv_iio_counters_accelread(int count);
+void inv_iio_counters_accelwrite(int count);
+void inv_iio_counters_compassread(int count);
+void inv_iio_counters_compasswrite(int count);
+
+void inv_iio_counters_tempread(int count);
+
+void inv_iio_counters_set_i2cirq(enum irqtype type, int irq);
+void inv_iio_counters_compassirq(void);
+void inv_iio_counters_accelirq(void);
+
+#else
+
+#define INV_I2C_INC_MPUREAD(x)
+#define INV_I2C_INC_MPUWRITE(x)
+#define INV_I2C_INC_ACCELREAD(x)
+#define INV_I2C_INC_ACCELWRITE(x)
+#define INV_I2C_INC_COMPASSREAD(x)
+#define INV_I2C_INC_COMPASSWRITE(x)
+
+#define INV_I2C_INC_TEMPREAD(x)
+
+#define INV_I2C_SETIRQ(type, irq)
+#define INV_I2C_INC_COMPASSIRQ()
+#define INV_I2C_INC_ACCELIRQ()
+
+#endif /* CONFIG_INV_TESTING */
+
+#endif /* _INV_COUNTERS_H_ */
+
diff --git a/drivers/iio/imu/st_asm330lhh/Kconfig b/drivers/iio/imu/st_asm330lhh/Kconfig
new file mode 100644
index 0000000..092cc48
--- /dev/null
+++ b/drivers/iio/imu/st_asm330lhh/Kconfig
@@ -0,0 +1,23 @@
+
+config IIO_ST_ASM330LHH
+ tristate "STMicroelectronics ASM330LHH sensor"
+ depends on (I2C || SPI)
+ select IIO_BUFFER
+ select IIO_KFIFO_BUF
+ select IIO_ST_ASM330LHH_I2C if (I2C)
+ select IIO_ST_ASM330LHH_SPI if (SPI_MASTER)
+ help
+ Say yes here to build support for STMicroelectronics ASM330LHH imu
+ sensor.
+
+ To compile this driver as a module, choose M here: the module
+ will be called st_asm330lhh.
+
+config IIO_ST_ASM330LHH_I2C
+ tristate
+ depends on IIO_ST_ASM330LHH
+
+config IIO_ST_ASM330LHH_SPI
+ tristate
+ depends on IIO_ST_ASM330LHH
+
diff --git a/drivers/iio/imu/st_asm330lhh/Makefile b/drivers/iio/imu/st_asm330lhh/Makefile
new file mode 100644
index 0000000..7af80de
--- /dev/null
+++ b/drivers/iio/imu/st_asm330lhh/Makefile
@@ -0,0 +1,5 @@
+st_asm330lhh-y := st_asm330lhh_core.o st_asm330lhh_buffer.o
+
+obj-$(CONFIG_IIO_ST_ASM330LHH) += st_asm330lhh.o
+obj-$(CONFIG_IIO_ST_ASM330LHH_I2C) += st_asm330lhh_i2c.o
+obj-$(CONFIG_IIO_ST_ASM330LHH_SPI) += st_asm330lhh_spi.o
diff --git a/drivers/iio/imu/st_asm330lhh/README.md b/drivers/iio/imu/st_asm330lhh/README.md
new file mode 100644
index 0000000..f06afd3
--- /dev/null
+++ b/drivers/iio/imu/st_asm330lhh/README.md
@@ -0,0 +1,201 @@
+Index
+=======
+ * Introduction
+ * Driver Integration details
+ * Android SensorHAL integration
+ * Linux SensorHAL integration
+ * More information
+ * Copyright
+
+
+Introduction
+==============
+This repository contains asm330lhh IMU STMicroelectronics MEMS sensor linux driver support for kernel version 3.18, 4.4 and 4.9.
+
+Data collected by asm330lhh STM sensor are pushed to userland through the kernel buffers of Linux IIO framework. User space applications can get sensor events by reading the related IIO devices created in the /dev directory (*/dev/iio{x}*). Please see [IIO][1] for more information.
+
+Asm330lhh IMU STM MEMS sensor support *I2C/SPI* digital interface. Please refer to [I2C][2] and [SPI][3] for detailed documentation.
+
+The STM Hardware Abstraction Layer (*HAL*) defines a standard interface for STM sensors allowing Android to be agnostic about low level driver implementation. The HAL library is packaged into modules (.so) file and loaded by the Android or Linux system at the appropriate time. For more information see [AOSP HAL Interface](https://source.android.com/devices/sensors/hal-interface.html)
+
+STM Sensor HAL is leaning on [Linux IIO framework](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/iio) to gather data from sensor device drivers and to forward samples to the Android Framework
+
+Driver Integration details
+=====================
+
+In order to explain how to integrate Asm330lhh IMU STM sensor into the kernel, please consider the following example
+
+### Source code integration
+
+> * Copy driver source code into your linux kernel target directory (e.g. *drivers/iio/imu*)
+> * Edit related Kconfig (e.g. *drivers/iio/imu/Kconfig*) adding *ASM330LHH* support:
+
+> source "drivers/iio/imu/st_asm330lhh/Kconfig"
+
+> * Edit related Makefile (e.g. *drivers/iio/imu/Makefile*) adding the following line:
+
+> obj-y += st_asm330lhh/
+
+### Device Tree configuration
+
+> To enable driver probing, add the asm330lhh node to the platform device tree as described below.
+
+> **Required properties:**
+
+> *- compatible*: "st,asm330lhh"
+
+> *- reg*: the I2C address or SPI chip select the device will respond to
+
+> *- interrupt-parent*: phandle to the parent interrupt controller as documented in [interrupts][4]
+
+> *- interrupts*: interrupt mapping for IRQ as documented in [interrupts][4]
+>
+>**Recommended properties for SPI bus usage:**
+
+> *- spi-max-frequency*: maximum SPI bus frequency as documented in [SPI][3]
+>
+> **Optional properties:**
+
+> *- st,drdy-int-pin*: MEMS sensor interrupt line to use (default 1)
+
+> I2C example (based on Raspberry PI 3):
+
+> &i2c0 {
+> status = "ok";
+> #address-cells = <0x1>;
+> #size-cells = <0x0>;
+> asm330lhh@6b {
+> compatible = "st,asm330lhh";
+> reg = <0x6b>;
+> interrupt-parent = <&gpio>;
+> interrupts = <26 IRQ_TYPE_EDGE_RISING>;
+> };
+
+> SPI example (based on Raspberry PI 3):
+
+> &spi0 {
+> status = "ok";
+> #address-cells = <0x1>;
+> #size-cells = <0x0>;
+> asm330lhh@0 {
+> spi-max-frequency = <500000>;
+> compatible = "st,asm330lhh";
+> reg = <0>;
+> interrupt-parent = <&gpio>;
+> interrupts = <26 IRQ_TYPE_EDGE_RISING>;
+> };
+
+### Kernel configuration
+
+Configure kernel with *make menuconfig* (alternatively use *make xconfig* or *make qconfig*)
+
+> Device Drivers --->
+> <M> Industrial I/O support --->
+> Inertial measurement units --->
+> <M> STMicroelectronics ASM330LHH sensor --->
+
+
+Android SensorHAL integration
+==============
+
+STM Sensor HAL is written in *C++* language using object-oriented design. For each hw sensor there is a custom class file (*Accelerometer.cpp*, *Gyroscope.cpp*) which extends the common base class (*SensorBase.cpp*).
+
+Copy the HAL source code into *<AOSP_DIR\>/hardware/STMicroelectronics/SensorHAL_IIO* folder. During building process Android will include automatically the SensorHAL Android.mk.
+In *<AOSP_DIR\>/device/<vendor\>/<board\>/device.mk* add package build information:
+
+ PRODUCT_PACKAGES += sensors.{TARGET_BOARD_PLATFORM}
+
+ Note: device.mk can not read $(TARGET_BOARD_PLATFORM) variable, read and replace the value from your BoardConfig.mk (e.g. PRODUCT_PACKAGES += sensors.msm8974 for Nexus 5)
+
+To compile the SensorHAL_IIO just build AOSP source code from *$TOP* folder
+
+ $ cd <AOSP_DIR>
+ $ source build/envsetup.sh
+ $ lunch <select target platform>
+ $ make V=99
+
+The compiled library will be placed in *<AOSP_DIR\>/out/target/product/<board\>/system/vendor/lib/hw/sensor.{TARGET_BOARD_PLATFORM}.so*
+
+To configure sensor the Sensor HAL IIO use mm utility from HAL root folder
+
+ since Android 7
+ $mm sensors-defconfig (default configuration)
+ $mm sensors-menuconfig
+
+ after Android 7
+ make -f Makefile_config sensors-defconfig (default configuration)
+ make -f Makefile_config sensors-menuconfig
+
+Linux SensorHAL integration
+==============
+
+Linux Sensor HAL share the same source code of Android Sensor HAL. Before compiling the Linux Sensor HAL IIO
+you need to follow the same procedure listed in previous chapter "Android SensorHAL integration"
+To cross compile Linux Sensor HAL must export the following shell variables
+
+> export AOSP_DIR=<AOSP_DIR>
+> export ARCH=<your target architecture>
+> export CROSS_COMPILE=<toolchain for your target>
+
+then in *<AOSP_DIR\>/hardware/STMicroelectronics/SensorHAL_IIO* folder type
+> make
+
+it will produce a SensorHAL.so file containing the library.
+In relative pat Documentation/LinuxHal/ there are some examples explaining how to use Linux Sensor HAL
+
+Copyright
+========
+Copyright (C) 2017 STMicroelectronics
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+
+More Information
+=================
+[http://st.com](http://st.com)
+
+[https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/iio](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/input)
+
+[https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/i2c](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/i2c)
+
+[https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/spi](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/spi)
+
+[https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bings/interrupt-controller/interrupts.txt](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt)
+
+
+Copyright Driver
+===========
+Copyright (C) 2017 STMicroelectronics
+
+This software is distributed under the GNU General Public License - see the accompanying COPYING file for more details.
+
+[1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/iio/iio_configfs.txt "IIO"
+[2]: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/i2c "I2C"
+[3]: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/spi "SPI"
+[4]: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt "interrupts"
+
+Copyright SensorHAL
+========
+Copyright (C) 2017 STMicroelectronics
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/drivers/iio/imu/st_asm330lhh/st_asm330lhh.h b/drivers/iio/imu/st_asm330lhh/st_asm330lhh.h
new file mode 100644
index 0000000..52b293f
--- /dev/null
+++ b/drivers/iio/imu/st_asm330lhh/st_asm330lhh.h
@@ -0,0 +1,238 @@
+/*
+ * STMicroelectronics st_asm330lhh sensor driver
+ *
+ * Copyright 2018 STMicroelectronics Inc.
+ *
+ * Lorenzo Bianconi <lorenzo.bianconi@st.com>
+ *
+ * Licensed under the GPL-2.
+ */
+
+#ifndef ST_ASM330LHH_H
+#define ST_ASM330LHH_H
+
+#include <linux/device.h>
+#include <linux/iio/iio.h>
+
+#define ST_ASM330LHH_REVISION "2.0.1"
+#define ST_ASM330LHH_PATCH "1"
+
+#define ST_ASM330LHH_VERSION "v" \
+ ST_ASM330LHH_REVISION \
+ "-" \
+ ST_ASM330LHH_PATCH
+
+#define ST_ASM330LHH_DEV_NAME "asm330lhh"
+
+#define ST_ASM330LHH_SAMPLE_SIZE 6
+#define ST_ASM330LHH_TS_SAMPLE_SIZE 4
+#define ST_ASM330LHH_TAG_SIZE 1
+#define ST_ASM330LHH_FIFO_SAMPLE_SIZE (ST_ASM330LHH_SAMPLE_SIZE + \
+ ST_ASM330LHH_TAG_SIZE)
+#define ST_ASM330LHH_MAX_FIFO_DEPTH 416
+
+#define ST_ASM330LHH_REG_FIFO_BATCH_ADDR 0x09
+#define ST_ASM330LHH_REG_FIFO_CTRL4_ADDR 0x0a
+#define ST_ASM330LHH_REG_STATUS_ADDR 0x1e
+#define ST_ASM330LHH_REG_STATUS_TDA BIT(2)
+#define ST_ASM330LHH_REG_OUT_TEMP_L_ADDR 0x20
+#define ST_ASM330LHH_REG_OUT_TEMP_H_ADDR 0x21
+
+#define ST_ASM330LHH_MAX_ODR 416
+
+/* Define Custom events for FIFO flush */
+#define CUSTOM_IIO_EV_DIR_FIFO_EMPTY (IIO_EV_DIR_NONE + 1)
+#define CUSTOM_IIO_EV_DIR_FIFO_DATA (IIO_EV_DIR_NONE + 2)
+#define CUSTOM_IIO_EV_TYPE_FIFO_FLUSH (IIO_EV_TYPE_CHANGE + 1)
+
+#define ST_ASM330LHH_CHANNEL(chan_type, addr, mod, ch2, scan_idx, \
+ rb, sb, sg) \
+{ \
+ .type = chan_type, \
+ .address = addr, \
+ .modified = mod, \
+ .channel2 = ch2, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE), \
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+ .scan_index = scan_idx, \
+ .scan_type = { \
+ .sign = sg, \
+ .realbits = rb, \
+ .storagebits = sb, \
+ .endianness = IIO_LE, \
+ }, \
+}
+
+static const struct iio_event_spec st_asm330lhh_flush_event = {
+ .type = CUSTOM_IIO_EV_TYPE_FIFO_FLUSH,
+ .dir = IIO_EV_DIR_EITHER,
+};
+
+#define ST_ASM330LHH_FLUSH_CHANNEL(dtype) \
+{ \
+ .type = dtype, \
+ .modified = 0, \
+ .scan_index = -1, \
+ .indexed = -1, \
+ .event_spec = &st_asm330lhh_flush_event, \
+ .num_event_specs = 1, \
+}
+
+#define ST_ASM330LHH_RX_MAX_LENGTH 8
+#define ST_ASM330LHH_TX_MAX_LENGTH 8
+
+struct st_asm330lhh_transfer_buffer {
+ u8 rx_buf[ST_ASM330LHH_RX_MAX_LENGTH];
+ u8 tx_buf[ST_ASM330LHH_TX_MAX_LENGTH] ____cacheline_aligned;
+};
+
+struct st_asm330lhh_transfer_function {
+ int (*read)(struct device *dev, u8 addr, int len, u8 *data);
+ int (*write)(struct device *dev, u8 addr, int len, u8 *data);
+};
+
+struct st_asm330lhh_reg {
+ u8 addr;
+ u8 mask;
+};
+
+struct st_asm330lhh_odr {
+ u16 hz;
+ u8 val;
+};
+
+#define ST_ASM330LHH_ODR_LIST_SIZE 7
+struct st_asm330lhh_odr_table_entry {
+ struct st_asm330lhh_reg reg;
+ struct st_asm330lhh_odr odr_avl[ST_ASM330LHH_ODR_LIST_SIZE];
+};
+
+struct st_asm330lhh_fs {
+ u32 gain;
+ u8 val;
+};
+
+#define ST_ASM330LHH_FS_ACC_LIST_SIZE 4
+#define ST_ASM330LHH_FS_GYRO_LIST_SIZE 6
+#define ST_ASM330LHH_FS_TEMP_LIST_SIZE 1
+#define ST_ASM330LHH_FS_LIST_SIZE 6
+struct st_asm330lhh_fs_table_entry {
+ u32 size;
+ struct st_asm330lhh_reg reg;
+ struct st_asm330lhh_fs fs_avl[ST_ASM330LHH_FS_LIST_SIZE];
+};
+
+enum st_asm330lhh_sensor_id {
+ ST_ASM330LHH_ID_ACC,
+ ST_ASM330LHH_ID_GYRO,
+ ST_ASM330LHH_ID_TEMP,
+ ST_ASM330LHH_ID_MAX,
+};
+
+enum st_asm330lhh_fifo_mode {
+ ST_ASM330LHH_FIFO_BYPASS = 0x0,
+ ST_ASM330LHH_FIFO_CONT = 0x6,
+};
+
+enum {
+ ST_ASM330LHH_HW_FLUSH,
+ ST_ASM330LHH_HW_OPERATIONAL,
+};
+
+/**
+ * struct st_asm330lhh_sensor - ST IMU sensor instance
+ * @id: Sensor identifier.
+ * @hw: Pointer to instance of struct st_asm330lhh_hw.
+ * @gain: Configured sensor sensitivity.
+ * @odr: Output data rate of the sensor [Hz].
+ * @watermark: Sensor watermark level.
+ * @batch_mask: Sensor mask for FIFO batching register
+ */
+struct st_asm330lhh_sensor {
+ enum st_asm330lhh_sensor_id id;
+ struct st_asm330lhh_hw *hw;
+
+ u32 gain;
+ u16 odr;
+ u32 offset;
+
+ __le16 old_data;
+
+ u8 std_samples;
+ u8 std_level;
+
+ u16 watermark;
+ u8 batch_mask;
+ u8 batch_addr;
+};
+
+/**
+ * struct st_asm330lhh_hw - ST IMU MEMS hw instance
+ * @dev: Pointer to instance of struct device (I2C or SPI).
+ * @irq: Device interrupt line (I2C or SPI).
+ * @lock: Mutex to protect read and write operations.
+ * @fifo_lock: Mutex to prevent concurrent access to the hw FIFO.
+ * @fifo_mode: FIFO operating mode supported by the device.
+ * @state: hw operational state.
+ * @enable_mask: Enabled sensor bitmask.
+ * @ts_offset: Hw timestamp offset.
+ * @hw_ts: Latest hw timestamp from the sensor.
+ * @ts: Latest timestamp from irq handler.
+ * @delta_ts: Delta time between two consecutive interrupts.
+ * @iio_devs: Pointers to acc/gyro iio_dev instances.
+ * @tf: Transfer function structure used by I/O operations.
+ * @tb: Transfer buffers used by SPI I/O operations.
+ */
+struct st_asm330lhh_hw {
+ struct device *dev;
+ int irq;
+
+ struct mutex lock;
+ struct mutex fifo_lock;
+
+ enum st_asm330lhh_fifo_mode fifo_mode;
+ unsigned long state;
+ u8 enable_mask;
+
+ s64 ts_offset;
+ s64 hw_ts;
+ s64 delta_ts;
+ s64 ts;
+ s64 tsample;
+ s64 hw_ts_old;
+ s64 delta_hw_ts;
+
+ /* Timestamp sample ODR */
+ u16 odr;
+
+ struct iio_dev *iio_devs[ST_ASM330LHH_ID_MAX];
+
+ const struct st_asm330lhh_transfer_function *tf;
+ struct st_asm330lhh_transfer_buffer tb;
+};
+
+extern const struct dev_pm_ops st_asm330lhh_pm_ops;
+
+int st_asm330lhh_probe(struct device *dev, int irq,
+ const struct st_asm330lhh_transfer_function *tf_ops);
+int st_asm330lhh_sensor_set_enable(struct st_asm330lhh_sensor *sensor,
+ bool enable);
+int st_asm330lhh_fifo_setup(struct st_asm330lhh_hw *hw);
+int st_asm330lhh_write_with_mask(struct st_asm330lhh_hw *hw, u8 addr, u8 mask,
+ u8 val);
+int st_asm330lhh_get_odr_val(enum st_asm330lhh_sensor_id id, u16 odr, u8 *val);
+ssize_t st_asm330lhh_flush_fifo(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size);
+ssize_t st_asm330lhh_get_max_watermark(struct device *dev,
+ struct device_attribute *attr, char *buf);
+ssize_t st_asm330lhh_get_watermark(struct device *dev,
+ struct device_attribute *attr, char *buf);
+ssize_t st_asm330lhh_set_watermark(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size);
+int st_asm330lhh_set_fifo_mode(struct st_asm330lhh_hw *hw,
+ enum st_asm330lhh_fifo_mode fifo_mode);
+int st_asm330lhh_suspend_fifo(struct st_asm330lhh_hw *hw);
+#endif /* ST_ASM330LHH_H */
diff --git a/drivers/iio/imu/st_asm330lhh/st_asm330lhh_buffer.c b/drivers/iio/imu/st_asm330lhh/st_asm330lhh_buffer.c
new file mode 100644
index 0000000..af8c5ba
--- /dev/null
+++ b/drivers/iio/imu/st_asm330lhh/st_asm330lhh_buffer.c
@@ -0,0 +1,531 @@
+/*
+ * STMicroelectronics st_asm330lhh FIFO buffer library driver
+ *
+ * Copyright 2018 STMicroelectronics Inc.
+ *
+ * Lorenzo Bianconi <lorenzo.bianconi@st.com>
+ *
+ * Licensed under the GPL-2.
+ */
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/iio/kfifo_buf.h>
+#include <linux/iio/events.h>
+#include <asm/unaligned.h>
+#include <linux/of.h>
+
+#include "st_asm330lhh.h"
+
+#define ST_ASM330LHH_REG_FIFO_THL_ADDR 0x07
+#define ST_ASM330LHH_REG_FIFO_LEN_MASK GENMASK(8, 0)
+#define ST_ASM330LHH_REG_FIFO_MODE_MASK GENMASK(2, 0)
+#define ST_ASM330LHH_REG_DEC_TS_MASK GENMASK(7, 6)
+#define ST_ASM330LHH_REG_HLACTIVE_ADDR 0x12
+#define ST_ASM330LHH_REG_HLACTIVE_MASK BIT(5)
+#define ST_ASM330LHH_REG_PP_OD_ADDR 0x12
+#define ST_ASM330LHH_REG_PP_OD_MASK BIT(4)
+#define ST_ASM330LHH_REG_FIFO_DIFFL_ADDR 0x3a
+#define ST_ASM330LHH_REG_TS0_ADDR 0x40
+#define ST_ASM330LHH_REG_TS2_ADDR 0x42
+#define ST_ASM330LHH_REG_FIFO_OUT_TAG_ADDR 0x78
+#define ST_ASM330LHH_GYRO_TAG 0x01
+#define ST_ASM330LHH_ACC_TAG 0x02
+#define ST_ASM330LHH_TS_TAG 0x04
+
+#define ST_ASM330LHH_TS_DELTA_NS 25000ULL /* 25us/LSB */
+
+static inline s64 st_asm330lhh_get_time_ns(void)
+{
+ struct timespec ts;
+
+ get_monotonic_boottime(&ts);
+ return timespec_to_ns(&ts);
+}
+
+#define ST_ASM330LHH_EWMA_LEVEL 120
+#define ST_ASM330LHH_EWMA_DIV 128
+static inline s64 st_asm330lhh_ewma(s64 old, s64 new, int weight)
+{
+ s64 diff, incr;
+
+ diff = new - old;
+ incr = div_s64((ST_ASM330LHH_EWMA_DIV - weight) * diff,
+ ST_ASM330LHH_EWMA_DIV);
+
+ return old + incr;
+}
+
+static inline int st_asm330lhh_reset_hwts(struct st_asm330lhh_hw *hw)
+{
+ u8 data = 0xaa;
+
+ hw->ts = st_asm330lhh_get_time_ns();
+ hw->ts_offset = hw->ts;
+ hw->hw_ts_old = 0ull;
+ hw->tsample = 0ull;
+
+ return hw->tf->write(hw->dev, ST_ASM330LHH_REG_TS2_ADDR, sizeof(data),
+ &data);
+}
+
+int st_asm330lhh_set_fifo_mode(struct st_asm330lhh_hw *hw,
+ enum st_asm330lhh_fifo_mode fifo_mode)
+{
+ int err;
+
+ err = st_asm330lhh_write_with_mask(hw, ST_ASM330LHH_REG_FIFO_CTRL4_ADDR,
+ ST_ASM330LHH_REG_FIFO_MODE_MASK,
+ fifo_mode);
+ if (err < 0)
+ return err;
+
+ hw->fifo_mode = fifo_mode;
+
+ return 0;
+}
+
+static int st_asm330lhh_set_sensor_batching_odr(struct st_asm330lhh_sensor *sensor,
+ bool enable)
+{
+ struct st_asm330lhh_hw *hw = sensor->hw;
+ u8 data = 0;
+ int err;
+
+ if (enable) {
+ err = st_asm330lhh_get_odr_val(sensor->id, sensor->odr, &data);
+ if (err < 0)
+ return err;
+ }
+
+ return st_asm330lhh_write_with_mask(hw,
+ sensor->batch_addr,
+ sensor->batch_mask, data);
+}
+
+static u16 st_asm330lhh_ts_odr(struct st_asm330lhh_hw *hw)
+{
+ struct st_asm330lhh_sensor *sensor;
+ u16 odr = 0;
+ u8 i;
+
+ for (i = 0; i < ST_ASM330LHH_ID_MAX; i++) {
+ if (!hw->iio_devs[i])
+ continue;
+
+ sensor = iio_priv(hw->iio_devs[i]);
+ if (hw->enable_mask & BIT(sensor->id))
+ odr = max_t(u16, odr, sensor->odr);
+ }
+
+ return odr;
+}
+
+static int st_asm330lhh_update_watermark(struct st_asm330lhh_sensor *sensor,
+ u16 watermark)
+{
+ u16 fifo_watermark = ST_ASM330LHH_MAX_FIFO_DEPTH, cur_watermark = 0;
+ struct st_asm330lhh_hw *hw = sensor->hw;
+ struct st_asm330lhh_sensor *cur_sensor;
+ __le16 wdata;
+ int i, err;
+ u8 data;
+
+ for (i = 0; i < ST_ASM330LHH_ID_MAX; i++) {
+ cur_sensor = iio_priv(hw->iio_devs[i]);
+
+ if (!(hw->enable_mask & BIT(cur_sensor->id)))
+ continue;
+
+ cur_watermark = (cur_sensor == sensor) ? watermark
+ : cur_sensor->watermark;
+
+ fifo_watermark = min_t(u16, fifo_watermark, cur_watermark);
+ }
+
+ fifo_watermark = max_t(u16, fifo_watermark, 2);
+ mutex_lock(&hw->lock);
+
+ err = hw->tf->read(hw->dev, ST_ASM330LHH_REG_FIFO_THL_ADDR + 1,
+ sizeof(data), &data);
+ if (err < 0)
+ goto out;
+
+ fifo_watermark = ((data << 8) & ~ST_ASM330LHH_REG_FIFO_LEN_MASK) |
+ (fifo_watermark & ST_ASM330LHH_REG_FIFO_LEN_MASK);
+ wdata = cpu_to_le16(fifo_watermark);
+ err = hw->tf->write(hw->dev, ST_ASM330LHH_REG_FIFO_THL_ADDR,
+ sizeof(wdata), (u8 *)&wdata);
+
+out:
+ mutex_unlock(&hw->lock);
+
+ return err < 0 ? err : 0;
+}
+
+static inline void st_asm330lhh_sync_hw_ts(struct st_asm330lhh_hw *hw, s64 ts)
+{
+ s64 delta = ts - hw->hw_ts;
+
+ hw->ts_offset = st_asm330lhh_ewma(hw->ts_offset, delta,
+ ST_ASM330LHH_EWMA_LEVEL);
+}
+
+static struct iio_dev *st_asm330lhh_get_iiodev_from_tag(struct st_asm330lhh_hw *hw,
+ u8 tag)
+{
+ struct iio_dev *iio_dev;
+
+ switch (tag) {
+ case ST_ASM330LHH_GYRO_TAG:
+ iio_dev = hw->iio_devs[ST_ASM330LHH_ID_GYRO];
+ break;
+ case ST_ASM330LHH_ACC_TAG:
+ iio_dev = hw->iio_devs[ST_ASM330LHH_ID_ACC];
+ break;
+ default:
+ iio_dev = NULL;
+ break;
+ }
+
+ return iio_dev;
+}
+
+static int st_asm330lhh_read_fifo(struct st_asm330lhh_hw *hw)
+{
+ u8 iio_buf[ALIGN(ST_ASM330LHH_SAMPLE_SIZE, sizeof(s64)) + sizeof(s64)];
+ u8 buf[6 * ST_ASM330LHH_FIFO_SAMPLE_SIZE], tag, *ptr;
+ s64 ts_delta_hw_ts = 0, ts_irq;
+ s64 ts_delta_offs;
+ int i, err, read_len, word_len, fifo_len;
+ struct st_asm330lhh_sensor *sensor;
+ struct iio_dev *iio_dev;
+ __le16 fifo_status;
+ u16 fifo_depth;
+ u32 val;
+ int ts_processed = 0;
+ s64 hw_ts = 0ull, delta_hw_ts, cpu_timestamp;
+
+ ts_irq = hw->ts - hw->delta_ts;
+
+ do
+ {
+ err = hw->tf->read(hw->dev, ST_ASM330LHH_REG_FIFO_DIFFL_ADDR,
+ sizeof(fifo_status), (u8 *)&fifo_status);
+ if (err < 0)
+ return err;
+
+ fifo_depth = le16_to_cpu(fifo_status) & ST_ASM330LHH_REG_FIFO_LEN_MASK;
+ if (!fifo_depth)
+ return 0;
+
+ read_len = 0;
+ fifo_len = fifo_depth * ST_ASM330LHH_FIFO_SAMPLE_SIZE;
+ while (read_len < fifo_len) {
+ word_len = min_t(int, fifo_len - read_len, sizeof(buf));
+ err = hw->tf->read(hw->dev,
+ ST_ASM330LHH_REG_FIFO_OUT_TAG_ADDR,
+ word_len, buf);
+ if (err < 0)
+ return err;
+
+ for (i = 0; i < word_len; i += ST_ASM330LHH_FIFO_SAMPLE_SIZE) {
+ ptr = &buf[i + ST_ASM330LHH_TAG_SIZE];
+ tag = buf[i] >> 3;
+
+ if (tag == ST_ASM330LHH_TS_TAG) {
+ val = get_unaligned_le32(ptr);
+ hw->hw_ts = val * ST_ASM330LHH_TS_DELTA_NS;
+ ts_delta_hw_ts = hw->hw_ts - hw->hw_ts_old;
+ hw_ts += ts_delta_hw_ts;
+ ts_delta_offs =
+ div_s64(hw->delta_hw_ts * ST_ASM330LHH_MAX_ODR, hw->odr);
+
+ hw->ts_offset = st_asm330lhh_ewma(hw->ts_offset, ts_irq -
+ hw->hw_ts + ts_delta_offs, ST_ASM330LHH_EWMA_LEVEL);
+
+ ts_irq += (hw->hw_ts + ts_delta_offs);
+ hw->hw_ts_old = hw->hw_ts;
+ ts_processed++;
+
+ if (!hw->tsample)
+ hw->tsample =
+ hw->ts_offset + (hw->hw_ts + ts_delta_offs);
+ else
+ hw->tsample =
+ hw->tsample + (ts_delta_hw_ts + ts_delta_offs);
+ } else {
+ iio_dev = st_asm330lhh_get_iiodev_from_tag(hw, tag);
+ if (!iio_dev)
+ continue;
+
+ sensor = iio_priv(iio_dev);
+ if (sensor->std_samples < sensor->std_level) {
+ sensor->std_samples++;
+ continue;
+ }
+
+ sensor = iio_priv(iio_dev);
+
+ /* Check if timestamp is in the future. */
+ cpu_timestamp = st_asm330lhh_get_time_ns();
+
+ /* Avoid samples in the future. */
+ if (hw->tsample > cpu_timestamp)
+ hw->tsample = cpu_timestamp;
+
+ memcpy(iio_buf, ptr, ST_ASM330LHH_SAMPLE_SIZE);
+ iio_push_to_buffers_with_timestamp(iio_dev,
+ iio_buf,
+ hw->tsample);
+ }
+ }
+ read_len += word_len;
+ }
+
+ delta_hw_ts = div_s64(hw->delta_ts - hw_ts, ts_processed);
+ delta_hw_ts = div_s64(delta_hw_ts * hw->odr, ST_ASM330LHH_MAX_ODR);
+ hw->delta_hw_ts = st_asm330lhh_ewma(hw->delta_hw_ts,
+ delta_hw_ts,
+ ST_ASM330LHH_EWMA_LEVEL);
+ } while(read_len);
+
+ return read_len;
+}
+
+ssize_t st_asm330lhh_get_max_watermark(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", ST_ASM330LHH_MAX_FIFO_DEPTH);
+}
+
+ssize_t st_asm330lhh_get_watermark(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct iio_dev *iio_dev = dev_get_drvdata(dev);
+ struct st_asm330lhh_sensor *sensor = iio_priv(iio_dev);
+
+ return sprintf(buf, "%d\n", sensor->watermark);
+}
+
+ssize_t st_asm330lhh_set_watermark(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct iio_dev *iio_dev = dev_get_drvdata(dev);
+ struct st_asm330lhh_sensor *sensor = iio_priv(iio_dev);
+ int err, val;
+
+ mutex_lock(&iio_dev->mlock);
+ if (iio_buffer_enabled(iio_dev)) {
+ err = -EBUSY;
+ goto out;
+ }
+
+ err = kstrtoint(buf, 10, &val);
+ if (err < 0)
+ goto out;
+
+ err = st_asm330lhh_update_watermark(sensor, val);
+ if (err < 0)
+ goto out;
+
+ sensor->watermark = val;
+
+out:
+ mutex_unlock(&iio_dev->mlock);
+
+ return err < 0 ? err : size;
+}
+
+ssize_t st_asm330lhh_flush_fifo(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct iio_dev *iio_dev = dev_get_drvdata(dev);
+ struct st_asm330lhh_sensor *sensor = iio_priv(iio_dev);
+ struct st_asm330lhh_hw *hw = sensor->hw;
+ s64 type, event;
+ int count;
+ s64 ts;
+
+ mutex_lock(&hw->fifo_lock);
+ ts = st_asm330lhh_get_time_ns();
+ hw->delta_ts = ts - hw->ts;
+ hw->ts = ts;
+ set_bit(ST_ASM330LHH_HW_FLUSH, &hw->state);
+
+ count = st_asm330lhh_read_fifo(hw);
+
+ mutex_unlock(&hw->fifo_lock);
+
+ type = count > 0 ? CUSTOM_IIO_EV_DIR_FIFO_DATA : CUSTOM_IIO_EV_DIR_FIFO_EMPTY;
+ event = IIO_UNMOD_EVENT_CODE(iio_dev->channels[0].type, -1,
+ CUSTOM_IIO_EV_TYPE_FIFO_FLUSH, type);
+ iio_push_event(iio_dev, event, st_asm330lhh_get_time_ns());
+
+ return size;
+}
+
+int st_asm330lhh_suspend_fifo(struct st_asm330lhh_hw *hw)
+{
+ int err;
+
+ mutex_lock(&hw->fifo_lock);
+
+ st_asm330lhh_read_fifo(hw);
+ err = st_asm330lhh_set_fifo_mode(hw, ST_ASM330LHH_FIFO_BYPASS);
+
+ mutex_unlock(&hw->fifo_lock);
+
+ return err;
+}
+
+static int st_asm330lhh_update_fifo(struct iio_dev *iio_dev, bool enable)
+{
+ struct st_asm330lhh_sensor *sensor = iio_priv(iio_dev);
+ struct st_asm330lhh_hw *hw = sensor->hw;
+ int err;
+
+ mutex_lock(&hw->fifo_lock);
+
+ err = st_asm330lhh_sensor_set_enable(sensor, enable);
+ if (err < 0)
+ goto out;
+
+ err = st_asm330lhh_set_sensor_batching_odr(sensor, enable);
+ if (err < 0)
+ goto out;
+
+ err = st_asm330lhh_update_watermark(sensor, sensor->watermark);
+ if (err < 0)
+ goto out;
+
+ hw->odr = st_asm330lhh_ts_odr(hw);
+
+ if (enable && hw->fifo_mode == ST_ASM330LHH_FIFO_BYPASS) {
+ st_asm330lhh_reset_hwts(hw);
+ err = st_asm330lhh_set_fifo_mode(hw, ST_ASM330LHH_FIFO_CONT);
+ } else if (!hw->enable_mask) {
+ err = st_asm330lhh_set_fifo_mode(hw, ST_ASM330LHH_FIFO_BYPASS);
+ }
+
+out:
+ mutex_unlock(&hw->fifo_lock);
+
+ return err;
+}
+
+static irqreturn_t st_asm330lhh_handler_irq(int irq, void *private)
+{
+ struct st_asm330lhh_hw *hw = (struct st_asm330lhh_hw *)private;
+ s64 ts = st_asm330lhh_get_time_ns();
+
+ hw->delta_ts = ts - hw->ts;
+ hw->ts = ts;
+
+ return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t st_asm330lhh_handler_thread(int irq, void *private)
+{
+ struct st_asm330lhh_hw *hw = (struct st_asm330lhh_hw *)private;
+
+ mutex_lock(&hw->fifo_lock);
+
+ st_asm330lhh_read_fifo(hw);
+ clear_bit(ST_ASM330LHH_HW_FLUSH, &hw->state);
+
+ mutex_unlock(&hw->fifo_lock);
+
+ return IRQ_HANDLED;
+}
+
+static int st_asm330lhh_buffer_preenable(struct iio_dev *iio_dev)
+{
+ return st_asm330lhh_update_fifo(iio_dev, true);
+}
+
+static int st_asm330lhh_buffer_postdisable(struct iio_dev *iio_dev)
+{
+ return st_asm330lhh_update_fifo(iio_dev, false);
+}
+
+static const struct iio_buffer_setup_ops st_asm330lhh_buffer_ops = {
+ .preenable = st_asm330lhh_buffer_preenable,
+ .postdisable = st_asm330lhh_buffer_postdisable,
+};
+
+static int st_asm330lhh_fifo_init(struct st_asm330lhh_hw *hw)
+{
+ return st_asm330lhh_write_with_mask(hw, ST_ASM330LHH_REG_FIFO_CTRL4_ADDR,
+ ST_ASM330LHH_REG_DEC_TS_MASK, 1);
+}
+
+int st_asm330lhh_fifo_setup(struct st_asm330lhh_hw *hw)
+{
+ struct device_node *np = hw->dev->of_node;
+ struct iio_buffer *buffer;
+ unsigned long irq_type;
+ bool irq_active_low;
+ int i, err;
+
+ irq_type = irqd_get_trigger_type(irq_get_irq_data(hw->irq));
+
+ switch (irq_type) {
+ case IRQF_TRIGGER_HIGH:
+ case IRQF_TRIGGER_RISING:
+ irq_active_low = false;
+ break;
+ case IRQF_TRIGGER_LOW:
+ case IRQF_TRIGGER_FALLING:
+ irq_active_low = true;
+ break;
+ default:
+ dev_info(hw->dev, "mode %lx unsupported\n", irq_type);
+ return -EINVAL;
+ }
+
+ err = st_asm330lhh_write_with_mask(hw, ST_ASM330LHH_REG_HLACTIVE_ADDR,
+ ST_ASM330LHH_REG_HLACTIVE_MASK,
+ irq_active_low);
+ if (err < 0)
+ return err;
+
+ if (np && of_property_read_bool(np, "drive-open-drain")) {
+ err = st_asm330lhh_write_with_mask(hw,
+ ST_ASM330LHH_REG_PP_OD_ADDR,
+ ST_ASM330LHH_REG_PP_OD_MASK, 1);
+ if (err < 0)
+ return err;
+
+ irq_type |= IRQF_SHARED;
+ }
+
+ err = devm_request_threaded_irq(hw->dev, hw->irq,
+ st_asm330lhh_handler_irq,
+ st_asm330lhh_handler_thread,
+ irq_type | IRQF_ONESHOT,
+ "asm330lhh", hw);
+ if (err) {
+ dev_err(hw->dev, "failed to request trigger irq %d\n",
+ hw->irq);
+ return err;
+ }
+
+ for (i = ST_ASM330LHH_ID_ACC; i < ST_ASM330LHH_ID_MAX; i++) {
+ if (!hw->iio_devs[i])
+ continue;
+
+ buffer = devm_iio_kfifo_allocate(hw->dev);
+ if (!buffer)
+ return -ENOMEM;
+
+ iio_device_attach_buffer(hw->iio_devs[i], buffer);
+ hw->iio_devs[i]->modes |= INDIO_BUFFER_SOFTWARE;
+ hw->iio_devs[i]->setup_ops = &st_asm330lhh_buffer_ops;
+ }
+
+ return st_asm330lhh_fifo_init(hw);
+}
+
diff --git a/drivers/iio/imu/st_asm330lhh/st_asm330lhh_core.c b/drivers/iio/imu/st_asm330lhh/st_asm330lhh_core.c
new file mode 100644
index 0000000..9d9ee20
--- /dev/null
+++ b/drivers/iio/imu/st_asm330lhh/st_asm330lhh_core.c
@@ -0,0 +1,824 @@
+/*
+ * STMicroelectronics st_asm330lhh sensor driver
+ *
+ * Copyright 2018 STMicroelectronics Inc.
+ *
+ * Lorenzo Bianconi <lorenzo.bianconi@st.com>
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/pm.h>
+#include <linux/version.h>
+#include <linux/of.h>
+
+#include <linux/platform_data/st_sensors_pdata.h>
+
+#include "st_asm330lhh.h"
+
+#define ST_ASM330LHH_REG_INT1_ADDR 0x0d
+#define ST_ASM330LHH_REG_INT2_ADDR 0x0e
+#define ST_ASM330LHH_REG_FIFO_CTRL4_ADDR 0x0a
+#define ST_ASM330LHH_REG_FIFO_FTH_IRQ_MASK BIT(3)
+#define ST_ASM330LHH_REG_WHOAMI_ADDR 0x0f
+#define ST_ASM330LHH_WHOAMI_VAL 0x6b
+#define ST_ASM330LHH_REG_CTRL1_XL_ADDR 0x10
+#define ST_ASM330LHH_REG_CTRL2_G_ADDR 0x11
+#define ST_ASM330LHH_REG_RESET_ADDR 0x12
+#define ST_ASM330LHH_REG_RESET_MASK BIT(0)
+#define ST_ASM330LHH_REG_BDU_ADDR 0x12
+#define ST_ASM330LHH_REG_BDU_MASK BIT(6)
+#define ST_ASM330LHH_REG_INT2_ON_INT1_ADDR 0x13
+#define ST_ASM330LHH_REG_INT2_ON_INT1_MASK BIT(5)
+#define ST_ASM330LHH_REG_ROUNDING_ADDR 0x14
+#define ST_ASM330LHH_REG_ROUNDING_MASK GENMASK(6, 5)
+#define ST_ASM330LHH_REG_TIMESTAMP_EN_ADDR 0x19
+#define ST_ASM330LHH_REG_TIMESTAMP_EN_MASK BIT(5)
+
+#define ST_ASM330LHH_REG_GYRO_OUT_X_L_ADDR 0x22
+#define ST_ASM330LHH_REG_GYRO_OUT_Y_L_ADDR 0x24
+#define ST_ASM330LHH_REG_GYRO_OUT_Z_L_ADDR 0x26
+
+#define ST_ASM330LHH_REG_ACC_OUT_X_L_ADDR 0x28
+#define ST_ASM330LHH_REG_ACC_OUT_Y_L_ADDR 0x2a
+#define ST_ASM330LHH_REG_ACC_OUT_Z_L_ADDR 0x2c
+
+#define ST_ASM330LHH_REG_LIR_ADDR 0x56
+#define ST_ASM330LHH_REG_LIR_MASK BIT(0)
+
+#define ST_ASM330LHH_ACC_FS_2G_GAIN IIO_G_TO_M_S_2(61)
+#define ST_ASM330LHH_ACC_FS_4G_GAIN IIO_G_TO_M_S_2(122)
+#define ST_ASM330LHH_ACC_FS_8G_GAIN IIO_G_TO_M_S_2(244)
+#define ST_ASM330LHH_ACC_FS_16G_GAIN IIO_G_TO_M_S_2(488)
+
+#define ST_ASM330LHH_GYRO_FS_125_GAIN IIO_DEGREE_TO_RAD(4375)
+#define ST_ASM330LHH_GYRO_FS_250_GAIN IIO_DEGREE_TO_RAD(8750)
+#define ST_ASM330LHH_GYRO_FS_500_GAIN IIO_DEGREE_TO_RAD(17500)
+#define ST_ASM330LHH_GYRO_FS_1000_GAIN IIO_DEGREE_TO_RAD(35000)
+#define ST_ASM330LHH_GYRO_FS_2000_GAIN IIO_DEGREE_TO_RAD(70000)
+#define ST_ASM330LHH_GYRO_FS_4000_GAIN IIO_DEGREE_TO_RAD(140000)
+
+/* Temperature in uC */
+#define ST_ASM330LHH_TEMP_GAIN 256
+#define ST_ASM330LHH_TEMP_FS_GAIN (1000000 / ST_ASM330LHH_TEMP_GAIN)
+#define ST_ASM330LHH_OFFSET (6400)
+
+struct st_asm330lhh_std_entry {
+ u16 odr;
+ u8 val;
+};
+
+/* Minimal number of sample to be discarded */
+struct st_asm330lhh_std_entry st_asm330lhh_std_table[] = {
+ { 13, 2 },
+ { 26, 3 },
+ { 52, 4 },
+ { 104, 6 },
+ { 208, 8 },
+ { 416, 18 },
+};
+
+static const struct st_asm330lhh_odr_table_entry st_asm330lhh_odr_table[] = {
+ [ST_ASM330LHH_ID_ACC] = {
+ .reg = {
+ .addr = ST_ASM330LHH_REG_CTRL1_XL_ADDR,
+ .mask = GENMASK(7, 4),
+ },
+ .odr_avl[0] = { 0, 0x00 },
+ .odr_avl[1] = { 13, 0x01 },
+ .odr_avl[2] = { 26, 0x02 },
+ .odr_avl[3] = { 52, 0x03 },
+ .odr_avl[4] = { 104, 0x04 },
+ .odr_avl[5] = { 208, 0x05 },
+ .odr_avl[6] = { 416, 0x06 },
+ },
+ [ST_ASM330LHH_ID_GYRO] = {
+ .reg = {
+ .addr = ST_ASM330LHH_REG_CTRL2_G_ADDR,
+ .mask = GENMASK(7, 4),
+ },
+ .odr_avl[0] = { 0, 0x00 },
+ .odr_avl[1] = { 13, 0x01 },
+ .odr_avl[2] = { 26, 0x02 },
+ .odr_avl[3] = { 52, 0x03 },
+ .odr_avl[4] = { 104, 0x04 },
+ .odr_avl[5] = { 208, 0x05 },
+ .odr_avl[6] = { 416, 0x06 },
+ },
+ [ST_ASM330LHH_ID_TEMP] = {
+ .odr_avl[0] = { 0, 0x00 },
+ .odr_avl[1] = { 52, 0x01 },
+ }
+};
+
+static const struct st_asm330lhh_fs_table_entry st_asm330lhh_fs_table[] = {
+ [ST_ASM330LHH_ID_ACC] = {
+ .reg = {
+ .addr = ST_ASM330LHH_REG_CTRL1_XL_ADDR,
+ .mask = GENMASK(3, 2),
+ },
+ .size = ST_ASM330LHH_FS_ACC_LIST_SIZE,
+ .fs_avl[0] = { ST_ASM330LHH_ACC_FS_2G_GAIN, 0x0 },
+ .fs_avl[1] = { ST_ASM330LHH_ACC_FS_4G_GAIN, 0x2 },
+ .fs_avl[2] = { ST_ASM330LHH_ACC_FS_8G_GAIN, 0x3 },
+ .fs_avl[3] = { ST_ASM330LHH_ACC_FS_16G_GAIN, 0x1 },
+ },
+ [ST_ASM330LHH_ID_GYRO] = {
+ .reg = {
+ .addr = ST_ASM330LHH_REG_CTRL2_G_ADDR,
+ .mask = GENMASK(3, 0),
+ },
+ .size = ST_ASM330LHH_FS_GYRO_LIST_SIZE,
+ .fs_avl[0] = { ST_ASM330LHH_GYRO_FS_125_GAIN, 0x2 },
+ .fs_avl[1] = { ST_ASM330LHH_GYRO_FS_250_GAIN, 0x0 },
+ .fs_avl[2] = { ST_ASM330LHH_GYRO_FS_500_GAIN, 0x4 },
+ .fs_avl[3] = { ST_ASM330LHH_GYRO_FS_1000_GAIN, 0x8 },
+ .fs_avl[4] = { ST_ASM330LHH_GYRO_FS_2000_GAIN, 0xC },
+ .fs_avl[5] = { ST_ASM330LHH_GYRO_FS_4000_GAIN, 0x1 },
+ },
+ [ST_ASM330LHH_ID_TEMP] = {
+ .size = ST_ASM330LHH_FS_TEMP_LIST_SIZE,
+ .fs_avl[0] = { ST_ASM330LHH_TEMP_FS_GAIN, 0x0 },
+ }
+};
+
+static const struct iio_chan_spec st_asm330lhh_acc_channels[] = {
+ ST_ASM330LHH_CHANNEL(IIO_ACCEL, ST_ASM330LHH_REG_ACC_OUT_X_L_ADDR,
+ 1, IIO_MOD_X, 0, 16, 16, 's'),
+ ST_ASM330LHH_CHANNEL(IIO_ACCEL, ST_ASM330LHH_REG_ACC_OUT_Y_L_ADDR,
+ 1, IIO_MOD_Y, 1, 16, 16, 's'),
+ ST_ASM330LHH_CHANNEL(IIO_ACCEL, ST_ASM330LHH_REG_ACC_OUT_Z_L_ADDR,
+ 1, IIO_MOD_Z, 2, 16, 16, 's'),
+ ST_ASM330LHH_FLUSH_CHANNEL(IIO_ACCEL),
+ IIO_CHAN_SOFT_TIMESTAMP(3),
+};
+
+static const struct iio_chan_spec st_asm330lhh_gyro_channels[] = {
+ ST_ASM330LHH_CHANNEL(IIO_ANGL_VEL, ST_ASM330LHH_REG_GYRO_OUT_X_L_ADDR,
+ 1, IIO_MOD_X, 0, 16, 16, 's'),
+ ST_ASM330LHH_CHANNEL(IIO_ANGL_VEL, ST_ASM330LHH_REG_GYRO_OUT_Y_L_ADDR,
+ 1, IIO_MOD_Y, 1, 16, 16, 's'),
+ ST_ASM330LHH_CHANNEL(IIO_ANGL_VEL, ST_ASM330LHH_REG_GYRO_OUT_Z_L_ADDR,
+ 1, IIO_MOD_Z, 2, 16, 16, 's'),
+ ST_ASM330LHH_FLUSH_CHANNEL(IIO_ANGL_VEL),
+ IIO_CHAN_SOFT_TIMESTAMP(3),
+};
+
+static const struct iio_chan_spec st_asm330lhh_temp_channels[] = {
+ {
+ .type = IIO_TEMP,
+ .address = ST_ASM330LHH_REG_OUT_TEMP_L_ADDR,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW)
+ | BIT(IIO_CHAN_INFO_OFFSET)
+ | BIT(IIO_CHAN_INFO_SCALE),
+ .scan_index = -1,
+ },
+};
+
+int st_asm330lhh_write_with_mask(struct st_asm330lhh_hw *hw, u8 addr, u8 mask,
+ u8 val)
+{
+ u8 data;
+ int err;
+
+ mutex_lock(&hw->lock);
+
+ err = hw->tf->read(hw->dev, addr, sizeof(data), &data);
+ if (err < 0) {
+ dev_err(hw->dev, "failed to read %02x register\n", addr);
+ goto out;
+ }
+
+ data = (data & ~mask) | ((val << __ffs(mask)) & mask);
+
+ err = hw->tf->write(hw->dev, addr, sizeof(data), &data);
+ if (err < 0)
+ dev_err(hw->dev, "failed to write %02x register\n", addr);
+
+out:
+ mutex_unlock(&hw->lock);
+
+ return err;
+}
+
+static int st_asm330lhh_check_whoami(struct st_asm330lhh_hw *hw)
+{
+ int err;
+ u8 data;
+
+ err = hw->tf->read(hw->dev, ST_ASM330LHH_REG_WHOAMI_ADDR, sizeof(data),
+ &data);
+ if (err < 0) {
+ dev_err(hw->dev, "failed to read whoami register\n");
+ return err;
+ }
+
+ if (data != ST_ASM330LHH_WHOAMI_VAL) {
+ dev_err(hw->dev, "unsupported whoami [%02x]\n", data);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int st_asm330lhh_set_full_scale(struct st_asm330lhh_sensor *sensor,
+ u32 gain)
+{
+ enum st_asm330lhh_sensor_id id = sensor->id;
+ int i, err;
+ u8 val;
+
+ for (i = 0; i < st_asm330lhh_fs_table[id].size; i++)
+ if (st_asm330lhh_fs_table[id].fs_avl[i].gain == gain)
+ break;
+
+ if (i == st_asm330lhh_fs_table[id].size)
+ return -EINVAL;
+
+ val = st_asm330lhh_fs_table[id].fs_avl[i].val;
+ err = st_asm330lhh_write_with_mask(sensor->hw,
+ st_asm330lhh_fs_table[id].reg.addr,
+ st_asm330lhh_fs_table[id].reg.mask,
+ val);
+ if (err < 0)
+ return err;
+
+ sensor->gain = gain;
+
+ return 0;
+}
+
+int st_asm330lhh_get_odr_val(enum st_asm330lhh_sensor_id id, u16 odr, u8 *val)
+{
+ int i;
+
+ for (i = 0; i < ST_ASM330LHH_ODR_LIST_SIZE; i++)
+ if (st_asm330lhh_odr_table[id].odr_avl[i].hz >= odr)
+ break;
+
+ if (i == ST_ASM330LHH_ODR_LIST_SIZE)
+ return -EINVAL;
+
+ *val = st_asm330lhh_odr_table[id].odr_avl[i].val;
+
+ return 0;
+}
+
+static int st_asm330lhh_set_std_level(struct st_asm330lhh_sensor *sensor,
+ u16 odr)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(st_asm330lhh_std_table); i++)
+ if (st_asm330lhh_std_table[i].odr == odr)
+ break;
+
+ if (i == ARRAY_SIZE(st_asm330lhh_std_table))
+ return -EINVAL;
+
+ sensor->std_level = st_asm330lhh_std_table[i].val;
+ sensor->std_samples = 0;
+
+ return 0;
+}
+
+static int st_asm330lhh_set_odr(struct st_asm330lhh_sensor *sensor, u16 odr)
+{
+ struct st_asm330lhh_hw *hw = sensor->hw;
+ u8 val;
+
+ if (st_asm330lhh_get_odr_val(sensor->id, odr, &val) < 0)
+ return -EINVAL;
+
+ return st_asm330lhh_write_with_mask(hw,
+ st_asm330lhh_odr_table[sensor->id].reg.addr,
+ st_asm330lhh_odr_table[sensor->id].reg.mask, val);
+}
+
+int st_asm330lhh_sensor_set_enable(struct st_asm330lhh_sensor *sensor,
+ bool enable)
+{
+ u16 odr = enable ? sensor->odr : 0;
+ int err;
+
+ if (sensor->id != ST_ASM330LHH_ID_TEMP) {
+ err = st_asm330lhh_set_odr(sensor, odr);
+ if (err < 0)
+ return err;
+ }
+
+ if (enable)
+ sensor->hw->enable_mask |= BIT(sensor->id);
+ else
+ sensor->hw->enable_mask &= ~BIT(sensor->id);
+
+ return 0;
+}
+
+static int st_asm330lhh_read_oneshot(struct st_asm330lhh_sensor *sensor,
+ u8 addr, int *val)
+{
+ int err, delay;
+ __le16 data;
+
+ if (sensor->id == ST_ASM330LHH_ID_TEMP) {
+ u8 status;
+
+ mutex_lock(&sensor->hw->fifo_lock);
+ err = sensor->hw->tf->read(sensor->hw->dev,
+ ST_ASM330LHH_REG_STATUS_ADDR, sizeof(status), &status);
+ if (err < 0)
+ goto unlock;
+
+ if (status & ST_ASM330LHH_REG_STATUS_TDA) {
+ err = sensor->hw->tf->read(sensor->hw->dev, addr, sizeof(data),
+ (u8 *)&data);
+ if (err < 0)
+ goto unlock;
+
+ sensor->old_data = data;
+ } else
+ data = sensor->old_data;
+unlock:
+ mutex_unlock(&sensor->hw->fifo_lock);
+
+ } else {
+ err = st_asm330lhh_sensor_set_enable(sensor, true);
+ if (err < 0)
+ return err;
+
+ delay = 1000000 / sensor->odr;
+ usleep_range(delay, 2 * delay);
+
+ err = sensor->hw->tf->read(sensor->hw->dev, addr, sizeof(data),
+ (u8 *)&data);
+ if (err < 0)
+ return err;
+
+ st_asm330lhh_sensor_set_enable(sensor, false);
+ }
+
+ *val = (s16)data;
+
+ return IIO_VAL_INT;
+}
+
+static int st_asm330lhh_read_raw(struct iio_dev *iio_dev,
+ struct iio_chan_spec const *ch,
+ int *val, int *val2, long mask)
+{
+ struct st_asm330lhh_sensor *sensor = iio_priv(iio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ mutex_lock(&iio_dev->mlock);
+ if (iio_buffer_enabled(iio_dev)) {
+ ret = -EBUSY;
+ mutex_unlock(&iio_dev->mlock);
+ break;
+ }
+ ret = st_asm330lhh_read_oneshot(sensor, ch->address, val);
+ mutex_unlock(&iio_dev->mlock);
+ break;
+ case IIO_CHAN_INFO_OFFSET:
+ switch (ch->type) {
+ case IIO_TEMP:
+ *val = sensor->offset;
+ ret = IIO_VAL_INT;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ *val = sensor->odr;
+ ret = IIO_VAL_INT;
+ break;
+ case IIO_CHAN_INFO_SCALE:
+ switch (ch->type) {
+ case IIO_TEMP:
+ *val = 1;
+ *val2 = ST_ASM330LHH_TEMP_GAIN;
+ ret = IIO_VAL_FRACTIONAL;
+ break;
+ case IIO_ACCEL:
+ case IIO_ANGL_VEL:
+ *val = 0;
+ *val2 = sensor->gain;
+ ret = IIO_VAL_INT_PLUS_MICRO;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static int st_asm330lhh_write_raw(struct iio_dev *iio_dev,
+ struct iio_chan_spec const *chan,
+ int val, int val2, long mask)
+{
+ struct st_asm330lhh_sensor *sensor = iio_priv(iio_dev);
+ int err;
+
+ mutex_lock(&iio_dev->mlock);
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SCALE:
+ err = st_asm330lhh_set_full_scale(sensor, val2);
+ break;
+ case IIO_CHAN_INFO_SAMP_FREQ: {
+ u8 data;
+
+ err = st_asm330lhh_set_std_level(sensor, val);
+ if (err < 0)
+ break;
+
+ err = st_asm330lhh_get_odr_val(sensor->id, val, &data);
+ if (!err)
+ sensor->odr = val;
+
+ err = st_asm330lhh_set_odr(sensor, sensor->odr);
+ break;
+ }
+ default:
+ err = -EINVAL;
+ break;
+ }
+
+ mutex_unlock(&iio_dev->mlock);
+
+ return err;
+}
+
+static ssize_t
+st_asm330lhh_sysfs_sampling_frequency_avail(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct st_asm330lhh_sensor *sensor = iio_priv(dev_get_drvdata(dev));
+ enum st_asm330lhh_sensor_id id = sensor->id;
+ int i, len = 0;
+
+ for (i = 1; i < ST_ASM330LHH_ODR_LIST_SIZE; i++)
+ len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
+ st_asm330lhh_odr_table[id].odr_avl[i].hz);
+ buf[len - 1] = '\n';
+
+ return len;
+}
+
+static ssize_t st_asm330lhh_sysfs_scale_avail(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct st_asm330lhh_sensor *sensor = iio_priv(dev_get_drvdata(dev));
+ enum st_asm330lhh_sensor_id id = sensor->id;
+ int i, len = 0;
+
+ for (i = 0; i < st_asm330lhh_fs_table[id].size; i++)
+ len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ",
+ st_asm330lhh_fs_table[id].fs_avl[i].gain);
+ buf[len - 1] = '\n';
+
+ return len;
+}
+
+static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(st_asm330lhh_sysfs_sampling_frequency_avail);
+static IIO_DEVICE_ATTR(in_accel_scale_available, 0444,
+ st_asm330lhh_sysfs_scale_avail, NULL, 0);
+static IIO_DEVICE_ATTR(in_anglvel_scale_available, 0444,
+ st_asm330lhh_sysfs_scale_avail, NULL, 0);
+static IIO_DEVICE_ATTR(in_temp_scale_available, 0444,
+ st_asm330lhh_sysfs_scale_avail, NULL, 0);
+static IIO_DEVICE_ATTR(hwfifo_watermark_max, 0444,
+ st_asm330lhh_get_max_watermark, NULL, 0);
+static IIO_DEVICE_ATTR(hwfifo_flush, 0200, NULL, st_asm330lhh_flush_fifo, 0);
+static IIO_DEVICE_ATTR(hwfifo_watermark, 0644, st_asm330lhh_get_watermark,
+ st_asm330lhh_set_watermark, 0);
+
+static struct attribute *st_asm330lhh_acc_attributes[] = {
+ &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
+ &iio_dev_attr_in_accel_scale_available.dev_attr.attr,
+ &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr,
+ &iio_dev_attr_hwfifo_watermark.dev_attr.attr,
+ &iio_dev_attr_hwfifo_flush.dev_attr.attr,
+ NULL,
+};
+
+static const struct attribute_group st_asm330lhh_acc_attribute_group = {
+ .attrs = st_asm330lhh_acc_attributes,
+};
+
+static const struct iio_info st_asm330lhh_acc_info = {
+ .driver_module = THIS_MODULE,
+ .attrs = &st_asm330lhh_acc_attribute_group,
+ .read_raw = st_asm330lhh_read_raw,
+ .write_raw = st_asm330lhh_write_raw,
+};
+
+static struct attribute *st_asm330lhh_gyro_attributes[] = {
+ &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
+ &iio_dev_attr_in_anglvel_scale_available.dev_attr.attr,
+ &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr,
+ &iio_dev_attr_hwfifo_watermark.dev_attr.attr,
+ &iio_dev_attr_hwfifo_flush.dev_attr.attr,
+ NULL,
+};
+
+static const struct attribute_group st_asm330lhh_gyro_attribute_group = {
+ .attrs = st_asm330lhh_gyro_attributes,
+};
+
+static const struct iio_info st_asm330lhh_gyro_info = {
+ .driver_module = THIS_MODULE,
+ .attrs = &st_asm330lhh_gyro_attribute_group,
+ .read_raw = st_asm330lhh_read_raw,
+ .write_raw = st_asm330lhh_write_raw,
+};
+
+static struct attribute *st_asm330lhh_temp_attributes[] = {
+ &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
+ &iio_dev_attr_in_temp_scale_available.dev_attr.attr,
+ &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr,
+ &iio_dev_attr_hwfifo_watermark.dev_attr.attr,
+ &iio_dev_attr_hwfifo_flush.dev_attr.attr,
+ NULL,
+};
+
+static const struct attribute_group st_asm330lhh_temp_attribute_group = {
+ .attrs = st_asm330lhh_temp_attributes,
+};
+
+static const struct iio_info st_asm330lhh_temp_info = {
+ .driver_module = THIS_MODULE,
+ .attrs = &st_asm330lhh_temp_attribute_group,
+ .read_raw = st_asm330lhh_read_raw,
+ .write_raw = st_asm330lhh_write_raw,
+};
+
+static const unsigned long st_asm330lhh_available_scan_masks[] = { 0x7, 0x0 };
+
+static int st_asm330lhh_of_get_drdy_pin(struct st_asm330lhh_hw *hw, int *drdy_pin)
+{
+ struct device_node *np = hw->dev->of_node;
+
+ if (!np)
+ return -EINVAL;
+
+ return of_property_read_u32(np, "st,drdy-int-pin", drdy_pin);
+}
+
+static int st_asm330lhh_get_drdy_reg(struct st_asm330lhh_hw *hw, u8 *drdy_reg)
+{
+ int err = 0, drdy_pin;
+
+ if (st_asm330lhh_of_get_drdy_pin(hw, &drdy_pin) < 0) {
+ struct st_sensors_platform_data *pdata;
+ struct device *dev = hw->dev;
+
+ pdata = (struct st_sensors_platform_data *)dev->platform_data;
+ drdy_pin = pdata ? pdata->drdy_int_pin : 1;
+ }
+
+ switch (drdy_pin) {
+ case 1:
+ *drdy_reg = ST_ASM330LHH_REG_INT1_ADDR;
+ break;
+ case 2:
+ *drdy_reg = ST_ASM330LHH_REG_INT2_ADDR;
+ break;
+ default:
+ dev_err(hw->dev, "unsupported data ready pin\n");
+ err = -EINVAL;
+ break;
+ }
+
+ return err;
+}
+
+static int st_asm330lhh_init_device(struct st_asm330lhh_hw *hw)
+{
+ u8 drdy_int_reg;
+ int err;
+
+ err = st_asm330lhh_write_with_mask(hw, ST_ASM330LHH_REG_RESET_ADDR,
+ ST_ASM330LHH_REG_RESET_MASK, 1);
+ if (err < 0)
+ return err;
+
+ msleep(200);
+
+ /* latch interrupts */
+ err = st_asm330lhh_write_with_mask(hw, ST_ASM330LHH_REG_LIR_ADDR,
+ ST_ASM330LHH_REG_LIR_MASK, 1);
+ if (err < 0)
+ return err;
+
+ /* enable Block Data Update */
+ err = st_asm330lhh_write_with_mask(hw, ST_ASM330LHH_REG_BDU_ADDR,
+ ST_ASM330LHH_REG_BDU_MASK, 1);
+ if (err < 0)
+ return err;
+
+ err = st_asm330lhh_write_with_mask(hw, ST_ASM330LHH_REG_ROUNDING_ADDR,
+ ST_ASM330LHH_REG_ROUNDING_MASK, 3);
+ if (err < 0)
+ return err;
+
+ /* init timestamp engine */
+ err = st_asm330lhh_write_with_mask(hw, ST_ASM330LHH_REG_TIMESTAMP_EN_ADDR,
+ ST_ASM330LHH_REG_TIMESTAMP_EN_MASK, 1);
+ if (err < 0)
+ return err;
+
+ /* enable FIFO watermak interrupt */
+ err = st_asm330lhh_get_drdy_reg(hw, &drdy_int_reg);
+ if (err < 0)
+ return err;
+
+ return st_asm330lhh_write_with_mask(hw, drdy_int_reg,
+ ST_ASM330LHH_REG_FIFO_FTH_IRQ_MASK, 1);
+}
+
+static struct iio_dev *st_asm330lhh_alloc_iiodev(struct st_asm330lhh_hw *hw,
+ enum st_asm330lhh_sensor_id id)
+{
+ struct st_asm330lhh_sensor *sensor;
+ struct iio_dev *iio_dev;
+
+ iio_dev = devm_iio_device_alloc(hw->dev, sizeof(*sensor));
+ if (!iio_dev)
+ return NULL;
+
+ iio_dev->modes = INDIO_DIRECT_MODE;
+ iio_dev->dev.parent = hw->dev;
+ iio_dev->available_scan_masks = st_asm330lhh_available_scan_masks;
+
+ sensor = iio_priv(iio_dev);
+ sensor->id = id;
+ sensor->hw = hw;
+ sensor->odr = st_asm330lhh_odr_table[id].odr_avl[1].hz;
+ sensor->gain = st_asm330lhh_fs_table[id].fs_avl[0].gain;
+ sensor->watermark = 1;
+ sensor->old_data = 0;
+
+ switch (id) {
+ case ST_ASM330LHH_ID_ACC:
+ iio_dev->channels = st_asm330lhh_acc_channels;
+ iio_dev->num_channels = ARRAY_SIZE(st_asm330lhh_acc_channels);
+ iio_dev->name = "asm330lhh_accel";
+ iio_dev->info = &st_asm330lhh_acc_info;
+ sensor->batch_addr = ST_ASM330LHH_REG_FIFO_BATCH_ADDR;
+ sensor->batch_mask = GENMASK(3, 0);
+ sensor->offset = 0;
+ break;
+ case ST_ASM330LHH_ID_GYRO:
+ iio_dev->channels = st_asm330lhh_gyro_channels;
+ iio_dev->num_channels = ARRAY_SIZE(st_asm330lhh_gyro_channels);
+ iio_dev->name = "asm330lhh_gyro";
+ iio_dev->info = &st_asm330lhh_gyro_info;
+ sensor->batch_addr = ST_ASM330LHH_REG_FIFO_BATCH_ADDR;
+ sensor->batch_mask = GENMASK(7, 4);
+ sensor->offset = 0;
+ break;
+ case ST_ASM330LHH_ID_TEMP:
+ iio_dev->channels = st_asm330lhh_temp_channels;
+ iio_dev->num_channels = ARRAY_SIZE(st_asm330lhh_temp_channels);
+ iio_dev->name = "asm330lhh_temp";
+ iio_dev->info = &st_asm330lhh_temp_info;
+ sensor->offset = ST_ASM330LHH_OFFSET;
+ break;
+ default:
+ return NULL;
+ }
+
+ return iio_dev;
+}
+
+int st_asm330lhh_probe(struct device *dev, int irq,
+ const struct st_asm330lhh_transfer_function *tf_ops)
+{
+ struct st_asm330lhh_hw *hw;
+ int i, err;
+
+ hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
+ if (!hw)
+ return -ENOMEM;
+
+ dev_set_drvdata(dev, (void *)hw);
+
+ mutex_init(&hw->lock);
+ mutex_init(&hw->fifo_lock);
+
+ hw->dev = dev;
+ hw->irq = irq;
+ hw->tf = tf_ops;
+
+ dev_info(hw->dev, "Ver: %s\n", ST_ASM330LHH_VERSION);
+ err = st_asm330lhh_check_whoami(hw);
+ if (err < 0)
+ return err;
+
+ err = st_asm330lhh_init_device(hw);
+ if (err < 0)
+ return err;
+
+ for (i = 0; i < ST_ASM330LHH_ID_MAX; i++) {
+ hw->iio_devs[i] = st_asm330lhh_alloc_iiodev(hw, i);
+ if (!hw->iio_devs[i])
+ return -ENOMEM;
+ }
+
+ if (hw->irq > 0) {
+ err = st_asm330lhh_fifo_setup(hw);
+ if (err < 0)
+ return err;
+ }
+
+ for (i = 0; i < ST_ASM330LHH_ID_MAX; i++) {
+ if (!hw->iio_devs[i])
+ continue;
+
+ err = devm_iio_device_register(hw->dev, hw->iio_devs[i]);
+ if (err)
+ return err;
+ }
+
+ dev_info(hw->dev, "probe ok\n");
+
+ return 0;
+}
+EXPORT_SYMBOL(st_asm330lhh_probe);
+
+static int __maybe_unused st_asm330lhh_suspend(struct device *dev)
+{
+ struct st_asm330lhh_hw *hw = dev_get_drvdata(dev);
+ struct st_asm330lhh_sensor *sensor;
+ int i, err = 0;
+
+ for (i = 0; i < ST_ASM330LHH_ID_MAX; i++) {
+ if (!hw->iio_devs[i])
+ continue;
+
+ sensor = iio_priv(hw->iio_devs[i]);
+
+ if (!(hw->enable_mask & BIT(sensor->id)))
+ continue;
+
+ err = st_asm330lhh_set_odr(sensor, 0);
+ if (err < 0)
+ return err;
+ }
+
+ if (hw->enable_mask)
+ err = st_asm330lhh_suspend_fifo(hw);
+
+ return err;
+}
+
+static int __maybe_unused st_asm330lhh_resume(struct device *dev)
+{
+ struct st_asm330lhh_hw *hw = dev_get_drvdata(dev);
+ struct st_asm330lhh_sensor *sensor;
+ int i, err = 0;
+
+ for (i = 0; i < ST_ASM330LHH_ID_MAX; i++) {
+ if (!hw->iio_devs[i])
+ continue;
+
+ sensor = iio_priv(hw->iio_devs[i]);
+ if (!(hw->enable_mask & BIT(sensor->id)))
+ continue;
+
+ err = st_asm330lhh_set_odr(sensor, sensor->odr);
+ if (err < 0)
+ return err;
+ }
+
+ if (hw->enable_mask)
+ err = st_asm330lhh_set_fifo_mode(hw, ST_ASM330LHH_FIFO_CONT);
+
+ return err;
+}
+
+const struct dev_pm_ops st_asm330lhh_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(st_asm330lhh_suspend, st_asm330lhh_resume)
+};
+EXPORT_SYMBOL(st_asm330lhh_pm_ops);
+
+MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics st_asm330lhh driver");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION(ST_ASM330LHH_VERSION);
diff --git a/drivers/iio/imu/st_asm330lhh/st_asm330lhh_i2c.c b/drivers/iio/imu/st_asm330lhh/st_asm330lhh_i2c.c
new file mode 100644
index 0000000..4875097
--- /dev/null
+++ b/drivers/iio/imu/st_asm330lhh/st_asm330lhh_i2c.c
@@ -0,0 +1,94 @@
+/*
+ * STMicroelectronics st_asm330lhh i2c driver
+ *
+ * Copyright 2018 STMicroelectronics Inc.
+ *
+ * Lorenzo Bianconi <lorenzo.bianconi@st.com>
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+
+#include "st_asm330lhh.h"
+
+static int st_asm330lhh_i2c_read(struct device *dev, u8 addr, int len, u8 *data)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct i2c_msg msg[2];
+
+ msg[0].addr = client->addr;
+ msg[0].flags = client->flags;
+ msg[0].len = 1;
+ msg[0].buf = &addr;
+
+ msg[1].addr = client->addr;
+ msg[1].flags = client->flags | I2C_M_RD;
+ msg[1].len = len;
+ msg[1].buf = data;
+
+ return i2c_transfer(client->adapter, msg, 2);
+}
+
+static int st_asm330lhh_i2c_write(struct device *dev, u8 addr, int len, u8 *data)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct i2c_msg msg;
+ u8 send[len + 1];
+
+ send[0] = addr;
+ memcpy(&send[1], data, len * sizeof(u8));
+
+ msg.addr = client->addr;
+ msg.flags = client->flags;
+ msg.len = len + 1;
+ msg.buf = send;
+
+ return i2c_transfer(client->adapter, &msg, 1);
+}
+
+static const struct st_asm330lhh_transfer_function st_asm330lhh_transfer_fn = {
+ .read = st_asm330lhh_i2c_read,
+ .write = st_asm330lhh_i2c_write,
+};
+
+static int st_asm330lhh_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ return st_asm330lhh_probe(&client->dev, client->irq,
+ &st_asm330lhh_transfer_fn);
+}
+
+static const struct of_device_id st_asm330lhh_i2c_of_match[] = {
+ {
+ .compatible = "st,asm330lhh",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, st_asm330lhh_i2c_of_match);
+
+static const struct i2c_device_id st_asm330lhh_i2c_id_table[] = {
+ { ST_ASM330LHH_DEV_NAME },
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, st_asm330lhh_i2c_id_table);
+
+static struct i2c_driver st_asm330lhh_driver = {
+ .driver = {
+ .name = "st_asm330lhh_i2c",
+ .pm = &st_asm330lhh_pm_ops,
+ .of_match_table = of_match_ptr(st_asm330lhh_i2c_of_match),
+ },
+ .probe = st_asm330lhh_i2c_probe,
+ .id_table = st_asm330lhh_i2c_id_table,
+};
+module_i2c_driver(st_asm330lhh_driver);
+
+MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics st_asm330lhh i2c driver");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION(ST_ASM330LHH_VERSION);
diff --git a/drivers/iio/imu/st_asm330lhh/st_asm330lhh_spi.c b/drivers/iio/imu/st_asm330lhh/st_asm330lhh_spi.c
new file mode 100644
index 0000000..07b8400
--- /dev/null
+++ b/drivers/iio/imu/st_asm330lhh/st_asm330lhh_spi.c
@@ -0,0 +1,109 @@
+/*
+ * STMicroelectronics st_asm330lhh spi driver
+ *
+ * Copyright 2018 STMicroelectronics Inc.
+ *
+ * Lorenzo Bianconi <lorenzo.bianconi@st.com>
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+
+#include "st_asm330lhh.h"
+
+#define SENSORS_SPI_READ BIT(7)
+
+static int st_asm330lhh_spi_read(struct device *dev, u8 addr, int len,
+ u8 *data)
+{
+ struct spi_device *spi = to_spi_device(dev);
+ struct st_asm330lhh_hw *hw = spi_get_drvdata(spi);
+ int err;
+
+ struct spi_transfer xfers[] = {
+ {
+ .tx_buf = hw->tb.tx_buf,
+ .bits_per_word = 8,
+ .len = 1,
+ },
+ {
+ .rx_buf = hw->tb.rx_buf,
+ .bits_per_word = 8,
+ .len = len,
+ }
+ };
+
+ hw->tb.tx_buf[0] = addr | SENSORS_SPI_READ;
+
+ err = spi_sync_transfer(spi, xfers, ARRAY_SIZE(xfers));
+ if (err < 0)
+ return err;
+
+ memcpy(data, hw->tb.rx_buf, len * sizeof(u8));
+
+ return len;
+}
+
+static int st_asm330lhh_spi_write(struct device *dev, u8 addr, int len,
+ u8 *data)
+{
+ struct st_asm330lhh_hw *hw;
+ struct spi_device *spi;
+
+ if (len >= ST_ASM330LHH_TX_MAX_LENGTH)
+ return -ENOMEM;
+
+ spi = to_spi_device(dev);
+ hw = spi_get_drvdata(spi);
+
+ hw->tb.tx_buf[0] = addr;
+ memcpy(&hw->tb.tx_buf[1], data, len);
+
+ return spi_write(spi, hw->tb.tx_buf, len + 1);
+}
+
+static const struct st_asm330lhh_transfer_function st_asm330lhh_transfer_fn = {
+ .read = st_asm330lhh_spi_read,
+ .write = st_asm330lhh_spi_write,
+};
+
+static int st_asm330lhh_spi_probe(struct spi_device *spi)
+{
+ return st_asm330lhh_probe(&spi->dev, spi->irq,
+ &st_asm330lhh_transfer_fn);
+}
+
+static const struct of_device_id st_asm330lhh_spi_of_match[] = {
+ {
+ .compatible = "st,asm330lhh",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, st_asm330lhh_spi_of_match);
+
+static const struct spi_device_id st_asm330lhh_spi_id_table[] = {
+ { ST_ASM330LHH_DEV_NAME },
+ {},
+};
+MODULE_DEVICE_TABLE(spi, st_asm330lhh_spi_id_table);
+
+static struct spi_driver st_asm330lhh_driver = {
+ .driver = {
+ .name = "st_asm330lhh_spi",
+ .pm = &st_asm330lhh_pm_ops,
+ .of_match_table = of_match_ptr(st_asm330lhh_spi_of_match),
+ },
+ .probe = st_asm330lhh_spi_probe,
+ .id_table = st_asm330lhh_spi_id_table,
+};
+module_spi_driver(st_asm330lhh_driver);
+
+MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics st_asm330lhh spi driver");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION(ST_ASM330LHH_VERSION);
diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig
index fb3fb89..5d5368a 100644
--- a/drivers/infiniband/Kconfig
+++ b/drivers/infiniband/Kconfig
@@ -34,6 +34,18 @@
libibverbs, libibcm and a hardware driver library from
<http://www.openfabrics.org/git/>.
+config INFINIBAND_USER_ACCESS_UCM
+ bool "Userspace CM (UCM, DEPRECATED)"
+ depends on BROKEN
+ depends on INFINIBAND_USER_ACCESS
+ help
+ The UCM module has known security flaws, which no one is
+ interested to fix. The user-space part of this code was
+ dropped from the upstream a long time ago.
+
+ This option is DEPRECATED and planned to be removed.
+
+
config INFINIBAND_USER_MEM
bool
depends on INFINIBAND_USER_ACCESS != n
diff --git a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile
index edaae9f..33dc00c 100644
--- a/drivers/infiniband/core/Makefile
+++ b/drivers/infiniband/core/Makefile
@@ -4,8 +4,8 @@
obj-$(CONFIG_INFINIBAND) += ib_core.o ib_cm.o iw_cm.o \
$(infiniband-y)
obj-$(CONFIG_INFINIBAND_USER_MAD) += ib_umad.o
-obj-$(CONFIG_INFINIBAND_USER_ACCESS) += ib_uverbs.o ib_ucm.o \
- $(user_access-y)
+obj-$(CONFIG_INFINIBAND_USER_ACCESS) += ib_uverbs.o $(user_access-y)
+obj-$(CONFIG_INFINIBAND_USER_ACCESS_UCM) += ib_ucm.o $(user_access-y)
ib_core-y := packer.o ud_header.o verbs.o cq.o rw.o sysfs.o \
device.o fmr_pool.o cache.o netlink.o \
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index 2395fe2..3e2ab04 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -1549,7 +1549,8 @@
mad_reg_req->oui, 3)) {
method = &(*vendor_table)->vendor_class[
vclass]->method_table[i];
- BUG_ON(!*method);
+ if (!*method)
+ goto error3;
goto check_in_use;
}
}
@@ -1559,10 +1560,12 @@
vclass]->oui[i])) {
method = &(*vendor_table)->vendor_class[
vclass]->method_table[i];
- BUG_ON(*method);
/* Allocate method table for this OUI */
- if ((ret = allocate_method_table(method)))
- goto error3;
+ if (!*method) {
+ ret = allocate_method_table(method);
+ if (ret)
+ goto error3;
+ }
memcpy((*vendor_table)->vendor_class[vclass]->oui[i],
mad_reg_req->oui, 3);
goto check_in_use;
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index a036d70..3bef6d4 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -218,7 +218,7 @@
return NULL;
mutex_lock(&mut);
- mc->id = idr_alloc(&multicast_idr, mc, 0, 0, GFP_KERNEL);
+ mc->id = idr_alloc(&multicast_idr, NULL, 0, 0, GFP_KERNEL);
mutex_unlock(&mut);
if (mc->id < 0)
goto error;
@@ -1385,6 +1385,10 @@
goto err3;
}
+ mutex_lock(&mut);
+ idr_replace(&multicast_idr, mc, mc->id);
+ mutex_unlock(&mut);
+
mutex_unlock(&file->mut);
ucma_put_ctx(ctx);
return 0;
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index 4b717cf..6f875bf 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -3725,6 +3725,11 @@
goto err_uobj;
}
+ if (qp->qp_type != IB_QPT_UD && qp->qp_type != IB_QPT_RAW_PACKET) {
+ err = -EINVAL;
+ goto err_put;
+ }
+
flow_attr = kzalloc(sizeof(*flow_attr) + cmd.flow_attr.num_of_specs *
sizeof(union ib_flow_spec), GFP_KERNEL);
if (!flow_attr) {
diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c
index 410408f..0c21535 100644
--- a/drivers/infiniband/hw/cxgb4/mem.c
+++ b/drivers/infiniband/hw/cxgb4/mem.c
@@ -724,7 +724,7 @@
{
struct c4iw_mr *mhp = to_c4iw_mr(ibmr);
- if (unlikely(mhp->mpl_len == mhp->max_mpl_len))
+ if (unlikely(mhp->mpl_len == mhp->attr.pbl_size))
return -ENOMEM;
mhp->mpl[mhp->mpl_len++] = addr;
diff --git a/drivers/input/misc/vl53l0x/src/vl53l0x_i2c_platform.c b/drivers/input/misc/vl53l0x/src/vl53l0x_i2c_platform.c
index f8633a0..b63f880 100644
--- a/drivers/input/misc/vl53l0x/src/vl53l0x_i2c_platform.c
+++ b/drivers/input/misc/vl53l0x/src/vl53l0x_i2c_platform.c
@@ -147,7 +147,7 @@
int32_t count)
{
int32_t status = STATUS_OK;
- uint8_t *buffer;
+ uint8_t buffer[64];
#ifdef VL_LOG_ENABLE
int32_t i = 0;
@@ -166,7 +166,6 @@
#endif
if ((count + 1) > VL_MAX_I2C_XFER_SIZE)
return STATUS_FAIL;
- buffer = VL_GetLocalBuffer(dev, (count+1));
buffer[0] = index;
memcpy(&buffer[1], pdata, count);
status = VL_I2CWrite(dev, buffer, (count+1));
diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c
index 97f6e05..a716482 100644
--- a/drivers/input/mouse/elan_i2c_core.c
+++ b/drivers/input/mouse/elan_i2c_core.c
@@ -1251,6 +1251,8 @@
{ "ELAN0611", 0 },
{ "ELAN0612", 0 },
{ "ELAN0618", 0 },
+ { "ELAN061D", 0 },
+ { "ELAN0622", 0 },
{ "ELAN1000", 0 },
{ }
};
diff --git a/drivers/input/sensors/bmi160/Kconfig b/drivers/input/sensors/bmi160/Kconfig
new file mode 100644
index 0000000..0b1feda
--- /dev/null
+++ b/drivers/input/sensors/bmi160/Kconfig
@@ -0,0 +1,121 @@
+#
+# Makefile for Bosch sensors driver.
+#
+config BOSCH_DRIVER_LOG_FUNC
+ tristate "Bosch Sensortec driver smart log function support"
+ depends on (I2C || SPI_MASTER) && SYSFS
+ help
+ If you say yes here, you get support for smart log function in Bosch Sensortec driver.
+
+config SENSORS_BMA2X2
+ tristate "BMA2x2 acceleration sensor support"
+ depends on I2C
+ help
+ If you say yes here, you get support for Bosch Sensortec's
+ acceleration sensors BMA255/BMA254/BMA355/BMA250E/BMA222E/BMA280.
+
+config SENSORS_BMA2X2_ENABLE_INT1
+ tristate "BMA2X2 acceleration sensor interrupt INT1 support"
+ depends on SENSORS_BMA2X2
+ help
+ If you say yes here, you get INT1 support for Bosch Sensortec
+ acceleration sensors BMA255/BMA250E/BMA222E/BMA280.
+ Select it will disable interrupt INT2 support
+
+config SENSORS_BMA2X2_ENABLE_INT2
+ tristate "BMA2X2 acceleration sensor interrupt INT2 support"
+ depends on SENSORS_BMA2X2 && !SENSORS_BMA2X2_ENABLE_INT1
+ help
+ If you say yes here, you get INT2 support for Bosch Sensortec
+ acceleration sensors BMA255/BMA250E/BMA222E/BMA280.
+ Can only open if you do NOT open interrupt INT1 support
+
+config SIG_MOTION
+ tristate "support significant motion sensor function"
+ depends on SENSORS_BMA2X2 && ( SENSORS_BMA2X2_ENABLE_INT1 || SENSORS_BMA2X2_ENABLE_INT2)
+ help
+ If you say yes here, if you want to support Bosch significant motion sensor function
+
+config DOUBLE_TAP
+ tristate "support double tap sensor function"
+ depends on SENSORS_BMA2X2 && ( SENSORS_BMA2X2_ENABLE_INT1 || SENSORS_BMA2X2_ENABLE_INT2)
+ help
+ If you say yes here, you get support Bosch double tap sensor function
+
+config SENSORS_BMG
+ tristate "Bosch Gyroscope Sensor Driver"
+ depends on I2C
+ help
+ If you say yes here, you get support for Bosch Sensortec's
+ gyroscope sensor drivers of BMG160/BMI055/BMI058 e.t.c.
+
+config SENSORS_BMG_FIFO
+ tristate "Bosch Gyroscope FIFO Support"
+ depends on SENSORS_BMG
+ help
+ If you say yes here, you get support for Gyroscope sensor FIFO operations.
+ Please check whether the chip supports fifo feature to open it.
+
+config SENSORS_BMI058
+ tristate "BMI058 Sensor Support"
+ depends on (SENSORS_BMG || SENSORS_BMA2X2)
+ help
+ If you say yes here, you get support for Bosch Sensortec's
+ sensor driver of BMI058.
+
+config SENSORS_YAS537
+ tristate "YAS537 Magnetic Sensor Driver"
+ depends on I2C
+ help
+ If you say yes here, you get support for YAMAHA
+ sensor YAS537 Magnetic Sensor
+
+config SENSORS_BMM050
+ tristate "BMM050 Magnetic Sensor Driver"
+ depends on I2C
+ help
+ If you say yes here, you get support for Bosch Sensortec's
+ sensor BMM050 Magnetic Sensor
+
+config SENSORS_AKM09911
+ tristate "AKM09911 Mag Sensor Driver"
+ depends on I2C
+ help
+ If you say yes here, you get support AKM09911 Sensor support.
+
+config SENSORS_AKM09912
+ tristate "AKM09912 Mag Sensor Driver"
+ depends on I2C
+ help
+ If you say yes here, you get support AKM09912 Sensor support.
+
+config SENSORS_BMA420
+ tristate "BMA4XY Sensor Support"
+ depends on I2C || SPI_MASTER
+ help
+ If you say yes here, you get support for Bosch Sensortec's sensor driver of BMA420.
+config SENSORS_BMA421
+ tristate "BMA4XY Sensor Support"
+ depends on I2C || SPI_MASTER
+ help
+ If you say yes here, you get support for Bosch Sensortec's sensor driver of BMA421.
+config SENSORS_BMA422
+ tristate "BMA4XY Sensor Support"
+ depends on I2C || SPI_MASTER
+ help
+ If you say yes here, you get support for Bosch Sensortec's sensor driver of BMA422.
+config SENSORS_BMA455
+ tristate "BMA4XY Sensor Support"
+ depends on I2C || SPI_MASTER
+ help
+ If you say yes here, you get support for Bosch Sensortec's sensor driver of BMA455.
+
+config BMA4XY_MAG_INTERFACE_SUPPORT
+tristate "BMA4XY Sensor mag interface support"
+depends on SENSORS_BMA4XY
+ help
+ If you say yes here, you get support for Bosch Sensortec's
+ sensor driver of BMA4XY with mag sensor support.
+
+
+
diff --git a/drivers/input/sensors/bmi160/Makefile b/drivers/input/sensors/bmi160/Makefile
new file mode 100644
index 0000000..0a9bb56
--- /dev/null
+++ b/drivers/input/sensors/bmi160/Makefile
@@ -0,0 +1,41 @@
+#
+# Makefile for Bosch sensor driver.
+#
+
+obj-$(CONFIG_BOSCH_DRIVER_LOG_FUNC) += bs_log.o
+obj-y += bstclass.o
+ifeq ($(CONFIG_BOSCH_DRIVER_LOG_FUNC),y)
+ EXTRA_CFLAGS += -DBOSCH_DRIVER_LOG_FUNC
+endif
+
+#obj-y += bma2x2.o
+
+ifeq ($(CONFIG_SENSORS_BMA2X2_ENABLE_INT1),y)
+ EXTRA_CFLAGS += -DBMA2X2_ENABLE_INT1
+endif
+
+ifeq ($(CONFIG_BOSCH_BMA2X2_ENABLE_INT2),y)
+ EXTRA_CFLAGS += -DBMA2X2_ENABLE_INT2
+endif
+
+#obj-y += bmg160_driver.o bmg160.o
+EXTRA_CFLAGS += -DBMG_USE_BASIC_I2C_FUNC
+
+obj-y += bmi160_driver.o bmi160.o
+ifeq ($(CONFIG_BMI160_MAG_INTERFACE_SUPPORT),y)
+ EXTRA_CFLAGS += -DBMI160_MAG_INTERFACE_SUPPORT
+endif
+ifeq ($(CONFIG_SENSORS_BMI160_ENABLE_INT1),y)
+ EXTRA_CFLAGS += -DBMI160_ENABLE_INT1
+endif
+
+ifeq ($(CONFIG_SENSORS_BMI160_ENABLE_INT2),y)
+ EXTRA_CFLAGS += -DBMI160_ENABLE_INT2
+endif
+
+obj-y += bmi160_i2c.o
+
+EXTRA_CFLAGS += -DBMI_USE_BASIC_I2C_FUNC
+
+obj-$(CONFIG_SENSORS_BMI160_SPI) += bmi160_spi.o
+
diff --git a/drivers/input/sensors/bmi160/bmi160.c b/drivers/input/sensors/bmi160/bmi160.c
new file mode 100644
index 0000000..071f7e3
--- /dev/null
+++ b/drivers/input/sensors/bmi160/bmi160.c
@@ -0,0 +1,18753 @@
+/*
+* @section LICENSE
+* (C) Copyright 2011~2018 Bosch Sensortec GmbH All Rights Reserved
+*
+* This software program is licensed subject to the GNU General
+* Public License (GPL).Version 2,June 1991,
+* available at http://www.fsf.org/copyleft/gpl.html
+
+*
+* @filename bmi160.c
+* @Date: 2015/04/02
+* @id 836294d
+* @Revision: 2.0.9 $
+*
+* Usage: Sensor Driver for BMI160 sensor
+*
+****************************************************************************
+* \section Disclaimer
+*
+* Common:
+* Bosch Sensortec products are developed for the consumer goods industry.
+* They may only be used within the parameters of the respective valid
+* product data sheet. Bosch Sensortec products are provided with the
+* express understanding that there is no warranty of fitness for a
+* particular purpose.They are not fit for use in life-sustaining,
+* safety or security sensitive systems or any system or device
+* that may lead to bodily harm or property damage if the system
+* or device malfunctions. In addition,Bosch Sensortec products are
+* not fit for use in products which interact with motor vehicle systems.
+* The resale and or use of products are at the purchasers own risk and
+* his own responsibility. The examination of fitness for the intended use
+* is the sole responsibility of the Purchaser.
+*
+* The purchaser shall indemnify Bosch Sensortec from all third party
+* claims, including any claims for incidental, or consequential damages,
+* arising from any product use not covered by the parameters of
+* the respective valid product data sheet or not approved by
+* Bosch Sensortec and reimburse Bosch Sensortec for all costs in
+* connection with such claims.
+*
+* The purchaser must monitor the market for the purchased products,
+* particularly with regard to product safety and inform Bosch Sensortec
+* without delay of all security relevant incidents.
+*
+* Engineering Samples are marked with an asterisk (*) or (e).
+* Samples may vary from the valid technical specifications of the product
+* series. They are therefore not intended or fit for resale to third
+* parties or for use in end products. Their sole purpose is internal
+* client testing. The testing of an engineering sample may in no way
+* replace the testing of a product series. Bosch Sensortec assumes
+* no liability for the use of engineering samples.
+* By accepting the engineering samples, the Purchaser agrees to indemnify
+* Bosch Sensortec from all claims arising from the use of engineering
+* samples.
+*
+* Special:
+* This software module (hereinafter called "Software") and any information
+* on application-sheets (hereinafter called "Information") is provided
+* free of charge for the sole purpose to support your application work.
+* The Software and Information is subject to the following
+* terms and conditions:
+*
+* The Software is specifically designed for the exclusive use for
+* Bosch Sensortec products by personnel who have special experience
+* and training. Do not use this Software if you do not have the
+* proper experience or training.
+*
+* This Software package is provided `` as is `` and without any expressed
+* or implied warranties,including without limitation, the implied warranties
+* of merchantability and fitness for a particular purpose.
+*
+* Bosch Sensortec and their representatives and agents deny any liability
+* for the functional impairment
+* of this Software in terms of fitness, performance and safety.
+* Bosch Sensortec and their representatives and agents shall not be liable
+* for any direct or indirect damages or injury, except as
+* otherwise stipulated in mandatory applicable law.
+*
+* The Information provided is believed to be accurate and reliable.
+* Bosch Sensortec assumes no responsibility for the consequences of use
+* of such Information nor for any infringement of patents or
+* other rights of third parties which may result from its use.
+* No license is granted by implication or otherwise under any patent or
+* patent rights of Bosch. Specifications mentioned in the Information are
+* subject to change without notice.
+**************************************************************************/
+/*! file <BMI160 >
+ brief <Sensor driver for BMI160> */
+#include "bmi160.h"
+#include <linux/kernel.h>
+
+/* user defined code to be added here ... */
+struct bmi160_t *p_bmi160;
+/* used for reading the mag trim values for compensation*/
+struct trim_data_t mag_trim;
+/* the following variable used for avoiding the selecting of auto mode
+when it is running in the manual mode of BMM150 mag interface*/
+u8 V_bmm150_maual_auto_condition_u8 = BMI160_INIT_VALUE;
+/* used for reading the AKM compensating data */
+struct bst_akm_sensitivity_data_t akm_asa_data;
+/* Assign the fifo time */
+u32 V_fifo_time_U32 = BMI160_INIT_VALUE;
+
+/* FIFO data read for 1024 bytes of data */
+u8 v_fifo_data_u8[FIFO_FRAME] = {BMI160_INIT_VALUE};
+/* YAMAHA-YAS532*/
+/* value of coeff*/
+static const int yas532_version_ac_coef[] = {YAS532_VERSION_AC_COEF_X,
+YAS532_VERSION_AC_COEF_Y1, YAS532_VERSION_AC_COEF_Y2};
+/* used for reading the yas532 calibration data*/
+struct yas532_t yas532_data;
+/* used for reading the yas537 calibration data*/
+struct yas537_t yas537_data;
+/*!
+ * @brief
+ * This function is used for initialize
+ * bus read and bus write functions
+ * assign the chip id and device address
+ * chip id is read in the register 0x00 bit from 0 to 7
+ *
+ * @param bmi160 : structure pointer
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ * @note
+ * While changing the parameter of the bmi160_t
+ * consider the following point:
+ * Changing the reference value of the parameter
+ * will changes the local copy or local reference
+ * make sure your changes will not
+ * affect the reference value of the parameter
+ * (Better case don't change the reference value of the parameter)
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_init(struct bmi160_t *bmi160)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ u8 v_pmu_data_u8 = BMI160_INIT_VALUE;
+ /* assign bmi160 ptr */
+ p_bmi160 = bmi160;
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_CHIP_ID__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ /* read Chip Id */
+ p_bmi160->chip_id = v_data_u8;
+ /* To avoid gyro wakeup it is required to write 0x00 to 0x6C*/
+ com_rslt += bmi160_write_reg(BMI160_USER_PMU_TRIGGER_ADDR,
+ &v_pmu_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ return com_rslt;
+}
+/*!
+ * @brief
+ * This API write the data to
+ * the given register
+ *
+ *
+ * @param v_addr_u8 -> Address of the register
+ * @param v_data_u8 -> The data from the register
+ * @param v_len_u8 -> no of bytes to read
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_write_reg(u8 v_addr_u8,
+u8 *v_data_u8, u8 v_len_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* write data from register*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->dev_addr,
+ v_addr_u8, v_data_u8, v_len_u8);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief
+ * This API reads the data from
+ * the given register
+ *
+ *
+ * @param v_addr_u8 -> Address of the register
+ * @param v_data_u8 -> The data from the register
+ * @param v_len_u8 -> no of bytes to read
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_reg(u8 v_addr_u8,
+u8 *v_data_u8, u8 v_len_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* Read data from register*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ v_addr_u8, v_data_u8, v_len_u8);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API used to reads the fatal error
+ * from the Register 0x02 bit 0
+ * This flag will be reset only by power-on-reset and soft reset
+ *
+ *
+ * @param v_fatal_err_u8 : The status of fatal error
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_fatal_err(u8
+*v_fatal_err_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* reading the fatal error status*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_FATAL_ERR__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fatal_err_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_FATAL_ERR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API used to read the error code
+ * from register 0x02 bit 1 to 4
+ *
+ *
+ * @param v_err_code_u8 : The status of error codes
+ * error_code | description
+ * ------------|---------------
+ * 0x00 |no error
+ * 0x01 |ACC_CONF error (accel ODR and bandwidth not compatible)
+ * 0x02 |GYR_CONF error (Gyroscope ODR and bandwidth not compatible)
+ * 0x03 |Under sampling mode and interrupt uses pre filtered data
+ * 0x04 |reserved
+ * 0x05 |Selected trigger-readout offset in
+ * - |MAG_IF greater than selected ODR
+ * 0x06 |FIFO configuration error for header less mode
+ * 0x07 |Under sampling mode and pre filtered data as FIFO source
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_err_code(u8
+*v_err_code_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_ERR_CODE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_err_code_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_ERR_CODE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API Reads the i2c error code from the
+ * Register 0x02 bit 5.
+ * This error occurred in I2C master detected
+ *
+ * @param v_i2c_err_code_u8 : The status of i2c fail error
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_i2c_fail_err(u8
+*v_i2c_err_code_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_I2C_FAIL_ERR__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_i2c_err_code_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_I2C_FAIL_ERR);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API Reads the dropped command error
+ * from the register 0x02 bit 6
+ *
+ *
+ * @param v_drop_cmd_err_u8 : The status of drop command error
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_drop_cmd_err(u8
+*v_drop_cmd_err_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_DROP_CMD_ERR__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_drop_cmd_err_u8 = BMI160_GET_BITSLICE(
+ v_data_u8,
+ BMI160_USER_DROP_CMD_ERR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the magnetometer data ready
+ * interrupt not active.
+ * It reads from the error register 0x0x2 bit 7
+ *
+ *
+ *
+ *
+ * @param v_mag_data_rdy_err_u8 : The status of mag data ready interrupt
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_dada_rdy_err(
+u8 *v_mag_data_rdy_err_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_MAG_DADA_RDY_ERR__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_mag_data_rdy_err_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_MAG_DADA_RDY_ERR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the error status
+ * from the error register 0x02 bit 0 to 7
+ *
+ * @param v_mag_data_rdy_err_u8 : The status of mag data ready interrupt
+ * @param v_fatal_er_u8r : The status of fatal error
+ * @param v_err_code_u8 : The status of error code
+ * @param v_i2c_fail_err_u8 : The status of I2C fail error
+ * @param v_drop_cmd_err_u8 : The status of drop command error
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_error_status(u8 *v_fatal_er_u8r,
+u8 *v_err_code_u8, u8 *v_i2c_fail_err_u8,
+u8 *v_drop_cmd_err_u8, u8 *v_mag_data_rdy_err_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the error codes*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_ERR_STAT__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ /* fatal error*/
+ *v_fatal_er_u8r =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_FATAL_ERR);
+ /* user error*/
+ *v_err_code_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_ERR_CODE);
+ /* i2c fail error*/
+ *v_i2c_fail_err_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_I2C_FAIL_ERR);
+ /* drop command error*/
+ *v_drop_cmd_err_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_DROP_CMD_ERR);
+ /* mag data ready error*/
+ *v_mag_data_rdy_err_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_MAG_DADA_RDY_ERR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the magnetometer power mode from
+ * PMU status register 0x03 bit 0 and 1
+ *
+ * @param v_mag_power_mode_stat_u8 : The value of mag power mode
+ * mag_powermode | value
+ * ------------------|----------
+ * SUSPEND | 0x00
+ * NORMAL | 0x01
+ * LOW POWER | 0x02
+ *
+ *
+ * @note The power mode of mag set by the 0x7E command register
+ * @note using the function "bmi160_set_command_register()"
+ * value | mode
+ * ---------|----------------
+ * 0x18 | MAG_MODE_SUSPEND
+ * 0x19 | MAG_MODE_NORMAL
+ * 0x1A | MAG_MODE_LOWPOWER
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_power_mode_stat(u8
+*v_mag_power_mode_stat_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_MAG_POWER_MODE_STAT__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_mag_power_mode_stat_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_MAG_POWER_MODE_STAT);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the gyroscope power mode from
+ * PMU status register 0x03 bit 2 and 3
+ *
+ * @param v_gyro_power_mode_stat_u8 : The value of gyro power mode
+ * gyro_powermode | value
+ * ------------------|----------
+ * SUSPEND | 0x00
+ * NORMAL | 0x01
+ * FAST POWER UP | 0x03
+ *
+ * @note The power mode of gyro set by the 0x7E command register
+ * @note using the function "bmi160_set_command_register()"
+ * value | mode
+ * ---------|----------------
+ * 0x14 | GYRO_MODE_SUSPEND
+ * 0x15 | GYRO_MODE_NORMAL
+ * 0x17 | GYRO_MODE_FASTSTARTUP
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_power_mode_stat(u8
+*v_gyro_power_mode_stat_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_GYRO_POWER_MODE_STAT__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_gyro_power_mode_stat_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_GYRO_POWER_MODE_STAT);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the accelerometer power mode from
+ * PMU status register 0x03 bit 4 and 5
+ *
+ *
+ * @param v_accel_power_mode_stat_u8 : The value of accel power mode
+ * accel_powermode | value
+ * ------------------|----------
+ * SUSPEND | 0x00
+ * NORMAL | 0x01
+ * LOW POWER | 0x02
+ *
+ * @note The power mode of accel set by the 0x7E command register
+ * @note using the function "bmi160_set_command_register()"
+ * value | mode
+ * ---------|----------------
+ * 0x11 | ACCEL_MODE_NORMAL
+ * 0x12 | ACCEL_LOWPOWER
+ * 0x10 | ACCEL_SUSPEND
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_power_mode_stat(u8
+*v_accel_power_mode_stat_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_ACCEL_POWER_MODE_STAT__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_power_mode_stat_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_ACCEL_POWER_MODE_STAT);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API switch mag interface to normal mode
+ * and confirm whether the mode switching done successfully or not
+*
+ * @return results of bus communication function and current MAG_PMU result
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_interface_normal(void)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = BMI160_INIT_VALUE;
+ /* aim to check the result of switching mag normal */
+ u8 v_try_times_u8 = BMI160_MAG_NOAMRL_SWITCH_TIMES;
+ u8 v_mag_pum_status_u8 = BMI160_INIT_VALUE;
+
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt = bmi160_set_command_register(MAG_MODE_NORMAL);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ while (v_try_times_u8) {
+ com_rslt = bmi160_get_mag_power_mode_stat(&v_mag_pum_status_u8);
+ if (v_mag_pum_status_u8 == MAG_INTERFACE_PMU_ENABLE)
+ break;
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ v_try_times_u8--;
+ }
+ if (v_mag_pum_status_u8 == MAG_INTERFACE_PMU_ENABLE)
+ com_rslt += SUCCESS;
+ else
+ com_rslt += E_BMI160_COMM_RES;
+
+ return com_rslt;
+}
+/*!
+ * @brief This API reads magnetometer data X values
+ * from the register 0x04 and 0x05
+ * @brief The mag sensor data read form auxiliary mag
+ *
+ * @param v_mag_x_s16 : The value of mag x
+ * @param v_sensor_select_u8 : Mag selection value
+ * value | sensor
+ * ---------|----------------
+ * 0 | BMM150
+ * 1 | AKM09911 or AKM09912
+ *
+ * @note For mag data output rate configuration use the following function
+ * @note bmi160_set_mag_output_data_rate()
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_mag_x(s16 *v_mag_x_s16,
+u8 v_sensor_select_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* Array contains the mag X lSB and MSB data
+ v_data_u8[0] - LSB
+ v_data_u8[1] - MSB*/
+ u8 v_data_u8[BMI160_MAG_X_DATA_SIZE] = {BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE};
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_sensor_select_u8) {
+ case BST_BMM:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_DATA_MAG_X_LSB__REG,
+ v_data_u8, BMI160_MAG_X_DATA_LENGTH);
+ /* X axis*/
+ v_data_u8[BMI160_MAG_X_LSB_BYTE] =
+ BMI160_GET_BITSLICE(v_data_u8[BMI160_MAG_X_LSB_BYTE],
+ BMI160_USER_DATA_MAG_X_LSB);
+ *v_mag_x_s16 = (s16)
+ ((((s32)((s8)v_data_u8[BMI160_MAG_X_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_05_BITS) |
+ (v_data_u8[BMI160_MAG_X_LSB_BYTE]));
+ break;
+ case BST_AKM:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_DATA_0_MAG_X_LSB__REG,
+ v_data_u8, BMI160_MAG_X_DATA_LENGTH);
+ *v_mag_x_s16 = (s16)
+ ((((s32)((s8)v_data_u8[BMI160_MAG_X_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[BMI160_MAG_X_LSB_BYTE]));
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads magnetometer data Y values
+ * from the register 0x06 and 0x07
+ * @brief The mag sensor data read form auxiliary mag
+ *
+ * @param v_mag_y_s16 : The value of mag y
+ * @param v_sensor_select_u8 : Mag selection value
+ * value | sensor
+ * ---------|----------------
+ * 0 | BMM150
+ * 1 | AKM09911 or AKM09912
+ *
+ * @note For mag data output rate configuration use the following function
+ * @note bmi160_set_mag_output_data_rate()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_mag_y(s16 *v_mag_y_s16,
+u8 v_sensor_select_u8)
+{
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_OUT_OF_RANGE;
+ /* Array contains the mag Y lSB and MSB data
+ v_data_u8[0] - LSB
+ v_data_u8[1] - MSB*/
+ u8 v_data_u8[BMI160_MAG_Y_DATA_SIZE] = {BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE};
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_sensor_select_u8) {
+ case BST_BMM:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_DATA_MAG_Y_LSB__REG,
+ v_data_u8, BMI160_MAG_Y_DATA_LENGTH);
+ /*Y-axis lsb value shifting*/
+ v_data_u8[BMI160_MAG_Y_LSB_BYTE] =
+ BMI160_GET_BITSLICE(v_data_u8[BMI160_MAG_Y_LSB_BYTE],
+ BMI160_USER_DATA_MAG_Y_LSB);
+ *v_mag_y_s16 = (s16)
+ ((((s32)((s8)v_data_u8[BMI160_MAG_Y_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_05_BITS) |
+ (v_data_u8[BMI160_MAG_Y_LSB_BYTE]));
+ break;
+ case BST_AKM:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_DATA_2_MAG_Y_LSB__REG,
+ v_data_u8, BMI160_MAG_Y_DATA_LENGTH);
+ *v_mag_y_s16 = (s16)
+ ((((s32)((s8)v_data_u8[BMI160_MAG_Y_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[BMI160_MAG_Y_LSB_BYTE]));
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads magnetometer data Z values
+ * from the register 0x08 and 0x09
+ * @brief The mag sensor data read form auxiliary mag
+ *
+ * @param v_mag_z_s16 : The value of mag z
+ * @param v_sensor_select_u8 : Mag selection value
+ * value | sensor
+ * ---------|----------------
+ * 0 | BMM150
+ * 1 | AKM09911 or AKM09912
+ *
+ * @note For mag data output rate configuration use the following function
+ * @note bmi160_set_mag_output_data_rate()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_mag_z(s16 *v_mag_z_s16,
+u8 v_sensor_select_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* Array contains the mag Z lSB and MSB data
+ v_data_u8[0] - LSB
+ v_data_u8[1] - MSB*/
+ u8 v_data_u8[BMI160_MAG_Z_DATA_SIZE] = {BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE};
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_sensor_select_u8) {
+ case BST_BMM:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_DATA_MAG_Z_LSB__REG,
+ v_data_u8, BMI160_MAG_Z_DATA_LENGTH);
+ /*Z-axis lsb value shifting*/
+ v_data_u8[BMI160_MAG_Z_LSB_BYTE] =
+ BMI160_GET_BITSLICE(v_data_u8[BMI160_MAG_Z_LSB_BYTE],
+ BMI160_USER_DATA_MAG_Z_LSB);
+ *v_mag_z_s16 = (s16)
+ ((((s32)((s8)v_data_u8[BMI160_MAG_Z_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_07_BITS) |
+ (v_data_u8[BMI160_MAG_Z_LSB_BYTE]));
+ break;
+ case BST_AKM:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_DATA_4_MAG_Z_LSB__REG,
+ v_data_u8, BMI160_MAG_Z_DATA_LENGTH);
+ *v_mag_z_s16 = (s16)
+ ((((s32)((s8)v_data_u8[BMI160_MAG_Z_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) | (
+ v_data_u8[BMI160_MAG_Z_LSB_BYTE]));
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads magnetometer data RHALL values
+ * from the register 0x0A and 0x0B
+ *
+ *
+ * @param v_mag_r_s16 : The value of BMM150 r data
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_mag_r(s16 *v_mag_r_s16)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* Array contains the mag R lSB and MSB data
+ v_data_u8[0] - LSB
+ v_data_u8[1] - MSB*/
+ u8 v_data_u8[BMI160_MAG_R_DATA_SIZE] = {BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE};
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_DATA_6_RHALL_LSB__REG,
+ v_data_u8, BMI160_MAG_R_DATA_LENGTH);
+ /*R-axis lsb value shifting*/
+ v_data_u8[BMI160_MAG_R_LSB_BYTE] =
+ BMI160_GET_BITSLICE(v_data_u8[BMI160_MAG_R_LSB_BYTE],
+ BMI160_USER_DATA_MAG_R_LSB);
+ *v_mag_r_s16 = (s16)
+ ((((s32)((s8)v_data_u8[BMI160_MAG_R_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_06_BITS) |
+ (v_data_u8[BMI160_MAG_R_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads magnetometer data X,Y,Z values
+ * from the register 0x04 to 0x09
+ *
+ * @brief The mag sensor data read form auxiliary mag
+ *
+ * @param mag : The value of mag xyz data
+ * @param v_sensor_select_u8 : Mag selection value
+ * value | sensor
+ * ---------|----------------
+ * 0 | BMM150
+ * 1 | AKM09911 or AKM09912
+ *
+ * @note For mag data output rate configuration use the following function
+ * @note bmi160_set_mag_output_data_rate()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_mag_xyz(
+struct bmi160_mag_t *mag, u8 v_sensor_select_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* Array contains the mag XYZ lSB and MSB data
+ v_data_u8[0] - X-LSB
+ v_data_u8[1] - X-MSB
+ v_data_u8[0] - Y-LSB
+ v_data_u8[1] - Y-MSB
+ v_data_u8[0] - Z-LSB
+ v_data_u8[1] - Z-MSB
+ */
+ u8 v_data_u8[BMI160_MAG_XYZ_DATA_SIZE] = {
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE};
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_sensor_select_u8) {
+ case BST_BMM:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_DATA_MAG_X_LSB__REG,
+ v_data_u8, BMI160_MAG_XYZ_DATA_LENGTH);
+ /*X-axis lsb value shifting*/
+ v_data_u8[BMI160_DATA_FRAME_MAG_X_LSB_BYTE] =
+ BMI160_GET_BITSLICE(
+ v_data_u8[BMI160_DATA_FRAME_MAG_X_LSB_BYTE],
+ BMI160_USER_DATA_MAG_X_LSB);
+ /* Data X */
+ mag->x = (s16)
+ ((((s32)((s8)v_data_u8[
+ BMI160_DATA_FRAME_MAG_X_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_05_BITS) |
+ (v_data_u8[BMI160_DATA_FRAME_MAG_X_LSB_BYTE]));
+ /* Data Y */
+ /*Y-axis lsb value shifting*/
+ v_data_u8[BMI160_DATA_FRAME_MAG_Y_LSB_BYTE] =
+ BMI160_GET_BITSLICE(
+ v_data_u8[BMI160_DATA_FRAME_MAG_Y_LSB_BYTE],
+ BMI160_USER_DATA_MAG_Y_LSB);
+ mag->y = (s16)
+ ((((s32)((s8)v_data_u8[
+ BMI160_DATA_FRAME_MAG_Y_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_05_BITS) |
+ (v_data_u8[BMI160_DATA_FRAME_MAG_Y_LSB_BYTE]));
+
+ /* Data Z */
+ /*Z-axis lsb value shifting*/
+ v_data_u8[BMI160_DATA_FRAME_MAG_Z_LSB_BYTE]
+ = BMI160_GET_BITSLICE(
+ v_data_u8[BMI160_DATA_FRAME_MAG_Z_LSB_BYTE],
+ BMI160_USER_DATA_MAG_Z_LSB);
+ mag->z = (s16)
+ ((((s32)((s8)v_data_u8[
+ BMI160_DATA_FRAME_MAG_Z_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_07_BITS) |
+ (v_data_u8[BMI160_DATA_FRAME_MAG_Z_LSB_BYTE]));
+ break;
+ case BST_AKM:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_DATA_0_MAG_X_LSB__REG,
+ v_data_u8, BMI160_MAG_XYZ_DATA_LENGTH);
+ /* Data X */
+ mag->x = (s16)
+ ((((s32)((s8)v_data_u8[
+ BMI160_DATA_FRAME_MAG_X_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[BMI160_DATA_FRAME_MAG_X_LSB_BYTE]));
+ /* Data Y */
+ mag->y = ((((s32)((s8)v_data_u8[
+ BMI160_DATA_FRAME_MAG_Y_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[BMI160_DATA_FRAME_MAG_Y_LSB_BYTE]));
+ /* Data Z */
+ mag->z = (s16)
+ ((((s32)((s8)v_data_u8[
+ BMI160_DATA_FRAME_MAG_Z_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[BMI160_DATA_FRAME_MAG_Z_LSB_BYTE]));
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+ /*!*
+ * @brief This API reads magnetometer data X,Y,Z,r
+ * values from the register 0x04 to 0x0B
+ *
+ * @brief The mag sensor data read form auxiliary mag
+ *
+ * @param mag : The value of mag-BMM150 xyzr data
+ *
+ * @note For mag data output rate configuration use the following function
+ * @note bmi160_set_mag_output_data_rate()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_mag_xyzr(
+struct bmi160_mag_xyzr_t *mag)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8[BMI160_MAG_XYZR_DATA_SIZE] = {
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE};
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_DATA_MAG_X_LSB__REG,
+ v_data_u8, BMI160_MAG_XYZR_DATA_LENGTH);
+
+ /* Data X */
+ /*X-axis lsb value shifting*/
+ v_data_u8[BMI160_DATA_FRAME_MAG_X_LSB_BYTE]
+ = BMI160_GET_BITSLICE(
+ v_data_u8[BMI160_DATA_FRAME_MAG_X_LSB_BYTE],
+ BMI160_USER_DATA_MAG_X_LSB);
+ mag->x = (s16)
+ ((((s32)((s8)v_data_u8[
+ BMI160_DATA_FRAME_MAG_X_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_05_BITS)
+ | (v_data_u8[BMI160_DATA_FRAME_MAG_X_LSB_BYTE]));
+ /* Data Y */
+ /*Y-axis lsb value shifting*/
+ v_data_u8[BMI160_DATA_FRAME_MAG_Y_LSB_BYTE]
+ = BMI160_GET_BITSLICE(
+ v_data_u8[BMI160_DATA_FRAME_MAG_Y_LSB_BYTE],
+ BMI160_USER_DATA_MAG_Y_LSB);
+ mag->y = (s16)
+ ((((s32)((s8)v_data_u8[
+ BMI160_DATA_FRAME_MAG_Y_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_05_BITS)
+ | (v_data_u8[
+ BMI160_DATA_FRAME_MAG_Y_LSB_BYTE]));
+
+ /* Data Z */
+ /*Z-axis lsb value shifting*/
+ v_data_u8[BMI160_DATA_FRAME_MAG_Z_LSB_BYTE]
+ = BMI160_GET_BITSLICE(
+ v_data_u8[BMI160_DATA_FRAME_MAG_Z_LSB_BYTE],
+ BMI160_USER_DATA_MAG_Z_LSB);
+ mag->z = (s16)
+ ((((s32)((s8)v_data_u8[
+ BMI160_DATA_FRAME_MAG_Z_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_07_BITS)
+ | (v_data_u8[BMI160_DATA_FRAME_MAG_Z_LSB_BYTE]));
+
+ /* RHall */
+ /*R-axis lsb value shifting*/
+ v_data_u8[BMI160_DATA_FRAME_MAG_R_LSB_BYTE]
+ = BMI160_GET_BITSLICE(
+ v_data_u8[BMI160_DATA_FRAME_MAG_R_LSB_BYTE],
+ BMI160_USER_DATA_MAG_R_LSB);
+ mag->r = (s16)
+ ((((s32)((s8)v_data_u8[
+ BMI160_DATA_FRAME_MAG_R_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_06_BITS)
+ | (v_data_u8[BMI160_DATA_FRAME_MAG_R_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads gyro data X values
+ * form the register 0x0C and 0x0D
+ *
+ *
+ *
+ *
+ * @param v_gyro_x_s16 : The value of gyro x data
+ *
+ * @note Gyro Configuration use the following function
+ * @note bmi160_set_gyro_output_data_rate()
+ * @note bmi160_set_gyro_bw()
+ * @note bmi160_set_gyro_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_gyro_x(s16 *v_gyro_x_s16)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* Array contains the gyro X lSB and MSB data
+ v_data_u8[0] - LSB
+ v_data_u8[MSB_ONE] - MSB*/
+ u8 v_data_u8[BMI160_GYRO_X_DATA_SIZE] = {BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE};
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_DATA_8_GYRO_X_LSB__REG,
+ v_data_u8, BMI160_GYRO_DATA_LENGTH);
+
+ *v_gyro_x_s16 = (s16)
+ ((((s32)((s8)v_data_u8[BMI160_GYRO_X_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (v_data_u8[BMI160_GYRO_X_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads gyro data Y values
+ * form the register 0x0E and 0x0F
+ *
+ *
+ *
+ *
+ * @param v_gyro_y_s16 : The value of gyro y data
+ *
+ * @note Gyro Configuration use the following function
+ * @note bmi160_set_gyro_output_data_rate()
+ * @note bmi160_set_gyro_bw()
+ * @note bmi160_set_gyro_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error result of communication routines
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_gyro_y(s16 *v_gyro_y_s16)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* Array contains the gyro Y lSB and MSB data
+ v_data_u8[LSB_ZERO] - LSB
+ v_data_u8[MSB_ONE] - MSB*/
+ u8 v_data_u8[BMI160_GYRO_Y_DATA_SIZE] = {BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE};
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read gyro y data*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_DATA_10_GYRO_Y_LSB__REG,
+ v_data_u8, BMI160_GYRO_DATA_LENGTH);
+
+ *v_gyro_y_s16 = (s16)
+ ((((s32)((s8)v_data_u8[BMI160_GYRO_Y_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (v_data_u8[BMI160_GYRO_Y_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads gyro data Z values
+ * form the register 0x10 and 0x11
+ *
+ *
+ *
+ *
+ * @param v_gyro_z_s16 : The value of gyro z data
+ *
+ * @note Gyro Configuration use the following function
+ * @note bmi160_set_gyro_output_data_rate()
+ * @note bmi160_set_gyro_bw()
+ * @note bmi160_set_gyro_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_gyro_z(s16 *v_gyro_z_s16)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* Array contains the gyro Z lSB and MSB data
+ v_data_u8[LSB_ZERO] - LSB
+ v_data_u8[MSB_ONE] - MSB*/
+ u8 v_data_u8[BMI160_GYRO_Z_DATA_SIZE] = {BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE};
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read gyro z data */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_DATA_12_GYRO_Z_LSB__REG,
+ v_data_u8, BMI160_GYRO_DATA_LENGTH);
+
+ *v_gyro_z_s16 = (s16)
+ ((((s32)((s8)v_data_u8[BMI160_GYRO_Z_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (v_data_u8[BMI160_GYRO_Z_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads gyro data X,Y,Z values
+ * from the register 0x0C to 0x11
+ *
+ *
+ *
+ *
+ * @param gyro : The value of gyro xyz
+ *
+ * @note Gyro Configuration use the following function
+ * @note bmi160_set_gyro_output_data_rate()
+ * @note bmi160_set_gyro_bw()
+ * @note bmi160_set_gyro_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_gyro_xyz(struct bmi160_gyro_t *gyro)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* Array contains the mag XYZ lSB and MSB data
+ v_data_u8[0] - X-LSB
+ v_data_u8[1] - X-MSB
+ v_data_u8[0] - Y-LSB
+ v_data_u8[1] - Y-MSB
+ v_data_u8[0] - Z-LSB
+ v_data_u8[1] - Z-MSB
+ */
+ u8 v_data_u8[BMI160_GYRO_XYZ_DATA_SIZE] = {
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE};
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the gyro xyz data*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_DATA_8_GYRO_X_LSB__REG,
+ v_data_u8, BMI160_GYRO_XYZ_DATA_LENGTH);
+
+ /* Data X */
+ gyro->x = (s16)
+ ((((s32)((s8)v_data_u8[
+ BMI160_DATA_FRAME_GYRO_X_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (v_data_u8[BMI160_DATA_FRAME_GYRO_X_LSB_BYTE]));
+ /* Data Y */
+ gyro->y = (s16)
+ ((((s32)((s8)v_data_u8[
+ BMI160_DATA_FRAME_GYRO_Y_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (v_data_u8[BMI160_DATA_FRAME_GYRO_Y_LSB_BYTE]));
+
+ /* Data Z */
+ gyro->z = (s16)
+ ((((s32)((s8)v_data_u8[
+ BMI160_DATA_FRAME_GYRO_Z_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (v_data_u8[BMI160_DATA_FRAME_GYRO_Z_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads accelerometer data X values
+ * form the register 0x12 and 0x13
+ *
+ *
+ *
+ *
+ * @param v_accel_x_s16 : The value of accel x
+ *
+ * @note For accel configuration use the following functions
+ * @note bmi160_set_accel_output_data_rate()
+ * @note bmi160_set_accel_bw()
+ * @note bmi160_set_accel_under_sampling_parameter()
+ * @note bmi160_set_accel_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_accel_x(s16 *v_accel_x_s16)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* Array contains the accel X lSB and MSB data
+ v_data_u8[0] - LSB
+ v_data_u8[1] - MSB*/
+ u8 v_data_u8[BMI160_ACCEL_X_DATA_SIZE] = {BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE};
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_DATA_14_ACCEL_X_LSB__REG,
+ v_data_u8, BMI160_ACCEL_DATA_LENGTH);
+
+ *v_accel_x_s16 = (s16)
+ ((((s32)((s8)v_data_u8[BMI160_ACCEL_X_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (v_data_u8[BMI160_ACCEL_X_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads accelerometer data Y values
+ * form the register 0x14 and 0x15
+ *
+ *
+ *
+ *
+ * @param v_accel_y_s16 : The value of accel y
+ *
+ * @note For accel configuration use the following functions
+ * @note bmi160_set_accel_output_data_rate()
+ * @note bmi160_set_accel_bw()
+ * @note bmi160_set_accel_under_sampling_parameter()
+ * @note bmi160_set_accel_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_accel_y(s16 *v_accel_y_s16)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* Array contains the accel Y lSB and MSB data
+ v_data_u8[0] - LSB
+ v_data_u8[1] - MSB*/
+ u8 v_data_u8[BMI160_ACCEL_Y_DATA_SIZE] = {BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE};
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_DATA_16_ACCEL_Y_LSB__REG,
+ v_data_u8, BMI160_ACCEL_DATA_LENGTH);
+
+ *v_accel_y_s16 = (s16)
+ ((((s32)((s8)v_data_u8[BMI160_ACCEL_Y_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (v_data_u8[BMI160_ACCEL_Y_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads accelerometer data Z values
+ * form the register 0x16 and 0x17
+ *
+ *
+ *
+ *
+ * @param v_accel_z_s16 : The value of accel z
+ *
+ * @note For accel configuration use the following functions
+ * @note bmi160_set_accel_output_data_rate()
+ * @note bmi160_set_accel_bw()
+ * @note bmi160_set_accel_under_sampling_parameter()
+ * @note bmi160_set_accel_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_accel_z(s16 *v_accel_z_s16)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* Array contains the accel Z lSB and MSB data
+ a_data_u8r[LSB_ZERO] - LSB
+ a_data_u8r[MSB_ONE] - MSB*/
+ u8 a_data_u8r[BMI160_ACCEL_Z_DATA_SIZE] = {
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE};
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_DATA_18_ACCEL_Z_LSB__REG,
+ a_data_u8r, BMI160_ACCEL_DATA_LENGTH);
+
+ *v_accel_z_s16 = (s16)
+ ((((s32)((s8)a_data_u8r[BMI160_ACCEL_Z_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (a_data_u8r[BMI160_ACCEL_Z_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads accelerometer data X,Y,Z values
+ * from the register 0x12 to 0x17
+ *
+ *
+ *
+ *
+ * @param accel :The value of accel xyz
+ *
+ * @note For accel configuration use the following functions
+ * @note bmi160_set_accel_output_data_rate()
+ * @note bmi160_set_accel_bw()
+ * @note bmi160_set_accel_under_sampling_parameter()
+ * @note bmi160_set_accel_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_accel_xyz(
+struct bmi160_accel_t *accel)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* Array contains the accel XYZ lSB and MSB data
+ a_data_u8r[0] - X-LSB
+ a_data_u8r[1] - X-MSB
+ a_data_u8r[0] - Y-LSB
+ a_data_u8r[1] - Y-MSB
+ a_data_u8r[0] - Z-LSB
+ a_data_u8r[1] - Z-MSB
+ */
+ u8 a_data_u8r[BMI160_ACCEL_XYZ_DATA_SIZE] = {
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE};
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_DATA_14_ACCEL_X_LSB__REG,
+ a_data_u8r, BMI160_ACCEL_XYZ_DATA_LENGTH);
+
+ /* Data X */
+ accel->x = (s16)
+ ((((s32)((s8)a_data_u8r[
+ BMI160_DATA_FRAME_ACCEL_X_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (a_data_u8r[BMI160_DATA_FRAME_ACCEL_X_LSB_BYTE]));
+ /* Data Y */
+ accel->y = (s16)
+ ((((s32)((s8)a_data_u8r[
+ BMI160_DATA_FRAME_ACCEL_Y_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (a_data_u8r[BMI160_DATA_FRAME_ACCEL_Y_LSB_BYTE]));
+
+ /* Data Z */
+ accel->z = (s16)
+ ((((s32)((s8)a_data_u8r[
+ BMI160_DATA_FRAME_ACCEL_Z_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (a_data_u8r[BMI160_DATA_FRAME_ACCEL_Z_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads sensor_time from the register
+ * 0x18 to 0x1A
+ *
+ *
+ * @param v_sensor_time_u32 : The value of sensor time
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_sensor_time(u32 *v_sensor_time_u32)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* Array contains the sensor time it is 32 bit data
+ a_data_u8r[0] - sensor time
+ a_data_u8r[1] - sensor time
+ a_data_u8r[0] - sensor time
+ */
+ u8 a_data_u8r[BMI160_SENSOR_TIME_DATA_SIZE] = {BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE};
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_SENSORTIME_0_SENSOR_TIME_LSB__REG,
+ a_data_u8r, BMI160_SENSOR_TIME_LENGTH);
+
+ *v_sensor_time_u32 = (u32)
+ ((((u32)a_data_u8r[BMI160_SENSOR_TIME_MSB_BYTE])
+ << BMI160_SHIFT_BIT_POSITION_BY_16_BITS)
+ |(((u32)a_data_u8r[BMI160_SENSOR_TIME_XLSB_BYTE])
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (a_data_u8r[BMI160_SENSOR_TIME_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the Gyroscope self test
+ * status from the register 0x1B bit 1
+ *
+ *
+ * @param v_gyro_selftest_u8 : The value of gyro self test status
+ * value | status
+ * ---------|----------------
+ * 0 | Gyroscope self test is running or failed
+ * 1 | Gyroscope self test completed successfully
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_selftest(u8
+*v_gyro_selftest_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_STAT_GYRO_SELFTEST_OK__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_gyro_selftest_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_STAT_GYRO_SELFTEST_OK);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the status of
+ * mag manual interface operation form the register 0x1B bit 2
+ *
+ *
+ *
+ * @param v_mag_manual_stat_u8 : The value of mag manual operation status
+ * value | status
+ * ---------|----------------
+ * 0 | Indicates no manual magnetometer
+ * - | interface operation is ongoing
+ * 1 | Indicates manual magnetometer
+ * - | interface operation is ongoing
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_manual_operation_stat(u8
+*v_mag_manual_stat_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read manual operation*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_STAT_MAG_MANUAL_OPERATION__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_mag_manual_stat_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_STAT_MAG_MANUAL_OPERATION);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the fast offset compensation
+ * status form the register 0x1B bit 3
+ *
+ *
+ * @param v_foc_rdy_u8 : The status of fast compensation
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_foc_rdy(u8
+*v_foc_rdy_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the FOC status*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_STAT_FOC_RDY__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_foc_rdy_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_STAT_FOC_RDY);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API Reads the nvm_rdy status from the
+ * resister 0x1B bit 4
+ *
+ *
+ * @param v_nvm_rdy_u8 : The value of NVM ready status
+ * value | status
+ * ---------|----------------
+ * 0 | NVM write operation in progress
+ * 1 | NVM is ready to accept a new write trigger
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_nvm_rdy(u8
+*v_nvm_rdy_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the nvm ready status*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_STAT_NVM_RDY__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_nvm_rdy_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_STAT_NVM_RDY);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the status of mag data ready
+ * from the register 0x1B bit 5
+ * The status get reset when one mag data register is read out
+ *
+ * @param v_data_rdy_u8 : The value of mag data ready status
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_data_rdy_mag(u8
+*v_data_rdy_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_STAT_DATA_RDY_MAG__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_data_rdy_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_STAT_DATA_RDY_MAG);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the status of gyro data ready form the
+ * register 0x1B bit 6
+ * The status get reset when gyro data register read out
+ *
+ *
+ * @param v_data_rdy_u8 : The value of gyro data ready
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_data_rdy(u8
+*v_data_rdy_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_STAT_DATA_RDY_GYRO__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_data_rdy_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_STAT_DATA_RDY_GYRO);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the status of accel data ready form the
+ * register 0x1B bit 7
+ * The status get reset when accel data register read out
+ *
+ *
+ * @param v_data_rdy_u8 : The value of accel data ready status
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_data_rdy(u8
+*v_data_rdy_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /*reads the status of accel data ready*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_STAT_DATA_RDY_ACCEL__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_data_rdy_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_STAT_DATA_RDY_ACCEL);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the step detector interrupt status
+ * from the register 0x1C bit 0
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_step_intr_u8 : The status of step detector interrupt
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_step_intr(u8
+*v_step_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_INTR_STAT_0_STEP_INTR__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_step_intr_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_STAT_0_STEP_INTR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the
+ * significant motion interrupt status
+ * from the register 0x1C bit 1
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ *
+ * @param v_significant_intr_u8 : The status of step
+ * motion interrupt
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_significant_intr(u8
+*v_significant_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_INTR_STAT_0_SIGNIFICANT_INTR__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_significant_intr_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_STAT_0_SIGNIFICANT_INTR);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API reads the any motion interrupt status
+ * from the register 0x1C bit 2
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ * @param v_any_motion_intr_u8 : The status of any-motion interrupt
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_any_motion_intr(u8
+*v_any_motion_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_INTR_STAT_0_ANY_MOTION__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_any_motion_intr_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_STAT_0_ANY_MOTION);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the power mode trigger interrupt status
+ * from the register 0x1C bit 3
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ *
+ * @param v_pmu_trigger_intr_u8 : The status of power mode trigger interrupt
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_pmu_trigger_intr(u8
+*v_pmu_trigger_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_INTR_STAT_0_PMU_TRIGGER__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_pmu_trigger_intr_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_STAT_0_PMU_TRIGGER);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the double tab status
+ * from the register 0x1C bit 4
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_double_tap_intr_u8 :The status of double tab interrupt
+ *
+ * @note Double tap interrupt can be configured by the following functions
+ * @note INTERRUPT MAPPING
+ * @note bmi160_set_intr_double_tap()
+ * @note AXIS MAPPING
+ * @note bmi160_get_stat2_tap_first_x()
+ * @note bmi160_get_stat2_tap_first_y()
+ * @note bmi160_get_stat2_tap_first_z()
+ * @note DURATION
+ * @note bmi160_set_intr_tap_durn()
+ * @note THRESHOLD
+ * @note bmi160_set_intr_tap_thres()
+ * @note TAP QUIET
+ * @note bmi160_set_intr_tap_quiet()
+ * @note TAP SHOCK
+ * @note bmi160_set_intr_tap_shock()
+ * @note TAP SOURCE
+ * @note bmi160_set_intr_tap_source()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_double_tap_intr(u8
+*v_double_tap_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_INTR_STAT_0_DOUBLE_TAP_INTR__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_double_tap_intr_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_STAT_0_DOUBLE_TAP_INTR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the single tab status
+ * from the register 0x1C bit 5
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_single_tap_intr_u8 :The status of single tap interrupt
+ *
+ * @note Single tap interrupt can be configured by the following functions
+ * @note INTERRUPT MAPPING
+ * @note bmi160_set_intr_single_tap()
+ * @note AXIS MAPPING
+ * @note bmi160_get_stat2_tap_first_x()
+ * @note bmi160_get_stat2_tap_first_y()
+ * @note bmi160_get_stat2_tap_first_z()
+ * @note DURATION
+ * @note bmi160_set_intr_tap_durn()
+ * @note THRESHOLD
+ * @note bmi160_set_intr_tap_thres()
+ * @note TAP QUIET
+ * @note bmi160_set_intr_tap_quiet()
+ * @note TAP SHOCK
+ * @note bmi160_set_intr_tap_shock()
+ * @note TAP SOURCE
+ * @note bmi160_set_intr_tap_source()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_single_tap_intr(u8
+*v_single_tap_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_INTR_STAT_0_SINGLE_TAP_INTR__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_single_tap_intr_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_STAT_0_SINGLE_TAP_INTR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the orient status
+ * from the register 0x1C bit 6
+ * flag is associated with a specific interrupt function.
+ * It is set when the orient interrupt triggers. The
+ * setting of INT_LATCH controls if the
+ * interrupt signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_orient_intr_u8 : The status of orient interrupt
+ *
+ * @note For orient interrupt configuration use the following functions
+ * @note STATUS
+ * @note bmi160_get_stat0_orient_intr()
+ * @note AXIS MAPPING
+ * @note bmi160_get_stat3_orient_xy()
+ * @note bmi160_get_stat3_orient_z()
+ * @note bmi160_set_intr_orient_axes_enable()
+ * @note INTERRUPT MAPPING
+ * @note bmi160_set_intr_orient()
+ * @note INTERRUPT OUTPUT
+ * @note bmi160_set_intr_orient_ud_enable()
+ * @note THETA
+ * @note bmi160_set_intr_orient_theta()
+ * @note HYSTERESIS
+ * @note bmi160_set_intr_orient_hyst()
+ * @note BLOCKING
+ * @note bmi160_set_intr_orient_blocking()
+ * @note MODE
+ * @note bmi160_set_intr_orient_mode()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_orient_intr(u8
+*v_orient_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_INTR_STAT_0_ORIENT__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_orient_intr_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_STAT_0_ORIENT);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the flat interrupt status
+ * from the register 0x1C bit 7
+ * flag is associated with a specific interrupt function.
+ * It is set when the flat interrupt triggers. The
+ * setting of INT_LATCH controls if the
+ * interrupt signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_flat_intr_u8 : The status of flat interrupt
+ *
+ * @note For flat configuration use the following functions
+ * @note STATS
+ * @note bmi160_get_stat0_flat_intr()
+ * @note bmi160_get_stat3_flat()
+ * @note INTERRUPT MAPPING
+ * @note bmi160_set_intr_flat()
+ * @note THETA
+ * @note bmi160_set_intr_flat_theta()
+ * @note HOLD TIME
+ * @note bmi160_set_intr_flat_hold()
+ * @note HYSTERESIS
+ * @note bmi160_set_intr_flat_hyst()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_flat_intr(u8
+*v_flat_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_INTR_STAT_0_FLAT__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_flat_intr_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_STAT_0_FLAT);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the high_g interrupt status
+ * from the register 0x1D bit 2
+ * flag is associated with a specific interrupt function.
+ * It is set when the high g interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt signal and hence the
+ * respective interrupt flag will be permanently
+ * latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_high_g_intr_u8 : The status of high_g interrupt
+ *
+ * @note High_g interrupt configured by following functions
+ * @note STATUS
+ * @note bmi160_get_stat1_high_g_intr()
+ * @note AXIS MAPPING
+ * @note bmi160_get_stat3_high_g_first_x()
+ * @note bmi160_get_stat3_high_g_first_y()
+ * @note bmi160_get_stat3_high_g_first_z()
+ * @note SIGN MAPPING
+ * @note bmi160_get_stat3_high_g_first_sign()
+ * @note INTERRUPT MAPPING
+ * @note bmi160_set_intr_high_g()
+ * @note HYSTERESIS
+ * @note bmi160_set_intr_high_g_hyst()
+ * @note DURATION
+ * @note bmi160_set_intr_high_g_durn()
+ * @note THRESHOLD
+ * @note bmi160_set_intr_high_g_thres()
+ * @note SOURCE
+ * @note bmi160_set_intr_low_high_source()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat1_high_g_intr(u8
+*v_high_g_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_INTR_STAT_1_HIGH_G_INTR__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_high_g_intr_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_STAT_1_HIGH_G_INTR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the low g interrupt status
+ * from the register 0x1D bit 3
+ * flag is associated with a specific interrupt function.
+ * It is set when the low g interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_low_g_intr_u8 : The status of low_g interrupt
+ *
+ * @note Low_g interrupt configured by following functions
+ * @note STATUS
+ * @note bmi160_get_stat1_low_g_intr()
+ * @note INTERRUPT MAPPING
+ * @note bmi160_set_intr_low_g()
+ * @note SOURCE
+ * @note bmi160_set_intr_low_high_source()
+ * @note DURATION
+ * @note bmi160_set_intr_low_g_durn()
+ * @note THRESHOLD
+ * @note bmi160_set_intr_low_g_thres()
+ * @note HYSTERESIS
+ * @note bmi160_set_intr_low_g_hyst()
+ * @note MODE
+ * @note bmi160_set_intr_low_g_mode()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat1_low_g_intr(u8
+*v_low_g_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_INTR_STAT_1_LOW_G_INTR__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_low_g_intr_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_STAT_1_LOW_G_INTR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads data ready interrupt status
+ * from the register 0x1D bit 4
+ * flag is associated with a specific interrupt function.
+ * It is set when the data ready interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_data_rdy_intr_u8 : The status of data ready interrupt
+ *
+ * @note Data ready interrupt configured by following functions
+ * @note STATUS
+ * @note bmi160_get_stat1_data_rdy_intr()
+ * @note INTERRUPT MAPPING
+ * @note bmi160_set_intr_data_rdy()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat1_data_rdy_intr(u8
+*v_data_rdy_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_INTR_STAT_1_DATA_RDY_INTR__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_data_rdy_intr_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_STAT_1_DATA_RDY_INTR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads data ready FIFO full interrupt status
+ * from the register 0x1D bit 5
+ * flag is associated with a specific interrupt function.
+ * It is set when the FIFO full interrupt triggers. The
+ * setting of INT_LATCH controls if the
+ * interrupt signal and hence the
+ * respective interrupt flag will
+ * be permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_fifo_full_intr_u8 : The status of fifo full interrupt
+ *
+ * @note FIFO full interrupt can be configured by following functions
+ * @note bmi160_set_intr_fifo_full()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat1_fifo_full_intr(u8
+*v_fifo_full_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_INTR_STAT_1_FIFO_FULL_INTR__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_full_intr_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_STAT_1_FIFO_FULL_INTR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads data
+ * ready FIFO watermark interrupt status
+ * from the register 0x1D bit 6
+ * flag is associated with a specific interrupt function.
+ * It is set when the FIFO watermark interrupt triggers. The
+ * setting of INT_LATCH controls if the
+ * interrupt signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_fifo_wm_intr_u8 : The status of fifo water mark interrupt
+ *
+ * @note FIFO full interrupt can be configured by following functions
+ * @note bmi160_set_intr_fifo_wm()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat1_fifo_wm_intr(u8
+*v_fifo_wm_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_INTR_STAT_1_FIFO_WM_INTR__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_wm_intr_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_STAT_1_FIFO_WM_INTR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads data ready no motion interrupt status
+ * from the register 0x1D bit 7
+ * flag is associated with a specific interrupt function.
+ * It is set when the no motion interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt signal and hence the
+ * respective interrupt flag will be permanently
+ * latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_nomotion_intr_u8 : The status of no motion interrupt
+ *
+ * @note No motion interrupt can be configured by following function
+ * @note STATUS
+ * @note bmi160_get_stat1_nomotion_intr()
+ * @note INTERRUPT MAPPING
+ * @note bmi160_set_intr_nomotion()
+ * @note DURATION
+ * @note bmi160_set_intr_slow_no_motion_durn()
+ * @note THRESHOLD
+ * @note bmi160_set_intr_slow_no_motion_thres()
+ * @note SLOW/NO MOTION SELECT
+ * @note bmi160_set_intr_slow_no_motion_select()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat1_nomotion_intr(u8
+*v_nomotion_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the no motion interrupt*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_INTR_STAT_1_NOMOTION_INTR__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_nomotion_intr_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_STAT_1_NOMOTION_INTR);
+ }
+ return com_rslt;
+}
+/*!
+ *@brief This API reads the status of any motion first x
+ * from the register 0x1E bit 0
+ *
+ *
+ *@param v_anymotion_first_x_u8 : The status of any motion first x interrupt
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by x axis
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_any_motion_first_x(u8
+*v_anymotion_first_x_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the any motion first x interrupt*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_X__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_anymotion_first_x_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_X);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the status of any motion first y interrupt
+ * from the register 0x1E bit 1
+ *
+ *
+ *
+ *@param v_any_motion_first_y_u8 : The status of any motion first y interrupt
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_any_motion_first_y(u8
+*v_any_motion_first_y_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the any motion first y interrupt*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_Y__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_any_motion_first_y_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_Y);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the status of any motion first z interrupt
+ * from the register 0x1E bit 2
+ *
+ *
+ *
+ *
+ *@param v_any_motion_first_z_u8 : The status of any motion first z interrupt
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_any_motion_first_z(u8
+*v_any_motion_first_z_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the any motion first z interrupt*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_Z__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_any_motion_first_z_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_Z);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the any motion sign status from the
+ * register 0x1E bit 3
+ *
+ *
+ *
+ *
+ * @param v_anymotion_sign_u8 : The status of any motion sign
+ * value | sign
+ * -----------|-------------
+ * 0 | positive
+ * 1 | negative
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_any_motion_sign(u8
+*v_anymotion_sign_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read any motion sign interrupt status */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_INTR_STAT_2_ANY_MOTION_SIGN__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_anymotion_sign_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_STAT_2_ANY_MOTION_SIGN);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the any motion tap first x status from the
+ * register 0x1E bit 4
+ *
+ *
+ *
+ *
+ * @param v_tap_first_x_u8 :The status of any motion tap first x
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by x axis
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_tap_first_x(u8
+*v_tap_first_x_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read tap first x interrupt status */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_INTR_STAT_2_TAP_FIRST_X__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_tap_first_x_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_STAT_2_TAP_FIRST_X);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the tap first y interrupt status from the
+ * register 0x1E bit 5
+ *
+ *
+ *
+ *
+ * @param v_tap_first_y_u8 :The status of tap first y interrupt
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_tap_first_y(u8
+*v_tap_first_y_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read tap first y interrupt status */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_INTR_STAT_2_TAP_FIRST_Y__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_tap_first_y_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_STAT_2_TAP_FIRST_Y);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the tap first z interrupt status from the
+ * register 0x1E bit 6
+ *
+ *
+ *
+ *
+ * @param v_tap_first_z_u8 :The status of tap first z interrupt
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_tap_first_z(u8
+*v_tap_first_z_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read tap first z interrupt status */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_INTR_STAT_2_TAP_FIRST_Z__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_tap_first_z_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_STAT_2_TAP_FIRST_Z);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the tap sign status from the
+ * register 0x1E bit 7
+ *
+ *
+ *
+ *
+ * @param v_tap_sign_u8 : The status of tap sign
+ * value | sign
+ * -----------|-------------
+ * 0 | positive
+ * 1 | negative
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_tap_sign(u8
+*v_tap_sign_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read tap_sign interrupt status */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_INTR_STAT_2_TAP_SIGN__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_tap_sign_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_STAT_2_TAP_SIGN);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the high_g first x status from the
+ * register 0x1F bit 0
+ *
+ *
+ *
+ *
+ * @param v_high_g_first_x_u8 :The status of high_g first x
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by x axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat3_high_g_first_x(u8
+*v_high_g_first_x_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read highg_x interrupt status */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_X__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_high_g_first_x_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_X);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the high_g first y status from the
+ * register 0x1F bit 1
+ *
+ *
+ *
+ *
+ * @param v_high_g_first_y_u8 : The status of high_g first y
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat3_high_g_first_y(u8
+*v_high_g_first_y_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read highg_y interrupt status */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_Y__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_high_g_first_y_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_Y);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the high_g first z status from the
+ * register 0x1F bit 3
+ *
+ *
+ *
+ *
+ * @param v_high_g_first_z_u8 : The status of high_g first z
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat3_high_g_first_z(u8
+*v_high_g_first_z_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read highg_z interrupt status */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_Z__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_high_g_first_z_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_Z);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the high sign status from the
+ * register 0x1F bit 3
+ *
+ *
+ *
+ *
+ * @param v_high_g_sign_u8 :The status of high sign
+ * value | sign
+ * -----------|-------------
+ * 0 | positive
+ * 1 | negative
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat3_high_g_sign(u8
+*v_high_g_sign_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read highg_sign interrupt status */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_INTR_STAT_3_HIGH_G_SIGN__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_high_g_sign_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_STAT_3_HIGH_G_SIGN);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the status of orient_xy plane
+ * from the register 0x1F bit 4 and 5
+ *
+ *
+ * @param v_orient_xy_u8 :The status of orient_xy plane
+ * value | status
+ * -----------|-------------
+ * 0x00 | portrait upright
+ * 0x01 | portrait upside down
+ * 0x02 | landscape left
+ * 0x03 | landscape right
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat3_orient_xy(u8
+*v_orient_xy_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read orient plane xy interrupt status */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_INTR_STAT_3_ORIENT_XY__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_orient_xy_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_STAT_3_ORIENT_XY);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the status of orient z plane
+ * from the register 0x1F bit 6
+ *
+ *
+ * @param v_orient_z_u8 :The status of orient z
+ * value | status
+ * -----------|-------------
+ * 0x00 | upward looking
+ * 0x01 | downward looking
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat3_orient_z(u8
+*v_orient_z_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read orient z plane interrupt status */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_INTR_STAT_3_ORIENT_Z__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_orient_z_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_STAT_3_ORIENT_Z);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the flat status from the register
+ * 0x1F bit 7
+ *
+ *
+ * @param v_flat_u8 : The status of flat interrupt
+ * value | status
+ * -----------|-------------
+ * 0x00 | non flat
+ * 0x01 | flat position
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat3_flat(u8
+*v_flat_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read flat interrupt status */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_INTR_STAT_3_FLAT__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_flat_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_STAT_3_FLAT);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the temperature of the sensor
+ * from the register 0x21 bit 0 to 7
+ *
+ *
+ *
+ * @param v_temp_s16 : The value of temperature
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_temp(s16
+*v_temp_s16)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* Array contains the temperature lSB and MSB data
+ v_data_u8[0] - LSB
+ v_data_u8[1] - MSB*/
+ u8 v_data_u8[BMI160_TEMP_DATA_SIZE] = {BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE};
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read temperature data */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_TEMP_LSB_VALUE__REG, v_data_u8,
+ BMI160_TEMP_DATA_LENGTH);
+ *v_temp_s16 =
+ (s16)(((s32)((s8) (v_data_u8[BMI160_TEMP_MSB_BYTE]) <<
+ BMI160_SHIFT_BIT_POSITION_BY_08_BITS))
+ | v_data_u8[BMI160_TEMP_LSB_BYTE]);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the of the sensor
+ * form the register 0x23 and 0x24 bit 0 to 7 and 0 to 2
+ * @brief this byte counter is updated each time a complete frame
+ * was read or writtern
+ *
+ *
+ * @param v_fifo_length_u32 : The value of fifo byte counter
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_fifo_length(u32 *v_fifo_length_u32)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* Array contains the fifo length data
+ v_data_u8[0] - fifo length
+ v_data_u8[1] - fifo length*/
+ u8 a_data_u8r[BMI160_FIFO_DATA_SIZE] = {BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE};
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read fifo length*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_FIFO_BYTE_COUNTER_LSB__REG, a_data_u8r,
+ BMI160_FIFO_DATA_LENGTH);
+
+ a_data_u8r[BMI160_FIFO_LENGTH_MSB_BYTE] =
+ BMI160_GET_BITSLICE(
+ a_data_u8r[BMI160_FIFO_LENGTH_MSB_BYTE],
+ BMI160_USER_FIFO_BYTE_COUNTER_MSB);
+
+ *v_fifo_length_u32 =
+ (u32)(((u32)((u8) (
+ a_data_u8r[BMI160_FIFO_LENGTH_MSB_BYTE]) <<
+ BMI160_SHIFT_BIT_POSITION_BY_08_BITS))
+ | a_data_u8r[BMI160_FIFO_LENGTH_LSB_BYTE]);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the fifo data of the sensor
+ * from the register 0x24
+ * @brief Data format depends on the setting of register FIFO_CONFIG
+ *
+ *
+ *
+ * @param v_fifodata_u8 : Pointer holding the fifo data
+ * @param fifo_length_u16 : The value of fifo length maximum
+ * 1024
+ *
+ * @note For reading FIFO data use the following functions
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_fifo_data(
+u8 *v_fifodata_u8, u16 v_fifo_length_u16)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read fifo data*/
+ com_rslt =
+ p_bmi160->BMI160_BURST_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_FIFO_DATA__REG,
+ v_fifodata_u8, v_fifo_length_u16);
+
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to get the
+ * accel output date rate form the register 0x40 bit 0 to 3
+ *
+ *
+ * @param v_output_data_rate_u8 :The value of accel output date rate
+ * value | output data rate
+ * -------|--------------------------
+ * 0 | BMI160_ACCEL_OUTPUT_DATA_RATE_RESERVED
+ * 1 | BMI160_ACCEL_OUTPUT_DATA_RATE_0_78HZ
+ * 2 | BMI160_ACCEL_OUTPUT_DATA_RATE_1_56HZ
+ * 3 | BMI160_ACCEL_OUTPUT_DATA_RATE_3_12HZ
+ * 4 | BMI160_ACCEL_OUTPUT_DATA_RATE_6_25HZ
+ * 5 | BMI160_ACCEL_OUTPUT_DATA_RATE_12_5HZ
+ * 6 | BMI160_ACCEL_OUTPUT_DATA_RATE_25HZ
+ * 7 | BMI160_ACCEL_OUTPUT_DATA_RATE_50HZ
+ * 8 | BMI160_ACCEL_OUTPUT_DATA_RATE_100HZ
+ * 9 | BMI160_ACCEL_OUTPUT_DATA_RATE_200HZ
+ * 10 | BMI160_ACCEL_OUTPUT_DATA_RATE_400HZ
+ * 11 | BMI160_ACCEL_OUTPUT_DATA_RATE_800HZ
+ * 12 | BMI160_ACCEL_OUTPUT_DATA_RATE_1600HZ
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_output_data_rate(
+u8 *v_output_data_rate_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the accel output data rate*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_output_data_rate_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set the
+ * accel output date rate form the register 0x40 bit 0 to 3
+ *
+ *
+ * @param v_output_data_rate_u8 :The value of accel output date rate
+ * value | output data rate
+ * -------|--------------------------
+ * 0 | BMI160_ACCEL_OUTPUT_DATA_RATE_RESERVED
+ * 1 | BMI160_ACCEL_OUTPUT_DATA_RATE_0_78HZ
+ * 2 | BMI160_ACCEL_OUTPUT_DATA_RATE_1_56HZ
+ * 3 | BMI160_ACCEL_OUTPUT_DATA_RATE_3_12HZ
+ * 4 | BMI160_ACCEL_OUTPUT_DATA_RATE_6_25HZ
+ * 5 | BMI160_ACCEL_OUTPUT_DATA_RATE_12_5HZ
+ * 6 | BMI160_ACCEL_OUTPUT_DATA_RATE_25HZ
+ * 7 | BMI160_ACCEL_OUTPUT_DATA_RATE_50HZ
+ * 8 | BMI160_ACCEL_OUTPUT_DATA_RATE_100HZ
+ * 9 | BMI160_ACCEL_OUTPUT_DATA_RATE_200HZ
+ * 10 | BMI160_ACCEL_OUTPUT_DATA_RATE_400HZ
+ * 11 | BMI160_ACCEL_OUTPUT_DATA_RATE_800HZ
+ * 12 | BMI160_ACCEL_OUTPUT_DATA_RATE_1600HZ
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_output_data_rate(
+u8 v_output_data_rate_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* accel output data rate selection */
+ if ((v_output_data_rate_u8 != BMI160_INIT_VALUE) &&
+ (v_output_data_rate_u8 <= BMI160_MAX_ACCEL_OUTPUT_DATA_RATE)) {
+ /* write accel output data rate */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE,
+ v_output_data_rate_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to get the
+ * accel bandwidth from the register 0x40 bit 4 to 6
+ * @brief bandwidth parameter determines filter configuration(acc_us=0)
+ * and averaging for under sampling mode(acc_us=1)
+ *
+ *
+ * @param v_bw_u8 : The value of accel bandwidth
+ *
+ * @note accel bandwidth depends on under sampling parameter
+ * @note under sampling parameter cab be set by the function
+ * "BMI160_SET_ACCEL_UNDER_SAMPLING_PARAMETER"
+ *
+ * @note Filter configuration
+ * accel_us | Filter configuration
+ * -----------|---------------------
+ * 0x00 | OSR4 mode
+ * 0x01 | OSR2 mode
+ * 0x02 | normal mode
+ * 0x03 | CIC mode
+ * 0x04 | Reserved
+ * 0x05 | Reserved
+ * 0x06 | Reserved
+ * 0x07 | Reserved
+ *
+ * @note accel under sampling mode
+ * accel_us | Under sampling mode
+ * -----------|---------------------
+ * 0x00 | no averaging
+ * 0x01 | average 2 samples
+ * 0x02 | average 4 samples
+ * 0x03 | average 8 samples
+ * 0x04 | average 16 samples
+ * 0x05 | average 32 samples
+ * 0x06 | average 64 samples
+ * 0x07 | average 128 samples
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_bw(u8 *v_bw_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the accel bandwidth */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_ACCEL_CONFIG_ACCEL_BW__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_bw_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_ACCEL_CONFIG_ACCEL_BW);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set the
+ * accel bandwidth from the register 0x40 bit 4 to 6
+ * @brief bandwidth parameter determines filter configuration(acc_us=0)
+ * and averaging for under sampling mode(acc_us=1)
+ *
+ *
+ * @param v_bw_u8 : The value of accel bandwidth
+ *
+ * @note accel bandwidth depends on under sampling parameter
+ * @note under sampling parameter cab be set by the function
+ * "BMI160_SET_ACCEL_UNDER_SAMPLING_PARAMETER"
+ *
+ * @note Filter configuration
+ * accel_us | Filter configuration
+ * -----------|---------------------
+ * 0x00 | OSR4 mode
+ * 0x01 | OSR2 mode
+ * 0x02 | normal mode
+ * 0x03 | CIC mode
+ * 0x04 | Reserved
+ * 0x05 | Reserved
+ * 0x06 | Reserved
+ * 0x07 | Reserved
+ *
+ * @note accel under sampling mode
+ * accel_us | Under sampling mode
+ * -----------|---------------------
+ * 0x00 | no averaging
+ * 0x01 | average 2 samples
+ * 0x02 | average 4 samples
+ * 0x03 | average 8 samples
+ * 0x04 | average 16 samples
+ * 0x05 | average 32 samples
+ * 0x06 | average 64 samples
+ * 0x07 | average 128 samples
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_bw(u8 v_bw_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* select accel bandwidth*/
+ if (v_bw_u8 <= BMI160_MAX_ACCEL_BW) {
+ /* write accel bandwidth*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_ACCEL_CONFIG_ACCEL_BW__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_ACCEL_CONFIG_ACCEL_BW,
+ v_bw_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_ACCEL_CONFIG_ACCEL_BW__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to get the accel
+ * under sampling parameter form the register 0x40 bit 7
+ *
+ *
+ *
+ *
+ * @param v_accel_under_sampling_u8 : The value of accel under sampling
+ * value | under_sampling
+ * ----------|---------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_under_sampling_parameter(
+u8 *v_accel_under_sampling_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the accel under sampling parameter */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_under_sampling_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set the accel
+ * under sampling parameter form the register 0x40 bit 7
+ *
+ *
+ *
+ *
+ * @param v_accel_under_sampling_u8 : The value of accel under sampling
+ * value | under_sampling
+ * ----------|---------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_under_sampling_parameter(
+u8 v_accel_under_sampling_u8)
+{
+/* variable used for return the status of communication result*/
+BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_accel_under_sampling_u8 <= BMI160_MAX_UNDER_SAMPLING) {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ /* write the accel under sampling parameter */
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING,
+ v_accel_under_sampling_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+}
+return com_rslt;
+}
+/*!
+ * @brief This API is used to get the ranges
+ * (g values) of the accel from the register 0x41 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_range_u8 : The value of accel g range
+ * value | g_range
+ * ----------|-----------
+ * 0x03 | BMI160_ACCEL_RANGE_2G
+ * 0x05 | BMI160_ACCEL_RANGE_4G
+ * 0x08 | BMI160_ACCEL_RANGE_8G
+ * 0x0C | BMI160_ACCEL_RANGE_16G
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_range(
+u8 *v_range_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the accel range*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_ACCEL_RANGE__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_range_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_ACCEL_RANGE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set the ranges
+ * (g values) of the accel from the register 0x41 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_range_u8 : The value of accel g range
+ * value | g_range
+ * ----------|-----------
+ * 0x03 | BMI160_ACCEL_RANGE_2G
+ * 0x05 | BMI160_ACCEL_RANGE_4G
+ * 0x08 | BMI160_ACCEL_RANGE_8G
+ * 0x0C | BMI160_ACCEL_RANGE_16G
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_range(u8 v_range_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if ((v_range_u8 == BMI160_ACCEL_RANGE0) ||
+ (v_range_u8 == BMI160_ACCEL_RANGE1) ||
+ (v_range_u8 == BMI160_ACCEL_RANGE3) ||
+ (v_range_u8 == BMI160_ACCEL_RANGE4)) {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_ACCEL_RANGE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(
+ v_data_u8, BMI160_USER_ACCEL_RANGE,
+ v_range_u8);
+ /* write the accel range*/
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_ACCEL_RANGE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to get the
+ * gyroscope output data rate from the register 0x42 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_output_data_rate_u8 :The value of gyro output data rate
+ * value | gyro output data rate
+ * -----------|-----------------------------
+ * 0x00 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x01 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x02 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x03 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x04 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x05 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x06 | BMI160_GYRO_OUTPUT_DATA_RATE_25HZ
+ * 0x07 | BMI160_GYRO_OUTPUT_DATA_RATE_50HZ
+ * 0x08 | BMI160_GYRO_OUTPUT_DATA_RATE_100HZ
+ * 0x09 | BMI160_GYRO_OUTPUT_DATA_RATE_200HZ
+ * 0x0A | BMI160_GYRO_OUTPUT_DATA_RATE_400HZ
+ * 0x0B | BMI160_GYRO_OUTPUT_DATA_RATE_800HZ
+ * 0x0C | BMI160_GYRO_OUTPUT_DATA_RATE_1600HZ
+ * 0x0D | BMI160_GYRO_OUTPUT_DATA_RATE_3200HZ
+ * 0x0E | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x0F | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_output_data_rate(
+u8 *v_output_data_rate_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the gyro output data rate*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_GYRO_CONFIG_OUTPUT_DATA_RATE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_output_data_rate_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_GYRO_CONFIG_OUTPUT_DATA_RATE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set the
+ * gyroscope output data rate from the register 0x42 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_output_data_rate_u8 :The value of gyro output data rate
+ * value | gyro output data rate
+ * -----------|-----------------------------
+ * 0x00 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x01 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x02 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x03 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x04 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x05 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x06 | BMI160_GYRO_OUTPUT_DATA_RATE_25HZ
+ * 0x07 | BMI160_GYRO_OUTPUT_DATA_RATE_50HZ
+ * 0x08 | BMI160_GYRO_OUTPUT_DATA_RATE_100HZ
+ * 0x09 | BMI160_GYRO_OUTPUT_DATA_RATE_200HZ
+ * 0x0A | BMI160_GYRO_OUTPUT_DATA_RATE_400HZ
+ * 0x0B | BMI160_GYRO_OUTPUT_DATA_RATE_800HZ
+ * 0x0C | BMI160_GYRO_OUTPUT_DATA_RATE_1600HZ
+ * 0x0D | BMI160_GYRO_OUTPUT_DATA_RATE_3200HZ
+ * 0x0E | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x0F | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_output_data_rate(
+u8 v_output_data_rate_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* select the gyro output data rate*/
+ if ((v_output_data_rate_u8 < BMI160_OUTPUT_DATA_RATE6) &&
+ (v_output_data_rate_u8 != BMI160_INIT_VALUE)
+ && (v_output_data_rate_u8 != BMI160_OUTPUT_DATA_RATE1)
+ && (v_output_data_rate_u8 != BMI160_OUTPUT_DATA_RATE2)
+ && (v_output_data_rate_u8 != BMI160_OUTPUT_DATA_RATE3)
+ && (v_output_data_rate_u8 != BMI160_OUTPUT_DATA_RATE4)
+ && (v_output_data_rate_u8 != BMI160_OUTPUT_DATA_RATE5)
+ && (v_output_data_rate_u8 != BMI160_OUTPUT_DATA_RATE6)
+ && (v_output_data_rate_u8 != BMI160_OUTPUT_DATA_RATE7)) {
+ /* write the gyro output data rate */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_GYRO_CONFIG_OUTPUT_DATA_RATE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_GYRO_CONFIG_OUTPUT_DATA_RATE,
+ v_output_data_rate_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_GYRO_CONFIG_OUTPUT_DATA_RATE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to get the
+ * data of gyro from the register 0x42 bit 4 to 5
+ *
+ *
+ *
+ *
+ * @param v_bw_u8 : The value of gyro bandwidth
+ * value | gyro bandwidth
+ * ----------|----------------
+ * 0x00 | BMI160_GYRO_OSR4_MODE
+ * 0x01 | BMI160_GYRO_OSR2_MODE
+ * 0x02 | BMI160_GYRO_NORMAL_MODE
+ * 0x03 | BMI160_GYRO_CIC_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_bw(u8 *v_bw_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read gyro bandwidth*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_GYRO_CONFIG_BW__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_bw_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_GYRO_CONFIG_BW);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set the
+ * data of gyro from the register 0x42 bit 4 to 5
+ *
+ *
+ *
+ *
+ * @param v_bw_u8 : The value of gyro bandwidth
+ * value | gyro bandwidth
+ * ----------|----------------
+ * 0x00 | BMI160_GYRO_OSR4_MODE
+ * 0x01 | BMI160_GYRO_OSR2_MODE
+ * 0x02 | BMI160_GYRO_NORMAL_MODE
+ * 0x03 | BMI160_GYRO_CIC_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_bw(u8 v_bw_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_bw_u8 <= BMI160_MAX_GYRO_BW) {
+ /* write the gyro bandwidth*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_GYRO_CONFIG_BW__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_GYRO_CONFIG_BW, v_bw_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_GYRO_CONFIG_BW__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the range
+ * of gyro from the register 0x43 bit 0 to 2
+ *
+ * @param v_range_u8 : The value of gyro range
+ * value | range
+ * ----------|-------------------------------
+ * 0x00 | BMI160_GYRO_RANGE_2000_DEG_SEC
+ * 0x01 | BMI160_GYRO_RANGE_1000_DEG_SEC
+ * 0x02 | BMI160_GYRO_RANGE_500_DEG_SEC
+ * 0x03 | BMI160_GYRO_RANGE_250_DEG_SEC
+ * 0x04 | BMI160_GYRO_RANGE_125_DEG_SEC
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_range(u8 *v_range_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the gyro range */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_GYRO_RANGE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_range_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_GYRO_RANGE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API set the range
+ * of gyro from the register 0x43 bit 0 to 2
+ *
+ * @param v_range_u8 : The value of gyro range
+ * value | range
+ * ----------|-------------------------------
+ * 0x00 | BMI160_GYRO_RANGE_2000_DEG_SEC
+ * 0x01 | BMI160_GYRO_RANGE_1000_DEG_SEC
+ * 0x02 | BMI160_GYRO_RANGE_500_DEG_SEC
+ * 0x03 | BMI160_GYRO_RANGE_250_DEG_SEC
+ * 0x04 | BMI160_GYRO_RANGE_125_DEG_SEC
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_range(u8 v_range_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_range_u8 <= BMI160_MAX_GYRO_RANGE) {
+ /* write the gyro range value */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_GYRO_RANGE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_GYRO_RANGE,
+ v_range_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_GYRO_RANGE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to get the
+ * output data rate of magnetometer from the register 0x44 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_output_data_rat_u8e : The value of mag output data rate
+ * value | mag output data rate
+ * ---------|---------------------------
+ * 0x00 |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED
+ * 0x01 |BMI160_MAG_OUTPUT_DATA_RATE_0_78HZ
+ * 0x02 |BMI160_MAG_OUTPUT_DATA_RATE_1_56HZ
+ * 0x03 |BMI160_MAG_OUTPUT_DATA_RATE_3_12HZ
+ * 0x04 |BMI160_MAG_OUTPUT_DATA_RATE_6_25HZ
+ * 0x05 |BMI160_MAG_OUTPUT_DATA_RATE_12_5HZ
+ * 0x06 |BMI160_MAG_OUTPUT_DATA_RATE_25HZ
+ * 0x07 |BMI160_MAG_OUTPUT_DATA_RATE_50HZ
+ * 0x08 |BMI160_MAG_OUTPUT_DATA_RATE_100HZ
+ * 0x09 |BMI160_MAG_OUTPUT_DATA_RATE_200HZ
+ * 0x0A |BMI160_MAG_OUTPUT_DATA_RATE_400HZ
+ * 0x0B |BMI160_MAG_OUTPUT_DATA_RATE_800HZ
+ * 0x0C |BMI160_MAG_OUTPUT_DATA_RATE_1600HZ
+ * 0x0D |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED0
+ * 0x0E |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED1
+ * 0x0F |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED2
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_output_data_rate(
+u8 *v_output_data_rat_u8e)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the mag data output rate*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_MAG_CONFIG_OUTPUT_DATA_RATE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_output_data_rat_u8e = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_MAG_CONFIG_OUTPUT_DATA_RATE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set the
+ * output data rate of magnetometer from the register 0x44 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_output_data_rat_u8e : The value of mag output data rate
+ * value | mag output data rate
+ * ---------|---------------------------
+ * 0x00 |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED
+ * 0x01 |BMI160_MAG_OUTPUT_DATA_RATE_0_78HZ
+ * 0x02 |BMI160_MAG_OUTPUT_DATA_RATE_1_56HZ
+ * 0x03 |BMI160_MAG_OUTPUT_DATA_RATE_3_12HZ
+ * 0x04 |BMI160_MAG_OUTPUT_DATA_RATE_6_25HZ
+ * 0x05 |BMI160_MAG_OUTPUT_DATA_RATE_12_5HZ
+ * 0x06 |BMI160_MAG_OUTPUT_DATA_RATE_25HZ
+ * 0x07 |BMI160_MAG_OUTPUT_DATA_RATE_50HZ
+ * 0x08 |BMI160_MAG_OUTPUT_DATA_RATE_100HZ
+ * 0x09 |BMI160_MAG_OUTPUT_DATA_RATE_200HZ
+ * 0x0A |BMI160_MAG_OUTPUT_DATA_RATE_400HZ
+ * 0x0B |BMI160_MAG_OUTPUT_DATA_RATE_800HZ
+ * 0x0C |BMI160_MAG_OUTPUT_DATA_RATE_1600HZ
+ * 0x0D |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED0
+ * 0x0E |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED1
+ * 0x0F |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED2
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_output_data_rate(
+u8 v_output_data_rat_u8e)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* select the mag data output rate*/
+ if ((v_output_data_rat_u8e
+ <= BMI160_MAX_ACCEL_OUTPUT_DATA_RATE)
+ && (v_output_data_rat_u8e
+ != BMI160_OUTPUT_DATA_RATE0)
+ && (v_output_data_rat_u8e
+ != BMI160_OUTPUT_DATA_RATE6)
+ && (v_output_data_rat_u8e
+ != BMI160_OUTPUT_DATA_RATE7)) {
+ /* write the mag data output rate*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_MAG_CONFIG_OUTPUT_DATA_RATE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_MAG_CONFIG_OUTPUT_DATA_RATE,
+ v_output_data_rat_u8e);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_MAG_CONFIG_OUTPUT_DATA_RATE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API is used to read Down sampling
+ * for gyro (2**downs_gyro) in the register 0x45 bit 0 to 2
+ *
+ *
+ *
+ *
+ * @param v_fifo_down_gyro_u8 :The value of gyro fifo down
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_down_gyro(
+u8 *v_fifo_down_gyro_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the gyro fifo down*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_FIFO_DOWN_GYRO__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_down_gyro_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_FIFO_DOWN_GYRO);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API is used to set Down sampling
+ * for gyro (2**downs_gyro) in the register 0x45 bit 0 to 2
+ *
+ *
+ *
+ *
+ * @param v_fifo_down_gyro_u8 :The value of gyro fifo down
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_down_gyro(
+u8 v_fifo_down_gyro_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* write the gyro fifo down*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_FIFO_DOWN_GYRO__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(
+ v_data_u8,
+ BMI160_USER_FIFO_DOWN_GYRO,
+ v_fifo_down_gyro_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_FIFO_DOWN_GYRO__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read gyro fifo filter data
+ * from the register 0x45 bit 3
+ *
+ *
+ *
+ * @param v_gyro_fifo_filter_data_u8 :The value of gyro filter data
+ * value | gyro_fifo_filter_data
+ * ------------|-------------------------
+ * 0x00 | Unfiltered data
+ * 0x01 | Filtered data
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_fifo_filter_data(
+u8 *v_gyro_fifo_filter_data_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the gyro fifo filter data */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_FIFO_FILTER_GYRO__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_gyro_fifo_filter_data_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_FIFO_FILTER_GYRO);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set gyro fifo filter data
+ * from the register 0x45 bit 3
+ *
+ *
+ *
+ * @param v_gyro_fifo_filter_data_u8 :The value of gyro filter data
+ * value | gyro_fifo_filter_data
+ * ------------|-------------------------
+ * 0x00 | Unfiltered data
+ * 0x01 | Filtered data
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_fifo_filter_data(
+u8 v_gyro_fifo_filter_data_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_gyro_fifo_filter_data_u8
+ <= BMI160_MAX_VALUE_FIFO_FILTER) {
+ /* write the gyro fifo filter data */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_FIFO_FILTER_GYRO__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(
+ v_data_u8,
+ BMI160_USER_FIFO_FILTER_GYRO,
+ v_gyro_fifo_filter_data_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_FIFO_FILTER_GYRO__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read Down sampling
+ * for accel (2*downs_accel) from the register 0x45 bit 4 to 6
+ *
+ *
+ *
+ *
+ * @param v_fifo_down_u8 :The value of accel fifo down
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_down_accel(
+u8 *v_fifo_down_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the accel fifo down data */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_FIFO_DOWN_ACCEL__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_down_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_FIFO_DOWN_ACCEL);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API is used to set Down sampling
+ * for accel (2*downs_accel) from the register 0x45 bit 4 to 6
+ *
+ *
+ *
+ *
+ * @param v_fifo_down_u8 :The value of accel fifo down
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_down_accel(
+u8 v_fifo_down_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* write the accel fifo down data */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_FIFO_DOWN_ACCEL__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_FIFO_DOWN_ACCEL, v_fifo_down_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_FIFO_DOWN_ACCEL__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read accel fifo filter data
+ * from the register 0x45 bit 7
+ *
+ *
+ *
+ * @param v_accel_fifo_filter_u8 :The value of accel filter data
+ * value | accel_fifo_filter_data
+ * ------------|-------------------------
+ * 0x00 | Unfiltered data
+ * 0x01 | Filtered data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_fifo_filter_data(
+u8 *v_accel_fifo_filter_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the accel fifo filter data */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_FIFO_FILTER_ACCEL__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_fifo_filter_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_FIFO_FILTER_ACCEL);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set accel fifo filter data
+ * from the register 0x45 bit 7
+ *
+ *
+ *
+ * @param v_accel_fifo_filter_u8 :The value of accel filter data
+ * value | accel_fifo_filter_data
+ * ------------|-------------------------
+ * 0x00 | Unfiltered data
+ * 0x01 | Filtered data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_fifo_filter_data(
+u8 v_accel_fifo_filter_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_accel_fifo_filter_u8 <= BMI160_MAX_VALUE_FIFO_FILTER) {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_FIFO_FILTER_ACCEL__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ /* write accel fifo filter data */
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_FIFO_FILTER_ACCEL,
+ v_accel_fifo_filter_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_FIFO_FILTER_ACCEL__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to Trigger an interrupt
+ * when FIFO contains water mark level from the register 0x46 bit 0 to 7
+ *
+ *
+ *
+ * @param v_fifo_wm_u8 : The value of fifo water mark level
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_wm(
+u8 *v_fifo_wm_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the fifo water mark level*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_FIFO_WM__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_wm_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_FIFO_WM);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to Trigger an interrupt
+ * when FIFO contains water mark level from the register 0x46 bit 0 to 7
+ *
+ *
+ *
+ * @param v_fifo_wm_u8 : The value of fifo water mark level
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_wm(
+u8 v_fifo_wm_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* write the fifo water mark level*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_FIFO_WM__REG,
+ &v_fifo_wm_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads fifo sensor time
+ * frame after the last valid data frame form the register 0x47 bit 1
+ *
+ *
+ *
+ *
+ * @param v_fifo_time_enable_u8 : The value of sensor time
+ * value | fifo sensor time
+ * ------------|-------------------------
+ * 0x00 | do not return sensortime frame
+ * 0x01 | return sensortime frame
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_time_enable(
+u8 *v_fifo_time_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the fifo sensor time*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_FIFO_TIME_ENABLE__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_time_enable_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_FIFO_TIME_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API set fifo sensor time
+ * frame after the last valid data frame form the register 0x47 bit 1
+ *
+ *
+ *
+ *
+ * @param v_fifo_time_enable_u8 : The value of sensor time
+ * value | fifo sensor time
+ * ------------|-------------------------
+ * 0x00 | do not return sensortime frame
+ * 0x01 | return sensortime frame
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_time_enable(
+u8 v_fifo_time_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_fifo_time_enable_u8 <= BMI160_MAX_VALUE_FIFO_TIME) {
+ /* write the fifo sensor time*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_FIFO_TIME_ENABLE__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_FIFO_TIME_ENABLE,
+ v_fifo_time_enable_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_FIFO_TIME_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads FIFO tag interrupt2 enable status
+ * from the resister 0x47 bit 2
+ *
+ * @param v_fifo_tag_intr2_u8 : The value of fifo tag interrupt
+ * value | fifo tag interrupt
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_tag_intr2_enable(
+u8 *v_fifo_tag_intr2_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the fifo tag interrupt2*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_FIFO_TAG_INTR2_ENABLE__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_tag_intr2_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_FIFO_TAG_INTR2_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API set FIFO tag interrupt2 enable status
+ * from the resister 0x47 bit 2
+ *
+ * @param v_fifo_tag_intr2_u8 : The value of fifo tag interrupt
+ * value | fifo tag interrupt
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_tag_intr2_enable(
+u8 v_fifo_tag_intr2_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_fifo_tag_intr2_u8 <= BMI160_MAX_VALUE_FIFO_INTR) {
+ /* write the fifo tag interrupt2*/
+ com_rslt = bmi160_set_input_enable(1,
+ v_fifo_tag_intr2_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_FIFO_TAG_INTR2_ENABLE__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_FIFO_TAG_INTR2_ENABLE,
+ v_fifo_tag_intr2_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_FIFO_TAG_INTR2_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API get FIFO tag interrupt1 enable status
+ * from the resister 0x47 bit 3
+ *
+ * @param v_fifo_tag_intr1_u8 :The value of fifo tag interrupt1
+ * value | fifo tag interrupt
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_tag_intr1_enable(
+u8 *v_fifo_tag_intr1_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read fifo tag interrupt*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_FIFO_TAG_INTR1_ENABLE__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_tag_intr1_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_FIFO_TAG_INTR1_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API set FIFO tag interrupt1 enable status
+ * from the resister 0x47 bit 3
+ *
+ * @param v_fifo_tag_intr1_u8 :The value of fifo tag interrupt1
+ * value | fifo tag interrupt
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_tag_intr1_enable(
+u8 v_fifo_tag_intr1_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_fifo_tag_intr1_u8 <= BMI160_MAX_VALUE_FIFO_INTR) {
+ /* write the fifo tag interrupt*/
+ com_rslt = bmi160_set_input_enable(BMI160_INIT_VALUE,
+ v_fifo_tag_intr1_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_FIFO_TAG_INTR1_ENABLE__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_FIFO_TAG_INTR1_ENABLE,
+ v_fifo_tag_intr1_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_FIFO_TAG_INTR1_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads FIFO frame
+ * header enable from the register 0x47 bit 4
+ *
+ * @param v_fifo_header_u8 :The value of fifo header
+ * value | fifo header
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_header_enable(
+u8 *v_fifo_header_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read fifo header */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_FIFO_HEADER_ENABLE__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_header_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_FIFO_HEADER_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API set FIFO frame
+ * header enable from the register 0x47 bit 4
+ *
+ * @param v_fifo_header_u8 :The value of fifo header
+ * value | fifo header
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_header_enable(
+u8 v_fifo_header_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_fifo_header_u8 <= BMI160_MAX_VALUE_FIFO_HEADER) {
+ /* write the fifo header */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_FIFO_HEADER_ENABLE__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_FIFO_HEADER_ENABLE,
+ v_fifo_header_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_FIFO_HEADER_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read stored
+ * magnetometer data in FIFO (all 3 axes) from the register 0x47 bit 5
+ *
+ * @param v_fifo_mag_u8 : The value of fifo mag enble
+ * value | fifo mag
+ * ----------|-------------------
+ * 0x00 | no magnetometer data is stored
+ * 0x01 | magnetometer data is stored
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_mag_enable(
+u8 *v_fifo_mag_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the fifo mag enable*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_FIFO_MAG_ENABLE__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_mag_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_FIFO_MAG_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set stored
+ * magnetometer data in FIFO (all 3 axes) from the register 0x47 bit 5
+ *
+ * @param v_fifo_mag_u8 : The value of fifo mag enble
+ * value | fifo mag
+ * ----------|-------------------
+ * 0x00 | no magnetometer data is stored
+ * 0x01 | magnetometer data is stored
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_mag_enable(
+u8 v_fifo_mag_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_fifo_mag_u8 <= BMI160_MAX_VALUE_FIFO_MAG) {
+ /* write the fifo mag enable*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_FIFO_MAG_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_FIFO_MAG_ENABLE,
+ v_fifo_mag_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_FIFO_MAG_ENABLE__REG,
+ &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read stored
+ * accel data in FIFO (all 3 axes) from the register 0x47 bit 6
+ *
+ * @param v_fifo_accel_u8 : The value of fifo accel enble
+ * value | fifo accel
+ * ----------|-------------------
+ * 0x00 | no accel data is stored
+ * 0x01 | accel data is stored
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_accel_enable(
+u8 *v_fifo_accel_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the accel fifo enable*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_FIFO_ACCEL_ENABLE__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_accel_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_FIFO_ACCEL_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set stored
+ * accel data in FIFO (all 3 axes) from the register 0x47 bit 6
+ *
+ * @param v_fifo_accel_u8 : The value of fifo accel enble
+ * value | fifo accel
+ * ----------|-------------------
+ * 0x00 | no accel data is stored
+ * 0x01 | accel data is stored
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_accel_enable(
+u8 v_fifo_accel_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_fifo_accel_u8 <= BMI160_MAX_VALUE_FIFO_ACCEL) {
+ /* write the fifo mag enables*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_FIFO_ACCEL_ENABLE__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_FIFO_ACCEL_ENABLE, v_fifo_accel_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_FIFO_ACCEL_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read stored
+ * gyro data in FIFO (all 3 axes) from the resister 0x47 bit 7
+ *
+ *
+ * @param v_fifo_gyro_u8 : The value of fifo gyro enble
+ * value | fifo gyro
+ * ----------|-------------------
+ * 0x00 | no gyro data is stored
+ * 0x01 | gyro data is stored
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_gyro_enable(
+u8 *v_fifo_gyro_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read fifo gyro enable */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_FIFO_GYRO_ENABLE__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_gyro_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_FIFO_GYRO_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set stored
+ * gyro data in FIFO (all 3 axes) from the resister 0x47 bit 7
+ *
+ *
+ * @param v_fifo_gyro_u8 : The value of fifo gyro enble
+ * value | fifo gyro
+ * ----------|-------------------
+ * 0x00 | no gyro data is stored
+ * 0x01 | gyro data is stored
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_gyro_enable(
+u8 v_fifo_gyro_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_fifo_gyro_u8 <= BMI160_MAX_VALUE_FIFO_GYRO) {
+ /* write fifo gyro enable*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_FIFO_GYRO_ENABLE__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_FIFO_GYRO_ENABLE, v_fifo_gyro_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_FIFO_GYRO_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read
+ * I2C device address of auxiliary mag from the register 0x4B bit 1 to 7
+ *
+ *
+ *
+ *
+ * @param v_i2c_device_addr_u8 : The value of mag I2C device address
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_i2c_device_addr(
+u8 *v_i2c_device_addr_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the mag I2C device address*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_I2C_DEVICE_ADDR__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_i2c_device_addr_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_I2C_DEVICE_ADDR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set
+ * I2C device address of auxiliary mag from the register 0x4B bit 1 to 7
+ *
+ *
+ *
+ *
+ * @param v_i2c_device_addr_u8 : The value of mag I2C device address
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_i2c_device_addr(
+u8 v_i2c_device_addr_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* write the mag I2C device address*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_I2C_DEVICE_ADDR__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_I2C_DEVICE_ADDR,
+ v_i2c_device_addr_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_I2C_DEVICE_ADDR__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read
+ * Burst data length (1,2,6,8 byte) from the register 0x4C bit 0 to 1
+ *
+ *
+ *
+ *
+ * @param v_mag_burst_u8 : The data of mag burst read lenth
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_burst(
+u8 *v_mag_burst_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read mag burst mode length*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_MAG_BURST__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_mag_burst_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_MAG_BURST);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set
+ * Burst data length (1,2,6,8 byte) from the register 0x4C bit 0 to 1
+ *
+ *
+ *
+ *
+ * @param v_mag_burst_u8 : The data of mag burst read lenth
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_burst(
+u8 v_mag_burst_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* write mag burst mode length*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_MAG_BURST__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_MAG_BURST, v_mag_burst_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_MAG_BURST__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read
+ * trigger-readout offset in units of 2.5 ms. If set to zero,
+ * the offset is maximum, i.e. after readout a trigger
+ * is issued immediately. from the register 0x4C bit 2 to 5
+ *
+ *
+ *
+ *
+ * @param v_mag_offset_u8 : The value of mag offset
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_offset(
+u8 *v_mag_offset_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_MAG_OFFSET__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_mag_offset_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_MAG_OFFSET);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set
+ * trigger-readout offset in units of 2.5 ms. If set to zero,
+ * the offset is maximum, i.e. after readout a trigger
+ * is issued immediately. from the register 0x4C bit 2 to 5
+ *
+ *
+ *
+ *
+ * @param v_mag_offset_u8 : The value of mag offset
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_offset(
+u8 v_mag_offset_u8)
+{
+/* variable used for return the status of communication result*/
+BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_MAG_OFFSET__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_MAG_OFFSET, v_mag_offset_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_MAG_OFFSET__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+return com_rslt;
+}
+/*!
+ * @brief This API is used to read
+ * Enable register access on MAG_IF[2] or MAG_IF[3] writes.
+ * This implies that the DATA registers are not updated with
+ * magnetometer values. Accessing magnetometer requires
+ * the magnetometer in normal mode in PMU_STATUS.
+ * from the register 0x4C bit 7
+ *
+ *
+ *
+ * @param v_mag_manual_u8 : The value of mag manual enable
+ * value | mag manual
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_manual_enable(
+u8 *v_mag_manual_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read mag manual */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_MAG_MANUAL_ENABLE__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_mag_manual_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_MAG_MANUAL_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set
+ * Enable register access on MAG_IF[2] or MAG_IF[3] writes.
+ * This implies that the DATA registers are not updated with
+ * magnetometer values. Accessing magnetometer requires
+ * the magnetometer in normal mode in PMU_STATUS.
+ * from the register 0x4C bit 7
+ *
+ *
+ *
+ * @param v_mag_manual_u8 : The value of mag manual enable
+ * value | mag manual
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_manual_enable(
+u8 v_mag_manual_u8)
+{
+/* variable used for return the status of communication result*/
+BMI160_RETURN_FUNCTION_TYPE com_rslt = BMI160_INIT_VALUE;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* write the mag manual*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_MAG_MANUAL_ENABLE__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ if (com_rslt == SUCCESS) {
+ /* set the bit of mag manual enable*/
+ v_data_u8 =
+ BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_MAG_MANUAL_ENABLE, v_mag_manual_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_MAG_MANUAL_ENABLE__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ if (com_rslt == SUCCESS)
+ p_bmi160->mag_manual_enable = v_mag_manual_u8;
+ else
+ p_bmi160->mag_manual_enable = E_BMI160_COMM_RES;
+ }
+return com_rslt;
+}
+/*!
+ * @brief This API is used to read data
+ * magnetometer address to read from the register 0x4D bit 0 to 7
+ * @brief It used to provide mag read address of auxiliary mag
+ *
+ *
+ *
+ *
+ * @param v_mag_read_addr_u8 : The value of address need to be read
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_read_addr(
+u8 *v_mag_read_addr_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the written address*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_READ_ADDR__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_mag_read_addr_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_READ_ADDR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set
+ * magnetometer write address from the register 0x4D bit 0 to 7
+ * @brief mag write address writes the address of auxiliary mag to write
+ *
+ *
+ *
+ * @param v_mag_read_addr_u8:
+ * The data of auxiliary mag address to write data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_read_addr(
+u8 v_mag_read_addr_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* write the mag read address*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_READ_ADDR__REG, &v_mag_read_addr_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read
+ * magnetometer write address from the register 0x4E bit 0 to 7
+ * @brief mag write address writes the address of auxiliary mag to write
+ *
+ *
+ *
+ * @param v_mag_write_addr_u8:
+ * The data of auxiliary mag address to write data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_write_addr(
+u8 *v_mag_write_addr_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the address of last written */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_WRITE_ADDR__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_mag_write_addr_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_WRITE_ADDR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set
+ * magnetometer write address from the register 0x4E bit 0 to 7
+ * @brief mag write address writes the address of auxiliary mag to write
+ *
+ *
+ *
+ * @param v_mag_write_addr_u8:
+ * The data of auxiliary mag address to write data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_write_addr(
+u8 v_mag_write_addr_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* write the data of mag address to write data */
+ com_rslt =
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_WRITE_ADDR__REG, &v_mag_write_addr_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read magnetometer write data
+ * form the resister 0x4F bit 0 to 7
+ * @brief This writes the data will be wrote to mag
+ *
+ *
+ *
+ * @param v_mag_write_data_u8: The value of mag data
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_write_data(
+u8 *v_mag_write_data_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_WRITE_DATA__REG, &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_mag_write_data_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_WRITE_DATA);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set magnetometer write data
+ * form the resister 0x4F bit 0 to 7
+ * @brief This writes the data will be wrote to mag
+ *
+ *
+ *
+ * @param v_mag_write_data_u8: The value of mag data
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_write_data(
+u8 v_mag_write_data_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt =
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_WRITE_DATA__REG, &v_mag_write_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read
+ * interrupt enable from the register 0x50 bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_enable_u8 : Value to decided to select interrupt
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_ANY_MOTION_X_ENABLE
+ * 1 | BMI160_ANY_MOTION_Y_ENABLE
+ * 2 | BMI160_ANY_MOTION_Z_ENABLE
+ * 3 | BMI160_DOUBLE_TAP_ENABLE
+ * 4 | BMI160_SINGLE_TAP_ENABLE
+ * 5 | BMI160_ORIENT_ENABLE
+ * 6 | BMI160_FLAT_ENABLE
+ *
+ * @param v_intr_enable_zero_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_enable_0(
+u8 v_enable_u8, u8 *v_intr_enable_zero_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* select interrupt to read*/
+ switch (v_enable_u8) {
+ case BMI160_ANY_MOTION_X_ENABLE:
+ /* read the any motion interrupt x data */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_zero_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE);
+ break;
+ case BMI160_ANY_MOTION_Y_ENABLE:
+ /* read the any motion interrupt y data */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_zero_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE);
+ break;
+ case BMI160_ANY_MOTION_Z_ENABLE:
+ /* read the any motion interrupt z data */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_zero_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE);
+ break;
+ case BMI160_DOUBLE_TAP_ENABLE:
+ /* read the double tap interrupt data */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_zero_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE);
+ break;
+ case BMI160_SINGLE_TAP_ENABLE:
+ /* read the single tap interrupt data */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_zero_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE);
+ break;
+ case BMI160_ORIENT_ENABLE:
+ /* read the orient interrupt data */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_ENABLE_0_ORIENT_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_zero_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_0_ORIENT_ENABLE);
+ break;
+ case BMI160_FLAT_ENABLE:
+ /* read the flat interrupt data */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_ENABLE_0_FLAT_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_zero_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_0_FLAT_ENABLE);
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set
+ * interrupt enable from the register 0x50 bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_enable_u8 : Value to decided to select interrupt
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_ANY_MOTION_X_ENABLE
+ * 1 | BMI160_ANY_MOTION_Y_ENABLE
+ * 2 | BMI160_ANY_MOTION_Z_ENABLE
+ * 3 | BMI160_DOUBLE_TAP_ENABLE
+ * 4 | BMI160_SINGLE_TAP_ENABLE
+ * 5 | BMI160_ORIENT_ENABLE
+ * 6 | BMI160_FLAT_ENABLE
+ *
+ * @param v_intr_enable_zero_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_enable_0(
+u8 v_enable_u8, u8 v_intr_enable_zero_u8)
+{
+/* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_enable_u8) {
+ case BMI160_ANY_MOTION_X_ENABLE:
+ /* write any motion x*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE,
+ v_intr_enable_zero_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_ANY_MOTION_Y_ENABLE:
+ /* write any motion y*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE,
+ v_intr_enable_zero_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_ANY_MOTION_Z_ENABLE:
+ /* write any motion z*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE,
+ v_intr_enable_zero_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_DOUBLE_TAP_ENABLE:
+ /* write double tap*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE,
+ v_intr_enable_zero_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_SINGLE_TAP_ENABLE:
+ /* write single tap */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE,
+ v_intr_enable_zero_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_ORIENT_ENABLE:
+ /* write orient interrupt*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_ENABLE_0_ORIENT_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_0_ORIENT_ENABLE,
+ v_intr_enable_zero_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_0_ORIENT_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_FLAT_ENABLE:
+ /* write flat interrupt*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_ENABLE_0_FLAT_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_0_FLAT_ENABLE,
+ v_intr_enable_zero_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_0_FLAT_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+/*!
+ * @brief This API is used to read
+ * interrupt enable byte1 from the register 0x51 bit 0 to 6
+ * @brief It read the high_g_x,high_g_y,high_g_z,low_g_enable
+ * data ready, fifo full and fifo water mark.
+ *
+ *
+ *
+ * @param v_enable_u8 : The value of interrupt enable
+ * @param v_enable_u8 : Value to decided to select interrupt
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_HIGH_G_X_ENABLE
+ * 1 | BMI160_HIGH_G_Y_ENABLE
+ * 2 | BMI160_HIGH_G_Z_ENABLE
+ * 3 | BMI160_LOW_G_ENABLE
+ * 4 | BMI160_DATA_RDY_ENABLE
+ * 5 | BMI160_FIFO_FULL_ENABLE
+ * 6 | BMI160_FIFO_WM_ENABLE
+ *
+ * @param v_intr_enable_1_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_enable_1(
+u8 v_enable_u8, u8 *v_intr_enable_1_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_enable_u8) {
+ case BMI160_HIGH_G_X_ENABLE:
+ /* read high_g_x interrupt*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_1_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE);
+ break;
+ case BMI160_HIGH_G_Y_ENABLE:
+ /* read high_g_y interrupt*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_1_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE);
+ break;
+ case BMI160_HIGH_G_Z_ENABLE:
+ /* read high_g_z interrupt*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_1_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE);
+ break;
+ case BMI160_LOW_G_ENABLE:
+ /* read low_g interrupt */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_1_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_1_LOW_G_ENABLE);
+ break;
+ case BMI160_DATA_RDY_ENABLE:
+ /* read data ready interrupt */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_1_DATA_RDY_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_1_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_1_DATA_RDY_ENABLE);
+ break;
+ case BMI160_FIFO_FULL_ENABLE:
+ /* read fifo full interrupt */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_1_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE);
+ break;
+ case BMI160_FIFO_WM_ENABLE:
+ /* read fifo water mark interrupt */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_1_FIFO_WM_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_1_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_1_FIFO_WM_ENABLE);
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set
+ * interrupt enable byte1 from the register 0x51 bit 0 to 6
+ * @brief It read the high_g_x,high_g_y,high_g_z,low_g_enable
+ * data ready, fifo full and fifo water mark.
+ *
+ *
+ *
+ * @param v_enable_u8 : The value of interrupt enable
+ * @param v_enable_u8 : Value to decided to select interrupt
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_HIGH_G_X_ENABLE
+ * 1 | BMI160_HIGH_G_Y_ENABLE
+ * 2 | BMI160_HIGH_G_Z_ENABLE
+ * 3 | BMI160_LOW_G_ENABLE
+ * 4 | BMI160_DATA_RDY_ENABLE
+ * 5 | BMI160_FIFO_FULL_ENABLE
+ * 6 | BMI160_FIFO_WM_ENABLE
+ *
+ * @param v_intr_enable_1_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_enable_1(
+u8 v_enable_u8, u8 v_intr_enable_1_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_enable_u8) {
+ case BMI160_HIGH_G_X_ENABLE:
+ /* write high_g_x interrupt*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE,
+ v_intr_enable_1_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_HIGH_G_Y_ENABLE:
+ /* write high_g_y interrupt*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE,
+ v_intr_enable_1_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_HIGH_G_Z_ENABLE:
+ /* write high_g_z interrupt*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE,
+ v_intr_enable_1_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_LOW_G_ENABLE:
+ /* write low_g interrupt*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_1_LOW_G_ENABLE,
+ v_intr_enable_1_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_DATA_RDY_ENABLE:
+ /* write data ready interrupt*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_1_DATA_RDY_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_1_DATA_RDY_ENABLE,
+ v_intr_enable_1_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_1_DATA_RDY_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_FIFO_FULL_ENABLE:
+ /* write fifo full interrupt*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE,
+ v_intr_enable_1_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_FIFO_WM_ENABLE:
+ /* write fifo water mark interrupt*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_ENABLE_1_FIFO_WM_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_1_FIFO_WM_ENABLE,
+ v_intr_enable_1_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_1_FIFO_WM_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read
+ * interrupt enable byte2 from the register bit 0x52 bit 0 to 3
+ * @brief It reads no motion x,y and z
+ *
+ *
+ *
+ * @param v_enable_u8: The value of interrupt enable
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_NOMOTION_X_ENABLE
+ * 1 | BMI160_NOMOTION_Y_ENABLE
+ * 2 | BMI160_NOMOTION_Z_ENABLE
+ *
+ * @param v_intr_enable_2_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_enable_2(
+u8 v_enable_u8, u8 *v_intr_enable_2_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_enable_u8) {
+ case BMI160_NOMOTION_X_ENABLE:
+ /* read no motion x */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_2_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE);
+ break;
+ case BMI160_NOMOTION_Y_ENABLE:
+ /* read no motion y */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_2_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE);
+ break;
+ case BMI160_NOMOTION_Z_ENABLE:
+ /* read no motion z */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_2_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE);
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set
+ * interrupt enable byte2 from the register bit 0x52 bit 0 to 3
+ * @brief It reads no motion x,y and z
+ *
+ *
+ *
+ * @param v_enable_u8: The value of interrupt enable
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_NOMOTION_X_ENABLE
+ * 1 | BMI160_NOMOTION_Y_ENABLE
+ * 2 | BMI160_NOMOTION_Z_ENABLE
+ *
+ * @param v_intr_enable_2_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_enable_2(
+u8 v_enable_u8, u8 v_intr_enable_2_u8)
+{
+/* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_enable_u8) {
+ case BMI160_NOMOTION_X_ENABLE:
+ /* write no motion x */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE,
+ v_intr_enable_2_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_NOMOTION_Y_ENABLE:
+ /* write no motion y */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE,
+ v_intr_enable_2_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_NOMOTION_Z_ENABLE:
+ /* write no motion z */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE,
+ v_intr_enable_2_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+ /*!
+ * @brief This API is used to read
+ * interrupt enable step detector interrupt from
+ * the register bit 0x52 bit 3
+ *
+ *
+ *
+ *
+ * @param v_step_intr_u8 : The value of step detector interrupt enable
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_step_detector_enable(
+u8 *v_step_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the step detector interrupt*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_step_intr_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API is used to set
+ * interrupt enable step detector interrupt from
+ * the register bit 0x52 bit 3
+ *
+ *
+ *
+ *
+ * @param v_step_intr_u8 : The value of step detector interrupt enable
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_step_detector_enable(
+u8 v_step_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE,
+ v_step_intr_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Configure trigger condition of interrupt1
+ * and interrupt2 pin from the register 0x53
+ * @brief interrupt1 - bit 0
+ * @brief interrupt2 - bit 4
+ *
+ * @param v_channel_u8: The value of edge trigger selection
+ * v_channel_u8 | Edge trigger
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_EDGE_CTRL
+ * 1 | BMI160_INTR2_EDGE_CTRL
+ *
+ * @param v_intr_edge_ctrl_u8 : The value of edge trigger enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_EDGE
+ * 0x00 | BMI160_LEVEL
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_edge_ctrl(
+u8 v_channel_u8, u8 *v_intr_edge_ctrl_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ case BMI160_INTR1_EDGE_CTRL:
+ /* read the edge trigger interrupt1*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR1_EDGE_CTRL__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_edge_ctrl_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR1_EDGE_CTRL);
+ break;
+ case BMI160_INTR2_EDGE_CTRL:
+ /* read the edge trigger interrupt2*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR2_EDGE_CTRL__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_edge_ctrl_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR2_EDGE_CTRL);
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Configure trigger condition of interrupt1
+ * and interrupt2 pin from the register 0x53
+ * @brief interrupt1 - bit 0
+ * @brief interrupt2 - bit 4
+ *
+ * @param v_channel_u8: The value of edge trigger selection
+ * v_channel_u8 | Edge trigger
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_EDGE_CTRL
+ * 1 | BMI160_INTR2_EDGE_CTRL
+ *
+ * @param v_intr_edge_ctrl_u8 : The value of edge trigger enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_EDGE
+ * 0x00 | BMI160_LEVEL
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_edge_ctrl(
+u8 v_channel_u8, u8 v_intr_edge_ctrl_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ case BMI160_INTR1_EDGE_CTRL:
+ /* write the edge trigger interrupt1*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR1_EDGE_CTRL__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR1_EDGE_CTRL,
+ v_intr_edge_ctrl_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR1_EDGE_CTRL__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_INTR2_EDGE_CTRL:
+ /* write the edge trigger interrupt2*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR2_EDGE_CTRL__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR2_EDGE_CTRL,
+ v_intr_edge_ctrl_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR2_EDGE_CTRL__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief API used for get the Configure level condition of interrupt1
+ * and interrupt2 pin form the register 0x53
+ * @brief interrupt1 - bit 1
+ * @brief interrupt2 - bit 5
+ *
+ * @param v_channel_u8: The value of level condition selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_LEVEL
+ * 1 | BMI160_INTR2_LEVEL
+ *
+ * @param v_intr_level_u8 : The value of level of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | BMI160_LEVEL_HIGH
+ * 0x00 | BMI160_LEVEL_LOW
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_level(
+u8 v_channel_u8, u8 *v_intr_level_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ case BMI160_INTR1_LEVEL:
+ /* read the interrupt1 level*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR1_LEVEL__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_level_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR1_LEVEL);
+ break;
+ case BMI160_INTR2_LEVEL:
+ /* read the interrupt2 level*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR2_LEVEL__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_level_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR2_LEVEL);
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief API used for set the Configure level condition of interrupt1
+ * and interrupt2 pin form the register 0x53
+ * @brief interrupt1 - bit 1
+ * @brief interrupt2 - bit 5
+ *
+ * @param v_channel_u8: The value of level condition selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_LEVEL
+ * 1 | BMI160_INTR2_LEVEL
+ *
+ * @param v_intr_level_u8 : The value of level of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | BMI160_LEVEL_HIGH
+ * 0x00 | BMI160_LEVEL_LOW
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_level(
+u8 v_channel_u8, u8 v_intr_level_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ case BMI160_INTR1_LEVEL:
+ /* write the interrupt1 level*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR1_LEVEL__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR1_LEVEL, v_intr_level_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR1_LEVEL__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_INTR2_LEVEL:
+ /* write the interrupt2 level*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR2_LEVEL__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR2_LEVEL, v_intr_level_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR2_LEVEL__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief API used to get configured output enable of interrupt1
+ * and interrupt2 from the register 0x53
+ * @brief interrupt1 - bit 2
+ * @brief interrupt2 - bit 6
+ *
+ *
+ * @param v_channel_u8: The value of output type enable selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_OUTPUT_TYPE
+ * 1 | BMI160_INTR2_OUTPUT_TYPE
+ *
+ * @param v_intr_output_type_u8 :
+ * The value of output type of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | BMI160_OPEN_DRAIN
+ * 0x00 | BMI160_PUSH_PULL
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_output_type(
+u8 v_channel_u8, u8 *v_intr_output_type_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ case BMI160_INTR1_OUTPUT_TYPE:
+ /* read the output type of interrupt1*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR1_OUTPUT_TYPE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_output_type_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR1_OUTPUT_TYPE);
+ break;
+ case BMI160_INTR2_OUTPUT_TYPE:
+ /* read the output type of interrupt2*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR2_OUTPUT_TYPE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_output_type_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR2_OUTPUT_TYPE);
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief API used to set output enable of interrupt1
+ * and interrupt2 from the register 0x53
+ * @brief interrupt1 - bit 2
+ * @brief interrupt2 - bit 6
+ *
+ *
+ * @param v_channel_u8: The value of output type enable selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_OUTPUT_TYPE
+ * 1 | BMI160_INTR2_OUTPUT_TYPE
+ *
+ * @param v_intr_output_type_u8 :
+ * The value of output type of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | BMI160_OPEN_DRAIN
+ * 0x00 | BMI160_PUSH_PULL
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_output_type(
+u8 v_channel_u8, u8 v_intr_output_type_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ case BMI160_INTR1_OUTPUT_TYPE:
+ /* write the output type of interrupt1*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR1_OUTPUT_TYPE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR1_OUTPUT_TYPE,
+ v_intr_output_type_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR1_OUTPUT_TYPE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_INTR2_OUTPUT_TYPE:
+ /* write the output type of interrupt2*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR2_OUTPUT_TYPE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR2_OUTPUT_TYPE,
+ v_intr_output_type_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR2_OUTPUT_TYPE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief API used to get the Output enable for interrupt1
+ * and interrupt1 pin from the register 0x53
+ * @brief interrupt1 - bit 3
+ * @brief interrupt2 - bit 7
+ *
+ * @param v_channel_u8: The value of output enable selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_OUTPUT_TYPE
+ * 1 | BMI160_INTR2_OUTPUT_TYPE
+ *
+ * @param v_output_enable_u8 :
+ * The value of output enable of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | BMI160_INPUT
+ * 0x00 | BMI160_OUTPUT
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_output_enable(
+u8 v_channel_u8, u8 *v_output_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ case BMI160_INTR1_OUTPUT_ENABLE:
+ /* read the output enable of interrupt1*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR1_OUTPUT_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_output_enable_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR1_OUTPUT_ENABLE);
+ break;
+ case BMI160_INTR2_OUTPUT_ENABLE:
+ /* read the output enable of interrupt2*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR2_OUTPUT_EN__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_output_enable_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR2_OUTPUT_EN);
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief API used to set the Output enable for interrupt1
+ * and interrupt1 pin from the register 0x53
+ * @brief interrupt1 - bit 3
+ * @brief interrupt2 - bit 7
+ *
+ * @param v_channel_u8: The value of output enable selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_OUTPUT_TYPE
+ * 1 | BMI160_INTR2_OUTPUT_TYPE
+ *
+ * @param v_output_enable_u8 :
+ * The value of output enable of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | BMI160_INPUT
+ * 0x00 | BMI160_OUTPUT
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_output_enable(
+u8 v_channel_u8, u8 v_output_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ case BMI160_INTR1_OUTPUT_ENABLE:
+ /* write the output enable of interrupt1*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR1_OUTPUT_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR1_OUTPUT_ENABLE,
+ v_output_enable_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR1_OUTPUT_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_INTR2_OUTPUT_ENABLE:
+ /* write the output enable of interrupt2*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR2_OUTPUT_EN__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR2_OUTPUT_EN,
+ v_output_enable_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR2_OUTPUT_EN__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to get the latch duration
+* from the register 0x54 bit 0 to 3
+* @brief This latch selection is not applicable for data ready,
+* orientation and flat interrupts.
+*
+*
+*
+* @param v_latch_intr_u8 : The value of latch duration
+* Latch Duration | value
+* --------------------------------------|------------------
+* BMI160_LATCH_DUR_NONE | 0x00
+* BMI160_LATCH_DUR_312_5_MICRO_SEC | 0x01
+* BMI160_LATCH_DUR_625_MICRO_SEC | 0x02
+* BMI160_LATCH_DUR_1_25_MILLI_SEC | 0x03
+* BMI160_LATCH_DUR_2_5_MILLI_SEC | 0x04
+* BMI160_LATCH_DUR_5_MILLI_SEC | 0x05
+* BMI160_LATCH_DUR_10_MILLI_SEC | 0x06
+* BMI160_LATCH_DUR_20_MILLI_SEC | 0x07
+* BMI160_LATCH_DUR_40_MILLI_SEC | 0x08
+* BMI160_LATCH_DUR_80_MILLI_SEC | 0x09
+* BMI160_LATCH_DUR_160_MILLI_SEC | 0x0A
+* BMI160_LATCH_DUR_320_MILLI_SEC | 0x0B
+* BMI160_LATCH_DUR_640_MILLI_SEC | 0x0C
+* BMI160_LATCH_DUR_1_28_SEC | 0x0D
+* BMI160_LATCH_DUR_2_56_SEC | 0x0E
+* BMI160_LATCHED | 0x0F
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_latch_intr(
+u8 *v_latch_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the latch duration value */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_LATCH__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_latch_intr_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_LATCH);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to set the latch duration
+* from the register 0x54 bit 0 to 3
+* @brief This latch selection is not applicable for data ready,
+* orientation and flat interrupts.
+*
+*
+*
+* @param v_latch_intr_u8 : The value of latch duration
+* Latch Duration | value
+* --------------------------------------|------------------
+* BMI160_LATCH_DUR_NONE | 0x00
+* BMI160_LATCH_DUR_312_5_MICRO_SEC | 0x01
+* BMI160_LATCH_DUR_625_MICRO_SEC | 0x02
+* BMI160_LATCH_DUR_1_25_MILLI_SEC | 0x03
+* BMI160_LATCH_DUR_2_5_MILLI_SEC | 0x04
+* BMI160_LATCH_DUR_5_MILLI_SEC | 0x05
+* BMI160_LATCH_DUR_10_MILLI_SEC | 0x06
+* BMI160_LATCH_DUR_20_MILLI_SEC | 0x07
+* BMI160_LATCH_DUR_40_MILLI_SEC | 0x08
+* BMI160_LATCH_DUR_80_MILLI_SEC | 0x09
+* BMI160_LATCH_DUR_160_MILLI_SEC | 0x0A
+* BMI160_LATCH_DUR_320_MILLI_SEC | 0x0B
+* BMI160_LATCH_DUR_640_MILLI_SEC | 0x0C
+* BMI160_LATCH_DUR_1_28_SEC | 0x0D
+* BMI160_LATCH_DUR_2_56_SEC | 0x0E
+* BMI160_LATCHED | 0x0F
+*
+*
+*
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+*
+*
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_latch_intr(u8 v_latch_intr_u8)
+{
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_latch_intr_u8 <= BMI160_MAX_LATCH_INTR) {
+ /* write the latch duration value */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_LATCH__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_LATCH, v_latch_intr_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_LATCH__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief API used to get input enable for interrupt1
+ * and interrupt2 pin from the register 0x54
+ * @brief interrupt1 - bit 4
+ * @brief interrupt2 - bit 5
+ *
+ * @param v_channel_u8: The value of input enable selection
+ * v_channel_u8 | input selection
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_INPUT_ENABLE
+ * 1 | BMI160_INTR2_INPUT_ENABLE
+ *
+ * @param v_input_en_u8 :
+ * The value of input enable of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | BMI160_INPUT
+ * 0x00 | BMI160_OUTPUT
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_input_enable(
+u8 v_channel_u8, u8 *v_input_en_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* read input enable of interrup1 and interrupt2*/
+ case BMI160_INTR1_INPUT_ENABLE:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR1_INPUT_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_input_en_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR1_INPUT_ENABLE);
+ break;
+ case BMI160_INTR2_INPUT_ENABLE:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR2_INPUT_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_input_en_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR2_INPUT_ENABLE);
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief API used to set input enable for interrupt1
+ * and interrupt2 pin from the register 0x54
+ * @brief interrupt1 - bit 4
+ * @brief interrupt2 - bit 5
+ *
+ * @param v_channel_u8: The value of input enable selection
+ * v_channel_u8 | input selection
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_INPUT_ENABLE
+ * 1 | BMI160_INTR2_INPUT_ENABLE
+ *
+ * @param v_input_en_u8 :
+ * The value of input enable of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | BMI160_INPUT
+ * 0x00 | BMI160_OUTPUT
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_input_enable(
+u8 v_channel_u8, u8 v_input_en_u8)
+{
+/* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* write input enable of interrup1 and interrupt2*/
+ case BMI160_INTR1_INPUT_ENABLE:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR1_INPUT_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR1_INPUT_ENABLE, v_input_en_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR1_INPUT_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_INTR2_INPUT_ENABLE:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR2_INPUT_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR2_INPUT_ENABLE, v_input_en_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR2_INPUT_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+ /*!
+ * @brief reads the Low g interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 0 in the register 0x55
+ * @brief interrupt2 bit 0 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of low_g selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_LOW_G
+ * 1 | BMI160_INTR2_MAP_LOW_G
+ *
+ * @param v_intr_low_g_u8 : The value of low_g enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_low_g(
+u8 v_channel_u8, u8 *v_intr_low_g_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* read the low_g interrupt */
+ case BMI160_INTR1_MAP_LOW_G:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_0_INTR1_LOW_G__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_low_g_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_0_INTR1_LOW_G);
+ break;
+ case BMI160_INTR2_MAP_LOW_G:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_2_INTR2_LOW_G__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_low_g_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_2_INTR2_LOW_G);
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief set the Low g interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 0 in the register 0x55
+ * @brief interrupt2 bit 0 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of low_g selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_LOW_G
+ * 1 | BMI160_INTR2_MAP_LOW_G
+ *
+ * @param v_intr_low_g_u8 : The value of low_g enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_low_g(
+u8 v_channel_u8, u8 v_intr_low_g_u8)
+{
+/* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+u8 v_step_cnt_stat_u8 = BMI160_INIT_VALUE;
+u8 v_step_det_stat_u8 = BMI160_INIT_VALUE;
+
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* check the step detector interrupt enable status*/
+ com_rslt = bmi160_get_step_detector_enable(&v_step_det_stat_u8);
+ /* disable the step detector interrupt */
+ if (v_step_det_stat_u8 != BMI160_INIT_VALUE)
+ com_rslt += bmi160_set_step_detector_enable(BMI160_INIT_VALUE);
+ /* check the step counter interrupt enable status*/
+ com_rslt += bmi160_get_step_counter_enable(&v_step_cnt_stat_u8);
+ /* disable the step counter interrupt */
+ if (v_step_cnt_stat_u8 != BMI160_INIT_VALUE)
+ com_rslt += bmi160_set_step_counter_enable(
+ BMI160_INIT_VALUE);
+ switch (v_channel_u8) {
+ /* write the low_g interrupt*/
+ case BMI160_INTR1_MAP_LOW_G:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_0_INTR1_LOW_G__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_0_INTR1_LOW_G, v_intr_low_g_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_0_INTR1_LOW_G__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_INTR2_MAP_LOW_G:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_2_INTR2_LOW_G__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_2_INTR2_LOW_G, v_intr_low_g_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_2_INTR2_LOW_G__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+/*!
+ * @brief Reads the HIGH g interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 1 in the register 0x55
+ * @brief interrupt2 bit 1 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of high_g selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_HIGH_G
+ * 1 | BMI160_INTR2_MAP_HIGH_G
+ *
+ * @param v_intr_high_g_u8 : The value of high_g enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_high_g(
+u8 v_channel_u8, u8 *v_intr_high_g_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the high_g interrupt*/
+ switch (v_channel_u8) {
+ case BMI160_INTR1_MAP_HIGH_G:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_0_INTR1_HIGH_G__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_high_g_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_0_INTR1_HIGH_G);
+ break;
+ case BMI160_INTR2_MAP_HIGH_G:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_2_INTR2_HIGH_G__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_high_g_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_2_INTR2_HIGH_G);
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Write the HIGH g interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 1 in the register 0x55
+ * @brief interrupt2 bit 1 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of high_g selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_HIGH_G
+ * 1 | BMI160_INTR2_MAP_HIGH_G
+ *
+ * @param v_intr_high_g_u8 : The value of high_g enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_high_g(
+u8 v_channel_u8, u8 v_intr_high_g_u8)
+{
+/* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* write the high_g interrupt*/
+ case BMI160_INTR1_MAP_HIGH_G:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_0_INTR1_HIGH_G__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_0_INTR1_HIGH_G, v_intr_high_g_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_0_INTR1_HIGH_G__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_INTR2_MAP_HIGH_G:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_2_INTR2_HIGH_G__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_2_INTR2_HIGH_G, v_intr_high_g_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_2_INTR2_HIGH_G__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+/*!
+ * @brief Reads the Any motion interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 2 in the register 0x55
+ * @brief interrupt2 bit 2 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of any motion selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_ANY_MOTION
+ * 1 | BMI160_INTR2_MAP_ANY_MOTION
+ *
+ * @param v_intr_any_motion_u8 : The value of any motion enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_any_motion(
+u8 v_channel_u8, u8 *v_intr_any_motion_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* read the any motion interrupt */
+ case BMI160_INTR1_MAP_ANY_MOTION:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_0_INTR1_ANY_MOTION__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_any_motion_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_0_INTR1_ANY_MOTION);
+ break;
+ case BMI160_INTR2_MAP_ANY_MOTION:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_2_INTR2_ANY_MOTION__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_any_motion_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_2_INTR2_ANY_MOTION);
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Write the Any motion interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 2 in the register 0x55
+ * @brief interrupt2 bit 2 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of any motion selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_ANY_MOTION
+ * 1 | BMI160_INTR2_MAP_ANY_MOTION
+ *
+ * @param v_intr_any_motion_u8 : The value of any motion enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_any_motion(
+u8 v_channel_u8, u8 v_intr_any_motion_u8)
+{
+/* variable used for return the status of communication result*/
+BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+u8 sig_mot_stat = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the status of significant motion interrupt */
+ com_rslt = bmi160_get_intr_significant_motion_select(&sig_mot_stat);
+ /* disable the significant motion interrupt */
+ if (sig_mot_stat != BMI160_INIT_VALUE)
+ com_rslt += bmi160_set_intr_significant_motion_select(
+ BMI160_INIT_VALUE);
+ switch (v_channel_u8) {
+ /* write the any motion interrupt */
+ case BMI160_INTR1_MAP_ANY_MOTION:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_0_INTR1_ANY_MOTION__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_0_INTR1_ANY_MOTION,
+ v_intr_any_motion_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_0_INTR1_ANY_MOTION__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_INTR2_MAP_ANY_MOTION:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_2_INTR2_ANY_MOTION__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_2_INTR2_ANY_MOTION,
+ v_intr_any_motion_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_2_INTR2_ANY_MOTION__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+/*!
+ * @brief Reads the No motion interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 3 in the register 0x55
+ * @brief interrupt2 bit 3 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of no motion selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_NOMO
+ * 1 | BMI160_INTR2_MAP_NOMO
+ *
+ * @param v_intr_nomotion_u8 : The value of no motion enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_nomotion(
+u8 v_channel_u8, u8 *v_intr_nomotion_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* read the no motion interrupt*/
+ case BMI160_INTR1_MAP_NOMO:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_0_INTR1_NOMOTION__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_nomotion_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_0_INTR1_NOMOTION);
+ break;
+ case BMI160_INTR2_MAP_NOMO:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_2_INTR2_NOMOTION__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_nomotion_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_2_INTR2_NOMOTION);
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Write the No motion interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 3 in the register 0x55
+ * @brief interrupt2 bit 3 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of no motion selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_NOMO
+ * 1 | BMI160_INTR2_MAP_NOMO
+ *
+ * @param v_intr_nomotion_u8 : The value of no motion enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_nomotion(
+u8 v_channel_u8, u8 v_intr_nomotion_u8)
+{
+/* variable used for return the status of communication result*/
+BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* write the no motion interrupt*/
+ case BMI160_INTR1_MAP_NOMO:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_0_INTR1_NOMOTION__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_0_INTR1_NOMOTION,
+ v_intr_nomotion_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_0_INTR1_NOMOTION__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_INTR2_MAP_NOMO:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_2_INTR2_NOMOTION__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_2_INTR2_NOMOTION,
+ v_intr_nomotion_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_2_INTR2_NOMOTION__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+/*!
+ * @brief Reads the Double Tap interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 4 in the register 0x55
+ * @brief interrupt2 bit 4 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of double tap interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_DOUBLE_TAP
+ * 1 | BMI160_INTR2_MAP_DOUBLE_TAP
+ *
+ * @param v_intr_double_tap_u8 : The value of double tap enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_double_tap(
+u8 v_channel_u8, u8 *v_intr_double_tap_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ case BMI160_INTR1_MAP_DOUBLE_TAP:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_0_INTR1_DOUBLE_TAP__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_double_tap_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_0_INTR1_DOUBLE_TAP);
+ break;
+ case BMI160_INTR2_MAP_DOUBLE_TAP:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_2_INTR2_DOUBLE_TAP__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_double_tap_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_2_INTR2_DOUBLE_TAP);
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Write the Double Tap interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 4 in the register 0x55
+ * @brief interrupt2 bit 4 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of double tap interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_DOUBLE_TAP
+ * 1 | BMI160_INTR2_MAP_DOUBLE_TAP
+ *
+ * @param v_intr_double_tap_u8 : The value of double tap enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_double_tap(
+u8 v_channel_u8, u8 v_intr_double_tap_u8)
+{
+/* variable used for return the status of communication result*/
+BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* set the double tap interrupt */
+ case BMI160_INTR1_MAP_DOUBLE_TAP:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_0_INTR1_DOUBLE_TAP__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_0_INTR1_DOUBLE_TAP,
+ v_intr_double_tap_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_0_INTR1_DOUBLE_TAP__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_INTR2_MAP_DOUBLE_TAP:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_2_INTR2_DOUBLE_TAP__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_2_INTR2_DOUBLE_TAP,
+ v_intr_double_tap_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_2_INTR2_DOUBLE_TAP__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+/*!
+ * @brief Reads the Single Tap interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 5 in the register 0x55
+ * @brief interrupt2 bit 5 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of single tap interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_SINGLE_TAP
+ * 1 | BMI160_INTR2_MAP_SINGLE_TAP
+ *
+ * @param v_intr_single_tap_u8 : The value of single tap enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_single_tap(
+u8 v_channel_u8, u8 *v_intr_single_tap_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* reads the single tap interrupt*/
+ case BMI160_INTR1_MAP_SINGLE_TAP:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_0_INTR1_SINGLE_TAP__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_single_tap_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_0_INTR1_SINGLE_TAP);
+ break;
+ case BMI160_INTR2_MAP_SINGLE_TAP:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_2_INTR2_SINGLE_TAP__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_single_tap_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_2_INTR2_SINGLE_TAP);
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Write the Single Tap interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 5 in the register 0x55
+ * @brief interrupt2 bit 5 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of single tap interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_SINGLE_TAP
+ * 1 | BMI160_INTR2_MAP_SINGLE_TAP
+ *
+ * @param v_intr_single_tap_u8 : The value of single tap enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_single_tap(
+u8 v_channel_u8, u8 v_intr_single_tap_u8)
+{
+/* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* write the single tap interrupt */
+ case BMI160_INTR1_MAP_SINGLE_TAP:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_0_INTR1_SINGLE_TAP__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_0_INTR1_SINGLE_TAP,
+ v_intr_single_tap_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_0_INTR1_SINGLE_TAP__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_INTR2_MAP_SINGLE_TAP:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_2_INTR2_SINGLE_TAP__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_2_INTR2_SINGLE_TAP,
+ v_intr_single_tap_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_2_INTR2_SINGLE_TAP__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+/*!
+ * @brief Reads the Orient interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 6 in the register 0x55
+ * @brief interrupt2 bit 6 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of orient interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_ORIENT
+ * 1 | BMI160_INTR2_MAP_ORIENT
+ *
+ * @param v_intr_orient_u8 : The value of orient enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_orient(
+u8 v_channel_u8, u8 *v_intr_orient_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* read the orientation interrupt*/
+ case BMI160_INTR1_MAP_ORIENT:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_0_INTR1_ORIENT__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_orient_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_0_INTR1_ORIENT);
+ break;
+ case BMI160_INTR2_MAP_ORIENT:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_2_INTR2_ORIENT__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_orient_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_2_INTR2_ORIENT);
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Write the Orient interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 6 in the register 0x55
+ * @brief interrupt2 bit 6 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of orient interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_ORIENT
+ * 1 | BMI160_INTR2_MAP_ORIENT
+ *
+ * @param v_intr_orient_u8 : The value of orient enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_orient(
+u8 v_channel_u8, u8 v_intr_orient_u8)
+{
+/* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* write the orientation interrupt*/
+ case BMI160_INTR1_MAP_ORIENT:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_0_INTR1_ORIENT__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_0_INTR1_ORIENT, v_intr_orient_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_0_INTR1_ORIENT__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_INTR2_MAP_ORIENT:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_2_INTR2_ORIENT__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_2_INTR2_ORIENT, v_intr_orient_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_2_INTR2_ORIENT__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+ /*!
+ * @brief Reads the Flat interrupt
+ * mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 7 in the register 0x55
+ * @brief interrupt2 bit 7 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of flat interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_FLAT
+ * 1 | BMI160_INTR2_MAP_FLAT
+ *
+ * @param v_intr_flat_u8 : The value of flat enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_flat(
+u8 v_channel_u8, u8 *v_intr_flat_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* read the flat interrupt*/
+ case BMI160_INTR1_MAP_FLAT:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_0_INTR1_FLAT__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_flat_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_0_INTR1_FLAT);
+ break;
+ case BMI160_INTR2_MAP_FLAT:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_2_INTR2_FLAT__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_flat_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_2_INTR2_FLAT);
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief Write the Flat interrupt
+ * mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 7 in the register 0x55
+ * @brief interrupt2 bit 7 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of flat interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_FLAT
+ * 1 | BMI160_INTR2_MAP_FLAT
+ *
+ * @param v_intr_flat_u8 : The value of flat enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_flat(
+u8 v_channel_u8, u8 v_intr_flat_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* write the flat interrupt */
+ case BMI160_INTR1_MAP_FLAT:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_0_INTR1_FLAT__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_0_INTR1_FLAT,
+ v_intr_flat_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_MAP_0_INTR1_FLAT__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_INTR2_MAP_FLAT:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_2_INTR2_FLAT__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_2_INTR2_FLAT,
+ v_intr_flat_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_MAP_2_INTR2_FLAT__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Reads PMU trigger interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 0 and 4
+ * @brief interrupt1 bit 0 in the register 0x56
+ * @brief interrupt2 bit 4 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of pmu trigger selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_PMUTRIG
+ * 1 | BMI160_INTR2_MAP_PMUTRIG
+ *
+ * @param v_intr_pmu_trig_u8 : The value of pmu trigger enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_pmu_trig(
+u8 v_channel_u8, u8 *v_intr_pmu_trig_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* read the pmu trigger interrupt*/
+ case BMI160_INTR1_MAP_PMUTRIG:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_1_INTR1_PMU_TRIG__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_pmu_trig_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_1_INTR1_PMU_TRIG);
+ break;
+ case BMI160_INTR2_MAP_PMUTRIG:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_1_INTR2_PMU_TRIG__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_pmu_trig_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_1_INTR2_PMU_TRIG);
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Write PMU trigger interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 0 and 4
+ * @brief interrupt1 bit 0 in the register 0x56
+ * @brief interrupt2 bit 4 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of pmu trigger selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_PMUTRIG
+ * 1 | BMI160_INTR2_MAP_PMUTRIG
+ *
+ * @param v_intr_pmu_trig_u8 : The value of pmu trigger enable
+ * value | trigger enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_pmu_trig(
+u8 v_channel_u8, u8 v_intr_pmu_trig_u8)
+{
+/* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* write the pmu trigger interrupt */
+ case BMI160_INTR1_MAP_PMUTRIG:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_1_INTR1_PMU_TRIG__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_1_INTR1_PMU_TRIG,
+ v_intr_pmu_trig_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_1_INTR1_PMU_TRIG__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_INTR2_MAP_PMUTRIG:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_1_INTR2_PMU_TRIG__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_1_INTR2_PMU_TRIG,
+ v_intr_pmu_trig_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_1_INTR2_PMU_TRIG__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+/*!
+ * @brief Reads FIFO Full interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 5 and 1
+ * @brief interrupt1 bit 5 in the register 0x56
+ * @brief interrupt2 bit 1 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of fifo full interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_FIFO_FULL
+ * 1 | BMI160_INTR2_MAP_FIFO_FULL
+ *
+ * @param v_intr_fifo_full_u8 : The value of fifo full interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_fifo_full(
+u8 v_channel_u8, u8 *v_intr_fifo_full_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* read the fifo full interrupt */
+ case BMI160_INTR1_MAP_FIFO_FULL:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_1_INTR1_FIFO_FULL__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_fifo_full_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_1_INTR1_FIFO_FULL);
+ break;
+ case BMI160_INTR2_MAP_FIFO_FULL:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_1_INTR2_FIFO_FULL__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_fifo_full_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_1_INTR2_FIFO_FULL);
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Write FIFO Full interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 5 and 1
+ * @brief interrupt1 bit 5 in the register 0x56
+ * @brief interrupt2 bit 1 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of fifo full interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_FIFO_FULL
+ * 1 | BMI160_INTR2_MAP_FIFO_FULL
+ *
+ * @param v_intr_fifo_full_u8 : The value of fifo full interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_fifo_full(
+u8 v_channel_u8, u8 v_intr_fifo_full_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* write the fifo full interrupt */
+ case BMI160_INTR1_MAP_FIFO_FULL:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_1_INTR1_FIFO_FULL__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_1_INTR1_FIFO_FULL,
+ v_intr_fifo_full_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_MAP_1_INTR1_FIFO_FULL__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_INTR2_MAP_FIFO_FULL:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_1_INTR2_FIFO_FULL__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_1_INTR2_FIFO_FULL,
+ v_intr_fifo_full_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_MAP_1_INTR2_FIFO_FULL__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Reads FIFO Watermark interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 6 and 2
+ * @brief interrupt1 bit 6 in the register 0x56
+ * @brief interrupt2 bit 2 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of fifo Watermark interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_FIFO_WM
+ * 1 | BMI160_INTR2_MAP_FIFO_WM
+ *
+ * @param v_intr_fifo_wm_u8 : The value of fifo Watermark interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_fifo_wm(
+u8 v_channel_u8, u8 *v_intr_fifo_wm_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* read the fifo water mark interrupt */
+ case BMI160_INTR1_MAP_FIFO_WM:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_1_INTR1_FIFO_WM__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_fifo_wm_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_1_INTR1_FIFO_WM);
+ break;
+ case BMI160_INTR2_MAP_FIFO_WM:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_1_INTR2_FIFO_WM__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_fifo_wm_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_1_INTR2_FIFO_WM);
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Write FIFO Watermark interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 6 and 2
+ * @brief interrupt1 bit 6 in the register 0x56
+ * @brief interrupt2 bit 2 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of fifo Watermark interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_FIFO_WM
+ * 1 | BMI160_INTR2_MAP_FIFO_WM
+ *
+ * @param v_intr_fifo_wm_u8 : The value of fifo Watermark interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_fifo_wm(
+u8 v_channel_u8, u8 v_intr_fifo_wm_u8)
+{
+/* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* write the fifo water mark interrupt */
+ case BMI160_INTR1_MAP_FIFO_WM:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_1_INTR1_FIFO_WM__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_1_INTR1_FIFO_WM,
+ v_intr_fifo_wm_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_MAP_1_INTR1_FIFO_WM__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_INTR2_MAP_FIFO_WM:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_1_INTR2_FIFO_WM__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_1_INTR2_FIFO_WM,
+ v_intr_fifo_wm_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr,
+ BMI160_USER_INTR_MAP_1_INTR2_FIFO_WM__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Reads Data Ready interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56
+ * @brief interrupt1 bit 7 in the register 0x56
+ * @brief interrupt2 bit 3 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of data ready interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_DATA_RDY
+ * 1 | BMI160_INTR2_MAP_DATA_RDY
+ *
+ * @param v_intr_data_rdy_u8 : The value of data ready interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_data_rdy(
+u8 v_channel_u8, u8 *v_intr_data_rdy_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /*Read Data Ready interrupt*/
+ case BMI160_INTR1_MAP_DATA_RDY:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_1_INTR1_DATA_RDY__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_data_rdy_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_1_INTR1_DATA_RDY);
+ break;
+ case BMI160_INTR2_MAP_DATA_RDY:
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_1_INTR2_DATA_RDY__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_data_rdy_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_1_INTR2_DATA_RDY);
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Write Data Ready interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56
+ * @brief interrupt1 bit 7 in the register 0x56
+ * @brief interrupt2 bit 3 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of data ready interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_DATA_RDY
+ * 1 | BMI160_INTR2_MAP_DATA_RDY
+ *
+ * @param v_intr_data_rdy_u8 : The value of data ready interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_data_rdy(
+u8 v_channel_u8, u8 v_intr_data_rdy_u8)
+{
+/* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /*Write Data Ready interrupt*/
+ case BMI160_INTR1_MAP_DATA_RDY:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_1_INTR1_DATA_RDY__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_1_INTR1_DATA_RDY,
+ v_intr_data_rdy_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_1_INTR1_DATA_RDY__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case BMI160_INTR2_MAP_DATA_RDY:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_1_INTR2_DATA_RDY__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MAP_1_INTR2_DATA_RDY,
+ v_intr_data_rdy_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(p_bmi160->
+ dev_addr, BMI160_USER_INTR_MAP_1_INTR2_DATA_RDY__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+ /*!
+ * @brief This API reads data source for the interrupt
+ * engine for the single and double tap interrupts from the register
+ * 0x58 bit 3
+ *
+ *
+ * @param v_tap_source_u8 : The value of the tap source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_tap_source(u8 *v_tap_source_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the tap source interrupt */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_DATA_0_INTR_TAP_SOURCE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_tap_source_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_DATA_0_INTR_TAP_SOURCE);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write data source for the interrupt
+ * engine for the single and double tap interrupts from the register
+ * 0x58 bit 3
+ *
+ *
+ * @param v_tap_source_u8 : The value of the tap source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_tap_source(
+u8 v_tap_source_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_tap_source_u8 <= BMI160_MAX_VALUE_SOURCE_INTR) {
+ /* write the tap source interrupt */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_DATA_0_INTR_TAP_SOURCE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_DATA_0_INTR_TAP_SOURCE,
+ v_tap_source_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_DATA_0_INTR_TAP_SOURCE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API Reads Data source for the
+ * interrupt engine for the low and high g interrupts
+ * from the register 0x58 bit 7
+ *
+ * @param v_low_high_source_u8 : The value of the tap source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_low_high_source(
+u8 *v_low_high_source_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the high_low_g source interrupt */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_low_high_source_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write Data source for the
+ * interrupt engine for the low and high g interrupts
+ * from the register 0x58 bit 7
+ *
+ * @param v_low_high_source_u8 : The value of the tap source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_low_high_source(
+u8 v_low_high_source_u8)
+{
+/* variable used for return the status of communication result*/
+BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_low_high_source_u8 <= BMI160_MAX_VALUE_SOURCE_INTR) {
+ /* write the high_low_g source interrupt */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE,
+ v_low_high_source_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+}
+return com_rslt;
+}
+ /*!
+ * @brief This API reads Data source for the
+ * interrupt engine for the nomotion and anymotion interrupts
+ * from the register 0x59 bit 7
+ *
+ * @param v_motion_source_u8 :
+ * The value of the any/no motion interrupt source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_motion_source(
+u8 *v_motion_source_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the any/no motion interrupt */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_DATA_1_INTR_MOTION_SOURCE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_motion_source_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_DATA_1_INTR_MOTION_SOURCE);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write Data source for the
+ * interrupt engine for the nomotion and anymotion interrupts
+ * from the register 0x59 bit 7
+ *
+ * @param v_motion_source_u8 :
+ * The value of the any/no motion interrupt source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_motion_source(
+u8 v_motion_source_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_motion_source_u8 <= BMI160_MAX_VALUE_SOURCE_INTR) {
+ /* write the any/no motion interrupt */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_DATA_1_INTR_MOTION_SOURCE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_DATA_1_INTR_MOTION_SOURCE,
+ v_motion_source_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_DATA_1_INTR_MOTION_SOURCE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API is used to read the low_g duration from register
+ * 0x5A bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_low_g_durn_u8 : The value of low_g duration
+ *
+ * @note Low_g duration trigger trigger delay according to
+ * "(v_low_g_durn_u8 * 2.5)ms" in a range from 2.5ms to 640ms.
+ * the default corresponds delay is 20ms
+ * @note When low_g data source of interrupt is unfiltered
+ * the sensor must not be in low power mode
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_low_g_durn(
+u8 *v_low_g_durn_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the low_g interrupt */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_LOWHIGH_0_INTR_LOW_DURN__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_low_g_durn_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_LOWHIGH_0_INTR_LOW_DURN);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API is used to write the low_g duration from register
+ * 0x5A bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_low_g_durn_u8 : The value of low_g duration
+ *
+ * @note Low_g duration trigger trigger delay according to
+ * "(v_low_g_durn_u8 * 2.5)ms" in a range from 2.5ms to 640ms.
+ * the default corresponds delay is 20ms
+ * @note When low_g data source of interrupt is unfiltered
+ * the sensor must not be in low power mode
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_low_g_durn(u8 v_low_g_durn_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* write the low_g interrupt */
+ com_rslt = p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_LOWHIGH_0_INTR_LOW_DURN__REG,
+ &v_low_g_durn_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read Threshold
+ * definition for the low-g interrupt from the register 0x5B bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_low_g_thres_u8 : The value of low_g threshold
+ *
+ * @note Low_g interrupt trigger threshold according to
+ * (v_low_g_thres_u8 * 7.81)mg for v_low_g_thres_u8 > 0
+ * 3.91 mg for v_low_g_thres_u8 = 0
+ * The threshold range is form 3.91mg to 2.000mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_low_g_thres(
+u8 *v_low_g_thres_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read low_g threshold */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_LOWHIGH_1_INTR_LOW_THRES__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_low_g_thres_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_LOWHIGH_1_INTR_LOW_THRES);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to write Threshold
+ * definition for the low-g interrupt from the register 0x5B bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_low_g_thres_u8 : The value of low_g threshold
+ *
+ * @note Low_g interrupt trigger threshold according to
+ * (v_low_g_thres_u8 * 7.81)mg for v_low_g_thres_u8 > 0
+ * 3.91 mg for v_low_g_thres_u8 = 0
+ * The threshold range is form 3.91mg to 2.000mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_low_g_thres(
+u8 v_low_g_thres_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* write low_g threshold */
+ com_rslt = p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_LOWHIGH_1_INTR_LOW_THRES__REG,
+ &v_low_g_thres_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API Reads Low-g interrupt hysteresis
+ * from the register 0x5C bit 0 to 1
+ *
+ * @param v_low_hyst_u8 :The value of low_g hysteresis
+ *
+ * @note Low_g hysteresis calculated by v_low_hyst_u8*125 mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_low_g_hyst(
+u8 *v_low_hyst_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read low_g hysteresis*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_low_hyst_u8 = BMI160_GET_BITSLICE(
+ v_data_u8,
+ BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write Low-g interrupt hysteresis
+ * from the register 0x5C bit 0 to 1
+ *
+ * @param v_low_hyst_u8 :The value of low_g hysteresis
+ *
+ * @note Low_g hysteresis calculated by v_low_hyst_u8*125 mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_low_g_hyst(
+u8 v_low_hyst_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* write low_g hysteresis*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST,
+ v_low_hyst_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads Low-g interrupt mode
+ * from the register 0x5C bit 2
+ *
+ * @param v_low_g_mode_u8 : The value of low_g mode
+ * Value | Description
+ * ----------|-----------------
+ * 0 | single-axis
+ * 1 | axis-summing
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_low_g_mode(u8 *v_low_g_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /*read Low-g interrupt mode*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_low_g_mode_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write Low-g interrupt mode
+ * from the register 0x5C bit 2
+ *
+ * @param v_low_g_mode_u8 : The value of low_g mode
+ * Value | Description
+ * ----------|-----------------
+ * 0 | single-axis
+ * 1 | axis-summing
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_low_g_mode(
+u8 v_low_g_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_low_g_mode_u8 <= BMI160_MAX_VALUE_LOW_G_MODE) {
+ /*write Low-g interrupt mode*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE,
+ v_low_g_mode_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads High-g interrupt hysteresis
+ * from the register 0x5C bit 6 and 7
+ *
+ * @param v_high_g_hyst_u8 : The value of high hysteresis
+ *
+ * @note High_g hysteresis changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | high_g hysteresis
+ * ----------------|---------------------
+ * 2g | high_hy*125 mg
+ * 4g | high_hy*250 mg
+ * 8g | high_hy*500 mg
+ * 16g | high_hy*1000 mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_high_g_hyst(
+u8 *v_high_g_hyst_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read high_g hysteresis*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_high_g_hyst_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write High-g interrupt hysteresis
+ * from the register 0x5C bit 6 and 7
+ *
+ * @param v_high_g_hyst_u8 : The value of high hysteresis
+ *
+ * @note High_g hysteresis changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | high_g hysteresis
+ * ----------------|---------------------
+ * 2g | high_hy*125 mg
+ * 4g | high_hy*250 mg
+ * 8g | high_hy*500 mg
+ * 16g | high_hy*1000 mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_high_g_hyst(
+u8 v_high_g_hyst_u8)
+{
+/* variable used for return the status of communication result*/
+BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* write high_g hysteresis*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST,
+ v_high_g_hyst_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+return com_rslt;
+}
+/*!
+ * @brief This API is used to read Delay
+ * time definition for the high-g interrupt from the register
+ * 0x5D bit 0 to 7
+ *
+ *
+ *
+ * @param v_high_g_durn_u8 : The value of high duration
+ *
+ * @note High_g interrupt delay triggered according to
+ * v_high_g_durn_u8 * 2.5ms in a range from 2.5ms to 640ms
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_high_g_durn(
+u8 *v_high_g_durn_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read high_g duration*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_LOWHIGH_3_INTR_HIGH_G_DURN__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_high_g_durn_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_LOWHIGH_3_INTR_HIGH_G_DURN);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to write Delay
+ * time definition for the high-g interrupt from the register
+ * 0x5D bit 0 to 7
+ *
+ *
+ *
+ * @param v_high_g_durn_u8 : The value of high duration
+ *
+ * @note High_g interrupt delay triggered according to
+ * v_high_g_durn_u8 * 2.5ms in a range from 2.5ms to 640ms
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_high_g_durn(
+u8 v_high_g_durn_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* write high_g duration*/
+ com_rslt = p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_LOWHIGH_3_INTR_HIGH_G_DURN__REG,
+ &v_high_g_durn_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read Threshold
+ * definition for the high-g interrupt from the register 0x5E 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_high_g_thres_u8 : Pointer holding the value of Threshold
+ * @note High_g threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | high_g threshold
+ * ----------------|---------------------
+ * 2g | v_high_g_thres_u8*7.81 mg
+ * 4g | v_high_g_thres_u8*15.63 mg
+ * 8g | v_high_g_thres_u8*31.25 mg
+ * 16g | v_high_g_thres_u8*62.5 mg
+ * @note when v_high_g_thres_u8 = 0
+ * accel_range | high_g threshold
+ * ----------------|---------------------
+ * 2g | 3.91 mg
+ * 4g | 7.81 mg
+ * 8g | 15.63 mg
+ * 16g | 31.25 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_high_g_thres(
+u8 *v_high_g_thres_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_LOWHIGH_4_INTR_HIGH_THRES__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_high_g_thres_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_LOWHIGH_4_INTR_HIGH_THRES);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to write Threshold
+ * definition for the high-g interrupt from the register 0x5E 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_high_g_thres_u8 : Pointer holding the value of Threshold
+ * @note High_g threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | high_g threshold
+ * ----------------|---------------------
+ * 2g | v_high_g_thres_u8*7.81 mg
+ * 4g | v_high_g_thres_u8*15.63 mg
+ * 8g | v_high_g_thres_u8*31.25 mg
+ * 16g | v_high_g_thres_u8*62.5 mg
+ * @note when v_high_g_thres_u8 = 0
+ * accel_range | high_g threshold
+ * ----------------|---------------------
+ * 2g | 3.91 mg
+ * 4g | 7.81 mg
+ * 8g | 15.63 mg
+ * 16g | 31.25 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_high_g_thres(
+u8 v_high_g_thres_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ com_rslt = p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_LOWHIGH_4_INTR_HIGH_THRES__REG,
+ &v_high_g_thres_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads any motion duration
+ * from the register 0x5F bit 0 and 1
+ *
+ * @param v_any_motion_durn_u8 : The value of any motion duration
+ *
+ * @note Any motion duration can be calculated by "v_any_motion_durn_u8 + 1"
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_any_motion_durn(
+u8 *v_any_motion_durn_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read any motion duration*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_any_motion_durn_u8 = BMI160_GET_BITSLICE
+ (v_data_u8,
+ BMI160_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write any motion duration
+ * from the register 0x5F bit 0 and 1
+ *
+ * @param v_any_motion_durn_u8 : The value of any motion duration
+ *
+ * @note Any motion duration can be calculated by "v_any_motion_durn_u8 + 1"
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_any_motion_durn(
+u8 v_any_motion_durn_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* write any motion duration*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN,
+ v_any_motion_durn_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API read Slow/no-motion
+ * interrupt trigger delay duration from the register 0x5F bit 2 to 7
+ *
+ * @param v_slow_no_motion_u8 :The value of slow no motion duration
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ * @note
+ * @note v_slow_no_motion_u8(5:4)=0b00 ->
+ * [v_slow_no_motion_u8(3:0) + 1] * 1.28s (1.28s-20.48s)
+ * @note v_slow_no_motion_u8(5:4)=1 ->
+ * [v_slow_no_motion_u8(3:0)+5] * 5.12s (25.6s-102.4s)
+ * @note v_slow_no_motion_u8(5)='1' ->
+ * [(v_slow_no_motion_u8:0)+11] * 10.24s (112.64s-430.08s);
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_slow_no_motion_durn(
+u8 *v_slow_no_motion_u8)
+{
+/* variable used for return the status of communication result*/
+BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read slow no motion duration*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_slow_no_motion_u8 = BMI160_GET_BITSLICE
+ (v_data_u8,
+ BMI160_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN);
+ }
+return com_rslt;
+}
+ /*!
+ * @brief This API write Slow/no-motion
+ * interrupt trigger delay duration from the register 0x5F bit 2 to 7
+ *
+ * @param v_slow_no_motion_u8 :The value of slow no motion duration
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ * @note
+ * @note v_slow_no_motion_u8(5:4)=0b00 ->
+ * [v_slow_no_motion_u8(3:0) + 1] * 1.28s (1.28s-20.48s)
+ * @note v_slow_no_motion_u8(5:4)=1 ->
+ * [v_slow_no_motion_u8(3:0)+5] * 5.12s (25.6s-102.4s)
+ * @note v_slow_no_motion_u8(5)='1' ->
+ * [(v_slow_no_motion_u8:0)+11] * 10.24s (112.64s-430.08s);
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_slow_no_motion_durn(
+u8 v_slow_no_motion_u8)
+{
+/* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* write slow no motion duration*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE
+ (v_data_u8,
+ BMI160_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN,
+ v_slow_no_motion_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+}
+return com_rslt;
+}
+/*!
+ * @brief This API is used to read threshold
+ * definition for the any-motion interrupt
+ * from the register 0x60 bit 0 to 7
+ *
+ *
+ * @param v_any_motion_thres_u8 : The value of any motion threshold
+ *
+ * @note any motion threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | any motion threshold
+ * ----------------|---------------------
+ * 2g | v_any_motion_thres_u8*3.91 mg
+ * 4g | v_any_motion_thres_u8*7.81 mg
+ * 8g | v_any_motion_thres_u8*15.63 mg
+ * 16g | v_any_motion_thres_u8*31.25 mg
+ * @note when v_any_motion_thres_u8 = 0
+ * accel_range | any motion threshold
+ * ----------------|---------------------
+ * 2g | 1.95 mg
+ * 4g | 3.91 mg
+ * 8g | 7.81 mg
+ * 16g | 15.63 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_any_motion_thres(
+u8 *v_any_motion_thres_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read any motion threshold*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_MOTION_1_INTR_ANY_MOTION_THRES__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_any_motion_thres_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MOTION_1_INTR_ANY_MOTION_THRES);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to write threshold
+ * definition for the any-motion interrupt
+ * from the register 0x60 bit 0 to 7
+ *
+ *
+ * @param v_any_motion_thres_u8 : The value of any motion threshold
+ *
+ * @note any motion threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | any motion threshold
+ * ----------------|---------------------
+ * 2g | v_any_motion_thres_u8*3.91 mg
+ * 4g | v_any_motion_thres_u8*7.81 mg
+ * 8g | v_any_motion_thres_u8*15.63 mg
+ * 16g | v_any_motion_thres_u8*31.25 mg
+ * @note when v_any_motion_thres_u8 = 0
+ * accel_range | any motion threshold
+ * ----------------|---------------------
+ * 2g | 1.95 mg
+ * 4g | 3.91 mg
+ * 8g | 7.81 mg
+ * 16g | 15.63 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_any_motion_thres(
+u8 v_any_motion_thres_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* write any motion threshold*/
+ com_rslt = p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_MOTION_1_INTR_ANY_MOTION_THRES__REG,
+ &v_any_motion_thres_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API is used to read threshold
+ * for the slow/no-motion interrupt
+ * from the register 0x61 bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_slow_no_motion_thres_u8 : The value of slow no motion threshold
+ * @note slow no motion threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | slow no motion threshold
+ * ----------------|---------------------
+ * 2g | v_slow_no_motion_thres_u8*3.91 mg
+ * 4g | v_slow_no_motion_thres_u8*7.81 mg
+ * 8g | v_slow_no_motion_thres_u8*15.63 mg
+ * 16g | v_slow_no_motion_thres_u8*31.25 mg
+ * @note when v_slow_no_motion_thres_u8 = 0
+ * accel_range | slow no motion threshold
+ * ----------------|---------------------
+ * 2g | 1.95 mg
+ * 4g | 3.91 mg
+ * 8g | 7.81 mg
+ * 16g | 15.63 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_slow_no_motion_thres(
+u8 *v_slow_no_motion_thres_u8)
+{
+BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read slow no motion threshold*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_MOTION_2_INTR_SLOW_NO_MOTION_THRES__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_slow_no_motion_thres_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MOTION_2_INTR_SLOW_NO_MOTION_THRES);
+ }
+return com_rslt;
+}
+ /*!
+ * @brief This API is used to write threshold
+ * for the slow/no-motion interrupt
+ * from the register 0x61 bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_slow_no_motion_thres_u8 : The value of slow no motion threshold
+ * @note slow no motion threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | slow no motion threshold
+ * ----------------|---------------------
+ * 2g | v_slow_no_motion_thres_u8*3.91 mg
+ * 4g | v_slow_no_motion_thres_u8*7.81 mg
+ * 8g | v_slow_no_motion_thres_u8*15.63 mg
+ * 16g | v_slow_no_motion_thres_u8*31.25 mg
+ * @note when v_slow_no_motion_thres_u8 = 0
+ * accel_range | slow no motion threshold
+ * ----------------|---------------------
+ * 2g | 1.95 mg
+ * 4g | 3.91 mg
+ * 8g | 7.81 mg
+ * 16g | 15.63 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_slow_no_motion_thres(
+u8 v_slow_no_motion_thres_u8)
+{
+BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* write slow no motion threshold*/
+ com_rslt = p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_MOTION_2_INTR_SLOW_NO_MOTION_THRES__REG,
+ &v_slow_no_motion_thres_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+return com_rslt;
+}
+ /*!
+ * @brief This API is used to read
+ * the slow/no-motion selection from the register 0x62 bit 0
+ *
+ *
+ *
+ *
+ * @param v_intr_slow_no_motion_select_u8 :
+ * The value of slow/no-motion select
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | SLOW_MOTION
+ * 0x01 | NO_MOTION
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_slow_no_motion_select(
+u8 *v_intr_slow_no_motion_select_u8)
+{
+BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read slow no motion select*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_slow_no_motion_select_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT);
+ }
+return com_rslt;
+}
+ /*!
+ * @brief This API is used to write
+ * the slow/no-motion selection from the register 0x62 bit 0
+ *
+ *
+ *
+ *
+ * @param v_intr_slow_no_motion_select_u8 :
+ * The value of slow/no-motion select
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | SLOW_MOTION
+ * 0x01 | NO_MOTION
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_slow_no_motion_select(
+u8 v_intr_slow_no_motion_select_u8)
+{
+/* variable used for return the status of communication result*/
+BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+} else {
+if (v_intr_slow_no_motion_select_u8 <= BMI160_MAX_VALUE_NO_MOTION) {
+ /* write slow no motion select*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT,
+ v_intr_slow_no_motion_select_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+} else {
+com_rslt = E_BMI160_OUT_OF_RANGE;
+}
+}
+return com_rslt;
+}
+ /*!
+ * @brief This API is used to select
+ * the significant or any motion interrupt from the register 0x62 bit 1
+ *
+ *
+ *
+ *
+ * @param v_intr_significant_motion_select_u8 :
+ * the value of significant or any motion interrupt selection
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | ANY_MOTION
+ * 0x01 | SIGNIFICANT_MOTION
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_significant_motion_select(
+u8 *v_intr_significant_motion_select_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the significant or any motion interrupt*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_SIGNIFICATION_MOTION_SELECT__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_significant_motion_select_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_SIGNIFICATION_MOTION_SELECT);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API is used to write, select
+ * the significant or any motion interrupt from the register 0x62 bit 1
+ *
+ *
+ *
+ *
+ * @param v_intr_significant_motion_select_u8 :
+ * the value of significant or any motion interrupt selection
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | ANY_MOTION
+ * 0x01 | SIGNIFICANT_MOTION
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_significant_motion_select(
+u8 v_intr_significant_motion_select_u8)
+{
+/* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_intr_significant_motion_select_u8 <=
+ BMI160_MAX_VALUE_SIGNIFICANT_MOTION) {
+ /* write the significant or any motion interrupt*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_SIGNIFICATION_MOTION_SELECT__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_SIGNIFICATION_MOTION_SELECT,
+ v_intr_significant_motion_select_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_SIGNIFICATION_MOTION_SELECT__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+}
+return com_rslt;
+}
+ /*!
+ * @brief This API is used to read
+ * the significant skip time from the register 0x62 bit 2 and 3
+ *
+ *
+ *
+ *
+ * @param v_int_sig_mot_skip_u8 : the value of significant skip time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | skip time 1.5 seconds
+ * 0x01 | skip time 3 seconds
+ * 0x02 | skip time 6 seconds
+ * 0x03 | skip time 12 seconds
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_significant_motion_skip(
+u8 *v_int_sig_mot_skip_u8)
+{
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read significant skip time*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_SIGNIFICANT_MOTION_SKIP__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_int_sig_mot_skip_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_SIGNIFICANT_MOTION_SKIP);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API is used to write
+ * the significant skip time from the register 0x62 bit 2 and 3
+ *
+ *
+ *
+ *
+ * @param v_int_sig_mot_skip_u8 : the value of significant skip time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | skip time 1.5 seconds
+ * 0x01 | skip time 3 seconds
+ * 0x02 | skip time 6 seconds
+ * 0x03 | skip time 12 seconds
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_significant_motion_skip(
+u8 v_int_sig_mot_skip_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_int_sig_mot_skip_u8 <= BMI160_MAX_UNDER_SIG_MOTION) {
+ /* write significant skip time*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_SIGNIFICANT_MOTION_SKIP__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_SIGNIFICANT_MOTION_SKIP,
+ v_int_sig_mot_skip_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_SIGNIFICANT_MOTION_SKIP__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API is used to read
+ * the significant proof time from the register 0x62 bit 4 and 5
+ *
+ *
+ *
+ *
+ * @param v_significant_motion_proof_u8 :
+ * the value of significant proof time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | proof time 0.25 seconds
+ * 0x01 | proof time 0.5 seconds
+ * 0x02 | proof time 1 seconds
+ * 0x03 | proof time 2 seconds
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_significant_motion_proof(
+u8 *v_significant_motion_proof_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read significant proof time */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_SIGNIFICANT_MOTION_PROOF__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_significant_motion_proof_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_SIGNIFICANT_MOTION_PROOF);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API is used to write
+ * the significant proof time from the register 0x62 bit 4 and 5
+ *
+ *
+ *
+ *
+ * @param v_significant_motion_proof_u8 :
+ * the value of significant proof time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | proof time 0.25 seconds
+ * 0x01 | proof time 0.5 seconds
+ * 0x02 | proof time 1 seconds
+ * 0x03 | proof time 2 seconds
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_significant_motion_proof(
+u8 v_significant_motion_proof_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_significant_motion_proof_u8
+ <= BMI160_MAX_UNDER_SIG_MOTION) {
+ /* write significant proof time */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_SIGNIFICANT_MOTION_PROOF__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_SIGNIFICANT_MOTION_PROOF,
+ v_significant_motion_proof_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_SIGNIFICANT_MOTION_PROOF__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to get the tap duration
+ * from the register 0x63 bit 0 to 2
+ *
+ *
+ *
+ * @param v_tap_durn_u8 : The value of tap duration
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | BMI160_TAP_DURN_50MS
+ * 0x01 | BMI160_TAP_DURN_100MS
+ * 0x03 | BMI160_TAP_DURN_150MS
+ * 0x04 | BMI160_TAP_DURN_200MS
+ * 0x05 | BMI160_TAP_DURN_250MS
+ * 0x06 | BMI160_TAP_DURN_375MS
+ * 0x07 | BMI160_TAP_DURN_700MS
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_tap_durn(
+u8 *v_tap_durn_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read tap duration*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_TAP_0_INTR_TAP_DURN__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_tap_durn_u8 = BMI160_GET_BITSLICE(
+ v_data_u8,
+ BMI160_USER_INTR_TAP_0_INTR_TAP_DURN);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to write the tap duration
+ * from the register 0x63 bit 0 to 2
+ *
+ *
+ *
+ * @param v_tap_durn_u8 : The value of tap duration
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | BMI160_TAP_DURN_50MS
+ * 0x01 | BMI160_TAP_DURN_100MS
+ * 0x03 | BMI160_TAP_DURN_150MS
+ * 0x04 | BMI160_TAP_DURN_200MS
+ * 0x05 | BMI160_TAP_DURN_250MS
+ * 0x06 | BMI160_TAP_DURN_375MS
+ * 0x07 | BMI160_TAP_DURN_700MS
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_tap_durn(
+u8 v_tap_durn_u8)
+{
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_tap_durn_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_tap_durn_u8 <= BMI160_MAX_TAP_TURN) {
+ switch (v_tap_durn_u8) {
+ case BMI160_TAP_DURN_50MS:
+ v_data_tap_durn_u8 = BMI160_TAP_DURN_50MS;
+ break;
+ case BMI160_TAP_DURN_100MS:
+ v_data_tap_durn_u8 = BMI160_TAP_DURN_100MS;
+ break;
+ case BMI160_TAP_DURN_150MS:
+ v_data_tap_durn_u8 = BMI160_TAP_DURN_150MS;
+ break;
+ case BMI160_TAP_DURN_200MS:
+ v_data_tap_durn_u8 = BMI160_TAP_DURN_200MS;
+ break;
+ case BMI160_TAP_DURN_250MS:
+ v_data_tap_durn_u8 = BMI160_TAP_DURN_250MS;
+ break;
+ case BMI160_TAP_DURN_375MS:
+ v_data_tap_durn_u8 = BMI160_TAP_DURN_375MS;
+ break;
+ case BMI160_TAP_DURN_500MS:
+ v_data_tap_durn_u8 = BMI160_TAP_DURN_500MS;
+ break;
+ case BMI160_TAP_DURN_700MS:
+ v_data_tap_durn_u8 = BMI160_TAP_DURN_700MS;
+ break;
+ default:
+ break;
+ }
+ /* write tap duration*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_TAP_0_INTR_TAP_DURN__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_TAP_0_INTR_TAP_DURN,
+ v_data_tap_durn_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_TAP_0_INTR_TAP_DURN__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API read the
+ * tap shock duration from the register 0x63 bit 2
+ *
+ * @param v_tap_shock_u8 :The value of tap shock
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | BMI160_TAP_SHOCK_50MS
+ * 0x01 | BMI160_TAP_SHOCK_75MS
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_tap_shock(
+u8 *v_tap_shock_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read tap shock duration*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_TAP_0_INTR_TAP_SHOCK__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_tap_shock_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_TAP_0_INTR_TAP_SHOCK);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write the
+ * tap shock duration from the register 0x63 bit 2
+ *
+ * @param v_tap_shock_u8 :The value of tap shock
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | BMI160_TAP_SHOCK_50MS
+ * 0x01 | BMI160_TAP_SHOCK_75MS
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_tap_shock(u8 v_tap_shock_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_tap_shock_u8 <= BMI160_MAX_VALUE_TAP_SHOCK) {
+ /* write tap shock duration*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_TAP_0_INTR_TAP_SHOCK__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_TAP_0_INTR_TAP_SHOCK,
+ v_tap_shock_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_TAP_0_INTR_TAP_SHOCK__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read
+ * tap quiet duration from the register 0x63 bit 7
+ *
+ *
+ * @param v_tap_quiet_u8 : The value of tap quiet
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | BMI160_TAP_QUIET_30MS
+ * 0x01 | BMI160_TAP_QUIET_20MS
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_tap_quiet(
+u8 *v_tap_quiet_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read tap quiet duration*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_TAP_0_INTR_TAP_QUIET__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_tap_quiet_u8 = BMI160_GET_BITSLICE(
+ v_data_u8,
+ BMI160_USER_INTR_TAP_0_INTR_TAP_QUIET);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write
+ * tap quiet duration from the register 0x63 bit 7
+ *
+ *
+ * @param v_tap_quiet_u8 : The value of tap quiet
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | BMI160_TAP_QUIET_30MS
+ * 0x01 | BMI160_TAP_QUIET_20MS
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_tap_quiet(u8 v_tap_quiet_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_tap_quiet_u8 <= BMI160_MAX_VALUE_TAP_QUIET) {
+ /* write tap quiet duration*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_TAP_0_INTR_TAP_QUIET__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_TAP_0_INTR_TAP_QUIET,
+ v_tap_quiet_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_TAP_0_INTR_TAP_QUIET__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API read Threshold of the
+ * single/double tap interrupt from the register 0x64 bit 0 to 4
+ *
+ *
+ * @param v_tap_thres_u8 : The value of single/double tap threshold
+ *
+ * @note single/double tap threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | single/double tap threshold
+ * ----------------|---------------------
+ * 2g | ((v_tap_thres_u8 + 1) * 62.5)mg
+ * 4g | ((v_tap_thres_u8 + 1) * 125)mg
+ * 8g | ((v_tap_thres_u8 + 1) * 250)mg
+ * 16g | ((v_tap_thres_u8 + 1) * 500)mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_tap_thres(
+u8 *v_tap_thres_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read tap threshold*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_TAP_1_INTR_TAP_THRES__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_tap_thres_u8 = BMI160_GET_BITSLICE
+ (v_data_u8,
+ BMI160_USER_INTR_TAP_1_INTR_TAP_THRES);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write Threshold of the
+ * single/double tap interrupt from the register 0x64 bit 0 to 4
+ *
+ *
+ * @param v_tap_thres_u8 : The value of single/double tap threshold
+ *
+ * @note single/double tap threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | single/double tap threshold
+ * ----------------|---------------------
+ * 2g | ((v_tap_thres_u8 + 1) * 62.5)mg
+ * 4g | ((v_tap_thres_u8 + 1) * 125)mg
+ * 8g | ((v_tap_thres_u8 + 1) * 250)mg
+ * 16g | ((v_tap_thres_u8 + 1) * 500)mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_tap_thres(
+u8 v_tap_thres_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* write tap threshold*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_TAP_1_INTR_TAP_THRES__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_TAP_1_INTR_TAP_THRES,
+ v_tap_thres_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_TAP_1_INTR_TAP_THRES__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API read the threshold for orientation interrupt
+ * from the register 0x65 bit 0 and 1
+ *
+ * @param v_orient_mode_u8 : The value of threshold for orientation
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | symmetrical
+ * 0x01 | high-asymmetrical
+ * 0x02 | low-asymmetrical
+ * 0x03 | symmetrical
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_orient_mode(
+u8 *v_orient_mode_u8)
+{
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read orientation threshold*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_MODE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_orient_mode_u8 = BMI160_GET_BITSLICE
+ (v_data_u8,
+ BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_MODE);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write the threshold for orientation interrupt
+ * from the register 0x65 bit 0 and 1
+ *
+ * @param v_orient_mode_u8 : The value of threshold for orientation
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | symmetrical
+ * 0x01 | high-asymmetrical
+ * 0x02 | low-asymmetrical
+ * 0x03 | symmetrical
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_orient_mode(
+u8 v_orient_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_orient_mode_u8 <= BMI160_MAX_ORIENT_MODE) {
+ /* write orientation threshold*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_MODE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_MODE,
+ v_orient_mode_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_MODE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read the orient blocking mode
+ * that is used for the generation of the orientation interrupt.
+ * from the register 0x65 bit 2 and 3
+ *
+ * @param v_orient_blocking_u8 : The value of orient blocking mode
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | No blocking
+ * 0x01 | Theta blocking or acceleration in any axis > 1.5g
+ * 0x02 | Theta blocking or acceleration slope in any axis >
+ * - | 0.2g or acceleration in any axis > 1.5g
+ * 0x03 | Theta blocking or acceleration slope in any axis >
+ * - | 0.4g or acceleration in any axis >
+ * - | 1.5g and value of orient is not stable
+ * - | for at least 100 ms
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_orient_blocking(
+u8 *v_orient_blocking_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read orient blocking mode*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_orient_blocking_u8 = BMI160_GET_BITSLICE
+ (v_data_u8,
+ BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write the orient blocking mode
+ * that is used for the generation of the orientation interrupt.
+ * from the register 0x65 bit 2 and 3
+ *
+ * @param v_orient_blocking_u8 : The value of orient blocking mode
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | No blocking
+ * 0x01 | Theta blocking or acceleration in any axis > 1.5g
+ * 0x02 | Theta blocking or acceleration slope in any axis >
+ * - | 0.2g or acceleration in any axis > 1.5g
+ * 0x03 | Theta blocking or acceleration slope in any axis >
+ * - | 0.4g or acceleration in any axis >
+ * - | 1.5g and value of orient is not stable
+ * - | for at least 100 ms
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_orient_blocking(
+u8 v_orient_blocking_u8)
+{
+/* variable used for return the status of communication result*/
+BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_orient_blocking_u8 <= BMI160_MAX_ORIENT_BLOCKING) {
+ /* write orient blocking mode*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING,
+ v_orient_blocking_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+}
+return com_rslt;
+}
+/*!
+ * @brief This API read Orient interrupt
+ * hysteresis, from the register 0x64 bit 4 to 7
+ *
+ *
+ *
+ * @param v_orient_hyst_u8 : The value of orient hysteresis
+ *
+ * @note 1 LSB corresponds to 62.5 mg,
+ * irrespective of the selected accel range
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_orient_hyst(
+u8 *v_orient_hyst_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read orient hysteresis*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_HYST__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_orient_hyst_u8 = BMI160_GET_BITSLICE
+ (v_data_u8,
+ BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_HYST);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write Orient interrupt
+ * hysteresis, from the register 0x64 bit 4 to 7
+ *
+ *
+ *
+ * @param v_orient_hyst_u8 : The value of orient hysteresis
+ *
+ * @note 1 LSB corresponds to 62.5 mg,
+ * irrespective of the selected accel range
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_orient_hyst(
+u8 v_orient_hyst_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* write orient hysteresis*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_HYST__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_HYST,
+ v_orient_hyst_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_HYST__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API read Orient
+ * blocking angle (0 to 44.8) from the register 0x66 bit 0 to 5
+ *
+ * @param v_orient_theta_u8 : The value of Orient blocking angle
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_orient_theta(
+u8 *v_orient_theta_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read Orient blocking angle*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_THETA__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_orient_theta_u8 = BMI160_GET_BITSLICE
+ (v_data_u8,
+ BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_THETA);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write Orient
+ * blocking angle (0 to 44.8) from the register 0x66 bit 0 to 5
+ *
+ * @param v_orient_theta_u8 : The value of Orient blocking angle
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_orient_theta(
+u8 v_orient_theta_u8)
+{
+/* variable used for return the status of communication result*/
+BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_orient_theta_u8 <= BMI160_MAX_ORIENT_THETA) {
+ /* write Orient blocking angle*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_THETA__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_THETA,
+ v_orient_theta_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_THETA__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+}
+return com_rslt;
+}
+/*!
+ * @brief This API read orient change
+ * of up/down bit from the register 0x66 bit 6
+ *
+ * @param v_orient_ud_u8 : The value of orient change of up/down
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | Is ignored
+ * 0x01 | Generates orientation interrupt
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_orient_ud_enable(
+u8 *v_orient_ud_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read orient up/down enable*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_orient_ud_u8 = BMI160_GET_BITSLICE
+ (v_data_u8,
+ BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write orient change
+ * of up/down bit from the register 0x66 bit 6
+ *
+ * @param v_orient_ud_u8 : The value of orient change of up/down
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | Is ignored
+ * 0x01 | Generates orientation interrupt
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_orient_ud_enable(
+u8 v_orient_ud_u8)
+{
+/* variable used for return the status of communication result*/
+BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_orient_ud_u8 <= BMI160_MAX_VALUE_ORIENT_UD) {
+ /* write orient up/down enable */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE,
+ v_orient_ud_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+}
+return com_rslt;
+}
+ /*!
+ * @brief This API read orientation axes changes
+ * from the register 0x66 bit 7
+ *
+ * @param v_orient_axes_u8 : The value of orient axes assignment
+ * value | Behaviour | Name
+ * ----------|--------------------|------
+ * 0x00 | x = x, y = y, z = z|orient_ax_noex
+ * 0x01 | x = y, y = z, z = x|orient_ax_ex
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_orient_axes_enable(
+u8 *v_orient_axes_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read orientation axes changes */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_orient_axes_u8 = BMI160_GET_BITSLICE
+ (v_data_u8,
+ BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write orientation axes changes
+ * from the register 0x66 bit 7
+ *
+ * @param v_orient_axes_u8 : The value of orient axes assignment
+ * value | Behaviour | Name
+ * ----------|--------------------|------
+ * 0x00 | x = x, y = y, z = z|orient_ax_noex
+ * 0x01 | x = y, y = z, z = x|orient_ax_ex
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_orient_axes_enable(
+u8 v_orient_axes_u8)
+{
+/* variable used for return the status of communication result*/
+BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_orient_axes_u8 <= BMI160_MAX_VALUE_ORIENT_AXES) {
+ /*write orientation axes changes */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX,
+ v_orient_axes_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+}
+return com_rslt;
+}
+ /*!
+ * @brief This API read Flat angle (0 to 44.8) for flat interrupt
+ * from the register 0x67 bit 0 to 5
+ *
+ * @param v_flat_theta_u8 : The value of flat angle
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_flat_theta(
+u8 *v_flat_theta_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read Flat angle*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_FLAT_0_INTR_FLAT_THETA__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_flat_theta_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_FLAT_0_INTR_FLAT_THETA);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write Flat angle (0 to 44.8) for flat interrupt
+ * from the register 0x67 bit 0 to 5
+ *
+ * @param v_flat_theta_u8 : The value of flat angle
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_flat_theta(
+u8 v_flat_theta_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_flat_theta_u8 <= BMI160_MAX_FLAT_THETA) {
+ /* write Flat angle */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_FLAT_0_INTR_FLAT_THETA__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_FLAT_0_INTR_FLAT_THETA,
+ v_flat_theta_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_FLAT_0_INTR_FLAT_THETA__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read Flat interrupt hold time;
+ * from the register 0x68 bit 4 and 5
+ *
+ * @param v_flat_hold_u8 : The value of flat hold time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | 0ms
+ * 0x01 | 512ms
+ * 0x01 | 1024ms
+ * 0x01 | 2048ms
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_flat_hold(
+u8 *v_flat_hold_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read flat hold time*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_FLAT_1_INTR_FLAT_HOLD__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_flat_hold_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_FLAT_1_INTR_FLAT_HOLD);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write Flat interrupt hold time;
+ * from the register 0x68 bit 4 and 5
+ *
+ * @param v_flat_hold_u8 : The value of flat hold time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | 0ms
+ * 0x01 | 512ms
+ * 0x01 | 1024ms
+ * 0x01 | 2048ms
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_flat_hold(
+u8 v_flat_hold_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_flat_hold_u8 <= BMI160_MAX_FLAT_HOLD) {
+ /* write flat hold time*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_FLAT_1_INTR_FLAT_HOLD__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_FLAT_1_INTR_FLAT_HOLD,
+ v_flat_hold_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_FLAT_1_INTR_FLAT_HOLD__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read flat interrupt hysteresis
+ * from the register 0x68 bit 0 to 3
+ *
+ * @param v_flat_hyst_u8 : The value of flat hysteresis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_flat_hyst(
+u8 *v_flat_hyst_u8)
+{
+ /* variable used to return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the flat hysteresis*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_INTR_FLAT_1_INTR_FLAT_HYST__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_flat_hyst_u8 = BMI160_GET_BITSLICE(
+ v_data_u8,
+ BMI160_USER_INTR_FLAT_1_INTR_FLAT_HYST);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write flat interrupt hysteresis
+ * from the register 0x68 bit 0 to 3
+ *
+ * @param v_flat_hyst_u8 : The value of flat hysteresis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_flat_hyst(
+u8 v_flat_hyst_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_flat_hyst_u8 <= BMI160_MAX_FLAT_HYST) {
+ /* read the flat hysteresis*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_FLAT_1_INTR_FLAT_HYST__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_INTR_FLAT_1_INTR_FLAT_HYST,
+ v_flat_hyst_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_INTR_FLAT_1_INTR_FLAT_HYST__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API read accel offset compensation
+ * target value for z-axis from the register 0x69 bit 0 and 1
+ *
+ * @param v_foc_accel_z_u8 : the value of accel offset compensation z axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_foc_accel_z(u8 *v_foc_accel_z_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the accel offset compensation for z axis*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_FOC_ACCEL_Z__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_foc_accel_z_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_FOC_ACCEL_Z);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write accel offset compensation
+ * target value for z-axis from the register 0x69 bit 0 and 1
+ *
+ * @param v_foc_accel_z_u8 : the value of accel offset compensation z axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_foc_accel_z(
+u8 v_foc_accel_z_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* write the accel offset compensation for z axis*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_FOC_ACCEL_Z__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_FOC_ACCEL_Z,
+ v_foc_accel_z_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_FOC_ACCEL_Z__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read accel offset compensation
+ * target value for y-axis
+ * from the register 0x69 bit 2 and 3
+ *
+ * @param v_foc_accel_y_u8 : the value of accel offset compensation y axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_foc_accel_y(u8 *v_foc_accel_y_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the accel offset compensation for y axis*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_FOC_ACCEL_Y__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_foc_accel_y_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_FOC_ACCEL_Y);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write accel offset compensation
+ * target value for y-axis
+ * from the register 0x69 bit 2 and 3
+ *
+ * @param v_foc_accel_y_u8 : the value of accel offset compensation y axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x02 | -1g
+ * 0x03 | 0g
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_foc_accel_y(u8 v_foc_accel_y_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_foc_accel_y_u8 <= BMI160_MAX_ACCEL_FOC) {
+ /* write the accel offset compensation for y axis*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_FOC_ACCEL_Y__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_FOC_ACCEL_Y,
+ v_foc_accel_y_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_FOC_ACCEL_Y__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read accel offset compensation
+ * target value for x-axis is
+ * from the register 0x69 bit 4 and 5
+ *
+ * @param v_foc_accel_x_u8 : the value of accel offset compensation x axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x02 | -1g
+ * 0x03 | 0g
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_foc_accel_x(u8 *v_foc_accel_x_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the accel offset compensation for x axis*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_FOC_ACCEL_X__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_foc_accel_x_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_FOC_ACCEL_X);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write accel offset compensation
+ * target value for x-axis is
+ * from the register 0x69 bit 4 and 5
+ *
+ * @param v_foc_accel_x_u8 : the value of accel offset compensation x axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_foc_accel_x(u8 v_foc_accel_x_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_foc_accel_x_u8 <= BMI160_MAX_ACCEL_FOC) {
+ /* write the accel offset compensation for x axis*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_FOC_ACCEL_X__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_FOC_ACCEL_X,
+ v_foc_accel_x_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_FOC_ACCEL_X__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API writes accel fast offset compensation
+ * from the register 0x69 bit 0 to 5
+ * @brief This API writes each axis individually
+ * FOC_X_AXIS - bit 4 and 5
+ * FOC_Y_AXIS - bit 2 and 3
+ * FOC_Z_AXIS - bit 0 and 1
+ *
+ * @param v_foc_accel_u8: The value of accel offset compensation
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @param v_axis_u8: The value of accel offset axis selection
+ * value | axis
+ * ----------|-------------------
+ * 0 | FOC_X_AXIS
+ * 1 | FOC_Y_AXIS
+ * 2 | FOC_Z_AXIS
+ *
+ * @param v_accel_offset_s8: The accel offset value
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_foc_trigger(u8 v_axis_u8,
+u8 v_foc_accel_u8, s8 *v_accel_offset_s8)
+{
+/* variable used for return the status of communication result*/
+BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+s8 v_status_s8 = SUCCESS;
+u8 v_timeout_u8 = BMI160_INIT_VALUE;
+s8 v_foc_accel_offset_x_s8 = BMI160_INIT_VALUE;
+s8 v_foc_accel_offset_y_s8 = BMI160_INIT_VALUE;
+s8 v_foc_accel_offset_z_s8 = BMI160_INIT_VALUE;
+u8 focstatus = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+} else {
+ v_status_s8 = bmi160_set_accel_offset_enable(
+ ACCEL_OFFSET_ENABLE);
+ if (v_status_s8 == SUCCESS) {
+ switch (v_axis_u8) {
+ case FOC_X_AXIS:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_FOC_ACCEL_X__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_FOC_ACCEL_X,
+ v_foc_accel_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_FOC_ACCEL_X__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ /* trigger the
+ FOC need to write
+ 0x03 in the register 0x7e*/
+ com_rslt +=
+ bmi160_set_command_register(
+ START_FOC_ACCEL_GYRO);
+
+ com_rslt +=
+ bmi160_get_foc_rdy(&focstatus);
+ if ((com_rslt != SUCCESS) ||
+ (focstatus != BMI160_FOC_STAT_HIGH)) {
+ while ((com_rslt != SUCCESS) ||
+ (focstatus != BMI160_FOC_STAT_HIGH
+ && v_timeout_u8 <
+ BMI160_MAXIMUM_TIMEOUT)) {
+ p_bmi160->delay_msec(
+ BMI160_DELAY_SETTLING_TIME);
+ com_rslt = bmi160_get_foc_rdy(
+ &focstatus);
+ v_timeout_u8++;
+ }
+ }
+ if ((com_rslt == SUCCESS) &&
+ (focstatus == BMI160_FOC_STAT_HIGH)) {
+ com_rslt +=
+ bmi160_get_accel_offset_compensation_xaxis(
+ &v_foc_accel_offset_x_s8);
+ *v_accel_offset_s8 =
+ v_foc_accel_offset_x_s8;
+ }
+ break;
+ case FOC_Y_AXIS:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_FOC_ACCEL_Y__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_FOC_ACCEL_Y,
+ v_foc_accel_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_FOC_ACCEL_Y__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ /* trigger the FOC
+ need to write 0x03
+ in the register 0x7e*/
+ com_rslt +=
+ bmi160_set_command_register(
+ START_FOC_ACCEL_GYRO);
+
+ com_rslt +=
+ bmi160_get_foc_rdy(&focstatus);
+ if ((com_rslt != SUCCESS) ||
+ (focstatus != BMI160_FOC_STAT_HIGH)) {
+ while ((com_rslt != SUCCESS) ||
+ (focstatus != BMI160_FOC_STAT_HIGH
+ && v_timeout_u8 <
+ BMI160_MAXIMUM_TIMEOUT)) {
+ p_bmi160->delay_msec(
+ BMI160_DELAY_SETTLING_TIME);
+ com_rslt = bmi160_get_foc_rdy(
+ &focstatus);
+ v_timeout_u8++;
+ }
+ }
+ if ((com_rslt == SUCCESS) &&
+ (focstatus == BMI160_FOC_STAT_HIGH)) {
+ com_rslt +=
+ bmi160_get_accel_offset_compensation_yaxis(
+ &v_foc_accel_offset_y_s8);
+ *v_accel_offset_s8 =
+ v_foc_accel_offset_y_s8;
+ }
+ break;
+ case FOC_Z_AXIS:
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_FOC_ACCEL_Z__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_FOC_ACCEL_Z,
+ v_foc_accel_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_FOC_ACCEL_Z__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ /* trigger the FOC need to write
+ 0x03 in the register 0x7e*/
+ com_rslt +=
+ bmi160_set_command_register(
+ START_FOC_ACCEL_GYRO);
+
+ com_rslt +=
+ bmi160_get_foc_rdy(&focstatus);
+ if ((com_rslt != SUCCESS) ||
+ (focstatus != BMI160_FOC_STAT_HIGH)) {
+ while ((com_rslt != SUCCESS) ||
+ (focstatus != BMI160_FOC_STAT_HIGH
+ && v_timeout_u8 <
+ BMI160_MAXIMUM_TIMEOUT)) {
+ p_bmi160->delay_msec(
+ BMI160_DELAY_SETTLING_TIME);
+ com_rslt = bmi160_get_foc_rdy(
+ &focstatus);
+ v_timeout_u8++;
+ }
+ }
+ if ((com_rslt == SUCCESS) &&
+ (focstatus == BMI160_FOC_STAT_HIGH)) {
+ com_rslt +=
+ bmi160_get_accel_offset_compensation_zaxis(
+ &v_foc_accel_offset_z_s8);
+ *v_accel_offset_s8 =
+ v_foc_accel_offset_z_s8;
+ }
+ break;
+ default:
+ break;
+ }
+ } else {
+ com_rslt = ERROR;
+ }
+}
+return com_rslt;
+}
+/*!
+ * @brief This API write fast accel offset compensation
+ * it writes all axis together.To the register 0x69 bit 0 to 5
+ * FOC_X_AXIS - bit 4 and 5
+ * FOC_Y_AXIS - bit 2 and 3
+ * FOC_Z_AXIS - bit 0 and 1
+ *
+ * @param v_foc_accel_x_u8: The value of accel offset x compensation
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @param v_foc_accel_y_u8: The value of accel offset y compensation
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @param v_foc_accel_z_u8: The value of accel offset z compensation
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @param v_accel_off_x_s8: The value of accel offset x axis
+ * @param v_accel_off_y_s8: The value of accel offset y axis
+ * @param v_accel_off_z_s8: The value of accel offset z axis
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_accel_foc_trigger_xyz(u8 v_foc_accel_x_u8,
+u8 v_foc_accel_y_u8, u8 v_foc_accel_z_u8, s8 *v_accel_off_x_s8,
+s8 *v_accel_off_y_s8, s8 *v_accel_off_z_s8)
+{
+/* variable used for return the status of communication result*/
+BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 focx = BMI160_INIT_VALUE;
+u8 focy = BMI160_INIT_VALUE;
+u8 focz = BMI160_INIT_VALUE;
+s8 v_foc_accel_offset_x_s8 = BMI160_INIT_VALUE;
+s8 v_foc_accel_offset_y_s8 = BMI160_INIT_VALUE;
+s8 v_foc_accel_offset_z_s8 = BMI160_INIT_VALUE;
+u8 v_status_s8 = SUCCESS;
+u8 v_timeout_u8 = BMI160_INIT_VALUE;
+u8 focstatus = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ v_status_s8 = bmi160_set_accel_offset_enable(
+ ACCEL_OFFSET_ENABLE);
+ if (v_status_s8 == SUCCESS) {
+ /* foc x axis*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_FOC_ACCEL_X__REG,
+ &focx, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ focx = BMI160_SET_BITSLICE(focx,
+ BMI160_USER_FOC_ACCEL_X,
+ v_foc_accel_x_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_FOC_ACCEL_X__REG,
+ &focx, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ /* foc y axis*/
+ com_rslt +=
+ p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_FOC_ACCEL_Y__REG,
+ &focy, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ focy = BMI160_SET_BITSLICE(focy,
+ BMI160_USER_FOC_ACCEL_Y,
+ v_foc_accel_y_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_FOC_ACCEL_Y__REG,
+ &focy, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ /* foc z axis*/
+ com_rslt +=
+ p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_FOC_ACCEL_Z__REG,
+ &focz, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ focz = BMI160_SET_BITSLICE(focz,
+ BMI160_USER_FOC_ACCEL_Z,
+ v_foc_accel_z_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_FOC_ACCEL_Z__REG,
+ &focz, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ /* trigger the FOC need to
+ write 0x03 in the register 0x7e*/
+ com_rslt += bmi160_set_command_register(
+ START_FOC_ACCEL_GYRO);
+
+ com_rslt += bmi160_get_foc_rdy(
+ &focstatus);
+ if ((com_rslt != SUCCESS) ||
+ (focstatus != BMI160_FOC_STAT_HIGH)) {
+ while ((com_rslt != SUCCESS) ||
+ (focstatus != BMI160_FOC_STAT_HIGH
+ && v_timeout_u8 <
+ BMI160_MAXIMUM_TIMEOUT)) {
+ p_bmi160->delay_msec(
+ BMI160_DELAY_SETTLING_TIME);
+ com_rslt = bmi160_get_foc_rdy(
+ &focstatus);
+ v_timeout_u8++;
+ }
+ }
+ if ((com_rslt == SUCCESS) &&
+ (focstatus == BMI160_GEN_READ_WRITE_DATA_LENGTH)) {
+ com_rslt +=
+ bmi160_get_accel_offset_compensation_xaxis(
+ &v_foc_accel_offset_x_s8);
+ *v_accel_off_x_s8 =
+ v_foc_accel_offset_x_s8;
+ com_rslt +=
+ bmi160_get_accel_offset_compensation_yaxis(
+ &v_foc_accel_offset_y_s8);
+ *v_accel_off_y_s8 =
+ v_foc_accel_offset_y_s8;
+ com_rslt +=
+ bmi160_get_accel_offset_compensation_zaxis(
+ &v_foc_accel_offset_z_s8);
+ *v_accel_off_z_s8 =
+ v_foc_accel_offset_z_s8;
+ }
+ } else {
+ com_rslt = ERROR;
+ }
+ }
+return com_rslt;
+}
+/*!
+ * @brief This API read gyro fast offset enable
+ * from the register 0x69 bit 6
+ *
+ * @param v_foc_gyro_u8 : The value of gyro fast offset enable
+ * value | Description
+ * ----------|-------------
+ * 0 | fast offset compensation disabled
+ * 1 | fast offset compensation enabled
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_foc_gyro_enable(
+u8 *v_foc_gyro_u8)
+{
+ /* used for return the status of bus communication */
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the gyro fast offset enable*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_FOC_GYRO_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_foc_gyro_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_FOC_GYRO_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write gyro fast offset enable
+ * from the register 0x69 bit 6
+ *
+ * @param v_foc_gyro_u8 : The value of gyro fast offset enable
+ * value | Description
+ * ----------|-------------
+ * 0 | fast offset compensation disabled
+ * 1 | fast offset compensation enabled
+ *
+ * @param v_gyro_off_x_s16 : The value of gyro fast offset x axis data
+ * @param v_gyro_off_y_s16 : The value of gyro fast offset y axis data
+ * @param v_gyro_off_z_s16 : The value of gyro fast offset z axis data
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_foc_gyro_enable(
+u8 v_foc_gyro_u8, s16 *v_gyro_off_x_s16,
+s16 *v_gyro_off_y_s16, s16 *v_gyro_off_z_s16)
+{
+/* variable used for return the status of communication result*/
+BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+u8 v_status_s8 = SUCCESS;
+u8 v_timeout_u8 = BMI160_INIT_VALUE;
+s16 offsetx = BMI160_INIT_VALUE;
+s16 offsety = BMI160_INIT_VALUE;
+s16 offsetz = BMI160_INIT_VALUE;
+u8 focstatus = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ v_status_s8 = bmi160_set_gyro_offset_enable(
+ GYRO_OFFSET_ENABLE);
+ if (v_status_s8 == SUCCESS) {
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_FOC_GYRO_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_FOC_GYRO_ENABLE,
+ v_foc_gyro_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_FOC_GYRO_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ /* trigger the FOC need to write 0x03
+ in the register 0x7e*/
+ com_rslt += bmi160_set_command_register
+ (START_FOC_ACCEL_GYRO);
+
+ com_rslt += bmi160_get_foc_rdy(&focstatus);
+ if ((com_rslt != SUCCESS) ||
+ (focstatus != BMI160_FOC_STAT_HIGH)) {
+ while ((com_rslt != SUCCESS) ||
+ (focstatus != BMI160_FOC_STAT_HIGH
+ && v_timeout_u8 <
+ BMI160_MAXIMUM_TIMEOUT)) {
+ p_bmi160->delay_msec(
+ BMI160_DELAY_SETTLING_TIME);
+ com_rslt = bmi160_get_foc_rdy(
+ &focstatus);
+ v_timeout_u8++;
+ }
+ }
+ if ((com_rslt == SUCCESS) &&
+ (focstatus == BMI160_FOC_STAT_HIGH)) {
+ com_rslt +=
+ bmi160_get_gyro_offset_compensation_xaxis
+ (&offsetx);
+ *v_gyro_off_x_s16 = offsetx;
+
+ com_rslt +=
+ bmi160_get_gyro_offset_compensation_yaxis
+ (&offsety);
+ *v_gyro_off_y_s16 = offsety;
+
+ com_rslt +=
+ bmi160_get_gyro_offset_compensation_zaxis(
+ &offsetz);
+ *v_gyro_off_z_s16 = offsetz;
+ }
+ } else {
+ com_rslt = ERROR;
+ }
+ }
+return com_rslt;
+}
+ /*!
+ * @brief This API read NVM program enable
+ * from the register 0x6A bit 1
+ *
+ * @param v_nvm_prog_u8 : The value of NVM program enable
+ * Value | Description
+ * --------|-------------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_nvm_prog_enable(
+u8 *v_nvm_prog_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read NVM program*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_CONFIG_NVM_PROG_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_nvm_prog_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_CONFIG_NVM_PROG_ENABLE);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write NVM program enable
+ * from the register 0x6A bit 1
+ *
+ * @param v_nvm_prog_u8 : The value of NVM program enable
+ * Value | Description
+ * --------|-------------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_nvm_prog_enable(
+u8 v_nvm_prog_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_nvm_prog_u8 <= BMI160_MAX_VALUE_NVM_PROG) {
+ /* write the NVM program*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_CONFIG_NVM_PROG_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_CONFIG_NVM_PROG_ENABLE,
+ v_nvm_prog_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_CONFIG_NVM_PROG_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read to configure SPI
+ * Interface Mode for primary and OIS interface
+ * from the register 0x6B bit 0
+ *
+ * @param v_spi3_u8 : The value of SPI mode selection
+ * Value | Description
+ * --------|-------------
+ * 0 | SPI 4-wire mode
+ * 1 | SPI 3-wire mode
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_spi3(
+u8 *v_spi3_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read SPI mode*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_IF_CONFIG_SPI3__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_spi3_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_IF_CONFIG_SPI3);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write to configure SPI
+ * Interface Mode for primary and OIS interface
+ * from the register 0x6B bit 0
+ *
+ * @param v_spi3_u8 : The value of SPI mode selection
+ * Value | Description
+ * --------|-------------
+ * 0 | SPI 4-wire mode
+ * 1 | SPI 3-wire mode
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_spi3(
+u8 v_spi3_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_spi3_u8 <= BMI160_MAX_VALUE_SPI3) {
+ /* write SPI mode*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_IF_CONFIG_SPI3__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_IF_CONFIG_SPI3,
+ v_spi3_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_IF_CONFIG_SPI3__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read I2C Watchdog timer
+ * from the register 0x70 bit 1
+ *
+ * @param v_i2c_wdt_u8 : The value of I2C watch dog timer
+ * Value | Description
+ * --------|-------------
+ * 0 | I2C watchdog v_timeout_u8 after 1 ms
+ * 1 | I2C watchdog v_timeout_u8 after 50 ms
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_i2c_wdt_select(
+u8 *v_i2c_wdt_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read I2C watch dog timer */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_IF_CONFIG_I2C_WDT_SELECT__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_i2c_wdt_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_IF_CONFIG_I2C_WDT_SELECT);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write I2C Watchdog timer
+ * from the register 0x70 bit 1
+ *
+ * @param v_i2c_wdt_u8 : The value of I2C watch dog timer
+ * Value | Description
+ * --------|-------------
+ * 0 | I2C watchdog v_timeout_u8 after 1 ms
+ * 1 | I2C watchdog v_timeout_u8 after 50 ms
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_i2c_wdt_select(
+u8 v_i2c_wdt_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_i2c_wdt_u8 <= BMI160_MAX_VALUE_I2C_WDT) {
+ /* write I2C watch dog timer */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_IF_CONFIG_I2C_WDT_SELECT__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_IF_CONFIG_I2C_WDT_SELECT,
+ v_i2c_wdt_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_IF_CONFIG_I2C_WDT_SELECT__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read I2C watchdog enable
+ * from the register 0x70 bit 2
+ *
+ * @param v_i2c_wdt_u8 : The value of I2C watchdog enable
+ * Value | Description
+ * --------|-------------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_i2c_wdt_enable(
+u8 *v_i2c_wdt_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read i2c watch dog eneble */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_IF_CONFIG_I2C_WDT_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_i2c_wdt_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_IF_CONFIG_I2C_WDT_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write I2C watchdog enable
+ * from the register 0x70 bit 2
+ *
+ * @param v_i2c_wdt_u8 : The value of I2C watchdog enable
+ * Value | Description
+ * --------|-------------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_i2c_wdt_enable(
+u8 v_i2c_wdt_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_i2c_wdt_u8 <= BMI160_MAX_VALUE_I2C_WDT) {
+ /* write i2c watch dog eneble */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_IF_CONFIG_I2C_WDT_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_IF_CONFIG_I2C_WDT_ENABLE,
+ v_i2c_wdt_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_IF_CONFIG_I2C_WDT_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read I2C interface configuration(if) moe
+ * from the register 0x6B bit 4 and 5
+ *
+ * @param v_if_mode_u8 : The value of interface configuration mode
+ * Value | Description
+ * --------|-------------
+ * 0x00 | Primary interface:autoconfig / secondary interface:off
+ * 0x01 | Primary interface:I2C / secondary interface:OIS
+ * 0x02 | Primary interface:autoconfig/secondary interface:Magnetometer
+ * 0x03 | Reserved
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_if_mode(
+u8 *v_if_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read if mode*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_IF_CONFIG_IF_MODE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_if_mode_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_IF_CONFIG_IF_MODE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write I2C interface configuration(if) moe
+ * from the register 0x6B bit 4 and 5
+ *
+ * @param v_if_mode_u8 : The value of interface configuration mode
+ * Value | Description
+ * --------|-------------
+ * 0x00 | Primary interface:autoconfig / secondary interface:off
+ * 0x01 | Primary interface:I2C / secondary interface:OIS
+ * 0x02 | Primary interface:autoconfig/secondary interface:Magnetometer
+ * 0x03 | Reserved
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_if_mode(
+u8 v_if_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_if_mode_u8 <= BMI160_MAX_IF_MODE) {
+ /* write if mode*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_IF_CONFIG_IF_MODE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_IF_CONFIG_IF_MODE,
+ v_if_mode_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_IF_CONFIG_IF_MODE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read gyro sleep trigger
+ * from the register 0x6C bit 0 to 2
+ *
+ * @param v_gyro_sleep_trigger_u8 : The value of gyro sleep trigger
+ * Value | Description
+ * --------|-------------
+ * 0x00 | nomotion: no / Not INT1 pin: no / INT2 pin: no
+ * 0x01 | nomotion: no / Not INT1 pin: no / INT2 pin: yes
+ * 0x02 | nomotion: no / Not INT1 pin: yes / INT2 pin: no
+ * 0x03 | nomotion: no / Not INT1 pin: yes / INT2 pin: yes
+ * 0x04 | nomotion: yes / Not INT1 pin: no / INT2 pin: no
+ * 0x05 | anymotion: yes / Not INT1 pin: no / INT2 pin: yes
+ * 0x06 | anymotion: yes / Not INT1 pin: yes / INT2 pin: no
+ * 0x07 | anymotion: yes / Not INT1 pin: yes / INT2 pin: yes
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_sleep_trigger(
+u8 *v_gyro_sleep_trigger_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read gyro sleep trigger */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_GYRO_SLEEP_TRIGGER__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_gyro_sleep_trigger_u8 =
+ BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_GYRO_SLEEP_TRIGGER);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write gyro sleep trigger
+ * from the register 0x6C bit 0 to 2
+ *
+ * @param v_gyro_sleep_trigger_u8 : The value of gyro sleep trigger
+ * Value | Description
+ * --------|-------------
+ * 0x00 | nomotion: no / Not INT1 pin: no / INT2 pin: no
+ * 0x01 | nomotion: no / Not INT1 pin: no / INT2 pin: yes
+ * 0x02 | nomotion: no / Not INT1 pin: yes / INT2 pin: no
+ * 0x03 | nomotion: no / Not INT1 pin: yes / INT2 pin: yes
+ * 0x04 | nomotion: yes / Not INT1 pin: no / INT2 pin: no
+ * 0x05 | anymotion: yes / Not INT1 pin: no / INT2 pin: yes
+ * 0x06 | anymotion: yes / Not INT1 pin: yes / INT2 pin: no
+ * 0x07 | anymotion: yes / Not INT1 pin: yes / INT2 pin: yes
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_sleep_trigger(
+u8 v_gyro_sleep_trigger_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_gyro_sleep_trigger_u8 <= BMI160_MAX_GYRO_SLEEP_TIGGER) {
+ /* write gyro sleep trigger */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_GYRO_SLEEP_TRIGGER__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_GYRO_SLEEP_TRIGGER,
+ v_gyro_sleep_trigger_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_GYRO_SLEEP_TRIGGER__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read gyro wakeup trigger
+ * from the register 0x6C bit 3 and 4
+ *
+ * @param v_gyro_wakeup_trigger_u8 : The value of gyro wakeup trigger
+ * Value | Description
+ * --------|-------------
+ * 0x00 | anymotion: no / INT1 pin: no
+ * 0x01 | anymotion: no / INT1 pin: yes
+ * 0x02 | anymotion: yes / INT1 pin: no
+ * 0x03 | anymotion: yes / INT1 pin: yes
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_wakeup_trigger(
+u8 *v_gyro_wakeup_trigger_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read gyro wakeup trigger */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_GYRO_WAKEUP_TRIGGER__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_gyro_wakeup_trigger_u8 = BMI160_GET_BITSLICE(
+ v_data_u8,
+ BMI160_USER_GYRO_WAKEUP_TRIGGER);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write gyro wakeup trigger
+ * from the register 0x6C bit 3 and 4
+ *
+ * @param v_gyro_wakeup_trigger_u8 : The value of gyro wakeup trigger
+ * Value | Description
+ * --------|-------------
+ * 0x00 | anymotion: no / INT1 pin: no
+ * 0x01 | anymotion: no / INT1 pin: yes
+ * 0x02 | anymotion: yes / INT1 pin: no
+ * 0x03 | anymotion: yes / INT1 pin: yes
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_wakeup_trigger(
+u8 v_gyro_wakeup_trigger_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_gyro_wakeup_trigger_u8
+ <= BMI160_MAX_GYRO_WAKEUP_TRIGGER) {
+ /* write gyro wakeup trigger */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_GYRO_WAKEUP_TRIGGER__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_GYRO_WAKEUP_TRIGGER,
+ v_gyro_wakeup_trigger_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_GYRO_WAKEUP_TRIGGER__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read Target state for gyro sleep mode
+ * from the register 0x6C bit 5
+ *
+ * @param v_gyro_sleep_state_u8 : The value of gyro sleep mode
+ * Value | Description
+ * --------|-------------
+ * 0x00 | Sleep transition to fast wake up state
+ * 0x01 | Sleep transition to suspend state
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_sleep_state(
+u8 *v_gyro_sleep_state_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read gyro sleep state*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_GYRO_SLEEP_STATE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_gyro_sleep_state_u8 = BMI160_GET_BITSLICE(
+ v_data_u8,
+ BMI160_USER_GYRO_SLEEP_STATE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write Target state for gyro sleep mode
+ * from the register 0x6C bit 5
+ *
+ * @param v_gyro_sleep_state_u8 : The value of gyro sleep mode
+ * Value | Description
+ * --------|-------------
+ * 0x00 | Sleep transition to fast wake up state
+ * 0x01 | Sleep transition to suspend state
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_sleep_state(
+u8 v_gyro_sleep_state_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_gyro_sleep_state_u8 <= BMI160_MAX_VALUE_SLEEP_STATE) {
+ /* write gyro sleep state*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_GYRO_SLEEP_STATE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_GYRO_SLEEP_STATE,
+ v_gyro_sleep_state_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_GYRO_SLEEP_STATE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read gyro wakeup interrupt
+ * from the register 0x6C bit 6
+ *
+ * @param v_gyro_wakeup_intr_u8 : The valeu of gyro wakeup interrupt
+ * Value | Description
+ * --------|-------------
+ * 0x00 | DISABLE
+ * 0x01 | ENABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_wakeup_intr(
+u8 *v_gyro_wakeup_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read gyro wakeup interrupt */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_GYRO_WAKEUP_INTR__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_gyro_wakeup_intr_u8 = BMI160_GET_BITSLICE(
+ v_data_u8,
+ BMI160_USER_GYRO_WAKEUP_INTR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write gyro wakeup interrupt
+ * from the register 0x6C bit 6
+ *
+ * @param v_gyro_wakeup_intr_u8 : The valeu of gyro wakeup interrupt
+ * Value | Description
+ * --------|-------------
+ * 0x00 | DISABLE
+ * 0x01 | ENABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_wakeup_intr(
+u8 v_gyro_wakeup_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_gyro_wakeup_intr_u8 <= BMI160_MAX_VALUE_WAKEUP_INTR) {
+ /* write gyro wakeup interrupt */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_GYRO_WAKEUP_INTR__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_GYRO_WAKEUP_INTR,
+ v_gyro_wakeup_intr_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_GYRO_WAKEUP_INTR__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read accel select axis to be self-test
+ *
+ * @param v_accel_selftest_axis_u8 :
+ * The value of accel self test axis selection
+ * Value | Description
+ * --------|-------------
+ * 0x00 | disabled
+ * 0x01 | x-axis
+ * 0x02 | y-axis
+ * 0x03 | z-axis
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_selftest_axis(
+u8 *v_accel_selftest_axis_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read accel self test axis*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_ACCEL_SELFTEST_AXIS__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_selftest_axis_u8 = BMI160_GET_BITSLICE(
+ v_data_u8,
+ BMI160_USER_ACCEL_SELFTEST_AXIS);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write accel select axis to be self-test
+ *
+ * @param v_accel_selftest_axis_u8 :
+ * The value of accel self test axis selection
+ * Value | Description
+ * --------|-------------
+ * 0x00 | disabled
+ * 0x01 | x-axis
+ * 0x02 | y-axis
+ * 0x03 | z-axis
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_selftest_axis(
+u8 v_accel_selftest_axis_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_accel_selftest_axis_u8
+ <= BMI160_MAX_ACCEL_SELFTEST_AXIS) {
+ /* write accel self test axis*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_ACCEL_SELFTEST_AXIS__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_ACCEL_SELFTEST_AXIS,
+ v_accel_selftest_axis_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_ACCEL_SELFTEST_AXIS__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read accel self test axis sign
+ * from the register 0x6D bit 2
+ *
+ * @param v_accel_selftest_sign_u8: The value of accel self test axis sign
+ * Value | Description
+ * --------|-------------
+ * 0x00 | negative
+ * 0x01 | positive
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_selftest_sign(
+u8 *v_accel_selftest_sign_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read accel self test axis sign*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_ACCEL_SELFTEST_SIGN__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_selftest_sign_u8 = BMI160_GET_BITSLICE(
+ v_data_u8,
+ BMI160_USER_ACCEL_SELFTEST_SIGN);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write accel self test axis sign
+ * from the register 0x6D bit 2
+ *
+ * @param v_accel_selftest_sign_u8: The value of accel self test axis sign
+ * Value | Description
+ * --------|-------------
+ * 0x00 | negative
+ * 0x01 | positive
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_selftest_sign(
+u8 v_accel_selftest_sign_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_accel_selftest_sign_u8 <=
+ BMI160_MAX_VALUE_SELFTEST_SIGN) {
+ /* write accel self test axis sign*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_ACCEL_SELFTEST_SIGN__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_ACCEL_SELFTEST_SIGN,
+ v_accel_selftest_sign_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_ACCEL_SELFTEST_SIGN__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read accel self test amplitude
+ * from the register 0x6D bit 3
+ * select amplitude of the selftest deflection:
+ *
+ * @param v_accel_selftest_amp_u8 : The value of accel self test amplitude
+ * Value | Description
+ * --------|-------------
+ * 0x00 | LOW
+ * 0x01 | HIGH
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_selftest_amp(
+u8 *v_accel_selftest_amp_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read self test amplitude*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_SELFTEST_AMP__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_selftest_amp_u8 = BMI160_GET_BITSLICE(
+ v_data_u8,
+ BMI160_USER_SELFTEST_AMP);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write accel self test amplitude
+ * from the register 0x6D bit 3
+ * select amplitude of the selftest deflection:
+ *
+ * @param v_accel_selftest_amp_u8 : The value of accel self test amplitude
+ * Value | Description
+ * --------|-------------
+ * 0x00 | LOW
+ * 0x01 | HIGH
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_selftest_amp(
+u8 v_accel_selftest_amp_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_accel_selftest_amp_u8 <=
+ BMI160_MAX_VALUE_SELFTEST_AMP) {
+ /* write self test amplitude*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_SELFTEST_AMP__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_SELFTEST_AMP,
+ v_accel_selftest_amp_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_SELFTEST_AMP__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read gyro self test trigger
+ *
+ * @param v_gyro_selftest_start_u8: The value of gyro self test start
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_selftest_start(
+u8 *v_gyro_selftest_start_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read gyro self test start */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_GYRO_SELFTEST_START__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_gyro_selftest_start_u8 = BMI160_GET_BITSLICE(
+ v_data_u8,
+ BMI160_USER_GYRO_SELFTEST_START);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write gyro self test trigger
+ *
+ * @param v_gyro_selftest_start_u8: The value of gyro self test start
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_selftest_start(
+u8 v_gyro_selftest_start_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_gyro_selftest_start_u8 <=
+ BMI160_MAX_VALUE_SELFTEST_START) {
+ /* write gyro self test start */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_GYRO_SELFTEST_START__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_GYRO_SELFTEST_START,
+ v_gyro_selftest_start_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_GYRO_SELFTEST_START__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API read primary interface selection I2C or SPI
+ * from the register 0x70 bit 0
+ *
+ * @param v_spi_enable_u8: The value of Interface selection
+ * Value | Description
+ * --------|-------------
+ * 0x00 | I2C Enable
+ * 0x01 | I2C DISBALE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_spi_enable(u8 *v_spi_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read interface section*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_NV_CONFIG_SPI_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_spi_enable_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_NV_CONFIG_SPI_ENABLE);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write primary interface selection I2C or SPI
+ * from the register 0x70 bit 0
+ *
+ * @param v_spi_enable_u8: The value of Interface selection
+ * Value | Description
+ * --------|-------------
+ * 0x00 | I2C Enable
+ * 0x01 | I2C DISBALE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_spi_enable(u8 v_spi_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* write interface section*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_NV_CONFIG_SPI_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_NV_CONFIG_SPI_ENABLE,
+ v_spi_enable_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_NV_CONFIG_SPI_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API read the spare zero
+ * form register 0x70 bit 3
+ *
+ *
+ * @param v_spare0_trim_u8: The value of spare zero
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_spare0_trim(u8 *v_spare0_trim_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read spare zero*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_NV_CONFIG_SPARE0__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_spare0_trim_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_NV_CONFIG_SPARE0);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write the spare zero
+ * form register 0x70 bit 3
+ *
+ *
+ * @param v_spare0_trim_u8: The value of spare zero
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_spare0_trim(u8 v_spare0_trim_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* write spare zero*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_NV_CONFIG_SPARE0__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_NV_CONFIG_SPARE0,
+ v_spare0_trim_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_NV_CONFIG_SPARE0__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API read the NVM counter
+ * form register 0x70 bit 4 to 7
+ *
+ *
+ * @param v_nvm_counter_u8: The value of NVM counter
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_nvm_counter(u8 *v_nvm_counter_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read NVM counter*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_NV_CONFIG_NVM_COUNTER__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_nvm_counter_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_NV_CONFIG_NVM_COUNTER);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write the NVM counter
+ * form register 0x70 bit 4 to 7
+ *
+ *
+ * @param v_nvm_counter_u8: The value of NVM counter
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_nvm_counter(
+u8 v_nvm_counter_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* write NVM counter*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_NV_CONFIG_NVM_COUNTER__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_NV_CONFIG_NVM_COUNTER,
+ v_nvm_counter_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_NV_CONFIG_NVM_COUNTER__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read accel manual offset compensation of x axis
+ * from the register 0x71 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_x_s8:
+ * The value of accel manual offset compensation of x axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_offset_compensation_xaxis(
+s8 *v_accel_off_x_s8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read accel manual offset compensation of x axis*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_0_ACCEL_OFF_X__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_off_x_s8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_OFFSET_0_ACCEL_OFF_X);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write accel manual offset compensation of x axis
+ * from the register 0x71 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_x_s8:
+ * The value of accel manual offset compensation of x axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_offset_compensation_xaxis(
+s8 v_accel_off_x_s8)
+{
+/* variable used for return the status of communication result*/
+BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+u8 v_status_s8 = SUCCESS;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* enable accel offset */
+ v_status_s8 = bmi160_set_accel_offset_enable(
+ ACCEL_OFFSET_ENABLE);
+ if (v_status_s8 == SUCCESS) {
+ /* write accel manual offset compensation of x axis*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_0_ACCEL_OFF_X__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ BMI160_SET_BITSLICE(
+ v_data_u8,
+ BMI160_USER_OFFSET_0_ACCEL_OFF_X,
+ v_accel_off_x_s8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_0_ACCEL_OFF_X__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = ERROR;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read accel manual offset compensation of y axis
+ * from the register 0x72 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_y_s8:
+ * The value of accel manual offset compensation of y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_offset_compensation_yaxis(
+s8 *v_accel_off_y_s8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read accel manual offset compensation of y axis*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_1_ACCEL_OFF_Y__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_off_y_s8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_OFFSET_1_ACCEL_OFF_Y);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write accel manual offset compensation of y axis
+ * from the register 0x72 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_y_s8:
+ * The value of accel manual offset compensation of y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_offset_compensation_yaxis(
+s8 v_accel_off_y_s8)
+{
+/* variable used for return the status of communication result*/
+BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+u8 v_status_s8 = SUCCESS;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* enable accel offset */
+ v_status_s8 = bmi160_set_accel_offset_enable(
+ ACCEL_OFFSET_ENABLE);
+ if (v_status_s8 == SUCCESS) {
+ /* write accel manual offset compensation of y axis*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_1_ACCEL_OFF_Y__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ BMI160_SET_BITSLICE(
+ v_data_u8,
+ BMI160_USER_OFFSET_1_ACCEL_OFF_Y,
+ v_accel_off_y_s8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_1_ACCEL_OFF_Y__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = ERROR;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read accel manual offset compensation of z axis
+ * from the register 0x73 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_z_s8:
+ * The value of accel manual offset compensation of z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_offset_compensation_zaxis(
+s8 *v_accel_off_z_s8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read accel manual offset compensation of z axis*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_2_ACCEL_OFF_Z__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_off_z_s8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_OFFSET_2_ACCEL_OFF_Z);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write accel manual offset compensation of z axis
+ * from the register 0x73 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_z_s8:
+ * The value of accel manual offset compensation of z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_offset_compensation_zaxis(
+s8 v_accel_off_z_s8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ u8 v_status_s8 = SUCCESS;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* enable accel offset */
+ v_status_s8 = bmi160_set_accel_offset_enable(
+ ACCEL_OFFSET_ENABLE);
+ if (v_status_s8 == SUCCESS) {
+ /* write accel manual offset
+ compensation of z axis*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_2_ACCEL_OFF_Z__REG,
+ &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_OFFSET_2_ACCEL_OFF_Z,
+ v_accel_off_z_s8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_2_ACCEL_OFF_Z__REG,
+ &v_data_u8,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = ERROR;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read gyro manual offset compensation of x axis
+ * from the register 0x74 bit 0 to 7 and 0x77 bit 0 and 1
+ *
+ *
+ *
+ * @param v_gyro_off_x_s16:
+ * The value of gyro manual offset compensation of x axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_offset_compensation_xaxis(
+s16 *v_gyro_off_x_s16)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data1_u8r = BMI160_INIT_VALUE;
+ u8 v_data2_u8r = BMI160_INIT_VALUE;
+ s16 v_data3_u8r, v_data4_u8r = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read gyro offset x*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_3_GYRO_OFF_X__REG,
+ &v_data1_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ v_data1_u8r = BMI160_GET_BITSLICE(v_data1_u8r,
+ BMI160_USER_OFFSET_3_GYRO_OFF_X);
+ com_rslt += p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_6_GYRO_OFF_X__REG,
+ &v_data2_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ v_data2_u8r = BMI160_GET_BITSLICE(v_data2_u8r,
+ BMI160_USER_OFFSET_6_GYRO_OFF_X);
+ v_data3_u8r = v_data2_u8r
+ << BMI160_SHIFT_BIT_POSITION_BY_14_BITS;
+ v_data4_u8r = v_data1_u8r
+ << BMI160_SHIFT_BIT_POSITION_BY_06_BITS;
+ v_data3_u8r = v_data3_u8r | v_data4_u8r;
+ *v_gyro_off_x_s16 = v_data3_u8r
+ >> BMI160_SHIFT_BIT_POSITION_BY_06_BITS;
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write gyro manual offset compensation of x axis
+ * from the register 0x74 bit 0 to 7 and 0x77 bit 0 and 1
+ *
+ *
+ *
+ * @param v_gyro_off_x_s16:
+ * The value of gyro manual offset compensation of x axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_offset_compensation_xaxis(
+s16 v_gyro_off_x_s16)
+{
+/* variable used for return the status of communication result*/
+BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data1_u8r, v_data2_u8r = BMI160_INIT_VALUE;
+u16 v_data3_u8r = BMI160_INIT_VALUE;
+u8 v_status_s8 = SUCCESS;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* write gyro offset x*/
+ v_status_s8 = bmi160_set_gyro_offset_enable(
+ GYRO_OFFSET_ENABLE);
+ if (v_status_s8 == SUCCESS) {
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_3_GYRO_OFF_X__REG,
+ &v_data2_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data1_u8r =
+ ((s8) (v_gyro_off_x_s16 &
+ BMI160_GYRO_MANUAL_OFFSET_0_7));
+ v_data2_u8r = BMI160_SET_BITSLICE(
+ v_data2_u8r,
+ BMI160_USER_OFFSET_3_GYRO_OFF_X,
+ v_data1_u8r);
+ /* write 0x74 bit 0 to 7*/
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_3_GYRO_OFF_X__REG,
+ &v_data2_u8r,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ com_rslt += p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_6_GYRO_OFF_X__REG,
+ &v_data2_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data3_u8r =
+ (u16) (v_gyro_off_x_s16 &
+ BMI160_GYRO_MANUAL_OFFSET_8_9);
+ v_data1_u8r = (u8)(v_data3_u8r
+ >> BMI160_SHIFT_BIT_POSITION_BY_08_BITS);
+ v_data2_u8r = BMI160_SET_BITSLICE(
+ v_data2_u8r,
+ BMI160_USER_OFFSET_6_GYRO_OFF_X,
+ v_data1_u8r);
+ /* write 0x77 bit 0 and 1*/
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_6_GYRO_OFF_X__REG,
+ &v_data2_u8r,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ return ERROR;
+ }
+ }
+return com_rslt;
+}
+/*!
+ * @brief This API read gyro manual offset compensation of y axis
+ * from the register 0x75 bit 0 to 7 and 0x77 bit 2 and 3
+ *
+ *
+ *
+ * @param v_gyro_off_y_s16:
+ * The value of gyro manual offset compensation of y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_offset_compensation_yaxis(
+s16 *v_gyro_off_y_s16)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data1_u8r = BMI160_INIT_VALUE;
+ u8 v_data2_u8r = BMI160_INIT_VALUE;
+ s16 v_data3_u8r, v_data4_u8r = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read gyro offset y*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_4_GYRO_OFF_Y__REG,
+ &v_data1_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ v_data1_u8r = BMI160_GET_BITSLICE(v_data1_u8r,
+ BMI160_USER_OFFSET_4_GYRO_OFF_Y);
+ com_rslt += p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_6_GYRO_OFF_Y__REG,
+ &v_data2_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ v_data2_u8r = BMI160_GET_BITSLICE(v_data2_u8r,
+ BMI160_USER_OFFSET_6_GYRO_OFF_Y);
+ v_data3_u8r = v_data2_u8r
+ << BMI160_SHIFT_BIT_POSITION_BY_14_BITS;
+ v_data4_u8r = v_data1_u8r
+ << BMI160_SHIFT_BIT_POSITION_BY_06_BITS;
+ v_data3_u8r = v_data3_u8r | v_data4_u8r;
+ *v_gyro_off_y_s16 = v_data3_u8r
+ >> BMI160_SHIFT_BIT_POSITION_BY_06_BITS;
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write gyro manual offset compensation of y axis
+ * from the register 0x75 bit 0 to 7 and 0x77 bit 2 and 3
+ *
+ *
+ *
+ * @param v_gyro_off_y_s16:
+ * The value of gyro manual offset compensation of y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_offset_compensation_yaxis(
+s16 v_gyro_off_y_s16)
+{
+/* variable used for return the status of communication result*/
+BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data1_u8r, v_data2_u8r = BMI160_INIT_VALUE;
+u16 v_data3_u8r = BMI160_INIT_VALUE;
+u8 v_status_s8 = SUCCESS;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* enable gyro offset bit */
+ v_status_s8 = bmi160_set_gyro_offset_enable(
+ GYRO_OFFSET_ENABLE);
+ /* write gyro offset y*/
+ if (v_status_s8 == SUCCESS) {
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_4_GYRO_OFF_Y__REG,
+ &v_data2_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data1_u8r =
+ ((s8) (v_gyro_off_y_s16 &
+ BMI160_GYRO_MANUAL_OFFSET_0_7));
+ v_data2_u8r = BMI160_SET_BITSLICE(
+ v_data2_u8r,
+ BMI160_USER_OFFSET_4_GYRO_OFF_Y,
+ v_data1_u8r);
+ /* write 0x75 bit 0 to 7*/
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_4_GYRO_OFF_Y__REG,
+ &v_data2_u8r,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ com_rslt += p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_6_GYRO_OFF_Y__REG,
+ &v_data2_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data3_u8r =
+ (u16) (v_gyro_off_y_s16 &
+ BMI160_GYRO_MANUAL_OFFSET_8_9);
+ v_data1_u8r = (u8)(v_data3_u8r
+ >> BMI160_SHIFT_BIT_POSITION_BY_08_BITS);
+ v_data2_u8r = BMI160_SET_BITSLICE(
+ v_data2_u8r,
+ BMI160_USER_OFFSET_6_GYRO_OFF_Y,
+ v_data1_u8r);
+ /* write 0x77 bit 2 and 3*/
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_6_GYRO_OFF_Y__REG,
+ &v_data2_u8r,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ return ERROR;
+ }
+ }
+return com_rslt;
+}
+/*!
+ * @brief This API read gyro manual offset compensation of z axis
+ * from the register 0x76 bit 0 to 7 and 0x77 bit 4 and 5
+ *
+ *
+ *
+ * @param v_gyro_off_z_s16:
+ * The value of gyro manual offset compensation of z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_offset_compensation_zaxis(
+s16 *v_gyro_off_z_s16)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data1_u8r = BMI160_INIT_VALUE;
+ u8 v_data2_u8r = BMI160_INIT_VALUE;
+ s16 v_data3_u8r, v_data4_u8r = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read gyro manual offset z axis*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_5_GYRO_OFF_Z__REG,
+ &v_data1_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ v_data1_u8r = BMI160_GET_BITSLICE
+ (v_data1_u8r,
+ BMI160_USER_OFFSET_5_GYRO_OFF_Z);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_6_GYRO_OFF_Z__REG,
+ &v_data2_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ v_data2_u8r = BMI160_GET_BITSLICE(
+ v_data2_u8r,
+ BMI160_USER_OFFSET_6_GYRO_OFF_Z);
+ v_data3_u8r = v_data2_u8r
+ << BMI160_SHIFT_BIT_POSITION_BY_14_BITS;
+ v_data4_u8r = v_data1_u8r
+ << BMI160_SHIFT_BIT_POSITION_BY_06_BITS;
+ v_data3_u8r = v_data3_u8r | v_data4_u8r;
+ *v_gyro_off_z_s16 = v_data3_u8r
+ >> BMI160_SHIFT_BIT_POSITION_BY_06_BITS;
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write gyro manual offset compensation of z axis
+ * from the register 0x76 bit 0 to 7 and 0x77 bit 4 and 5
+ *
+ *
+ *
+ * @param v_gyro_off_z_s16:
+ * The value of gyro manual offset compensation of z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_offset_compensation_zaxis(
+s16 v_gyro_off_z_s16)
+{
+/* variable used for return the status of communication result*/
+BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data1_u8r, v_data2_u8r = BMI160_INIT_VALUE;
+u16 v_data3_u8r = BMI160_INIT_VALUE;
+u8 v_status_s8 = SUCCESS;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* enable gyro offset*/
+ v_status_s8 = bmi160_set_gyro_offset_enable(
+ GYRO_OFFSET_ENABLE);
+ /* write gyro manual offset z axis*/
+ if (v_status_s8 == SUCCESS) {
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_5_GYRO_OFF_Z__REG,
+ &v_data2_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data1_u8r =
+ ((u8) (v_gyro_off_z_s16 &
+ BMI160_GYRO_MANUAL_OFFSET_0_7));
+ v_data2_u8r = BMI160_SET_BITSLICE(
+ v_data2_u8r,
+ BMI160_USER_OFFSET_5_GYRO_OFF_Z,
+ v_data1_u8r);
+ /* write 0x76 bit 0 to 7*/
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_5_GYRO_OFF_Z__REG,
+ &v_data2_u8r,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ com_rslt += p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_6_GYRO_OFF_Z__REG,
+ &v_data2_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data3_u8r =
+ (u16) (v_gyro_off_z_s16 &
+ BMI160_GYRO_MANUAL_OFFSET_8_9);
+ v_data1_u8r = (u8)(v_data3_u8r
+ >> BMI160_SHIFT_BIT_POSITION_BY_08_BITS);
+ v_data2_u8r = BMI160_SET_BITSLICE(
+ v_data2_u8r,
+ BMI160_USER_OFFSET_6_GYRO_OFF_Z,
+ v_data1_u8r);
+ /* write 0x77 bit 4 and 5*/
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_6_GYRO_OFF_Z__REG,
+ &v_data2_u8r,
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ return ERROR;
+ }
+ }
+return com_rslt;
+}
+/*!
+ * @brief This API read the accel offset enable bit
+ * from the register 0x77 bit 6
+ *
+ *
+ *
+ * @param v_accel_off_enable_u8: The value of accel offset enable
+ * value | Description
+ * ----------|--------------
+ * 0x01 | ENABLE
+ * 0x00 | DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_offset_enable(
+u8 *v_accel_off_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read accel offset enable */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_6_ACCEL_OFF_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_off_enable_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_OFFSET_6_ACCEL_OFF_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write the accel offset enable bit
+ * from the register 0x77 bit 6
+ *
+ *
+ *
+ * @param v_accel_off_enable_u8: The value of accel offset enable
+ * value | Description
+ * ----------|--------------
+ * 0x01 | ENABLE
+ * 0x00 | DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_offset_enable(
+u8 v_accel_off_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* write accel offset enable */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_6_ACCEL_OFF_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_OFFSET_6_ACCEL_OFF_ENABLE,
+ v_accel_off_enable_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_6_ACCEL_OFF_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read the accel offset enable bit
+ * from the register 0x77 bit 7
+ *
+ *
+ *
+ * @param v_gyro_off_enable_u8: The value of gyro offset enable
+ * value | Description
+ * ----------|--------------
+ * 0x01 | ENABLE
+ * 0x00 | DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_offset_enable(
+u8 *v_gyro_off_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read gyro offset*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_6_GYRO_OFF_EN__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_gyro_off_enable_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_OFFSET_6_GYRO_OFF_EN);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write the accel offset enable bit
+ * from the register 0x77 bit 7
+ *
+ *
+ *
+ * @param v_gyro_off_enable_u8: The value of gyro offset enable
+ * value | Description
+ * ----------|--------------
+ * 0x01 | ENABLE
+ * 0x00 | DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_offset_enable(
+u8 v_gyro_off_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* write gyro offset*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_6_GYRO_OFF_EN__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_OFFSET_6_GYRO_OFF_EN,
+ v_gyro_off_enable_u8);
+ com_rslt += p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_OFFSET_6_GYRO_OFF_EN__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads step counter value
+ * form the register 0x78 and 0x79
+ *
+ *
+ *
+ *
+ * @param v_step_cnt_s16 : The value of step counter
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_step_count(u16 *v_step_cnt_s16)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* array having the step counter LSB and MSB data
+ v_data_u8[0] - LSB
+ v_data_u8[1] - MSB*/
+ u8 a_data_u8r[BMI160_STEP_COUNT_DATA_SIZE] = {BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE};
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read step counter */
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_STEP_COUNT_LSB__REG,
+ a_data_u8r, BMI160_STEP_COUNTER_LENGTH);
+
+ *v_step_cnt_s16 = (s16)
+ ((((s32)((s8)a_data_u8r[BMI160_STEP_COUNT_MSB_BYTE]))
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (a_data_u8r[BMI160_STEP_COUNT_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API Reads
+ * step counter configuration
+ * from the register 0x7A bit 0 to 7
+ * and from the register 0x7B bit 0 to 2 and 4 to 7
+ *
+ *
+ * @param v_step_config_u16 : The value of step configuration
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_step_config(
+u16 *v_step_config_u16)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data1_u8r = BMI160_INIT_VALUE;
+ u8 v_data2_u8r = BMI160_INIT_VALUE;
+ u16 v_data3_u8r = BMI160_INIT_VALUE;
+ /* Read the 0 to 7 bit*/
+ com_rslt =
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_STEP_CONFIG_ZERO__REG,
+ &v_data1_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ /* Read the 8 to 10 bit*/
+ com_rslt +=
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_STEP_CONFIG_ONE_CNF1__REG,
+ &v_data2_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ v_data2_u8r = BMI160_GET_BITSLICE(v_data2_u8r,
+ BMI160_USER_STEP_CONFIG_ONE_CNF1);
+ v_data3_u8r = ((u16)((((u32)
+ ((u8)v_data2_u8r))
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) | (v_data1_u8r)));
+ /* Read the 11 to 14 bit*/
+ com_rslt +=
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_STEP_CONFIG_ONE_CNF2__REG,
+ &v_data1_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ v_data1_u8r = BMI160_GET_BITSLICE(v_data1_u8r,
+ BMI160_USER_STEP_CONFIG_ONE_CNF2);
+ *v_step_config_u16 = ((u16)((((u32)
+ ((u8)v_data1_u8r))
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) | (v_data3_u8r)));
+
+ return com_rslt;
+}
+ /*!
+ * @brief This API write
+ * step counter configuration
+ * from the register 0x7A bit 0 to 7
+ * and from the register 0x7B bit 0 to 2 and 4 to 7
+ *
+ *
+ * @param v_step_config_u16 :
+ * the value of Enable step configuration
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_step_config(
+u16 v_step_config_u16)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data1_u8r = BMI160_INIT_VALUE;
+ u8 v_data2_u8r = BMI160_INIT_VALUE;
+ u16 v_data3_u16 = BMI160_INIT_VALUE;
+
+ /* write the 0 to 7 bit*/
+ v_data1_u8r = (u8)(v_step_config_u16 &
+ BMI160_STEP_CONFIG_0_7);
+ p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_STEP_CONFIG_ZERO__REG,
+ &v_data1_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ /* write the 8 to 10 bit*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_STEP_CONFIG_ONE_CNF1__REG,
+ &v_data2_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data3_u16 = (u16) (v_step_config_u16 &
+ BMI160_STEP_CONFIG_8_10);
+ v_data1_u8r = (u8)(v_data3_u16
+ >> BMI160_SHIFT_BIT_POSITION_BY_08_BITS);
+ v_data2_u8r = BMI160_SET_BITSLICE(v_data2_u8r,
+ BMI160_USER_STEP_CONFIG_ONE_CNF1, v_data1_u8r);
+ p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_STEP_CONFIG_ONE_CNF1__REG,
+ &v_data2_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ /* write the 11 to 14 bit*/
+ com_rslt += p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_STEP_CONFIG_ONE_CNF2__REG,
+ &v_data2_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data3_u16 = (u16) (v_step_config_u16 &
+ BMI160_STEP_CONFIG_11_14);
+ v_data1_u8r = (u8)(v_data3_u16
+ >> BMI160_SHIFT_BIT_POSITION_BY_12_BITS);
+ v_data2_u8r = BMI160_SET_BITSLICE(v_data2_u8r,
+ BMI160_USER_STEP_CONFIG_ONE_CNF2, v_data1_u8r);
+ p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_STEP_CONFIG_ONE_CNF2__REG,
+ &v_data2_u8r, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ return com_rslt;
+}
+ /*!
+ * @brief This API read enable step counter
+ * from the register 0x7B bit 3
+ *
+ *
+ * @param v_step_counter_u8 : The value of step counter enable
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_step_counter_enable(
+u8 *v_step_counter_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the step counter */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_step_counter_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write enable step counter
+ * from the register 0x7B bit 3
+ *
+ *
+ * @param v_step_counter_u8 : The value of step counter enable
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_step_counter_enable(u8 v_step_counter_u8)
+{
+/* variable used for return the status of communication result*/
+BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+/* check the p_bmi160 structure as NULL*/
+if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+} else {
+ if (v_step_counter_u8 <= BMI160_MAX_GYRO_STEP_COUNTER) {
+ /* write the step counter */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE,
+ v_step_counter_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+}
+ return com_rslt;
+}
+ /*!
+ * @brief This API set Step counter modes
+ *
+ *
+ * @param v_step_mode_u8 : The value of step counter mode
+ * value | mode
+ * ----------|-----------
+ * 0 | BMI160_STEP_NORMAL_MODE
+ * 1 | BMI160_STEP_SENSITIVE_MODE
+ * 2 | BMI160_STEP_ROBUST_MODE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_step_mode(u8 v_step_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+
+ switch (v_step_mode_u8) {
+ case BMI160_STEP_NORMAL_MODE:
+ com_rslt = bmi160_set_step_config(
+ STEP_CONFIG_NORMAL);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ break;
+ case BMI160_STEP_SENSITIVE_MODE:
+ com_rslt = bmi160_set_step_config(
+ STEP_CONFIG_SENSITIVE);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ break;
+ case BMI160_STEP_ROBUST_MODE:
+ com_rslt = bmi160_set_step_config(
+ STEP_CONFIG_ROBUST);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+
+ return com_rslt;
+}
+/*!
+ * @brief This API used to trigger the signification motion
+ * interrupt
+ *
+ *
+ * @param v_significant_u8 : The value of interrupt selection
+ * value | interrupt
+ * ----------|-----------
+ * 0 | BMI160_MAP_INTR1
+ * 1 | BMI160_MAP_INTR2
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_map_significant_motion_intr(
+u8 v_significant_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_sig_motion_u8 = BMI160_INIT_VALUE;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ u8 v_any_motion_intr1_stat_u8 = BMI160_ENABLE_ANY_MOTION_INTR1;
+ u8 v_any_motion_intr2_stat_u8 = BMI160_ENABLE_ANY_MOTION_INTR2;
+ u8 v_any_motion_axis_stat_u8 = BMI160_ENABLE_ANY_MOTION_AXIS;
+ /* enable the significant motion interrupt */
+ com_rslt = bmi160_get_intr_significant_motion_select(&v_sig_motion_u8);
+ if (v_sig_motion_u8 != BMI160_SIG_MOTION_STAT_HIGH)
+ com_rslt += bmi160_set_intr_significant_motion_select(
+ BMI160_SIG_MOTION_INTR_ENABLE);
+ switch (v_significant_u8) {
+ case BMI160_MAP_INTR1:
+ /* interrupt */
+ com_rslt += bmi160_read_reg(
+ BMI160_USER_INTR_MAP_0_INTR1_ANY_MOTION__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ v_data_u8 |= v_any_motion_intr1_stat_u8;
+ /* map the signification interrupt to any-motion interrupt1*/
+ com_rslt += bmi160_write_reg(
+ BMI160_USER_INTR_MAP_0_INTR1_ANY_MOTION__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* axis*/
+ com_rslt = bmi160_read_reg(BMI160_USER_INTR_ENABLE_0_ADDR,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ v_data_u8 |= v_any_motion_axis_stat_u8;
+ com_rslt += bmi160_write_reg(
+ BMI160_USER_INTR_ENABLE_0_ADDR,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ break;
+
+ case BMI160_MAP_INTR2:
+ /* map the signification interrupt to any-motion interrupt2*/
+ com_rslt += bmi160_read_reg(
+ BMI160_USER_INTR_MAP_2_INTR2_ANY_MOTION__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ v_data_u8 |= v_any_motion_intr2_stat_u8;
+ com_rslt += bmi160_write_reg(
+ BMI160_USER_INTR_MAP_2_INTR2_ANY_MOTION__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* axis*/
+ com_rslt = bmi160_read_reg(BMI160_USER_INTR_ENABLE_0_ADDR,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ v_data_u8 |= v_any_motion_axis_stat_u8;
+ com_rslt += bmi160_write_reg(
+ BMI160_USER_INTR_ENABLE_0_ADDR,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ break;
+
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API used to trigger the step detector
+ * interrupt
+ *
+ *
+ * @param v_step_detector_u8 : The value of interrupt selection
+ * value | interrupt
+ * ----------|-----------
+ * 0 | BMI160_MAP_INTR1
+ * 1 | BMI160_MAP_INTR2
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_map_step_detector_intr(
+u8 v_step_detector_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_step_det_u8 = BMI160_INIT_VALUE;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ u8 v_low_g_intr_u81_stat_u8 = BMI160_LOW_G_INTR_STAT;
+ u8 v_low_g_intr_u82_stat_u8 = BMI160_LOW_G_INTR_STAT;
+ u8 v_low_g_enable_u8 = BMI160_ENABLE_LOW_G;
+ /* read the v_status_s8 of step detector interrupt*/
+ com_rslt = bmi160_get_step_detector_enable(&v_step_det_u8);
+ if (v_step_det_u8 != BMI160_STEP_DET_STAT_HIGH)
+ com_rslt += bmi160_set_step_detector_enable(
+ BMI160_STEP_DETECT_INTR_ENABLE);
+ switch (v_step_detector_u8) {
+ case BMI160_MAP_INTR1:
+ com_rslt += bmi160_read_reg(
+ BMI160_USER_INTR_MAP_0_INTR1_LOW_G__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ v_data_u8 |= v_low_g_intr_u81_stat_u8;
+ /* map the step detector interrupt
+ to Low-g interrupt 1*/
+ com_rslt += bmi160_write_reg(
+ BMI160_USER_INTR_MAP_0_INTR1_LOW_G__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* Enable the Low-g interrupt*/
+ com_rslt = bmi160_read_reg(
+ BMI160_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ v_data_u8 |= v_low_g_enable_u8;
+ com_rslt += bmi160_write_reg(
+ BMI160_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ break;
+ case BMI160_MAP_INTR2:
+ /* map the step detector interrupt
+ to Low-g interrupt 1*/
+ com_rslt += bmi160_read_reg(
+ BMI160_USER_INTR_MAP_2_INTR2_LOW_G__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ v_data_u8 |= v_low_g_intr_u82_stat_u8;
+
+ com_rslt += bmi160_write_reg(
+ BMI160_USER_INTR_MAP_2_INTR2_LOW_G__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* Enable the Low-g interrupt*/
+ com_rslt = bmi160_read_reg(
+ BMI160_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ v_data_u8 |= v_low_g_enable_u8;
+ com_rslt += bmi160_write_reg(
+ BMI160_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API used to clear the step counter interrupt
+ * interrupt
+ *
+ *
+ * @param : None
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_clear_step_counter(void)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* clear the step counter*/
+ com_rslt = bmi160_set_command_register(RESET_STEP_COUNTER);
+ p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+
+ return com_rslt;
+
+}
+ /*!
+ * @brief This API writes value to the register 0x7E bit 0 to 7
+ *
+ *
+ * @param v_command_reg_u8 : The value to write command register
+ * value | Description
+ * ---------|--------------------------------------------------------
+ * 0x00 | Reserved
+ * 0x03 | Starts fast offset calibration for the accel and gyro
+ * 0x10 | Sets the PMU mode for the Accelerometer to suspend
+ * 0x11 | Sets the PMU mode for the Accelerometer to normal
+ * 0x12 | Sets the PMU mode for the Accelerometer Lowpower
+ * 0x14 | Sets the PMU mode for the Gyroscope to suspend
+ * 0x15 | Sets the PMU mode for the Gyroscope to normal
+ * 0x16 | Reserved
+ * 0x17 | Sets the PMU mode for the Gyroscope to fast start-up
+ * 0x18 | Sets the PMU mode for the Magnetometer to suspend
+ * 0x19 | Sets the PMU mode for the Magnetometer to normal
+ * 0x1A | Sets the PMU mode for the Magnetometer to Lowpower
+ * 0xB0 | Clears all data in the FIFO
+ * 0xB1 | Resets the interrupt engine
+ * 0xB2 | step_cnt_clr Clears the step counter
+ * 0xB6 | Triggers a reset
+ * 0x37 | See extmode_en_last
+ * 0x9A | See extmode_en_last
+ * 0xC0 | Enable the extended mode
+ * 0xC4 | Erase NVM cell
+ * 0xC8 | Load NVM cell
+ * 0xF0 | Reset acceleration data path
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_command_register(u8 v_command_reg_u8)
+{
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* write command register */
+ com_rslt = p_bmi160->BMI160_BUS_WRITE_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_CMD_COMMANDS__REG,
+ &v_command_reg_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API read target page from the register 0x7F bit 4 and 5
+ *
+ * @param v_target_page_u8: The value of target page
+ * value | page
+ * ---------|-----------
+ * 0 | User data/configure page
+ * 1 | Chip level trim/test page
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_target_page(u8 *v_target_page_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the page*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_CMD_TARGET_PAGE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_target_page_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_CMD_TARGET_PAGE);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write target page from the register 0x7F bit 4 and 5
+ *
+ * @param v_target_page_u8: The value of target page
+ * value | page
+ * ---------|-----------
+ * 0 | User data/configure page
+ * 1 | Chip level trim/test page
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_target_page(u8 v_target_page_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_target_page_u8 <= BMI160_MAX_TARGET_PAGE) {
+ /* write the page*/
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_CMD_TARGET_PAGE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_CMD_TARGET_PAGE,
+ v_target_page_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_CMD_TARGET_PAGE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API read page enable from the register 0x7F bit 7
+ *
+ *
+ *
+ * @param v_page_enable_u8: The value of page enable
+ * value | page
+ * ---------|-----------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_paging_enable(u8 *v_page_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the page enable */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_CMD_PAGING_EN__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_page_enable_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_CMD_PAGING_EN);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write page enable from the register 0x7F bit 7
+ *
+ *
+ *
+ * @param v_page_enable_u8: The value of page enable
+ * value | page
+ * ---------|-----------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_paging_enable(
+u8 v_page_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ if (v_page_enable_u8 <= BMI160_MAX_VALUE_PAGE) {
+ /* write the page enable */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_CMD_PAGING_EN__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_CMD_PAGING_EN,
+ v_page_enable_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_CMD_PAGING_EN__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API read
+ * pull up configuration from the register 0X85 bit 4 an 5
+ *
+ *
+ *
+ * @param v_control_pullup_u8: The value of pull up register
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_pullup_configuration(
+u8 *v_control_pullup_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read pull up value */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC(
+ p_bmi160->dev_addr,
+ BMI160_COM_C_TRIM_FIVE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ *v_control_pullup_u8 = BMI160_GET_BITSLICE(v_data_u8,
+ BMI160_COM_C_TRIM_FIVE);
+ }
+ return com_rslt;
+
+}
+ /*!
+ * @brief This API write
+ * pull up configuration from the register 0X85 bit 4 an 5
+ *
+ *
+ *
+ * @param v_control_pullup_u8: The value of pull up register
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_pullup_configuration(
+u8 v_control_pullup_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* write pull up value */
+ com_rslt = p_bmi160->BMI160_BUS_READ_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_COM_C_TRIM_FIVE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ BMI160_SET_BITSLICE(v_data_u8,
+ BMI160_COM_C_TRIM_FIVE,
+ v_control_pullup_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_WRITE_FUNC
+ (p_bmi160->dev_addr,
+ BMI160_COM_C_TRIM_FIVE__REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+
+/*!
+ * @brief This function used for read the compensated value of mag
+ * Before start reading the mag compensated data's
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_bmm150_mag_compensate_xyz(
+struct bmi160_mag_xyz_s32_t *mag_comp_xyz)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ struct bmi160_mag_xyzr_t mag_xyzr;
+ com_rslt = bmi160_read_mag_xyzr(&mag_xyzr);
+ if (com_rslt)
+ return com_rslt;
+ /* Compensation for X axis */
+ mag_comp_xyz->x = bmi160_bmm150_mag_compensate_X(
+ mag_xyzr.x, mag_xyzr.r);
+
+ /* Compensation for Y axis */
+ mag_comp_xyz->y = bmi160_bmm150_mag_compensate_Y(
+ mag_xyzr.y, mag_xyzr.r);
+
+ /* Compensation for Z axis */
+ mag_comp_xyz->z = bmi160_bmm150_mag_compensate_Z(
+ mag_xyzr.z, mag_xyzr.r);
+
+ return com_rslt;
+}
+
+/*!
+ * @brief This function used for read the compensated value of mag
+ * Before start reading the mag compensated data's
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_bmm150_mag_compensate_xyz_raw(
+struct bmi160_mag_xyz_s32_t *mag_comp_xyz, struct bmi160_mag_xyzr_t mag_xyzr)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+
+ /* Compensation for X axis */
+ mag_comp_xyz->x = bmi160_bmm150_mag_compensate_X(
+ mag_xyzr.x, mag_xyzr.r);
+
+ /* Compensation for Y axis */
+ mag_comp_xyz->y = bmi160_bmm150_mag_compensate_Y(
+ mag_xyzr.y, mag_xyzr.r);
+
+ /* Compensation for Z axis */
+ mag_comp_xyz->z = bmi160_bmm150_mag_compensate_Z(
+ mag_xyzr.z, mag_xyzr.r);
+
+ return com_rslt;
+}
+/*!
+ * @brief This API used to get the compensated BMM150-X data
+ * the out put of X as s32
+ * Before start reading the mag compensated X data
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ *
+ *
+ * @param v_mag_data_x_s16 : The value of mag raw X data
+ * @param v_data_r_u16 : The value of mag R data
+ *
+ * @return results of compensated X data value output as s32
+ *
+ */
+s32 bmi160_bmm150_mag_compensate_X(s16 v_mag_data_x_s16, u16 v_data_r_u16)
+{
+s32 inter_retval = BMI160_INIT_VALUE;
+/* no overflow */
+if (v_mag_data_x_s16 != BMI160_MAG_FLIP_OVERFLOW_ADCVAL) {
+ if ((v_data_r_u16 != 0)
+ && (mag_trim.dig_xyz1 != 0)) {
+ inter_retval = ((s32)(((u16)
+ ((((s32)mag_trim.dig_xyz1)
+ << BMI160_SHIFT_BIT_POSITION_BY_14_BITS)/
+ (v_data_r_u16 != 0 ?
+ v_data_r_u16 : mag_trim.dig_xyz1))) -
+ ((u16)0x4000)));
+ } else {
+ inter_retval = BMI160_MAG_OVERFLOW_OUTPUT;
+ return inter_retval;
+ }
+ inter_retval = ((s32)((((s32)v_mag_data_x_s16) *
+ ((((((((s32)mag_trim.dig_xy2) *
+ ((((s32)inter_retval) *
+ ((s32)inter_retval))
+ >> BMI160_SHIFT_BIT_POSITION_BY_07_BITS)) +
+ (((s32)inter_retval) *
+ ((s32)(((s16)mag_trim.dig_xy1)
+ << BMI160_SHIFT_BIT_POSITION_BY_07_BITS))))
+ >> BMI160_SHIFT_BIT_POSITION_BY_09_BITS) +
+ ((s32)0x100000)) *
+ ((s32)(((s16)mag_trim.dig_x2) +
+ ((s16)0xA0))))
+ >> BMI160_SHIFT_BIT_POSITION_BY_12_BITS))
+ >> BMI160_SHIFT_BIT_POSITION_BY_13_BITS)) +
+ (((s16)mag_trim.dig_x1)
+ << BMI160_SHIFT_BIT_POSITION_BY_03_BITS);
+ /* check the overflow output */
+ if (inter_retval == (s32)BMI160_MAG_OVERFLOW_OUTPUT)
+ inter_retval = BMI160_MAG_OVERFLOW_OUTPUT_S32;
+} else {
+ /* overflow */
+ inter_retval = BMI160_MAG_OVERFLOW_OUTPUT;
+}
+return inter_retval;
+}
+/*!
+ * @brief This API used to get the compensated BMM150-Y data
+ * the out put of Y as s32
+ * Before start reading the mag compensated Y data
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ *
+ *
+ * @param v_mag_data_y_s16 : The value of mag raw Y data
+ * @param v_data_r_u16 : The value of mag R data
+ *
+ * @return results of compensated Y data value output as s32
+ */
+s32 bmi160_bmm150_mag_compensate_Y(s16 v_mag_data_y_s16, u16 v_data_r_u16)
+{
+s32 inter_retval = BMI160_INIT_VALUE;
+/* no overflow */
+if (v_mag_data_y_s16 != BMI160_MAG_FLIP_OVERFLOW_ADCVAL) {
+ if ((v_data_r_u16 != 0)
+ && (mag_trim.dig_xyz1 != 0)) {
+ inter_retval = ((s32)(((u16)(((
+ (s32)mag_trim.dig_xyz1)
+ << BMI160_SHIFT_BIT_POSITION_BY_14_BITS) /
+ (v_data_r_u16 != 0 ?
+ v_data_r_u16 : mag_trim.dig_xyz1))) -
+ ((u16)0x4000)));
+ } else {
+ inter_retval = BMI160_MAG_OVERFLOW_OUTPUT;
+ return inter_retval;
+ }
+ inter_retval = ((s32)((((s32)v_mag_data_y_s16) * ((((((((s32)
+ mag_trim.dig_xy2) * ((((s32) inter_retval) *
+ ((s32)inter_retval)) >> BMI160_SHIFT_BIT_POSITION_BY_07_BITS))
+ + (((s32)inter_retval) *
+ ((s32)(((s16)mag_trim.dig_xy1)
+ << BMI160_SHIFT_BIT_POSITION_BY_07_BITS))))
+ >> BMI160_SHIFT_BIT_POSITION_BY_09_BITS) +
+ ((s32)0x100000))
+ * ((s32)(((s16)mag_trim.dig_y2)
+ + ((s16)0xA0))))
+ >> BMI160_SHIFT_BIT_POSITION_BY_12_BITS))
+ >> BMI160_SHIFT_BIT_POSITION_BY_13_BITS)) +
+ (((s16)mag_trim.dig_y1)
+ << BMI160_SHIFT_BIT_POSITION_BY_03_BITS);
+ /* check the overflow output */
+ if (inter_retval == (s32)BMI160_MAG_OVERFLOW_OUTPUT)
+ inter_retval = BMI160_MAG_OVERFLOW_OUTPUT_S32;
+} else {
+ /* overflow */
+ inter_retval = BMI160_MAG_OVERFLOW_OUTPUT;
+}
+return inter_retval;
+}
+/*!
+ * @brief This API used to get the compensated BMM150-Z data
+ * the out put of Z as s32
+ * Before start reading the mag compensated Z data
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ *
+ *
+ * @param v_mag_data_z_s16 : The value of mag raw Z data
+ * @param v_data_r_u16 : The value of mag R data
+ *
+ * @return results of compensated Z data value output as s32
+ */
+s32 bmi160_bmm150_mag_compensate_Z(s16 v_mag_data_z_s16, u16 v_data_r_u16)
+{
+ s32 retval = BMI160_INIT_VALUE;
+
+ if (v_mag_data_z_s16 != BMI160_MAG_HALL_OVERFLOW_ADCVAL) {
+ if ((v_data_r_u16 != 0)
+ && (mag_trim.dig_z2 != 0)
+ /* && (mag_trim.dig_z3 != 0)*/
+ && (mag_trim.dig_z1 != 0)
+ && (mag_trim.dig_xyz1 != 0)) {
+ retval = (((((s32)(v_mag_data_z_s16 - mag_trim.dig_z4))
+ << BMI160_SHIFT_BIT_POSITION_BY_15_BITS) -
+ ((((s32)mag_trim.dig_z3) *
+ ((s32)(((s16)v_data_r_u16) -
+ ((s16)mag_trim.dig_xyz1))))
+ >> BMI160_SHIFT_BIT_POSITION_BY_02_BITS))/
+ (mag_trim.dig_z2 +
+ ((s16)(((((s32)mag_trim.dig_z1) *
+ ((((s16)v_data_r_u16)
+ << BMI160_SHIFT_BIT_POSITION_BY_01_BIT))) +
+ (1 << BMI160_SHIFT_BIT_POSITION_BY_15_BITS))
+ >> BMI160_SHIFT_BIT_POSITION_BY_16_BITS))));
+ }
+ } else {
+ retval = BMI160_MAG_OVERFLOW_OUTPUT;
+ }
+ return retval;
+}
+ /*!
+ * @brief This function used for initialize the bmm150 sensor
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_bmm150_mag_interface_init(void)
+{
+ /* This variable used for provide the communication
+ results*/
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = BMI160_INIT_VALUE;
+ u8 v_pull_value_u8 = BMI160_INIT_VALUE;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ /* accel operation mode to normal*/
+ com_rslt = bmi160_set_command_register(ACCEL_MODE_NORMAL);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* write the mag power mode as NORMAL*/
+ com_rslt += bmi160_set_mag_interface_normal();
+
+ /* register 0x7E write the 0x37, 0x9A and 0x30*/
+ com_rslt += bmi160_set_command_register(BMI160_COMMAND_REG_ONE);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_command_register(BMI160_COMMAND_REG_TWO);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_command_register(BMI160_COMMAND_REG_THREE);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /*switch the page1*/
+ com_rslt += bmi160_set_target_page(BMI160_WRITE_TARGET_PAGE1);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ bmi160_get_target_page(&v_data_u8);
+ com_rslt += bmi160_set_paging_enable(BMI160_WRITE_ENABLE_PAGE1);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ bmi160_get_paging_enable(&v_data_u8);
+ /* enable the pullup configuration from
+ the register 0x05 bit 4 and 5 as 10*/
+ bmi160_get_pullup_configuration(&v_pull_value_u8);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ v_pull_value_u8 = v_pull_value_u8 | BMI160_PULL_UP_DATA;
+ com_rslt += bmi160_set_pullup_configuration(v_pull_value_u8);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /*switch the page0*/
+ com_rslt += bmi160_set_target_page(BMI160_WRITE_TARGET_PAGE0);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ bmi160_get_target_page(&v_data_u8);
+ /* Write the BMM150 i2c address*/
+ com_rslt += bmi160_set_i2c_device_addr(BMI160_AUX_BMM150_I2C_ADDRESS);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* enable the mag interface to manual mode*/
+ com_rslt += bmi160_set_mag_manual_enable(BMI160_MANUAL_ENABLE);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ bmi160_get_mag_manual_enable(&v_data_u8);
+ /*Enable the MAG interface */
+ com_rslt += bmi160_set_if_mode(BMI160_ENABLE_MAG_IF_MODE);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ bmi160_get_if_mode(&v_data_u8);
+ /* Mag normal mode*/
+ com_rslt += bmi160_bmm150_mag_wakeup();
+ printk(KERN_INFO "com_rslt:%d, <%s><%d>\n",
+ com_rslt, __func__, __LINE__);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* Read the BMM150 device id is 0x32*/
+ /*com_rslt += bmi160_set_mag_read_addr(BMI160_BMM150_CHIP_ID);*/
+ /*p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);*/
+ /*com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);*/
+ /**v_chip_id_u8 = v_data_u8;*/
+ /*p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);*/
+ /* write the power mode register*/
+ com_rslt += bmi160_set_mag_write_data(BMI160_BMM_POWER_MODE_REG);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /*write 0x4C register to write set power mode to normal*/
+ com_rslt += bmi160_set_mag_write_addr(
+ BMI160_BMM150_POWE_MODE_REG);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* read the mag trim values*/
+ com_rslt += bmi160_read_bmm150_mag_trim();
+ printk(KERN_INFO "com_rslt:%d, <%s><%d>\n",
+ com_rslt, __func__, __LINE__);
+ /* To avoid the auto mode enable when manual mode operation running*/
+ V_bmm150_maual_auto_condition_u8 = BMI160_MANUAL_ENABLE;
+ /* write the XY and Z repetitions*/
+ com_rslt += bmi160_set_bmm150_mag_presetmode(
+ BMI160_MAG_PRESETMODE_REGULAR);
+ printk(KERN_INFO "com_rslt:%d, <%s><%d>\n",
+ com_rslt, __func__, __LINE__);
+ /* To avoid the auto mode enable when manual mode operation running*/
+ V_bmm150_maual_auto_condition_u8 = BMI160_MANUAL_DISABLE;
+ /* Set the power mode of mag as force mode*/
+ /* The data have to write for the register
+ It write the value in the register 0x4F */
+ com_rslt += bmi160_set_mag_write_data(BMI160_BMM150_FORCE_MODE);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ printk(KERN_INFO "com_rslt:%d, <%s><%d>\n",
+ com_rslt, __func__, __LINE__);
+ /* write into power mode register*/
+ com_rslt += bmi160_set_mag_write_addr(
+ BMI160_BMM150_POWE_MODE_REG);
+ /* write the mag v_data_bw_u8 as 25Hz*/
+ com_rslt += bmi160_set_mag_output_data_rate(
+ BMI160_MAG_OUTPUT_DATA_RATE_25HZ);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+
+ /* When mag interface is auto mode - The mag read address
+ starts the register 0x42*/
+ com_rslt += bmi160_set_mag_read_addr(
+ BMI160_BMM150_DATA_REG);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* enable mag interface to auto mode*/
+ com_rslt += bmi160_set_mag_manual_enable(BMI160_MANUAL_DISABLE);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ bmi160_get_mag_manual_enable(&v_data_u8);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+
+ return com_rslt;
+}
+ /*!
+ * @brief This function used for set the mag power control
+ * bit enable
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_bmm150_mag_wakeup(void)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = BMI160_INIT_VALUE;
+ u8 v_try_times_u8 = BMI160_BMM150_MAX_RETRY_WAKEUP;
+ u8 v_power_control_bit_u8 = BMI160_INIT_VALUE;
+ u8 i = BMI160_INIT_VALUE;
+
+ for (i = BMI160_INIT_VALUE; i < v_try_times_u8; i++) {
+ com_rslt = bmi160_set_mag_write_data(BMI160_BMM150_POWER_ON);
+ p_bmi160->delay_msec(BMI160_BMM150_WAKEUP_DELAY1);
+ /*write 0x4B register to enable power control bit*/
+ com_rslt += bmi160_set_mag_write_addr(
+ BMI160_BMM150_POWE_CONTROL_REG);
+ p_bmi160->delay_msec(BMI160_BMM150_WAKEUP_DELAY2);
+ com_rslt += bmi160_set_mag_read_addr(
+ BMI160_BMM150_POWE_CONTROL_REG);
+ /* 0x04 is secondary read mag x lsb register */
+ p_bmi160->delay_msec(BMI160_BMM150_WAKEUP_DELAY3);
+ com_rslt += bmi160_read_reg(BMI160_USER_DATA_0_ADDR,
+ &v_power_control_bit_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ v_power_control_bit_u8 = BMI160_BMM150_SET_POWER_CONTROL
+ & v_power_control_bit_u8;
+ if (v_power_control_bit_u8 == BMI160_BMM150_POWER_ON)
+ break;
+ }
+ com_rslt = (i >= v_try_times_u8) ?
+ BMI160_BMM150_POWER_ON_FAIL : BMI160_BMM150_POWER_ON_SUCCESS;
+ return com_rslt;
+}
+ /*!
+ * @brief This function used for set the magnetometer
+ * power mode.
+ * @note
+ * Before set the mag power mode
+ * make sure the following two point is addressed
+ * Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ *
+ * @param v_mag_sec_if_pow_mode_u8 : The value of mag power mode
+ * value | mode
+ * ----------|------------
+ * 0 | BMI160_MAG_FORCE_MODE
+ * 1 | BMI160_MAG_SUSPEND_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_bmm150_mag_and_secondary_if_power_mode(
+u8 v_mag_sec_if_pow_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = BMI160_INIT_VALUE;
+ /* set the accel power mode to NORMAL*/
+ com_rslt = bmi160_set_command_register(ACCEL_MODE_NORMAL);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_bmi160->mag_manual_enable, __func__, __LINE__);
+ /* set mag interface manual mode*/
+ if (p_bmi160->mag_manual_enable != BMI160_MANUAL_ENABLE) {
+ com_rslt += bmi160_set_mag_manual_enable(
+ BMI160_MANUAL_ENABLE);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ }
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_bmi160->mag_manual_enable, __func__, __LINE__);
+
+ switch (v_mag_sec_if_pow_mode_u8) {
+ case BMI160_MAG_FORCE_MODE:
+ /* set the secondary mag power mode as NORMAL*/
+ com_rslt += bmi160_set_mag_interface_normal();
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_bmi160->mag_manual_enable, __func__, __LINE__);
+ /* set the mag power mode as FORCE mode*/
+ com_rslt += bmi160_bmm150_mag_set_power_mode(FORCE_MODE);
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_bmi160->mag_manual_enable, __func__, __LINE__);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ break;
+ case BMI160_MAG_SUSPEND_MODE:
+ /* set the mag power mode as SUSPEND mode*/
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_bmi160->mag_manual_enable, __func__, __LINE__);
+ com_rslt += bmi160_bmm150_mag_set_power_mode(SUSPEND_MODE);
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_bmi160->mag_manual_enable, __func__, __LINE__);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* set the secondary mag power mode as SUSPEND*/
+ com_rslt += bmi160_set_command_register(MAG_MODE_SUSPEND);
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_bmi160->mag_manual_enable, __func__, __LINE__);
+ p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ if (p_bmi160->mag_manual_enable == BMI160_MANUAL_ENABLE) {
+ /* set mag interface auto mode*/
+ com_rslt += bmi160_set_mag_manual_enable(
+ BMI160_MANUAL_DISABLE);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ }
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_bmi160->mag_manual_enable, __func__, __LINE__);
+ return com_rslt;
+}
+/*!
+ * @brief This function used for set the magnetometer
+ * power mode.
+ * @note
+ * Before set the mag power mode
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ * @param v_mag_pow_mode_u8 : The value of mag power mode
+ * value | mode
+ * ----------|------------
+ * 0 | FORCE_MODE
+ * 1 | SUSPEND_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_bmm150_mag_set_power_mode(
+u8 v_mag_pow_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = BMI160_INIT_VALUE;
+ u8 manual_enable_status = 0;
+ /* set mag interface manual mode*/
+ if (p_bmi160->mag_manual_enable != BMI160_MANUAL_ENABLE) {
+ com_rslt = bmi160_set_mag_manual_enable(
+ BMI160_MANUAL_ENABLE);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_get_mag_manual_enable(&manual_enable_status);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ printk(KERN_INFO "1com_rslt:%d, manual:%d, manual_read:%d\n",
+ com_rslt, p_bmi160->mag_manual_enable, manual_enable_status);
+ }
+ printk(KERN_INFO "2com_rslt:%d, manual:%d, manual_read:%d\n",
+ com_rslt, p_bmi160->mag_manual_enable, manual_enable_status);
+
+ switch (v_mag_pow_mode_u8) {
+ case FORCE_MODE:
+ /* Set the power control bit enabled */
+ com_rslt = bmi160_bmm150_mag_wakeup();
+ /* write the mag power mode as FORCE mode*/
+ com_rslt += bmi160_set_mag_write_data(
+ BMI160_BMM150_FORCE_MODE);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(
+ BMI160_BMM150_POWE_MODE_REG);
+ p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* To avoid the auto mode enable when manual
+ mode operation running*/
+ V_bmm150_maual_auto_condition_u8 = BMI160_MANUAL_ENABLE;
+ /* set the preset mode */
+ com_rslt += bmi160_set_bmm150_mag_presetmode(
+ BMI160_MAG_PRESETMODE_REGULAR);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* To avoid the auto mode enable when manual
+ mode operation running*/
+ V_bmm150_maual_auto_condition_u8 = BMI160_MANUAL_DISABLE;
+ /* set the mag read address to data registers*/
+ com_rslt += bmi160_set_mag_read_addr(
+ BMI160_BMM150_DATA_REG);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ break;
+ case SUSPEND_MODE:
+ printk(KERN_INFO "3com_rslt:%d, manual:%d, read_manual:%d\n",
+ com_rslt, p_bmi160->mag_manual_enable, manual_enable_status);
+ /* Set the power mode of mag as suspend mode*/
+ com_rslt += bmi160_set_mag_write_data(
+ BMI160_BMM150_POWER_OFF);
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_bmi160->mag_manual_enable, __func__, __LINE__);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(
+ BMI160_BMM150_POWE_CONTROL_REG);
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_bmi160->mag_manual_enable, __func__, __LINE__);
+ p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ printk(KERN_INFO "4com_rslt:%d, manual:%d, manual_read:%d\n",
+ com_rslt, p_bmi160->mag_manual_enable, manual_enable_status);
+ /* set mag interface auto mode*/
+ if (p_bmi160->mag_manual_enable == BMI160_MANUAL_ENABLE) {
+ com_rslt += bmi160_set_mag_manual_enable(
+ BMI160_MANUAL_DISABLE);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_get_mag_manual_enable(&manual_enable_status);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ }
+ printk(KERN_INFO "5com_rslt:%d, manual:%d, manual_read:%d\n",
+ com_rslt, p_bmi160->mag_manual_enable, manual_enable_status);
+ return com_rslt;
+}
+/*!
+ * @brief This API used to set the pre-set modes of bmm150
+ * The pre-set mode setting is depend on data rate and xy and z repetitions
+ *
+ * @note
+ * Before set the mag preset mode
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ *
+ * @param v_mode_u8: The value of pre-set mode selection value
+ * value | pre_set mode
+ * ----------|------------
+ * 1 | BMI160_MAG_PRESETMODE_LOWPOWER
+ * 2 | BMI160_MAG_PRESETMODE_REGULAR
+ * 3 | BMI160_MAG_PRESETMODE_HIGHACCURACY
+ * 4 | BMI160_MAG_PRESETMODE_ENHANCED
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_bmm150_mag_presetmode(u8 v_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ switch (v_mode_u8) {
+ case BMI160_MAG_PRESETMODE_LOWPOWER:
+ /* write the XY and Z repetitions*/
+ /* The v_data_u8 have to write for the register
+ It write the value in the register 0x4F*/
+ com_rslt = bmi160_set_mag_write_data(
+ BMI160_MAG_LOWPOWER_REPXY);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(
+ BMI160_BMM150_XY_REP);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* write the Z repetitions*/
+ /* The v_data_u8 have to write for the register
+ It write the value in the register 0x4F*/
+ com_rslt += bmi160_set_mag_write_data(
+ BMI160_MAG_LOWPOWER_REPZ);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(
+ BMI160_BMM150_Z_REP);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* set the mag v_data_u8 rate as 10 to the register 0x4C*/
+ com_rslt += bmi160_set_mag_write_data(
+ BMI160_MAG_LOWPOWER_DR);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(
+ BMI160_BMM150_POWE_MODE_REG);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ break;
+ case BMI160_MAG_PRESETMODE_REGULAR:
+ /* write the XY and Z repetitions*/
+ /* The v_data_u8 have to write for the register
+ It write the value in the register 0x4F*/
+ com_rslt = bmi160_set_mag_write_data(
+ BMI160_MAG_REGULAR_REPXY);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(
+ BMI160_BMM150_XY_REP);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* write the Z repetitions*/
+ /* The v_data_u8 have to write for the register
+ It write the value in the register 0x4F*/
+ com_rslt += bmi160_set_mag_write_data(
+ BMI160_MAG_REGULAR_REPZ);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(
+ BMI160_BMM150_Z_REP);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* set the mag v_data_u8 rate as 10 to the register 0x4C*/
+ com_rslt += bmi160_set_mag_write_data(
+ BMI160_MAG_REGULAR_DR);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(
+ BMI160_BMM150_POWE_MODE_REG);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ break;
+ case BMI160_MAG_PRESETMODE_HIGHACCURACY:
+ /* write the XY and Z repetitions*/
+ /* The v_data_u8 have to write for the register
+ It write the value in the register 0x4F*/
+ com_rslt = bmi160_set_mag_write_data(
+ BMI160_MAG_HIGHACCURACY_REPXY);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(
+ BMI160_BMM150_XY_REP);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* write the Z repetitions*/
+ /* The v_data_u8 have to write for the register
+ It write the value in the register 0x4F*/
+ com_rslt += bmi160_set_mag_write_data(
+ BMI160_MAG_HIGHACCURACY_REPZ);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(
+ BMI160_BMM150_Z_REP);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* set the mag v_data_u8 rate as 20 to the register 0x4C*/
+ com_rslt += bmi160_set_mag_write_data(
+ BMI160_MAG_HIGHACCURACY_DR);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(
+ BMI160_BMM150_POWE_MODE_REG);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ break;
+ case BMI160_MAG_PRESETMODE_ENHANCED:
+ /* write the XY and Z repetitions*/
+ /* The v_data_u8 have to write for the register
+ It write the value in the register 0x4F*/
+ com_rslt = bmi160_set_mag_write_data(
+ BMI160_MAG_ENHANCED_REPXY);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(
+ BMI160_BMM150_XY_REP);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* write the Z repetitions*/
+ /* The v_data_u8 have to write for the register
+ It write the value in the register 0x4F*/
+ com_rslt += bmi160_set_mag_write_data(
+ BMI160_MAG_ENHANCED_REPZ);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(
+ BMI160_BMM150_Z_REP);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* set the mag v_data_u8 rate as 10 to the register 0x4C*/
+ com_rslt += bmi160_set_mag_write_data(
+ BMI160_MAG_ENHANCED_DR);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(
+ BMI160_BMM150_POWE_MODE_REG);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+
+ return com_rslt;
+}
+ /*!
+ * @brief This function used for read the trim values of magnetometer
+ *
+ * @note
+ * Before reading the mag trimming values
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_bmm150_mag_trim(void)
+{
+ /* This variable used for provide the communication
+ results*/
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* Array holding the bmm150 trim data
+ */
+ u8 v_data_u8[BMI160_MAG_TRIM_DATA_SIZE] = {
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE};
+ /* read dig_x1 value */
+ com_rslt = bmi160_set_mag_read_addr(
+ BMI160_MAG_DIG_X1);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[BMI160_BMM150_DIG_X1],
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ mag_trim.dig_x1 = v_data_u8[BMI160_BMM150_DIG_X1];
+ /* read dig_y1 value */
+ com_rslt += bmi160_set_mag_read_addr(
+ BMI160_MAG_DIG_Y1);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[BMI160_BMM150_DIG_Y1],
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ mag_trim.dig_y1 = v_data_u8[BMI160_BMM150_DIG_Y1];
+
+ /* read dig_x2 value */
+ com_rslt += bmi160_set_mag_read_addr(
+ BMI160_MAG_DIG_X2);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[BMI160_BMM150_DIG_X2],
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ mag_trim.dig_x2 = v_data_u8[BMI160_BMM150_DIG_X2];
+ /* read dig_y2 value */
+ com_rslt += bmi160_set_mag_read_addr(
+ BMI160_MAG_DIG_Y2);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[BMI160_BMM150_DIG_Y3],
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ mag_trim.dig_y2 = v_data_u8[BMI160_BMM150_DIG_Y3];
+
+ /* read dig_xy1 value */
+ com_rslt += bmi160_set_mag_read_addr(
+ BMI160_MAG_DIG_XY1);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[BMI160_BMM150_DIG_XY1],
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ mag_trim.dig_xy1 = v_data_u8[BMI160_BMM150_DIG_XY1];
+ /* read dig_xy2 value */
+ com_rslt += bmi160_set_mag_read_addr(
+ BMI160_MAG_DIG_XY2);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* 0x04 is v_mag_x_s16 ls register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[BMI160_BMM150_DIG_XY2],
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ mag_trim.dig_xy2 = v_data_u8[BMI160_BMM150_DIG_XY2];
+
+ /* read dig_z1 lsb value */
+ com_rslt += bmi160_set_mag_read_addr(
+ BMI160_MAG_DIG_Z1_LSB);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[BMI160_BMM150_DIG_Z1_LSB],
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* read dig_z1 msb value */
+ com_rslt += bmi160_set_mag_read_addr(BMI160_MAG_DIG_Z1_MSB);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* 0x04 is v_mag_x_s16 msb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[BMI160_BMM150_DIG_Z1_MSB],
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ mag_trim.dig_z1 =
+ (u16)((((u32)((u8)v_data_u8[BMI160_BMM150_DIG_Z1_MSB]))
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[BMI160_BMM150_DIG_Z1_LSB]));
+
+ /* read dig_z2 lsb value */
+ com_rslt += bmi160_set_mag_read_addr(BMI160_MAG_DIG_Z2_LSB);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[BMI160_BMM150_DIG_Z2_LSB],
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* read dig_z2 msb value */
+ com_rslt += bmi160_set_mag_read_addr(BMI160_MAG_DIG_Z2_MSB);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* 0x04 is v_mag_x_s16 msb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[BMI160_BMM150_DIG_Z2_MSB],
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ mag_trim.dig_z2 =
+ (s16)((((s32)((s8)v_data_u8[BMI160_BMM150_DIG_Z2_MSB]))
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[BMI160_BMM150_DIG_Z2_LSB]));
+
+ /* read dig_z3 lsb value */
+ com_rslt += bmi160_set_mag_read_addr(BMI160_MAG_DIG_Z3_LSB);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[BMI160_BMM150_DIG_DIG_Z3_LSB],
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* read dig_z3 msb value */
+ com_rslt += bmi160_set_mag_read_addr(BMI160_MAG_DIG_Z3_MSB);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* 0x04 is v_mag_x_s16 msb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[BMI160_BMM150_DIG_DIG_Z3_MSB],
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ mag_trim.dig_z3 =
+ (s16)((((s32)((s8)v_data_u8[BMI160_BMM150_DIG_DIG_Z3_MSB]))
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[BMI160_BMM150_DIG_DIG_Z3_LSB]));
+
+ /* read dig_z4 lsb value */
+ com_rslt += bmi160_set_mag_read_addr(BMI160_MAG_DIG_Z4_LSB);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[BMI160_BMM150_DIG_DIG_Z4_LSB],
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* read dig_z4 msb value */
+ com_rslt += bmi160_set_mag_read_addr(BMI160_MAG_DIG_Z4_MSB);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* 0x04 is v_mag_x_s16 msb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[BMI160_BMM150_DIG_DIG_Z4_MSB],
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ mag_trim.dig_z4 =
+ (s16)((((s32)((s8)v_data_u8[BMI160_BMM150_DIG_DIG_Z4_MSB]))
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[BMI160_BMM150_DIG_DIG_Z4_LSB]));
+
+ /* read dig_xyz1 lsb value */
+ com_rslt += bmi160_set_mag_read_addr(BMI160_MAG_DIG_XYZ1_LSB);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[BMI160_BMM150_DIG_DIG_XYZ1_LSB],
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* read dig_xyz1 msb value */
+ com_rslt += bmi160_set_mag_read_addr(BMI160_MAG_DIG_XYZ1_MSB);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* 0x04 is v_mag_x_s16 msb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[BMI160_BMM150_DIG_DIG_XYZ1_MSB],
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ mag_trim.dig_xyz1 =
+ (u16)((((u32)((u8)v_data_u8[BMI160_BMM150_DIG_DIG_XYZ1_MSB]))
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[BMI160_BMM150_DIG_DIG_XYZ1_LSB]));
+
+ return com_rslt;
+}
+ /*!
+ * @brief This function used for initialize
+ * the AKM09911 and AKM09912 sensor
+ *
+ *
+ * @param v_akm_i2c_address_u8: The value of device address
+ * AKM sensor | Slave address
+ * --------------|---------------------
+ * AKM09911 | AKM09911_I2C_ADDR_1
+ * - | and AKM09911_I2C_ADDR_2
+ * AKM09912 | AKM09912_I2C_ADDR_1
+ * - | AKM09912_I2C_ADDR_2
+ * - | AKM09912_I2C_ADDR_3
+ * - | AKM09912_I2C_ADDR_4
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_akm_mag_interface_init(
+u8 v_akm_i2c_address_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_pull_value_u8 = BMI160_INIT_VALUE;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ u8 v_akm_chip_id_u8 = BMI160_INIT_VALUE;
+ /* accel operation mode to normal*/
+ com_rslt = bmi160_set_command_register(ACCEL_MODE_NORMAL);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_command_register(MAG_MODE_NORMAL);
+ p_bmi160->delay_msec(BMI160_AKM_INIT_DELAY);
+ bmi160_get_mag_power_mode_stat(&v_data_u8);
+ /* register 0x7E write the 0x37, 0x9A and 0x30*/
+ com_rslt += bmi160_set_command_register(BMI160_COMMAND_REG_ONE);
+ p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_command_register(BMI160_COMMAND_REG_TWO);
+ p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_command_register(BMI160_COMMAND_REG_THREE);
+ p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /*switch the page1*/
+ com_rslt += bmi160_set_target_page(BMI160_WRITE_TARGET_PAGE1);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ bmi160_get_target_page(&v_data_u8);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_paging_enable(BMI160_WRITE_ENABLE_PAGE1);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ bmi160_get_paging_enable(&v_data_u8);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* enable the pullup configuration from
+ the register 0x05 bit 4 and 5 to 10*/
+ bmi160_get_pullup_configuration(&v_pull_value_u8);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ v_pull_value_u8 = v_pull_value_u8 | BMI160_PULL_UP_DATA;
+ com_rslt += bmi160_set_pullup_configuration(v_pull_value_u8);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+
+ /*switch the page0*/
+ com_rslt += bmi160_set_target_page(BMI160_WRITE_TARGET_PAGE0);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ bmi160_get_target_page(&v_data_u8);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* Write the AKM09911 0r AKM09912 i2c address*/
+ com_rslt += bmi160_set_i2c_device_addr(v_akm_i2c_address_u8);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* enable the mag interface to manual mode*/
+ com_rslt += bmi160_set_mag_manual_enable(BMI160_MANUAL_ENABLE);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ bmi160_get_mag_manual_enable(&v_data_u8);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /*Enable the MAG interface */
+ com_rslt += bmi160_set_if_mode(BMI160_ENABLE_MAG_IF_MODE);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ bmi160_get_if_mode(&v_data_u8);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+
+ /* Set the AKM Fuse ROM mode */
+ /* Set value for fuse ROM mode*/
+ com_rslt += bmi160_set_mag_write_data(AKM_FUSE_ROM_MODE);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* AKM mode address is 0x31*/
+ com_rslt += bmi160_set_mag_write_addr(AKM_POWER_MODE_REG);
+ p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* Read the Fuse ROM v_data_u8 from registers
+ 0x60,0x61 and 0x62*/
+ /* ASAX v_data_u8 */
+ com_rslt += bmi160_read_bst_akm_sensitivity_data();
+ p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* read the device id of the AKM sensor
+ if device id is 0x05 - AKM09911
+ if device id is 0x04 - AKM09912*/
+ com_rslt += bmi160_set_mag_read_addr(AKM09912_CHIP_ID_REG);
+ /* 0x04 is mag_x lsb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_akm_chip_id_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ printk(KERN_INFO "bmi160,addr:0x%x, akm_chip_id:0x%x",
+ v_akm_i2c_address_u8, v_akm_chip_id_u8);
+ /* Set value power down mode mode*/
+ com_rslt += bmi160_set_mag_write_data(AKM_POWER_DOWN_MODE_DATA);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* AKM mode address is 0x31*/
+ com_rslt += bmi160_set_mag_write_addr(AKM_POWER_MODE_REG);
+ p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* Set AKM Force mode*/
+ com_rslt += bmi160_set_mag_write_data(
+ AKM_SINGLE_MEASUREMENT_MODE);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* AKM mode address is 0x31*/
+ com_rslt += bmi160_set_mag_write_addr(AKM_POWER_MODE_REG);
+ p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* Set the AKM read xyz v_data_u8 address*/
+ com_rslt += bmi160_set_mag_read_addr(AKM_DATA_REGISTER);
+ /* write the mag v_data_bw_u8 as 25Hz*/
+ com_rslt += bmi160_set_mag_output_data_rate(
+ BMI160_MAG_OUTPUT_DATA_RATE_25HZ);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* Enable mag interface to auto mode*/
+ com_rslt += bmi160_set_mag_manual_enable(BMI160_MANUAL_DISABLE);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ bmi160_get_mag_manual_enable(&v_data_u8);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+
+ return com_rslt;
+}
+ /*!
+ * @brief This function used for read the sensitivity data of
+ * AKM09911 and AKM09912
+ *
+ * @note Before reading the mag sensitivity values
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_bst_akm_sensitivity_data(void)
+{
+ /* This variable used for provide the communication
+ results*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* Array holding the sensitivity ax,ay and az data*/
+ u8 v_data_u8[BMI160_AKM_SENSITIVITY_DATA_SIZE] = {
+ BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE};
+ /* read asax value */
+ com_rslt = bmi160_set_mag_read_addr(BMI160_BST_AKM_ASAX);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[AKM_ASAX],
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ akm_asa_data.asax = v_data_u8[AKM_ASAX];
+ /* read asay value */
+ com_rslt += bmi160_set_mag_read_addr(BMI160_BST_AKM_ASAY);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[AKM_ASAY],
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ akm_asa_data.asay = v_data_u8[AKM_ASAY];
+ /* read asaz value */
+ com_rslt += bmi160_set_mag_read_addr(BMI160_BST_AKM_ASAZ);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[AKM_ASAZ],
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ akm_asa_data.asaz = v_data_u8[AKM_ASAZ];
+
+ return com_rslt;
+}
+/*!
+ * @brief This API used to get the compensated X data
+ * of AKM09911 the out put of X as s32
+ * @note Before start reading the mag compensated X data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bst_akm_x_s16 : The value of X data
+ *
+ * @return results of compensated X data value output as s32
+ *
+ */
+s32 bmi160_bst_akm09911_compensate_X(s16 v_bst_akm_x_s16)
+{
+ /*Return value of AKM x compensated v_data_u8*/
+ s32 retval = BMI160_INIT_VALUE;
+ /* Convert raw v_data_u8 into compensated v_data_u8*/
+ retval = (v_bst_akm_x_s16 *
+ ((akm_asa_data.asax/AKM09911_SENSITIVITY_DIV) +
+ BMI160_GEN_READ_WRITE_DATA_LENGTH));
+ return retval;
+}
+/*!
+ * @brief This API used to get the compensated Y data
+ * of AKM09911 the out put of Y as s32
+ * @note Before start reading the mag compensated Y data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bst_akm_y_s16 : The value of Y data
+ *
+ * @return results of compensated Y data value output as s32
+ *
+ */
+s32 bmi160_bst_akm09911_compensate_Y(s16 v_bst_akm_y_s16)
+{
+ /*Return value of AKM y compensated v_data_u8*/
+ s32 retval = BMI160_INIT_VALUE;
+ /* Convert raw v_data_u8 into compensated v_data_u8*/
+ retval = (v_bst_akm_y_s16 *
+ ((akm_asa_data.asay/AKM09911_SENSITIVITY_DIV) +
+ BMI160_GEN_READ_WRITE_DATA_LENGTH));
+ return retval;
+}
+/*!
+ * @brief This API used to get the compensated Z data
+ * of AKM09911 the out put of Z as s32
+ * @note Before start reading the mag compensated Z data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bst_akm_z_s16 : The value of Z data
+ *
+ * @return results of compensated Z data value output as s32
+ *
+ */
+s32 bmi160_bst_akm09911_compensate_Z(s16 v_bst_akm_z_s16)
+{
+ /*Return value of AKM z compensated v_data_u8*/
+ s32 retval = BMI160_INIT_VALUE;
+ /* Convert raw v_data_u8 into compensated v_data_u8*/
+ retval = (v_bst_akm_z_s16 *
+ ((akm_asa_data.asaz/AKM09911_SENSITIVITY_DIV) +
+ BMI160_GEN_READ_WRITE_DATA_LENGTH));
+ return retval;
+}
+/*!
+ * @brief This API used to get the compensated X data
+ * of AKM09912 the out put of X as s32
+ * @note Before start reading the mag compensated X data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bst_akm_x_s16 : The value of X data
+ *
+ * @return results of compensated X data value output as s32
+ *
+ */
+s32 bmi160_bst_akm09912_compensate_X(s16 v_bst_akm_x_s16)
+{
+ /*Return value of AKM x compensated data*/
+ s32 retval = BMI160_INIT_VALUE;
+ /* Convert raw data into compensated data*/
+ retval = v_bst_akm_x_s16 *
+ (akm_asa_data.asax + AKM09912_SENSITIVITY)
+ / AKM09912_SENSITIVITY_DIV;
+ return retval;
+}
+/*!
+ * @brief This API used to get the compensated Y data
+ * of AKM09912 the out put of Y as s32
+ * @note Before start reading the mag compensated Y data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bst_akm_y_s16 : The value of Y data
+ *
+ * @return results of compensated Y data value output as s32
+ *
+ */
+s32 bmi160_bst_akm09912_compensate_Y(s16 v_bst_akm_y_s16)
+{
+ /*Return value of AKM y compensated data*/
+ s32 retval = BMI160_INIT_VALUE;
+ /* Convert raw data into compensated data*/
+ retval = v_bst_akm_y_s16 *
+ (akm_asa_data.asax + AKM09912_SENSITIVITY)
+ / AKM09912_SENSITIVITY_DIV;
+ return retval;
+}
+/*!
+ * @brief This API used to get the compensated Z data
+ * of AKM09912 the out put of Z as s32
+ * @note Before start reading the mag compensated Z data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bst_akm_z_s16 : The value of Z data
+ *
+ * @return results of compensated Z data value output as s32
+ *
+ */
+s32 bmi160_bst_akm09912_compensate_Z(s16 v_bst_akm_z_s16)
+{
+ /*Return value of AKM z compensated data*/
+ s32 retval = BMI160_INIT_VALUE;
+ /* Convert raw data into compensated data*/
+ retval = v_bst_akm_z_s16 *
+ (akm_asa_data.asax + AKM09912_SENSITIVITY)
+ / AKM09912_SENSITIVITY_DIV;
+ return retval;
+}
+ /*!
+ * @brief This function used for read the compensated value of
+ * AKM09911
+ * @note Before start reading the mag compensated data's
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_akm09911_compensate_xyz(
+struct bmi160_mag_xyz_s32_t *bst_akm_xyz)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ struct bmi160_mag_t mag_xyz;
+
+ com_rslt = bmi160_read_mag_xyz(&mag_xyz, BST_AKM);
+ /* Compensation for X axis */
+ bst_akm_xyz->x = bmi160_bst_akm09911_compensate_X(mag_xyz.x);
+
+ /* Compensation for Y axis */
+ bst_akm_xyz->y = bmi160_bst_akm09911_compensate_Y(mag_xyz.y);
+
+ /* Compensation for Z axis */
+ bst_akm_xyz->z = bmi160_bst_akm09911_compensate_Z(mag_xyz.z);
+
+ return com_rslt;
+}
+ /*!
+ * @brief This function used for read the compensated value of
+ * AKM09912
+ * @note Before start reading the mag compensated data's
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_akm09912_compensate_xyz(
+struct bmi160_mag_xyz_s32_t *bst_akm_xyz)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ struct bmi160_mag_t mag_xyz;
+
+ com_rslt = bmi160_read_mag_xyz(&mag_xyz, BST_AKM);
+ printk(KERN_INFO "akm09912_raw_x:%d, %d, %d, <%s>,<%d>",
+ mag_xyz.x, mag_xyz.y, mag_xyz.z, __func__, __LINE__);
+ /* Compensation for X axis */
+ bst_akm_xyz->x = bmi160_bst_akm09912_compensate_X(mag_xyz.x);
+
+ /* Compensation for Y axis */
+ bst_akm_xyz->y = bmi160_bst_akm09912_compensate_Y(mag_xyz.y);
+
+ /* Compensation for Z axis */
+ bst_akm_xyz->z = bmi160_bst_akm09912_compensate_Z(mag_xyz.z);
+ return com_rslt;
+}
+ /*!
+ * @brief This function used for read the compensated value of
+ * AKM09912
+ * @note Before start reading the mag compensated data's
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_akm09912_compensate_xyz_raw(
+struct bmi160_mag_xyz_s32_t *bst_akm_xyz)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* Compensation for X axis */
+ bst_akm_xyz->x = bmi160_bst_akm09912_compensate_X(bst_akm_xyz->x);
+
+ /* Compensation for Y axis */
+ bst_akm_xyz->y = bmi160_bst_akm09912_compensate_Y(bst_akm_xyz->y);
+
+ /* Compensation for Z axis */
+ bst_akm_xyz->z = bmi160_bst_akm09912_compensate_Z(bst_akm_xyz->z);
+
+ return com_rslt;
+}
+/*!
+ * @brief This function used for set the AKM09911 and AKM09912
+ * power mode.
+ * @note Before set the AKM power mode
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ * @param v_akm_pow_mode_u8 : The value of akm power mode
+ * value | Description
+ * ---------|--------------------
+ * 0 | AKM_POWER_DOWN_MODE
+ * 1 | AKM_SINGLE_MEAS_MODE
+ * 2 | FUSE_ROM_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_akm_set_powermode(
+u8 v_akm_pow_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = BMI160_INIT_VALUE;
+ /* set mag interface manual mode*/
+ if (p_bmi160->mag_manual_enable != BMI160_MANUAL_ENABLE) {
+ com_rslt = bmi160_set_mag_manual_enable(
+ BMI160_MANUAL_ENABLE);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ }
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s>\n",
+ com_rslt, p_bmi160->mag_manual_enable, __func__);
+ switch (v_akm_pow_mode_u8) {
+ case AKM_POWER_DOWN_MODE:
+ /* Set the power mode of AKM as power down mode*/
+ com_rslt += bmi160_set_mag_write_data(AKM_POWER_DOWN_MODE_DATA);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(AKM_POWER_MODE_REG);
+ p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ break;
+ case AKM_SINGLE_MEAS_MODE:
+ /* Set the power mode of AKM as
+ single measurement mode*/
+ com_rslt += bmi160_set_mag_write_data
+ (AKM_SINGLE_MEASUREMENT_MODE);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(AKM_POWER_MODE_REG);
+ p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_read_addr(AKM_DATA_REGISTER);
+ break;
+ case FUSE_ROM_MODE:
+ /* Set the power mode of AKM as
+ Fuse ROM mode*/
+ com_rslt += bmi160_set_mag_write_data(AKM_FUSE_ROM_MODE);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(AKM_POWER_MODE_REG);
+ p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* Sensitivity v_data_u8 */
+ com_rslt += bmi160_read_bst_akm_sensitivity_data();
+ p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* power down mode*/
+ com_rslt += bmi160_set_mag_write_data(AKM_POWER_DOWN_MODE);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(AKM_POWER_MODE_REG);
+ p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ /* set mag interface auto mode*/
+ if (p_bmi160->mag_manual_enable == BMI160_MANUAL_ENABLE) {
+ com_rslt += bmi160_set_mag_manual_enable(
+ BMI160_MANUAL_DISABLE);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ }
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_bmi160->mag_manual_enable, __func__, __LINE__);
+ return com_rslt;
+}
+ /*!
+ * @brief This function used for set the magnetometer
+ * power mode of AKM09911 and AKM09912
+ * @note Before set the mag power mode
+ * make sure the following two point is addressed
+ * Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ *
+ * @param v_mag_sec_if_pow_mode_u8 : The value of secondary if power mode
+ * value | Description
+ * ---------|--------------------
+ * 0 | BMI160_MAG_FORCE_MODE
+ * 1 | BMI160_MAG_SUSPEND_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_bst_akm_and_secondary_if_powermode(
+u8 v_mag_sec_if_pow_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* accel operation mode to normal*/
+ com_rslt = bmi160_set_command_register(ACCEL_MODE_NORMAL);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* set mag interface manual mode*/
+ if (p_bmi160->mag_manual_enable != BMI160_MANUAL_ENABLE) {
+ com_rslt = bmi160_set_mag_manual_enable(
+ BMI160_MANUAL_ENABLE);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ }
+ printk(KERN_ERR "com_rslt:%d, manual:%d,after setacc normal mode\n",
+ com_rslt, p_bmi160->mag_manual_enable);
+ switch (v_mag_sec_if_pow_mode_u8) {
+ case BMI160_MAG_FORCE_MODE:
+ /* set the secondary mag power mode as NORMAL*/
+ com_rslt += bmi160_set_mag_interface_normal();
+ /* set the akm power mode as single measurement mode*/
+ com_rslt += bmi160_bst_akm_set_powermode(AKM_SINGLE_MEAS_MODE);
+ p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_read_addr(AKM_DATA_REGISTER);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ break;
+ case BMI160_MAG_SUSPEND_MODE:
+ /* set the akm power mode as power down mode*/
+ com_rslt += bmi160_bst_akm_set_powermode(AKM_POWER_DOWN_MODE);
+ p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* set the secondary mag power mode as SUSPEND*/
+ com_rslt += bmi160_set_command_register(MAG_MODE_SUSPEND);
+ p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ break;
+ default:
+ com_rslt = E_BMI160_OUT_OF_RANGE;
+ break;
+ }
+ /* set mag interface auto mode*/
+ if (p_bmi160->mag_manual_enable == BMI160_MANUAL_ENABLE)
+ com_rslt += bmi160_set_mag_manual_enable(
+ BMI160_MANUAL_DISABLE);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ return com_rslt;
+}
+/*!
+ * @brief This function used for read the YAMAH-YAS532 init
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yamaha_yas532_mag_interface_init(
+void)
+{
+ /* This variable used for provide the communication
+ results*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ u8 v_pull_value_u8 = BMI160_INIT_VALUE;
+ u8 v_data_u8 = BMI160_INIT_VALUE;
+ u8 i = BMI160_INIT_VALUE;
+ /* accel operation mode to normal*/
+ com_rslt = bmi160_set_command_register(ACCEL_MODE_NORMAL);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* write mag power mode as NORMAL*/
+ com_rslt += bmi160_set_mag_interface_normal();
+ /* register 0x7E write the 0x37, 0x9A and 0x30*/
+ com_rslt += bmi160_set_command_register(BMI160_COMMAND_REG_ONE);
+ p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_command_register(BMI160_COMMAND_REG_TWO);
+ p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_command_register(BMI160_COMMAND_REG_THREE);
+ p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /*switch the page1*/
+ com_rslt += bmi160_set_target_page(BMI160_WRITE_TARGET_PAGE1);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ bmi160_get_target_page(&v_data_u8);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_paging_enable(BMI160_WRITE_ENABLE_PAGE1);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ bmi160_get_paging_enable(&v_data_u8);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* enable the pullup configuration from
+ the register 0x05 bit 4 and 5 as 10*/
+ bmi160_get_pullup_configuration(&v_pull_value_u8);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ v_pull_value_u8 = v_pull_value_u8 | BMI160_PULL_UP_DATA;
+ com_rslt += bmi160_set_pullup_configuration(v_pull_value_u8);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /*switch the page0*/
+ com_rslt += bmi160_set_target_page(BMI160_WRITE_TARGET_PAGE0);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ bmi160_get_target_page(&v_data_u8);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* Write the YAS532 i2c address*/
+ com_rslt += bmi160_set_i2c_device_addr(BMI160_AUX_YAS532_I2C_ADDRESS);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* enable the mag interface to manual mode*/
+ com_rslt += bmi160_set_mag_manual_enable(BMI160_MANUAL_ENABLE);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ bmi160_get_mag_manual_enable(&v_data_u8);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /*Enable the MAG interface */
+ com_rslt += bmi160_set_if_mode(BMI160_ENABLE_MAG_IF_MODE);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ bmi160_get_if_mode(&v_data_u8);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ v_data_u8 = BMI160_MANUAL_DISABLE;
+ /* Read the YAS532 device id is 0x02*/
+ com_rslt += bmi160_set_mag_read_addr(BMI160_YAS_DEVICE_ID_REG);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* Read the YAS532 calibration data*/
+ com_rslt += bmi160_bst_yamaha_yas532_calib_values();
+ p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* Assign the data acquisition mode*/
+ yas532_data.measure_state = YAS532_MAG_STATE_INIT_COIL;
+ /* Set the default offset as invalid offset*/
+ set_vector(yas532_data.v_hard_offset_s8, INVALID_OFFSET);
+ /* set the transform to zero */
+ yas532_data.transform = BMI160_NULL;
+ /* Assign overflow as zero*/
+ yas532_data.overflow = 0;
+ #if YAS532_MAG_LOG < YAS532_MAG_TEMPERATURE_LOG
+ yas532_data.temp_data.num =
+ yas532_data.temp_data.idx = 0;
+ #endif
+ /* Assign the coef value*/
+ for (i = 0; i < 3; i++) {
+ yas532_data.coef[i] = yas532_version_ac_coef[i];
+ yas532_data.last_raw[i] = 0;
+ }
+ yas532_data.last_raw[3] = 0;
+ /* Set the initial values of yas532*/
+ com_rslt += bmi160_bst_yas532_set_initial_values();
+ /* write the mag v_data_bw_u8 as 25Hz*/
+ com_rslt += bmi160_set_mag_output_data_rate(
+ BMI160_MAG_OUTPUT_DATA_RATE_25HZ);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* Enable mag interface to auto mode*/
+ com_rslt += bmi160_set_mag_manual_enable(
+ BMI160_MANUAL_DISABLE);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ bmi160_get_mag_manual_enable(&v_data_u8);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+
+ return com_rslt;
+}
+/*!
+ * @brief This function used to set the YAS532 initial values
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas532_set_initial_values(void)
+{
+/* This variable used for provide the communication
+ results*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* write testr1 as 0x00*/
+ com_rslt = bmi160_set_mag_write_data(
+ BMI160_YAS532_WRITE_TESTR1);
+ p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(BMI160_YAS532_TESTR1);
+ p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* write testr2 as 0x00*/
+ com_rslt += bmi160_set_mag_write_data(
+ BMI160_YAS532_WRITE_TESTR2);
+ p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(BMI160_YAS532_TESTR2);
+ p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* write Rcoil as 0x00*/
+ com_rslt += bmi160_set_mag_write_data(
+ BMI160_YAS532_WRITE_RCOIL);
+ p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(BMI160_YAS532_RCOIL);
+ p_bmi160->delay_msec(BMI160_YAS532_SET_INITIAL_VALUE_DELAY);
+ /* check the valid offset*/
+ if (is_valid_offset(yas532_data.v_hard_offset_s8)) {
+ com_rslt += bmi160_bst_yas532_set_offset(
+ yas532_data.v_hard_offset_s8);
+ yas532_data.measure_state = YAS532_MAG_STATE_NORMAL;
+ } else {
+ /* set the default offset as invalid offset*/
+ set_vector(yas532_data.v_hard_offset_s8, INVALID_OFFSET);
+ /*Set the default measure state for offset correction*/
+ yas532_data.measure_state = YAS532_MAG_STATE_MEASURE_OFFSET;
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This function used for YAS532 offset correction
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas532_magnetic_measure_set_offset(
+void)
+{
+ /* This variable used for provide the communication
+ results*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* used for offset value set to the offset register*/
+ s8 v_hard_offset_s8[BMI160_HARD_OFFSET_DATA_SIZE] = {
+ BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE};
+ /* offset correction factors*/
+ static const u8 v_correct_u8[BMI160_YAS_CORRECT_DATA_SIZE] = {
+ 16, 8, 4, 2, 1};
+ /* used for the temperature */
+ u16 v_temp_u16 = BMI160_INIT_VALUE;
+ /* used for the xy1y2 read*/
+ u16 v_xy1y2_u16[BMI160_YAS_XY1Y2_DATA_SIZE] = {BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE};
+ /* local flag for assign the values*/
+ s32 v_flag_s32[BMI160_YAS_FLAG_DATA_SIZE] = {BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE};
+ u8 i, j, v_busy_u8, v_overflow_u8 = BMI160_INIT_VALUE;
+
+ for (i = 0; i < 5; i++) {
+ /* set the offset values*/
+ com_rslt = bmi160_bst_yas532_set_offset(v_hard_offset_s8);
+ /* read the sensor data*/
+ com_rslt += bmi160_bst_yas532_normal_measurement_data(
+ BMI160_YAS532_ACQ_START, &v_busy_u8, &v_temp_u16,
+ v_xy1y2_u16, &v_overflow_u8);
+ /* check the sensor busy status*/
+ if (v_busy_u8)
+ return E_BMI160_BUSY;
+ /* calculate the magnetic correction with
+ offset and assign the values
+ to the offset register */
+ for (j = 0; j < 3; j++) {
+ if (YAS532_DATA_CENTER == v_xy1y2_u16[j])
+ v_flag_s32[j] = 0;
+ if (YAS532_DATA_CENTER < v_xy1y2_u16[j])
+ v_flag_s32[j] = 1;
+ if (v_xy1y2_u16[j] < YAS532_DATA_CENTER)
+ v_flag_s32[j] = -1;
+ }
+ for (j = 0; j < 3; j++) {
+ if (v_flag_s32[j])
+ v_hard_offset_s8[j] = (s8)(v_hard_offset_s8[j]
+ + v_flag_s32[j] * v_correct_u8[i]);
+ }
+ }
+ /* set the offset */
+ com_rslt += bmi160_bst_yas532_set_offset(v_hard_offset_s8);
+ return com_rslt;
+}
+/*!
+ * @brief This function used for read the
+ * YAMAHA YAS532 calibration data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yamaha_yas532_calib_values(void)
+{
+ /* This variable used for provide the communication
+ results*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* Array holding the YAS532 calibration values */
+ u8 v_data_u8[BMI160_YAS532_CALIB_DATA_SIZE] = {
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE};
+ /* Read the DX value */
+ com_rslt = bmi160_set_mag_read_addr(BMI160_YAS532_CALIB_CX);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[0], BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ yas532_data.calib_yas532.cx = (s32)((v_data_u8[0]
+ * 10) - 1280);
+ /* Read the DY1 value */
+ com_rslt += bmi160_set_mag_read_addr(BMI160_YAS532_CALIB_CY1);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[1], BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ yas532_data.calib_yas532.cy1 =
+ (s32)((v_data_u8[1] * 10) - 1280);
+ /* Read the DY2 value */
+ com_rslt += bmi160_set_mag_read_addr(BMI160_YAS532_CALIB_CY2);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[2], BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ yas532_data.calib_yas532.cy2 =
+ (s32)((v_data_u8[2] * 10) - 1280);
+ /* Read the D2 and D3 value */
+ com_rslt += bmi160_set_mag_read_addr(BMI160_YAS532_CALIB1);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[3], BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ yas532_data.calib_yas532.a2 =
+ (s32)(((v_data_u8[3] >>
+ BMI160_SHIFT_BIT_POSITION_BY_02_BITS)
+ & 0x03F) - 32);
+ /* Read the D3 and D4 value */
+ com_rslt += bmi160_set_mag_read_addr(BMI160_YAS532_CALIB2);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[4], BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ /* calculate a3*/
+ yas532_data.calib_yas532.a3 = (s32)((((v_data_u8[3] <<
+ BMI160_SHIFT_BIT_POSITION_BY_02_BITS) & 0x0C) |
+ ((v_data_u8[4]
+ >> BMI160_SHIFT_BIT_POSITION_BY_06_BITS)
+ & 0x03)) - 8);
+ /* calculate a4*/
+ yas532_data.calib_yas532.a4 = (s32)((v_data_u8[4]
+ & 0x3F) - 32);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* Read the D5 and D6 value */
+ com_rslt += bmi160_set_mag_read_addr(BMI160_YAS532_CALIB3);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[5], BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ /* calculate a5*/
+ yas532_data.calib_yas532.a5 =
+ (s32)(((v_data_u8[5]
+ >> BMI160_SHIFT_BIT_POSITION_BY_02_BITS)
+ & 0x3F) + 38);
+ /* Read the D6 and D7 value */
+ com_rslt += bmi160_set_mag_read_addr(BMI160_YAS532_CALIB4);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[6], BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ /* calculate a6*/
+ yas532_data.calib_yas532.a6 =
+ (s32)((((v_data_u8[5]
+ << BMI160_SHIFT_BIT_POSITION_BY_04_BITS)
+ & 0x30) | ((v_data_u8[6] >>
+ BMI160_SHIFT_BIT_POSITION_BY_04_BITS)
+ & 0x0F)) - 32);
+ /* Read the D7 and D8 value */
+ com_rslt += bmi160_set_mag_read_addr(BMI160_YAS532_CALIB5);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[7], BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ /* calculate a7*/
+ yas532_data.calib_yas532.a7 = (s32)((((v_data_u8[6]
+ << BMI160_SHIFT_BIT_POSITION_BY_03_BITS)
+ & 0x78) |
+ ((v_data_u8[7]
+ >> BMI160_SHIFT_BIT_POSITION_BY_05_BITS) &
+ 0x07)) - 64);
+ /* Read the D8 and D9 value */
+ com_rslt += bmi160_set_mag_read_addr(BMI160_YAS532_CLAIB6);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[8], BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ /* calculate a8*/
+ yas532_data.calib_yas532.a8 = (s32)((((v_data_u8[7] <<
+ BMI160_GEN_READ_WRITE_DATA_LENGTH) & 0x3E) |
+ ((v_data_u8[8] >>
+ BMI160_SHIFT_BIT_POSITION_BY_07_BITS) & 0x01)) -
+ 32);
+
+ /* Read the D8 and D9 value */
+ com_rslt += bmi160_set_mag_read_addr(BMI160_YAS532_CALIB7);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[9], BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ /* calculate a9*/
+ yas532_data.calib_yas532.a9 = (s32)(((v_data_u8[8] <<
+ BMI160_GEN_READ_WRITE_DATA_LENGTH) & 0xFE) |
+ ((v_data_u8[9] >>
+ BMI160_SHIFT_BIT_POSITION_BY_07_BITS) & 0x01));
+ /* calculate k*/
+ yas532_data.calib_yas532.k = (s32)((v_data_u8[9] >>
+ BMI160_SHIFT_BIT_POSITION_BY_02_BITS) & 0x1F);
+ /* Read the value from register 0x9A*/
+ com_rslt += bmi160_set_mag_read_addr(BMI160_YAS532_CALIB8);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[10],
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ /* Read the value from register 0x9B*/
+ com_rslt += bmi160_set_mag_read_addr(BMI160_YAS532_CALIIB9);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[11],
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ /* Read the value from register 0x9C*/
+ com_rslt += bmi160_set_mag_read_addr(BMI160_YAS532_CALIB10);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[12],
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ /* Read the value from register 0x9D*/
+ com_rslt += bmi160_set_mag_read_addr(BMI160_YAS532_CALIB11);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+ &v_data_u8[13],
+ BMI160_GEN_READ_WRITE_DATA_LENGTH);
+ /* Calculate the fxy1y2 and rxy1y1*/
+ yas532_data.calib_yas532.fxy1y2[0] =
+ (u8)(((v_data_u8[10]
+ & 0x01)
+ << BMI160_SHIFT_BIT_POSITION_BY_01_BIT)
+ | ((v_data_u8[11] >>
+ BMI160_SHIFT_BIT_POSITION_BY_07_BITS) & 0x01));
+ yas532_data.calib_yas532.rxy1y2[0] =
+ ((s8)(((v_data_u8[10]
+ >> BMI160_SHIFT_BIT_POSITION_BY_01_BIT) & 0x3F)
+ << BMI160_SHIFT_BIT_POSITION_BY_02_BITS))
+ >> BMI160_SHIFT_BIT_POSITION_BY_02_BITS;
+ yas532_data.calib_yas532.fxy1y2[1] =
+ (u8)(((v_data_u8[11] & 0x01)
+ << BMI160_SHIFT_BIT_POSITION_BY_01_BIT)
+ | ((v_data_u8[12] >>
+ BMI160_SHIFT_BIT_POSITION_BY_07_BITS) & 0x01));
+ yas532_data.calib_yas532.rxy1y2[1] =
+ ((s8)(((v_data_u8[11]
+ >> BMI160_SHIFT_BIT_POSITION_BY_01_BIT) & 0x3F)
+ << BMI160_SHIFT_BIT_POSITION_BY_02_BITS))
+ >> BMI160_SHIFT_BIT_POSITION_BY_02_BITS;
+ yas532_data.calib_yas532.fxy1y2[2] =
+ (u8)(((v_data_u8[12] & 0x01)
+ << BMI160_SHIFT_BIT_POSITION_BY_01_BIT)
+ | ((v_data_u8[13]
+ >> BMI160_SHIFT_BIT_POSITION_BY_07_BITS) & 0x01));
+ yas532_data.calib_yas532.rxy1y2[2] =
+ ((s8)(((v_data_u8[12]
+ >> BMI160_SHIFT_BIT_POSITION_BY_01_BIT) & 0x3F)
+ << BMI160_SHIFT_BIT_POSITION_BY_02_BITS))
+ >> BMI160_SHIFT_BIT_POSITION_BY_02_BITS;
+
+ return com_rslt;
+}
+/*!
+ * @brief This function used for calculate the
+ * YAS532 read the linear data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas532_xy1y2_to_linear(
+u16 *v_xy1y2_u16, s32 *xy1y2_linear)
+{
+ /* This variable used for provide the communication
+ results*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = SUCCESS;
+ static const u16 v_calib_data[] = {
+ 3721, 3971, 4221, 4471};
+ u8 i = BMI160_INIT_VALUE;
+
+ for (i = 0; i < 3; i++)
+ xy1y2_linear[i] = v_xy1y2_u16[i] -
+ v_calib_data[yas532_data.calib_yas532.fxy1y2[i]]
+ + (yas532_data.v_hard_offset_s8[i] -
+ yas532_data.calib_yas532.rxy1y2[i])
+ * yas532_data.coef[i];
+ return com_rslt;
+}
+/*!
+ * @brief This function used for read the YAS532 sensor data
+ * @param v_acquisition_command_u8: used to set the data acquisition
+ * acquisition_command | operation
+ * ---------------------|-------------------------
+ * 0x17 | turn on the acquisition coil
+ * - | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Deferred acquisition mode
+ * 0x07 | turn on the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Normal acquisition mode
+ * 0x11 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Deferred acquisition mode
+ * 0x01 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Normal acquisition mode
+ *
+ * @param v_busy_u8 : used to get the busy flay for sensor data read
+ * @param v_temp_u16 : used to get the temperature data
+ * @param v_xy1y2_u16 : used to get the sensor xy1y2 data
+ * @param v_overflow_u8 : used to get the overflow data
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas532_normal_measurement_data(
+u8 v_acquisition_command_u8, u8 *v_busy_u8,
+u16 *v_temp_u16, u16 *v_xy1y2_u16, u8 *v_overflow_u8)
+{
+ /* This variable used for provide the communication
+ results*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = BMI160_INIT_VALUE;
+ /* Array holding the YAS532 xyy1 data*/
+ u8 v_data_u8[BMI160_YAS_XY1Y2T_DATA_SIZE] = {
+ BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE};
+ u8 i = BMI160_INIT_VALUE;
+ /* check the p_bmi160 structure as NULL*/
+ if (p_bmi160 == BMI160_NULL) {
+ return E_BMI160_NULL_PTR;
+ } else {
+ /* read the sensor data */
+ com_rslt = bmi160_bst_yas532_acquisition_command_register(
+ v_acquisition_command_u8);
+ com_rslt +=
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_DATA_MAG_X_LSB__REG,
+ v_data_u8, BMI160_MAG_YAS_DATA_LENGTH);
+ /* read the xyy1 data*/
+ *v_busy_u8 =
+ ((v_data_u8[0]
+ >> BMI160_SHIFT_BIT_POSITION_BY_07_BITS) & 0x01);
+ *v_temp_u16 =
+ (u16)((((s32)v_data_u8[0]
+ << BMI160_SHIFT_BIT_POSITION_BY_03_BITS)
+ & 0x3F8) | ((v_data_u8[1]
+ >> BMI160_SHIFT_BIT_POSITION_BY_05_BITS) & 0x07));
+ v_xy1y2_u16[0] =
+ (u16)((((s32)v_data_u8[2]
+ << BMI160_SHIFT_BIT_POSITION_BY_06_BITS) & 0x1FC0)
+ | ((v_data_u8[3] >>
+ BMI160_SHIFT_BIT_POSITION_BY_02_BITS) & 0x3F));
+ v_xy1y2_u16[1] =
+ (u16)((((s32)v_data_u8[4]
+ << BMI160_SHIFT_BIT_POSITION_BY_06_BITS)
+ & 0x1FC0)
+ | ((v_data_u8[5]
+ >> BMI160_SHIFT_BIT_POSITION_BY_02_BITS) & 0x3F));
+ v_xy1y2_u16[2] =
+ (u16)((((s32)v_data_u8[6]
+ << BMI160_SHIFT_BIT_POSITION_BY_06_BITS)
+ & 0x1FC0)
+ | ((v_data_u8[7]
+ >> BMI160_SHIFT_BIT_POSITION_BY_02_BITS) & 0x3F));
+ *v_overflow_u8 = 0;
+ for (i = 0; i < 3; i++) {
+ if (v_xy1y2_u16[i] == YAS532_DATA_OVERFLOW)
+ *v_overflow_u8 |= (1 << (i * 2));
+ if (v_xy1y2_u16[i] == YAS532_DATA_UNDERFLOW)
+ *v_overflow_u8 |= (1 << (i * 2 + 1));
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This function used for YAS532 sensor data
+ * @param v_acquisition_command_u8 : the value of CMDR
+ * acquisition_command | operation
+ * ---------------------|-------------------------
+ * 0x17 | turn on the acquisition coil
+ * - | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Deferred acquisition mode
+ * 0x07 | turn on the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Normal acquisition mode
+ * 0x11 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Deferred acquisition mode
+ * 0x01 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Normal acquisition mode
+ *
+ * @param xyz_data : the vector xyz output
+ * @param v_overflow_s8 : the value of overflow
+ * @param v_temp_correction_u8 : the value of temperate correction enable
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas532_measurement_xyz_data(
+struct yas532_vector *xyz_data, u8 *v_overflow_s8, u8 v_temp_correction_u8,
+u8 v_acquisition_command_u8)
+{
+ /* This variable used for provide the communication
+ results*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = BMI160_INIT_VALUE;
+ /* Array holding the linear calculation output*/
+ s32 v_xy1y2_linear_s32[BMI160_YAS_XY1Y2_DATA_SIZE] = {
+ BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE};
+ /* Array holding the temperature data */
+ s32 v_xyz_tmp_s32[BMI160_YAS_TEMP_DATA_SIZE] = {BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE};
+ s32 tmp = BMI160_INIT_VALUE;
+ s32 sx, sy1, sy2, sy, sz = BMI160_INIT_VALUE;
+ u8 i, v_busy_u8 = BMI160_INIT_VALUE;
+ u16 v_temp_u16 = BMI160_INIT_VALUE;
+ /* Array holding the xyy1 sensor raw data*/
+ u16 v_xy1y2_u16[BMI160_YAS_XY1Y2_DATA_SIZE] = {BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE};
+ #if YAS532_MAG_LOG < YAS532_MAG_TEMPERATURE_LOG
+ s32 sum = BMI160_INIT_VALUE;
+ #endif
+ *v_overflow_s8 = BMI160_INIT_VALUE;
+ switch (yas532_data.measure_state) {
+ case YAS532_MAG_STATE_INIT_COIL:
+ if (p_bmi160->mag_manual_enable != BMI160_MANUAL_ENABLE)
+ com_rslt = bmi160_set_mag_manual_enable(
+ BMI160_MANUAL_ENABLE);
+ /* write Rcoil*/
+ com_rslt += bmi160_set_mag_write_data(
+ BMI160_YAS_DISABLE_RCOIL);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(BMI160_YAS532_RCOIL);
+ p_bmi160->delay_msec(BMI160_YAS532_MEASUREMENT_DELAY);
+ if (!yas532_data.overflow && is_valid_offset(
+ yas532_data.v_hard_offset_s8))
+ yas532_data.measure_state = 0;
+ break;
+ case YAS532_MAG_STATE_MEASURE_OFFSET:
+ com_rslt = bmi160_bst_yas532_magnetic_measure_set_offset();
+ yas532_data.measure_state = 0;
+ break;
+ default:
+ break;
+ }
+ /* Read sensor data*/
+ com_rslt += bmi160_bst_yas532_normal_measurement_data(
+ v_acquisition_command_u8, &v_busy_u8, &v_temp_u16,
+ v_xy1y2_u16, v_overflow_s8);
+ /* Calculate the linear data*/
+ com_rslt += bmi160_bst_yas532_xy1y2_to_linear(v_xy1y2_u16,
+ v_xy1y2_linear_s32);
+ /* Calculate temperature correction */
+ #if YAS532_MAG_LOG < YAS532_MAG_TEMPERATURE_LOG
+ yas532_data.temp_data.log[yas532_data.temp_data.idx++] =
+ v_temp_u16;
+ if (YAS532_MAG_TEMPERATURE_LOG <= yas532_data.temp_data.idx)
+ yas532_data.temp_data.idx = 0;
+ yas532_data.temp_data.num++;
+ if (YAS532_MAG_TEMPERATURE_LOG <= yas532_data.temp_data.num)
+ yas532_data.temp_data.num = YAS532_MAG_TEMPERATURE_LOG;
+ for (i = 0; i < yas532_data.temp_data.num; i++)
+ sum += yas532_data.temp_data.log[i];
+ tmp = sum * 10 / yas532_data.temp_data.num
+ - YAS532_TEMP20DEGREE_TYPICAL * 10;
+ #else
+ tmp = (v_temp_u16 - YAS532_TEMP20DEGREE_TYPICAL)
+ * 10;
+ #endif
+ sx = v_xy1y2_linear_s32[0];
+ sy1 = v_xy1y2_linear_s32[1];
+ sy2 = v_xy1y2_linear_s32[2];
+ /* Temperature correction */
+ if (v_temp_correction_u8) {
+ sx -= (yas532_data.calib_yas532.cx * tmp)
+ / 1000;
+ sy1 -= (yas532_data.calib_yas532.cy1 * tmp)
+ / 1000;
+ sy2 -= (yas532_data.calib_yas532.cy2 * tmp)
+ / 1000;
+ }
+ sy = sy1 - sy2;
+ sz = -sy1 - sy2;
+
+ xyz_data->yas532_vector_xyz[0] = yas532_data.calib_yas532.k *
+ ((100 * sx + yas532_data.calib_yas532.a2 * sy +
+ yas532_data.calib_yas532.a3 * sz) / 10);
+ xyz_data->yas532_vector_xyz[1] = yas532_data.calib_yas532.k *
+ ((yas532_data.calib_yas532.a4 * sx + yas532_data.calib_yas532.a5 * sy +
+ yas532_data.calib_yas532.a6 * sz) / 10);
+ xyz_data->yas532_vector_xyz[2] = yas532_data.calib_yas532.k *
+ ((yas532_data.calib_yas532.a7 * sx + yas532_data.calib_yas532.a8 * sy +
+ yas532_data.calib_yas532.a9 * sz) / 10);
+ if (yas532_data.transform != BMI160_NULL) {
+ for (i = 0; i < 3; i++) {
+ v_xyz_tmp_s32[i] = yas532_data.transform[i
+ * 3] *
+ xyz_data->yas532_vector_xyz[0]
+ + yas532_data.transform[i * 3 + 1] *
+ xyz_data->yas532_vector_xyz[1]
+ + yas532_data.transform[i * 3 + 2] *
+ xyz_data->yas532_vector_xyz[2];
+ }
+ set_vector(xyz_data->yas532_vector_xyz, v_xyz_tmp_s32);
+ }
+ for (i = 0; i < 3; i++) {
+ xyz_data->yas532_vector_xyz[i] -=
+ xyz_data->yas532_vector_xyz[i] % 10;
+ if (*v_overflow_s8 & (1
+ << (i * 2)))
+ xyz_data->yas532_vector_xyz[i] +=
+ 1; /* set overflow */
+ if (*v_overflow_s8 & (1 <<
+ (i * 2 + 1)))
+ xyz_data->yas532_vector_xyz[i] += 2; /* set underflow */
+ }
+
+
+if (v_busy_u8)
+ return com_rslt;
+ if (0 < *v_overflow_s8) {
+ if (!yas532_data.overflow)
+ yas532_data.overflow = 1;
+ yas532_data.measure_state = YAS532_MAG_STATE_INIT_COIL;
+ } else
+ yas532_data.overflow = 0;
+ for (i = 0; i < 3; i++)
+ yas532_data.last_raw[i] = v_xy1y2_u16[i];
+ yas532_data.last_raw[i] = v_temp_u16;
+ return com_rslt;
+}
+/*!
+ * @brief This function used for YAS532 write data acquisition
+ * command register write
+ * @param v_command_reg_data_u8 : the value of data acquisition
+ * acquisition_command | operation
+ * ---------------------|-------------------------
+ * 0x17 | turn on the acquisition coil
+ * - | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Deferred acquisition mode
+ * 0x07 | turn on the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Normal acquisition mode
+ * 0x11 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Deferred acquisition mode
+ * 0x01 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Normal acquisition mode
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas532_acquisition_command_register(
+u8 v_command_reg_data_u8)
+{
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+
+ if (p_bmi160->mag_manual_enable != BMI160_MANUAL_ENABLE)
+ com_rslt = bmi160_set_mag_manual_enable(
+ BMI160_MANUAL_ENABLE);
+
+ com_rslt = bmi160_set_mag_write_data(v_command_reg_data_u8);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* YAMAHA YAS532-0x82*/
+ com_rslt += bmi160_set_mag_write_addr(
+ BMI160_YAS532_COMMAND_REGISTER);
+ p_bmi160->delay_msec(BMI160_YAS_ACQ_COMMAND_DELAY);
+ com_rslt += bmi160_set_mag_read_addr(
+ BMI160_YAS532_DATA_REGISTER);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+
+ if (p_bmi160->mag_manual_enable == BMI160_MANUAL_ENABLE)
+ com_rslt += bmi160_set_mag_manual_enable(BMI160_MANUAL_DISABLE);
+
+ return com_rslt;
+
+}
+/*!
+ * @brief This function used write offset of YAS532
+ *
+ * @param p_offset_s8 : The value of offset to write
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas532_set_offset(
+const s8 *p_offset_s8)
+{
+ /* This variable used for provide the communication
+ results*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+
+ if (p_bmi160->mag_manual_enable != BMI160_MANUAL_ENABLE)
+ com_rslt = bmi160_set_mag_manual_enable(BMI160_MANUAL_ENABLE);
+ p_bmi160->delay_msec(BMI160_YAS532_OFFSET_DELAY);
+
+ /* Write offset X data*/
+ com_rslt = bmi160_set_mag_write_data(p_offset_s8[0]);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* YAS532 offset x write*/
+ com_rslt += bmi160_set_mag_write_addr(BMI160_YAS532_OFFSET_X);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+
+ /* Write offset Y data*/
+ com_rslt = bmi160_set_mag_write_data(p_offset_s8[1]);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* YAS532 offset y write*/
+ com_rslt += bmi160_set_mag_write_addr(BMI160_YAS532_OFFSET_Y);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+
+ /* Write offset Z data*/
+ com_rslt = bmi160_set_mag_write_data(p_offset_s8[2]);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* YAS532 offset z write*/
+ com_rslt += bmi160_set_mag_write_addr(BMI160_YAS532_OFFSET_Z);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ set_vector(yas532_data.v_hard_offset_s8, p_offset_s8);
+
+ if (p_bmi160->mag_manual_enable == BMI160_MANUAL_ENABLE)
+ com_rslt = bmi160_set_mag_manual_enable(BMI160_MANUAL_DISABLE);
+ return com_rslt;
+}
+/*!
+ * @brief This function used to init the YAMAH-YAS537
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yamaha_yas537_mag_interface_init(
+void)
+{
+/* This variable used for provide the communication
+results*/
+BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+u8 v_pull_value_u8 = BMI160_INIT_VALUE;
+u8 v_data_u8 = BMI160_INIT_VALUE;
+u8 i = BMI160_INIT_VALUE;
+/* accel operation mode to normal*/
+com_rslt = bmi160_set_command_register(ACCEL_MODE_NORMAL);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+/* write mag power mode as NORMAL*/
+com_rslt += bmi160_set_mag_interface_normal();
+/* register 0x7E write the 0x37, 0x9A and 0x30*/
+com_rslt += bmi160_set_command_register(BMI160_COMMAND_REG_ONE);
+p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+com_rslt += bmi160_set_command_register(BMI160_COMMAND_REG_TWO);
+p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+com_rslt += bmi160_set_command_register(BMI160_COMMAND_REG_THREE);
+p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+/*switch the page1*/
+com_rslt += bmi160_set_target_page(BMI160_WRITE_TARGET_PAGE1);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+bmi160_get_target_page(&v_data_u8);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+com_rslt += bmi160_set_paging_enable(BMI160_WRITE_ENABLE_PAGE1);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+bmi160_get_paging_enable(&v_data_u8);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+/* enable the pullup configuration from
+the register 0x05 bit 4 and 5 as 10*/
+bmi160_get_pullup_configuration(&v_pull_value_u8);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+v_pull_value_u8 = v_pull_value_u8 | BMI160_PULL_UP_DATA;
+com_rslt += bmi160_set_pullup_configuration(v_pull_value_u8);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+/*switch the page0*/
+com_rslt += bmi160_set_target_page(BMI160_WRITE_TARGET_PAGE0);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+bmi160_get_target_page(&v_data_u8);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+/* Write the YAS532 i2c address*/
+com_rslt += bmi160_set_i2c_device_addr(BMI160_YAS537_I2C_ADDRESS);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+/* enable the mag interface to manual mode*/
+com_rslt += bmi160_set_mag_manual_enable(BMI160_MANUAL_ENABLE);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+bmi160_get_mag_manual_enable(&v_data_u8);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+/*Enable the MAG interface */
+com_rslt += bmi160_set_if_mode(BMI160_ENABLE_MAG_IF_MODE);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+bmi160_get_if_mode(&v_data_u8);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+v_data_u8 = BMI160_MANUAL_DISABLE;
+/* Read the YAS537 device id*/
+com_rslt += bmi160_set_mag_read_addr(BMI160_YAS_DEVICE_ID_REG);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+&v_data_u8, BMI160_GEN_READ_WRITE_DATA_LENGTH);
+yas537_data.dev_id = v_data_u8;
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+/* Read the YAS532 calibration data*/
+com_rslt +=
+bmi160_bst_yamaha_yas537_calib_values(
+BMI160_GEN_READ_WRITE_DATA_LENGTH);
+p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+/* set the mode to NORMAL*/
+yas537_data.measure_state = YAS537_MAG_STATE_NORMAL;
+/* set the transform to zero */
+yas537_data.transform = BMI160_NULL;
+yas537_data.average = 32;
+for (i = 0; i < 3; i++) {
+ yas537_data.hard_offset[i] = -128;
+ yas537_data.last_after_rcoil[i] = 0;
+}
+for (i = 0; i < 4; i++)
+ yas537_data.last_raw[i] = 0;
+/* write the mag bandwidth as 25Hz*/
+com_rslt += bmi160_set_mag_output_data_rate(
+BMI160_MAG_OUTPUT_DATA_RATE_25HZ);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+/* Enable mag interface to auto mode*/
+com_rslt += bmi160_set_mag_manual_enable(
+BMI160_MANUAL_DISABLE);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+bmi160_get_mag_manual_enable(&v_data_u8);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+return com_rslt;
+}
+/*!
+* @brief This function used for read the
+* YAMAHA YAS537 calibration data
+*
+*
+* @param v_rcoil_u8 : The value of r coil
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yamaha_yas537_calib_values(
+u8 v_rcoil_u8)
+{
+/* This variable used for provide the communication
+results*/
+BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+/* Array holding the YAS532 calibration values */
+u8 a_data_u8[BMI160_YAS537_CALIB_DATA_SIZE] = {
+BMI160_INIT_VALUE, BMI160_INIT_VALUE,
+BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE,
+BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE,
+BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE,
+BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE,
+BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE,
+};
+static const u8 v_avrr_u8[] = {0x50, 0x60, 0x70};
+u8 v_cal_valid_u8 = BMI160_INIT_VALUE, i;
+/* write soft reset as 0x02*/
+com_rslt = bmi160_set_mag_write_data(
+YAS537_SRSTR_DATA);
+p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+com_rslt += bmi160_set_mag_write_addr(YAS537_REG_SRSTR);
+p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+/* Read the DX value */
+com_rslt = bmi160_set_mag_read_addr(YAS537_REG_CALR_C0);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+&a_data_u8[0], BMI160_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the DY1 value */
+com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_C1);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+&a_data_u8[1], BMI160_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the DY2 value */
+com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_C2);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+&a_data_u8[2], BMI160_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the D2 value */
+com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_C3);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+&a_data_u8[3], BMI160_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the D3 value */
+com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_C4);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+&a_data_u8[4], BMI160_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the D4 value */
+com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_C5);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+&a_data_u8[5], BMI160_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the D5 value */
+com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_C6);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+&a_data_u8[6], BMI160_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the D6 value */
+com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_C7);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+&a_data_u8[7], BMI160_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the D7 value */
+com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_C8);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+&a_data_u8[8], BMI160_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the D8 value */
+com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_C9);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+&a_data_u8[9], BMI160_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the D9 value */
+com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_CA);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+&a_data_u8[10], BMI160_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the RX value */
+com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_CB);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+&a_data_u8[11], BMI160_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the RY1 value */
+com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_CC);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+&a_data_u8[12], BMI160_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the RY2 value */
+com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_CD);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+&a_data_u8[13], BMI160_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the RY2 value */
+com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_CE);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+&a_data_u8[14], BMI160_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the CHF value */
+com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_CF);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+&a_data_u8[15], BMI160_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the VER value */
+com_rslt += bmi160_set_mag_read_addr(YAS537_REG_CALR_DO);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += bmi160_read_reg(BMI160_MAG_DATA_READ_REG,
+&a_data_u8[16], BMI160_GEN_READ_WRITE_DATA_LENGTH);
+/* get the calib ver*/
+yas537_data.calib_yas537.ver =
+(a_data_u8[16] >> BMI160_SHIFT_BIT_POSITION_BY_06_BITS);
+for (i = 0; i < 17; i++) {
+ if (((i < 16 && a_data_u8[i]) != 0))
+ v_cal_valid_u8 = 1;
+ if ((i < 16 &&
+ (a_data_u8[i] & 0x3F)) != 0)
+ v_cal_valid_u8 = 1;
+}
+if (!v_cal_valid_u8)
+ return ERROR;
+if (yas537_data.calib_yas537.ver == 0) {
+ for (i = 0; i < 17; i++) {
+ if (i < 12) {
+ /* write offset*/
+ com_rslt += bmi160_set_mag_write_data(
+ a_data_u8[i]);
+ p_bmi160->delay_msec(
+ BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(
+ YAS537_REG_MTCR + i);
+ p_bmi160->delay_msec(
+ BMI160_GEN_READ_WRITE_DELAY);
+ } else if (i < 15) {
+ /* write offset correction*/
+ com_rslt += bmi160_set_mag_write_data(
+ a_data_u8[i]);
+ p_bmi160->delay_msec(
+ BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr((
+ (YAS537_REG_OXR + i) - 12));
+ p_bmi160->delay_msec(
+ BMI160_GEN_READ_WRITE_DELAY);
+ yas537_data.hard_offset[i - 12]
+ = a_data_u8[i];
+ } else {
+ /* write offset correction*/
+ com_rslt += bmi160_set_mag_write_data(
+ a_data_u8[i]);
+ p_bmi160->delay_msec(
+ BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr((
+ (YAS537_REG_OXR + i) - 11));
+ p_bmi160->delay_msec(
+ BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ }
+
+}
+} else if (yas537_data.calib_yas537.ver == 1) {
+ for (i = 0; i < 3; i++) {
+ /* write offset*/
+ com_rslt += bmi160_set_mag_write_data(
+ a_data_u8[i]);
+ p_bmi160->delay_msec(
+ BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(
+ YAS537_REG_MTCR + i);
+ p_bmi160->delay_msec(
+ BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ if (com_rslt == SUCCESS) {
+ /* write offset*/
+ com_rslt += bmi160_set_mag_write_data(
+ a_data_u8[i + 12]);
+ p_bmi160->delay_msec(
+ BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(
+ YAS537_REG_OXR + i);
+ p_bmi160->delay_msec(
+ BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ yas537_data.hard_offset[i] =
+ a_data_u8[i + 12];
+ } else {
+ com_rslt = ERROR;
+ }
+ }
+ /* write offset*/
+ com_rslt += bmi160_set_mag_write_data(
+ ((a_data_u8[i] & 0xE0) | 0x10));
+ p_bmi160->delay_msec(
+ BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(
+ YAS537_REG_MTCR + i);
+ p_bmi160->delay_msec(
+ BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* write offset*/
+ com_rslt += bmi160_set_mag_write_data(
+ ((a_data_u8[15]
+ >> BMI160_SHIFT_BIT_POSITION_BY_03_BITS)
+ & 0x1E));
+ p_bmi160->delay_msec(
+ BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(YAS537_REG_HCKR);
+ p_bmi160->delay_msec(
+ BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* write offset*/
+ com_rslt += bmi160_set_mag_write_data(
+ ((a_data_u8[15] << 1) & 0x1E));
+ p_bmi160->delay_msec(
+ BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(YAS537_REG_LCKR);
+ p_bmi160->delay_msec(
+ BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* write offset*/
+ com_rslt += bmi160_set_mag_write_data(
+ (a_data_u8[16] & 0x3F));
+ p_bmi160->delay_msec(
+ BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(YAS537_REG_OCR);
+ p_bmi160->delay_msec(
+ BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+
+ /* Assign the calibration values*/
+ /* a2 */
+ yas537_data.calib_yas537.a2 =
+ ((((a_data_u8[3]
+ << BMI160_SHIFT_BIT_POSITION_BY_02_BITS)
+ & 0x7C)
+ | (a_data_u8[4]
+ >> BMI160_SHIFT_BIT_POSITION_BY_06_BITS)) - 64);
+ /* a3 */
+ yas537_data.calib_yas537.a3 =
+ ((((a_data_u8[4] << BMI160_SHIFT_BIT_POSITION_BY_01_BIT)
+ & 0x7E)
+ | (a_data_u8[5]
+ >> BMI160_SHIFT_BIT_POSITION_BY_07_BITS)) - 64);
+ /* a4 */
+ yas537_data.calib_yas537.a4 =
+ ((((a_data_u8[5]
+ << BMI160_SHIFT_BIT_POSITION_BY_01_BIT)
+ & 0xFE)
+ | (a_data_u8[6]
+ >> BMI160_SHIFT_BIT_POSITION_BY_07_BITS))
+ - 128);
+ /* a5 */
+ yas537_data.calib_yas537.a5 =
+ ((((a_data_u8[6]
+ << BMI160_SHIFT_BIT_POSITION_BY_02_BITS)
+ & 0x1FC)
+ | (a_data_u8[7]
+ >> BMI160_SHIFT_BIT_POSITION_BY_06_BITS))
+ - 112);
+ /* a6 */
+ yas537_data.calib_yas537.a6 =
+ ((((a_data_u8[7]
+ << BMI160_SHIFT_BIT_POSITION_BY_01_BIT)
+ & 0x7E)
+ | (a_data_u8[8]
+ >> BMI160_SHIFT_BIT_POSITION_BY_07_BITS)) - 64);
+ /* a7 */
+ yas537_data.calib_yas537.a7 =
+ ((((a_data_u8[8]
+ << BMI160_SHIFT_BIT_POSITION_BY_01_BIT)
+ & 0xFE)
+ | (a_data_u8[9]
+ >> BMI160_SHIFT_BIT_POSITION_BY_07_BITS))
+ - 128);
+ /* a8 */
+ yas537_data.calib_yas537.a8 = ((a_data_u8[9] &
+ 0x7F) - 64);
+ /* a9 */
+ yas537_data.calib_yas537.a9 = ((((a_data_u8[10]
+ << BMI160_SHIFT_BIT_POSITION_BY_01_BIT) & 0x1FE)
+ | (a_data_u8[11]
+ >> BMI160_SHIFT_BIT_POSITION_BY_07_BITS))
+ - 112);
+ /* k */
+ yas537_data.calib_yas537.k = (
+ a_data_u8[11] & 0x7F);
+ } else {
+ return ERROR;
+ }
+/* write A/D converter*/
+com_rslt += bmi160_set_mag_write_data(
+YAS537_WRITE_A_D_CONVERTER);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+com_rslt += bmi160_set_mag_write_addr(YAS537_REG_ADCCALR);
+p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+/* write A/D converter second register*/
+com_rslt += bmi160_set_mag_write_data(
+YAS537_WRITE_A_D_CONVERTER2);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+com_rslt += bmi160_set_mag_write_addr(YAS537_REG_ADCCALR_ONE);
+p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+/* write temperature calibration register*/
+com_rslt += bmi160_set_mag_write_data(YAS537_WRITE_TEMP_CALIB);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+com_rslt += bmi160_set_mag_write_addr(YAS537_REG_TRMR);
+p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+/* write average filter register*/
+com_rslt += bmi160_set_mag_write_data(
+v_avrr_u8[yas537_data.average]);
+p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+com_rslt += bmi160_set_mag_write_addr(YAS537_REG_AVRR);
+p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+if (v_rcoil_u8) {
+ /* write average; filter register*/
+ com_rslt += bmi160_set_mag_write_data(
+ YAS537_WRITE_FILTER);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(YAS537_REG_CONFR);
+ p_bmi160->delay_msec(
+ BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+}
+
+return com_rslt;
+
+}
+/*!
+ * @brief This function used for YAS537 write data acquisition
+ * command register write
+ * @param v_command_reg_data_u8 : the value of data acquisition
+ * acquisition_command | operation
+ * ---------------------|-------------------------
+ * 0x17 | turn on the acquisition coil
+ * - | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Deferred acquisition mode
+ * 0x07 | turn on the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Normal acquisition mode
+ * 0x11 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Deferred acquisition mode
+ * 0x01 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Normal acquisition mode
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas537_acquisition_command_register(
+u8 v_command_reg_data_u8)
+{
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+
+ if (p_bmi160->mag_manual_enable != BMI160_MANUAL_ENABLE)
+ com_rslt = bmi160_set_mag_manual_enable(
+ BMI160_MANUAL_ENABLE);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+
+ com_rslt = bmi160_set_mag_write_data(v_command_reg_data_u8);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ /* YAMAHA YAS532-0x82*/
+ com_rslt += bmi160_set_mag_write_addr(
+ BMI160_REG_YAS537_CMDR);
+ /* set the mode to RECORD*/
+ yas537_data.measure_state = YAS537_MAG_STATE_RECORD_DATA;
+ p_bmi160->delay_msec(BMI160_YAS_ACQ_COMMAND_DELAY);
+ com_rslt += bmi160_set_mag_read_addr(
+ YAS537_REG_TEMPERATURE_0);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+
+ if (p_bmi160->mag_manual_enable == BMI160_MANUAL_ENABLE)
+ com_rslt += bmi160_set_mag_manual_enable(
+ BMI160_MANUAL_DISABLE);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+
+ return com_rslt;
+
+}
+/*!
+ * @brief This function used for read the
+ * YAMAHA YAS537 xy1y2 data
+ *
+ * @param xy1y2: The value of raw xy1y2 data
+ * @param xyz: The value of xyz data
+ *
+ *
+ * @return None
+ *
+ *
+ */
+static void xy1y2_to_xyz(u16 *xy1y2, s32 *xyz)
+{
+ xyz[0] = ((xy1y2[0] - 8192)
+ * 300);
+ xyz[1] = (((xy1y2[1] - xy1y2[2])
+ * 1732) / 10);
+ xyz[2] = (((-xy1y2[2] - xy1y2[2])
+ + 16384) * 300);
+}
+/*!
+ * @brief This function used for read the
+ * YAMAHA YAS537 xy1y2 data
+ *
+ * @param v_coil_stat_u8: The value of R coil status
+ * @param v_busy_u8: The value of busy status
+ * @param v_temperature_u16: The value of temperature
+ * @param xy1y2: The value of raw xy1y2 data
+ * @param v_ouflow_u8: The value of overflow
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yamaha_yas537_read_xy1y2_data(
+u8 *v_coil_stat_u8, u8 *v_busy_u8,
+u16 *v_temperature_u16, u16 *xy1y2, u8 *v_ouflow_u8)
+{
+ /* This variable used for provide the communication
+ results*/
+ BMI160_RETURN_FUNCTION_TYPE com_rslt = E_BMI160_COMM_RES;
+ /* Array holding the YAS532 calibration values */
+ u8 a_data_u8[BMI160_YAS_XY1Y2T_DATA_SIZE] = {
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE,
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE,
+ };
+ u8 i = BMI160_INIT_VALUE;
+ s32 a_h_s32[BMI160_YAS_H_DATA_SIZE] = {
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE};
+ s32 a_s_s32[BMI160_YAS_S_DATA_SIZE] = {
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE};
+ /* set command register*/
+ com_rslt = bmi160_bst_yas537_acquisition_command_register(
+ YAS537_SET_COMMAND_REGISTER);
+ /* read the yas537 sensor data of xy1y2*/
+ com_rslt +=
+ p_bmi160->BMI160_BUS_READ_FUNC(p_bmi160->dev_addr,
+ BMI160_USER_DATA_MAG_X_LSB__REG,
+ a_data_u8, BMI160_MAG_YAS_DATA_LENGTH);
+ /* read the busy flag*/
+ *v_busy_u8 = a_data_u8[2]
+ >> BMI160_SHIFT_BIT_POSITION_BY_07_BITS;
+ /* read the coil status*/
+ *v_coil_stat_u8 =
+ ((a_data_u8[2] >>
+ BMI160_SHIFT_BIT_POSITION_BY_06_BITS) & 0X01);
+ /* read temperature data*/
+ *v_temperature_u16 = (u16)((a_data_u8[0]
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) | a_data_u8[1]);
+ /* read x data*/
+ xy1y2[0] = (u16)(((a_data_u8[2] &
+ 0x3F)
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (a_data_u8[3]));
+ /* read y1 data*/
+ xy1y2[1] = (u16)((a_data_u8[4]
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS)
+ | a_data_u8[5]);
+ /* read y2 data*/
+ xy1y2[2] = (u16)((a_data_u8[6]
+ << BMI160_SHIFT_BIT_POSITION_BY_08_BITS)
+ | a_data_u8[7]);
+ for (i = 0; i < 3; i++)
+ yas537_data.last_raw[i] = xy1y2[i];
+ yas537_data.last_raw[i] = *v_temperature_u16;
+ if (yas537_data.calib_yas537.ver == 1) {
+ for (i = 0; i < 3; i++)
+ a_s_s32[i] = xy1y2[i] - 8192;
+ /* read hx*/
+ a_h_s32[0] = ((yas537_data.calib_yas537.k * (
+ (128 * a_s_s32[0]) +
+ (yas537_data.calib_yas537.a2 * a_s_s32[1]) +
+ (yas537_data.calib_yas537.a3 * a_s_s32[2])))
+ / (8192));
+ /* read hy1*/
+ a_h_s32[1] = ((yas537_data.calib_yas537.k * (
+ (yas537_data.calib_yas537.a4 * a_s_s32[0]) +
+ (yas537_data.calib_yas537.a5 * a_s_s32[1]) +
+ (yas537_data.calib_yas537.a6 * a_s_s32[2])))
+ / (8192));
+ /* read hy2*/
+ a_h_s32[2] = ((yas537_data.calib_yas537.k * (
+ (yas537_data.calib_yas537.a7 * a_s_s32[0]) +
+ (yas537_data.calib_yas537.a8 * a_s_s32[1]) +
+ (yas537_data.calib_yas537.a9 * a_s_s32[2])))
+ / (8192));
+
+ for (i = 0; i < 3; i++) {
+ if (a_h_s32[i] < -8192)
+ a_h_s32[i] = -8192;
+
+ if (8192 < a_h_s32[i])
+ a_h_s32[i] = 8192;
+
+ xy1y2[i] = a_h_s32[i] + 8192;
+
+ }
+ }
+ *v_ouflow_u8 = 0;
+ for (i = 0; i < 3; i++) {
+ if (YAS537_DATA_OVERFLOW <= xy1y2[i])
+ *v_ouflow_u8 |= (1 << (i * 2));
+ if (xy1y2[i] == YAS537_DATA_UNDERFLOW)
+ *v_ouflow_u8 |= (1 << (i * 2 + 1));
+ }
+
+ return com_rslt;
+
+}
+/*!
+ * @brief This function used for read the
+ * YAMAHA YAS537 xy1y2 data
+ *
+ * @param v_ouflow_u8: The value of overflow
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+static BMI160_RETURN_FUNCTION_TYPE invalid_magnetic_field(
+u16 *v_cur_u16, u16 *v_last_u16)
+{
+ s16 invalid_thresh[] = {1500, 1500, 1500};
+ u8 i = BMI160_INIT_VALUE;
+
+ for (i = 0; i < 3; i++)
+ if (invalid_thresh[i] < ABS(v_cur_u16[i] - v_last_u16[i]))
+ return 1;
+ return 0;
+}
+/*!
+ * @brief This function used for read the
+ * YAMAHA YAS537 xy1y2 data
+ *
+ * @param v_ouflow_u8: The value of overflow
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yamaha_yas537_measure_xyz_data(
+u8 *v_ouflow_u8, struct yas_vector *vector_xyz)
+{
+ s32 a_xyz_tmp_s32[BMI160_YAS_TEMP_DATA_SIZE] = {
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE};
+ u8 i = BMI160_INIT_VALUE;
+ s8 com_rslt = BMI160_INIT_VALUE;
+ u8 v_busy_u8 = BMI160_INIT_VALUE;
+ u8 v_rcoil_u8 = BMI160_INIT_VALUE;
+ u16 v_temperature_u16 = BMI160_INIT_VALUE;
+ u16 a_xy1y2_u16[BMI160_YAS_XY1Y2_DATA_SIZE] = {
+ BMI160_INIT_VALUE, BMI160_INIT_VALUE, BMI160_INIT_VALUE};
+ *v_ouflow_u8 = 0;
+ /* read the yas537 xy1y2 data*/
+ com_rslt = bmi160_bst_yamaha_yas537_read_xy1y2_data(
+ &v_rcoil_u8, &v_busy_u8,
+ &v_temperature_u16, a_xy1y2_u16, v_ouflow_u8);
+ /* linear calculation*/
+ xy1y2_to_xyz(a_xy1y2_u16, vector_xyz->yas537_vector_xyz);
+ if (yas537_data.transform != BMI160_NULL) {
+ for (i = 0; i < 3; i++) {
+ a_xyz_tmp_s32[i] = ((
+ yas537_data.transform[i + 3]
+ * vector_xyz->yas537_vector_xyz[0])
+ + (yas537_data.transform[
+ i * 3 + 1]
+ * vector_xyz->yas537_vector_xyz[1])
+ + (yas537_data.transform[
+ i * 3 + 2]
+ * vector_xyz->yas537_vector_xyz[2]));
+ }
+ yas537_set_vector(
+ vector_xyz->yas537_vector_xyz, a_xyz_tmp_s32);
+ }
+ for (i = 0; i < 3; i++) {
+ vector_xyz->yas537_vector_xyz[i] -=
+ vector_xyz->yas537_vector_xyz[i] % 10;
+ if (*v_ouflow_u8 & (1 <<
+ (i * 2)))
+ vector_xyz->yas537_vector_xyz[i] +=
+ 1; /* set overflow */
+ if (*v_ouflow_u8 & (1 << (i * 2 + 1)))
+ /* set underflow */
+ vector_xyz->yas537_vector_xyz[i] += 2;
+ }
+ if (v_busy_u8)
+ return ERROR;
+ switch (yas537_data.measure_state) {
+ case YAS537_MAG_STATE_INIT_COIL:
+ if (p_bmi160->mag_manual_enable != BMI160_MANUAL_ENABLE)
+ com_rslt = bmi160_set_mag_manual_enable(
+ BMI160_MANUAL_ENABLE);
+ com_rslt += bmi160_set_mag_write_data(YAS537_WRITE_CONFR);
+ p_bmi160->delay_msec(BMI160_GEN_READ_WRITE_DELAY);
+ com_rslt += bmi160_set_mag_write_addr(YAS537_REG_CONFR);
+ p_bmi160->delay_msec(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ yas537_data.measure_state = YAS537_MAG_STATE_RECORD_DATA;
+ if (p_bmi160->mag_manual_enable == BMI160_MANUAL_ENABLE)
+ com_rslt = bmi160_set_mag_manual_enable(
+ BMI160_MANUAL_DISABLE);
+ break;
+ case YAS537_MAG_STATE_RECORD_DATA:
+ if (v_rcoil_u8)
+ break;
+ yas537_set_vector(yas537_data.last_after_rcoil, a_xy1y2_u16);
+ yas537_data.measure_state = YAS537_MAG_STATE_NORMAL;
+ break;
+ case YAS537_MAG_STATE_NORMAL:
+ if (BMI160_INIT_VALUE < v_ouflow_u8
+ || invalid_magnetic_field(a_xy1y2_u16,
+ yas537_data.last_after_rcoil)) {
+ yas537_data.measure_state = YAS537_MAG_STATE_INIT_COIL;
+ for (i = 0; i < 3; i++) {
+ if (!*v_ouflow_u8)
+ vector_xyz->yas537_vector_xyz[i] += 3;
+ }
+ }
+ break;
+ }
+
+ return com_rslt;
+}
+/*!
+ * @brief This function used for reading
+ * bmi160_t structure
+ *
+ * @return the reference and values of bmi160_t
+ *
+ *
+*/
+struct bmi160_t *bmi160_get_ptr(void)
+{
+ return p_bmi160;
+}
diff --git a/drivers/input/sensors/bmi160/bmi160.h b/drivers/input/sensors/bmi160/bmi160.h
new file mode 100644
index 0000000..bc94a35
--- /dev/null
+++ b/drivers/input/sensors/bmi160/bmi160.h
@@ -0,0 +1,11814 @@
+/*
+****************************************************************************
+* Copyright (C) 2014 Bosch Sensortec GmbH
+*
+* bmi160.h
+* Date : 2015/04/02
+* @id 836294d
+* Revision : 2.0.9 $
+* @brief
+* The head file of BMI160API
+*
+****************************************************************************
+*
+* \section Disclaimer
+*
+* Common:
+* Bosch Sensortec products are developed for the consumer goods industry.
+* They may only be used within the parameters of the respective valid
+* product data sheet. Bosch Sensortec products are provided with the
+* express understanding that there is no warranty of fitness for a
+* particular purpose.They are not fit for use in life-sustaining,
+* safety or security sensitive systems or any system or device
+* that may lead to bodily harm or property damage if the system
+* or device malfunctions. In addition,Bosch Sensortec products are
+* not fit for use in products which interact with motor vehicle systems.
+* The resale and or use of products are at the purchasers own risk and
+* his own responsibility. The examination of fitness for the intended use
+* is the sole responsibility of the Purchaser.
+*
+* The purchaser shall indemnify Bosch Sensortec from all third party
+* claims, including any claims for incidental, or consequential damages,
+* arising from any product use not covered by the parameters of
+* the respective valid product data sheet or not approved by
+* Bosch Sensortec and reimburse Bosch Sensortec for all costs in
+* connection with such claims.
+*
+* The purchaser must monitor the market for the purchased products,
+* particularly with regard to product safety and inform Bosch Sensortec
+* without delay of all security relevant incidents.
+*
+* Engineering Samples are marked with an asterisk (*) or (e).
+* Samples may vary from the valid technical specifications of the product
+* series. They are therefore not intended or fit for resale to third
+* parties or for use in end products. Their sole purpose is internal
+* client testing. The testing of an engineering sample may in no way
+* replace the testing of a product series. Bosch Sensortec assumes
+* no liability for the use of engineering samples.
+* By accepting the engineering samples, the Purchaser agrees to indemnify
+* Bosch Sensortec from all claims arising from the use of engineering
+* samples.
+*
+* Special:
+* This software module (hereinafter called "Software") and any information
+* on application-sheets (hereinafter called "Information") is provided
+* free of charge for the sole purpose to support your application work.
+* The Software and Information is subject to the following
+* terms and conditions:
+*
+* The Software is specifically designed for the exclusive use for
+* Bosch Sensortec products by personnel who have special experience
+* and training. Do not use this Software if you do not have the
+* proper experience or training.
+*
+* This Software package is provided `` as is `` and without any expressed
+* or implied warranties,including without limitation, the implied warranties
+* of merchantability and fitness for a particular purpose.
+*
+* Bosch Sensortec and their representatives and agents deny any liability
+* for the functional impairment
+* of this Software in terms of fitness, performance and safety.
+* Bosch Sensortec and their representatives and agents shall not be liable
+* for any direct or indirect damages or injury, except as
+* otherwise stipulated in mandatory applicable law.
+*
+* The Information provided is believed to be accurate and reliable.
+* Bosch Sensortec assumes no responsibility for the consequences of use
+* of such Information nor for any infringement of patents or
+* other rights of third parties which may result from its use.
+* No license is granted by implication or otherwise under any patent or
+* patent rights of Bosch. Specifications mentioned in the Information are
+* subject to change without notice.
+**************************************************************************/
+/*! \file bmi160.h
+ \brief BMI160 Sensor Driver Support Header File */
+/* user defined code to be added here ... */
+#ifndef __BMI160_H__
+#define __BMI160_H__
+
+/*!
+* @brief The following definition uses for define the data types
+*
+* @note While porting the API please consider the following
+* @note Please check the version of C standard
+* @note Are you using Linux platform
+*/
+
+/*!
+* @brief For the Linux platform support
+* Please use the types.h for your data types definitions
+*/
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+
+#else /* ! __KERNEL__ */
+/**********************************************************
+* These definition uses for define the C
+* standard version data types
+***********************************************************/
+# if !defined(__STDC_VERSION__)
+
+/************************************************
+ * compiler is C11 C standard
+************************************************/
+#if (__STDC_VERSION__ == 201112L)
+
+/************************************************/
+#include <stdint.h>
+/************************************************/
+
+/*unsigned integer types*/
+#define u8 uint8_t
+#define u16 uint16_t
+#define u32 uint32_t
+#define u64 uint64_t
+
+/*signed integer types*/
+#define s8 int8_t
+#define s16 int16_t
+#define s32 int32_t
+#define s64 int64_t
+/************************************************
+ * compiler is C99 C standard
+************************************************/
+
+#elif (__STDC_VERSION__ == 199901L)
+
+/* stdint.h is a C99 supported c library.
+which is used to fixed the integer size*/
+/************************************************/
+#include <stdint.h>
+/************************************************/
+
+/*unsigned integer types*/
+#define u8 uint8_t
+#define u16 uint16_t
+#define u32 uint32_t
+#define u64 uint64_t
+
+/*signed integer types*/
+#define s8 int8_t
+#define s16 int16_t
+#define s32 int32_t
+#define s64 int64_t
+/************************************************
+ * compiler is C89 or other C standard
+************************************************/
+#else /* !defined(__STDC_VERSION__) */
+/* By default it is defined as 32 bit machine configuration*/
+/* define the definition based on your machine configuration*/
+/* define the data types based on your
+ machine/compiler/controller configuration*/
+#define MACHINE_32_BIT
+
+/* If your machine support 16 bit
+define the MACHINE_16_BIT*/
+#ifdef MACHINE_16_BIT
+#include <limits.h>
+/*signed integer types*/
+#define s8 signed char
+#define s16 signed short int
+#define s32 signed long int
+
+#if defined(LONG_MAX) && LONG_MAX == 0x7fffffffffffffffL
+#define s64 long int
+#define u64 unsigned long int
+#elif defined(LLONG_MAX) && (LLONG_MAX == 0x7fffffffffffffffLL)
+#define s64 long long int
+#define u64 unsigned long long int
+#else
+#warning Either the correct data type for signed 64 bit integer \
+could not be found, or 64 bit integers are not supported in your environment.
+#warning If 64 bit integers are supported on your platform, \
+please set s64 manually.
+#endif
+
+/*unsigned integer types*/
+#define u8 unsigned char
+#define u16 unsigned short int
+#define u32 unsigned long int
+
+/* If your machine support 32 bit
+define the MACHINE_32_BIT*/
+#elif defined MACHINE_32_BIT
+/*signed integer types*/
+#define s8 signed char
+#define s16 signed short int
+#define s32 signed int
+#define s64 signed long long int
+
+/*unsigned integer types*/
+#define u8 unsigned char
+#define u16 unsigned short int
+#define u32 unsigned int
+#define u64 unsigned long long int
+
+/* If your machine support 64 bit
+define the MACHINE_64_BIT*/
+#elif defined MACHINE_64_BIT
+/*signed integer types*/
+#define s8 signed char
+#define s16 signed short int
+#define s32 signed int
+#define s64 signed long int
+
+/*unsigned integer types*/
+#define u8 unsigned char
+#define u16 unsigned short int
+#define u32 unsigned int
+#define u64 unsigned long int
+
+#else
+#warning The data types defined above which not supported \
+define the data types manually
+#endif
+#endif
+
+/*** This else will execute for the compilers
+ * which are not supported the C standards
+ * Like C89/C99/C11***/
+#else
+/* By default it is defined as 32 bit machine configuration*/
+/* define the definition based on your machine configuration*/
+/* define the data types based on your
+ machine/compiler/controller configuration*/
+#define MACHINE_32_BIT
+
+/* If your machine support 16 bit
+define the MACHINE_16_BIT*/
+#ifdef MACHINE_16_BIT
+#include <limits.h>
+/*signed integer types*/
+#define s8 signed char
+#define s16 signed short int
+#define s32 signed long int
+
+#if defined(LONG_MAX) && LONG_MAX == 0x7fffffffffffffffL
+#define s64 long int
+#define u64 unsigned long int
+#elif defined(LLONG_MAX) && (LLONG_MAX == 0x7fffffffffffffffLL)
+#define s64 long long int
+#define u64 unsigned long long int
+#else
+#warning Either the correct data type for signed 64 bit integer \
+could not be found, or 64 bit integers are not supported in your environment.
+#warning If 64 bit integers are supported on your platform, \
+please set s64 manually.
+#endif
+
+/*unsigned integer types*/
+#define u8 unsigned char
+#define u16 unsigned short int
+#define u32 unsigned long int
+
+/* If your machine support 32 bit
+define the MACHINE_32_BIT*/
+#elif defined MACHINE_32_BIT
+/*signed integer types*/
+#define s8 signed char
+#define s16 signed short int
+#define s32 signed int
+#define s64 signed long long int
+
+/*unsigned integer types*/
+#define u8 unsigned char
+#define u16 unsigned short int
+#define u32 unsigned int
+#define u64 unsigned long long int
+
+/* If your machine support 64 bit
+define the MACHINE_64_BIT*/
+#elif defined MACHINE_64_BIT
+/*signed integer types*/
+#define s8 signed char
+#define s16 signed short int
+#define s32 signed int
+#define s64 signed long int
+
+/*unsigned integer types*/
+#define u8 unsigned char
+#define u16 unsigned short int
+#define u32 unsigned int
+#define u64 unsigned long int
+
+#else
+#warning The data types defined above which not supported \
+define the data types manually
+#endif
+#endif
+#endif
+/***************************************************************/
+/**\name BUS READ AND WRITE FUNCTION POINTERS */
+/***************************************************************/
+/*!
+ @brief Define the calling convention of YOUR bus communication routine.
+ @note This includes types of parameters. This example shows the
+ configuration for an SPI bus link.
+
+ If your communication function looks like this:
+
+ write_my_bus_xy(u8 device_addr, u8 register_addr,
+ u8 * data, u8 length);
+
+ The BMI160_WR_FUNC_PTR would equal:
+
+ BMI160_WR_FUNC_PTR s8 (* bus_write)(u8,
+ u8, u8 *, u8)
+
+ Parameters can be mixed as needed refer to the
+ @ref BMI160_BUS_WRITE_FUNC macro.
+
+
+*/
+#define BMI160_WR_FUNC_PTR s8 (*bus_write)(u8, u8,\
+u8 *, u8)
+/**< link macro between API function calls and bus write function
+ @note The bus write function can change since this is a
+ system dependant issue.
+
+ If the bus_write parameter calling order is like: reg_addr,
+ reg_data, wr_len it would be as it is here.
+
+ If the parameters are differently ordered or your communication
+ function like I2C need to know the device address,
+ you can change this macro accordingly.
+
+
+ BMI160_BUS_WRITE_FUNC(dev_addr, reg_addr, reg_data, wr_len)\
+ bus_write(dev_addr, reg_addr, reg_data, wr_len)
+
+ This macro lets all API functions call YOUR communication routine in a
+ way that equals your definition in the
+ @ref BMI160_WR_FUNC_PTR definition.
+
+*/
+#define BMI160_BUS_WRITE_FUNC(dev_addr, reg_addr, reg_data, wr_len)\
+ bus_write(dev_addr, reg_addr, reg_data, wr_len)
+
+/**< Define the calling convention of YOUR bus communication routine.
+ @note This includes types of parameters. This example shows the
+ configuration for an SPI bus link.
+
+ If your communication function looks like this:
+
+ read_my_bus_xy(u8 device_addr, u8 register_addr,
+ u8 * data, u8 length);
+
+ The BMI160_RD_FUNC_PTR would equal:
+
+ BMI160_RD_FUNC_PTR s8 (* bus_read)(u8,
+ u8, u8 *, u8)
+
+ Parameters can be mixed as needed refer to the
+ refer BMI160_BUS_READ_FUNC macro.
+
+*/
+#define BMI160_SPI_RD_MASK (0x80) /* for spi read transactions on SPI the
+ MSB has to be set */
+#define BMI160_RD_FUNC_PTR s8 (*bus_read)(u8,\
+ u8, u8 *, u8)
+
+#define BMI160_BRD_FUNC_PTR s8 \
+(*burst_read)(u8, u8, u8 *, u32)
+
+/**< link macro between API function calls and bus read function
+ @note The bus write function can change since this is a
+ system dependant issue.
+
+ If the bus_read parameter calling order is like: reg_addr,
+ reg_data, wr_len it would be as it is here.
+
+ If the parameters are differently ordered or your communication
+ function like I2C need to know the device address,
+ you can change this macro accordingly.
+
+
+ BMI160_BUS_READ_FUNC(dev_addr, reg_addr, reg_data, wr_len)\
+ bus_read(dev_addr, reg_addr, reg_data, wr_len)
+
+ This macro lets all API functions call YOUR communication routine in a
+ way that equals your definition in the
+ refer BMI160_WR_FUNC_PTR definition.
+
+ @note: this macro also includes the "MSB='1'
+ for reading BMI160 addresses.
+
+*/
+#define BMI160_BUS_READ_FUNC(dev_addr, reg_addr, reg_data, r_len)\
+ bus_read(dev_addr, reg_addr, reg_data, r_len)
+
+#define BMI160_BURST_READ_FUNC(device_addr, \
+register_addr, register_data, rd_len)\
+burst_read(device_addr, register_addr, register_data, rd_len)
+
+
+#define BMI160_MDELAY_DATA_TYPE u32
+
+/***************************************************************/
+/**\name BUS READ AND WRITE FUNCTION POINTERS */
+/***************************************************************/
+#define BMI160_I2C_ADDR1 0x68 /**< I2C Address needs to be changed */
+#define BMI160_I2C_ADDR2 0x69 /**< I2C Address needs to be changed */
+#define BMI160_AUX_BMM150_I2C_ADDRESS (0x10)
+#define BMI160_AUX_YAS532_I2C_ADDRESS (0x2E)
+/**< I2C address of YAS532*/
+#define BMI160_AKM09911_I2C_ADDRESS 0x0C/**< I2C address of AKM09911*/
+/**< I2C address of AKM09911*/
+#define BMI160_AUX_AKM09911_I2C_ADDR_2 (0x0D)
+/**< I2C address of AKM09911*/
+#define BMI160_AUX_AKM09912_I2C_ADDR_1 (0x0C)
+/**< I2C address of AKM09912*/
+#define BMI160_AUX_AKM09912_I2C_ADDR_2 (0x0D)
+/**< I2C address of AKM09912*/
+#define BMI160_AUX_AKM09912_I2C_ADDR_3 (0x0E)
+/**< I2C address of AKM09912*/
+#define BMI160_AKM09912_I2C_ADDRESS 0x0F/**< I2C address of akm09912*/
+
+#define BMI160_YAS532_I2C_ADDRESS 0x2E/**< I2C address of YAS532*/
+/*******************************************/
+/**\name CONSTANTS */
+/******************************************/
+#define BMI160_INIT_VALUE (0)
+#define BMI160_GEN_READ_WRITE_DATA_LENGTH (1)
+#define BMI160_MAXIMUM_TIMEOUT (10)
+/* output data rate condition check*/
+#define BMI160_OUTPUT_DATA_RATE0 (0)
+#define BMI160_OUTPUT_DATA_RATE1 (1)
+#define BMI160_OUTPUT_DATA_RATE2 (2)
+#define BMI160_OUTPUT_DATA_RATE3 (3)
+#define BMI160_OUTPUT_DATA_RATE4 (4)
+#define BMI160_OUTPUT_DATA_RATE5 (5)
+#define BMI160_OUTPUT_DATA_RATE6 (14)
+#define BMI160_OUTPUT_DATA_RATE7 (15)
+/* accel range check*/
+#define BMI160_ACCEL_RANGE0 (3)
+#define BMI160_ACCEL_RANGE1 (5)
+#define BMI160_ACCEL_RANGE3 (8)
+#define BMI160_ACCEL_RANGE4 (12)
+/* check the status of registers*/
+#define BMI160_FOC_STAT_HIGH (1)
+#define BMI160_SIG_MOTION_STAT_HIGH (1)
+#define BMI160_STEP_DET_STAT_HIGH (1)
+
+/*condition check for reading and writing data*/
+#define BMI160_MAX_VALUE_SIGNIFICANT_MOTION (1)
+#define BMI160_MAX_VALUE_FIFO_FILTER (1)
+#define BMI160_MAX_VALUE_FIFO_TIME (1)
+#define BMI160_MAX_VALUE_FIFO_INTR (1)
+#define BMI160_MAX_VALUE_FIFO_HEADER (1)
+#define BMI160_MAX_VALUE_FIFO_MAG (1)
+#define BMI160_MAX_VALUE_FIFO_ACCEL (1)
+#define BMI160_MAX_VALUE_FIFO_GYRO (1)
+#define BMI160_MAX_VALUE_SOURCE_INTR (1)
+#define BMI160_MAX_VALUE_LOW_G_MODE (1)
+#define BMI160_MAX_VALUE_NO_MOTION (1)
+#define BMI160_MAX_VALUE_TAP_SHOCK (1)
+#define BMI160_MAX_VALUE_TAP_QUIET (1)
+#define BMI160_MAX_VALUE_ORIENT_UD (1)
+#define BMI160_MAX_VALUE_ORIENT_AXES (1)
+#define BMI160_MAX_VALUE_NVM_PROG (1)
+#define BMI160_MAX_VALUE_SPI3 (1)
+#define BMI160_MAX_VALUE_PAGE (1)
+#define BMI160_MAX_VALUE_I2C_WDT (1)
+#define BMI160_MAX_VALUE_SLEEP_STATE (1)
+#define BMI160_MAX_VALUE_WAKEUP_INTR (1)
+#define BMI160_MAX_VALUE_SELFTEST_SIGN (1)
+#define BMI160_MAX_VALUE_SELFTEST_AMP (1)
+#define BMI160_MAX_VALUE_SELFTEST_START (1)
+#define BMI160_MAX_GYRO_WAKEUP_TRIGGER (3)
+#define BMI160_MAX_ACCEL_SELFTEST_AXIS (3)
+#define BMI160_MAX_GYRO_STEP_COUNTER (1)
+#define BMI160_MAX_GYRO_BW (3)
+#define BMI160_MAX_ACCEL_BW (7)
+#define BMI160_MAX_ORIENT_MODE (3)
+#define BMI160_MAX_ORIENT_BLOCKING (3)
+#define BMI160_MAX_FLAT_HOLD (3)
+#define BMI160_MAX_ACCEL_FOC (3)
+#define BMI160_MAX_IF_MODE (3)
+#define BMI160_MAX_TARGET_PAGE (3)
+#define BMI160_MAX_GYRO_RANGE (4)
+#define BMI160_MAX_GYRO_SLEEP_TIGGER (7)
+#define BMI160_MAX_TAP_TURN (7)
+#define BMI160_MAX_UNDER_SAMPLING (1)
+#define BMI160_MAX_UNDER_SIG_MOTION (3)
+#define BMI160_MAX_ACCEL_OUTPUT_DATA_RATE (12)
+#define BMI160_MAX_LATCH_INTR (15)
+#define BMI160_MAX_FLAT_HYST (15)
+#define BMI160_MAX_ORIENT_THETA (63)
+#define BMI160_MAX_FLAT_THETA (63)
+
+/* FIFO index definitions*/
+#define BMI160_FIFO_X_LSB_DATA (0)
+#define BMI160_FIFO_X_MSB_DATA (1)
+#define BMI160_FIFO_Y_LSB_DATA (2)
+#define BMI160_FIFO_Y_MSB_DATA (3)
+#define BMI160_FIFO_Z_LSB_DATA (4)
+#define BMI160_FIFO_Z_MSB_DATA (5)
+#define BMI160_FIFO_R_LSB_DATA (6)
+#define BMI160_FIFO_R_MSB_DATA (7)
+/* FIFO gyro definition*/
+#define BMI160_GA_FIFO_G_X_LSB (0)
+#define BMI160_GA_FIFO_G_X_MSB (1)
+#define BMI160_GA_FIFO_G_Y_LSB (2)
+#define BMI160_GA_FIFO_G_Y_MSB (3)
+#define BMI160_GA_FIFO_G_Z_LSB (4)
+#define BMI160_GA_FIFO_G_Z_MSB (5)
+#define BMI160_GA_FIFO_A_X_LSB (6)
+#define BMI160_GA_FIFO_A_X_MSB (7)
+#define BMI160_GA_FIFO_A_Y_LSB (8)
+#define BMI160_GA_FIFO_A_Y_MSB (9)
+#define BMI160_GA_FIFO_A_Z_LSB (10)
+#define BMI160_GA_FIFO_A_Z_MSB (11)
+/* FIFO mag/gyro/accel definition*/
+#define BMI160_MGA_FIFO_M_X_LSB (0)
+#define BMI160_MGA_FIFO_M_X_MSB (1)
+#define BMI160_MGA_FIFO_M_Y_LSB (2)
+#define BMI160_MGA_FIFO_M_Y_MSB (3)
+#define BMI160_MGA_FIFO_M_Z_LSB (4)
+#define BMI160_MGA_FIFO_M_Z_MSB (5)
+#define BMI160_MGA_FIFO_M_R_LSB (6)
+#define BMI160_MGA_FIFO_M_R_MSB (7)
+#define BMI160_MGA_FIFO_G_X_LSB (8)
+#define BMI160_MGA_FIFO_G_X_MSB (9)
+#define BMI160_MGA_FIFO_G_Y_LSB (10)
+#define BMI160_MGA_FIFO_G_Y_MSB (11)
+#define BMI160_MGA_FIFO_G_Z_LSB (12)
+#define BMI160_MGA_FIFO_G_Z_MSB (13)
+#define BMI160_MGA_FIFO_A_X_LSB (14)
+#define BMI160_MGA_FIFO_A_X_MSB (15)
+#define BMI160_MGA_FIFO_A_Y_LSB (16)
+#define BMI160_MGA_FIFO_A_Y_MSB (17)
+#define BMI160_MGA_FIFO_A_Z_LSB (18)
+#define BMI160_MGA_FIFO_A_Z_MSB (19)
+/* FIFO mag definition*/
+#define BMI160_MA_FIFO_M_X_LSB (0)
+#define BMI160_MA_FIFO_M_X_MSB (1)
+#define BMI160_MA_FIFO_M_Y_LSB (2)
+#define BMI160_MA_FIFO_M_Y_MSB (3)
+#define BMI160_MA_FIFO_M_Z_LSB (4)
+#define BMI160_MA_FIFO_M_Z_MSB (5)
+#define BMI160_MA_FIFO_M_R_LSB (6)
+#define BMI160_MA_FIFO_M_R_MSB (7)
+#define BMI160_MA_FIFO_A_X_LSB (8)
+#define BMI160_MA_FIFO_A_X_MSB (9)
+#define BMI160_MA_FIFO_A_Y_LSB (10)
+#define BMI160_MA_FIFO_A_Y_MSB (11)
+#define BMI160_MA_FIFO_A_Z_LSB (12)
+#define BMI160_MA_FIFO_A_Z_MSB (13)
+/* FIFO mag/gyro definition*/
+#define BMI160_MG_FIFO_M_X_LSB (0)
+#define BMI160_MG_FIFO_M_X_MSB (1)
+#define BMI160_MG_FIFO_M_Y_LSB (2)
+#define BMI160_MG_FIFO_M_Y_MSB (3)
+#define BMI160_MG_FIFO_M_Z_LSB (4)
+#define BMI160_MG_FIFO_M_Z_MSB (5)
+#define BMI160_MG_FIFO_M_R_LSB (6)
+#define BMI160_MG_FIFO_M_R_MSB (7)
+#define BMI160_MG_FIFO_G_X_LSB (8)
+#define BMI160_MG_FIFO_G_X_MSB (9)
+#define BMI160_MG_FIFO_G_Y_LSB (10)
+#define BMI160_MG_FIFO_G_Y_MSB (11)
+#define BMI160_MG_FIFO_G_Z_LSB (12)
+#define BMI160_MG_FIFO_G_Z_MSB (13)
+/* FIFO length definitions*/
+#define BMI160_FIFO_SENSOR_TIME_LSB (0)
+#define BMI160_FIFO_SENSOR_TIME_XLSB (1)
+#define BMI160_FIFO_SENSOR_TIME_MSB (2)
+#define BMI160_FIFO_SENSOR_TIME_LENGTH (3)
+#define BMI160_FIFO_A_LENGTH (6)
+#define BMI160_FIFO_G_LENGTH (6)
+#define BMI160_FIFO_M_LENGTH (8)
+#define BMI160_FIFO_AG_LENGTH (12)
+#define BMI160_FIFO_AMG_LENGTH (20)
+#define BMI160_FIFO_MA_OR_MG_LENGTH (14)
+
+/* bus read and write length for mag, accel and gyro*/
+#define BMI160_MAG_X_DATA_LENGTH (2)
+#define BMI160_MAG_Y_DATA_LENGTH (2)
+#define BMI160_MAG_Z_DATA_LENGTH (2)
+#define BMI160_MAG_R_DATA_LENGTH (2)
+#define BMI160_MAG_XYZ_DATA_LENGTH (6)
+#define BMI160_MAG_XYZR_DATA_LENGTH (8)
+#define BMI160_MAG_YAS_DATA_LENGTH (8)
+#define BMI160_GYRO_DATA_LENGTH (2)
+#define BMI160_GYRO_XYZ_DATA_LENGTH (6)
+#define BMI160_ACCEL_DATA_LENGTH (2)
+#define BMI160_ACCEL_XYZ_DATA_LENGTH (6)
+#define BMI160_TEMP_DATA_LENGTH (2)
+#define BMI160_FIFO_DATA_LENGTH (2)
+#define BMI160_STEP_COUNTER_LENGTH (2)
+#define BMI160_SENSOR_TIME_LENGTH (3)
+
+/* Delay definitions*/
+#define BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY (5)
+#define BMI160_BMM150_WAKEUP_DELAY1 (2)
+#define BMI160_BMM150_WAKEUP_DELAY2 (3)
+#define BMI160_BMM150_WAKEUP_DELAY3 (1)
+#define BMI160_YAS532_OFFSET_DELAY (2)
+#define BMI160_GEN_READ_WRITE_DELAY (1)
+#define BMI160_YAS532_MEASUREMENT_DELAY (25)
+#define BMI160_YAS_ACQ_COMMAND_DELAY (50)
+#define BMI160_YAS532_SET_INITIAL_VALUE_DELAY (200)
+#define BMI160_AKM_INIT_DELAY (60)
+/****************************************************/
+/**\name ARRAY SIZE DEFINITIONS */
+/***************************************************/
+#define BMI160_ACCEL_X_DATA_SIZE (2)
+#define BMI160_ACCEL_Y_DATA_SIZE (2)
+#define BMI160_ACCEL_Z_DATA_SIZE (2)
+#define BMI160_ACCEL_XYZ_DATA_SIZE (6)
+
+#define BMI160_GYRO_X_DATA_SIZE (2)
+#define BMI160_GYRO_Y_DATA_SIZE (2)
+#define BMI160_GYRO_Z_DATA_SIZE (2)
+#define BMI160_GYRO_XYZ_DATA_SIZE (6)
+
+#define BMI160_MAG_X_DATA_SIZE (2)
+#define BMI160_MAG_Y_DATA_SIZE (2)
+#define BMI160_MAG_Z_DATA_SIZE (2)
+#define BMI160_MAG_R_DATA_SIZE (2)
+#define BMI160_MAG_XYZ_DATA_SIZE (6)
+#define BMI160_MAG_XYZR_DATA_SIZE (8)
+#define BMI160_MAG_TRIM_DATA_SIZE (16)
+
+
+#define BMI160_TEMP_DATA_SIZE (2)
+#define BMI160_FIFO_DATA_SIZE (2)
+#define BMI160_STEP_COUNT_DATA_SIZE (2)
+
+#define BMI160_SENSOR_TIME_DATA_SIZE (3)
+#define BMI160_AKM_SENSITIVITY_DATA_SIZE (3)
+#define BMI160_HARD_OFFSET_DATA_SIZE (3)
+#define BMI160_YAS_XY1Y2_DATA_SIZE (3)
+#define BMI160_YAS_FLAG_DATA_SIZE (3)
+#define BMI160_YAS_TEMP_DATA_SIZE (3)
+#define BMI160_YAS_H_DATA_SIZE (3)
+#define BMI160_YAS_S_DATA_SIZE (3)
+#define BMI160_YAS_CORRECT_DATA_SIZE (5)
+#define BMI160_YAS_XY1Y2T_DATA_SIZE (8)
+#define BMI160_YAS537_CALIB_DATA_SIZE (17)
+#define BMI160_YAS532_CALIB_DATA_SIZE (14)
+/****************************************************/
+/**\name ARRAY PARAMETER DEFINITIONS */
+/***************************************************/
+#define BMI160_SENSOR_TIME_MSB_BYTE (2)
+#define BMI160_SENSOR_TIME_XLSB_BYTE (1)
+#define BMI160_SENSOR_TIME_LSB_BYTE (0)
+
+#define BMI160_MAG_X_LSB_BYTE (0)
+#define BMI160_MAG_X_MSB_BYTE (1)
+#define BMI160_MAG_Y_LSB_BYTE (0)
+#define BMI160_MAG_Y_MSB_BYTE (1)
+#define BMI160_MAG_Z_LSB_BYTE (0)
+#define BMI160_MAG_Z_MSB_BYTE (1)
+#define BMI160_MAG_R_LSB_BYTE (0)
+#define BMI160_MAG_R_MSB_BYTE (1)
+#define BMI160_DATA_FRAME_MAG_X_LSB_BYTE (0)
+#define BMI160_DATA_FRAME_MAG_X_MSB_BYTE (1)
+#define BMI160_DATA_FRAME_MAG_Y_LSB_BYTE (2)
+#define BMI160_DATA_FRAME_MAG_Y_MSB_BYTE (3)
+#define BMI160_DATA_FRAME_MAG_Z_LSB_BYTE (4)
+#define BMI160_DATA_FRAME_MAG_Z_MSB_BYTE (5)
+#define BMI160_DATA_FRAME_MAG_R_LSB_BYTE (6)
+#define BMI160_DATA_FRAME_MAG_R_MSB_BYTE (7)
+
+#define BMI160_GYRO_X_LSB_BYTE (0)
+#define BMI160_GYRO_X_MSB_BYTE (1)
+#define BMI160_GYRO_Y_LSB_BYTE (0)
+#define BMI160_GYRO_Y_MSB_BYTE (1)
+#define BMI160_GYRO_Z_LSB_BYTE (0)
+#define BMI160_GYRO_Z_MSB_BYTE (1)
+#define BMI160_DATA_FRAME_GYRO_X_LSB_BYTE (0)
+#define BMI160_DATA_FRAME_GYRO_X_MSB_BYTE (1)
+#define BMI160_DATA_FRAME_GYRO_Y_LSB_BYTE (2)
+#define BMI160_DATA_FRAME_GYRO_Y_MSB_BYTE (3)
+#define BMI160_DATA_FRAME_GYRO_Z_LSB_BYTE (4)
+#define BMI160_DATA_FRAME_GYRO_Z_MSB_BYTE (5)
+
+#define BMI160_ACCEL_X_LSB_BYTE (0)
+#define BMI160_ACCEL_X_MSB_BYTE (1)
+#define BMI160_ACCEL_Y_LSB_BYTE (0)
+#define BMI160_ACCEL_Y_MSB_BYTE (1)
+#define BMI160_ACCEL_Z_LSB_BYTE (0)
+#define BMI160_ACCEL_Z_MSB_BYTE (1)
+#define BMI160_DATA_FRAME_ACCEL_X_LSB_BYTE (0)
+#define BMI160_DATA_FRAME_ACCEL_X_MSB_BYTE (1)
+#define BMI160_DATA_FRAME_ACCEL_Y_LSB_BYTE (2)
+#define BMI160_DATA_FRAME_ACCEL_Y_MSB_BYTE (3)
+#define BMI160_DATA_FRAME_ACCEL_Z_LSB_BYTE (4)
+#define BMI160_DATA_FRAME_ACCEL_Z_MSB_BYTE (5)
+
+#define BMI160_TEMP_LSB_BYTE (0)
+#define BMI160_TEMP_MSB_BYTE (1)
+
+#define BMI160_FIFO_LENGTH_LSB_BYTE (0)
+#define BMI160_FIFO_LENGTH_MSB_BYTE (1)
+
+#define BMI160_STEP_COUNT_LSB_BYTE (0)
+#define BMI160_STEP_COUNT_MSB_BYTE (1)
+/****************************************************/
+/**\name ERROR CODES */
+/***************************************************/
+
+#define E_BMI160_NULL_PTR ((s8)-127)
+#define E_BMI160_COMM_RES ((s8)-1)
+#define E_BMI160_OUT_OF_RANGE ((s8)-2)
+#define E_BMI160_BUSY ((s8)-3)
+#define SUCCESS ((u8)0)
+#define ERROR ((s8)-1)
+
+/* Constants */
+#define BMI160_NULL (0)
+#define BMI160_DELAY_SETTLING_TIME (5)
+/*This refers BMI160 return type as s8 */
+#define BMI160_RETURN_FUNCTION_TYPE s8
+/****************************************************/
+/**\name REGISTER DEFINITIONS */
+/***************************************************/
+/*******************/
+/**\name CHIP ID */
+/*******************/
+#define BMI160_USER_CHIP_ID_ADDR (0x00)
+/*******************/
+/**\name ERROR STATUS */
+/*******************/
+#define BMI160_USER_ERROR_ADDR (0X02)
+/*******************/
+/**\name POWER MODE STATUS */
+/*******************/
+#define BMI160_USER_PMU_STAT_ADDR (0X03)
+/*******************/
+/**\name MAG DATA REGISTERS */
+/*******************/
+#define BMI160_USER_DATA_0_ADDR (0X04)
+#define BMI160_USER_DATA_1_ADDR (0X05)
+#define BMI160_USER_DATA_2_ADDR (0X06)
+#define BMI160_USER_DATA_3_ADDR (0X07)
+#define BMI160_USER_DATA_4_ADDR (0X08)
+#define BMI160_USER_DATA_5_ADDR (0X09)
+#define BMI160_USER_DATA_6_ADDR (0X0A)
+#define BMI160_USER_DATA_7_ADDR (0X0B)
+/*******************/
+/**\name GYRO DATA REGISTERS */
+/*******************/
+#define BMI160_USER_DATA_8_ADDR (0X0C)
+#define BMI160_USER_DATA_9_ADDR (0X0D)
+#define BMI160_USER_DATA_10_ADDR (0X0E)
+#define BMI160_USER_DATA_11_ADDR (0X0F)
+#define BMI160_USER_DATA_12_ADDR (0X10)
+#define BMI160_USER_DATA_13_ADDR (0X11)
+#define BMI160_USER_DATA_14_ADDR (0X12)
+#define BMI160_USER_DATA_15_ADDR (0X13)
+/*******************/
+/**\name ACCEL DATA REGISTERS */
+/*******************/
+#define BMI160_USER_DATA_16_ADDR (0X14)
+#define BMI160_USER_DATA_17_ADDR (0X15)
+#define BMI160_USER_DATA_18_ADDR (0X16)
+#define BMI160_USER_DATA_19_ADDR (0X17)
+/*******************/
+/**\name SENSOR TIME REGISTERS */
+/*******************/
+#define BMI160_USER_SENSORTIME_0_ADDR (0X18)
+#define BMI160_USER_SENSORTIME_1_ADDR (0X19)
+#define BMI160_USER_SENSORTIME_2_ADDR (0X1A)
+/*******************/
+/**\name STATUS REGISTER FOR SENSOR STATUS FLAG */
+/*******************/
+#define BMI160_USER_STAT_ADDR (0X1B)
+/*******************/
+/**\name INTERRUPY STATUS REGISTERS */
+/*******************/
+#define BMI160_USER_INTR_STAT_0_ADDR (0X1C)
+#define BMI160_USER_INTR_STAT_1_ADDR (0X1D)
+#define BMI160_USER_INTR_STAT_2_ADDR (0X1E)
+#define BMI160_USER_INTR_STAT_3_ADDR (0X1F)
+/*******************/
+/**\name TEMPERATURE REGISTERS */
+/*******************/
+#define BMI160_USER_TEMPERATURE_0_ADDR (0X20)
+#define BMI160_USER_TEMPERATURE_1_ADDR (0X21)
+/*******************/
+/**\name FIFO REGISTERS */
+/*******************/
+#define BMI160_USER_FIFO_LENGTH_0_ADDR (0X22)
+#define BMI160_USER_FIFO_LENGTH_1_ADDR (0X23)
+#define BMI160_USER_FIFO_DATA_ADDR (0X24)
+/***************************************************/
+/**\name ACCEL CONFIG REGISTERS FOR ODR, BANDWIDTH AND UNDERSAMPLING*/
+/******************************************************/
+#define BMI160_USER_ACCEL_CONFIG_ADDR (0X40)
+/*******************/
+/**\name ACCEL RANGE */
+/*******************/
+#define BMI160_USER_ACCEL_RANGE_ADDR (0X41)
+/***************************************************/
+/**\name GYRO CONFIG REGISTERS FOR ODR AND BANDWIDTH */
+/******************************************************/
+#define BMI160_USER_GYRO_CONFIG_ADDR (0X42)
+/*******************/
+/**\name GYRO RANGE */
+/*******************/
+#define BMI160_USER_GYRO_RANGE_ADDR (0X43)
+/***************************************************/
+/**\name MAG CONFIG REGISTERS FOR ODR*/
+/******************************************************/
+#define BMI160_USER_MAG_CONFIG_ADDR (0X44)
+/***************************************************/
+/**\name REGISTER FOR GYRO AND ACCEL DOWNSAMPLING RATES FOR FIFO*/
+/******************************************************/
+#define BMI160_USER_FIFO_DOWN_ADDR (0X45)
+/***************************************************/
+/**\name FIFO CONFIG REGISTERS*/
+/******************************************************/
+#define BMI160_USER_FIFO_CONFIG_0_ADDR (0X46)
+#define BMI160_USER_FIFO_CONFIG_1_ADDR (0X47)
+/***************************************************/
+/**\name MAG INTERFACE REGISTERS*/
+/******************************************************/
+#define BMI160_USER_MAG_IF_0_ADDR (0X4B)
+#define BMI160_USER_MAG_IF_1_ADDR (0X4C)
+#define BMI160_USER_MAG_IF_2_ADDR (0X4D)
+#define BMI160_USER_MAG_IF_3_ADDR (0X4E)
+#define BMI160_USER_MAG_IF_4_ADDR (0X4F)
+/***************************************************/
+/**\name INTERRUPT ENABLE REGISTERS*/
+/******************************************************/
+#define BMI160_USER_INTR_ENABLE_0_ADDR (0X50)
+#define BMI160_USER_INTR_ENABLE_1_ADDR (0X51)
+#define BMI160_USER_INTR_ENABLE_2_ADDR (0X52)
+#define BMI160_USER_INTR_OUT_CTRL_ADDR (0X53)
+/***************************************************/
+/**\name LATCH DURATION REGISTERS*/
+/******************************************************/
+#define BMI160_USER_INTR_LATCH_ADDR (0X54)
+/***************************************************/
+/**\name MAP INTERRUPT 1 and 2 REGISTERS*/
+/******************************************************/
+#define BMI160_USER_INTR_MAP_0_ADDR (0X55)
+#define BMI160_USER_INTR_MAP_1_ADDR (0X56)
+#define BMI160_USER_INTR_MAP_2_ADDR (0X57)
+/***************************************************/
+/**\name DATA SOURCE REGISTERS*/
+/******************************************************/
+#define BMI160_USER_INTR_DATA_0_ADDR (0X58)
+#define BMI160_USER_INTR_DATA_1_ADDR (0X59)
+/***************************************************/
+/**\name
+INTERRUPT THRESHOLD, HYSTERESIS, DURATION, MODE CONFIGURATION REGISTERS*/
+/******************************************************/
+#define BMI160_USER_INTR_LOWHIGH_0_ADDR (0X5A)
+#define BMI160_USER_INTR_LOWHIGH_1_ADDR (0X5B)
+#define BMI160_USER_INTR_LOWHIGH_2_ADDR (0X5C)
+#define BMI160_USER_INTR_LOWHIGH_3_ADDR (0X5D)
+#define BMI160_USER_INTR_LOWHIGH_4_ADDR (0X5E)
+#define BMI160_USER_INTR_MOTION_0_ADDR (0X5F)
+#define BMI160_USER_INTR_MOTION_1_ADDR (0X60)
+#define BMI160_USER_INTR_MOTION_2_ADDR (0X61)
+#define BMI160_USER_INTR_MOTION_3_ADDR (0X62)
+#define BMI160_USER_INTR_TAP_0_ADDR (0X63)
+#define BMI160_USER_INTR_TAP_1_ADDR (0X64)
+#define BMI160_USER_INTR_ORIENT_0_ADDR (0X65)
+#define BMI160_USER_INTR_ORIENT_1_ADDR (0X66)
+#define BMI160_USER_INTR_FLAT_0_ADDR (0X67)
+#define BMI160_USER_INTR_FLAT_1_ADDR (0X68)
+/***************************************************/
+/**\name FAST OFFSET CONFIGURATION REGISTER*/
+/******************************************************/
+#define BMI160_USER_FOC_CONFIG_ADDR (0X69)
+/***************************************************/
+/**\name MISCELLANEOUS CONFIGURATION REGISTER*/
+/******************************************************/
+#define BMI160_USER_CONFIG_ADDR (0X6A)
+/***************************************************/
+/**\name SERIAL INTERFACE SETTINGS REGISTER*/
+/******************************************************/
+#define BMI160_USER_IF_CONFIG_ADDR (0X6B)
+/***************************************************/
+/**\name GYRO POWER MODE TRIGGER REGISTER */
+/******************************************************/
+#define BMI160_USER_PMU_TRIGGER_ADDR (0X6C)
+/***************************************************/
+/**\name SELF_TEST REGISTER*/
+/******************************************************/
+#define BMI160_USER_SELF_TEST_ADDR (0X6D)
+/***************************************************/
+/**\name SPI,I2C SELECTION REGISTER*/
+/******************************************************/
+#define BMI160_USER_NV_CONFIG_ADDR (0x70)
+/***************************************************/
+/**\name ACCEL AND GYRO OFFSET REGISTERS*/
+/******************************************************/
+#define BMI160_USER_OFFSET_0_ADDR (0X71)
+#define BMI160_USER_OFFSET_1_ADDR (0X72)
+#define BMI160_USER_OFFSET_2_ADDR (0X73)
+#define BMI160_USER_OFFSET_3_ADDR (0X74)
+#define BMI160_USER_OFFSET_4_ADDR (0X75)
+#define BMI160_USER_OFFSET_5_ADDR (0X76)
+#define BMI160_USER_OFFSET_6_ADDR (0X77)
+/***************************************************/
+/**\name STEP COUNTER INTERRUPT REGISTERS*/
+/******************************************************/
+#define BMI160_USER_STEP_COUNT_0_ADDR (0X78)
+#define BMI160_USER_STEP_COUNT_1_ADDR (0X79)
+/***************************************************/
+/**\name STEP COUNTER CONFIGURATION REGISTERS*/
+/******************************************************/
+#define BMI160_USER_STEP_CONFIG_0_ADDR (0X7A)
+#define BMI160_USER_STEP_CONFIG_1_ADDR (0X7B)
+/***************************************************/
+/**\name COMMAND REGISTER*/
+/******************************************************/
+#define BMI160_CMD_COMMANDS_ADDR (0X7E)
+/***************************************************/
+/**\name PAGE REGISTERS*/
+/******************************************************/
+#define BMI160_CMD_EXT_MODE_ADDR (0X7F)
+#define BMI160_COM_C_TRIM_FIVE_ADDR (0X05)
+
+/****************************************************/
+/**\name SHIFT VALUE DEFINITION */
+/***************************************************/
+#define BMI160_SHIFT_BIT_POSITION_BY_01_BIT (1)
+#define BMI160_SHIFT_BIT_POSITION_BY_02_BITS (2)
+#define BMI160_SHIFT_BIT_POSITION_BY_03_BITS (3)
+#define BMI160_SHIFT_BIT_POSITION_BY_04_BITS (4)
+#define BMI160_SHIFT_BIT_POSITION_BY_05_BITS (5)
+#define BMI160_SHIFT_BIT_POSITION_BY_06_BITS (6)
+#define BMI160_SHIFT_BIT_POSITION_BY_07_BITS (7)
+#define BMI160_SHIFT_BIT_POSITION_BY_08_BITS (8)
+#define BMI160_SHIFT_BIT_POSITION_BY_09_BITS (9)
+#define BMI160_SHIFT_BIT_POSITION_BY_12_BITS (12)
+#define BMI160_SHIFT_BIT_POSITION_BY_13_BITS (13)
+#define BMI160_SHIFT_BIT_POSITION_BY_14_BITS (14)
+#define BMI160_SHIFT_BIT_POSITION_BY_15_BITS (15)
+#define BMI160_SHIFT_BIT_POSITION_BY_16_BITS (16)
+
+/****************************************************/
+/**\name DEFINITIONS USED FOR YAMAHA-YAS532 */
+/***************************************************/
+#define YAS532_MAG_STATE_NORMAL (0)
+#define YAS532_MAG_STATE_INIT_COIL (1)
+#define YAS532_MAG_STATE_MEASURE_OFFSET (2)
+#define YAS532_MAG_INITCOIL_TIMEOUT (1000)
+#define YAS532_MAG_NOTRANS_POSITION (3)
+#define YAS532_DEFAULT_SENSOR_DELAY (50)
+#define YAS532_DATA_OVERFLOW (8190)
+#define YAS532_DATA_UNDERFLOW (0)
+#define YAS532_MAG_LOG (20)
+#define YAS532_MAG_TEMPERATURE_LOG (10)
+#define YAS532_TEMP20DEGREE_TYPICAL (390)
+#define YAS532_VERSION_AC_COEF_X (850)
+#define YAS532_VERSION_AC_COEF_Y1 (750)
+#define YAS532_VERSION_AC_COEF_Y2 (750)
+#define YAS532_DATA_CENTER (4096)
+/****************************************************/
+/**\name YAMAHA-YAS532 OFFSET DEFINITION */
+/***************************************************/
+static const s8 INVALID_OFFSET[] = {0x7f, 0x7f, 0x7f};
+#define set_vector(to, from) \
+ {int _l; for (_l = 0; _l < 3; _l++) (to)[_l] = (from)[_l]; }
+#define is_valid_offset(a) \
+ (((a)[0] <= 31) && ((a)[1] <= 31) && ((a)[2] <= 31) \
+ && (-31 <= (a)[0]) && (-31 <= (a)[1]) && (-31 <= (a)[2]))
+
+/**************************************************/
+/**\name YAS532 CALIB DATA DEFINITIONS */
+/*************************************************/
+
+
+/* register address of YAS532*/
+#define BMI160_YAS532_TESTR1 (0x88)
+#define BMI160_YAS532_TESTR2 (0x89)
+#define BMI160_YAS532_RCOIL (0x81)
+#define BMI160_YAS532_COMMAND_REGISTER (0x82)
+#define BMI160_YAS532_DATA_REGISTER (0xB0)
+/* calib data register definition*/
+#define BMI160_YAS532_CALIB_CX (0x90)
+#define BMI160_YAS532_CALIB_CY1 (0x91)
+#define BMI160_YAS532_CALIB_CY2 (0x92)
+#define BMI160_YAS532_CALIB1 (0x93)
+#define BMI160_YAS532_CALIB2 (0x94)
+#define BMI160_YAS532_CALIB3 (0x95)
+#define BMI160_YAS532_CALIB4 (0x96)
+#define BMI160_YAS532_CALIB5 (0x97)
+#define BMI160_YAS532_CLAIB6 (0x98)
+#define BMI160_YAS532_CALIB7 (0x99)
+#define BMI160_YAS532_CALIB8 (0x9A)
+#define BMI160_YAS532_CALIIB9 (0x9B)
+#define BMI160_YAS532_CALIB10 (0x9C)
+#define BMI160_YAS532_CALIB11 (0x9D)
+/* offset definition */
+#define BMI160_YAS532_OFFSET_X (0x85)
+#define BMI160_YAS532_OFFSET_Y (0x86)
+#define BMI160_YAS532_OFFSET_Z (0x87)
+/* data to write register for yas532*/
+#define BMI160_YAS532_WRITE_TESTR1 (0x00)
+#define BMI160_YAS532_WRITE_TESTR2 (0x00)
+#define BMI160_YAS532_WRITE_RCOIL (0x00)
+/**************************************************/
+/**\name YAS537 DEFINITION */
+/*************************************************/
+
+#define YAS537_SRSTR_DATA (0x02)
+#define YAS537_WRITE_A_D_CONVERTER (0x03)
+#define YAS537_WRITE_A_D_CONVERTER2 (0xF8)
+#define YAS537_WRITE_FILTER (0x08)
+#define YAS537_WRITE_CONFR (0x08)
+#define YAS537_WRITE_TEMP_CALIB (0xFF)
+#define YAS537_SET_COMMAND_REGISTER (0x01)
+
+/**************************************************/
+/**\name YAS537 REGISTER DEFINITION */
+/*************************************************/
+#define YAS537_REG_SRSTR (0x90)
+#define YAS537_REG_CALR_C0 (0xC0)
+#define YAS537_REG_CALR_C1 (0xC1)
+#define YAS537_REG_CALR_C2 (0xC2)
+#define YAS537_REG_CALR_C3 (0xC3)
+#define YAS537_REG_CALR_C4 (0xC4)
+#define YAS537_REG_CALR_C5 (0xC5)
+#define YAS537_REG_CALR_C6 (0xC6)
+#define YAS537_REG_CALR_C7 (0xC7)
+#define YAS537_REG_CALR_C8 (0xC8)
+#define YAS537_REG_CALR_C9 (0xC9)
+#define YAS537_REG_CALR_CA (0xCA)
+#define YAS537_REG_CALR_CB (0xCB)
+#define YAS537_REG_CALR_CC (0xCC)
+#define YAS537_REG_CALR_CD (0xCD)
+#define YAS537_REG_CALR_CE (0xCE)
+#define YAS537_REG_CALR_CF (0xCF)
+#define YAS537_REG_CALR_DO (0xD0)
+#define YAS537_REG_MTCR (0x93)
+#define YAS537_REG_CONFR (0x82)
+#define BMI160_REG_YAS537_CMDR (0x81)
+#define YAS537_REG_OXR (0x84)
+#define YAS537_REG_AVRR (0x87)
+#define YAS537_REG_HCKR (0x88)
+#define YAS537_REG_LCKR (0x89)
+#define YAS537_REG_ADCCALR (0x91)
+#define YAS537_REG_ADCCALR_ONE (0x92)
+#define YAS537_REG_OCR (0x9E)
+#define YAS537_REG_TRMR (0x9F)
+#define YAS537_REG_TEMPERATURE_0 (0xB0)
+#define YAS537_REG_TEMPERATURE_1 (0xB1)
+#define YAS537_REG_DATA_X_0 (0xB2)
+#define YAS537_REG_DATA_X_1 (0xB3)
+#define YAS537_REG_DATA_Y1_0 (0xB4)
+#define YAS537_REG_DATA_Y1_1 (0xB5)
+#define YAS537_REG_DATA_Y2_0 (0xB6)
+#define YAS537_REG_DATA_Y2_1 (0xB7)
+#define YAS537_MAG_STATE_NORMAL (0)
+#define YAS537_MAG_STATE_INIT_COIL (1)
+#define YAS537_MAG_STATE_RECORD_DATA (2)
+#define YAS537_DATA_UNDERFLOW (0)
+#define YAS537_DATA_OVERFLOW (16383)
+/****************************************************/
+/**\name YAS537_set vector */
+/***************************************************/
+#define yas537_set_vector(to, from) \
+ {int _l; for (_l = 0; _l < 3; _l++) (to)[_l] = (from)[_l]; }
+
+#ifndef ABS
+#define ABS(a) ((a) > 0 ? (a) : -(a)) /*!< Absolute value */
+#endif
+/****************************************************/
+/**\name AKM09911 AND AKM09912 DEFINITION */
+/***************************************************/
+#define AKM09912_SENSITIVITY_DIV (256)
+#define AKM09912_SENSITIVITY (128)
+#define AKM09911_SENSITIVITY_DIV (128)
+#define AKM_ASAX (0)
+#define AKM_ASAY (1)
+#define AKM_ASAZ (2)
+#define AKM_POWER_DOWN_MODE_DATA (0x00)
+#define AKM_FUSE_ROM_MODE (0x1F)
+#define AKM_POWER_MODE_REG (0x31)
+#define AKM_SINGLE_MEASUREMENT_MODE (0x01)
+#define AKM_DATA_REGISTER (0x11)
+/*! AKM09912 Register definition */
+#define AKM09912_CHIP_ID_REG (0x01)
+/****************************************************/
+/**\name BMM150 DEFINITION */
+/***************************************************/
+#define BMI160_BMM150_SET_POWER_CONTROL (0x01)
+#define BMI160_BMM150_MAX_RETRY_WAKEUP (5)
+#define BMI160_BMM150_POWER_ON (0x01)
+#define BMI160_BMM150_POWER_OFF (0x00)
+#define BMI160_BMM150_FORCE_MODE (0x02)
+#define BMI160_BMM150_POWER_ON_SUCCESS (0)
+#define BMI160_BMM150_POWER_ON_FAIL ((s8)-1)
+
+#define BMI160_BMM150_DIG_X1 (0)
+#define BMI160_BMM150_DIG_Y1 (1)
+#define BMI160_BMM150_DIG_X2 (2)
+#define BMI160_BMM150_DIG_Y3 (3)
+#define BMI160_BMM150_DIG_XY1 (4)
+#define BMI160_BMM150_DIG_XY2 (5)
+#define BMI160_BMM150_DIG_Z1_LSB (6)
+#define BMI160_BMM150_DIG_Z1_MSB (7)
+#define BMI160_BMM150_DIG_Z2_LSB (8)
+#define BMI160_BMM150_DIG_Z2_MSB (9)
+#define BMI160_BMM150_DIG_DIG_Z3_LSB (10)
+#define BMI160_BMM150_DIG_DIG_Z3_MSB (11)
+#define BMI160_BMM150_DIG_DIG_Z4_LSB (12)
+#define BMI160_BMM150_DIG_DIG_Z4_MSB (13)
+#define BMI160_BMM150_DIG_DIG_XYZ1_LSB (14)
+#define BMI160_BMM150_DIG_DIG_XYZ1_MSB (15)
+
+/**************************************************************/
+/**\name STRUCTURE DEFINITIONS */
+/**************************************************************/
+/*!
+* @brief bmi160 structure
+* This structure holds all relevant information about bmi160
+*/
+struct bmi160_t {
+u8 chip_id;/**< chip id of BMI160 */
+u8 dev_addr;/**< device address of BMI160 */
+s8 mag_manual_enable;/**< used for check the mag manual/auto mode status */
+BMI160_WR_FUNC_PTR;/**< bus write function pointer */
+BMI160_RD_FUNC_PTR;/**< bus read function pointer */
+BMI160_BRD_FUNC_PTR;/**< burst write function pointer */
+void (*delay_msec)(BMI160_MDELAY_DATA_TYPE);/**< delay function pointer */
+};
+/*!
+ * @brief Structure containing bmm150 and akm09911
+ * magnetometer values for x,y and
+ * z-axis in s16
+ */
+struct bmi160_mag_t {
+s16 x;/**< BMM150 and AKM09911 and AKM09912 X raw data*/
+s16 y;/**< BMM150 and AKM09911 and AKM09912 Y raw data*/
+s16 z;/**< BMM150 and AKM09911 and AKM09912 Z raw data*/
+};
+/*!
+ * @brief Structure containing bmm150 xyz data and temperature
+ */
+struct bmi160_mag_xyzr_t {
+s16 x;/**< BMM150 X raw data*/
+s16 y;/**< BMM150 Y raw data*/
+s16 z;/**<BMM150 Z raw data*/
+u16 r;/**<BMM150 R raw data*/
+};
+/*!
+ * @brief Structure containing gyro xyz data
+ */
+struct bmi160_gyro_t {
+s16 x;/**<gyro X data*/
+s16 y;/**<gyro Y data*/
+s16 z;/**<gyro Z data*/
+};
+/*!
+ * @brief Structure containing accel xyz data
+ */
+struct bmi160_accel_t {
+s16 x;/**<accel X data*/
+s16 y;/**<accel Y data*/
+s16 z;/**<accel Z data*/
+};
+/*!
+ * @brief Structure bmm150 mag compensated data with s32 output
+ */
+struct bmi160_mag_xyz_s32_t {
+s16 x;/**<BMM150 X compensated data*/
+s16 y;/**<BMM150 Y compensated data*/
+s16 z;/**<BMM150 Z compensated data*/
+};
+/*!
+ * @brief Structure bmm150 mag trim data
+ */
+struct trim_data_t {
+s8 dig_x1;/**<BMM150 trim x1 data*/
+s8 dig_y1;/**<BMM150 trim y1 data*/
+
+s8 dig_x2;/**<BMM150 trim x2 data*/
+s8 dig_y2;/**<BMM150 trim y2 data*/
+
+u16 dig_z1;/**<BMM150 trim z1 data*/
+s16 dig_z2;/**<BMM150 trim z2 data*/
+s16 dig_z3;/**<BMM150 trim z3 data*/
+s16 dig_z4;/**<BMM150 trim z4 data*/
+
+u8 dig_xy1;/**<BMM150 trim xy1 data*/
+s8 dig_xy2;/**<BMM150 trim xy2 data*/
+
+u16 dig_xyz1;/**<BMM150 trim xyz1 data*/
+};
+
+/*!
+* @brief Structure for reading AKM compensating data
+*/
+struct bst_akm_sensitivity_data_t {
+u8 asax;/**<AKM09911 and AKM09912 X sensitivity data*/
+u8 asay;/**<AKM09911 and AKM09912 Y sensitivity data*/
+u8 asaz;/**<AKM09911 and AKM09912 Z sensitivity data*/
+};
+/*!
+* @brief YAMAHA-YAS532 struct
+* Calibration YAS532 data struct
+*/
+struct bst_yas532_calib_data_t {
+s32 cx;/**<YAS532 calib cx data */
+s32 cy1;/**<YAS532 calib cy1 data */
+s32 cy2;/**<YAS532 calib cy2 data */
+s32 a2;/**<YAS532 calib a2 data */
+s32 a3;/**<YAS532 calib a3 data */
+s32 a4;/**<YAS532 calib a4 data */
+s32 a5;/**<YAS532 calib a5 data */
+s32 a6;/**<YAS532 calib a6 data */
+s32 a7;/**<YAS532 calib a7 data */
+s32 a8;/**<YAS532 calib a8 data */
+s32 a9;/**<YAS532 calib a9 data */
+s32 k;/**<YAS532 calib k data */
+s8 rxy1y2[3];/**<YAS532 calib rxy1y2 data */
+u8 fxy1y2[3];/**<YAS532 calib fxy1y2 data */
+};
+/*!
+* @brief YAS532 Temperature structure
+*/
+#if YAS532_MAG_LOG < YAS532_MAG_TEMPERATURE_LOG
+struct yas_temp_filter_t {
+u16 log[YAS532_MAG_TEMPERATURE_LOG];/**<YAS532 temp log array */
+u8 num;/**< used for increment the index */
+u8 idx;/**< used for increment the index */
+};
+#endif
+/*!
+* @brief YAS532 sensor initialization
+*/
+struct yas532_t {
+struct bst_yas532_calib_data_t calib_yas532;/**< calib data */
+s8 measure_state;/**< update measure state */
+s8 v_hard_offset_s8[3];/**< offset write array*/
+s32 coef[3];/**< co efficient data */
+s8 overflow;/**< over flow condition check */
+u8 dev_id;/**< device id information */
+const s8 *transform;/**< transform condition check */
+#if YAS532_MAG_LOG < YAS532_MAG_TEMPERATURE_LOG
+struct yas_temp_filter_t temp_data;/**< temp data */
+#endif
+u16 last_raw[4];/**< raw data */
+};
+/*!
+* @brief Used for reading the YAS532 XYZ data
+*/
+struct yas532_vector {
+s32 yas532_vector_xyz[3];/**< YAS532 compensated xyz data*/
+};
+/**
+ * @struct yas_vector
+ * @brief Stores the sensor data
+ */
+struct yas_vector {
+ s32 yas537_vector_xyz[3]; /*!< vector data */
+};
+/*!
+* @brief YAMAHA-YAS532 struct
+* Calibration YAS532 data struct
+*/
+struct bst_yas537_calib_data_t {
+s8 a2;/**<YAS532 calib a2 data */
+s8 a3;/**<YAS532 calib a3 data */
+s8 a4;/**<YAS532 calib a4 data */
+s16 a5;/**<YAS532 calib a5 data */
+s8 a6;/**<YAS532 calib a6 data */
+s8 a7;/**<YAS532 calib a7 data */
+s8 a8;/**<YAS532 calib a8 data */
+s16 a9;/**<YAS532 calib a9 data */
+u8 k;/**<YAS532 calib k data */
+u8 ver;/**<YAS532 calib ver data*/
+};
+/*!
+* @brief YAS537 sensor initialization
+*/
+struct yas537_t {
+struct bst_yas537_calib_data_t calib_yas537;/**< calib data */
+s8 measure_state;/**< update measure state */
+s8 hard_offset[3];/**< offset write array*/
+u16 last_after_rcoil[3];/**< rcoil write array*/
+s32 coef[3];/**< co efficient data */
+s8 overflow;/**< over flow condition check */
+u8 dev_id;/**< device id information */
+u8 average;/**<average selection for offset configuration*/
+const s8 *transform;/**< transform condition check */
+u16 last_raw[4];/**< raw data */
+struct yas_vector xyz; /*!< X, Y, Z measurement data of the sensor */
+};
+/**************************************************************/
+/**\name USER DATA REGISTERS DEFINITION START */
+/**************************************************************/
+
+/**************************************************************/
+/**\name CHIP ID LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* Chip ID Description - Reg Addr --> (0x00), Bit --> 0...7 */
+#define BMI160_USER_CHIP_ID__POS (0)
+#define BMI160_USER_CHIP_ID__MSK (0xFF)
+#define BMI160_USER_CHIP_ID__LEN (8)
+#define BMI160_USER_CHIP_ID__REG (BMI160_USER_CHIP_ID_ADDR)
+/**************************************************************/
+/**\name ERROR STATUS LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* Error Description - Reg Addr --> (0x02), Bit --> 0 */
+#define BMI160_USER_ERR_STAT__POS (0)
+#define BMI160_USER_ERR_STAT__LEN (8)
+#define BMI160_USER_ERR_STAT__MSK (0xFF)
+#define BMI160_USER_ERR_STAT__REG (BMI160_USER_ERROR_ADDR)
+
+#define BMI160_USER_FATAL_ERR__POS (0)
+#define BMI160_USER_FATAL_ERR__LEN (1)
+#define BMI160_USER_FATAL_ERR__MSK (0x01)
+#define BMI160_USER_FATAL_ERR__REG (BMI160_USER_ERROR_ADDR)
+
+/* Error Description - Reg Addr --> (0x02), Bit --> 1...4 */
+#define BMI160_USER_ERR_CODE__POS (1)
+#define BMI160_USER_ERR_CODE__LEN (4)
+#define BMI160_USER_ERR_CODE__MSK (0x1E)
+#define BMI160_USER_ERR_CODE__REG (BMI160_USER_ERROR_ADDR)
+
+/* Error Description - Reg Addr --> (0x02), Bit --> 5 */
+#define BMI160_USER_I2C_FAIL_ERR__POS (5)
+#define BMI160_USER_I2C_FAIL_ERR__LEN (1)
+#define BMI160_USER_I2C_FAIL_ERR__MSK (0x20)
+#define BMI160_USER_I2C_FAIL_ERR__REG (BMI160_USER_ERROR_ADDR)
+
+/* Error Description - Reg Addr --> (0x02), Bit --> 6 */
+#define BMI160_USER_DROP_CMD_ERR__POS (6)
+#define BMI160_USER_DROP_CMD_ERR__LEN (1)
+#define BMI160_USER_DROP_CMD_ERR__MSK (0x40)
+#define BMI160_USER_DROP_CMD_ERR__REG (BMI160_USER_ERROR_ADDR)
+/**************************************************************/
+/**\name MAG DATA READY LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* Error Description - Reg Addr --> (0x02), Bit --> 7 */
+#define BMI160_USER_MAG_DADA_RDY_ERR__POS (7)
+#define BMI160_USER_MAG_DADA_RDY_ERR__LEN (1)
+#define BMI160_USER_MAG_DADA_RDY_ERR__MSK (0x80)
+#define BMI160_USER_MAG_DADA_RDY_ERR__REG (BMI160_USER_ERROR_ADDR)
+/**************************************************************/
+/**\name MAG POWER MODE LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* PMU_Status Description of MAG - Reg Addr --> (0x03), Bit --> 1..0 */
+#define BMI160_USER_MAG_POWER_MODE_STAT__POS (0)
+#define BMI160_USER_MAG_POWER_MODE_STAT__LEN (2)
+#define BMI160_USER_MAG_POWER_MODE_STAT__MSK (0x03)
+#define BMI160_USER_MAG_POWER_MODE_STAT__REG \
+(BMI160_USER_PMU_STAT_ADDR)
+/**************************************************************/
+/**\name GYRO POWER MODE LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* PMU_Status Description of GYRO - Reg Addr --> (0x03), Bit --> 3...2 */
+#define BMI160_USER_GYRO_POWER_MODE_STAT__POS (2)
+#define BMI160_USER_GYRO_POWER_MODE_STAT__LEN (2)
+#define BMI160_USER_GYRO_POWER_MODE_STAT__MSK (0x0C)
+#define BMI160_USER_GYRO_POWER_MODE_STAT__REG \
+(BMI160_USER_PMU_STAT_ADDR)
+/**************************************************************/
+/**\name ACCEL POWER MODE LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* PMU_Status Description of ACCEL - Reg Addr --> (0x03), Bit --> 5...4 */
+#define BMI160_USER_ACCEL_POWER_MODE_STAT__POS (4)
+#define BMI160_USER_ACCEL_POWER_MODE_STAT__LEN (2)
+#define BMI160_USER_ACCEL_POWER_MODE_STAT__MSK (0x30)
+#define BMI160_USER_ACCEL_POWER_MODE_STAT__REG \
+(BMI160_USER_PMU_STAT_ADDR)
+/**************************************************************/
+/**\name MAG DATA XYZ LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* Mag_X(LSB) Description - Reg Addr --> (0x04), Bit --> 0...7 */
+#define BMI160_USER_DATA_0_MAG_X_LSB__POS (0)
+#define BMI160_USER_DATA_0_MAG_X_LSB__LEN (8)
+#define BMI160_USER_DATA_0_MAG_X_LSB__MSK (0xFF)
+#define BMI160_USER_DATA_0_MAG_X_LSB__REG (BMI160_USER_DATA_0_ADDR)
+
+/* Mag_X(LSB) Description - Reg Addr --> (0x04), Bit --> 3...7 */
+#define BMI160_USER_DATA_MAG_X_LSB__POS (3)
+#define BMI160_USER_DATA_MAG_X_LSB__LEN (5)
+#define BMI160_USER_DATA_MAG_X_LSB__MSK (0xF8)
+#define BMI160_USER_DATA_MAG_X_LSB__REG (BMI160_USER_DATA_0_ADDR)
+
+/* Mag_X(MSB) Description - Reg Addr --> (0x05), Bit --> 0...7 */
+#define BMI160_USER_DATA_1_MAG_X_MSB__POS (0)
+#define BMI160_USER_DATA_1_MAG_X_MSB__LEN (8)
+#define BMI160_USER_DATA_1_MAG_X_MSB__MSK (0xFF)
+#define BMI160_USER_DATA_1_MAG_X_MSB__REG (BMI160_USER_DATA_1_ADDR)
+
+/* Mag_Y(LSB) Description - Reg Addr --> (0x06), Bit --> 0...7 */
+#define BMI160_USER_DATA_2_MAG_Y_LSB__POS (0)
+#define BMI160_USER_DATA_2_MAG_Y_LSB__LEN (8)
+#define BMI160_USER_DATA_2_MAG_Y_LSB__MSK (0xFF)
+#define BMI160_USER_DATA_2_MAG_Y_LSB__REG (BMI160_USER_DATA_2_ADDR)
+
+/* Mag_Y(LSB) Description - Reg Addr --> (0x06), Bit --> 3...7 */
+#define BMI160_USER_DATA_MAG_Y_LSB__POS (3)
+#define BMI160_USER_DATA_MAG_Y_LSB__LEN (5)
+#define BMI160_USER_DATA_MAG_Y_LSB__MSK (0xF8)
+#define BMI160_USER_DATA_MAG_Y_LSB__REG (BMI160_USER_DATA_2_ADDR)
+
+/* Mag_Y(MSB) Description - Reg Addr --> (0x07), Bit --> 0...7 */
+#define BMI160_USER_DATA_3_MAG_Y_MSB__POS (0)
+#define BMI160_USER_DATA_3_MAG_Y_MSB__LEN (8)
+#define BMI160_USER_DATA_3_MAG_Y_MSB__MSK (0xFF)
+#define BMI160_USER_DATA_3_MAG_Y_MSB__REG (BMI160_USER_DATA_3_ADDR)
+
+/* Mag_Z(LSB) Description - Reg Addr --> (0x08), Bit --> 0...7 */
+#define BMI160_USER_DATA_4_MAG_Z_LSB__POS (0)
+#define BMI160_USER_DATA_4_MAG_Z_LSB__LEN (8)
+#define BMI160_USER_DATA_4_MAG_Z_LSB__MSK (0xFF)
+#define BMI160_USER_DATA_4_MAG_Z_LSB__REG (BMI160_USER_DATA_4_ADDR)
+
+/* Mag_X(LSB) Description - Reg Addr --> (0x08), Bit --> 3...7 */
+#define BMI160_USER_DATA_MAG_Z_LSB__POS (1)
+#define BMI160_USER_DATA_MAG_Z_LSB__LEN (7)
+#define BMI160_USER_DATA_MAG_Z_LSB__MSK (0xFE)
+#define BMI160_USER_DATA_MAG_Z_LSB__REG (BMI160_USER_DATA_4_ADDR)
+
+/* Mag_Z(MSB) Description - Reg Addr --> (0x09), Bit --> 0...7 */
+#define BMI160_USER_DATA_5_MAG_Z_MSB__POS (0)
+#define BMI160_USER_DATA_5_MAG_Z_MSB__LEN (8)
+#define BMI160_USER_DATA_5_MAG_Z_MSB__MSK (0xFF)
+#define BMI160_USER_DATA_5_MAG_Z_MSB__REG (BMI160_USER_DATA_5_ADDR)
+
+/* RHALL(LSB) Description - Reg Addr --> (0x0A), Bit --> 0...7 */
+#define BMI160_USER_DATA_6_RHALL_LSB__POS (0)
+#define BMI160_USER_DATA_6_RHALL_LSB__LEN (8)
+#define BMI160_USER_DATA_6_RHALL_LSB__MSK (0xFF)
+#define BMI160_USER_DATA_6_RHALL_LSB__REG (BMI160_USER_DATA_6_ADDR)
+
+/* Mag_R(LSB) Description - Reg Addr --> (0x0A), Bit --> 3...7 */
+#define BMI160_USER_DATA_MAG_R_LSB__POS (2)
+#define BMI160_USER_DATA_MAG_R_LSB__LEN (6)
+#define BMI160_USER_DATA_MAG_R_LSB__MSK (0xFC)
+#define BMI160_USER_DATA_MAG_R_LSB__REG (BMI160_USER_DATA_6_ADDR)
+
+/* RHALL(MSB) Description - Reg Addr --> (0x0B), Bit --> 0...7 */
+#define BMI160_USER_DATA_7_RHALL_MSB__POS (0)
+#define BMI160_USER_DATA_7_RHALL_MSB__LEN (8)
+#define BMI160_USER_DATA_7_RHALL_MSB__MSK (0xFF)
+#define BMI160_USER_DATA_7_RHALL_MSB__REG (BMI160_USER_DATA_7_ADDR)
+/**************************************************************/
+/**\name GYRO DATA XYZ LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* GYR_X (LSB) Description - Reg Addr --> (0x0C), Bit --> 0...7 */
+#define BMI160_USER_DATA_8_GYRO_X_LSB__POS (0)
+#define BMI160_USER_DATA_8_GYRO_X_LSB__LEN (8)
+#define BMI160_USER_DATA_8_GYRO_X_LSB__MSK (0xFF)
+#define BMI160_USER_DATA_8_GYRO_X_LSB__REG (BMI160_USER_DATA_8_ADDR)
+
+/* GYR_X (MSB) Description - Reg Addr --> (0x0D), Bit --> 0...7 */
+#define BMI160_USER_DATA_9_GYRO_X_MSB__POS (0)
+#define BMI160_USER_DATA_9_GYRO_X_MSB__LEN (8)
+#define BMI160_USER_DATA_9_GYRO_X_MSB__MSK (0xFF)
+#define BMI160_USER_DATA_9_GYRO_X_MSB__REG (BMI160_USER_DATA_9_ADDR)
+
+/* GYR_Y (LSB) Description - Reg Addr --> 0x0E, Bit --> 0...7 */
+#define BMI160_USER_DATA_10_GYRO_Y_LSB__POS (0)
+#define BMI160_USER_DATA_10_GYRO_Y_LSB__LEN (8)
+#define BMI160_USER_DATA_10_GYRO_Y_LSB__MSK (0xFF)
+#define BMI160_USER_DATA_10_GYRO_Y_LSB__REG (BMI160_USER_DATA_10_ADDR)
+
+/* GYR_Y (MSB) Description - Reg Addr --> (0x0F), Bit --> 0...7 */
+#define BMI160_USER_DATA_11_GYRO_Y_MSB__POS (0)
+#define BMI160_USER_DATA_11_GYRO_Y_MSB__LEN (8)
+#define BMI160_USER_DATA_11_GYRO_Y_MSB__MSK (0xFF)
+#define BMI160_USER_DATA_11_GYRO_Y_MSB__REG (BMI160_USER_DATA_11_ADDR)
+
+/* GYR_Z (LSB) Description - Reg Addr --> (0x10), Bit --> 0...7 */
+#define BMI160_USER_DATA_12_GYRO_Z_LSB__POS (0)
+#define BMI160_USER_DATA_12_GYRO_Z_LSB__LEN (8)
+#define BMI160_USER_DATA_12_GYRO_Z_LSB__MSK (0xFF)
+#define BMI160_USER_DATA_12_GYRO_Z_LSB__REG (BMI160_USER_DATA_12_ADDR)
+
+/* GYR_Z (MSB) Description - Reg Addr --> (0x11), Bit --> 0...7 */
+#define BMI160_USER_DATA_13_GYRO_Z_MSB__POS (0)
+#define BMI160_USER_DATA_13_GYRO_Z_MSB__LEN (8)
+#define BMI160_USER_DATA_13_GYRO_Z_MSB__MSK (0xFF)
+#define BMI160_USER_DATA_13_GYRO_Z_MSB__REG (BMI160_USER_DATA_13_ADDR)
+/**************************************************************/
+/**\name ACCEL DATA XYZ LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* ACC_X (LSB) Description - Reg Addr --> (0x12), Bit --> 0...7 */
+#define BMI160_USER_DATA_14_ACCEL_X_LSB__POS (0)
+#define BMI160_USER_DATA_14_ACCEL_X_LSB__LEN (8)
+#define BMI160_USER_DATA_14_ACCEL_X_LSB__MSK (0xFF)
+#define BMI160_USER_DATA_14_ACCEL_X_LSB__REG (BMI160_USER_DATA_14_ADDR)
+
+/* ACC_X (MSB) Description - Reg Addr --> 0x13, Bit --> 0...7 */
+#define BMI160_USER_DATA_15_ACCEL_X_MSB__POS (0)
+#define BMI160_USER_DATA_15_ACCEL_X_MSB__LEN (8)
+#define BMI160_USER_DATA_15_ACCEL_X_MSB__MSK (0xFF)
+#define BMI160_USER_DATA_15_ACCEL_X_MSB__REG (BMI160_USER_DATA_15_ADDR)
+
+/* ACC_Y (LSB) Description - Reg Addr --> (0x14), Bit --> 0...7 */
+#define BMI160_USER_DATA_16_ACCEL_Y_LSB__POS (0)
+#define BMI160_USER_DATA_16_ACCEL_Y_LSB__LEN (8)
+#define BMI160_USER_DATA_16_ACCEL_Y_LSB__MSK (0xFF)
+#define BMI160_USER_DATA_16_ACCEL_Y_LSB__REG (BMI160_USER_DATA_16_ADDR)
+
+/* ACC_Y (MSB) Description - Reg Addr --> (0x15), Bit --> 0...7 */
+#define BMI160_USER_DATA_17_ACCEL_Y_MSB__POS (0)
+#define BMI160_USER_DATA_17_ACCEL_Y_MSB__LEN (8)
+#define BMI160_USER_DATA_17_ACCEL_Y_MSB__MSK (0xFF)
+#define BMI160_USER_DATA_17_ACCEL_Y_MSB__REG (BMI160_USER_DATA_17_ADDR)
+
+/* ACC_Z (LSB) Description - Reg Addr --> 0x16, Bit --> 0...7 */
+#define BMI160_USER_DATA_18_ACCEL_Z_LSB__POS (0)
+#define BMI160_USER_DATA_18_ACCEL_Z_LSB__LEN (8)
+#define BMI160_USER_DATA_18_ACCEL_Z_LSB__MSK (0xFF)
+#define BMI160_USER_DATA_18_ACCEL_Z_LSB__REG (BMI160_USER_DATA_18_ADDR)
+
+/* ACC_Z (MSB) Description - Reg Addr --> (0x17), Bit --> 0...7 */
+#define BMI160_USER_DATA_19_ACCEL_Z_MSB__POS (0)
+#define BMI160_USER_DATA_19_ACCEL_Z_MSB__LEN (8)
+#define BMI160_USER_DATA_19_ACCEL_Z_MSB__MSK (0xFF)
+#define BMI160_USER_DATA_19_ACCEL_Z_MSB__REG (BMI160_USER_DATA_19_ADDR)
+/**************************************************************/
+/**\name SENSOR TIME LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* SENSORTIME_0 (LSB) Description - Reg Addr --> (0x18), Bit --> 0...7 */
+#define BMI160_USER_SENSORTIME_0_SENSOR_TIME_LSB__POS (0)
+#define BMI160_USER_SENSORTIME_0_SENSOR_TIME_LSB__LEN (8)
+#define BMI160_USER_SENSORTIME_0_SENSOR_TIME_LSB__MSK (0xFF)
+#define BMI160_USER_SENSORTIME_0_SENSOR_TIME_LSB__REG \
+ (BMI160_USER_SENSORTIME_0_ADDR)
+
+/* SENSORTIME_1 (MSB) Description - Reg Addr --> (0x19), Bit --> 0...7 */
+#define BMI160_USER_SENSORTIME_1_SENSOR_TIME_MSB__POS (0)
+#define BMI160_USER_SENSORTIME_1_SENSOR_TIME_MSB__LEN (8)
+#define BMI160_USER_SENSORTIME_1_SENSOR_TIME_MSB__MSK (0xFF)
+#define BMI160_USER_SENSORTIME_1_SENSOR_TIME_MSB__REG \
+ (BMI160_USER_SENSORTIME_1_ADDR)
+
+/* SENSORTIME_2 (MSB) Description - Reg Addr --> (0x1A), Bit --> 0...7 */
+#define BMI160_USER_SENSORTIME_2_SENSOR_TIME_MSB__POS (0)
+#define BMI160_USER_SENSORTIME_2_SENSOR_TIME_MSB__LEN (8)
+#define BMI160_USER_SENSORTIME_2_SENSOR_TIME_MSB__MSK (0xFF)
+#define BMI160_USER_SENSORTIME_2_SENSOR_TIME_MSB__REG \
+ (BMI160_USER_SENSORTIME_2_ADDR)
+/**************************************************************/
+/**\name GYRO SELF TEST LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* Status Description - Reg Addr --> 0x1B, Bit --> 1 */
+#define BMI160_USER_STAT_GYRO_SELFTEST_OK__POS (1)
+#define BMI160_USER_STAT_GYRO_SELFTEST_OK__LEN (1)
+#define BMI160_USER_STAT_GYRO_SELFTEST_OK__MSK (0x02)
+#define BMI160_USER_STAT_GYRO_SELFTEST_OK__REG \
+ (BMI160_USER_STAT_ADDR)
+/**************************************************************/
+/**\name MAG MANUAL OPERATION LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* Status Description - Reg Addr --> 0x1B, Bit --> 2 */
+#define BMI160_USER_STAT_MAG_MANUAL_OPERATION__POS (2)
+#define BMI160_USER_STAT_MAG_MANUAL_OPERATION__LEN (1)
+#define BMI160_USER_STAT_MAG_MANUAL_OPERATION__MSK (0x04)
+#define BMI160_USER_STAT_MAG_MANUAL_OPERATION__REG \
+ (BMI160_USER_STAT_ADDR)
+/**************************************************************/
+/**\name FOC STATUS LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* Status Description - Reg Addr --> 0x1B, Bit --> 3 */
+#define BMI160_USER_STAT_FOC_RDY__POS (3)
+#define BMI160_USER_STAT_FOC_RDY__LEN (1)
+#define BMI160_USER_STAT_FOC_RDY__MSK (0x08)
+#define BMI160_USER_STAT_FOC_RDY__REG (BMI160_USER_STAT_ADDR)
+/**************************************************************/
+/**\name NVM READY LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* Status Description - Reg Addr --> 0x1B, Bit --> 4 */
+#define BMI160_USER_STAT_NVM_RDY__POS (4)
+#define BMI160_USER_STAT_NVM_RDY__LEN (1)
+#define BMI160_USER_STAT_NVM_RDY__MSK (0x10)
+#define BMI160_USER_STAT_NVM_RDY__REG (BMI160_USER_STAT_ADDR)
+/**************************************************************/
+/**\name DATA READY LENGTH, POSITION AND MASK FOR ACCEL, MAG AND GYRO*/
+/**************************************************************/
+/* Status Description - Reg Addr --> 0x1B, Bit --> 5 */
+#define BMI160_USER_STAT_DATA_RDY_MAG__POS (5)
+#define BMI160_USER_STAT_DATA_RDY_MAG__LEN (1)
+#define BMI160_USER_STAT_DATA_RDY_MAG__MSK (0x20)
+#define BMI160_USER_STAT_DATA_RDY_MAG__REG (BMI160_USER_STAT_ADDR)
+
+/* Status Description - Reg Addr --> 0x1B, Bit --> 6 */
+#define BMI160_USER_STAT_DATA_RDY_GYRO__POS (6)
+#define BMI160_USER_STAT_DATA_RDY_GYRO__LEN (1)
+#define BMI160_USER_STAT_DATA_RDY_GYRO__MSK (0x40)
+#define BMI160_USER_STAT_DATA_RDY_GYRO__REG (BMI160_USER_STAT_ADDR)
+
+/* Status Description - Reg Addr --> 0x1B, Bit --> 7 */
+#define BMI160_USER_STAT_DATA_RDY_ACCEL__POS (7)
+#define BMI160_USER_STAT_DATA_RDY_ACCEL__LEN (1)
+#define BMI160_USER_STAT_DATA_RDY_ACCEL__MSK (0x80)
+#define BMI160_USER_STAT_DATA_RDY_ACCEL__REG (BMI160_USER_STAT_ADDR)
+/**************************************************************/
+/**\name INTERRUPT STATUS LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 0 */
+#define BMI160_USER_INTR_STAT_0_STEP_INTR__POS (0)
+#define BMI160_USER_INTR_STAT_0_STEP_INTR__LEN (1)
+#define BMI160_USER_INTR_STAT_0_STEP_INTR__MSK (0x01)
+#define BMI160_USER_INTR_STAT_0_STEP_INTR__REG \
+ (BMI160_USER_INTR_STAT_0_ADDR)
+/**************************************************************/
+/**\name SIGNIFICANT INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 1 */
+#define BMI160_USER_INTR_STAT_0_SIGNIFICANT_INTR__POS (1)
+#define BMI160_USER_INTR_STAT_0_SIGNIFICANT_INTR__LEN (1)
+#define BMI160_USER_INTR_STAT_0_SIGNIFICANT_INTR__MSK (0x02)
+#define BMI160_USER_INTR_STAT_0_SIGNIFICANT_INTR__REG \
+ (BMI160_USER_INTR_STAT_0_ADDR)
+/**************************************************************/
+/**\name ANY_MOTION INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 2 */
+#define BMI160_USER_INTR_STAT_0_ANY_MOTION__POS (2)
+#define BMI160_USER_INTR_STAT_0_ANY_MOTION__LEN (1)
+#define BMI160_USER_INTR_STAT_0_ANY_MOTION__MSK (0x04)
+#define BMI160_USER_INTR_STAT_0_ANY_MOTION__REG \
+ (BMI160_USER_INTR_STAT_0_ADDR)
+/**************************************************************/
+/**\name PMU TRIGGER INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 3 */
+#define BMI160_USER_INTR_STAT_0_PMU_TRIGGER__POS 3
+#define BMI160_USER_INTR_STAT_0_PMU_TRIGGER__LEN (1)
+#define BMI160_USER_INTR_STAT_0_PMU_TRIGGER__MSK (0x08)
+#define BMI160_USER_INTR_STAT_0_PMU_TRIGGER__REG \
+ (BMI160_USER_INTR_STAT_0_ADDR)
+/**************************************************************/
+/**\name DOUBLE TAP INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 4 */
+#define BMI160_USER_INTR_STAT_0_DOUBLE_TAP_INTR__POS 4
+#define BMI160_USER_INTR_STAT_0_DOUBLE_TAP_INTR__LEN (1)
+#define BMI160_USER_INTR_STAT_0_DOUBLE_TAP_INTR__MSK (0x10)
+#define BMI160_USER_INTR_STAT_0_DOUBLE_TAP_INTR__REG \
+ (BMI160_USER_INTR_STAT_0_ADDR)
+/**************************************************************/
+/**\name SINGLE TAP INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 5 */
+#define BMI160_USER_INTR_STAT_0_SINGLE_TAP_INTR__POS 5
+#define BMI160_USER_INTR_STAT_0_SINGLE_TAP_INTR__LEN (1)
+#define BMI160_USER_INTR_STAT_0_SINGLE_TAP_INTR__MSK (0x20)
+#define BMI160_USER_INTR_STAT_0_SINGLE_TAP_INTR__REG \
+ (BMI160_USER_INTR_STAT_0_ADDR)
+/**************************************************************/
+/**\name ORIENT INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 6 */
+#define BMI160_USER_INTR_STAT_0_ORIENT__POS (6)
+#define BMI160_USER_INTR_STAT_0_ORIENT__LEN (1)
+#define BMI160_USER_INTR_STAT_0_ORIENT__MSK (0x40)
+#define BMI160_USER_INTR_STAT_0_ORIENT__REG \
+ (BMI160_USER_INTR_STAT_0_ADDR)
+/**************************************************************/
+/**\name FLAT INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 7 */
+#define BMI160_USER_INTR_STAT_0_FLAT__POS (7)
+#define BMI160_USER_INTR_STAT_0_FLAT__LEN (1)
+#define BMI160_USER_INTR_STAT_0_FLAT__MSK (0x80)
+#define BMI160_USER_INTR_STAT_0_FLAT__REG \
+ (BMI160_USER_INTR_STAT_0_ADDR)
+/**************************************************************/
+/**\name HIGH_G INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_1 Description - Reg Addr --> 0x1D, Bit --> 2 */
+#define BMI160_USER_INTR_STAT_1_HIGH_G_INTR__POS (2)
+#define BMI160_USER_INTR_STAT_1_HIGH_G_INTR__LEN (1)
+#define BMI160_USER_INTR_STAT_1_HIGH_G_INTR__MSK (0x04)
+#define BMI160_USER_INTR_STAT_1_HIGH_G_INTR__REG \
+ (BMI160_USER_INTR_STAT_1_ADDR)
+/**************************************************************/
+/**\name LOW_G INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_1 Description - Reg Addr --> 0x1D, Bit --> 3 */
+#define BMI160_USER_INTR_STAT_1_LOW_G_INTR__POS (3)
+#define BMI160_USER_INTR_STAT_1_LOW_G_INTR__LEN (1)
+#define BMI160_USER_INTR_STAT_1_LOW_G_INTR__MSK (0x08)
+#define BMI160_USER_INTR_STAT_1_LOW_G_INTR__REG \
+ (BMI160_USER_INTR_STAT_1_ADDR)
+/**************************************************************/
+/**\name DATA READY INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_1 Description - Reg Addr --> 0x1D, Bit --> 4 */
+#define BMI160_USER_INTR_STAT_1_DATA_RDY_INTR__POS (4)
+#define BMI160_USER_INTR_STAT_1_DATA_RDY_INTR__LEN (1)
+#define BMI160_USER_INTR_STAT_1_DATA_RDY_INTR__MSK (0x10)
+#define BMI160_USER_INTR_STAT_1_DATA_RDY_INTR__REG \
+ (BMI160_USER_INTR_STAT_1_ADDR)
+/**************************************************************/
+/**\name FIFO FULL INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_1 Description - Reg Addr --> 0x1D, Bit --> 5 */
+#define BMI160_USER_INTR_STAT_1_FIFO_FULL_INTR__POS (5)
+#define BMI160_USER_INTR_STAT_1_FIFO_FULL_INTR__LEN (1)
+#define BMI160_USER_INTR_STAT_1_FIFO_FULL_INTR__MSK (0x20)
+#define BMI160_USER_INTR_STAT_1_FIFO_FULL_INTR__REG \
+ (BMI160_USER_INTR_STAT_1_ADDR)
+/**************************************************************/
+/**\name FIFO WATERMARK INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_1 Description - Reg Addr --> 0x1D, Bit --> 6 */
+#define BMI160_USER_INTR_STAT_1_FIFO_WM_INTR__POS (6)
+#define BMI160_USER_INTR_STAT_1_FIFO_WM_INTR__LEN (1)
+#define BMI160_USER_INTR_STAT_1_FIFO_WM_INTR__MSK (0x40)
+#define BMI160_USER_INTR_STAT_1_FIFO_WM_INTR__REG \
+ (BMI160_USER_INTR_STAT_1_ADDR)
+/**************************************************************/
+/**\name NO MOTION INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_1 Description - Reg Addr --> 0x1D, Bit --> 7 */
+#define BMI160_USER_INTR_STAT_1_NOMOTION_INTR__POS (7)
+#define BMI160_USER_INTR_STAT_1_NOMOTION_INTR__LEN (1)
+#define BMI160_USER_INTR_STAT_1_NOMOTION_INTR__MSK (0x80)
+#define BMI160_USER_INTR_STAT_1_NOMOTION_INTR__REG \
+ (BMI160_USER_INTR_STAT_1_ADDR)
+/**************************************************************/
+/**\name ANY MOTION-XYZ AXIS INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 0 */
+#define BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_X__POS (0)
+#define BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_X__LEN (1)
+#define BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_X__MSK (0x01)
+#define BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_X__REG \
+ (BMI160_USER_INTR_STAT_2_ADDR)
+
+/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 1 */
+#define BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_Y__POS (1)
+#define BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_Y__LEN (1)
+#define BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_Y__MSK (0x02)
+#define BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_Y__REG \
+ (BMI160_USER_INTR_STAT_2_ADDR)
+
+/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 2 */
+#define BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_Z__POS (2)
+#define BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_Z__LEN (1)
+#define BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_Z__MSK (0x04)
+#define BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_Z__REG \
+ (BMI160_USER_INTR_STAT_2_ADDR)
+/**************************************************************/
+/**\name ANY MOTION SIGN LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 3 */
+#define BMI160_USER_INTR_STAT_2_ANY_MOTION_SIGN__POS (3)
+#define BMI160_USER_INTR_STAT_2_ANY_MOTION_SIGN__LEN (1)
+#define BMI160_USER_INTR_STAT_2_ANY_MOTION_SIGN__MSK (0x08)
+#define BMI160_USER_INTR_STAT_2_ANY_MOTION_SIGN__REG \
+ (BMI160_USER_INTR_STAT_2_ADDR)
+/**************************************************************/
+/**\name TAP_XYZ AND SIGN LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 4 */
+#define BMI160_USER_INTR_STAT_2_TAP_FIRST_X__POS (4)
+#define BMI160_USER_INTR_STAT_2_TAP_FIRST_X__LEN (1)
+#define BMI160_USER_INTR_STAT_2_TAP_FIRST_X__MSK (0x10)
+#define BMI160_USER_INTR_STAT_2_TAP_FIRST_X__REG \
+ (BMI160_USER_INTR_STAT_2_ADDR)
+
+/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 5 */
+#define BMI160_USER_INTR_STAT_2_TAP_FIRST_Y__POS (5)
+#define BMI160_USER_INTR_STAT_2_TAP_FIRST_Y__LEN (1)
+#define BMI160_USER_INTR_STAT_2_TAP_FIRST_Y__MSK (0x20)
+#define BMI160_USER_INTR_STAT_2_TAP_FIRST_Y__REG \
+ (BMI160_USER_INTR_STAT_2_ADDR)
+
+/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 6 */
+#define BMI160_USER_INTR_STAT_2_TAP_FIRST_Z__POS (6)
+#define BMI160_USER_INTR_STAT_2_TAP_FIRST_Z__LEN (1)
+#define BMI160_USER_INTR_STAT_2_TAP_FIRST_Z__MSK (0x40)
+#define BMI160_USER_INTR_STAT_2_TAP_FIRST_Z__REG \
+ (BMI160_USER_INTR_STAT_2_ADDR)
+
+/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 7 */
+#define BMI160_USER_INTR_STAT_2_TAP_SIGN__POS (7)
+#define BMI160_USER_INTR_STAT_2_TAP_SIGN__LEN (1)
+#define BMI160_USER_INTR_STAT_2_TAP_SIGN__MSK (0x80)
+#define BMI160_USER_INTR_STAT_2_TAP_SIGN__REG \
+ (BMI160_USER_INTR_STAT_2_ADDR)
+/**************************************************************/
+/**\name INTERRUPT SATAUS FOR WHOLE 0x1E LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 0...7 */
+#define BMI160_USER_INTR_STAT_2__POS (0)
+#define BMI160_USER_INTR_STAT_2__LEN (8)
+#define BMI160_USER_INTR_STAT_2__MSK (0xFF)
+#define BMI160_USER_INTR_STAT_2__REG \
+ (BMI160_USER_INTR_STAT_2_ADDR)
+/**************************************************************/
+/**\name HIGH_G-XYZ AND SIGN LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_3 Description - Reg Addr --> (0x1F), Bit --> 0 */
+#define BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_X__POS (0)
+#define BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_X__LEN (1)
+#define BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_X__MSK (0x01)
+#define BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_X__REG \
+ (BMI160_USER_INTR_STAT_3_ADDR)
+
+/* Int_Status_3 Description - Reg Addr --> 0x1E, Bit --> 1 */
+#define BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_Y__POS (1)
+#define BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_Y__LEN (1)
+#define BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_Y__MSK (0x02)
+#define BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_Y__REG \
+ (BMI160_USER_INTR_STAT_3_ADDR)
+
+/* Int_Status_3 Description - Reg Addr --> (0x1F), Bit --> 2 */
+#define BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_Z__POS (2)
+#define BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_Z__LEN (1)
+#define BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_Z__MSK (0x04)
+#define BMI160_USER_INTR_STAT_3_HIGH_G_FIRST_Z__REG \
+ (BMI160_USER_INTR_STAT_3_ADDR)
+
+/* Int_Status_3 Description - Reg Addr --> (0x1F), Bit --> 3 */
+#define BMI160_USER_INTR_STAT_3_HIGH_G_SIGN__POS (3)
+#define BMI160_USER_INTR_STAT_3_HIGH_G_SIGN__LEN (1)
+#define BMI160_USER_INTR_STAT_3_HIGH_G_SIGN__MSK (0x08)
+#define BMI160_USER_INTR_STAT_3_HIGH_G_SIGN__REG \
+ (BMI160_USER_INTR_STAT_3_ADDR)
+/**************************************************************/
+/**\name ORIENT XY and Z AXIS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_3 Description - Reg Addr --> (0x1F), Bit --> 4...5 */
+#define BMI160_USER_INTR_STAT_3_ORIENT_XY__POS (4)
+#define BMI160_USER_INTR_STAT_3_ORIENT_XY__LEN (2)
+#define BMI160_USER_INTR_STAT_3_ORIENT_XY__MSK (0x30)
+#define BMI160_USER_INTR_STAT_3_ORIENT_XY__REG \
+ (BMI160_USER_INTR_STAT_3_ADDR)
+
+/* Int_Status_3 Description - Reg Addr --> (0x1F), Bit --> 6 */
+#define BMI160_USER_INTR_STAT_3_ORIENT_Z__POS (6)
+#define BMI160_USER_INTR_STAT_3_ORIENT_Z__LEN (1)
+#define BMI160_USER_INTR_STAT_3_ORIENT_Z__MSK (0x40)
+#define BMI160_USER_INTR_STAT_3_ORIENT_Z__REG \
+ (BMI160_USER_INTR_STAT_3_ADDR)
+/**************************************************************/
+/**\name FLAT LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_3 Description - Reg Addr --> (0x1F), Bit --> 7 */
+#define BMI160_USER_INTR_STAT_3_FLAT__POS (7)
+#define BMI160_USER_INTR_STAT_3_FLAT__LEN (1)
+#define BMI160_USER_INTR_STAT_3_FLAT__MSK (0x80)
+#define BMI160_USER_INTR_STAT_3_FLAT__REG \
+ (BMI160_USER_INTR_STAT_3_ADDR)
+/**************************************************************/
+/**\name (0x1F) LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_3 Description - Reg Addr --> (0x1F), Bit --> 0...7 */
+#define BMI160_USER_INTR_STAT_3__POS (0)
+#define BMI160_USER_INTR_STAT_3__LEN (8)
+#define BMI160_USER_INTR_STAT_3__MSK (0xFF)
+#define BMI160_USER_INTR_STAT_3__REG \
+ (BMI160_USER_INTR_STAT_3_ADDR)
+/**************************************************************/
+/**\name TEMPERATURE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Temperature Description - LSB Reg Addr --> (0x20), Bit --> 0...7 */
+#define BMI160_USER_TEMP_LSB_VALUE__POS (0)
+#define BMI160_USER_TEMP_LSB_VALUE__LEN (8)
+#define BMI160_USER_TEMP_LSB_VALUE__MSK (0xFF)
+#define BMI160_USER_TEMP_LSB_VALUE__REG \
+ (BMI160_USER_TEMPERATURE_0_ADDR)
+
+/* Temperature Description - LSB Reg Addr --> 0x21, Bit --> 0...7 */
+#define BMI160_USER_TEMP_MSB_VALUE__POS (0)
+#define BMI160_USER_TEMP_MSB_VALUE__LEN (8)
+#define BMI160_USER_TEMP_MSB_VALUE__MSK (0xFF)
+#define BMI160_USER_TEMP_MSB_VALUE__REG \
+ (BMI160_USER_TEMPERATURE_1_ADDR)
+/**************************************************************/
+/**\name FIFO BYTE COUNTER LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Length0 Description - Reg Addr --> 0x22, Bit --> 0...7 */
+#define BMI160_USER_FIFO_BYTE_COUNTER_LSB__POS (0)
+#define BMI160_USER_FIFO_BYTE_COUNTER_LSB__LEN (8)
+#define BMI160_USER_FIFO_BYTE_COUNTER_LSB__MSK (0xFF)
+#define BMI160_USER_FIFO_BYTE_COUNTER_LSB__REG \
+ (BMI160_USER_FIFO_LENGTH_0_ADDR)
+
+/*Fifo_Length1 Description - Reg Addr --> 0x23, Bit --> 0...2 */
+#define BMI160_USER_FIFO_BYTE_COUNTER_MSB__POS (0)
+#define BMI160_USER_FIFO_BYTE_COUNTER_MSB__LEN 3
+#define BMI160_USER_FIFO_BYTE_COUNTER_MSB__MSK (0x07)
+#define BMI160_USER_FIFO_BYTE_COUNTER_MSB__REG \
+ (BMI160_USER_FIFO_LENGTH_1_ADDR)
+
+/**************************************************************/
+/**\name FIFO DATA LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Data Description - Reg Addr --> 0x24, Bit --> 0...7 */
+#define BMI160_USER_FIFO_DATA__POS (0)
+#define BMI160_USER_FIFO_DATA__LEN (8)
+#define BMI160_USER_FIFO_DATA__MSK (0xFF)
+#define BMI160_USER_FIFO_DATA__REG (BMI160_USER_FIFO_DATA_ADDR)
+
+/**************************************************************/
+/**\name ACCEL CONFIGURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Acc_Conf Description - Reg Addr --> (0x40), Bit --> 0...3 */
+#define BMI160_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE__POS (0)
+#define BMI160_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE__LEN (4)
+#define BMI160_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE__MSK (0x0F)
+#define BMI160_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE__REG \
+(BMI160_USER_ACCEL_CONFIG_ADDR)
+
+/* Acc_Conf Description - Reg Addr --> (0x40), Bit --> 4...6 */
+#define BMI160_USER_ACCEL_CONFIG_ACCEL_BW__POS (4)
+#define BMI160_USER_ACCEL_CONFIG_ACCEL_BW__LEN (3)
+#define BMI160_USER_ACCEL_CONFIG_ACCEL_BW__MSK (0x70)
+#define BMI160_USER_ACCEL_CONFIG_ACCEL_BW__REG (BMI160_USER_ACCEL_CONFIG_ADDR)
+
+/* Acc_Conf Description - Reg Addr --> (0x40), Bit --> 7 */
+#define BMI160_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING__POS (7)
+#define BMI160_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING__LEN (1)
+#define BMI160_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING__MSK (0x80)
+#define BMI160_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING__REG \
+(BMI160_USER_ACCEL_CONFIG_ADDR)
+
+/* Acc_Range Description - Reg Addr --> 0x41, Bit --> 0...3 */
+#define BMI160_USER_ACCEL_RANGE__POS (0)
+#define BMI160_USER_ACCEL_RANGE__LEN (4)
+#define BMI160_USER_ACCEL_RANGE__MSK (0x0F)
+#define BMI160_USER_ACCEL_RANGE__REG \
+(BMI160_USER_ACCEL_RANGE_ADDR)
+/**************************************************************/
+/**\name GYRO CONFIGURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Gyro_Conf Description - Reg Addr --> (0x42), Bit --> 0...3 */
+#define BMI160_USER_GYRO_CONFIG_OUTPUT_DATA_RATE__POS (0)
+#define BMI160_USER_GYRO_CONFIG_OUTPUT_DATA_RATE__LEN (4)
+#define BMI160_USER_GYRO_CONFIG_OUTPUT_DATA_RATE__MSK (0x0F)
+#define BMI160_USER_GYRO_CONFIG_OUTPUT_DATA_RATE__REG \
+(BMI160_USER_GYRO_CONFIG_ADDR)
+
+/* Gyro_Conf Description - Reg Addr --> (0x42), Bit --> 4...5 */
+#define BMI160_USER_GYRO_CONFIG_BW__POS (4)
+#define BMI160_USER_GYRO_CONFIG_BW__LEN (2)
+#define BMI160_USER_GYRO_CONFIG_BW__MSK (0x30)
+#define BMI160_USER_GYRO_CONFIG_BW__REG \
+(BMI160_USER_GYRO_CONFIG_ADDR)
+
+/* Gyr_Range Description - Reg Addr --> 0x43, Bit --> 0...2 */
+#define BMI160_USER_GYRO_RANGE__POS (0)
+#define BMI160_USER_GYRO_RANGE__LEN (3)
+#define BMI160_USER_GYRO_RANGE__MSK (0x07)
+#define BMI160_USER_GYRO_RANGE__REG (BMI160_USER_GYRO_RANGE_ADDR)
+/**************************************************************/
+/**\name MAG CONFIGURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Mag_Conf Description - Reg Addr --> (0x44), Bit --> 0...3 */
+#define BMI160_USER_MAG_CONFIG_OUTPUT_DATA_RATE__POS (0)
+#define BMI160_USER_MAG_CONFIG_OUTPUT_DATA_RATE__LEN (4)
+#define BMI160_USER_MAG_CONFIG_OUTPUT_DATA_RATE__MSK (0x0F)
+#define BMI160_USER_MAG_CONFIG_OUTPUT_DATA_RATE__REG \
+(BMI160_USER_MAG_CONFIG_ADDR)
+/**************************************************************/
+/**\name FIFO DOWNS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Downs Description - Reg Addr --> 0x45, Bit --> 0...2 */
+#define BMI160_USER_FIFO_DOWN_GYRO__POS (0)
+#define BMI160_USER_FIFO_DOWN_GYRO__LEN (3)
+#define BMI160_USER_FIFO_DOWN_GYRO__MSK (0x07)
+#define BMI160_USER_FIFO_DOWN_GYRO__REG (BMI160_USER_FIFO_DOWN_ADDR)
+/**************************************************************/
+/**\name FIFO FILTER FOR ACCEL AND GYRO LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_filt Description - Reg Addr --> 0x45, Bit --> 3 */
+#define BMI160_USER_FIFO_FILTER_GYRO__POS (3)
+#define BMI160_USER_FIFO_FILTER_GYRO__LEN (1)
+#define BMI160_USER_FIFO_FILTER_GYRO__MSK (0x08)
+#define BMI160_USER_FIFO_FILTER_GYRO__REG (BMI160_USER_FIFO_DOWN_ADDR)
+
+/* Fifo_Downs Description - Reg Addr --> 0x45, Bit --> 4...6 */
+#define BMI160_USER_FIFO_DOWN_ACCEL__POS (4)
+#define BMI160_USER_FIFO_DOWN_ACCEL__LEN (3)
+#define BMI160_USER_FIFO_DOWN_ACCEL__MSK (0x70)
+#define BMI160_USER_FIFO_DOWN_ACCEL__REG (BMI160_USER_FIFO_DOWN_ADDR)
+
+/* Fifo_FILT Description - Reg Addr --> 0x45, Bit --> 7 */
+#define BMI160_USER_FIFO_FILTER_ACCEL__POS (7)
+#define BMI160_USER_FIFO_FILTER_ACCEL__LEN (1)
+#define BMI160_USER_FIFO_FILTER_ACCEL__MSK (0x80)
+#define BMI160_USER_FIFO_FILTER_ACCEL__REG (BMI160_USER_FIFO_DOWN_ADDR)
+/**************************************************************/
+/**\name FIFO WATER MARK LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Config_0 Description - Reg Addr --> 0x46, Bit --> 0...7 */
+#define BMI160_USER_FIFO_WM__POS (0)
+#define BMI160_USER_FIFO_WM__LEN (8)
+#define BMI160_USER_FIFO_WM__MSK (0xFF)
+#define BMI160_USER_FIFO_WM__REG (BMI160_USER_FIFO_CONFIG_0_ADDR)
+/**************************************************************/
+/**\name FIFO TIME LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Config_1 Description - Reg Addr --> 0x47, Bit --> 1 */
+#define BMI160_USER_FIFO_TIME_ENABLE__POS (1)
+#define BMI160_USER_FIFO_TIME_ENABLE__LEN (1)
+#define BMI160_USER_FIFO_TIME_ENABLE__MSK (0x02)
+#define BMI160_USER_FIFO_TIME_ENABLE__REG (BMI160_USER_FIFO_CONFIG_1_ADDR)
+/**************************************************************/
+/**\name FIFO TAG INTERRUPT LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Config_1 Description - Reg Addr --> 0x47, Bit --> 2 */
+#define BMI160_USER_FIFO_TAG_INTR2_ENABLE__POS (2)
+#define BMI160_USER_FIFO_TAG_INTR2_ENABLE__LEN (1)
+#define BMI160_USER_FIFO_TAG_INTR2_ENABLE__MSK (0x04)
+#define BMI160_USER_FIFO_TAG_INTR2_ENABLE__REG (BMI160_USER_FIFO_CONFIG_1_ADDR)
+
+/* Fifo_Config_1 Description - Reg Addr --> 0x47, Bit --> 3 */
+#define BMI160_USER_FIFO_TAG_INTR1_ENABLE__POS (3)
+#define BMI160_USER_FIFO_TAG_INTR1_ENABLE__LEN (1)
+#define BMI160_USER_FIFO_TAG_INTR1_ENABLE__MSK (0x08)
+#define BMI160_USER_FIFO_TAG_INTR1_ENABLE__REG (BMI160_USER_FIFO_CONFIG_1_ADDR)
+/**************************************************************/
+/**\name FIFO HEADER LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Config_1 Description - Reg Addr --> 0x47, Bit --> 4 */
+#define BMI160_USER_FIFO_HEADER_ENABLE__POS (4)
+#define BMI160_USER_FIFO_HEADER_ENABLE__LEN (1)
+#define BMI160_USER_FIFO_HEADER_ENABLE__MSK (0x10)
+#define BMI160_USER_FIFO_HEADER_ENABLE__REG \
+(BMI160_USER_FIFO_CONFIG_1_ADDR)
+/**************************************************************/
+/**\name FIFO MAG ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Config_1 Description - Reg Addr --> 0x47, Bit --> 5 */
+#define BMI160_USER_FIFO_MAG_ENABLE__POS (5)
+#define BMI160_USER_FIFO_MAG_ENABLE__LEN (1)
+#define BMI160_USER_FIFO_MAG_ENABLE__MSK (0x20)
+#define BMI160_USER_FIFO_MAG_ENABLE__REG \
+(BMI160_USER_FIFO_CONFIG_1_ADDR)
+/**************************************************************/
+/**\name FIFO ACCEL ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Config_1 Description - Reg Addr --> 0x47, Bit --> 6 */
+#define BMI160_USER_FIFO_ACCEL_ENABLE__POS (6)
+#define BMI160_USER_FIFO_ACCEL_ENABLE__LEN (1)
+#define BMI160_USER_FIFO_ACCEL_ENABLE__MSK (0x40)
+#define BMI160_USER_FIFO_ACCEL_ENABLE__REG \
+(BMI160_USER_FIFO_CONFIG_1_ADDR)
+/**************************************************************/
+/**\name FIFO GYRO ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Config_1 Description - Reg Addr --> 0x47, Bit --> 7 */
+#define BMI160_USER_FIFO_GYRO_ENABLE__POS (7)
+#define BMI160_USER_FIFO_GYRO_ENABLE__LEN (1)
+#define BMI160_USER_FIFO_GYRO_ENABLE__MSK (0x80)
+#define BMI160_USER_FIFO_GYRO_ENABLE__REG \
+(BMI160_USER_FIFO_CONFIG_1_ADDR)
+
+/**************************************************************/
+/**\name MAG I2C ADDRESS SELECTION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+
+/* Mag_IF_0 Description - Reg Addr --> 0x4b, Bit --> 1...7 */
+#define BMI160_USER_I2C_DEVICE_ADDR__POS (1)
+#define BMI160_USER_I2C_DEVICE_ADDR__LEN (7)
+#define BMI160_USER_I2C_DEVICE_ADDR__MSK (0xFE)
+#define BMI160_USER_I2C_DEVICE_ADDR__REG (BMI160_USER_MAG_IF_0_ADDR)
+/**************************************************************/
+/**\name MAG CONFIGURATION FOR SECONDARY
+ INTERFACE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Mag_IF_1 Description - Reg Addr --> 0x4c, Bit --> 0...1 */
+#define BMI160_USER_MAG_BURST__POS (0)
+#define BMI160_USER_MAG_BURST__LEN (2)
+#define BMI160_USER_MAG_BURST__MSK (0x03)
+#define BMI160_USER_MAG_BURST__REG (BMI160_USER_MAG_IF_1_ADDR)
+
+/* Mag_IF_1 Description - Reg Addr --> 0x4c, Bit --> 2...5 */
+#define BMI160_USER_MAG_OFFSET__POS (2)
+#define BMI160_USER_MAG_OFFSET__LEN (4)
+#define BMI160_USER_MAG_OFFSET__MSK (0x3C)
+#define BMI160_USER_MAG_OFFSET__REG (BMI160_USER_MAG_IF_1_ADDR)
+
+/* Mag_IF_1 Description - Reg Addr --> 0x4c, Bit --> 7 */
+#define BMI160_USER_MAG_MANUAL_ENABLE__POS (7)
+#define BMI160_USER_MAG_MANUAL_ENABLE__LEN (1)
+#define BMI160_USER_MAG_MANUAL_ENABLE__MSK (0x80)
+#define BMI160_USER_MAG_MANUAL_ENABLE__REG \
+(BMI160_USER_MAG_IF_1_ADDR)
+
+/* Mag_IF_2 Description - Reg Addr --> 0x4d, Bit -->0... 7 */
+#define BMI160_USER_READ_ADDR__POS (0)
+#define BMI160_USER_READ_ADDR__LEN (8)
+#define BMI160_USER_READ_ADDR__MSK (0xFF)
+#define BMI160_USER_READ_ADDR__REG (BMI160_USER_MAG_IF_2_ADDR)
+
+/* Mag_IF_3 Description - Reg Addr --> 0x4e, Bit -->0... 7 */
+#define BMI160_USER_WRITE_ADDR__POS (0)
+#define BMI160_USER_WRITE_ADDR__LEN (8)
+#define BMI160_USER_WRITE_ADDR__MSK (0xFF)
+#define BMI160_USER_WRITE_ADDR__REG (BMI160_USER_MAG_IF_3_ADDR)
+
+/* Mag_IF_4 Description - Reg Addr --> 0x4f, Bit -->0... 7 */
+#define BMI160_USER_WRITE_DATA__POS (0)
+#define BMI160_USER_WRITE_DATA__LEN (8)
+#define BMI160_USER_WRITE_DATA__MSK (0xFF)
+#define BMI160_USER_WRITE_DATA__REG (BMI160_USER_MAG_IF_4_ADDR)
+/**************************************************************/
+/**\name ANY MOTION XYZ AXIS ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_0 Description - Reg Addr --> 0x50, Bit -->0 */
+#define BMI160_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE__POS (0)
+#define BMI160_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE__LEN (1)
+#define BMI160_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE__MSK (0x01)
+#define BMI160_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE__REG \
+(BMI160_USER_INTR_ENABLE_0_ADDR)
+
+/* Int_En_0 Description - Reg Addr --> 0x50, Bit -->1 */
+#define BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE__POS (1)
+#define BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE__LEN (1)
+#define BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE__MSK (0x02)
+#define BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE__REG \
+(BMI160_USER_INTR_ENABLE_0_ADDR)
+
+/* Int_En_0 Description - Reg Addr --> 0x50, Bit -->2 */
+#define BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE__POS (2)
+#define BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE__LEN (1)
+#define BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE__MSK (0x04)
+#define BMI160_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE__REG \
+(BMI160_USER_INTR_ENABLE_0_ADDR)
+/**************************************************************/
+/**\name DOUBLE TAP ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_0 Description - Reg Addr --> 0x50, Bit -->4 */
+#define BMI160_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE__POS (4)
+#define BMI160_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE__LEN (1)
+#define BMI160_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE__MSK (0x10)
+#define BMI160_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE__REG \
+(BMI160_USER_INTR_ENABLE_0_ADDR)
+/**************************************************************/
+/**\name SINGLE TAP ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_0 Description - Reg Addr --> 0x50, Bit -->5 */
+#define BMI160_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE__POS (5)
+#define BMI160_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE__LEN (1)
+#define BMI160_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE__MSK (0x20)
+#define BMI160_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE__REG \
+(BMI160_USER_INTR_ENABLE_0_ADDR)
+/**************************************************************/
+/**\name ORIENT ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_0 Description - Reg Addr --> 0x50, Bit -->6 */
+#define BMI160_USER_INTR_ENABLE_0_ORIENT_ENABLE__POS (6)
+#define BMI160_USER_INTR_ENABLE_0_ORIENT_ENABLE__LEN (1)
+#define BMI160_USER_INTR_ENABLE_0_ORIENT_ENABLE__MSK (0x40)
+#define BMI160_USER_INTR_ENABLE_0_ORIENT_ENABLE__REG \
+(BMI160_USER_INTR_ENABLE_0_ADDR)
+/**************************************************************/
+/**\name FLAT ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_0 Description - Reg Addr --> 0x50, Bit -->7 */
+#define BMI160_USER_INTR_ENABLE_0_FLAT_ENABLE__POS (7)
+#define BMI160_USER_INTR_ENABLE_0_FLAT_ENABLE__LEN (1)
+#define BMI160_USER_INTR_ENABLE_0_FLAT_ENABLE__MSK (0x80)
+#define BMI160_USER_INTR_ENABLE_0_FLAT_ENABLE__REG \
+(BMI160_USER_INTR_ENABLE_0_ADDR)
+/**************************************************************/
+/**\name HIGH_G XYZ ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_1 Description - Reg Addr --> (0x51), Bit -->0 */
+#define BMI160_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE__POS (0)
+#define BMI160_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE__LEN (1)
+#define BMI160_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE__MSK (0x01)
+#define BMI160_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE__REG \
+(BMI160_USER_INTR_ENABLE_1_ADDR)
+
+/* Int_En_1 Description - Reg Addr --> (0x51), Bit -->1 */
+#define BMI160_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE__POS (1)
+#define BMI160_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE__LEN (1)
+#define BMI160_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE__MSK (0x02)
+#define BMI160_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE__REG \
+(BMI160_USER_INTR_ENABLE_1_ADDR)
+
+/* Int_En_1 Description - Reg Addr --> (0x51), Bit -->2 */
+#define BMI160_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE__POS (2)
+#define BMI160_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE__LEN (1)
+#define BMI160_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE__MSK (0x04)
+#define BMI160_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE__REG \
+(BMI160_USER_INTR_ENABLE_1_ADDR)
+/**************************************************************/
+/**\name LOW_G ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_1 Description - Reg Addr --> (0x51), Bit -->3 */
+#define BMI160_USER_INTR_ENABLE_1_LOW_G_ENABLE__POS (3)
+#define BMI160_USER_INTR_ENABLE_1_LOW_G_ENABLE__LEN (1)
+#define BMI160_USER_INTR_ENABLE_1_LOW_G_ENABLE__MSK (0x08)
+#define BMI160_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG \
+(BMI160_USER_INTR_ENABLE_1_ADDR)
+/**************************************************************/
+/**\name DATA READY ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_1 Description - Reg Addr --> (0x51), Bit -->4 */
+#define BMI160_USER_INTR_ENABLE_1_DATA_RDY_ENABLE__POS (4)
+#define BMI160_USER_INTR_ENABLE_1_DATA_RDY_ENABLE__LEN (1)
+#define BMI160_USER_INTR_ENABLE_1_DATA_RDY_ENABLE__MSK (0x10)
+#define BMI160_USER_INTR_ENABLE_1_DATA_RDY_ENABLE__REG \
+(BMI160_USER_INTR_ENABLE_1_ADDR)
+/**************************************************************/
+/**\name FIFO FULL AND WATER MARK ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_1 Description - Reg Addr --> (0x51), Bit -->5 */
+#define BMI160_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE__POS (5)
+#define BMI160_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE__LEN (1)
+#define BMI160_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE__MSK (0x20)
+#define BMI160_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE__REG \
+(BMI160_USER_INTR_ENABLE_1_ADDR)
+
+/* Int_En_1 Description - Reg Addr --> (0x51), Bit -->6 */
+#define BMI160_USER_INTR_ENABLE_1_FIFO_WM_ENABLE__POS (6)
+#define BMI160_USER_INTR_ENABLE_1_FIFO_WM_ENABLE__LEN (1)
+#define BMI160_USER_INTR_ENABLE_1_FIFO_WM_ENABLE__MSK (0x40)
+#define BMI160_USER_INTR_ENABLE_1_FIFO_WM_ENABLE__REG \
+(BMI160_USER_INTR_ENABLE_1_ADDR)
+/**************************************************************/
+/**\name NO MOTION XYZ ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_2 Description - Reg Addr --> (0x52), Bit -->0 */
+#define BMI160_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE__POS (0)
+#define BMI160_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE__LEN (1)
+#define BMI160_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE__MSK (0x01)
+#define BMI160_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE__REG \
+(BMI160_USER_INTR_ENABLE_2_ADDR)
+
+/* Int_En_2 Description - Reg Addr --> (0x52), Bit -->1 */
+#define BMI160_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE__POS (1)
+#define BMI160_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE__LEN (1)
+#define BMI160_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE__MSK (0x02)
+#define BMI160_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE__REG \
+(BMI160_USER_INTR_ENABLE_2_ADDR)
+
+/* Int_En_2 Description - Reg Addr --> (0x52), Bit -->2 */
+#define BMI160_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE__POS (2)
+#define BMI160_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE__LEN (1)
+#define BMI160_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE__MSK (0x04)
+#define BMI160_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE__REG \
+(BMI160_USER_INTR_ENABLE_2_ADDR)
+/**************************************************************/
+/**\name STEP DETECTOR ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_2 Description - Reg Addr --> (0x52), Bit -->3 */
+#define BMI160_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE__POS (3)
+#define BMI160_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE__LEN (1)
+#define BMI160_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE__MSK (0x08)
+#define BMI160_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE__REG \
+(BMI160_USER_INTR_ENABLE_2_ADDR)
+/**************************************************************/
+/**\name EDGE CONTROL ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->0 */
+#define BMI160_USER_INTR1_EDGE_CTRL__POS (0)
+#define BMI160_USER_INTR1_EDGE_CTRL__LEN (1)
+#define BMI160_USER_INTR1_EDGE_CTRL__MSK (0x01)
+#define BMI160_USER_INTR1_EDGE_CTRL__REG \
+(BMI160_USER_INTR_OUT_CTRL_ADDR)
+/**************************************************************/
+/**\name LEVEL CONTROL ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->1 */
+#define BMI160_USER_INTR1_LEVEL__POS (1)
+#define BMI160_USER_INTR1_LEVEL__LEN (1)
+#define BMI160_USER_INTR1_LEVEL__MSK (0x02)
+#define BMI160_USER_INTR1_LEVEL__REG \
+(BMI160_USER_INTR_OUT_CTRL_ADDR)
+/**************************************************************/
+/**\name OUTPUT TYPE ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->2 */
+#define BMI160_USER_INTR1_OUTPUT_TYPE__POS (2)
+#define BMI160_USER_INTR1_OUTPUT_TYPE__LEN (1)
+#define BMI160_USER_INTR1_OUTPUT_TYPE__MSK (0x04)
+#define BMI160_USER_INTR1_OUTPUT_TYPE__REG \
+(BMI160_USER_INTR_OUT_CTRL_ADDR)
+/**************************************************************/
+/**\name OUTPUT TYPE ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->3 */
+#define BMI160_USER_INTR1_OUTPUT_ENABLE__POS (3)
+#define BMI160_USER_INTR1_OUTPUT_ENABLE__LEN (1)
+#define BMI160_USER_INTR1_OUTPUT_ENABLE__MSK (0x08)
+#define BMI160_USER_INTR1_OUTPUT_ENABLE__REG \
+(BMI160_USER_INTR_OUT_CTRL_ADDR)
+/**************************************************************/
+/**\name EDGE CONTROL ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->4 */
+#define BMI160_USER_INTR2_EDGE_CTRL__POS (4)
+#define BMI160_USER_INTR2_EDGE_CTRL__LEN (1)
+#define BMI160_USER_INTR2_EDGE_CTRL__MSK (0x10)
+#define BMI160_USER_INTR2_EDGE_CTRL__REG \
+(BMI160_USER_INTR_OUT_CTRL_ADDR)
+/**************************************************************/
+/**\name LEVEL CONTROL ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->5 */
+#define BMI160_USER_INTR2_LEVEL__POS (5)
+#define BMI160_USER_INTR2_LEVEL__LEN (1)
+#define BMI160_USER_INTR2_LEVEL__MSK (0x20)
+#define BMI160_USER_INTR2_LEVEL__REG \
+(BMI160_USER_INTR_OUT_CTRL_ADDR)
+/**************************************************************/
+/**\name OUTPUT TYPE ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->6 */
+#define BMI160_USER_INTR2_OUTPUT_TYPE__POS (6)
+#define BMI160_USER_INTR2_OUTPUT_TYPE__LEN (1)
+#define BMI160_USER_INTR2_OUTPUT_TYPE__MSK (0x40)
+#define BMI160_USER_INTR2_OUTPUT_TYPE__REG \
+(BMI160_USER_INTR_OUT_CTRL_ADDR)
+
+/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->7 */
+#define BMI160_USER_INTR2_OUTPUT_EN__POS (7)
+#define BMI160_USER_INTR2_OUTPUT_EN__LEN (1)
+#define BMI160_USER_INTR2_OUTPUT_EN__MSK (0x80)
+#define BMI160_USER_INTR2_OUTPUT_EN__REG \
+(BMI160_USER_INTR_OUT_CTRL_ADDR)
+/**************************************************************/
+/**\name LATCH INTERRUPT LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Latch Description - Reg Addr --> 0x54, Bit -->0...3 */
+#define BMI160_USER_INTR_LATCH__POS (0)
+#define BMI160_USER_INTR_LATCH__LEN (4)
+#define BMI160_USER_INTR_LATCH__MSK (0x0F)
+#define BMI160_USER_INTR_LATCH__REG (BMI160_USER_INTR_LATCH_ADDR)
+/**************************************************************/
+/**\name INPUT ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Latch Description - Reg Addr --> 0x54, Bit -->4 */
+#define BMI160_USER_INTR1_INPUT_ENABLE__POS (4)
+#define BMI160_USER_INTR1_INPUT_ENABLE__LEN (1)
+#define BMI160_USER_INTR1_INPUT_ENABLE__MSK (0x10)
+#define BMI160_USER_INTR1_INPUT_ENABLE__REG \
+(BMI160_USER_INTR_LATCH_ADDR)
+
+/* Int_Latch Description - Reg Addr --> 0x54, Bit -->5*/
+#define BMI160_USER_INTR2_INPUT_ENABLE__POS (5)
+#define BMI160_USER_INTR2_INPUT_ENABLE__LEN (1)
+#define BMI160_USER_INTR2_INPUT_ENABLE__MSK (0x20)
+#define BMI160_USER_INTR2_INPUT_ENABLE__REG \
+(BMI160_USER_INTR_LATCH_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF LOW_G LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_0 Description - Reg Addr --> 0x55, Bit -->0 */
+#define BMI160_USER_INTR_MAP_0_INTR1_LOW_G__POS (0)
+#define BMI160_USER_INTR_MAP_0_INTR1_LOW_G__LEN (1)
+#define BMI160_USER_INTR_MAP_0_INTR1_LOW_G__MSK (0x01)
+#define BMI160_USER_INTR_MAP_0_INTR1_LOW_G__REG (BMI160_USER_INTR_MAP_0_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF HIGH_G LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_0 Description - Reg Addr --> 0x55, Bit -->1 */
+#define BMI160_USER_INTR_MAP_0_INTR1_HIGH_G__POS (1)
+#define BMI160_USER_INTR_MAP_0_INTR1_HIGH_G__LEN (1)
+#define BMI160_USER_INTR_MAP_0_INTR1_HIGH_G__MSK (0x02)
+#define BMI160_USER_INTR_MAP_0_INTR1_HIGH_G__REG \
+(BMI160_USER_INTR_MAP_0_ADDR)
+/**************************************************************/
+/**\name INTERRUPT MAPPIONG OF ANY MOTION_G LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_0 Description - Reg Addr --> 0x55, Bit -->2 */
+#define BMI160_USER_INTR_MAP_0_INTR1_ANY_MOTION__POS (2)
+#define BMI160_USER_INTR_MAP_0_INTR1_ANY_MOTION__LEN (1)
+#define BMI160_USER_INTR_MAP_0_INTR1_ANY_MOTION__MSK (0x04)
+#define BMI160_USER_INTR_MAP_0_INTR1_ANY_MOTION__REG \
+(BMI160_USER_INTR_MAP_0_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF NO MOTION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_0 Description - Reg Addr --> 0x55, Bit -->3 */
+#define BMI160_USER_INTR_MAP_0_INTR1_NOMOTION__POS (3)
+#define BMI160_USER_INTR_MAP_0_INTR1_NOMOTION__LEN (1)
+#define BMI160_USER_INTR_MAP_0_INTR1_NOMOTION__MSK (0x08)
+#define BMI160_USER_INTR_MAP_0_INTR1_NOMOTION__REG (BMI160_USER_INTR_MAP_0_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF DOUBLE TAP LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_0 Description - Reg Addr --> 0x55, Bit -->4 */
+#define BMI160_USER_INTR_MAP_0_INTR1_DOUBLE_TAP__POS (4)
+#define BMI160_USER_INTR_MAP_0_INTR1_DOUBLE_TAP__LEN (1)
+#define BMI160_USER_INTR_MAP_0_INTR1_DOUBLE_TAP__MSK (0x10)
+#define BMI160_USER_INTR_MAP_0_INTR1_DOUBLE_TAP__REG \
+(BMI160_USER_INTR_MAP_0_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF SINGLE TAP LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_0 Description - Reg Addr --> 0x55, Bit -->5 */
+#define BMI160_USER_INTR_MAP_0_INTR1_SINGLE_TAP__POS (5)
+#define BMI160_USER_INTR_MAP_0_INTR1_SINGLE_TAP__LEN (1)
+#define BMI160_USER_INTR_MAP_0_INTR1_SINGLE_TAP__MSK (0x20)
+#define BMI160_USER_INTR_MAP_0_INTR1_SINGLE_TAP__REG \
+(BMI160_USER_INTR_MAP_0_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF ORIENT LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_0 Description - Reg Addr --> 0x55, Bit -->6 */
+#define BMI160_USER_INTR_MAP_0_INTR1_ORIENT__POS (6)
+#define BMI160_USER_INTR_MAP_0_INTR1_ORIENT__LEN (1)
+#define BMI160_USER_INTR_MAP_0_INTR1_ORIENT__MSK (0x40)
+#define BMI160_USER_INTR_MAP_0_INTR1_ORIENT__REG \
+(BMI160_USER_INTR_MAP_0_ADDR)
+/**************************************************************/
+/**\name INTERRUPT MAPPIONG OF FLAT LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_0 Description - Reg Addr --> 0x56, Bit -->7 */
+#define BMI160_USER_INTR_MAP_0_INTR1_FLAT__POS (7)
+#define BMI160_USER_INTR_MAP_0_INTR1_FLAT__LEN (1)
+#define BMI160_USER_INTR_MAP_0_INTR1_FLAT__MSK (0x80)
+#define BMI160_USER_INTR_MAP_0_INTR1_FLAT__REG (BMI160_USER_INTR_MAP_0_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF PMU TRIGGER LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->0 */
+#define BMI160_USER_INTR_MAP_1_INTR2_PMU_TRIG__POS (0)
+#define BMI160_USER_INTR_MAP_1_INTR2_PMU_TRIG__LEN (1)
+#define BMI160_USER_INTR_MAP_1_INTR2_PMU_TRIG__MSK (0x01)
+#define BMI160_USER_INTR_MAP_1_INTR2_PMU_TRIG__REG (BMI160_USER_INTR_MAP_1_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF FIFO FULL AND
+ WATER MARK LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->1 */
+#define BMI160_USER_INTR_MAP_1_INTR2_FIFO_FULL__POS (1)
+#define BMI160_USER_INTR_MAP_1_INTR2_FIFO_FULL__LEN (1)
+#define BMI160_USER_INTR_MAP_1_INTR2_FIFO_FULL__MSK (0x02)
+#define BMI160_USER_INTR_MAP_1_INTR2_FIFO_FULL__REG \
+(BMI160_USER_INTR_MAP_1_ADDR)
+
+/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->2 */
+#define BMI160_USER_INTR_MAP_1_INTR2_FIFO_WM__POS (2)
+#define BMI160_USER_INTR_MAP_1_INTR2_FIFO_WM__LEN (1)
+#define BMI160_USER_INTR_MAP_1_INTR2_FIFO_WM__MSK (0x04)
+#define BMI160_USER_INTR_MAP_1_INTR2_FIFO_WM__REG \
+(BMI160_USER_INTR_MAP_1_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF DATA READY LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->3 */
+#define BMI160_USER_INTR_MAP_1_INTR2_DATA_RDY__POS (3)
+#define BMI160_USER_INTR_MAP_1_INTR2_DATA_RDY__LEN (1)
+#define BMI160_USER_INTR_MAP_1_INTR2_DATA_RDY__MSK (0x08)
+#define BMI160_USER_INTR_MAP_1_INTR2_DATA_RDY__REG \
+(BMI160_USER_INTR_MAP_1_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF PMU TRIGGER LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->4 */
+#define BMI160_USER_INTR_MAP_1_INTR1_PMU_TRIG__POS (4)
+#define BMI160_USER_INTR_MAP_1_INTR1_PMU_TRIG__LEN (1)
+#define BMI160_USER_INTR_MAP_1_INTR1_PMU_TRIG__MSK (0x10)
+#define BMI160_USER_INTR_MAP_1_INTR1_PMU_TRIG__REG (BMI160_USER_INTR_MAP_1_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF FIFO FULL AND
+ WATER MARK LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->5 */
+#define BMI160_USER_INTR_MAP_1_INTR1_FIFO_FULL__POS (5)
+#define BMI160_USER_INTR_MAP_1_INTR1_FIFO_FULL__LEN (1)
+#define BMI160_USER_INTR_MAP_1_INTR1_FIFO_FULL__MSK (0x20)
+#define BMI160_USER_INTR_MAP_1_INTR1_FIFO_FULL__REG \
+(BMI160_USER_INTR_MAP_1_ADDR)
+
+/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->6 */
+#define BMI160_USER_INTR_MAP_1_INTR1_FIFO_WM__POS (6)
+#define BMI160_USER_INTR_MAP_1_INTR1_FIFO_WM__LEN (1)
+#define BMI160_USER_INTR_MAP_1_INTR1_FIFO_WM__MSK (0x40)
+#define BMI160_USER_INTR_MAP_1_INTR1_FIFO_WM__REG \
+(BMI160_USER_INTR_MAP_1_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF DATA READY LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->7 */
+#define BMI160_USER_INTR_MAP_1_INTR1_DATA_RDY__POS (7)
+#define BMI160_USER_INTR_MAP_1_INTR1_DATA_RDY__LEN (1)
+#define BMI160_USER_INTR_MAP_1_INTR1_DATA_RDY__MSK (0x80)
+#define BMI160_USER_INTR_MAP_1_INTR1_DATA_RDY__REG \
+(BMI160_USER_INTR_MAP_1_ADDR)
+/**************************************************************/
+/**\name INTERRUPT2 MAPPIONG OF LOW_G LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->0 */
+#define BMI160_USER_INTR_MAP_2_INTR2_LOW_G__POS (0)
+#define BMI160_USER_INTR_MAP_2_INTR2_LOW_G__LEN (1)
+#define BMI160_USER_INTR_MAP_2_INTR2_LOW_G__MSK (0x01)
+#define BMI160_USER_INTR_MAP_2_INTR2_LOW_G__REG (BMI160_USER_INTR_MAP_2_ADDR)
+/**************************************************************/
+/**\name INTERRUPT2 MAPPIONG OF HIGH_G LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->1 */
+#define BMI160_USER_INTR_MAP_2_INTR2_HIGH_G__POS (1)
+#define BMI160_USER_INTR_MAP_2_INTR2_HIGH_G__LEN (1)
+#define BMI160_USER_INTR_MAP_2_INTR2_HIGH_G__MSK (0x02)
+#define BMI160_USER_INTR_MAP_2_INTR2_HIGH_G__REG \
+(BMI160_USER_INTR_MAP_2_ADDR)
+/**************************************************************/
+/**\name INTERRUPT2 MAPPIONG OF ANY MOTION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->2 */
+#define BMI160_USER_INTR_MAP_2_INTR2_ANY_MOTION__POS (2)
+#define BMI160_USER_INTR_MAP_2_INTR2_ANY_MOTION__LEN (1)
+#define BMI160_USER_INTR_MAP_2_INTR2_ANY_MOTION__MSK (0x04)
+#define BMI160_USER_INTR_MAP_2_INTR2_ANY_MOTION__REG \
+(BMI160_USER_INTR_MAP_2_ADDR)
+/**************************************************************/
+/**\name INTERRUPT2 MAPPIONG OF NO MOTION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->3 */
+#define BMI160_USER_INTR_MAP_2_INTR2_NOMOTION__POS (3)
+#define BMI160_USER_INTR_MAP_2_INTR2_NOMOTION__LEN (1)
+#define BMI160_USER_INTR_MAP_2_INTR2_NOMOTION__MSK (0x08)
+#define BMI160_USER_INTR_MAP_2_INTR2_NOMOTION__REG (BMI160_USER_INTR_MAP_2_ADDR)
+/**************************************************************/
+/**\name INTERRUPT2 MAPPIONG OF DOUBLE TAP LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->4 */
+#define BMI160_USER_INTR_MAP_2_INTR2_DOUBLE_TAP__POS (4)
+#define BMI160_USER_INTR_MAP_2_INTR2_DOUBLE_TAP__LEN (1)
+#define BMI160_USER_INTR_MAP_2_INTR2_DOUBLE_TAP__MSK (0x10)
+#define BMI160_USER_INTR_MAP_2_INTR2_DOUBLE_TAP__REG \
+(BMI160_USER_INTR_MAP_2_ADDR)
+/**************************************************************/
+/**\name INTERRUPT2 MAPPIONG OF SINGLE TAP LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->5 */
+#define BMI160_USER_INTR_MAP_2_INTR2_SINGLE_TAP__POS (5)
+#define BMI160_USER_INTR_MAP_2_INTR2_SINGLE_TAP__LEN (1)
+#define BMI160_USER_INTR_MAP_2_INTR2_SINGLE_TAP__MSK (0x20)
+#define BMI160_USER_INTR_MAP_2_INTR2_SINGLE_TAP__REG \
+(BMI160_USER_INTR_MAP_2_ADDR)
+/**************************************************************/
+/**\name INTERRUPT2 MAPPIONG OF ORIENT LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->6 */
+#define BMI160_USER_INTR_MAP_2_INTR2_ORIENT__POS (6)
+#define BMI160_USER_INTR_MAP_2_INTR2_ORIENT__LEN (1)
+#define BMI160_USER_INTR_MAP_2_INTR2_ORIENT__MSK (0x40)
+#define BMI160_USER_INTR_MAP_2_INTR2_ORIENT__REG \
+(BMI160_USER_INTR_MAP_2_ADDR)
+/**************************************************************/
+/**\name INTERRUPT2 MAPPIONG OF FLAT LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->7 */
+#define BMI160_USER_INTR_MAP_2_INTR2_FLAT__POS (7)
+#define BMI160_USER_INTR_MAP_2_INTR2_FLAT__LEN (1)
+#define BMI160_USER_INTR_MAP_2_INTR2_FLAT__MSK (0x80)
+#define BMI160_USER_INTR_MAP_2_INTR2_FLAT__REG (BMI160_USER_INTR_MAP_2_ADDR)
+
+/**************************************************************/
+/**\name TAP SOURCE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Data_0 Description - Reg Addr --> 0x58, Bit --> 3 */
+#define BMI160_USER_INTR_DATA_0_INTR_TAP_SOURCE__POS (3)
+#define BMI160_USER_INTR_DATA_0_INTR_TAP_SOURCE__LEN (1)
+#define BMI160_USER_INTR_DATA_0_INTR_TAP_SOURCE__MSK (0x08)
+#define BMI160_USER_INTR_DATA_0_INTR_TAP_SOURCE__REG \
+(BMI160_USER_INTR_DATA_0_ADDR)
+
+/**************************************************************/
+/**\name HIGH SOURCE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Data_0 Description - Reg Addr --> 0x58, Bit --> 7 */
+#define BMI160_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE__POS (7)
+#define BMI160_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE__LEN (1)
+#define BMI160_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE__MSK (0x80)
+#define BMI160_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE__REG \
+(BMI160_USER_INTR_DATA_0_ADDR)
+
+/**************************************************************/
+/**\name MOTION SOURCE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Data_1 Description - Reg Addr --> 0x59, Bit --> 7 */
+#define BMI160_USER_INTR_DATA_1_INTR_MOTION_SOURCE__POS (7)
+#define BMI160_USER_INTR_DATA_1_INTR_MOTION_SOURCE__LEN (1)
+#define BMI160_USER_INTR_DATA_1_INTR_MOTION_SOURCE__MSK (0x80)
+#define BMI160_USER_INTR_DATA_1_INTR_MOTION_SOURCE__REG \
+ (BMI160_USER_INTR_DATA_1_ADDR)
+/**************************************************************/
+/**\name LOW HIGH DURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_LowHigh_0 Description - Reg Addr --> 0x5a, Bit --> 0...7 */
+#define BMI160_USER_INTR_LOWHIGH_0_INTR_LOW_DURN__POS (0)
+#define BMI160_USER_INTR_LOWHIGH_0_INTR_LOW_DURN__LEN (8)
+#define BMI160_USER_INTR_LOWHIGH_0_INTR_LOW_DURN__MSK (0xFF)
+#define BMI160_USER_INTR_LOWHIGH_0_INTR_LOW_DURN__REG \
+ (BMI160_USER_INTR_LOWHIGH_0_ADDR)
+/**************************************************************/
+/**\name LOW THRESHOLD LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_LowHigh_1 Description - Reg Addr --> 0x5b, Bit --> 0...7 */
+#define BMI160_USER_INTR_LOWHIGH_1_INTR_LOW_THRES__POS (0)
+#define BMI160_USER_INTR_LOWHIGH_1_INTR_LOW_THRES__LEN (8)
+#define BMI160_USER_INTR_LOWHIGH_1_INTR_LOW_THRES__MSK (0xFF)
+#define BMI160_USER_INTR_LOWHIGH_1_INTR_LOW_THRES__REG \
+ (BMI160_USER_INTR_LOWHIGH_1_ADDR)
+/**************************************************************/
+/**\name LOW HYSTERESIS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_LowHigh_2 Description - Reg Addr --> 0x5c, Bit --> 0...1 */
+#define BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST__POS (0)
+#define BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST__LEN (2)
+#define BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST__MSK (0x03)
+#define BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST__REG \
+ (BMI160_USER_INTR_LOWHIGH_2_ADDR)
+/**************************************************************/
+/**\name LOW MODE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_LowHigh_2 Description - Reg Addr --> 0x5c, Bit --> 2 */
+#define BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE__POS (2)
+#define BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE__LEN (1)
+#define BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE__MSK (0x04)
+#define BMI160_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE__REG \
+ (BMI160_USER_INTR_LOWHIGH_2_ADDR)
+/**************************************************************/
+/**\name HIGH_G HYSTERESIS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_LowHigh_2 Description - Reg Addr --> 0x5c, Bit --> 6...7 */
+#define BMI160_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST__POS (6)
+#define BMI160_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST__LEN (2)
+#define BMI160_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST__MSK (0xC0)
+#define BMI160_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST__REG \
+ (BMI160_USER_INTR_LOWHIGH_2_ADDR)
+/**************************************************************/
+/**\name HIGH_G DURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_LowHigh_3 Description - Reg Addr --> 0x5d, Bit --> 0...7 */
+#define BMI160_USER_INTR_LOWHIGH_3_INTR_HIGH_G_DURN__POS (0)
+#define BMI160_USER_INTR_LOWHIGH_3_INTR_HIGH_G_DURN__LEN (8)
+#define BMI160_USER_INTR_LOWHIGH_3_INTR_HIGH_G_DURN__MSK (0xFF)
+#define BMI160_USER_INTR_LOWHIGH_3_INTR_HIGH_G_DURN__REG \
+ (BMI160_USER_INTR_LOWHIGH_3_ADDR)
+/**************************************************************/
+/**\name HIGH_G THRESHOLD LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_LowHigh_4 Description - Reg Addr --> 0x5e, Bit --> 0...7 */
+#define BMI160_USER_INTR_LOWHIGH_4_INTR_HIGH_THRES__POS (0)
+#define BMI160_USER_INTR_LOWHIGH_4_INTR_HIGH_THRES__LEN (8)
+#define BMI160_USER_INTR_LOWHIGH_4_INTR_HIGH_THRES__MSK (0xFF)
+#define BMI160_USER_INTR_LOWHIGH_4_INTR_HIGH_THRES__REG \
+ (BMI160_USER_INTR_LOWHIGH_4_ADDR)
+/**************************************************************/
+/**\name ANY MOTION DURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Motion_0 Description - Reg Addr --> 0x5f, Bit --> 0...1 */
+#define BMI160_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN__POS (0)
+#define BMI160_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN__LEN (2)
+#define BMI160_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN__MSK (0x03)
+#define BMI160_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN__REG \
+ (BMI160_USER_INTR_MOTION_0_ADDR)
+/**************************************************************/
+/**\name SLOW/NO MOTION DURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+ /* Int_Motion_0 Description - Reg Addr --> 0x5f, Bit --> 2...7 */
+#define BMI160_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN__POS (2)
+#define BMI160_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN__LEN (6)
+#define BMI160_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN__MSK (0xFC)
+#define BMI160_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN__REG \
+ (BMI160_USER_INTR_MOTION_0_ADDR)
+/**************************************************************/
+/**\name ANY MOTION THRESHOLD LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Motion_1 Description - Reg Addr --> (0x60), Bit --> 0...7 */
+#define BMI160_USER_INTR_MOTION_1_INTR_ANY_MOTION_THRES__POS (0)
+#define BMI160_USER_INTR_MOTION_1_INTR_ANY_MOTION_THRES__LEN (8)
+#define BMI160_USER_INTR_MOTION_1_INTR_ANY_MOTION_THRES__MSK (0xFF)
+#define BMI160_USER_INTR_MOTION_1_INTR_ANY_MOTION_THRES__REG \
+ (BMI160_USER_INTR_MOTION_1_ADDR)
+/**************************************************************/
+/**\name SLOW/NO MOTION THRESHOLD LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Motion_2 Description - Reg Addr --> 0x61, Bit --> 0...7 */
+#define BMI160_USER_INTR_MOTION_2_INTR_SLOW_NO_MOTION_THRES__POS (0)
+#define BMI160_USER_INTR_MOTION_2_INTR_SLOW_NO_MOTION_THRES__LEN (8)
+#define BMI160_USER_INTR_MOTION_2_INTR_SLOW_NO_MOTION_THRES__MSK (0xFF)
+#define BMI160_USER_INTR_MOTION_2_INTR_SLOW_NO_MOTION_THRES__REG \
+ (BMI160_USER_INTR_MOTION_2_ADDR)
+/**************************************************************/
+/**\name SLOW/NO MOTION SELECT LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Motion_3 Description - Reg Addr --> (0x62), Bit --> 0 */
+#define BMI160_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT__POS (0)
+#define BMI160_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT__LEN (1)
+#define BMI160_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT__MSK (0x01)
+#define BMI160_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT__REG \
+(BMI160_USER_INTR_MOTION_3_ADDR)
+/**************************************************************/
+/**\name SIGNIFICANT MOTION SELECT LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Motion_3 Description - Reg Addr --> (0x62), Bit --> 1 */
+#define BMI160_USER_INTR_SIGNIFICATION_MOTION_SELECT__POS (1)
+#define BMI160_USER_INTR_SIGNIFICATION_MOTION_SELECT__LEN (1)
+#define BMI160_USER_INTR_SIGNIFICATION_MOTION_SELECT__MSK (0x02)
+#define BMI160_USER_INTR_SIGNIFICATION_MOTION_SELECT__REG \
+ (BMI160_USER_INTR_MOTION_3_ADDR)
+
+/* Int_Motion_3 Description - Reg Addr --> (0x62), Bit --> 3..2 */
+#define BMI160_USER_INTR_SIGNIFICANT_MOTION_SKIP__POS (2)
+#define BMI160_USER_INTR_SIGNIFICANT_MOTION_SKIP__LEN (2)
+#define BMI160_USER_INTR_SIGNIFICANT_MOTION_SKIP__MSK (0x0C)
+#define BMI160_USER_INTR_SIGNIFICANT_MOTION_SKIP__REG \
+ (BMI160_USER_INTR_MOTION_3_ADDR)
+
+/* Int_Motion_3 Description - Reg Addr --> (0x62), Bit --> 5..4 */
+#define BMI160_USER_INTR_SIGNIFICANT_MOTION_PROOF__POS (4)
+#define BMI160_USER_INTR_SIGNIFICANT_MOTION_PROOF__LEN (2)
+#define BMI160_USER_INTR_SIGNIFICANT_MOTION_PROOF__MSK (0x30)
+#define BMI160_USER_INTR_SIGNIFICANT_MOTION_PROOF__REG \
+ (BMI160_USER_INTR_MOTION_3_ADDR)
+/**************************************************************/
+/**\name TAP DURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* INT_TAP_0 Description - Reg Addr --> (0x63), Bit --> 0..2*/
+#define BMI160_USER_INTR_TAP_0_INTR_TAP_DURN__POS (0)
+#define BMI160_USER_INTR_TAP_0_INTR_TAP_DURN__LEN (3)
+#define BMI160_USER_INTR_TAP_0_INTR_TAP_DURN__MSK (0x07)
+#define BMI160_USER_INTR_TAP_0_INTR_TAP_DURN__REG \
+(BMI160_USER_INTR_TAP_0_ADDR)
+/**************************************************************/
+/**\name TAP SHOCK LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Tap_0 Description - Reg Addr --> (0x63), Bit --> 6 */
+#define BMI160_USER_INTR_TAP_0_INTR_TAP_SHOCK__POS (6)
+#define BMI160_USER_INTR_TAP_0_INTR_TAP_SHOCK__LEN (1)
+#define BMI160_USER_INTR_TAP_0_INTR_TAP_SHOCK__MSK (0x40)
+#define BMI160_USER_INTR_TAP_0_INTR_TAP_SHOCK__REG (BMI160_USER_INTR_TAP_0_ADDR)
+/**************************************************************/
+/**\name TAP QUIET LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Tap_0 Description - Reg Addr --> (0x63), Bit --> 7 */
+#define BMI160_USER_INTR_TAP_0_INTR_TAP_QUIET__POS (7)
+#define BMI160_USER_INTR_TAP_0_INTR_TAP_QUIET__LEN (1)
+#define BMI160_USER_INTR_TAP_0_INTR_TAP_QUIET__MSK (0x80)
+#define BMI160_USER_INTR_TAP_0_INTR_TAP_QUIET__REG (BMI160_USER_INTR_TAP_0_ADDR)
+/**************************************************************/
+/**\name TAP THRESHOLD LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Tap_1 Description - Reg Addr --> (0x64), Bit --> 0...4 */
+#define BMI160_USER_INTR_TAP_1_INTR_TAP_THRES__POS (0)
+#define BMI160_USER_INTR_TAP_1_INTR_TAP_THRES__LEN (5)
+#define BMI160_USER_INTR_TAP_1_INTR_TAP_THRES__MSK (0x1F)
+#define BMI160_USER_INTR_TAP_1_INTR_TAP_THRES__REG (BMI160_USER_INTR_TAP_1_ADDR)
+/**************************************************************/
+/**\name ORIENT MODE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Orient_0 Description - Reg Addr --> (0x65), Bit --> 0...1 */
+#define BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_MODE__POS (0)
+#define BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_MODE__LEN (2)
+#define BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_MODE__MSK (0x03)
+#define BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_MODE__REG \
+ (BMI160_USER_INTR_ORIENT_0_ADDR)
+/**************************************************************/
+/**\name ORIENT BLOCKING LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Orient_0 Description - Reg Addr --> (0x65), Bit --> 2...3 */
+#define BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING__POS (2)
+#define BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING__LEN (2)
+#define BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING__MSK (0x0C)
+#define BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING__REG \
+ (BMI160_USER_INTR_ORIENT_0_ADDR)
+/**************************************************************/
+/**\name ORIENT HYSTERESIS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Orient_0 Description - Reg Addr --> (0x65), Bit --> 4...7 */
+#define BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_HYST__POS (4)
+#define BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_HYST__LEN (4)
+#define BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_HYST__MSK (0xF0)
+#define BMI160_USER_INTR_ORIENT_0_INTR_ORIENT_HYST__REG \
+ (BMI160_USER_INTR_ORIENT_0_ADDR)
+/**************************************************************/
+/**\name ORIENT THETA LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Orient_1 Description - Reg Addr --> 0x66, Bit --> 0...5 */
+#define BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_THETA__POS (0)
+#define BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_THETA__LEN (6)
+#define BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_THETA__MSK (0x3F)
+#define BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_THETA__REG \
+ (BMI160_USER_INTR_ORIENT_1_ADDR)
+/**************************************************************/
+/**\name ORIENT UD LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Orient_1 Description - Reg Addr --> 0x66, Bit --> 6 */
+#define BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE__POS (6)
+#define BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE__LEN (1)
+#define BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE__MSK (0x40)
+#define BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE__REG \
+ (BMI160_USER_INTR_ORIENT_1_ADDR)
+/**************************************************************/
+/**\name ORIENT AXIS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Orient_1 Description - Reg Addr --> 0x66, Bit --> 7 */
+#define BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX__POS (7)
+#define BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX__LEN (1)
+#define BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX__MSK (0x80)
+#define BMI160_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX__REG \
+ (BMI160_USER_INTR_ORIENT_1_ADDR)
+/**************************************************************/
+/**\name FLAT THETA LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Flat_0 Description - Reg Addr --> 0x67, Bit --> 0...5 */
+#define BMI160_USER_INTR_FLAT_0_INTR_FLAT_THETA__POS (0)
+#define BMI160_USER_INTR_FLAT_0_INTR_FLAT_THETA__LEN (6)
+#define BMI160_USER_INTR_FLAT_0_INTR_FLAT_THETA__MSK (0x3F)
+#define BMI160_USER_INTR_FLAT_0_INTR_FLAT_THETA__REG \
+ (BMI160_USER_INTR_FLAT_0_ADDR)
+/**************************************************************/
+/**\name FLAT HYSTERESIS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Flat_1 Description - Reg Addr --> (0x68), Bit --> 0...3 */
+#define BMI160_USER_INTR_FLAT_1_INTR_FLAT_HYST__POS (0)
+#define BMI160_USER_INTR_FLAT_1_INTR_FLAT_HYST__LEN (4)
+#define BMI160_USER_INTR_FLAT_1_INTR_FLAT_HYST__MSK (0x0F)
+#define BMI160_USER_INTR_FLAT_1_INTR_FLAT_HYST__REG \
+(BMI160_USER_INTR_FLAT_1_ADDR)
+/**************************************************************/
+/**\name FLAT HOLD LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Flat_1 Description - Reg Addr --> (0x68), Bit --> 4...5 */
+#define BMI160_USER_INTR_FLAT_1_INTR_FLAT_HOLD__POS (4)
+#define BMI160_USER_INTR_FLAT_1_INTR_FLAT_HOLD__LEN (2)
+#define BMI160_USER_INTR_FLAT_1_INTR_FLAT_HOLD__MSK (0x30)
+#define BMI160_USER_INTR_FLAT_1_INTR_FLAT_HOLD__REG \
+(BMI160_USER_INTR_FLAT_1_ADDR)
+/**************************************************************/
+/**\name FOC ACCEL XYZ LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Foc_Conf Description - Reg Addr --> (0x69), Bit --> 0...1 */
+#define BMI160_USER_FOC_ACCEL_Z__POS (0)
+#define BMI160_USER_FOC_ACCEL_Z__LEN (2)
+#define BMI160_USER_FOC_ACCEL_Z__MSK (0x03)
+#define BMI160_USER_FOC_ACCEL_Z__REG (BMI160_USER_FOC_CONFIG_ADDR)
+
+/* Foc_Conf Description - Reg Addr --> (0x69), Bit --> 2...3 */
+#define BMI160_USER_FOC_ACCEL_Y__POS (2)
+#define BMI160_USER_FOC_ACCEL_Y__LEN (2)
+#define BMI160_USER_FOC_ACCEL_Y__MSK (0x0C)
+#define BMI160_USER_FOC_ACCEL_Y__REG (BMI160_USER_FOC_CONFIG_ADDR)
+
+/* Foc_Conf Description - Reg Addr --> (0x69), Bit --> 4...5 */
+#define BMI160_USER_FOC_ACCEL_X__POS (4)
+#define BMI160_USER_FOC_ACCEL_X__LEN (2)
+#define BMI160_USER_FOC_ACCEL_X__MSK (0x30)
+#define BMI160_USER_FOC_ACCEL_X__REG (BMI160_USER_FOC_CONFIG_ADDR)
+/**************************************************************/
+/**\name FOC GYRO LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Foc_Conf Description - Reg Addr --> (0x69), Bit --> 6 */
+#define BMI160_USER_FOC_GYRO_ENABLE__POS (6)
+#define BMI160_USER_FOC_GYRO_ENABLE__LEN (1)
+#define BMI160_USER_FOC_GYRO_ENABLE__MSK (0x40)
+#define BMI160_USER_FOC_GYRO_ENABLE__REG \
+(BMI160_USER_FOC_CONFIG_ADDR)
+/**************************************************************/
+/**\name NVM PROGRAM LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* CONF Description - Reg Addr --> (0x6A), Bit --> 1 */
+#define BMI160_USER_CONFIG_NVM_PROG_ENABLE__POS (1)
+#define BMI160_USER_CONFIG_NVM_PROG_ENABLE__LEN (1)
+#define BMI160_USER_CONFIG_NVM_PROG_ENABLE__MSK (0x02)
+#define BMI160_USER_CONFIG_NVM_PROG_ENABLE__REG \
+(BMI160_USER_CONFIG_ADDR)
+
+/*IF_CONF Description - Reg Addr --> (0x6B), Bit --> 0 */
+
+#define BMI160_USER_IF_CONFIG_SPI3__POS (0)
+#define BMI160_USER_IF_CONFIG_SPI3__LEN (1)
+#define BMI160_USER_IF_CONFIG_SPI3__MSK (0x01)
+#define BMI160_USER_IF_CONFIG_SPI3__REG \
+(BMI160_USER_IF_CONFIG_ADDR)
+
+/*IF_CONF Description - Reg Addr --> (0x6B), Bit --> 5..4 */
+#define BMI160_USER_IF_CONFIG_IF_MODE__POS (4)
+#define BMI160_USER_IF_CONFIG_IF_MODE__LEN (2)
+#define BMI160_USER_IF_CONFIG_IF_MODE__MSK (0x30)
+#define BMI160_USER_IF_CONFIG_IF_MODE__REG \
+(BMI160_USER_IF_CONFIG_ADDR)
+/**************************************************************/
+/**\name GYRO SLEEP CONFIGURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Pmu_Trigger Description - Reg Addr --> 0x6c, Bit --> 0...2 */
+#define BMI160_USER_GYRO_SLEEP_TRIGGER__POS (0)
+#define BMI160_USER_GYRO_SLEEP_TRIGGER__LEN (3)
+#define BMI160_USER_GYRO_SLEEP_TRIGGER__MSK (0x07)
+#define BMI160_USER_GYRO_SLEEP_TRIGGER__REG (BMI160_USER_PMU_TRIGGER_ADDR)
+
+/* Pmu_Trigger Description - Reg Addr --> 0x6c, Bit --> 3...4 */
+#define BMI160_USER_GYRO_WAKEUP_TRIGGER__POS (3)
+#define BMI160_USER_GYRO_WAKEUP_TRIGGER__LEN (2)
+#define BMI160_USER_GYRO_WAKEUP_TRIGGER__MSK (0x18)
+#define BMI160_USER_GYRO_WAKEUP_TRIGGER__REG (BMI160_USER_PMU_TRIGGER_ADDR)
+
+/* Pmu_Trigger Description - Reg Addr --> 0x6c, Bit --> 5 */
+#define BMI160_USER_GYRO_SLEEP_STATE__POS (5)
+#define BMI160_USER_GYRO_SLEEP_STATE__LEN (1)
+#define BMI160_USER_GYRO_SLEEP_STATE__MSK (0x20)
+#define BMI160_USER_GYRO_SLEEP_STATE__REG (BMI160_USER_PMU_TRIGGER_ADDR)
+
+/* Pmu_Trigger Description - Reg Addr --> 0x6c, Bit --> 6 */
+#define BMI160_USER_GYRO_WAKEUP_INTR__POS (6)
+#define BMI160_USER_GYRO_WAKEUP_INTR__LEN (1)
+#define BMI160_USER_GYRO_WAKEUP_INTR__MSK (0x40)
+#define BMI160_USER_GYRO_WAKEUP_INTR__REG (BMI160_USER_PMU_TRIGGER_ADDR)
+/**************************************************************/
+/**\name ACCEL SELF TEST LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Self_Test Description - Reg Addr --> 0x6d, Bit --> 0...1 */
+#define BMI160_USER_ACCEL_SELFTEST_AXIS__POS (0)
+#define BMI160_USER_ACCEL_SELFTEST_AXIS__LEN (2)
+#define BMI160_USER_ACCEL_SELFTEST_AXIS__MSK (0x03)
+#define BMI160_USER_ACCEL_SELFTEST_AXIS__REG (BMI160_USER_SELF_TEST_ADDR)
+
+/* Self_Test Description - Reg Addr --> 0x6d, Bit --> 2 */
+#define BMI160_USER_ACCEL_SELFTEST_SIGN__POS (2)
+#define BMI160_USER_ACCEL_SELFTEST_SIGN__LEN (1)
+#define BMI160_USER_ACCEL_SELFTEST_SIGN__MSK (0x04)
+#define BMI160_USER_ACCEL_SELFTEST_SIGN__REG (BMI160_USER_SELF_TEST_ADDR)
+
+/* Self_Test Description - Reg Addr --> 0x6d, Bit --> 3 */
+#define BMI160_USER_SELFTEST_AMP__POS (3)
+#define BMI160_USER_SELFTEST_AMP__LEN (1)
+#define BMI160_USER_SELFTEST_AMP__MSK (0x08)
+#define BMI160_USER_SELFTEST_AMP__REG (BMI160_USER_SELF_TEST_ADDR)
+/**************************************************************/
+/**\name GYRO SELF TEST LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Self_Test Description - Reg Addr --> 0x6d, Bit --> 4 */
+#define BMI160_USER_GYRO_SELFTEST_START__POS (4)
+#define BMI160_USER_GYRO_SELFTEST_START__LEN (1)
+#define BMI160_USER_GYRO_SELFTEST_START__MSK (0x10)
+#define BMI160_USER_GYRO_SELFTEST_START__REG \
+(BMI160_USER_SELF_TEST_ADDR)
+/**************************************************************/
+/**\name NV_CONFIG LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* NV_CONF Description - Reg Addr --> (0x70), Bit --> 0 */
+#define BMI160_USER_NV_CONFIG_SPI_ENABLE__POS (0)
+#define BMI160_USER_NV_CONFIG_SPI_ENABLE__LEN (1)
+#define BMI160_USER_NV_CONFIG_SPI_ENABLE__MSK (0x01)
+#define BMI160_USER_NV_CONFIG_SPI_ENABLE__REG (BMI160_USER_NV_CONFIG_ADDR)
+
+/*IF_CONF Description - Reg Addr --> (0x70), Bit --> 1 */
+#define BMI160_USER_IF_CONFIG_I2C_WDT_SELECT__POS (1)
+#define BMI160_USER_IF_CONFIG_I2C_WDT_SELECT__LEN (1)
+#define BMI160_USER_IF_CONFIG_I2C_WDT_SELECT__MSK (0x02)
+#define BMI160_USER_IF_CONFIG_I2C_WDT_SELECT__REG \
+(BMI160_USER_NV_CONFIG_ADDR)
+
+/*IF_CONF Description - Reg Addr --> (0x70), Bit --> 2 */
+#define BMI160_USER_IF_CONFIG_I2C_WDT_ENABLE__POS (2)
+#define BMI160_USER_IF_CONFIG_I2C_WDT_ENABLE__LEN (1)
+#define BMI160_USER_IF_CONFIG_I2C_WDT_ENABLE__MSK (0x04)
+#define BMI160_USER_IF_CONFIG_I2C_WDT_ENABLE__REG \
+(BMI160_USER_NV_CONFIG_ADDR)
+
+/* NV_CONF Description - Reg Addr --> (0x70), Bit --> 3 */
+#define BMI160_USER_NV_CONFIG_SPARE0__POS (3)
+#define BMI160_USER_NV_CONFIG_SPARE0__LEN (1)
+#define BMI160_USER_NV_CONFIG_SPARE0__MSK (0x08)
+#define BMI160_USER_NV_CONFIG_SPARE0__REG (BMI160_USER_NV_CONFIG_ADDR)
+
+/* NV_CONF Description - Reg Addr --> (0x70), Bit --> 4...7 */
+#define BMI160_USER_NV_CONFIG_NVM_COUNTER__POS (4)
+#define BMI160_USER_NV_CONFIG_NVM_COUNTER__LEN (4)
+#define BMI160_USER_NV_CONFIG_NVM_COUNTER__MSK (0xF0)
+#define BMI160_USER_NV_CONFIG_NVM_COUNTER__REG (BMI160_USER_NV_CONFIG_ADDR)
+/**************************************************************/
+/**\name ACCEL MANUAL OFFSET LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Offset_0 Description - Reg Addr --> (0x71), Bit --> 0...7 */
+#define BMI160_USER_OFFSET_0_ACCEL_OFF_X__POS (0)
+#define BMI160_USER_OFFSET_0_ACCEL_OFF_X__LEN (8)
+#define BMI160_USER_OFFSET_0_ACCEL_OFF_X__MSK (0xFF)
+#define BMI160_USER_OFFSET_0_ACCEL_OFF_X__REG (BMI160_USER_OFFSET_0_ADDR)
+
+/* Offset_1 Description - Reg Addr --> 0x72, Bit --> 0...7 */
+#define BMI160_USER_OFFSET_1_ACCEL_OFF_Y__POS (0)
+#define BMI160_USER_OFFSET_1_ACCEL_OFF_Y__LEN (8)
+#define BMI160_USER_OFFSET_1_ACCEL_OFF_Y__MSK (0xFF)
+#define BMI160_USER_OFFSET_1_ACCEL_OFF_Y__REG (BMI160_USER_OFFSET_1_ADDR)
+
+/* Offset_2 Description - Reg Addr --> 0x73, Bit --> 0...7 */
+#define BMI160_USER_OFFSET_2_ACCEL_OFF_Z__POS (0)
+#define BMI160_USER_OFFSET_2_ACCEL_OFF_Z__LEN (8)
+#define BMI160_USER_OFFSET_2_ACCEL_OFF_Z__MSK (0xFF)
+#define BMI160_USER_OFFSET_2_ACCEL_OFF_Z__REG (BMI160_USER_OFFSET_2_ADDR)
+/**************************************************************/
+/**\name GYRO MANUAL OFFSET LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Offset_3 Description - Reg Addr --> 0x74, Bit --> 0...7 */
+#define BMI160_USER_OFFSET_3_GYRO_OFF_X__POS (0)
+#define BMI160_USER_OFFSET_3_GYRO_OFF_X__LEN (8)
+#define BMI160_USER_OFFSET_3_GYRO_OFF_X__MSK (0xFF)
+#define BMI160_USER_OFFSET_3_GYRO_OFF_X__REG (BMI160_USER_OFFSET_3_ADDR)
+
+/* Offset_4 Description - Reg Addr --> 0x75, Bit --> 0...7 */
+#define BMI160_USER_OFFSET_4_GYRO_OFF_Y__POS (0)
+#define BMI160_USER_OFFSET_4_GYRO_OFF_Y__LEN (8)
+#define BMI160_USER_OFFSET_4_GYRO_OFF_Y__MSK (0xFF)
+#define BMI160_USER_OFFSET_4_GYRO_OFF_Y__REG (BMI160_USER_OFFSET_4_ADDR)
+
+/* Offset_5 Description - Reg Addr --> 0x76, Bit --> 0...7 */
+#define BMI160_USER_OFFSET_5_GYRO_OFF_Z__POS (0)
+#define BMI160_USER_OFFSET_5_GYRO_OFF_Z__LEN (8)
+#define BMI160_USER_OFFSET_5_GYRO_OFF_Z__MSK (0xFF)
+#define BMI160_USER_OFFSET_5_GYRO_OFF_Z__REG (BMI160_USER_OFFSET_5_ADDR)
+
+
+/* Offset_6 Description - Reg Addr --> 0x77, Bit --> 0..1 */
+#define BMI160_USER_OFFSET_6_GYRO_OFF_X__POS (0)
+#define BMI160_USER_OFFSET_6_GYRO_OFF_X__LEN (2)
+#define BMI160_USER_OFFSET_6_GYRO_OFF_X__MSK (0x03)
+#define BMI160_USER_OFFSET_6_GYRO_OFF_X__REG (BMI160_USER_OFFSET_6_ADDR)
+
+/* Offset_6 Description - Reg Addr --> 0x77, Bit --> 2...3 */
+#define BMI160_USER_OFFSET_6_GYRO_OFF_Y__POS (2)
+#define BMI160_USER_OFFSET_6_GYRO_OFF_Y__LEN (2)
+#define BMI160_USER_OFFSET_6_GYRO_OFF_Y__MSK (0x0C)
+#define BMI160_USER_OFFSET_6_GYRO_OFF_Y__REG (BMI160_USER_OFFSET_6_ADDR)
+
+/* Offset_6 Description - Reg Addr --> 0x77, Bit --> 4...5 */
+#define BMI160_USER_OFFSET_6_GYRO_OFF_Z__POS (4)
+#define BMI160_USER_OFFSET_6_GYRO_OFF_Z__LEN (2)
+#define BMI160_USER_OFFSET_6_GYRO_OFF_Z__MSK (0x30)
+#define BMI160_USER_OFFSET_6_GYRO_OFF_Z__REG (BMI160_USER_OFFSET_6_ADDR)
+/**************************************************************/
+/**\name ACCEL OFFSET ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Offset_6 Description - Reg Addr --> 0x77, Bit --> 6 */
+#define BMI160_USER_OFFSET_6_ACCEL_OFF_ENABLE__POS (6)
+#define BMI160_USER_OFFSET_6_ACCEL_OFF_ENABLE__LEN (1)
+#define BMI160_USER_OFFSET_6_ACCEL_OFF_ENABLE__MSK (0x40)
+#define BMI160_USER_OFFSET_6_ACCEL_OFF_ENABLE__REG \
+(BMI160_USER_OFFSET_6_ADDR)
+/**************************************************************/
+/**\name GYRO OFFSET ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Offset_6 Description - Reg Addr --> 0x77, Bit --> 7 */
+#define BMI160_USER_OFFSET_6_GYRO_OFF_EN__POS (7)
+#define BMI160_USER_OFFSET_6_GYRO_OFF_EN__LEN (1)
+#define BMI160_USER_OFFSET_6_GYRO_OFF_EN__MSK (0x80)
+#define BMI160_USER_OFFSET_6_GYRO_OFF_EN__REG (BMI160_USER_OFFSET_6_ADDR)
+/**************************************************************/
+/**\name STEP COUNTER LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* STEP_CNT_0 Description - Reg Addr --> 0x78, Bit --> 0 to 7 */
+#define BMI160_USER_STEP_COUNT_LSB__POS (0)
+#define BMI160_USER_STEP_COUNT_LSB__LEN (7)
+#define BMI160_USER_STEP_COUNT_LSB__MSK (0xFF)
+#define BMI160_USER_STEP_COUNT_LSB__REG (BMI160_USER_STEP_COUNT_0_ADDR)
+
+/* STEP_CNT_1 Description - Reg Addr --> 0x79, Bit --> 0 to 7 */
+#define BMI160_USER_STEP_COUNT_MSB__POS (0)
+#define BMI160_USER_STEP_COUNT_MSB__LEN (7)
+#define BMI160_USER_STEP_COUNT_MSB__MSK (0xFF)
+#define BMI160_USER_STEP_COUNT_MSB__REG (BMI160_USER_STEP_COUNT_1_ADDR)
+/**************************************************************/
+/**\name STEP COUNTER CONFIGURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* STEP_CONFIG_0 Description - Reg Addr --> 0x7A, Bit --> 0 to 7 */
+#define BMI160_USER_STEP_CONFIG_ZERO__POS (0)
+#define BMI160_USER_STEP_CONFIG_ZERO__LEN (7)
+#define BMI160_USER_STEP_CONFIG_ZERO__MSK (0xFF)
+#define BMI160_USER_STEP_CONFIG_ZERO__REG \
+(BMI160_USER_STEP_CONFIG_0_ADDR)
+
+
+/* STEP_CONFIG_1 Description - Reg Addr --> 0x7B, Bit --> 0 to 2 and
+4 to 7 */
+#define BMI160_USER_STEP_CONFIG_ONE_CNF1__POS (0)
+#define BMI160_USER_STEP_CONFIG_ONE_CNF1__LEN (3)
+#define BMI160_USER_STEP_CONFIG_ONE_CNF1__MSK (0x07)
+#define BMI160_USER_STEP_CONFIG_ONE_CNF1__REG \
+(BMI160_USER_STEP_CONFIG_1_ADDR)
+
+#define BMI160_USER_STEP_CONFIG_ONE_CNF2__POS (4)
+#define BMI160_USER_STEP_CONFIG_ONE_CNF2__LEN (4)
+#define BMI160_USER_STEP_CONFIG_ONE_CNF2__MSK (0xF0)
+#define BMI160_USER_STEP_CONFIG_ONE_CNF2__REG \
+(BMI160_USER_STEP_CONFIG_1_ADDR)
+/**************************************************************/
+/**\name STEP COUNTER ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* STEP_CONFIG_1 Description - Reg Addr --> 0x7B, Bit --> 0 to 2 */
+#define BMI160_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE__POS (3)
+#define BMI160_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE__LEN (1)
+#define BMI160_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE__MSK (0x08)
+#define BMI160_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE__REG \
+(BMI160_USER_STEP_CONFIG_1_ADDR)
+
+/* USER REGISTERS DEFINITION END */
+/**************************************************************************/
+/* CMD REGISTERS DEFINITION START */
+/**************************************************************/
+/**\name COMMAND REGISTER LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Command description address - Reg Addr --> 0x7E, Bit --> 0....7 */
+#define BMI160_CMD_COMMANDS__POS (0)
+#define BMI160_CMD_COMMANDS__LEN (8)
+#define BMI160_CMD_COMMANDS__MSK (0xFF)
+#define BMI160_CMD_COMMANDS__REG (BMI160_CMD_COMMANDS_ADDR)
+/**************************************************************/
+/**\name PAGE ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Target page address - Reg Addr --> 0x7F, Bit --> 4....5 */
+#define BMI160_CMD_TARGET_PAGE__POS (4)
+#define BMI160_CMD_TARGET_PAGE__LEN (2)
+#define BMI160_CMD_TARGET_PAGE__MSK (0x30)
+#define BMI160_CMD_TARGET_PAGE__REG (BMI160_CMD_EXT_MODE_ADDR)
+
+/* Target page address - Reg Addr --> 0x7F, Bit --> 4....5 */
+#define BMI160_CMD_PAGING_EN__POS (7)
+#define BMI160_CMD_PAGING_EN__LEN (1)
+#define BMI160_CMD_PAGING_EN__MSK (0x80)
+#define BMI160_CMD_PAGING_EN__REG (BMI160_CMD_EXT_MODE_ADDR)
+
+/* Target page address - Reg Addr --> 0x7F, Bit --> 4....5 */
+#define BMI160_COM_C_TRIM_FIVE__POS (0)
+#define BMI160_COM_C_TRIM_FIVE__LEN (8)
+#define BMI160_COM_C_TRIM_FIVE__MSK (0xFF)
+#define BMI160_COM_C_TRIM_FIVE__REG (BMI160_COM_C_TRIM_FIVE_ADDR)
+
+/**************************************************************************/
+/* CMD REGISTERS DEFINITION END */
+
+/**************************************************/
+/**\name FIFO FRAME COUNT DEFINITION */
+/*************************************************/
+#define FIFO_FRAME (1024)
+#define FIFO_CONFIG_CHECK1 (0x00)
+#define FIFO_CONFIG_CHECK2 (0x80)
+/**************************************************/
+/**\name MAG SENSOR SELECT */
+/*************************************************/
+#define BST_BMM (0)
+#define BST_AKM (1)
+#define BMI160_YAS537_I2C_ADDRESS (0x2E)
+/**************************************************/
+/**\name ACCEL RANGE */
+/*************************************************/
+#define BMI160_ACCEL_RANGE_2G (0X03)
+#define BMI160_ACCEL_RANGE_4G (0X05)
+#define BMI160_ACCEL_RANGE_8G (0X08)
+#define BMI160_ACCEL_RANGE_16G (0X0C)
+/**************************************************/
+/**\name ACCEL ODR */
+/*************************************************/
+#define BMI160_ACCEL_OUTPUT_DATA_RATE_RESERVED (0x00)
+#define BMI160_ACCEL_OUTPUT_DATA_RATE_0_78HZ (0x01)
+#define BMI160_ACCEL_OUTPUT_DATA_RATE_1_56HZ (0x02)
+#define BMI160_ACCEL_OUTPUT_DATA_RATE_3_12HZ (0x03)
+#define BMI160_ACCEL_OUTPUT_DATA_RATE_6_25HZ (0x04)
+#define BMI160_ACCEL_OUTPUT_DATA_RATE_12_5HZ (0x05)
+#define BMI160_ACCEL_OUTPUT_DATA_RATE_25HZ (0x06)
+#define BMI160_ACCEL_OUTPUT_DATA_RATE_50HZ (0x07)
+#define BMI160_ACCEL_OUTPUT_DATA_RATE_100HZ (0x08)
+#define BMI160_ACCEL_OUTPUT_DATA_RATE_200HZ (0x09)
+#define BMI160_ACCEL_OUTPUT_DATA_RATE_400HZ (0x0A)
+#define BMI160_ACCEL_OUTPUT_DATA_RATE_800HZ (0x0B)
+#define BMI160_ACCEL_OUTPUT_DATA_RATE_1600HZ (0x0C)
+#define BMI160_ACCEL_OUTPUT_DATA_RATE_RESERVED0 (0x0D)
+#define BMI160_ACCEL_OUTPUT_DATA_RATE_RESERVED1 (0x0E)
+#define BMI160_ACCEL_OUTPUT_DATA_RATE_RESERVED2 (0x0F)
+/**************************************************/
+/**\name ACCEL BANDWIDTH PARAMETER */
+/*************************************************/
+#define BMI160_ACCEL_OSR4_AVG1 (0x00)
+#define BMI160_ACCEL_OSR2_AVG2 (0x01)
+#define BMI160_ACCEL_NORMAL_AVG4 (0x02)
+#define BMI160_ACCEL_CIC_AVG8 (0x03)
+#define BMI160_ACCEL_RES_AVG16 (0x04)
+#define BMI160_ACCEL_RES_AVG32 (0x05)
+#define BMI160_ACCEL_RES_AVG64 (0x06)
+#define BMI160_ACCEL_RES_AVG128 (0x07)
+/**************************************************/
+/**\name GYRO ODR */
+/*************************************************/
+#define BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED (0x00)
+#define BMI160_GYRO_OUTPUT_DATA_RATE_25HZ (0x06)
+#define BMI160_GYRO_OUTPUT_DATA_RATE_50HZ (0x07)
+#define BMI160_GYRO_OUTPUT_DATA_RATE_100HZ (0x08)
+#define BMI160_GYRO_OUTPUT_DATA_RATE_200HZ (0x09)
+#define BMI160_GYRO_OUTPUT_DATA_RATE_400HZ (0x0A)
+#define BMI160_GYRO_OUTPUT_DATA_RATE_800HZ (0x0B)
+#define BMI160_GYRO_OUTPUT_DATA_RATE_1600HZ (0x0C)
+#define BMI160_GYRO_OUTPUT_DATA_RATE_3200HZ (0x0D)
+/**************************************************/
+/**\name GYRO BANDWIDTH PARAMETER */
+/*************************************************/
+#define BMI160_GYRO_OSR4_MODE (0x00)
+#define BMI160_GYRO_OSR2_MODE (0x01)
+#define BMI160_GYRO_NORMAL_MODE (0x02)
+#define BMI160_GYRO_CIC_MODE (0x03)
+/**************************************************/
+/**\name GYROSCOPE RANGE PARAMETER */
+/*************************************************/
+#define BMI160_GYRO_RANGE_2000_DEG_SEC (0x00)
+#define BMI160_GYRO_RANGE_1000_DEG_SEC (0x01)
+#define BMI160_GYRO_RANGE_500_DEG_SEC (0x02)
+#define BMI160_GYRO_RANGE_250_DEG_SEC (0x03)
+#define BMI160_GYRO_RANGE_125_DEG_SEC (0x04)
+/**************************************************/
+/**\name MAG ODR */
+/*************************************************/
+#define BMI160_MAG_OUTPUT_DATA_RATE_RESERVED (0x00)
+#define BMI160_MAG_OUTPUT_DATA_RATE_0_78HZ (0x01)
+#define BMI160_MAG_OUTPUT_DATA_RATE_1_56HZ (0x02)
+#define BMI160_MAG_OUTPUT_DATA_RATE_3_12HZ (0x03)
+#define BMI160_MAG_OUTPUT_DATA_RATE_6_25HZ (0x04)
+#define BMI160_MAG_OUTPUT_DATA_RATE_12_5HZ (0x05)
+#define BMI160_MAG_OUTPUT_DATA_RATE_25HZ (0x06)
+#define BMI160_MAG_OUTPUT_DATA_RATE_50HZ (0x07)
+#define BMI160_MAG_OUTPUT_DATA_RATE_100HZ (0x08)
+#define BMI160_MAG_OUTPUT_DATA_RATE_200HZ (0x09)
+#define BMI160_MAG_OUTPUT_DATA_RATE_400HZ (0x0A)
+#define BMI160_MAG_OUTPUT_DATA_RATE_800HZ (0x0B)
+#define BMI160_MAG_OUTPUT_DATA_RATE_1600HZ (0x0C)
+#define BMI160_MAG_OUTPUT_DATA_RATE_RESERVED0 (0x0D)
+#define BMI160_MAG_OUTPUT_DATA_RATE_RESERVED1 (0x0E)
+#define BMI160_MAG_OUTPUT_DATA_RATE_RESERVED2 (0x0F)
+
+/**************************************************/
+/**\name ENABLE/DISABLE SELECTIONS */
+/*************************************************/
+
+/* Enable accel and gyro offset */
+#define ACCEL_OFFSET_ENABLE (0x01)
+#define GYRO_OFFSET_ENABLE (0x01)
+
+/* command register definition */
+#define START_FOC_ACCEL_GYRO (0X03)
+
+ /* INT ENABLE 1 */
+#define BMI160_ANY_MOTION_X_ENABLE (0)
+#define BMI160_ANY_MOTION_Y_ENABLE (1)
+#define BMI160_ANY_MOTION_Z_ENABLE (2)
+#define BMI160_DOUBLE_TAP_ENABLE (4)
+#define BMI160_SINGLE_TAP_ENABLE (5)
+#define BMI160_ORIENT_ENABLE (6)
+#define BMI160_FLAT_ENABLE (7)
+
+/* INT ENABLE 1 */
+#define BMI160_HIGH_G_X_ENABLE (0)
+#define BMI160_HIGH_G_Y_ENABLE (1)
+#define BMI160_HIGH_G_Z_ENABLE (2)
+#define BMI160_LOW_G_ENABLE (3)
+#define BMI160_DATA_RDY_ENABLE (4)
+#define BMI160_FIFO_FULL_ENABLE (5)
+#define BMI160_FIFO_WM_ENABLE (6)
+
+/* INT ENABLE 2 */
+#define BMI160_NOMOTION_X_ENABLE (0)
+#define BMI160_NOMOTION_Y_ENABLE (1)
+#define BMI160_NOMOTION_Z_ENABLE (2)
+#define BMI160_STEP_DETECTOR_EN (3)
+
+/* FOC axis selection for accel*/
+#define FOC_X_AXIS (0)
+#define FOC_Y_AXIS (1)
+#define FOC_Z_AXIS (2)
+
+/* IN OUT CONTROL */
+#define BMI160_INTR1_EDGE_CTRL (0)
+#define BMI160_INTR2_EDGE_CTRL (1)
+#define BMI160_INTR1_LEVEL (0)
+#define BMI160_INTR2_LEVEL (1)
+#define BMI160_INTR1_OUTPUT_TYPE (0)
+#define BMI160_INTR2_OUTPUT_TYPE (1)
+#define BMI160_INTR1_OUTPUT_ENABLE (0)
+#define BMI160_INTR2_OUTPUT_ENABLE (1)
+
+#define BMI160_INTR1_INPUT_ENABLE (0)
+#define BMI160_INTR2_INPUT_ENABLE (1)
+
+/* INTERRUPT MAPS */
+#define BMI160_INTR1_MAP_LOW_G (0)
+#define BMI160_INTR2_MAP_LOW_G (1)
+#define BMI160_INTR1_MAP_HIGH_G (0)
+#define BMI160_INTR2_MAP_HIGH_G (1)
+#define BMI160_INTR1_MAP_ANY_MOTION (0)
+#define BMI160_INTR2_MAP_ANY_MOTION (1)
+#define BMI160_INTR1_MAP_NOMO (0)
+#define BMI160_INTR2_MAP_NOMO (1)
+#define BMI160_INTR1_MAP_DOUBLE_TAP (0)
+#define BMI160_INTR2_MAP_DOUBLE_TAP (1)
+#define BMI160_INTR1_MAP_SINGLE_TAP (0)
+#define BMI160_INTR2_MAP_SINGLE_TAP (1)
+#define BMI160_INTR1_MAP_ORIENT (0)
+#define BMI160_INTR2_MAP_ORIENT (1)
+#define BMI160_INTR1_MAP_FLAT (0)
+#define BMI160_INTR2_MAP_FLAT (1)
+#define BMI160_INTR1_MAP_DATA_RDY (0)
+#define BMI160_INTR2_MAP_DATA_RDY (1)
+#define BMI160_INTR1_MAP_FIFO_WM (0)
+#define BMI160_INTR2_MAP_FIFO_WM (1)
+#define BMI160_INTR1_MAP_FIFO_FULL (0)
+#define BMI160_INTR2_MAP_FIFO_FULL (1)
+#define BMI160_INTR1_MAP_PMUTRIG (0)
+#define BMI160_INTR2_MAP_PMUTRIG (1)
+
+/* Interrupt mapping*/
+#define BMI160_MAP_INTR1 (0)
+#define BMI160_MAP_INTR2 (1)
+/**************************************************/
+/**\name TAP DURATION */
+/*************************************************/
+#define BMI160_TAP_DURN_50MS (0x00)
+#define BMI160_TAP_DURN_100MS (0x01)
+#define BMI160_TAP_DURN_150MS (0x02)
+#define BMI160_TAP_DURN_200MS (0x03)
+#define BMI160_TAP_DURN_250MS (0x04)
+#define BMI160_TAP_DURN_375MS (0x05)
+#define BMI160_TAP_DURN_500MS (0x06)
+#define BMI160_TAP_DURN_700MS (0x07)
+/**************************************************/
+/**\name TAP SHOCK */
+/*************************************************/
+#define BMI160_TAP_SHOCK_50MS (0x00)
+#define BMI160_TAP_SHOCK_75MS (0x01)
+/**************************************************/
+/**\name TAP QUIET */
+/*************************************************/
+#define BMI160_TAP_QUIET_30MS (0x00)
+#define BMI160_TAP_QUIET_20MS (0x01)
+/**************************************************/
+/**\name STEP DETECTION SELECTION MODES */
+/*************************************************/
+#define BMI160_STEP_NORMAL_MODE (0)
+#define BMI160_STEP_SENSITIVE_MODE (1)
+#define BMI160_STEP_ROBUST_MODE (2)
+/**************************************************/
+/**\name STEP CONFIGURATION SELECT MODE */
+/*************************************************/
+#define STEP_CONFIG_NORMAL (0X315)
+#define STEP_CONFIG_SENSITIVE (0X2D)
+#define STEP_CONFIG_ROBUST (0X71D)
+/**************************************************/
+/**\name BMM150 TRIM DATA DEFINITIONS */
+/*************************************************/
+#define BMI160_MAG_DIG_X1 (0x5D)
+#define BMI160_MAG_DIG_Y1 (0x5E)
+#define BMI160_MAG_DIG_Z4_LSB (0x62)
+#define BMI160_MAG_DIG_Z4_MSB (0x63)
+#define BMI160_MAG_DIG_X2 (0x64)
+#define BMI160_MAG_DIG_Y2 (0x65)
+#define BMI160_MAG_DIG_Z2_LSB (0x68)
+#define BMI160_MAG_DIG_Z2_MSB (0x69)
+#define BMI160_MAG_DIG_Z1_LSB (0x6A)
+#define BMI160_MAG_DIG_Z1_MSB (0x6B)
+#define BMI160_MAG_DIG_XYZ1_LSB (0x6C)
+#define BMI160_MAG_DIG_XYZ1_MSB (0x6D)
+#define BMI160_MAG_DIG_Z3_LSB (0x6E)
+#define BMI160_MAG_DIG_Z3_MSB (0x6F)
+#define BMI160_MAG_DIG_XY2 (0x70)
+#define BMI160_MAG_DIG_XY1 (0x71)
+/**************************************************/
+/**\name BMM150 PRE-SET MODE DEFINITIONS */
+/*************************************************/
+#define BMI160_MAG_PRESETMODE_LOWPOWER (1)
+#define BMI160_MAG_PRESETMODE_REGULAR (2)
+#define BMI160_MAG_PRESETMODE_HIGHACCURACY (3)
+#define BMI160_MAG_PRESETMODE_ENHANCED (4)
+/**************************************************/
+/**\name BMM150 PRESET MODES - DATA RATES */
+/*************************************************/
+#define BMI160_MAG_LOWPOWER_DR (0x02)
+#define BMI160_MAG_REGULAR_DR (0x02)
+#define BMI160_MAG_HIGHACCURACY_DR (0x2A)
+#define BMI160_MAG_ENHANCED_DR (0x02)
+/**************************************************/
+/**\name BMM150 PRESET MODES - REPETITIONS-XY RATES */
+/*************************************************/
+#define BMI160_MAG_LOWPOWER_REPXY (1)
+#define BMI160_MAG_REGULAR_REPXY (4)
+#define BMI160_MAG_HIGHACCURACY_REPXY (23)
+#define BMI160_MAG_ENHANCED_REPXY (7)
+/**************************************************/
+/**\name BMM150 PRESET MODES - REPETITIONS-Z RATES */
+/*************************************************/
+#define BMI160_MAG_LOWPOWER_REPZ (2)
+#define BMI160_MAG_REGULAR_REPZ (14)
+#define BMI160_MAG_HIGHACCURACY_REPZ (82)
+#define BMI160_MAG_ENHANCED_REPZ (26)
+#define BMI160_MAG_NOAMRL_SWITCH_TIMES (5)
+#define MAG_INTERFACE_PMU_ENABLE (1)
+#define MAG_INTERFACE_PMU_DISABLE (0)
+/**************************************************/
+/**\name USED FOR MAG OVERFLOW CHECK FOR BMM150 */
+/*************************************************/
+#define BMI160_MAG_OVERFLOW_OUTPUT ((s16)-32768)
+#define BMI160_MAG_OVERFLOW_OUTPUT_S32 ((s32)(-2147483647-1))
+#define BMI160_MAG_NEGATIVE_SATURATION_Z ((s16)-32767)
+#define BMI160_MAG_POSITIVE_SATURATION_Z ((u16)32767)
+#define BMI160_MAG_FLIP_OVERFLOW_ADCVAL ((s16)-4096)
+#define BMI160_MAG_HALL_OVERFLOW_ADCVAL ((s16)-16384)
+/**************************************************/
+/**\name BMM150 REGISTER DEFINITION */
+/*************************************************/
+#define BMI160_BMM150_CHIP_ID (0x40)
+#define BMI160_BMM150_POWE_CONTROL_REG (0x4B)
+#define BMI160_BMM150_POWE_MODE_REG (0x4C)
+#define BMI160_BMM150_DATA_REG (0x42)
+#define BMI160_BMM150_XY_REP (0x51)
+#define BMI160_BMM150_Z_REP (0x52)
+/**************************************************/
+/**\name AKM COMPENSATING DATA REGISTERS */
+/*************************************************/
+#define BMI160_BST_AKM_ASAX (0x60)
+#define BMI160_BST_AKM_ASAY (0x61)
+#define BMI160_BST_AKM_ASAZ (0x62)
+/**************************************************/
+/**\name AKM POWER MODE SELECTION */
+/*************************************************/
+#define AKM_POWER_DOWN_MODE (0)
+#define AKM_SINGLE_MEAS_MODE (1)
+#define FUSE_ROM_MODE (2)
+/**************************************************/
+/**\name SECONDARY_MAG POWER MODE SELECTION */
+/*************************************************/
+#define BMI160_MAG_FORCE_MODE (0)
+#define BMI160_MAG_SUSPEND_MODE (1)
+/**************************************************/
+/**\name MAG POWER MODE SELECTION */
+/*************************************************/
+#define FORCE_MODE (0)
+#define SUSPEND_MODE (1)
+#define NORMAL_MODE (2)
+#define MAG_SUSPEND_MODE (1)
+/**************************************************/
+/**\name FIFO CONFIGURATIONS */
+/*************************************************/
+#define FIFO_HEADER_ENABLE (0x01)
+#define FIFO_MAG_ENABLE (0x01)
+#define FIFO_ACCEL_ENABLE (0x01)
+#define FIFO_GYRO_ENABLE (0x01)
+#define FIFO_TIME_ENABLE (0x01)
+#define FIFO_STOPONFULL_ENABLE (0x01)
+#define FIFO_WM_INTERRUPT_ENABLE (0x01)
+#define BMI160_FIFO_INDEX_LENGTH (1)
+#define BMI160_FIFO_TAG_INTR_MASK (0xFC)
+
+/**************************************************/
+/**\name ACCEL POWER MODE */
+/*************************************************/
+#define ACCEL_MODE_NORMAL (0x11)
+#define ACCEL_LOWPOWER (0X12)
+#define ACCEL_SUSPEND (0X10)
+/**************************************************/
+/**\name GYRO POWER MODE */
+/*************************************************/
+#define GYRO_MODE_SUSPEND (0x14)
+#define GYRO_MODE_NORMAL (0x15)
+#define GYRO_MODE_FASTSTARTUP (0x17)
+/**************************************************/
+/**\name MAG POWER MODE */
+/*************************************************/
+#define MAG_MODE_SUSPEND (0x18)
+#define MAG_MODE_NORMAL (0x19)
+#define MAG_MODE_LOWPOWER (0x1A)
+/**************************************************/
+/**\name ENABLE/DISABLE BIT VALUES */
+/*************************************************/
+#define BMI160_ENABLE (0x01)
+#define BMI160_DISABLE (0x00)
+/**************************************************/
+/**\name INTERRUPT EDGE TRIGGER ENABLE */
+/*************************************************/
+#define BMI160_EDGE (0x01)
+#define BMI160_LEVEL (0x00)
+/**************************************************/
+/**\name INTERRUPT LEVEL ENABLE */
+/*************************************************/
+#define BMI160_LEVEL_LOW (0x00)
+#define BMI160_LEVEL_HIGH (0x01)
+/**************************************************/
+/**\name INTERRUPT OUTPUT ENABLE */
+/*************************************************/
+#define BMI160_OPEN_DRAIN (0x01)
+#define BMI160_PUSH_PULL (0x00)
+
+/* interrupt output enable*/
+#define BMI160_INPUT (0x01)
+#define BMI160_OUTPUT (0x00)
+
+/**************************************************/
+/**\name INTERRUPT TAP SOURCE ENABLE */
+/*************************************************/
+#define FILTER_DATA (0x00)
+#define UNFILTER_DATA (0x01)
+/**************************************************/
+/**\name SLOW MOTION/ NO MOTION SELECT */
+/*************************************************/
+#define SLOW_MOTION (0x00)
+#define NO_MOTION (0x01)
+/**************************************************/
+/**\name SIGNIFICANT MOTION SELECTION */
+/*************************************************/
+#define ANY_MOTION (0x00)
+#define SIGNIFICANT_MOTION (0x01)
+/**************************************************/
+/**\name LATCH DURATION */
+/*************************************************/
+#define BMI160_LATCH_DUR_NONE (0x00)
+#define BMI160_LATCH_DUR_312_5_MICRO_SEC (0x01)
+#define BMI160_LATCH_DUR_625_MICRO_SEC (0x02)
+#define BMI160_LATCH_DUR_1_25_MILLI_SEC (0x03)
+#define BMI160_LATCH_DUR_2_5_MILLI_SEC (0x04)
+#define BMI160_LATCH_DUR_5_MILLI_SEC (0x05)
+#define BMI160_LATCH_DUR_10_MILLI_SEC (0x06)
+#define BMI160_LATCH_DUR_20_MILLI_SEC (0x07)
+#define BMI160_LATCH_DUR_40_MILLI_SEC (0x08)
+#define BMI160_LATCH_DUR_80_MILLI_SEC (0x09)
+#define BMI160_LATCH_DUR_160_MILLI_SEC (0x0A)
+#define BMI160_LATCH_DUR_320_MILLI_SEC (0x0B)
+#define BMI160_LATCH_DUR_640_MILLI_SEC (0x0C)
+#define BMI160_LATCH_DUR_1_28_SEC (0x0D)
+#define BMI160_LATCH_DUR_2_56_SEC (0x0E)
+#define BMI160_LATCHED (0x0F)
+/**************************************************/
+/**\name GYRO OFFSET MASK DEFINITION */
+/*************************************************/
+#define BMI160_GYRO_MANUAL_OFFSET_0_7 (0x00FF)
+#define BMI160_GYRO_MANUAL_OFFSET_8_9 (0x0300)
+/**************************************************/
+/**\name STEP CONFIGURATION MASK DEFINITION */
+/*************************************************/
+#define BMI160_STEP_CONFIG_0_7 (0x00FF)
+#define BMI160_STEP_CONFIG_8_10 (0x0700)
+#define BMI160_STEP_CONFIG_11_14 (0xF000)
+/**************************************************/
+/**\name DEFINITION USED FOR DIFFERENT WRITE */
+/*************************************************/
+#define BMI160_WRITE_TARGET_PAGE0 (0x00)
+#define BMI160_WRITE_TARGET_PAGE1 (0x01)
+#define BMI160_WRITE_ENABLE_PAGE1 (0x01)
+#define BMI160_MANUAL_DISABLE (0x00)
+#define BMI160_MANUAL_ENABLE (0x01)
+#define BMI160_YAS_DISABLE_RCOIL (0x00)
+#define BMI160_ENABLE_MAG_IF_MODE (0x02)
+#define BMI160_ENABLE_ANY_MOTION_INTR1 (0x04)
+#define BMI160_ENABLE_ANY_MOTION_INTR2 (0x04)
+#define BMI160_MAG_DATA_READ_REG (0x04)
+#define BMI160_BMM_POWER_MODE_REG (0x06)
+#define BMI160_ENABLE_ANY_MOTION_AXIS (0x07)
+#define BMI160_ENABLE_LOW_G (0x08)
+#define BMI160_YAS532_ACQ_START (0x11)
+#define BMI160_YAS_DEVICE_ID_REG (0x80)
+#define BMI160_FIFO_GYRO_ENABLE (0x80)
+#define BMI160_SIG_MOTION_INTR_ENABLE (0x01)
+#define BMI160_STEP_DETECT_INTR_ENABLE (0x01)
+#define BMI160_LOW_G_INTR_STAT (0x01)
+#define BMI160_PULL_UP_DATA (0x30)
+#define BMI160_FIFO_M_G_A_ENABLE (0xE0)
+#define BMI160_FIFO_M_G_ENABLE (0xA0)
+#define BMI160_FIFO_M_A_ENABLE (0x60)
+#define BMI160_FIFO_G_A_ENABLE (0xC0)
+#define BMI160_FIFO_A_ENABLE (0x40)
+#define BMI160_FIFO_M_ENABLE (0x20)
+/**************************************************/
+/**\name MAG INIT DEFINITION */
+/*************************************************/
+#define BMI160_COMMAND_REG_ONE (0x37)
+#define BMI160_COMMAND_REG_TWO (0x9A)
+#define BMI160_COMMAND_REG_THREE (0xC0)
+#define RESET_STEP_COUNTER (0xB2)
+/**************************************************/
+/**\name BIT SLICE GET AND SET FUNCTIONS */
+/*************************************************/
+#define BMI160_GET_BITSLICE(regvar, bitname)\
+ ((regvar & bitname##__MSK) >> bitname##__POS)
+
+
+#define BMI160_SET_BITSLICE(regvar, bitname, val)\
+ ((regvar & ~bitname##__MSK) | \
+ ((val<<bitname##__POS)&bitname##__MSK))
+
+/**************************************************/
+/**\name FUNCTION DECLARATIONS */
+/*************************************************/
+/**************************************************/
+/**\name FUNCTION FOR BMI160 INITIALIZE */
+/*************************************************/
+/*!
+ * @brief
+ * This function is used for initialize
+ * bus read and bus write functions
+ * assign the chip id and device address
+ * chip id is read in the register 0x00 bit from 0 to 7
+ *
+ * @param bmi160 : structure pointer
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ * @note
+ * While changing the parameter of the bmi160_t
+ * consider the following point:
+ * Changing the reference value of the parameter
+ * will changes the local copy or local reference
+ * make sure your changes will not
+ * affect the reference value of the parameter
+ * (Better case don't change the reference value of the parameter)
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_init(struct bmi160_t *bmi160);
+/**************************************************/
+/**\name FUNCTION FOR READ AND WRITE REGISTERS */
+/*************************************************/
+/*!
+ * @brief
+ * This API write the data to
+ * the given register
+ *
+ *
+ * @param v_addr_u8 -> Address of the register
+ * @param v_data_u8 -> The data from the register
+ * @param v_len_u8 -> no of bytes to read
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_write_reg(u8 v_addr_u8,
+u8 *v_data_u8, u8 v_len_u8);
+/*!
+ * @brief
+ * This API reads the data from
+ * the given register
+ *
+ *
+ * @param v_addr_u8 -> Address of the register
+ * @param v_data_u8 -> The data from the register
+ * @param v_len_u8 -> no of bytes to read
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_reg(u8 v_addr_u8,
+u8 *v_data_u8, u8 v_len_u8);
+/**************************************************/
+/**\name FUNCTION FOR ERROR CODES */
+/*************************************************/
+/*!
+ * @brief This API used to reads the fatal error
+ * from the Register 0x02 bit 0
+ * This flag will be reset only by power-on-reset and soft reset
+ *
+ *
+ * @param v_fatal_err_u8 : The status of fatal error
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_fatal_err(u8
+*v_fatal_err_u8);
+/*!
+ * @brief This API used to read the error code
+ * from register 0x02 bit 1 to 4
+ *
+ *
+ * @param v_err_code_u8 : The status of error codes
+ * error_code | description
+ * ------------|---------------
+ * 0x00 |no error
+ * 0x01 |ACC_CONF error (accel ODR and bandwidth not compatible)
+ * 0x02 |GYR_CONF error (Gyroscope ODR and bandwidth not compatible)
+ * 0x03 |Under sampling mode and interrupt uses pre filtered data
+ * 0x04 |reserved
+ * 0x05 |Selected trigger-readout offset in
+ * - |MAG_IF greater than selected ODR
+ * 0x06 |FIFO configuration error for header less mode
+ * 0x07 |Under sampling mode and pre filtered data as FIFO source
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_err_code(u8
+*v_error_code_u8);
+/*!
+ * @brief This API Reads the i2c error code from the
+ * Register 0x02 bit 5.
+ * This error occurred in I2C master detected
+ *
+ * @param v_i2c_err_code_u8 : The status of i2c fail error
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_i2c_fail_err(u8
+*v_i2c_error_code_u8);
+ /*!
+ * @brief This API Reads the dropped command error
+ * from the register 0x02 bit 6
+ *
+ *
+ * @param v_drop_cmd_err_u8 : The status of drop command error
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_drop_cmd_err(u8
+*v_drop_cmd_err_u8);
+/*!
+ * @brief This API reads the magnetometer data ready
+ * interrupt not active.
+ * It reads from the error register 0x0x2 bit 7
+ *
+ *
+ *
+ *
+ * @param v_mag_data_rdy_err_u8 : The status of mag data ready interrupt
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_dada_rdy_err(u8
+*v_mag_data_rdy_err_u8);
+/*!
+ * @brief This API reads the error status
+ * from the error register 0x02 bit 0 to 7
+ *
+ * @param v_mag_data_rdy_err_u8 : The status of mag data ready interrupt
+ * @param v_fatal_er_u8r : The status of fatal error
+ * @param v_err_code_u8 : The status of error code
+ * @param v_i2c_fail_err_u8 : The status of I2C fail error
+ * @param v_drop_cmd_err_u8 : The status of drop command error
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_error_status(u8 *v_fatal_er_u8r,
+u8 *v_err_code_u8, u8 *v_i2c_fail_err_u8,
+u8 *v_drop_cmd_err_u8, u8 *v_mag_data_rdy_err_u8);
+/******************************************************************/
+/**\name FUNCTIONS FOR MAG,ACCEL AND GYRO POWER MODE STATUS */
+/*****************************************************************/
+/*!
+ * @brief This API reads the magnetometer power mode from
+ * PMU status register 0x03 bit 0 and 1
+ *
+ * @param v_mag_power_mode_stat_u8 : The value of mag power mode
+ * mag_powermode | value
+ * ------------------|----------
+ * SUSPEND | 0x00
+ * NORMAL | 0x01
+ * LOW POWER | 0x02
+ *
+ *
+ * @note The power mode of mag set by the 0x7E command register
+ * @note using the function "bmi160_set_command_register()"
+ * value | mode
+ * ---------|----------------
+ * 0x18 | MAG_MODE_SUSPEND
+ * 0x19 | MAG_MODE_NORMAL
+ * 0x1A | MAG_MODE_LOWPOWER
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_power_mode_stat(u8
+*v_mag_power_mode_stat_u8);
+/*!
+ * @brief This API reads the gyroscope power mode from
+ * PMU status register 0x03 bit 2 and 3
+ *
+ * @param v_gyro_power_mode_stat_u8 : The value of gyro power mode
+ * gyro_powermode | value
+ * ------------------|----------
+ * SUSPEND | 0x00
+ * NORMAL | 0x01
+ * FAST POWER UP | 0x03
+ *
+ * @note The power mode of gyro set by the 0x7E command register
+ * @note using the function "bmi160_set_command_register()"
+ * value | mode
+ * ---------|----------------
+ * 0x14 | GYRO_MODE_SUSPEND
+ * 0x15 | GYRO_MODE_NORMAL
+ * 0x17 | GYRO_MODE_FASTSTARTUP
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_power_mode_stat(u8
+*v_gyro_power_mode_stat_u8);
+/*!
+ * @brief This API reads the accelerometer power mode from
+ * PMU status register 0x03 bit 4 and 5
+ *
+ *
+ * @param v_accel_power_mode_stat_u8 : The value of accel power mode
+ * accel_powermode | value
+ * ------------------|----------
+ * SUSPEND | 0x00
+ * NORMAL | 0x01
+ * LOW POWER | 0x03
+ *
+ * @note The power mode of accel set by the 0x7E command register
+ * @note using the function "bmi160_set_command_register()"
+ * value | mode
+ * ---------|----------------
+ * 0x11 | ACCEL_MODE_NORMAL
+ * 0x12 | ACCEL_LOWPOWER
+ * 0x10 | ACCEL_SUSPEND
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_power_mode_stat(u8
+*v_accel_power_mode_stat_u8);
+/*!
+ * @brief This API switch mag interface to normal mode
+ * and confirm whether the mode switching done successfully or not
+*
+ * @return results of bus communication function and current MAG_PMU result
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_interface_normal(void);
+/**************************************************/
+/**\name FUNCTION FOR Mag XYZ data read */
+/*************************************************/
+/*!
+ * @brief This API reads magnetometer data X values
+ * from the register 0x04 and 0x05
+ * @brief The mag sensor data read form auxiliary mag
+ *
+ * @param v_mag_x_s16 : The value of mag x
+ * @param v_sensor_select_u8 : Mag selection value
+ * value | sensor
+ * ---------|----------------
+ * 0 | BMM150
+ * 1 | AKM09911 or AKM09912
+ *
+ * @note For mag data output rate configuration use the following function
+ * @note bmi160_set_mag_output_data_rate()
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_mag_x(s16 *v_mag_x_s16,
+u8 v_sensor_select_u8);
+/*!
+ * @brief This API reads magnetometer data Y values
+ * from the register 0x06 and 0x07
+ * @brief The mag sensor data read form auxiliary mag
+ *
+ * @param v_mag_y_s16 : The value of mag y
+ * @param v_sensor_select_u8 : Mag selection value
+ * value | sensor
+ * ---------|----------------
+ * 0 | BMM150
+ * 1 | AKM09911 or AKM09912
+ *
+ * @note For mag data output rate configuration use the following function
+ * @note bmi160_set_mag_output_data_rate()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_mag_y(s16 *v_mag_y_s16,
+u8 v_sensor_select_u8);
+/*!
+ * @brief This API reads magnetometer data Z values
+ * from the register 0x08 and 0x09
+ * @brief The mag sensor data read form auxiliary mag
+ *
+ * @param v_mag_z_s16 : The value of mag z
+ * @param v_sensor_select_u8 : Mag selection value
+ * value | sensor
+ * ---------|----------------
+ * 0 | BMM150
+ * 1 | AKM09911 or AKM09912
+ *
+ * @note For mag data output rate configuration use the following function
+ * @note bmi160_set_mag_output_data_rate()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_mag_z(s16 *v_mag_z_s16,
+u8 v_sensor_select_u8);
+/*!
+ * @brief This API reads magnetometer data RHALL values
+ * from the register 0x0A and 0x0B
+ *
+ *
+ * @param v_mag_r_s16 : The value of BMM150 r data
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_mag_r(
+s16 *v_mag_r_s16);
+/*!
+ * @brief This API reads magnetometer data X,Y,Z values
+ * from the register 0x04 to 0x09
+ *
+ * @brief The mag sensor data read form auxiliary mag
+ *
+ * @param mag : The value of mag xyz data
+ * @param v_sensor_select_u8 : Mag selection value
+ * value | sensor
+ * ---------|----------------
+ * 0 | BMM150
+ * 1 | AKM09911 or AKM09912
+ *
+ * @note For mag data output rate configuration use the following function
+ * @note bmi160_set_mag_output_data_rate()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_mag_xyz(
+struct bmi160_mag_t *mag, u8 v_sensor_select_u8);
+ /*!*
+ * @brief This API reads magnetometer data X,Y,Z,r
+ * values from the register 0x04 to 0x0B
+ *
+ * @brief The mag sensor data read form auxiliary mag
+ *
+ * @param mag : The value of mag-BMM150 xyzr data
+ *
+ * @note For mag data output rate configuration use the following function
+ * @note bmi160_set_mag_output_data_rate()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_mag_xyzr(
+struct bmi160_mag_xyzr_t *mag);
+/**************************************************/
+/**\name FUNCTION FOR GYRO XYZ DATA READ */
+/*************************************************/
+/*!
+ * @brief This API reads gyro data X values
+ * form the register 0x0C and 0x0D
+ *
+ *
+ *
+ *
+ * @param v_gyro_x_s16 : The value of gyro x data
+ *
+ * @note Gyro Configuration use the following function
+ * @note bmi160_set_gyro_output_data_rate()
+ * @note bmi160_set_gyro_bw()
+ * @note bmi160_set_gyro_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_gyro_x(
+s16 *v_gyro_x_s16);
+/*!
+ * @brief This API reads gyro data Y values
+ * form the register 0x0E and 0x0F
+ *
+ *
+ *
+ *
+ * @param v_gyro_y_s16 : The value of gyro y data
+ *
+ * @note Gyro Configuration use the following function
+ * @note bmi160_set_gyro_output_data_rate()
+ * @note bmi160_set_gyro_bw()
+ * @note bmi160_set_gyro_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error result of communication routines
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_gyro_y(
+s16 *v_gyro_y_s16);
+/*!
+ * @brief This API reads gyro data Z values
+ * form the register 0x10 and 0x11
+ *
+ *
+ *
+ *
+ * @param v_gyro_z_s16 : The value of gyro z data
+ *
+ * @note Gyro Configuration use the following function
+ * @note bmi160_set_gyro_output_data_rate()
+ * @note bmi160_set_gyro_bw()
+ * @note bmi160_set_gyro_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_gyro_z(
+s16 *v_gyro_z_s16);
+/*!
+ * @brief This API reads gyro data X,Y,Z values
+ * from the register 0x0C to 0x11
+ *
+ *
+ *
+ *
+ * @param gyro : The value of gyro xyz
+ *
+ * @note Gyro Configuration use the following function
+ * @note bmi160_set_gyro_output_data_rate()
+ * @note bmi160_set_gyro_bw()
+ * @note bmi160_set_gyro_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_gyro_xyz(
+struct bmi160_gyro_t *gyro);
+/**************************************************/
+/**\name FUNCTION FOR ACCEL XYZ DATA READ */
+/*************************************************/
+/*!
+ * @brief This API reads accelerometer data X values
+ * form the register 0x12 and 0x13
+ *
+ *
+ *
+ *
+ * @param v_accel_x_s16 : The value of accel x
+ *
+ * @note For accel configuration use the following functions
+ * @note bmi160_set_accel_output_data_rate()
+ * @note bmi160_set_accel_bw()
+ * @note bmi160_set_accel_under_sampling_parameter()
+ * @note bmi160_set_accel_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_accel_x(
+s16 *v_accel_x_s16);
+/*!
+ * @brief This API reads accelerometer data Y values
+ * form the register 0x14 and 0x15
+ *
+ *
+ *
+ *
+ * @param v_accel_y_s16 : The value of accel y
+ *
+ * @note For accel configuration use the following functions
+ * @note bmi160_set_accel_output_data_rate()
+ * @note bmi160_set_accel_bw()
+ * @note bmi160_set_accel_under_sampling_parameter()
+ * @note bmi160_set_accel_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_accel_y(
+s16 *v_accel_y_s16);
+/*!
+ * @brief This API reads accelerometer data Z values
+ * form the register 0x16 and 0x17
+ *
+ *
+ *
+ *
+ * @param v_accel_z_s16 : The value of accel z
+ *
+ * @note For accel configuration use the following functions
+ * @note bmi160_set_accel_output_data_rate()
+ * @note bmi160_set_accel_bw()
+ * @note bmi160_set_accel_under_sampling_parameter()
+ * @note bmi160_set_accel_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_accel_z(
+s16 *v_accel_z_s16);
+/*!
+ * @brief This API reads accelerometer data X,Y,Z values
+ * from the register 0x12 to 0x17
+ *
+ *
+ *
+ *
+ * @param accel :The value of accel xyz
+ *
+ * @note For accel configuration use the following functions
+ * @note bmi160_set_accel_output_data_rate()
+ * @note bmi160_set_accel_bw()
+ * @note bmi160_set_accel_under_sampling_parameter()
+ * @note bmi160_set_accel_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_accel_xyz(
+struct bmi160_accel_t *accel);
+/**************************************************/
+/**\name FUNCTION FOR SENSOR TIME */
+/*************************************************/
+/*!
+ * @brief This API reads sensor_time from the register
+ * 0x18 to 0x1A
+ *
+ *
+ * @param v_sensor_time_u32 : The value of sensor time
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_sensor_time(
+u32 *v_sensor_time_u32);
+/**************************************************/
+/**\name FUNCTION FOR GYRO SLEF TEST */
+/*************************************************/
+/*!
+ * @brief This API reads the Gyroscope self test
+ * status from the register 0x1B bit 1
+ *
+ *
+ * @param v_gyro_selftest_u8 : The value of gyro self test status
+ * value | status
+ * ---------|----------------
+ * 0 | Gyroscope self test is running or failed
+ * 1 | Gyroscope self test completed successfully
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_selftest(u8
+*v_gyro_selftest_u8);
+/**************************************************/
+/**\name FUNCTION FOR MANUAL INTERFACE */
+/*************************************************/
+/*!
+ * @brief This API reads the status of
+ * mag manual interface operation form the register 0x1B bit 2
+ *
+ *
+ *
+ * @param v_mag_manual_stat_u8 : The value of mag manual operation status
+ * value | status
+ * ---------|----------------
+ * 0 | Indicates no manual magnetometer
+ * - | interface operation is ongoing
+ * 1 | Indicates manual magnetometer
+ * - | interface operation is ongoing
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_manual_operation_stat(u8
+*v_mag_manual_stat_u8);
+/**************************************************/
+/**\name FUNCTION FOR FAST OFFSET READY */
+/*************************************************/
+/*!
+ * @brief This API reads the fast offset compensation
+ * status form the register 0x1B bit 3
+ *
+ *
+ * @param v_foc_rdy_u8 : The status of fast compensation
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_foc_rdy(u8
+*v_foc_rdy_u8);
+/**************************************************/
+/**\name FUNCTION FOR NVM READY */
+/*************************************************/
+/*!
+ * @brief This API Reads the nvm_rdy status from the
+ * resister 0x1B bit 4
+ *
+ *
+ * @param v_nvm_rdy_u8 : The value of NVM ready status
+ * value | status
+ * ---------|----------------
+ * 0 | NVM write operation in progress
+ * 1 | NVM is ready to accept a new write trigger
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_nvm_rdy(u8
+*v_nvm_rdy_u8);
+/**************************************************/
+/**\name FUNCTION FOR DATA READY FOR MAG, GYRO, AND ACCEL */
+/*************************************************/
+/*!
+ * @brief This API reads the status of mag data ready
+ * from the register 0x1B bit 5
+ * The status get reset when one mag data register is read out
+ *
+ * @param v_data_rdy_u8 : The value of mag data ready status
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_data_rdy_mag(u8
+*v_data_rdy_u8);
+/*!
+ * @brief This API reads the status of gyro data ready form the
+ * register 0x1B bit 6
+ * The status get reset when gyro data register read out
+ *
+ *
+ * @param v_data_rdy_u8 : The value of gyro data ready
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_data_rdy(u8
+*v_data_rdy_u8);
+/*!
+ * @brief This API reads the status of accel data ready form the
+ * register 0x1B bit 7
+ * The status get reset when accel data register read out
+ *
+ *
+ * @param v_data_rdy_u8 : The value of accel data ready status
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_data_rdy(u8
+*drdy_acc);
+/**************************************************/
+/**\name FUNCTION FOR STEP INTERRUPT STATUS */
+/*************************************************/
+/*!
+ * @brief This API reads the step detector interrupt status
+ * from the register 0x1C bit 0
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_step_intr_u8 : The status of step detector interrupt
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_step_intr(u8
+*v_step_intr_u8);
+/**************************************************/
+/**\name FUNCTION FOR SIGNIFICANT INTERRUPT STATUS */
+/*************************************************/
+/*!
+ * @brief This API reads the
+ * significant motion interrupt status
+ * from the register 0x1C bit 1
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ *
+ * @param v_significant_intr_u8 : The status of step
+ * motion interrupt
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_significant_intr(u8
+*sigmot_intr);
+/**************************************************/
+/**\name FUNCTION FOR ANY MOTION INTERRUPT STATUS */
+/*************************************************/
+ /*!
+ * @brief This API reads the any motion interrupt status
+ * from the register 0x1C bit 2
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ * @param v_any_motion_intr_u8 : The status of any-motion interrupt
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_any_motion_intr(u8
+*v_any_motion_intr_u8);
+/**************************************************/
+/**\name FUNCTION FOR PMU TRIGGER INTERRUPT STATUS */
+/*************************************************/
+/*!
+ * @brief This API reads the power mode trigger interrupt status
+ * from the register 0x1C bit 3
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ *
+ * @param v_pmu_trigger_intr_u8 : The status of power mode trigger interrupt
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_pmu_trigger_intr(u8
+*v_pmu_trigger_intr_u8);
+/**************************************************/
+/**\name FUNCTION FOR DOUBLE TAB STATUS */
+/*************************************************/
+/*!
+ * @brief This API reads the double tab status
+ * from the register 0x1C bit 4
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_double_tap_intr_u8 :The status of double tab interrupt
+ *
+ * @note Double tap interrupt can be configured by the following functions
+ * @note INTERRUPT MAPPING
+ * @note bmi160_set_intr_double_tap()
+ * @note AXIS MAPPING
+ * @note bmi160_get_stat2_tap_first_x()
+ * @note bmi160_get_stat2_tap_first_y()
+ * @note bmi160_get_stat2_tap_first_z()
+ * @note DURATION
+ * @note bmi160_set_intr_tap_durn()
+ * @note THRESHOLD
+ * @note bmi160_set_intr_tap_thres()
+ * @note TAP QUIET
+ * @note bmi160_set_intr_tap_quiet()
+ * @note TAP SHOCK
+ * @note bmi160_set_intr_tap_shock()
+ * @note TAP SOURCE
+ * @note bmi160_set_intr_tap_source()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_double_tap_intr(u8
+*v_double_tap_intr_u8);
+/**************************************************/
+/**\name FUNCTION FOR SINGLE TAB STATUS */
+/*************************************************/
+/*!
+ * @brief This API reads the single tab status
+ * from the register 0x1C bit 5
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_single_tap_intr_u8 :The status of single tap interrupt
+ *
+ * @note Single tap interrupt can be configured by the following functions
+ * @note INTERRUPT MAPPING
+ * @note bmi160_set_intr_single_tap()
+ * @note AXIS MAPPING
+ * @note bmi160_get_stat2_tap_first_x()
+ * @note bmi160_get_stat2_tap_first_y()
+ * @note bmi160_get_stat2_tap_first_z()
+ * @note DURATION
+ * @note bmi160_set_intr_tap_durn()
+ * @note THRESHOLD
+ * @note bmi160_set_intr_tap_thres()
+ * @note TAP QUIET
+ * @note bmi160_set_intr_tap_quiet()
+ * @note TAP SHOCK
+ * @note bmi160_set_intr_tap_shock()
+ * @note TAP SOURCE
+ * @note bmi160_set_intr_tap_source()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_single_tap_intr(u8
+*v_single_tap_intr_u8);
+/**************************************************/
+/**\name FUNCTION FOR ORIENT INTERRUPT STATUS */
+/*************************************************/
+/*!
+ * @brief This API reads the orient status
+ * from the register 0x1C bit 6
+ * flag is associated with a specific interrupt function.
+ * It is set when the orient interrupt triggers. The
+ * setting of INT_LATCH controls if the
+ * interrupt signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_orient_intr_u8 : The status of orient interrupt
+ *
+ * @note For orient interrupt configuration use the following functions
+ * @note STATUS
+ * @note bmi160_get_stat0_orient_intr()
+ * @note AXIS MAPPING
+ * @note bmi160_get_stat3_orient_xy()
+ * @note bmi160_get_stat3_orient_z()
+ * @note bmi160_set_intr_orient_axes_enable()
+ * @note INTERRUPT MAPPING
+ * @note bmi160_set_intr_orient()
+ * @note INTERRUPT OUTPUT
+ * @note bmi160_set_intr_orient_ud_enable()
+ * @note THETA
+ * @note bmi160_set_intr_orient_theta()
+ * @note HYSTERESIS
+ * @note bmi160_set_intr_orient_hyst()
+ * @note BLOCKING
+ * @note bmi160_set_intr_orient_blocking()
+ * @note MODE
+ * @note bmi160_set_intr_orient_mode()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_orient_intr(u8
+*v_orient_intr_u8);
+/**************************************************/
+/**\name FUNCTION FOR FLAT INTERRUPT STATUS */
+/*************************************************/
+/*!
+ * @brief This API reads the flat interrupt status
+ * from the register 0x1C bit 7
+ * flag is associated with a specific interrupt function.
+ * It is set when the flat interrupt triggers. The
+ * setting of INT_LATCH controls if the
+ * interrupt signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_flat_intr_u8 : The status of flat interrupt
+ *
+ * @note For flat configuration use the following functions
+ * @note STATS
+ * @note bmi160_get_stat0_flat_intr()
+ * @note bmi160_get_stat3_flat()
+ * @note INTERRUPT MAPPING
+ * @note bmi160_set_intr_flat()
+ * @note THETA
+ * @note bmi160_set_intr_flat_theta()
+ * @note HOLD TIME
+ * @note bmi160_set_intr_flat_hold()
+ * @note HYSTERESIS
+ * @note bmi160_set_intr_flat_hyst()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat0_flat_intr(u8
+*v_flat_intr_u8);
+/**************************************************/
+/**\name FUNCTION FOR HIGH_G INTERRUPT STATUS */
+/*************************************************/
+/*!
+ * @brief This API reads the high_g interrupt status
+ * from the register 0x1D bit 2
+ * flag is associated with a specific interrupt function.
+ * It is set when the high g interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt signal and hence the
+ * respective interrupt flag will be permanently
+ * latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_high_g_intr_u8 : The status of high_g interrupt
+ *
+ * @note High_g interrupt configured by following functions
+ * @note STATUS
+ * @note bmi160_get_stat1_high_g_intr()
+ * @note AXIS MAPPING
+ * @note bmi160_get_stat3_high_g_first_x()
+ * @note bmi160_get_stat3_high_g_first_y()
+ * @note bmi160_get_stat3_high_g_first_z()
+ * @note SIGN MAPPING
+ * @note bmi160_get_stat3_high_g_first_sign()
+ * @note INTERRUPT MAPPING
+ * @note bmi160_set_intr_high_g()
+ * @note HYSTERESIS
+ * @note bmi160_set_intr_high_g_hyst()
+ * @note DURATION
+ * @note bmi160_set_intr_high_g_durn()
+ * @note THRESHOLD
+ * @note bmi160_set_intr_high_g_thres()
+ * @note SOURCE
+ * @note bmi160_set_intr_low_high_source()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat1_high_g_intr(u8
+*v_high_g_intr_u8);
+/**************************************************/
+/**\name FUNCTION FOR LOW_G INTERRUPT STATUS */
+/*************************************************/
+/*!
+ * @brief This API reads the low g interrupt status
+ * from the register 0x1D bit 3
+ * flag is associated with a specific interrupt function.
+ * It is set when the low g interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_low_g_intr_u8 : The status of low_g interrupt
+ *
+ * @note Low_g interrupt configured by following functions
+ * @note STATUS
+ * @note bmi160_get_stat1_low_g_intr()
+ * @note INTERRUPT MAPPING
+ * @note bmi160_set_intr_low_g()
+ * @note SOURCE
+ * @note bmi160_set_intr_low_high_source()
+ * @note DURATION
+ * @note bmi160_set_intr_low_g_durn()
+ * @note THRESHOLD
+ * @note bmi160_set_intr_low_g_thres()
+ * @note HYSTERESIS
+ * @note bmi160_set_intr_low_g_hyst()
+ * @note MODE
+ * @note bmi160_set_intr_low_g_mode()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat1_low_g_intr(u8
+*v_low_g_intr_u8);
+/**************************************************/
+/**\name FUNCTION FOR DATA READY INTERRUPT STATUS */
+/*************************************************/
+/*!
+ * @brief This API reads data ready interrupt status
+ * from the register 0x1D bit 4
+ * flag is associated with a specific interrupt function.
+ * It is set when the data ready interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_data_rdy_intr_u8 : The status of data ready interrupt
+ *
+ * @note Data ready interrupt configured by following functions
+ * @note STATUS
+ * @note bmi160_get_stat1_data_rdy_intr()
+ * @note INTERRUPT MAPPING
+ * @note bmi160_set_intr_data_rdy()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat1_data_rdy_intr(u8
+*v_data_rdy_intr_u8);
+/**************************************************/
+/**\name FUNCTIONS FOR FIFO FULL AND WATER MARK INTERRUPT STATUS*/
+/*************************************************/
+/*!
+ * @brief This API reads data ready FIFO full interrupt status
+ * from the register 0x1D bit 5
+ * flag is associated with a specific interrupt function.
+ * It is set when the FIFO full interrupt triggers. The
+ * setting of INT_LATCH controls if the
+ * interrupt signal and hence the
+ * respective interrupt flag will
+ * be permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_fifo_full_intr_u8 : The status of fifo full interrupt
+ *
+ * @note FIFO full interrupt can be configured by following functions
+ * @note bmi160_set_intr_fifo_full()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat1_fifo_full_intr(u8
+*v_fifo_full_intr_u8);
+/*!
+ * @brief This API reads data
+ * ready FIFO watermark interrupt status
+ * from the register 0x1D bit 6
+ * flag is associated with a specific interrupt function.
+ * It is set when the FIFO watermark interrupt triggers. The
+ * setting of INT_LATCH controls if the
+ * interrupt signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_fifo_wm_intr_u8 : The status of fifo water mark interrupt
+ *
+ * @note FIFO full interrupt can be configured by following functions
+ * @note bmi160_set_intr_fifo_wm()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat1_fifo_wm_intr(u8
+*v_fifo_wm_intr_u8);
+/**************************************************/
+/**\name FUNCTIONS FOR NO MOTION INTERRUPT STATUS*/
+/*************************************************/
+/*!
+ * @brief This API reads data ready no motion interrupt status
+ * from the register 0x1D bit 7
+ * flag is associated with a specific interrupt function.
+ * It is set when the no motion interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt signal and hence the
+ * respective interrupt flag will be permanently
+ * latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_nomotion_intr_u8 : The status of no motion interrupt
+ *
+ * @note No motion interrupt can be configured by following function
+ * @note STATUS
+ * @note bmi160_get_stat1_nomotion_intr()
+ * @note INTERRUPT MAPPING
+ * @note bmi160_set_intr_nomotion()
+ * @note DURATION
+ * @note bmi160_set_intr_slow_no_motion_durn()
+ * @note THRESHOLD
+ * @note bmi160_set_intr_slow_no_motion_thres()
+ * @note SLOW/NO MOTION SELECT
+ * @note bmi160_set_intr_slow_no_motion_select()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat1_nomotion_intr(u8
+*nomo_intr);
+/**************************************************/
+/**\name FUNCTIONS FOR ANY MOTION FIRST XYZ AND SIGN INTERRUPT STATUS*/
+/*************************************************/
+/*!
+ * @brief This API reads the status of any motion first x
+ * from the register 0x1E bit 0
+ *
+ *
+ * @param v_anymotion_first_x_u8 : The status of any motion first x interrupt
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by x axis
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_any_motion_first_x(u8
+*v_anymotion_first_x_u8);
+/*!
+ * @brief This API reads the status of any motion first y interrupt
+ * from the register 0x1E bit 1
+ *
+ *
+ *
+ *@param v_any_motion_first_y_u8 : The status of any motion first y interrupt
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_any_motion_first_y(u8
+*v_any_motion_first_y_u8);
+/*!
+ * @brief This API reads the status of any motion first z interrupt
+ * from the register 0x1E bit 2
+ *
+ *
+ *
+ *
+ *@param v_any_motion_first_z_u8 : The status of any motion first z interrupt
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_any_motion_first_z(u8
+*v_any_motion_first_z_u8);
+/*!
+ * @brief This API reads the any motion sign status from the
+ * register 0x1E bit 3
+ *
+ *
+ *
+ *
+ * @param v_anymotion_sign_u8 : The status of any motion sign
+ * value | sign
+ * -----------|-------------
+ * 0 | positive
+ * 1 | negative
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_any_motion_sign(u8
+*v_anymotion_sign_u8);
+/**************************************************/
+/**\name FUNCTIONS FOR TAP FIRST XYZ AND SIGN INTERRUPT STATUS*/
+/*************************************************/
+/*!
+ * @brief This API reads the any motion tap first x status from the
+ * register 0x1E bit 4
+ *
+ *
+ *
+ *
+ * @param v_tap_first_x_u8 :The status of any motion tap first x
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by x axis
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_tap_first_x(u8
+*v_tap_first_x_u8);
+/*!
+ * @brief This API reads the tap first y interrupt status from the
+ * register 0x1E bit 5
+ *
+ *
+ *
+ *
+ * @param v_tap_first_y_u8 :The status of tap first y interrupt
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_tap_first_y(u8
+*v_tap_first_y_u8);
+/*!
+ * @brief This API reads the tap first z interrupt status from the
+ * register 0x1E bit 6
+ *
+ *
+ *
+ *
+ * @param v_tap_first_z_u8 :The status of tap first z interrupt
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_tap_first_z(u8
+*v_tap_first_z_u8);
+/*!
+ * @brief This API reads the tap sign status from the
+ * register 0x1E bit 7
+ *
+ *
+ *
+ *
+ * @param v_tap_sign_u8 : The status of tap sign
+ * value | sign
+ * -----------|-------------
+ * 0 | positive
+ * 1 | negative
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat2_tap_sign(u8
+*tap_sign);
+/**************************************************/
+/**\name FUNCTIONS FOR HIGH_G FIRST XYZ AND SIGN INTERRUPT STATUS*/
+/*************************************************/
+/*!
+ * @brief This API reads the high_g first x status from the
+ * register 0x1F bit 0
+ *
+ *
+ *
+ *
+ * @param v_high_g_first_x_u8 :The status of high_g first x
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by x axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat3_high_g_first_x(u8
+*v_high_g_first_x_u8);
+/*!
+ * @brief This API reads the high_g first y status from the
+ * register 0x1F bit 1
+ *
+ *
+ *
+ *
+ * @param v_high_g_first_y_u8 : The status of high_g first y
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat3_high_g_first_y(u8
+*v_high_g_first_y_u8);
+/*!
+ * @brief This API reads the high_g first z status from the
+ * register 0x1F bit 3
+ *
+ *
+ *
+ *
+ * @param v_high_g_first_z_u8 : The status of high_g first z
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat3_high_g_first_z(u8
+*v_high_g_first_z_u8);
+/*!
+ * @brief This API reads the high sign status from the
+ * register 0x1F bit 3
+ *
+ *
+ *
+ *
+ * @param v_high_g_sign_u8 :The status of high sign
+ * value | sign
+ * -----------|-------------
+ * 0 | positive
+ * 1 | negative
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat3_high_g_sign(u8
+*v_high_g_sign_u8);
+/**************************************************/
+/**\name FUNCTIONS FOR ORIENT XY AND Z INTERRUPT STATUS*/
+/*************************************************/
+/*!
+ * @brief This API reads the status of orient_xy plane
+ * from the register 0x1F bit 4 and 5
+ *
+ *
+ * @param v_orient_xy_u8 :The status of orient_xy plane
+ * value | status
+ * -----------|-------------
+ * 0x00 | portrait upright
+ * 0x01 | portrait upside down
+ * 0x02 | landscape left
+ * 0x03 | landscape right
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat3_orient_xy(u8
+*v_orient_xy_u8);
+/*!
+ * @brief This API reads the status of orient z plane
+ * from the register 0x1F bit 6
+ *
+ *
+ * @param v_orient_z_u8 :The status of orient z
+ * value | status
+ * -----------|-------------
+ * 0x00 | upward looking
+ * 0x01 | downward looking
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat3_orient_z(u8
+*v_orient_z_u8);
+/**************************************************/
+/**\name FUNCTIONS FOR FLAT INTERRUPT STATUS*/
+/*************************************************/
+/*!
+ * @brief This API reads the flat status from the register
+ * 0x1F bit 7
+ *
+ *
+ * @param v_flat_u8 : The status of flat interrupt
+ * value | status
+ * -----------|-------------
+ * 0x00 | non flat
+ * 0x01 | flat position
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_stat3_flat(u8
+*flat);
+/**************************************************/
+/**\name FUNCTION FOR TEMPERATUE READ */
+/*************************************************/
+/*!
+ * @brief This API reads the temperature of the sensor
+ * from the register 0x21 bit 0 to 7
+ *
+ *
+ *
+ * @param v_temp_s16 : The value of temperature
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_temp(s16
+*v_temp_s16);
+/**************************************************/
+/**\name FUNCTION FOR FIFO LENGTH AND FIFO DATA READ */
+/*************************************************/
+/*!
+ * @brief This API reads the of the sensor
+ * form the register 0x23 and 0x24 bit 0 to 7 and 0 to 2
+ * @brief this byte counter is updated each time a complete frame
+ * was read or writtern
+ *
+ *
+ * @param v_fifo_length_u32 : The value of fifo byte counter
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_fifo_length(
+u32 *v_fifo_length_u32);
+/*!
+ * @brief This API reads the fifo data of the sensor
+ * from the register 0x24
+ * @brief Data format depends on the setting of register FIFO_CONFIG
+ *
+ *
+ *
+ * @param v_fifodata_u8 : Pointer holding the fifo data
+ *
+ * @note For reading FIFO data use the following functions
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_fifo_data(
+u8 *v_fifodata_u8, u16 v_fifo_length_u16);
+/**************************************************/
+/**\name FUNCTION FOR ACCEL CONFIGURATIONS */
+/*************************************************/
+/*!
+ * @brief This API is used to get the
+ * accel output date rate form the register 0x40 bit 0 to 3
+ *
+ *
+ * @param v_output_data_rate_u8 :The value of accel output date rate
+ * value | output data rate
+ * -------|--------------------------
+ * 0 | BMI160_ACCEL_OUTPUT_DATA_RATE_RESERVED
+ * 1 | BMI160_ACCEL_OUTPUT_DATA_RATE_0_78HZ
+ * 2 | BMI160_ACCEL_OUTPUT_DATA_RATE_1_56HZ
+ * 3 | BMI160_ACCEL_OUTPUT_DATA_RATE_3_12HZ
+ * 4 | BMI160_ACCEL_OUTPUT_DATA_RATE_6_25HZ
+ * 5 | BMI160_ACCEL_OUTPUT_DATA_RATE_12_5HZ
+ * 6 | BMI160_ACCEL_OUTPUT_DATA_RATE_25HZ
+ * 7 | BMI160_ACCEL_OUTPUT_DATA_RATE_50HZ
+ * 8 | BMI160_ACCEL_OUTPUT_DATA_RATE_100HZ
+ * 9 | BMI160_ACCEL_OUTPUT_DATA_RATE_200HZ
+ * 10 | BMI160_ACCEL_OUTPUT_DATA_RATE_400HZ
+ * 11 | BMI160_ACCEL_OUTPUT_DATA_RATE_800HZ
+ * 12 | BMI160_ACCEL_OUTPUT_DATA_RATE_1600HZ
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_output_data_rate(
+u8 *v_output_data_rate_u8);
+/*!
+ * @brief This API is used to set the
+ * accel output date rate form the register 0x40 bit 0 to 3
+ *
+ *
+ * @param v_output_data_rate_u8 :The value of accel output date rate
+ * value | output data rate
+ * -------|--------------------------
+ * 0 | BMI160_ACCEL_OUTPUT_DATA_RATE_RESERVED
+ * 1 | BMI160_ACCEL_OUTPUT_DATA_RATE_0_78HZ
+ * 2 | BMI160_ACCEL_OUTPUT_DATA_RATE_1_56HZ
+ * 3 | BMI160_ACCEL_OUTPUT_DATA_RATE_3_12HZ
+ * 4 | BMI160_ACCEL_OUTPUT_DATA_RATE_6_25HZ
+ * 5 | BMI160_ACCEL_OUTPUT_DATA_RATE_12_5HZ
+ * 6 | BMI160_ACCEL_OUTPUT_DATA_RATE_25HZ
+ * 7 | BMI160_ACCEL_OUTPUT_DATA_RATE_50HZ
+ * 8 | BMI160_ACCEL_OUTPUT_DATA_RATE_100HZ
+ * 9 | BMI160_ACCEL_OUTPUT_DATA_RATE_200HZ
+ * 10 | BMI160_ACCEL_OUTPUT_DATA_RATE_400HZ
+ * 11 | BMI160_ACCEL_OUTPUT_DATA_RATE_800HZ
+ * 12 | BMI160_ACCEL_OUTPUT_DATA_RATE_1600HZ
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_output_data_rate(u8 odr);
+/*!
+ * @brief This API is used to get the
+ * accel bandwidth from the register 0x40 bit 4 to 6
+ * @brief bandwidth parameter determines filter configuration(acc_us=0)
+ * and averaging for under sampling mode(acc_us=1)
+ *
+ *
+ * @param v_bw_u8 : The value of accel bandwidth
+ *
+ * @note accel bandwidth depends on under sampling parameter
+ * @note under sampling parameter cab be set by the function
+ * "BMI160_SET_ACCEL_UNDER_SAMPLING_PARAMETER"
+ *
+ * @note Filter configuration
+ * accel_us | Filter configuration
+ * -----------|---------------------
+ * 0x00 | OSR4 mode
+ * 0x01 | OSR2 mode
+ * 0x02 | normal mode
+ * 0x03 | CIC mode
+ * 0x04 | Reserved
+ * 0x05 | Reserved
+ * 0x06 | Reserved
+ * 0x07 | Reserved
+ *
+ * @note accel under sampling mode
+ * accel_us | Under sampling mode
+ * -----------|---------------------
+ * 0x00 | no averaging
+ * 0x01 | average 2 samples
+ * 0x02 | average 4 samples
+ * 0x03 | average 8 samples
+ * 0x04 | average 16 samples
+ * 0x05 | average 32 samples
+ * 0x06 | average 64 samples
+ * 0x07 | average 128 samples
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_bw(u8 *v_bw_u8);
+/*!
+ * @brief This API is used to set the
+ * accel bandwidth from the register 0x40 bit 4 to 6
+ * @brief bandwidth parameter determines filter configuration(acc_us=0)
+ * and averaging for under sampling mode(acc_us=1)
+ *
+ *
+ * @param v_bw_u8 : The value of accel bandwidth
+ *
+ * @note accel bandwidth depends on under sampling parameter
+ * @note under sampling parameter cab be set by the function
+ * "BMI160_SET_ACCEL_UNDER_SAMPLING_PARAMETER"
+ *
+ * @note Filter configuration
+ * accel_us | Filter configuration
+ * -----------|---------------------
+ * 0x00 | OSR4 mode
+ * 0x01 | OSR2 mode
+ * 0x02 | normal mode
+ * 0x03 | CIC mode
+ * 0x04 | Reserved
+ * 0x05 | Reserved
+ * 0x06 | Reserved
+ * 0x07 | Reserved
+ *
+ * @note accel under sampling mode
+ * accel_us | Under sampling mode
+ * -----------|---------------------
+ * 0x00 | no averaging
+ * 0x01 | average 2 samples
+ * 0x02 | average 4 samples
+ * 0x03 | average 8 samples
+ * 0x04 | average 16 samples
+ * 0x05 | average 32 samples
+ * 0x06 | average 64 samples
+ * 0x07 | average 128 samples
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_bw(u8 v_bw_u8);
+/*!
+ * @brief This API is used to get the accel
+ * under sampling parameter form the register 0x40 bit 7
+ *
+ *
+ *
+ *
+ * @param v_accel_under_sampling_u8 : The value of accel under sampling
+ * value | under_sampling
+ * ----------|---------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_under_sampling_parameter(
+u8 *v_accel_under_sampling_u8);
+/*!
+ * @brief This API is used to set the accel
+ * under sampling parameter form the register 0x40 bit 7
+ *
+ *
+ *
+ *
+ * @param v_accel_under_sampling_u8 : The value of accel under sampling
+ * value | under_sampling
+ * ----------|---------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_under_sampling_parameter(
+u8 v_accel_under_sampling_u8);
+/*!
+ * @brief This API is used to get the ranges
+ * (g values) of the accel from the register 0x41 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_range_u8 : The value of accel g range
+ * value | g_range
+ * ----------|-----------
+ * 0x03 | BMI160_ACCEL_RANGE_2G
+ * 0x05 | BMI160_ACCEL_RANGE_4G
+ * 0x08 | BMI160_ACCEL_RANGE_8G
+ * 0x0C | BMI160_ACCEL_RANGE_16G
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_range(
+u8 *v_range_u8);
+/*!
+ * @brief This API is used to set the ranges
+ * (g values) of the accel from the register 0x41 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_range_u8 : The value of accel g range
+ * value | g_range
+ * ----------|-----------
+ * 0x03 | BMI160_ACCEL_RANGE_2G
+ * 0x05 | BMI160_ACCEL_RANGE_4G
+ * 0x08 | BMI160_ACCEL_RANGE_8G
+ * 0x0C | BMI160_ACCEL_RANGE_16G
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_range(
+u8 v_range_u8);
+/**************************************************/
+/**\name FUNCTION FOR GYRO CONFIGURATIONS */
+/*************************************************/
+/*!
+ * @brief This API is used to get the
+ * gyroscope output data rate from the register 0x42 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_output_data_rate_u8 :The value of gyro output data rate
+ * value | gyro output data rate
+ * -----------|-----------------------------
+ * 0x00 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x01 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x02 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x03 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x04 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x05 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x06 | BMI160_GYRO_OUTPUT_DATA_RATE_25HZ
+ * 0x07 | BMI160_GYRO_OUTPUT_DATA_RATE_50HZ
+ * 0x08 | BMI160_GYRO_OUTPUT_DATA_RATE_100HZ
+ * 0x09 | BMI160_GYRO_OUTPUT_DATA_RATE_200HZ
+ * 0x0A | BMI160_GYRO_OUTPUT_DATA_RATE_400HZ
+ * 0x0B | BMI160_GYRO_OUTPUT_DATA_RATE_800HZ
+ * 0x0C | BMI160_GYRO_OUTPUT_DATA_RATE_1600HZ
+ * 0x0D | BMI160_GYRO_OUTPUT_DATA_RATE_3200HZ
+ * 0x0E | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x0F | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_output_data_rate(
+u8 *gyro_output_typer);
+/*!
+ * @brief This API is used to set the
+ * gyroscope output data rate from the register 0x42 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_output_data_rate_u8 :The value of gyro output data rate
+ * value | gyro output data rate
+ * -----------|-----------------------------
+ * 0x00 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x01 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x02 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x03 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x04 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x05 | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x06 | BMI160_GYRO_OUTPUT_DATA_RATE_25HZ
+ * 0x07 | BMI160_GYRO_OUTPUT_DATA_RATE_50HZ
+ * 0x08 | BMI160_GYRO_OUTPUT_DATA_RATE_100HZ
+ * 0x09 | BMI160_GYRO_OUTPUT_DATA_RATE_200HZ
+ * 0x0A | BMI160_GYRO_OUTPUT_DATA_RATE_400HZ
+ * 0x0B | BMI160_GYRO_OUTPUT_DATA_RATE_800HZ
+ * 0x0C | BMI160_GYRO_OUTPUT_DATA_RATE_1600HZ
+ * 0x0D | BMI160_GYRO_OUTPUT_DATA_RATE_3200HZ
+ * 0x0E | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x0F | BMI160_GYRO_OUTPUT_DATA_RATE_RESERVED
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_output_data_rate(
+u8 gyro_output_typer);
+/*!
+ * @brief This API is used to get the
+ * data of gyro from the register 0x42 bit 4 to 5
+ *
+ *
+ *
+ *
+ * @param v_bw_u8 : The value of gyro bandwidth
+ * value | gyro bandwidth
+ * ----------|----------------
+ * 0x00 | BMI160_GYRO_OSR4_MODE
+ * 0x01 | BMI160_GYRO_OSR2_MODE
+ * 0x02 | BMI160_GYRO_NORMAL_MODE
+ * 0x03 | BMI160_GYRO_CIC_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_bw(u8 *v_bw_u8);
+/*!
+ * @brief This API is used to set the
+ * data of gyro from the register 0x42 bit 4 to 5
+ *
+ *
+ *
+ *
+ * @param v_bw_u8 : The value of gyro bandwidth
+ * value | gyro bandwidth
+ * ----------|----------------
+ * 0x00 | BMI160_GYRO_OSR4_MODE
+ * 0x01 | BMI160_GYRO_OSR2_MODE
+ * 0x02 | BMI160_GYRO_NORMAL_MODE
+ * 0x03 | BMI160_GYRO_CIC_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_bw(u8 v_bw_u8);
+/*!
+ * @brief This API reads the range
+ * of gyro from the register 0x43 bit 0 to 2
+ *
+ * @param v_range_u8 : The value of gyro range
+ * value | range
+ * ----------|-------------------------------
+ * 0x00 | BMI160_GYRO_RANGE_2000_DEG_SEC
+ * 0x01 | BMI160_GYRO_RANGE_1000_DEG_SEC
+ * 0x02 | BMI160_GYRO_RANGE_500_DEG_SEC
+ * 0x03 | BMI160_GYRO_RANGE_250_DEG_SEC
+ * 0x04 | BMI160_GYRO_RANGE_125_DEG_SEC
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_range(
+u8 *v_range_u8);
+/*!
+ * @brief This API set the range
+ * of gyro from the register 0x43 bit 0 to 2
+ *
+ * @param v_range_u8 : The value of gyro range
+ * value | range
+ * ----------|-------------------------------
+ * 0x00 | BMI160_GYRO_RANGE_2000_DEG_SEC
+ * 0x01 | BMI160_GYRO_RANGE_1000_DEG_SEC
+ * 0x02 | BMI160_GYRO_RANGE_500_DEG_SEC
+ * 0x03 | BMI160_GYRO_RANGE_250_DEG_SEC
+ * 0x04 | BMI160_GYRO_RANGE_125_DEG_SEC
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_range(
+u8 v_range_u8);
+/**************************************************/
+/**\name FUNCTION FOR MAG CONFIGURATIONS */
+/*************************************************/
+/*!
+ * @brief This API is used to get the
+ * output data rate of magnetometer from the register 0x44 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_output_data_rat_u8e : The value of mag output data rate
+ * value | mag output data rate
+ * ---------|---------------------------
+ * 0x00 |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED
+ * 0x01 |BMI160_MAG_OUTPUT_DATA_RATE_0_78HZ
+ * 0x02 |BMI160_MAG_OUTPUT_DATA_RATE_1_56HZ
+ * 0x03 |BMI160_MAG_OUTPUT_DATA_RATE_3_12HZ
+ * 0x04 |BMI160_MAG_OUTPUT_DATA_RATE_6_25HZ
+ * 0x05 |BMI160_MAG_OUTPUT_DATA_RATE_12_5HZ
+ * 0x06 |BMI160_MAG_OUTPUT_DATA_RATE_25HZ
+ * 0x07 |BMI160_MAG_OUTPUT_DATA_RATE_50HZ
+ * 0x08 |BMI160_MAG_OUTPUT_DATA_RATE_100HZ
+ * 0x09 |BMI160_MAG_OUTPUT_DATA_RATE_200HZ
+ * 0x0A |BMI160_MAG_OUTPUT_DATA_RATE_400HZ
+ * 0x0B |BMI160_MAG_OUTPUT_DATA_RATE_800HZ
+ * 0x0C |BMI160_MAG_OUTPUT_DATA_RATE_1600HZ
+ * 0x0D |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED0
+ * 0x0E |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED1
+ * 0x0F |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED2
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_output_data_rate(u8 *odr);
+/*!
+ * @brief This API is used to set the
+ * output data rate of magnetometer from the register 0x44 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_output_data_rat_u8e : The value of mag output data rate
+ * value | mag output data rate
+ * ---------|---------------------------
+ * 0x00 |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED
+ * 0x01 |BMI160_MAG_OUTPUT_DATA_RATE_0_78HZ
+ * 0x02 |BMI160_MAG_OUTPUT_DATA_RATE_1_56HZ
+ * 0x03 |BMI160_MAG_OUTPUT_DATA_RATE_3_12HZ
+ * 0x04 |BMI160_MAG_OUTPUT_DATA_RATE_6_25HZ
+ * 0x05 |BMI160_MAG_OUTPUT_DATA_RATE_12_5HZ
+ * 0x06 |BMI160_MAG_OUTPUT_DATA_RATE_25HZ
+ * 0x07 |BMI160_MAG_OUTPUT_DATA_RATE_50HZ
+ * 0x08 |BMI160_MAG_OUTPUT_DATA_RATE_100HZ
+ * 0x09 |BMI160_MAG_OUTPUT_DATA_RATE_200HZ
+ * 0x0A |BMI160_MAG_OUTPUT_DATA_RATE_400HZ
+ * 0x0B |BMI160_MAG_OUTPUT_DATA_RATE_800HZ
+ * 0x0C |BMI160_MAG_OUTPUT_DATA_RATE_1600HZ
+ * 0x0D |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED0
+ * 0x0E |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED1
+ * 0x0F |BMI160_MAG_OUTPUT_DATA_RATE_RESERVED2
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_output_data_rate(u8 odr);
+/**************************************************/
+/**\name FUNCTION FOR FIFO CONFIGURATIONS */
+/*************************************************/
+ /*!
+ * @brief This API is used to read Down sampling
+ * for gyro (2**downs_gyro) in the register 0x45 bit 0 to 2
+ *
+ *
+ *
+ *
+ * @param v_fifo_down_gyro_u8 :The value of gyro fifo down
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_down_gyro(
+u8 *v_fifo_down_gyro_u8);
+ /*!
+ * @brief This API is used to set Down sampling
+ * for gyro (2**downs_gyro) in the register 0x45 bit 0 to 2
+ *
+ *
+ *
+ *
+ * @param v_fifo_down_gyro_u8 :The value of gyro fifo down
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_down_gyro(
+u8 v_fifo_down_gyro_u8);
+/*!
+ * @brief This API is used to read gyro fifo filter data
+ * from the register 0x45 bit 3
+ *
+ *
+ *
+ * @param v_gyro_fifo_filter_data_u8 :The value of gyro filter data
+ * value | gyro_fifo_filter_data
+ * ------------|-------------------------
+ * 0x00 | Unfiltered data
+ * 0x01 | Filtered data
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_fifo_filter_data(
+u8 *v_gyro_fifo_filter_data_u8);
+/*!
+ * @brief This API is used to set gyro fifo filter data
+ * from the register 0x45 bit 3
+ *
+ *
+ *
+ * @param v_gyro_fifo_filter_data_u8 :The value of gyro filter data
+ * value | gyro_fifo_filter_data
+ * ------------|-------------------------
+ * 0x00 | Unfiltered data
+ * 0x01 | Filtered data
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_fifo_filter_data(
+u8 v_gyro_fifo_filter_data_u8);
+/*!
+ * @brief This API is used to read Down sampling
+ * for accel (2*downs_accel) from the register 0x45 bit 4 to 6
+ *
+ *
+ *
+ *
+ * @param v_fifo_down_u8 :The value of accel fifo down
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_down_accel(
+u8 *v_fifo_down_u8);
+ /*!
+ * @brief This API is used to set Down sampling
+ * for accel (2*downs_accel) from the register 0x45 bit 4 to 6
+ *
+ *
+ *
+ *
+ * @param v_fifo_down_u8 :The value of accel fifo down
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_down_accel(
+u8 v_fifo_down_u8);
+/*!
+ * @brief This API is used to read accel fifo filter data
+ * from the register 0x45 bit 7
+ *
+ *
+ *
+ * @param v_accel_fifo_filter_u8 :The value of accel filter data
+ * value | accel_fifo_filter_data
+ * ------------|-------------------------
+ * 0x00 | Unfiltered data
+ * 0x01 | Filtered data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_fifo_filter_data(
+u8 *v_accel_fifo_filter_u8);
+/*!
+ * @brief This API is used to set accel fifo filter data
+ * from the register 0x45 bit 7
+ *
+ *
+ *
+ * @param v_accel_fifo_filter_u8 :The value of accel filter data
+ * value | accel_fifo_filter_data
+ * ------------|-------------------------
+ * 0x00 | Unfiltered data
+ * 0x01 | Filtered data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_fifo_filter_data(
+u8 v_accel_fifo_filter_u8);
+/**************************************************/
+/**\name FUNCTION FOR FIFO WATER MARK ENABLE */
+/*************************************************/
+/*!
+ * @brief This API is used to Trigger an interrupt
+ * when FIFO contains water mark level from the register 0x46 bit 0 to 7
+ *
+ *
+ *
+ * @param v_fifo_wm_u8 : The value of fifo water mark level
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_wm(
+u8 *v_fifo_wm_u8);
+/*!
+ * @brief This API is used to Trigger an interrupt
+ * when FIFO contains water mark level from the register 0x46 bit 0 to 7
+ *
+ *
+ *
+ * @param v_fifo_wm_u8 : The value of fifo water mark level
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_wm(
+u8 v_fifo_wm_u8);
+/**************************************************/
+/**\name FUNCTION FOR FIFO CONFIGURATIONS */
+/*************************************************/
+/*!
+ * @brief This API reads fifo sensor time
+ * frame after the last valid data frame form the register 0x47 bit 1
+ *
+ *
+ *
+ *
+ * @param v_fifo_time_enable_u8 : The value of sensor time
+ * value | fifo sensor time
+ * ------------|-------------------------
+ * 0x00 | do not return sensortime frame
+ * 0x01 | return sensortime frame
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_time_enable(
+u8 *v_fifo_time_enable_u8);
+/*!
+ * @brief This API set fifo sensor time
+ * frame after the last valid data frame form the register 0x47 bit 1
+ *
+ *
+ *
+ *
+ * @param v_fifo_time_enable_u8 : The value of sensor time
+ * value | fifo sensor time
+ * ------------|-------------------------
+ * 0x00 | do not return sensortime frame
+ * 0x01 | return sensortime frame
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_time_enable(
+u8 v_fifo_time_enable_u8);
+/*!
+ * @brief This API reads FIFO tag interrupt2 enable status
+ * from the resister 0x47 bit 2
+ *
+ * @param v_fifo_tag_intr2_u8 : The value of fifo tag interrupt
+ * value | fifo tag interrupt
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_tag_intr2_enable(
+u8 *v_fifo_tag_intr2_u8);
+/*!
+ * @brief This API set FIFO tag interrupt2 enable status
+ * from the resister 0x47 bit 2
+ *
+ * @param v_fifo_tag_intr2_u8 : The value of fifo tag interrupt
+ * value | fifo tag interrupt
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_tag_intr2_enable(
+u8 v_fifo_tag_intr2_u8);
+/*!
+ * @brief This API get FIFO tag interrupt1 enable status
+ * from the resister 0x47 bit 3
+ *
+ * @param v_fifo_tag_intr1_u8 :The value of fifo tag interrupt1
+ * value | fifo tag interrupt
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_tag_intr1_enable(
+u8 *v_fifo_tag_intr1_u8);
+/*!
+ * @brief This API set FIFO tag interrupt1 enable status
+ * from the resister 0x47 bit 3
+ *
+ * @param v_fifo_tag_intr1_u8 :The value of fifo tag interrupt1
+ * value | fifo tag interrupt
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_tag_intr1_enable(
+u8 v_fifo_tag_intr1_u8);
+/*!
+ * @brief This API reads FIFO frame
+ * header enable from the register 0x47 bit 4
+ *
+ * @param v_fifo_header_u8 :The value of fifo header
+ * value | fifo header
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_header_enable(
+u8 *v_fifo_header_u8);
+/*!
+ * @brief This API set FIFO frame
+ * header enable from the register 0x47 bit 4
+ *
+ * @param v_fifo_header_u8 :The value of fifo header
+ * value | fifo header
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_header_enable(
+u8 v_fifo_header_u8);
+/*!
+ * @brief This API is used to read stored
+ * magnetometer data in FIFO (all 3 axes) from the register 0x47 bit 5
+ *
+ * @param v_fifo_mag_u8 : The value of fifo mag enble
+ * value | fifo mag
+ * ----------|-------------------
+ * 0x00 | no magnetometer data is stored
+ * 0x01 | magnetometer data is stored
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_mag_enable(
+u8 *v_fifo_mag_u8);
+/*!
+ * @brief This API is used to set stored
+ * magnetometer data in FIFO (all 3 axes) from the register 0x47 bit 5
+ *
+ * @param v_fifo_mag_u8 : The value of fifo mag enble
+ * value | fifo mag
+ * ----------|-------------------
+ * 0x00 | no magnetometer data is stored
+ * 0x01 | magnetometer data is stored
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_mag_enable(
+u8 v_fifo_mag_u8);
+/*!
+ * @brief This API is used to read stored
+ * accel data in FIFO (all 3 axes) from the register 0x47 bit 6
+ *
+ * @param v_fifo_accel_u8 : The value of fifo accel enble
+ * value | fifo accel
+ * ----------|-------------------
+ * 0x00 | no accel data is stored
+ * 0x01 | accel data is stored
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_accel_enable(
+u8 *v_fifo_accel_u8);
+/*!
+ * @brief This API is used to set stored
+ * accel data in FIFO (all 3 axes) from the register 0x47 bit 6
+ *
+ * @param v_fifo_accel_u8 : The value of fifo accel enble
+ * value | fifo accel
+ * ----------|-------------------
+ * 0x00 | no accel data is stored
+ * 0x01 | accel data is stored
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_accel_enable(
+u8 v_fifo_accel_u8);
+/*!
+ * @brief This API is used to read stored
+ * gyro data in FIFO (all 3 axes) from the resister 0x47 bit 7
+ *
+ *
+ * @param v_fifo_gyro_u8 : The value of fifo gyro enble
+ * value | fifo gyro
+ * ----------|-------------------
+ * 0x00 | no gyro data is stored
+ * 0x01 | gyro data is stored
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_fifo_gyro_enable(
+u8 *v_fifo_gyro_u8);
+/*!
+ * @brief This API is used to set stored
+ * gyro data in FIFO (all 3 axes) from the resister 0x47 bit 7
+ *
+ *
+ * @param v_fifo_gyro_u8 : The value of fifo gyro enble
+ * value | fifo gyro
+ * ----------|-------------------
+ * 0x00 | no gyro data is stored
+ * 0x01 | gyro data is stored
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_fifo_gyro_enable(
+u8 v_fifo_gyro_u8);
+/***************************************************************/
+/**\name FUNCTION FOR MAG I2C ADDRESS SELECTION */
+/***************************************************************/
+/*!
+ * @brief This API is used to read
+ * I2C device address of auxiliary mag from the register 0x4B bit 1 to 7
+ *
+ *
+ *
+ *
+ * @param v_i2c_device_addr_u8 : The value of mag I2C device address
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_i2c_device_addr(
+u8 *v_i2c_device_addr_u8);
+/*!
+ * @brief This API is used to set
+ * I2C device address of auxiliary mag from the register 0x4B bit 1 to 7
+ *
+ *
+ *
+ *
+ * @param v_i2c_device_addr_u8 : The value of mag I2C device address
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_i2c_device_addr(
+u8 v_i2c_device_addr_u8);
+/*!
+ * @brief This API is used to read
+ * Burst data length (1,2,6,8 byte) from the register 0x4C bit 0 to 1
+ *
+ *
+ *
+ *
+ * @param v_mag_burst_u8 : The data of mag burst read lenth
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_burst(
+u8 *v_mag_burst_u8);
+/*!
+ * @brief This API is used to set
+ * Burst data length (1,2,6,8 byte) from the register 0x4C bit 0 to 1
+ *
+ *
+ *
+ *
+ * @param v_mag_burst_u8 : The data of mag burst read lenth
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_burst(
+u8 v_mag_burst_u8);
+/***************************************************************/
+/**\name FUNCTION FOR MAG OFFSET */
+/***************************************************************/
+/*!
+ * @brief This API is used to read
+ * trigger-readout offset in units of 2.5 ms. If set to zero,
+ * the offset is maximum, i.e. after readout a trigger
+ * is issued immediately. from the register 0x4C bit 2 to 5
+ *
+ *
+ *
+ *
+ * @param v_mag_offset_u8 : The value of mag offset
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_offset(
+u8 *v_mag_offset_u8);
+/*!
+ * @brief This API is used to set
+ * trigger-readout offset in units of 2.5 ms. If set to zero,
+ * the offset is maximum, i.e. after readout a trigger
+ * is issued immediately. from the register 0x4C bit 2 to 5
+ *
+ *
+ *
+ *
+ * @param v_mag_offset_u8 : The value of mag offset
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_offset(
+u8 v_mag_offset_u8);
+/***************************************************************/
+/**\name FUNCTION FOR MAG MANUAL/AUTO MODE SELECTION */
+/***************************************************************/
+/*!
+ * @brief This API is used to read
+ * Enable register access on MAG_IF[2] or MAG_IF[3] writes.
+ * This implies that the DATA registers are not updated with
+ * magnetometer values. Accessing magnetometer requires
+ * the magnetometer in normal mode in PMU_STATUS.
+ * from the register 0x4C bit 7
+ *
+ *
+ *
+ * @param v_mag_manual_u8 : The value of mag manual enable
+ * value | mag manual
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_manual_enable(
+u8 *v_mag_manual_u8);
+/*!
+ * @brief This API is used to set
+ * Enable register access on MAG_IF[2] or MAG_IF[3] writes.
+ * This implies that the DATA registers are not updated with
+ * magnetometer values. Accessing magnetometer requires
+ * the magnetometer in normal mode in PMU_STATUS.
+ * from the register 0x4C bit 7
+ *
+ *
+ *
+ * @param v_mag_manual_u8 : The value of mag manual enable
+ * value | mag manual
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_manual_enable(
+u8 v_mag_manual_u8);
+/***************************************************************/
+/**\name FUNCTIONS FOR MAG READ, WRITE AND WRITE DATA ADDRESS */
+/***************************************************************/
+/*!
+ * @brief This API is used to read data
+ * magnetometer address to read from the register 0x4D bit 0 to 7
+ * @brief It used to provide mag read address of auxiliary mag
+ *
+ *
+ *
+ *
+ * @param v_mag_read_addr_u8 : The value of address need to be read
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_read_addr(
+u8 *v_mag_read_addr_u8);
+/*!
+ * @brief This API is used to set
+ * magnetometer write address from the register 0x4D bit 0 to 7
+ * @brief mag write address writes the address of auxiliary mag to write
+ *
+ *
+ *
+ * @param v_mag_read_addr_u8:
+ * The data of auxiliary mag address to write data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_read_addr(
+u8 v_mag_read_addr_u8);
+/*!
+ * @brief This API is used to read
+ * magnetometer write address from the register 0x4E bit 0 to 7
+ * @brief mag write address writes the address of auxiliary mag to write
+ *
+ *
+ *
+ * @param v_mag_write_addr_u8:
+ * The data of auxiliary mag address to write data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_write_addr(
+u8 *v_mag_write_addr_u8);
+/*!
+ * @brief This API is used to set
+ * magnetometer write address from the register 0x4E bit 0 to 7
+ * @brief mag write address writes the address of auxiliary mag to write
+ *
+ *
+ *
+ * @param v_mag_write_addr_u8:
+ * The data of auxiliary mag address to write data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_write_addr(
+u8 v_mag_write_addr_u8);
+/*!
+ * @brief This API is used to read magnetometer write data
+ * form the resister 0x4F bit 0 to 7
+ * @brief This writes the data will be wrote to mag
+ *
+ *
+ *
+ * @param v_mag_write_data_u8: The value of mag data
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_mag_write_data(
+u8 *v_mag_write_data_u8);
+/*!
+ * @brief This API is used to set magnetometer write data
+ * form the resister 0x4F bit 0 to 7
+ * @brief This writes the data will be wrote to mag
+ *
+ *
+ *
+ * @param v_mag_write_data_u8: The value of mag data
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_mag_write_data(
+u8 v_mag_write_data_u8);
+/***************************************************************/
+/**\name FUNCTION FOR INTERRUPT ENABLE OF
+ANY-MOTION XYZ, DOUBLE AND SINGLE TAP, ORIENT AND FLAT */
+/***************************************************************/
+/*!
+ * @brief This API is used to read
+ * interrupt enable from the register 0x50 bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_enable_u8 : Value to decided to select interrupt
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_ANY_MOTION_X_ENABLE
+ * 1 | BMI160_ANY_MOTION_Y_ENABLE
+ * 2 | BMI160_ANY_MOTION_Z_ENABLE
+ * 3 | BMI160_DOUBLE_TAP_ENABLE
+ * 4 | BMI160_SINGLE_TAP_ENABLE
+ * 5 | BMI160_ORIENT_ENABLE
+ * 6 | BMI160_FLAT_ENABLE
+ *
+ * @param v_intr_enable_zero_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_enable_0(
+u8 enable, u8 *v_intr_enable_zero_u8);
+/*!
+ * @brief This API is used to set
+ * interrupt enable from the register 0x50 bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_enable_u8 : Value to decided to select interrupt
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_ANY_MOTION_X_ENABLE
+ * 1 | BMI160_ANY_MOTION_Y_ENABLE
+ * 2 | BMI160_ANY_MOTION_Z_ENABLE
+ * 3 | BMI160_DOUBLE_TAP_ENABLE
+ * 4 | BMI160_SINGLE_TAP_ENABLE
+ * 5 | BMI160_ORIENT_ENABLE
+ * 6 | BMI160_FLAT_ENABLE
+ *
+ * @param v_intr_enable_zero_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_enable_0(
+u8 enable, u8 v_intr_enable_zero_u8);
+/***************************************************************/
+/**\name FUNCTION FOR INTERRUPT ENABLE OF
+HIGH_G XYZ, LOW_G, DATA READY, FIFO FULL AND FIFO WATER MARK */
+/***************************************************************/
+/*!
+ * @brief This API is used to read
+ * interrupt enable byte1 from the register 0x51 bit 0 to 6
+ * @brief It read the high_g_x,high_g_y,high_g_z,low_g_enable
+ * data ready, fifo full and fifo water mark.
+ *
+ *
+ *
+ * @param v_enable_u8 : The value of interrupt enable
+ * @param v_enable_u8 : Value to decided to select interrupt
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_HIGH_G_X_ENABLE
+ * 1 | BMI160_HIGH_G_Y_ENABLE
+ * 2 | BMI160_HIGH_G_Z_ENABLE
+ * 3 | BMI160_LOW_G_ENABLE
+ * 4 | BMI160_DATA_RDY_ENABLE
+ * 5 | BMI160_FIFO_FULL_ENABLE
+ * 6 | BMI160_FIFO_WM_ENABLE
+ *
+ * @param v_intr_enable_1_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_enable_1(
+u8 enable, u8 *v_intr_enable_1_u8);
+/*!
+ * @brief This API is used to set
+ * interrupt enable byte1 from the register 0x51 bit 0 to 6
+ * @brief It read the high_g_x,high_g_y,high_g_z,low_g_enable
+ * data ready, fifo full and fifo water mark.
+ *
+ *
+ *
+ * @param v_enable_u8 : The value of interrupt enable
+ * @param v_enable_u8 : Value to decided to select interrupt
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_HIGH_G_X_ENABLE
+ * 1 | BMI160_HIGH_G_Y_ENABLE
+ * 2 | BMI160_HIGH_G_Z_ENABLE
+ * 3 | BMI160_LOW_G_ENABLE
+ * 4 | BMI160_DATA_RDY_ENABLE
+ * 5 | BMI160_FIFO_FULL_ENABLE
+ * 6 | BMI160_FIFO_WM_ENABLE
+ *
+ * @param v_intr_enable_1_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_enable_1(
+u8 enable, u8 v_intr_enable_1_u8);
+/***************************************************************/
+/**\name FUNCTION FOR INTERRUPT ENABLE OF
+NO MOTION XYZ */
+/***************************************************************/
+/*!
+ * @brief This API is used to read
+ * interrupt enable byte2 from the register bit 0x52 bit 0 to 3
+ * @brief It reads no motion x,y and z
+ *
+ *
+ *
+ * @param v_enable_u8: The value of interrupt enable
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_NOMOTION_X_ENABLE
+ * 1 | BMI160_NOMOTION_Y_ENABLE
+ * 2 | BMI160_NOMOTION_Z_ENABLE
+ *
+ * @param v_intr_enable_2_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_enable_2(
+u8 enable, u8 *v_intr_enable_2_u8);
+/*!
+ * @brief This API is used to set
+ * interrupt enable byte2 from the register bit 0x52 bit 0 to 3
+ * @brief It reads no motion x,y and z
+ *
+ *
+ *
+ * @param v_enable_u8: The value of interrupt enable
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_NOMOTION_X_ENABLE
+ * 1 | BMI160_NOMOTION_Y_ENABLE
+ * 2 | BMI160_NOMOTION_Z_ENABLE
+ *
+ * @param v_intr_enable_2_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_enable_2(
+u8 enable, u8 v_intr_enable_2_u8);
+/***************************************************************/
+/**\name FUNCTION FOR INTERRUPT ENABLE OF
+ STEP DETECTOR */
+/***************************************************************/
+ /*!
+ * @brief This API is used to read
+ * interrupt enable step detector interrupt from
+ * the register bit 0x52 bit 3
+ *
+ *
+ *
+ *
+ * @param v_step_intr_u8 : The value of step detector interrupt enable
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_step_detector_enable(
+u8 *v_step_intr_u8);
+ /*!
+ * @brief This API is used to set
+ * interrupt enable step detector interrupt from
+ * the register bit 0x52 bit 3
+ *
+ *
+ *
+ *
+ * @param v_step_intr_u8 : The value of step detector interrupt enable
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_step_detector_enable(
+u8 v_step_intr_u8);
+/***************************************************************/
+/**\name FUNCTION FOR INTERRUPT CONTROL */
+/***************************************************************/
+/*!
+ * @brief Configure trigger condition of interrupt1
+ * and interrupt2 pin from the register 0x53
+ * @brief interrupt1 - bit 0
+ * @brief interrupt2 - bit 4
+ *
+ * @param v_channel_u8: The value of edge trigger selection
+ * v_channel_u8 | Edge trigger
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_EDGE_CTRL
+ * 1 | BMI160_INTR2_EDGE_CTRL
+ *
+ * @param v_intr_edge_ctrl_u8 : The value of edge trigger enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_EDGE
+ * 0x00 | BMI160_LEVEL
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_edge_ctrl(
+u8 v_channel_u8, u8 *v_intr_edge_ctrl_u8);
+/*!
+ * @brief Configure trigger condition of interrupt1
+ * and interrupt2 pin from the register 0x53
+ * @brief interrupt1 - bit 0
+ * @brief interrupt2 - bit 4
+ *
+ * @param v_channel_u8: The value of edge trigger selection
+ * v_channel_u8 | Edge trigger
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_EDGE_CTRL
+ * 1 | BMI160_INTR2_EDGE_CTRL
+ *
+ * @param v_intr_edge_ctrl_u8 : The value of edge trigger enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_EDGE
+ * 0x00 | BMI160_LEVEL
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_edge_ctrl(
+u8 v_channel_u8, u8 v_intr_edge_ctrl_u8);
+/*!
+ * @brief API used for get the Configure level condition of interrupt1
+ * and interrupt2 pin form the register 0x53
+ * @brief interrupt1 - bit 1
+ * @brief interrupt2 - bit 5
+ *
+ * @param v_channel_u8: The value of level condition selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_LEVEL
+ * 1 | BMI160_INTR2_LEVEL
+ *
+ * @param v_intr_level_u8 : The value of level of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | BMI160_LEVEL_HIGH
+ * 0x00 | BMI160_LEVEL_LOW
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_level(
+u8 v_channel_u8, u8 *v_intr_level_u8);
+/*!
+ * @brief API used for set the Configure level condition of interrupt1
+ * and interrupt2 pin form the register 0x53
+ * @brief interrupt1 - bit 1
+ * @brief interrupt2 - bit 5
+ *
+ * @param v_channel_u8: The value of level condition selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_LEVEL
+ * 1 | BMI160_INTR2_LEVEL
+ *
+ * @param v_intr_level_u8 : The value of level of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | BMI160_LEVEL_HIGH
+ * 0x00 | BMI160_LEVEL_LOW
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_level(
+u8 v_channel_u8, u8 v_intr_level_u8);
+/*!
+ * @brief API used to get configured output enable of interrupt1
+ * and interrupt2 from the register 0x53
+ * @brief interrupt1 - bit 2
+ * @brief interrupt2 - bit 6
+ *
+ *
+ * @param v_channel_u8: The value of output type enable selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_OUTPUT_TYPE
+ * 1 | BMI160_INTR2_OUTPUT_TYPE
+ *
+ * @param v_intr_output_type_u8 :
+ * The value of output type of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | BMI160_OPEN_DRAIN
+ * 0x00 | BMI160_PUSH_PULL
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_output_type(
+u8 v_channel_u8, u8 *v_intr_output_type_u8);
+/*!
+ * @brief API used to set output enable of interrupt1
+ * and interrupt2 from the register 0x53
+ * @brief interrupt1 - bit 2
+ * @brief interrupt2 - bit 6
+ *
+ *
+ * @param v_channel_u8: The value of output type enable selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_OUTPUT_TYPE
+ * 1 | BMI160_INTR2_OUTPUT_TYPE
+ *
+ * @param v_intr_output_type_u8 :
+ * The value of output type of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | BMI160_OPEN_DRAIN
+ * 0x00 | BMI160_PUSH_PULL
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_output_type(
+u8 v_channel_u8, u8 v_intr_output_type_u8);
+ /*!
+ * @brief API used to get the Output enable for interrupt1
+ * and interrupt1 pin from the register 0x53
+ * @brief interrupt1 - bit 3
+ * @brief interrupt2 - bit 7
+ *
+ * @param v_channel_u8: The value of output enable selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_OUTPUT_TYPE
+ * 1 | BMI160_INTR2_OUTPUT_TYPE
+ *
+ * @param v_output_enable_u8 :
+ * The value of output enable of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | BMI160_INPUT
+ * 0x00 | BMI160_OUTPUT
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_output_enable(
+u8 v_channel_u8, u8 *v_output_enable_u8);
+ /*!
+ * @brief API used to set the Output enable for interrupt1
+ * and interrupt1 pin from the register 0x53
+ * @brief interrupt1 - bit 3
+ * @brief interrupt2 - bit 7
+ *
+ * @param v_channel_u8: The value of output enable selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_OUTPUT_TYPE
+ * 1 | BMI160_INTR2_OUTPUT_TYPE
+ *
+ * @param v_output_enable_u8 :
+ * The value of output enable of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | BMI160_INPUT
+ * 0x00 | BMI160_OUTPUT
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_output_enable(
+u8 v_channel_u8, u8 v_output_enable_u8);
+/***************************************************************/
+/**\name FUNCTION FOR INTERRUPT LATCH INTERRUPT */
+/***************************************************************/
+/*!
+* @brief This API is used to get the latch duration
+* from the register 0x54 bit 0 to 3
+* @brief This latch selection is not applicable for data ready,
+* orientation and flat interrupts.
+*
+*
+*
+* @param v_latch_intr_u8 : The value of latch duration
+* Latch Duration | value
+* --------------------------------------|------------------
+* BMI160_LATCH_DUR_NONE | 0x00
+* BMI160_LATCH_DUR_312_5_MICRO_SEC | 0x01
+* BMI160_LATCH_DUR_625_MICRO_SEC | 0x02
+* BMI160_LATCH_DUR_1_25_MILLI_SEC | 0x03
+* BMI160_LATCH_DUR_2_5_MILLI_SEC | 0x04
+* BMI160_LATCH_DUR_5_MILLI_SEC | 0x05
+* BMI160_LATCH_DUR_10_MILLI_SEC | 0x06
+* BMI160_LATCH_DUR_20_MILLI_SEC | 0x07
+* BMI160_LATCH_DUR_40_MILLI_SEC | 0x08
+* BMI160_LATCH_DUR_80_MILLI_SEC | 0x09
+* BMI160_LATCH_DUR_160_MILLI_SEC | 0x0A
+* BMI160_LATCH_DUR_320_MILLI_SEC | 0x0B
+* BMI160_LATCH_DUR_640_MILLI_SEC | 0x0C
+* BMI160_LATCH_DUR_1_28_SEC | 0x0D
+* BMI160_LATCH_DUR_2_56_SEC | 0x0E
+* BMI160_LATCHED | 0x0F
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_latch_intr(
+u8 *v_latch_intr_u8);
+/*!
+* @brief This API is used to set the latch duration
+* from the register 0x54 bit 0 to 3
+* @brief This latch selection is not applicable for data ready,
+* orientation and flat interrupts.
+*
+*
+*
+* @param v_latch_intr_u8 : The value of latch duration
+* Latch Duration | value
+* --------------------------------------|------------------
+* BMI160_LATCH_DUR_NONE | 0x00
+* BMI160_LATCH_DUR_312_5_MICRO_SEC | 0x01
+* BMI160_LATCH_DUR_625_MICRO_SEC | 0x02
+* BMI160_LATCH_DUR_1_25_MILLI_SEC | 0x03
+* BMI160_LATCH_DUR_2_5_MILLI_SEC | 0x04
+* BMI160_LATCH_DUR_5_MILLI_SEC | 0x05
+* BMI160_LATCH_DUR_10_MILLI_SEC | 0x06
+* BMI160_LATCH_DUR_20_MILLI_SEC | 0x07
+* BMI160_LATCH_DUR_40_MILLI_SEC | 0x08
+* BMI160_LATCH_DUR_80_MILLI_SEC | 0x09
+* BMI160_LATCH_DUR_160_MILLI_SEC | 0x0A
+* BMI160_LATCH_DUR_320_MILLI_SEC | 0x0B
+* BMI160_LATCH_DUR_640_MILLI_SEC | 0x0C
+* BMI160_LATCH_DUR_1_28_SEC | 0x0D
+* BMI160_LATCH_DUR_2_56_SEC | 0x0E
+* BMI160_LATCHED | 0x0F
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_latch_intr(
+u8 v_latch_intr_u8);
+/*!
+ * @brief API used to get input enable for interrupt1
+ * and interrupt2 pin from the register 0x54
+ * @brief interrupt1 - bit 4
+ * @brief interrupt2 - bit 5
+ *
+ * @param v_channel_u8: The value of input enable selection
+ * v_channel_u8 | input selection
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_INPUT_ENABLE
+ * 1 | BMI160_INTR2_INPUT_ENABLE
+ *
+ * @param v_input_en_u8 :
+ * The value of input enable of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | BMI160_INPUT
+ * 0x00 | BMI160_OUTPUT
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_input_enable(
+u8 v_channel_u8, u8 *v_input_en_u8);
+/*!
+ * @brief API used to set input enable for interrupt1
+ * and interrupt2 pin from the register 0x54
+ * @brief interrupt1 - bit 4
+ * @brief interrupt2 - bit 5
+ *
+ * @param v_channel_u8: The value of input enable selection
+ * v_channel_u8 | input selection
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_INPUT_ENABLE
+ * 1 | BMI160_INTR2_INPUT_ENABLE
+ *
+ * @param v_input_en_u8 :
+ * The value of input enable of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | BMI160_INPUT
+ * 0x00 | BMI160_OUTPUT
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_input_enable(
+u8 v_channel_u8, u8 v_input_en_u8);
+/***************************************************************/
+/**\name FUNCTION FOR INTERRUPT1 AND INTERRUPT2 MAPPING */
+/***************************************************************/
+ /*!
+ * @brief reads the Low g interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 0 in the register 0x55
+ * @brief interrupt2 bit 0 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of low_g selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_LOW_G
+ * 1 | BMI160_INTR2_MAP_LOW_G
+ *
+ * @param v_intr_low_g_u8 : The value of low_g enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_low_g(
+u8 v_channel_u8, u8 *v_intr_low_g_u8);
+ /*!
+ * @brief set the Low g interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 0 in the register 0x55
+ * @brief interrupt2 bit 0 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of low_g selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_LOW_G
+ * 1 | BMI160_INTR2_MAP_LOW_G
+ *
+ * @param v_intr_low_g_u8 : The value of low_g enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_low_g(
+u8 v_channel_u8, u8 v_intr_low_g_u8);
+/*!
+ * @brief Reads the HIGH g interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 1 in the register 0x55
+ * @brief interrupt2 bit 1 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of high_g selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_HIGH_G
+ * 1 | BMI160_INTR2_MAP_HIGH_G
+ *
+ * @param v_intr_high_g_u8 : The value of high_g enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_high_g(
+u8 v_channel_u8, u8 *v_intr_high_g_u8);
+/*!
+ * @brief Write the HIGH g interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 1 in the register 0x55
+ * @brief interrupt2 bit 1 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of high_g selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_HIGH_G
+ * 1 | BMI160_INTR2_MAP_HIGH_G
+ *
+ * @param v_intr_high_g_u8 : The value of high_g enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_high_g(
+u8 v_channel_u8, u8 v_intr_high_g_u8);
+/*!
+ * @brief Reads the Any motion interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 2 in the register 0x55
+ * @brief interrupt2 bit 2 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of any motion selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_ANY_MOTION
+ * 1 | BMI160_INTR2_MAP_ANY_MOTION
+ *
+ * @param v_intr_any_motion_u8 : The value of any motion enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_any_motion(
+u8 v_channel_u8, u8 *v_intr_any_motion_u8);
+/*!
+ * @brief Write the Any motion interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 2 in the register 0x55
+ * @brief interrupt2 bit 2 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of any motion selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_ANY_MOTION
+ * 1 | BMI160_INTR2_MAP_ANY_MOTION
+ *
+ * @param v_intr_any_motion_u8 : The value of any motion enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_any_motion(
+u8 v_channel_u8, u8 v_intr_any_motion_u8);
+/*!
+ * @brief Reads the No motion interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 3 in the register 0x55
+ * @brief interrupt2 bit 3 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of no motion selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_NOMO
+ * 1 | BMI160_INTR2_MAP_NOMO
+ *
+ * @param v_intr_nomotion_u8 : The value of no motion enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_nomotion(
+u8 v_channel_u8, u8 *v_intr_nomotion_u8);
+/*!
+ * @brief Write the No motion interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 3 in the register 0x55
+ * @brief interrupt2 bit 3 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of no motion selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_NOMO
+ * 1 | BMI160_INTR2_MAP_NOMO
+ *
+ * @param v_intr_nomotion_u8 : The value of no motion enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_nomotion(
+u8 v_channel_u8, u8 v_intr_nomotion_u8);
+/*!
+ * @brief Reads the Double Tap interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 4 in the register 0x55
+ * @brief interrupt2 bit 4 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of double tap interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_DOUBLE_TAP
+ * 1 | BMI160_INTR2_MAP_DOUBLE_TAP
+ *
+ * @param v_intr_double_tap_u8 : The value of double tap enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_double_tap(
+u8 v_channel_u8, u8 *v_intr_double_tap_u8);
+/*!
+ * @brief Write the Double Tap interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 4 in the register 0x55
+ * @brief interrupt2 bit 4 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of double tap interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_DOUBLE_TAP
+ * 1 | BMI160_INTR2_MAP_DOUBLE_TAP
+ *
+ * @param v_intr_double_tap_u8 : The value of double tap enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_double_tap(
+u8 v_channel_u8, u8 v_intr_double_tap_u8);
+/*!
+ * @brief Reads the Single Tap interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 5 in the register 0x55
+ * @brief interrupt2 bit 5 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of single tap interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_SINGLE_TAP
+ * 1 | BMI160_INTR2_MAP_SINGLE_TAP
+ *
+ * @param v_intr_single_tap_u8 : The value of single tap enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_single_tap(
+u8 v_channel_u8, u8 *v_intr_single_tap_u8);
+/*!
+ * @brief Write the Single Tap interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 5 in the register 0x55
+ * @brief interrupt2 bit 5 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of single tap interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_SINGLE_TAP
+ * 1 | BMI160_INTR2_MAP_SINGLE_TAP
+ *
+ * @param v_intr_single_tap_u8 : The value of single tap enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_single_tap(
+u8 v_channel_u8, u8 v_intr_single_tap_u8);
+/*!
+ * @brief Reads the Orient interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 6 in the register 0x55
+ * @brief interrupt2 bit 6 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of orient interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_ORIENT
+ * 1 | BMI160_INTR2_MAP_ORIENT
+ *
+ * @param v_intr_orient_u8 : The value of orient enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_orient(
+u8 v_channel_u8, u8 *v_intr_orient_u8);
+/*!
+ * @brief Write the Orient interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 6 in the register 0x55
+ * @brief interrupt2 bit 6 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of orient interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_ORIENT
+ * 1 | BMI160_INTR2_MAP_ORIENT
+ *
+ * @param v_intr_orient_u8 : The value of orient enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_orient(
+u8 v_channel_u8, u8 v_intr_orient_u8);
+ /*!
+ * @brief Reads the Flat interrupt
+ * mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 7 in the register 0x55
+ * @brief interrupt2 bit 7 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of flat interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_FLAT
+ * 1 | BMI160_INTR2_MAP_FLAT
+ *
+ * @param v_intr_flat_u8 : The value of flat enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_flat(
+u8 v_channel_u8, u8 *v_intr_flat_u8);
+ /*!
+ * @brief Write the Flat interrupt
+ * mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 7 in the register 0x55
+ * @brief interrupt2 bit 7 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of flat interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_FLAT
+ * 1 | BMI160_INTR2_MAP_FLAT
+ *
+ * @param v_intr_flat_u8 : The value of flat enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_flat(
+u8 v_channel_u8, u8 v_intr_flat_u8);
+/*!
+ * @brief Reads PMU trigger interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 0 and 4
+ * @brief interrupt1 bit 0 in the register 0x56
+ * @brief interrupt2 bit 4 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of pmu trigger selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_PMUTRIG
+ * 1 | BMI160_INTR2_MAP_PMUTRIG
+ *
+ * @param v_intr_pmu_trig_u8 : The value of pmu trigger enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_pmu_trig(
+u8 v_channel_u8, u8 *v_intr_pmu_trig_u8);
+/*!
+ * @brief Write PMU trigger interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 0 and 4
+ * @brief interrupt1 bit 0 in the register 0x56
+ * @brief interrupt2 bit 4 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of pmu trigger selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_PMUTRIG
+ * 1 | BMI160_INTR2_MAP_PMUTRIG
+ *
+ * @param v_intr_pmu_trig_u8 : The value of pmu trigger enable
+ * value | trigger enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_pmu_trig(
+u8 v_channel_u8, u8 v_intr_pmu_trig_u8);
+/*!
+ * @brief Reads FIFO Full interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 5 and 1
+ * @brief interrupt1 bit 5 in the register 0x56
+ * @brief interrupt2 bit 1 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of fifo full interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_FIFO_FULL
+ * 1 | BMI160_INTR2_MAP_FIFO_FULL
+ *
+ * @param v_intr_fifo_full_u8 : The value of fifo full interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_fifo_full(
+u8 v_channel_u8, u8 *v_intr_fifo_full_u8);
+/*!
+ * @brief Write FIFO Full interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 5 and 1
+ * @brief interrupt1 bit 5 in the register 0x56
+ * @brief interrupt2 bit 1 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of fifo full interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_FIFO_FULL
+ * 1 | BMI160_INTR2_MAP_FIFO_FULL
+ *
+ * @param v_intr_fifo_full_u8 : The value of fifo full interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_fifo_full(
+u8 v_channel_u8, u8 v_intr_fifo_full_u8);
+/*!
+ * @brief Reads FIFO Watermark interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 6 and 2
+ * @brief interrupt1 bit 6 in the register 0x56
+ * @brief interrupt2 bit 2 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of fifo Watermark interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_FIFO_WM
+ * 1 | BMI160_INTR2_MAP_FIFO_WM
+ *
+ * @param v_intr_fifo_wm_u8 : The value of fifo Watermark interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_fifo_wm(
+u8 v_channel_u8, u8 *v_intr_fifo_wm_u8);
+/*!
+ * @brief Write FIFO Watermark interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 6 and 2
+ * @brief interrupt1 bit 6 in the register 0x56
+ * @brief interrupt2 bit 2 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of fifo Watermark interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_FIFO_WM
+ * 1 | BMI160_INTR2_MAP_FIFO_WM
+ *
+ * @param v_intr_fifo_wm_u8 : The value of fifo Watermark interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_fifo_wm(
+u8 v_channel_u8, u8 v_intr_fifo_wm_u8);
+/*!
+ * @brief Reads Data Ready interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56
+ * @brief interrupt1 bit 7 in the register 0x56
+ * @brief interrupt2 bit 3 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of data ready interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_DATA_RDY
+ * 1 | BMI160_INTR2_MAP_DATA_RDY
+ *
+ * @param v_intr_data_rdy_u8 : The value of data ready interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_data_rdy(
+u8 v_channel_u8, u8 *v_intr_data_rdy_u8);
+/*!
+ * @brief Write Data Ready interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56
+ * @brief interrupt1 bit 7 in the register 0x56
+ * @brief interrupt2 bit 3 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of data ready interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | BMI160_INTR1_MAP_DATA_RDY
+ * 1 | BMI160_INTR2_MAP_DATA_RDY
+ *
+ * @param v_intr_data_rdy_u8 : The value of data ready interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | BMI160_ENABLE
+ * 0x00 | BMI160_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_data_rdy(
+u8 v_channel_u8, u8 v_intr_data_rdy_u8);
+/***************************************************************/
+/**\name FUNCTION FOR TAP SOURCE CONFIGURATION */
+/***************************************************************/
+ /*!
+ * @brief This API reads data source for the interrupt
+ * engine for the single and double tap interrupts from the register
+ * 0x58 bit 3
+ *
+ *
+ * @param v_tap_source_u8 : The value of the tap source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_tap_source(
+u8 *v_tap_source_u8);
+ /*!
+ * @brief This API write data source for the interrupt
+ * engine for the single and double tap interrupts from the register
+ * 0x58 bit 3
+ *
+ *
+ * @param v_tap_source_u8 : The value of the tap source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_tap_source(
+u8 v_tap_source_u8);
+/***************************************************************/
+/**\name FUNCTION FOR LOW_G AND HIGH_G SOURCE CONFIGURATION */
+/***************************************************************/
+ /*!
+ * @brief This API Reads Data source for the
+ * interrupt engine for the low and high g interrupts
+ * from the register 0x58 bit 7
+ *
+ * @param v_low_high_source_u8 : The value of the tap source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_low_high_source(
+u8 *v_low_high_source_u8);
+ /*!
+ * @brief This API write Data source for the
+ * interrupt engine for the low and high g interrupts
+ * from the register 0x58 bit 7
+ *
+ * @param v_low_high_source_u8 : The value of the tap source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_low_high_source(
+u8 v_low_high_source_u8);
+/***************************************************************/
+/**\name FUNCTION FOR MOTION SOURCE CONFIGURATION */
+/***************************************************************/
+ /*!
+ * @brief This API reads Data source for the
+ * interrupt engine for the nomotion and anymotion interrupts
+ * from the register 0x59 bit 7
+ *
+ * @param v_motion_source_u8 :
+ * The value of the any/no motion interrupt source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_motion_source(
+u8 *v_motion_source_u8);
+ /*!
+ * @brief This API write Data source for the
+ * interrupt engine for the nomotion and anymotion interrupts
+ * from the register 0x59 bit 7
+ *
+ * @param v_motion_source_u8 :
+ * The value of the any/no motion interrupt source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_motion_source(
+u8 v_motion_source_u8);
+/***************************************************************/
+/**\name FUNCTION FOR LOW_G DURATION CONFIGURATION */
+/***************************************************************/
+/*!
+ * @brief This API is used to read the low_g duration from register
+ * 0x5A bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_low_g_durn_u8 : The value of low_g duration
+ *
+ * @note Low_g duration trigger trigger delay according to
+ * "(v_low_g_durn_u8 * 2.5)ms" in a range from 2.5ms to 640ms.
+ * the default corresponds delay is 20ms
+ * @note When low_g data source of interrupt is unfiltered
+ * the sensor must not be in low power mode
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_low_g_durn(
+u8 *v_low_durn_u8);
+ /*!
+ * @brief This API is used to write the low_g duration from register
+ * 0x5A bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_low_g_durn_u8 : The value of low_g duration
+ *
+ * @note Low_g duration trigger trigger delay according to
+ * "(v_low_g_durn_u8 * 2.5)ms" in a range from 2.5ms to 640ms.
+ * the default corresponds delay is 20ms
+ * @note When low_g data source of interrupt is unfiltered
+ * the sensor must not be in low power mode
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_low_g_durn(
+u8 v_low_durn_u8);
+/***************************************************************/
+/**\name FUNCTION FOR LOW_G THRESH CONFIGURATION */
+/***************************************************************/
+/*!
+ * @brief This API is used to read Threshold
+ * definition for the low-g interrupt from the register 0x5B bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_low_g_thres_u8 : The value of low_g threshold
+ *
+ * @note Low_g interrupt trigger threshold according to
+ * (v_low_g_thres_u8 * 7.81)mg for v_low_g_thres_u8 > 0
+ * 3.91 mg for v_low_g_thres_u8 = 0
+ * The threshold range is form 3.91mg to 2.000mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_low_g_thres(
+u8 *v_low_g_thres_u8);
+/*!
+ * @brief This API is used to write Threshold
+ * definition for the low-g interrupt from the register 0x5B bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_low_g_thres_u8 : The value of low_g threshold
+ *
+ * @note Low_g interrupt trigger threshold according to
+ * (v_low_g_thres_u8 * 7.81)mg for v_low_g_thres_u8 > 0
+ * 3.91 mg for v_low_g_thres_u8 = 0
+ * The threshold range is form 3.91mg to 2.000mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_low_g_thres(
+u8 v_low_g_thres_u8);
+/***************************************************************/
+/**\name FUNCTION FOR LOW_G HYSTERESIS CONFIGURATION */
+/***************************************************************/
+ /*!
+ * @brief This API Reads Low-g interrupt hysteresis
+ * from the register 0x5C bit 0 to 1
+ *
+ * @param v_low_hyst_u8 :The value of low_g hysteresis
+ *
+ * @note Low_g hysteresis calculated by v_low_hyst_u8*125 mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_low_g_hyst(
+u8 *v_low_hyst_u8);
+ /*!
+ * @brief This API write Low-g interrupt hysteresis
+ * from the register 0x5C bit 0 to 1
+ *
+ * @param v_low_hyst_u8 :The value of low_g hysteresis
+ *
+ * @note Low_g hysteresis calculated by v_low_hyst_u8*125 mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_low_g_hyst(
+u8 v_low_hyst_u8);
+/***************************************************************/
+/**\name FUNCTION FOR LOW_G MODE CONFIGURATION */
+/***************************************************************/
+/*!
+ * @brief This API reads Low-g interrupt mode
+ * from the register 0x5C bit 2
+ *
+ * @param v_low_g_mode_u8 : The value of low_g mode
+ * Value | Description
+ * ----------|-----------------
+ * 0 | single-axis
+ * 1 | axis-summing
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_low_g_mode(
+u8 *v_low_g_mode_u8);
+/*!
+ * @brief This API write Low-g interrupt mode
+ * from the register 0x5C bit 2
+ *
+ * @param v_low_g_mode_u8 : The value of low_g mode
+ * Value | Description
+ * ----------|-----------------
+ * 0 | single-axis
+ * 1 | axis-summing
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_low_g_mode(
+u8 v_low_g_mode_u8);
+/***************************************************************/
+/**\name FUNCTION FOR HIGH_G HYST CONFIGURATION */
+/***************************************************************/
+/*!
+ * @brief This API reads High-g interrupt hysteresis
+ * from the register 0x5C bit 6 and 7
+ *
+ * @param v_high_g_hyst_u8 : The value of high hysteresis
+ *
+ * @note High_g hysteresis changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | high_g hysteresis
+ * ----------------|---------------------
+ * 2g | high_hy*125 mg
+ * 4g | high_hy*250 mg
+ * 8g | high_hy*500 mg
+ * 16g | high_hy*1000 mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_high_g_hyst(
+u8 *v_high_g_hyst_u8);
+/*!
+ * @brief This API write High-g interrupt hysteresis
+ * from the register 0x5C bit 6 and 7
+ *
+ * @param v_high_g_hyst_u8 : The value of high hysteresis
+ *
+ * @note High_g hysteresis changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | high_g hysteresis
+ * ----------------|---------------------
+ * 2g | high_hy*125 mg
+ * 4g | high_hy*250 mg
+ * 8g | high_hy*500 mg
+ * 16g | high_hy*1000 mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_high_g_hyst(
+u8 v_high_g_hyst_u8);
+/***************************************************************/
+/**\name FUNCTION FOR HIGH_G DURATION CONFIGURATION */
+/***************************************************************/
+/*!
+ * @brief This API is used to read Delay
+ * time definition for the high-g interrupt from the register
+ * 0x5D bit 0 to 7
+ *
+ *
+ *
+ * @param v_high_g_durn_u8 : The value of high duration
+ *
+ * @note High_g interrupt delay triggered according to
+ * v_high_g_durn_u8 * 2.5ms in a range from 2.5ms to 640ms
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_high_g_durn(
+u8 *v_high_g_durn_u8);
+/*!
+ * @brief This API is used to write Delay
+ * time definition for the high-g interrupt from the register
+ * 0x5D bit 0 to 7
+ *
+ *
+ *
+ * @param v_high_g_durn_u8 : The value of high duration
+ *
+ * @note High_g interrupt delay triggered according to
+ * v_high_g_durn_u8 * 2.5ms in a range from 2.5ms to 640ms
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_high_g_durn(
+u8 v_high_g_durn_u8);
+/***************************************************************/
+/**\name FUNCTION FOR HIGH_G THRESHOLD CONFIGURATION */
+/***************************************************************/
+/*!
+ * @brief This API is used to read Threshold
+ * definition for the high-g interrupt from the register 0x5E 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_high_g_thres_u8 : Pointer holding the value of Threshold
+ * @note High_g threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | high_g threshold
+ * ----------------|---------------------
+ * 2g | v_high_g_thres_u8*7.81 mg
+ * 4g | v_high_g_thres_u8*15.63 mg
+ * 8g | v_high_g_thres_u8*31.25 mg
+ * 16g | v_high_g_thres_u8*62.5 mg
+ * @note when v_high_g_thres_u8 = 0
+ * accel_range | high_g threshold
+ * ----------------|---------------------
+ * 2g | 3.91 mg
+ * 4g | 7.81 mg
+ * 8g | 15.63 mg
+ * 16g | 31.25 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_high_g_thres(
+u8 *v_high_g_thres_u8);
+/*!
+ * @brief This API is used to write Threshold
+ * definition for the high-g interrupt from the register 0x5E 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_high_g_thres_u8 : Pointer holding the value of Threshold
+ * @note High_g threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | high_g threshold
+ * ----------------|---------------------
+ * 2g | v_high_g_thres_u8*7.81 mg
+ * 4g | v_high_g_thres_u8*15.63 mg
+ * 8g | v_high_g_thres_u8*31.25 mg
+ * 16g | v_high_g_thres_u8*62.5 mg
+ * @note when v_high_g_thres_u8 = 0
+ * accel_range | high_g threshold
+ * ----------------|---------------------
+ * 2g | 3.91 mg
+ * 4g | 7.81 mg
+ * 8g | 15.63 mg
+ * 16g | 31.25 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_high_g_thres(
+u8 v_high_g_thres_u8);
+/***************************************************************/
+/**\name FUNCTION FOR ANY MOTION DURATION CONFIGURATION */
+/***************************************************************/
+/*!
+ * @brief This API reads any motion duration
+ * from the register 0x5F bit 0 and 1
+ *
+ * @param v_any_motion_durn_u8 : The value of any motion duration
+ *
+ * @note Any motion duration can be calculated by "v_any_motion_durn_u8 + 1"
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_any_motion_durn(
+u8 *v_any_motion_durn_u8);
+/*!
+ * @brief This API write any motion duration
+ * from the register 0x5F bit 0 and 1
+ *
+ * @param v_any_motion_durn_u8 : The value of any motion duration
+ *
+ * @note Any motion duration can be calculated by "v_any_motion_durn_u8 + 1"
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_any_motion_durn(
+u8 nomotion);
+/***************************************************************/
+/**\name FUNCTION FOR SLOW NO MOTION DURATION CONFIGURATION */
+/***************************************************************/
+ /*!
+ * @brief This API read Slow/no-motion
+ * interrupt trigger delay duration from the register 0x5F bit 2 to 7
+ *
+ * @param v_slow_no_motion_u8 :The value of slow no motion duration
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ * @note
+ * @note v_slow_no_motion_u8(5:4)=0b00 ->
+ * [v_slow_no_motion_u8(3:0) + 1] * 1.28s (1.28s-20.48s)
+ * @note v_slow_no_motion_u8(5:4)=1 ->
+ * [v_slow_no_motion_u8(3:0)+5] * 5.12s (25.6s-102.4s)
+ * @note v_slow_no_motion_u8(5)='1' ->
+ * [(v_slow_no_motion_u8:0)+11] * 10.24s (112.64s-430.08s);
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_slow_no_motion_durn(
+u8 *v_slow_no_motion_u8);
+ /*!
+ * @brief This API write Slow/no-motion
+ * interrupt trigger delay duration from the register 0x5F bit 2 to 7
+ *
+ * @param v_slow_no_motion_u8 :The value of slow no motion duration
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ * @note
+ * @note v_slow_no_motion_u8(5:4)=0b00 ->
+ * [v_slow_no_motion_u8(3:0) + 1] * 1.28s (1.28s-20.48s)
+ * @note v_slow_no_motion_u8(5:4)=1 ->
+ * [v_slow_no_motion_u8(3:0)+5] * 5.12s (25.6s-102.4s)
+ * @note v_slow_no_motion_u8(5)='1' ->
+ * [(v_slow_no_motion_u8:0)+11] * 10.24s (112.64s-430.08s);
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_slow_no_motion_durn(
+u8 v_slow_no_motion_u8);
+/***************************************************************/
+/**\name FUNCTION FOR ANY MOTION THRESHOLD CONFIGURATION */
+/***************************************************************/
+/*!
+ * @brief This API is used to read threshold
+ * definition for the any-motion interrupt
+ * from the register 0x60 bit 0 to 7
+ *
+ *
+ * @param v_any_motion_thres_u8 : The value of any motion threshold
+ *
+ * @note any motion threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | any motion threshold
+ * ----------------|---------------------
+ * 2g | v_any_motion_thres_u8*3.91 mg
+ * 4g | v_any_motion_thres_u8*7.81 mg
+ * 8g | v_any_motion_thres_u8*15.63 mg
+ * 16g | v_any_motion_thres_u8*31.25 mg
+ * @note when v_any_motion_thres_u8 = 0
+ * accel_range | any motion threshold
+ * ----------------|---------------------
+ * 2g | 1.95 mg
+ * 4g | 3.91 mg
+ * 8g | 7.81 mg
+ * 16g | 15.63 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_any_motion_thres(
+u8 *v_any_motion_thres_u8);
+/*!
+ * @brief This API is used to write threshold
+ * definition for the any-motion interrupt
+ * from the register 0x60 bit 0 to 7
+ *
+ *
+ * @param v_any_motion_thres_u8 : The value of any motion threshold
+ *
+ * @note any motion threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | any motion threshold
+ * ----------------|---------------------
+ * 2g | v_any_motion_thres_u8*3.91 mg
+ * 4g | v_any_motion_thres_u8*7.81 mg
+ * 8g | v_any_motion_thres_u8*15.63 mg
+ * 16g | v_any_motion_thres_u8*31.25 mg
+ * @note when v_any_motion_thres_u8 = 0
+ * accel_range | any motion threshold
+ * ----------------|---------------------
+ * 2g | 1.95 mg
+ * 4g | 3.91 mg
+ * 8g | 7.81 mg
+ * 16g | 15.63 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_any_motion_thres(
+u8 v_any_motion_thres_u8);
+/***************************************************************/
+/**\name FUNCTION FOR SLO/NO MOTION THRESHOLD CONFIGURATION */
+/***************************************************************/
+ /*!
+ * @brief This API is used to read threshold
+ * for the slow/no-motion interrupt
+ * from the register 0x61 bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_slow_no_motion_thres_u8 : The value of slow no motion threshold
+ * @note slow no motion threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | slow no motion threshold
+ * ----------------|---------------------
+ * 2g | v_slow_no_motion_thres_u8*3.91 mg
+ * 4g | v_slow_no_motion_thres_u8*7.81 mg
+ * 8g | v_slow_no_motion_thres_u8*15.63 mg
+ * 16g | v_slow_no_motion_thres_u8*31.25 mg
+ * @note when v_slow_no_motion_thres_u8 = 0
+ * accel_range | slow no motion threshold
+ * ----------------|---------------------
+ * 2g | 1.95 mg
+ * 4g | 3.91 mg
+ * 8g | 7.81 mg
+ * 16g | 15.63 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_slow_no_motion_thres(
+u8 *v_slow_no_motion_thres_u8);
+ /*!
+ * @brief This API is used to write threshold
+ * for the slow/no-motion interrupt
+ * from the register 0x61 bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_slow_no_motion_thres_u8 : The value of slow no motion threshold
+ * @note slow no motion threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | slow no motion threshold
+ * ----------------|---------------------
+ * 2g | v_slow_no_motion_thres_u8*3.91 mg
+ * 4g | v_slow_no_motion_thres_u8*7.81 mg
+ * 8g | v_slow_no_motion_thres_u8*15.63 mg
+ * 16g | v_slow_no_motion_thres_u8*31.25 mg
+ * @note when v_slow_no_motion_thres_u8 = 0
+ * accel_range | slow no motion threshold
+ * ----------------|---------------------
+ * 2g | 1.95 mg
+ * 4g | 3.91 mg
+ * 8g | 7.81 mg
+ * 16g | 15.63 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_slow_no_motion_thres(
+u8 v_slow_no_motion_thres_u8);
+/***************************************************************/
+/**\name FUNCTION FOR SLO/NO MOTION SELECT CONFIGURATION */
+/***************************************************************/
+ /*!
+ * @brief This API is used to read
+ * the slow/no-motion selection from the register 0x62 bit 0
+ *
+ *
+ *
+ *
+ * @param v_intr_slow_no_motion_select_u8 :
+ * The value of slow/no-motion select
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | SLOW_MOTION
+ * 0x01 | NO_MOTION
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_slow_no_motion_select(
+u8 *v_intr_slow_no_motion_select_u8);
+ /*!
+ * @brief This API is used to write
+ * the slow/no-motion selection from the register 0x62 bit 0
+ *
+ *
+ *
+ *
+ * @param v_intr_slow_no_motion_select_u8 :
+ * The value of slow/no-motion select
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | SLOW_MOTION
+ * 0x01 | NO_MOTION
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_slow_no_motion_select(
+u8 v_intr_slow_no_motion_select_u8);
+/***************************************************************/
+/**\name FUNCTION FOR SIGNIFICANT MOTION SELECT CONFIGURATION*/
+/***************************************************************/
+ /*!
+ * @brief This API is used to select
+ * the significant or any motion interrupt from the register 0x62 bit 1
+ *
+ *
+ *
+ *
+ * @param v_intr_significant_motion_select_u8 :
+ * the value of significant or any motion interrupt selection
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | ANY_MOTION
+ * 0x01 | SIGNIFICANT_MOTION
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_significant_motion_select(
+u8 *int_sig_mot_sel);
+ /*!
+ * @brief This API is used to write, select
+ * the significant or any motion interrupt from the register 0x62 bit 1
+ *
+ *
+ *
+ *
+ * @param v_intr_significant_motion_select_u8 :
+ * the value of significant or any motion interrupt selection
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | ANY_MOTION
+ * 0x01 | SIGNIFICANT_MOTION
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_significant_motion_select(
+u8 int_sig_mot_sel);
+ /*!
+ * @brief This API is used to read
+ * the significant skip time from the register 0x62 bit 2 and 3
+ *
+ *
+ *
+ *
+ * @param v_int_sig_mot_skip_u8 : the value of significant skip time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | skip time 1.5 seconds
+ * 0x01 | skip time 3 seconds
+ * 0x02 | skip time 6 seconds
+ * 0x03 | skip time 12 seconds
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_significant_motion_skip(
+u8 *v_int_sig_mot_skip_u8);
+ /*!
+ * @brief This API is used to write
+ * the significant skip time from the register 0x62 bit 2 and 3
+ *
+ *
+ *
+ *
+ * @param v_int_sig_mot_skip_u8 : the value of significant skip time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | skip time 1.5 seconds
+ * 0x01 | skip time 3 seconds
+ * 0x02 | skip time 6 seconds
+ * 0x03 | skip time 12 seconds
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_significant_motion_skip(
+u8 v_int_sig_mot_skip_u8);
+ /*!
+ * @brief This API is used to read
+ * the significant proof time from the register 0x62 bit 4 and 5
+ *
+ *
+ *
+ *
+ * @param v_significant_motion_proof_u8 :
+ * the value of significant proof time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | proof time 0.25 seconds
+ * 0x01 | proof time 0.5 seconds
+ * 0x02 | proof time 1 seconds
+ * 0x03 | proof time 2 seconds
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_significant_motion_proof(
+u8 *int_sig_mot_proof);
+ /*!
+ * @brief This API is used to write
+ * the significant proof time from the register 0x62 bit 4 and 5
+ *
+ *
+ *
+ *
+ * @param v_significant_motion_proof_u8 :
+ * the value of significant proof time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | proof time 0.25 seconds
+ * 0x01 | proof time 0.5 seconds
+ * 0x02 | proof time 1 seconds
+ * 0x03 | proof time 2 seconds
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_significant_motion_proof(
+u8 int_sig_mot_proof);
+/***************************************************************/
+/**\name FUNCTION FOR TAP DURATION CONFIGURATION*/
+/***************************************************************/
+/*!
+ * @brief This API is used to get the tap duration
+ * from the register 0x63 bit 0 to 2
+ *
+ *
+ *
+ * @param v_tap_durn_u8 : The value of tap duration
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | BMI160_TAP_DURN_50MS
+ * 0x01 | BMI160_TAP_DURN_100MS
+ * 0x03 | BMI160_TAP_DURN_150MS
+ * 0x04 | BMI160_TAP_DURN_200MS
+ * 0x05 | BMI160_TAP_DURN_250MS
+ * 0x06 | BMI160_TAP_DURN_375MS
+ * 0x07 | BMI160_TAP_DURN_700MS
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_tap_durn(
+u8 *v_tap_durn_u8);
+/*!
+ * @brief This API is used to write the tap duration
+ * from the register 0x63 bit 0 to 2
+ *
+ *
+ *
+ * @param v_tap_durn_u8 : The value of tap duration
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | BMI160_TAP_DURN_50MS
+ * 0x01 | BMI160_TAP_DURN_100MS
+ * 0x03 | BMI160_TAP_DURN_150MS
+ * 0x04 | BMI160_TAP_DURN_200MS
+ * 0x05 | BMI160_TAP_DURN_250MS
+ * 0x06 | BMI160_TAP_DURN_375MS
+ * 0x07 | BMI160_TAP_DURN_700MS
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_tap_durn(
+u8 v_tap_durn_u8);
+/***************************************************************/
+/**\name FUNCTION FOR TAP SHOCK CONFIGURATION*/
+/***************************************************************/
+ /*!
+ * @brief This API read the
+ * tap shock duration from the register 0x63 bit 2
+ *
+ * @param v_tap_shock_u8 :The value of tap shock
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | BMI160_TAP_SHOCK_50MS
+ * 0x01 | BMI160_TAP_SHOCK_75MS
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_tap_shock(
+u8 *v_tap_shock_u8);
+ /*!
+ * @brief This API write the
+ * tap shock duration from the register 0x63 bit 2
+ *
+ * @param v_tap_shock_u8 :The value of tap shock
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | BMI160_TAP_SHOCK_50MS
+ * 0x01 | BMI160_TAP_SHOCK_75MS
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_tap_shock(
+u8 v_tap_shock_u8);
+/***************************************************************/
+/**\name FUNCTION FOR TAP QUIET CONFIGURATION*/
+/***************************************************************/
+/*!
+ * @brief This API read
+ * tap quiet duration from the register 0x63 bit 7
+ *
+ *
+ * @param v_tap_quiet_u8 : The value of tap quiet
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | BMI160_TAP_QUIET_30MS
+ * 0x01 | BMI160_TAP_QUIET_20MS
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_tap_quiet(
+u8 *v_tap_quiet_u8);
+/*!
+ * @brief This API write
+ * tap quiet duration from the register 0x63 bit 7
+ *
+ *
+ * @param v_tap_quiet_u8 : The value of tap quiet
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | BMI160_TAP_QUIET_30MS
+ * 0x01 | BMI160_TAP_QUIET_20MS
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_tap_quiet(
+u8 v_tap_quiet_u8);
+/***************************************************************/
+/**\name FUNCTION FOR TAP THRESHOLD CONFIGURATION*/
+/***************************************************************/
+ /*!
+ * @brief This API read Threshold of the
+ * single/double tap interrupt from the register 0x64 bit 0 to 4
+ *
+ *
+ * @param v_tap_thres_u8 : The value of single/double tap threshold
+ *
+ * @note single/double tap threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | single/double tap threshold
+ * ----------------|---------------------
+ * 2g | ((v_tap_thres_u8 + 1) * 62.5)mg
+ * 4g | ((v_tap_thres_u8 + 1) * 125)mg
+ * 8g | ((v_tap_thres_u8 + 1) * 250)mg
+ * 16g | ((v_tap_thres_u8 + 1) * 500)mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_tap_thres(
+u8 *v_tap_thres_u8);
+ /*!
+ * @brief This API write Threshold of the
+ * single/double tap interrupt from the register 0x64 bit 0 to 4
+ *
+ *
+ * @param v_tap_thres_u8 : The value of single/double tap threshold
+ *
+ * @note single/double tap threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | single/double tap threshold
+ * ----------------|---------------------
+ * 2g | ((v_tap_thres_u8 + 1) * 62.5)mg
+ * 4g | ((v_tap_thres_u8 + 1) * 125)mg
+ * 8g | ((v_tap_thres_u8 + 1) * 250)mg
+ * 16g | ((v_tap_thres_u8 + 1) * 500)mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_tap_thres(
+u8 v_tap_thres_u8);
+/***************************************************************/
+/**\name FUNCTION FOR ORIENT MODE CONFIGURATION*/
+/***************************************************************/
+ /*!
+ * @brief This API read the threshold for orientation interrupt
+ * from the register 0x65 bit 0 and 1
+ *
+ * @param v_orient_mode_u8 : The value of threshold for orientation
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | symmetrical
+ * 0x01 | high-asymmetrical
+ * 0x02 | low-asymmetrical
+ * 0x03 | symmetrical
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_orient_mode(
+u8 *v_orient_mode_u8);
+ /*!
+ * @brief This API write the threshold for orientation interrupt
+ * from the register 0x65 bit 0 and 1
+ *
+ * @param v_orient_mode_u8 : The value of threshold for orientation
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | symmetrical
+ * 0x01 | high-asymmetrical
+ * 0x02 | low-asymmetrical
+ * 0x03 | symmetrical
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_orient_mode(
+u8 v_orient_mode_u8);
+/***************************************************************/
+/**\name FUNCTION FOR ORIENT BLOCKING CONFIGURATION*/
+/***************************************************************/
+/*!
+ * @brief This API read the orient blocking mode
+ * that is used for the generation of the orientation interrupt.
+ * from the register 0x65 bit 2 and 3
+ *
+ * @param v_orient_blocking_u8 : The value of orient blocking mode
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | No blocking
+ * 0x01 | Theta blocking or acceleration in any axis > 1.5g
+ * 0x02 | Theta blocking or acceleration slope in any axis >
+ * - | 0.2g or acceleration in any axis > 1.5g
+ * 0x03 | Theta blocking or acceleration slope in any axis >
+ * - | 0.4g or acceleration in any axis >
+ * - | 1.5g and value of orient is not stable
+ * - | for at least 100 ms
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_orient_blocking(
+u8 *v_orient_blocking_u8);
+/*!
+ * @brief This API write the orient blocking mode
+ * that is used for the generation of the orientation interrupt.
+ * from the register 0x65 bit 2 and 3
+ *
+ * @param v_orient_blocking_u8 : The value of orient blocking mode
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | No blocking
+ * 0x01 | Theta blocking or acceleration in any axis > 1.5g
+ * 0x02 | Theta blocking or acceleration slope in any axis >
+ * - | 0.2g or acceleration in any axis > 1.5g
+ * 0x03 | Theta blocking or acceleration slope in any axis >
+ * - | 0.4g or acceleration in any axis >
+ * - | 1.5g and value of orient is not stable
+ * - | for at least 100 ms
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_orient_blocking(
+u8 v_orient_blocking_u8);
+/***************************************************************/
+/**\name FUNCTION FOR ORIENT HYSTERESIS CONFIGURATION*/
+/***************************************************************/
+/*!
+ * @brief This API read Orient interrupt
+ * hysteresis, from the register 0x64 bit 4 to 7
+ *
+ *
+ *
+ * @param v_orient_hyst_u8 : The value of orient hysteresis
+ *
+ * @note 1 LSB corresponds to 62.5 mg,
+ * irrespective of the selected accel range
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_orient_hyst(
+u8 *v_orient_hyst_u8);
+/*!
+ * @brief This API write Orient interrupt
+ * hysteresis, from the register 0x64 bit 4 to 7
+ *
+ *
+ *
+ * @param v_orient_hyst_u8 : The value of orient hysteresis
+ *
+ * @note 1 LSB corresponds to 62.5 mg,
+ * irrespective of the selected accel range
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_orient_hyst(
+u8 v_orient_hyst_u8);
+/***************************************************************/
+/**\name FUNCTION FOR ORIENT THETA CONFIGURATION*/
+/***************************************************************/
+ /*!
+ * @brief This API read Orient
+ * blocking angle (0 to 44.8) from the register 0x66 bit 0 to 5
+ *
+ * @param v_orient_theta_u8 : The value of Orient blocking angle
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_orient_theta(
+u8 *v_orient_theta_u8);
+ /*!
+ * @brief This API write Orient
+ * blocking angle (0 to 44.8) from the register 0x66 bit 0 to 5
+ *
+ * @param v_orient_theta_u8 : The value of Orient blocking angle
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_orient_theta(
+u8 v_orient_theta_u8);
+/***************************************************************/
+/**\name FUNCTION FOR ORIENT OUTPUT ENABLE CONFIGURATION*/
+/***************************************************************/
+/*!
+ * @brief This API read orient change
+ * of up/down bit from the register 0x66 bit 6
+ *
+ * @param v_orient_ud_u8 : The value of orient change of up/down
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | Is ignored
+ * 0x01 | Generates orientation interrupt
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_orient_ud_enable(
+u8 *v_orient_ud_u8);
+/*!
+ * @brief This API write orient change
+ * of up/down bit from the register 0x66 bit 6
+ *
+ * @param v_orient_ud_u8 : The value of orient change of up/down
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | Is ignored
+ * 0x01 | Generates orientation interrupt
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_orient_ud_enable(
+u8 v_orient_ud_u8);
+/***************************************************************/
+/**\name FUNCTION FOR ORIENT AXIS ENABLE CONFIGURATION*/
+/***************************************************************/
+ /*!
+ * @brief This API read orientation axes changes
+ * from the register 0x66 bit 7
+ *
+ * @param v_orient_axes_u8 : The value of orient axes assignment
+ * value | Behaviour | Name
+ * ----------|--------------------|------
+ * 0x00 | x = x, y = y, z = z|orient_ax_noex
+ * 0x01 | x = y, y = z, z = x|orient_ax_ex
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_orient_axes_enable(
+u8 *v_orient_axes_u8);
+ /*!
+ * @brief This API write orientation axes changes
+ * from the register 0x66 bit 7
+ *
+ * @param v_orient_axes_u8 : The value of orient axes assignment
+ * value | Behaviour | Name
+ * ----------|--------------------|------
+ * 0x00 | x = x, y = y, z = z|orient_ax_noex
+ * 0x01 | x = y, y = z, z = x|orient_ax_ex
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_orient_axes_enable(
+u8 v_orient_axes_u8);
+/***************************************************************/
+/**\name FUNCTION FOR FLAT THETA CONFIGURATION*/
+/***************************************************************/
+ /*!
+ * @brief This API read Flat angle (0 to 44.8) for flat interrupt
+ * from the register 0x67 bit 0 to 5
+ *
+ * @param v_flat_theta_u8 : The value of flat angle
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_flat_theta(
+u8 *v_flat_theta_u8);
+ /*!
+ * @brief This API write Flat angle (0 to 44.8) for flat interrupt
+ * from the register 0x67 bit 0 to 5
+ *
+ * @param v_flat_theta_u8 : The value of flat angle
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_flat_theta(
+u8 v_flat_theta_u8);
+/***************************************************************/
+/**\name FUNCTION FOR FLAT HOLD CONFIGURATION*/
+/***************************************************************/
+/*!
+ * @brief This API read Flat interrupt hold time;
+ * from the register 0x68 bit 4 and 5
+ *
+ * @param v_flat_hold_u8 : The value of flat hold time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | 0ms
+ * 0x01 | 512ms
+ * 0x01 | 1024ms
+ * 0x01 | 2048ms
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_flat_hold(
+u8 *v_flat_hold_u8);
+/*!
+ * @brief This API write Flat interrupt hold time;
+ * from the register 0x68 bit 4 and 5
+ *
+ * @param v_flat_hold_u8 : The value of flat hold time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | 0ms
+ * 0x01 | 512ms
+ * 0x01 | 1024ms
+ * 0x01 | 2048ms
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_flat_hold(
+u8 v_flat_hold_u8);
+/***************************************************************/
+/**\name FUNCTION FOR FLAT HYSTERESIS CONFIGURATION*/
+/***************************************************************/
+/*!
+ * @brief This API read flat interrupt hysteresis
+ * from the register 0x68 bit 0 to 3
+ *
+ * @param v_flat_hyst_u8 : The value of flat hysteresis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_intr_flat_hyst(
+u8 *v_flat_hyst_u8);
+/*!
+ * @brief This API write flat interrupt hysteresis
+ * from the register 0x68 bit 0 to 3
+ *
+ * @param v_flat_hyst_u8 : The value of flat hysteresis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_intr_flat_hyst(
+u8 v_flat_hyst_u8);
+/***************************************************************/
+/**\name FUNCTION FAST OFFSET COMPENSATION FOR ACCEL */
+/***************************************************************/
+ /*!
+ * @brief This API read accel offset compensation
+ * target value for z-axis from the register 0x69 bit 0 and 1
+ *
+ * @param v_foc_accel_z_u8 : the value of accel offset compensation z axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_foc_accel_z(
+u8 *v_foc_accel_z_u8);
+ /*!
+ * @brief This API write accel offset compensation
+ * target value for z-axis from the register 0x69 bit 0 and 1
+ *
+ * @param v_foc_accel_z_u8 : the value of accel offset compensation z axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_foc_accel_z(
+u8 v_foc_accel_z_u8);
+/*!
+ * @brief This API read accel offset compensation
+ * target value for y-axis
+ * from the register 0x69 bit 2 and 3
+ *
+ * @param v_foc_accel_y_u8 : the value of accel offset compensation y axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_foc_accel_y(
+u8 *v_foc_accel_y_u8);
+/*!
+ * @brief This API write accel offset compensation
+ * target value for y-axis
+ * from the register 0x69 bit 2 and 3
+ *
+ * @param v_foc_accel_y_u8 : the value of accel offset compensation y axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_foc_accel_y(
+u8 v_foc_accel_y_u8);
+/*!
+ * @brief This API read accel offset compensation
+ * target value for x-axis is
+ * from the register 0x69 bit 4 and 5
+ *
+ * @param v_foc_accel_x_u8 : the value of accel offset compensation x axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_foc_accel_x(
+u8 *v_foc_accel_x_u8);
+/*!
+ * @brief This API write accel offset compensation
+ * target value for x-axis is
+ * from the register 0x69 bit 4 and 5
+ *
+ * @param v_foc_accel_x_u8 : the value of accel offset compensation x axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_foc_accel_x(
+u8 v_foc_accel_x_u8);
+/***************************************************************/
+/**\name FUNCTION FAST OFFSET COMPENSATION FOR GYRO */
+/***************************************************************/
+/*!
+ * @brief This API write gyro fast offset enable
+ * from the register 0x69 bit 6
+ *
+ * @param v_foc_gyro_u8 : The value of gyro fast offset enable
+ * value | Description
+ * ----------|-------------
+ * 0 | fast offset compensation disabled
+ * 1 | fast offset compensation enabled
+ *
+ * @param v_gyro_off_x_s16 : The value of gyro fast offset x axis data
+ * @param v_gyro_off_y_s16 : The value of gyro fast offset y axis data
+ * @param v_gyro_off_z_s16 : The value of gyro fast offset z axis data
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_foc_gyro_enable(
+u8 v_foc_gyro_u8, s16 *v_gyro_off_x_s16,
+s16 *v_gyro_off_y_s16, s16 *v_gyro_off_z_s16);
+/***************************************************/
+/**\name FUNCTION FOR NVM*/
+/***************************************************/
+ /*!
+ * @brief This API read NVM program enable
+ * from the register 0x6A bit 1
+ *
+ * @param v_nvm_prog_u8 : The value of NVM program enable
+ * Value | Description
+ * --------|-------------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_nvm_prog_enable(
+u8 *v_nvm_prog_u8);
+ /*!
+ * @brief This API write NVM program enable
+ * from the register 0x6A bit 1
+ *
+ * @param v_nvm_prog_u8 : The value of NVM program enable
+ * Value | Description
+ * --------|-------------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_nvm_prog_enable(
+u8 v_nvm_prog_u8);
+/***************************************************/
+/**\name FUNCTION FOR SPI MODE*/
+/***************************************************/
+/*!
+ * @brief This API read to configure SPI
+ * Interface Mode for primary and OIS interface
+ * from the register 0x6B bit 0
+ *
+ * @param v_spi3_u8 : The value of SPI mode selection
+ * Value | Description
+ * --------|-------------
+ * 0 | SPI 4-wire mode
+ * 1 | SPI 3-wire mode
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_spi3(
+u8 *v_spi3_u8);
+/*!
+ * @brief This API write to configure SPI
+ * Interface Mode for primary and OIS interface
+ * from the register 0x6B bit 0
+ *
+ * @param v_spi3_u8 : The value of SPI mode selection
+ * Value | Description
+ * --------|-------------
+ * 0 | SPI 4-wire mode
+ * 1 | SPI 3-wire mode
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_spi3(
+u8 v_spi3_u8);
+/***************************************************/
+/**\name FUNCTION FOR FOC GYRO */
+/***************************************************/
+/*!
+ * @brief This API read gyro fast offset enable
+ * from the register 0x69 bit 6
+ *
+ * @param v_foc_gyro_u8 : The value of gyro fast offset enable
+ * value | Description
+ * ----------|-------------
+ * 0 | fast offset compensation disabled
+ * 1 | fast offset compensation enabled
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_foc_gyro_enable(
+u8 *v_foc_gyro_u8);
+/***************************************************/
+/**\name FUNCTION FOR I2C WATCHDOG TIMBER */
+/***************************************************/
+/*!
+ * @brief This API read I2C Watchdog timer
+ * from the register 0x70 bit 1
+ *
+ * @param v_i2c_wdt_u8 : The value of I2C watch dog timer
+ * Value | Description
+ * --------|-------------
+ * 0 | I2C watchdog v_timeout_u8 after 1 ms
+ * 1 | I2C watchdog v_timeout_u8 after 50 ms
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_i2c_wdt_select(
+u8 *v_i2c_wdt_u8);
+/*!
+ * @brief This API write I2C Watchdog timer
+ * from the register 0x70 bit 1
+ *
+ * @param v_i2c_wdt_u8 : The value of I2C watch dog timer
+ * Value | Description
+ * --------|-------------
+ * 0 | I2C watchdog v_timeout_u8 after 1 ms
+ * 1 | I2C watchdog v_timeout_u8 after 50 ms
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE
+bmi160_set_i2c_wdt_select(u8 v_i2c_wdt_u8);
+/*!
+ * @brief This API read I2C watchdog enable
+ * from the register 0x70 bit 2
+ *
+ * @param v_i2c_wdt_u8 : The value of I2C watchdog enable
+ * Value | Description
+ * --------|-------------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_i2c_wdt_enable(
+u8 *v_i2c_wdt_u8);
+/*!
+ * @brief This API write I2C watchdog enable
+ * from the register 0x70 bit 2
+ *
+ * @param v_i2c_wdt_u8 : The value of I2C watchdog enable
+ * Value | Description
+ * --------|-------------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_i2c_wdt_enable(
+u8 v_i2c_wdt_u8);
+/***************************************************/
+/**\name FUNCTION FOR IF MODE*/
+/***************************************************/
+/*!
+ * @brief This API read I2C interface configuration(if) moe
+ * from the register 0x6B bit 4 and 5
+ *
+ * @param v_if_mode_u8 : The value of interface configuration mode
+ * Value | Description
+ * --------|-------------
+ * 0x00 | Primary interface:autoconfig / secondary interface:off
+ * 0x01 | Primary interface:I2C / secondary interface:OIS
+ * 0x02 | Primary interface:autoconfig/secondary interface:Magnetometer
+ * 0x03 | Reserved
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_if_mode(
+u8 *v_if_mode_u8);
+/*!
+ * @brief This API write I2C interface configuration(if) moe
+ * from the register 0x6B bit 4 and 5
+ *
+ * @param v_if_mode_u8 : The value of interface configuration mode
+ * Value | Description
+ * --------|-------------
+ * 0x00 | Primary interface:autoconfig / secondary interface:off
+ * 0x01 | Primary interface:I2C / secondary interface:OIS
+ * 0x02 | Primary interface:autoconfig/secondary interface:Magnetometer
+ * 0x03 | Reserved
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_if_mode(
+u8 v_if_mode_u8);
+/***************************************************/
+/**\name FUNCTION FOR GYRO SLEEP TRIGGER INTERRUPT CONFIGURATION*/
+/***************************************************/
+/*!
+ * @brief This API read gyro sleep trigger
+ * from the register 0x6C bit 0 to 2
+ *
+ * @param v_gyro_sleep_trigger_u8 : The value of gyro sleep trigger
+ * Value | Description
+ * --------|-------------
+ * 0x00 | nomotion: no / Not INT1 pin: no / INT2 pin: no
+ * 0x01 | nomotion: no / Not INT1 pin: no / INT2 pin: yes
+ * 0x02 | nomotion: no / Not INT1 pin: yes / INT2 pin: no
+ * 0x03 | nomotion: no / Not INT1 pin: yes / INT2 pin: yes
+ * 0x04 | nomotion: yes / Not INT1 pin: no / INT2 pin: no
+ * 0x05 | anymotion: yes / Not INT1 pin: no / INT2 pin: yes
+ * 0x06 | anymotion: yes / Not INT1 pin: yes / INT2 pin: no
+ * 0x07 | anymotion: yes / Not INT1 pin: yes / INT2 pin: yes
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_sleep_trigger(
+u8 *v_gyro_sleep_trigger_u8);
+/*!
+ * @brief This API write gyro sleep trigger
+ * from the register 0x6C bit 0 to 2
+ *
+ * @param v_gyro_sleep_trigger_u8 : The value of gyro sleep trigger
+ * Value | Description
+ * --------|-------------
+ * 0x00 | nomotion: no / Not INT1 pin: no / INT2 pin: no
+ * 0x01 | nomotion: no / Not INT1 pin: no / INT2 pin: yes
+ * 0x02 | nomotion: no / Not INT1 pin: yes / INT2 pin: no
+ * 0x03 | nomotion: no / Not INT1 pin: yes / INT2 pin: yes
+ * 0x04 | nomotion: yes / Not INT1 pin: no / INT2 pin: no
+ * 0x05 | anymotion: yes / Not INT1 pin: no / INT2 pin: yes
+ * 0x06 | anymotion: yes / Not INT1 pin: yes / INT2 pin: no
+ * 0x07 | anymotion: yes / Not INT1 pin: yes / INT2 pin: yes
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_sleep_trigger(
+u8 v_gyro_sleep_trigger_u8);
+/*!
+ * @brief This API read gyro wakeup trigger
+ * from the register 0x6C bit 3 and 4
+ *
+ * @param v_gyro_wakeup_trigger_u8 : The value of gyro wakeup trigger
+ * Value | Description
+ * --------|-------------
+ * 0x00 | anymotion: no / INT1 pin: no
+ * 0x01 | anymotion: no / INT1 pin: yes
+ * 0x02 | anymotion: yes / INT1 pin: no
+ * 0x03 | anymotion: yes / INT1 pin: yes
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_wakeup_trigger(
+u8 *v_gyro_wakeup_trigger_u8);
+/*!
+ * @brief This API write gyro wakeup trigger
+ * from the register 0x6C bit 3 and 4
+ *
+ * @param v_gyro_wakeup_trigger_u8 : The value of gyro wakeup trigger
+ * Value | Description
+ * --------|-------------
+ * 0x00 | anymotion: no / INT1 pin: no
+ * 0x01 | anymotion: no / INT1 pin: yes
+ * 0x02 | anymotion: yes / INT1 pin: no
+ * 0x03 | anymotion: yes / INT1 pin: yes
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_wakeup_trigger(
+u8 v_gyro_wakeup_trigger_u8);
+/*!
+ * @brief This API read Target state for gyro sleep mode
+ * from the register 0x6C bit 5
+ *
+ * @param v_gyro_sleep_state_u8 : The value of gyro sleep mode
+ * Value | Description
+ * --------|-------------
+ * 0x00 | Sleep transition to fast wake up state
+ * 0x01 | Sleep transition to suspend state
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_sleep_state(
+u8 *v_gyro_sleep_state_u8);
+/*!
+ * @brief This API write Target state for gyro sleep mode
+ * from the register 0x6C bit 5
+ *
+ * @param v_gyro_sleep_state_u8 : The value of gyro sleep mode
+ * Value | Description
+ * --------|-------------
+ * 0x00 | Sleep transition to fast wake up state
+ * 0x01 | Sleep transition to suspend state
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_sleep_state(
+u8 v_gyro_sleep_state_u8);
+/*!
+ * @brief This API read gyro wakeup interrupt
+ * from the register 0x6C bit 6
+ *
+ * @param v_gyro_wakeup_intr_u8 : The valeu of gyro wakeup interrupt
+ * Value | Description
+ * --------|-------------
+ * 0x00 | DISABLE
+ * 0x01 | ENABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_wakeup_intr(
+u8 *v_gyro_wakeup_intr_u8);
+/*!
+ * @brief This API write gyro wakeup interrupt
+ * from the register 0x6C bit 6
+ *
+ * @param v_gyro_wakeup_intr_u8 : The valeu of gyro wakeup interrupt
+ * Value | Description
+ * --------|-------------
+ * 0x00 | DISABLE
+ * 0x01 | ENABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_wakeup_intr(
+u8 v_gyro_wakeup_intr_u8);
+/***************************************************/
+/**\name FUNCTION FOR ACCEL SELF TEST */
+/***************************************************/
+/*!
+ * @brief This API read accel select axis to be self-test
+ *
+ * @param v_accel_selftest_axis_u8 :
+ * The value of accel self test axis selection
+ * Value | Description
+ * --------|-------------
+ * 0x00 | disabled
+ * 0x01 | x-axis
+ * 0x02 | y-axis
+ * 0x03 | z-axis
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_selftest_axis(
+u8 *acc_selftest_axis);
+/*!
+ * @brief This API write accel select axis to be self-test
+ *
+ * @param v_accel_selftest_axis_u8 :
+ * The value of accel self test axis selection
+ * Value | Description
+ * --------|-------------
+ * 0x00 | disabled
+ * 0x01 | x-axis
+ * 0x02 | y-axis
+ * 0x03 | z-axis
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_selftest_axis(
+u8 acc_selftest_axis);
+/*!
+ * @brief This API read accel self test axis sign
+ * from the register 0x6D bit 2
+ *
+ * @param v_accel_selftest_sign_u8: The value of accel self test axis sign
+ * Value | Description
+ * --------|-------------
+ * 0x00 | negative
+ * 0x01 | positive
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_selftest_sign(
+u8 *acc_selftest_sign);
+/*!
+ * @brief This API write accel self test axis sign
+ * from the register 0x6D bit 2
+ *
+ * @param v_accel_selftest_sign_u8: The value of accel self test axis sign
+ * Value | Description
+ * --------|-------------
+ * 0x00 | negative
+ * 0x01 | positive
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_selftest_sign(
+u8 acc_selftest_sign);
+/*!
+ * @brief This API read accel self test amplitude
+ * from the register 0x6D bit 3
+ * select amplitude of the selftest deflection:
+ *
+ * @param v_accel_selftest_amp_u8 : The value of accel self test amplitude
+ * Value | Description
+ * --------|-------------
+ * 0x00 | LOW
+ * 0x01 | HIGH
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_selftest_amp(
+u8 *acc_selftest_amp);
+/*!
+ * @brief This API write accel self test amplitude
+ * from the register 0x6D bit 3
+ * select amplitude of the selftest deflection:
+ *
+ * @param v_accel_selftest_amp_u8 : The value of accel self test amplitude
+ * Value | Description
+ * --------|-------------
+ * 0x00 | LOW
+ * 0x01 | HIGH
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_selftest_amp(
+u8 acc_selftest_amp);
+/***************************************************/
+/**\name FUNCTION FOR GYRO SELF TEST */
+/***************************************************/
+/*!
+ * @brief This API read gyro self test trigger
+ *
+ * @param v_gyro_selftest_start_u8: The value of gyro self test start
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_selftest_start(
+u8 *v_gyro_selftest_start_u8);
+/*!
+ * @brief This API write gyro self test trigger
+ *
+ * @param v_gyro_selftest_start_u8: The value of gyro self test start
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_selftest_start(
+u8 v_gyro_selftest_start_u8);
+/***************************************************/
+/**\name FUNCTION FOR SPI/I2C ENABLE */
+/***************************************************/
+ /*!
+ * @brief This API read primary interface selection I2C or SPI
+ * from the register 0x70 bit 0
+ *
+ * @param v_spi_enable_u8: The value of Interface selection
+ * Value | Description
+ * --------|-------------
+ * 0x00 | I2C Enable
+ * 0x01 | I2C DISBALE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_spi_enable(
+u8 *v_spi_enable_u8);
+ /*!
+ * @brief This API write primary interface selection I2C or SPI
+ * from the register 0x70 bit 0
+ *
+ * @param v_spi_enable_u8: The value of Interface selection
+ * Value | Description
+ * --------|-------------
+ * 0x00 | I2C Enable
+ * 0x01 | I2C DISBALE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_spi_enable(
+u8 v_spi_enable_u8);
+ /*!
+ * @brief This API read the spare zero
+ * form register 0x70 bit 3
+ *
+ *
+ * @param v_spare0_trim_u8: The value of spare zero
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_spare0_trim
+(u8 *v_spare0_trim_u8);
+ /*!
+ * @brief This API write the spare zero
+ * form register 0x70 bit 3
+ *
+ *
+ * @param v_spare0_trim_u8: The value of spare zero
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_spare0_trim
+(u8 v_spare0_trim_u8);
+/***************************************************/
+/**\name FUNCTION FOR NVM COUNTER */
+/***************************************************/
+ /*!
+ * @brief This API read the NVM counter
+ * form register 0x70 bit 4 to 7
+ *
+ *
+ * @param v_nvm_counter_u8: The value of NVM counter
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_nvm_counter(
+u8 *v_nvm_counter_u8);
+ /*!
+ * @brief This API write the NVM counter
+ * form register 0x70 bit 4 to 7
+ *
+ *
+ * @param v_nvm_counter_u8: The value of NVM counter
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_nvm_counter(
+u8 v_nvm_counter_u8);
+/***************************************************/
+/**\name FUNCTION FOR ACCEL MANUAL OFFSET COMPENSATION */
+/***************************************************/
+/*!
+ * @brief This API read accel manual offset compensation of x axis
+ * from the register 0x71 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_x_s8:
+ * The value of accel manual offset compensation of x axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_offset_compensation_xaxis(
+s8 *v_accel_off_x_s8);
+/*!
+ * @brief This API write accel manual offset compensation of x axis
+ * from the register 0x71 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_x_s8:
+ * The value of accel manual offset compensation of x axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_offset_compensation_xaxis(
+s8 v_accel_off_x_s8);
+/*!
+ * @brief This API read accel manual offset compensation of y axis
+ * from the register 0x72 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_y_s8:
+ * The value of accel manual offset compensation of y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_offset_compensation_yaxis(
+s8 *v_accel_off_y_s8);
+/*!
+ * @brief This API write accel manual offset compensation of y axis
+ * from the register 0x72 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_y_s8:
+ * The value of accel manual offset compensation of y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_offset_compensation_yaxis(
+s8 v_accel_off_y_s8);
+/*!
+ * @brief This API read accel manual offset compensation of z axis
+ * from the register 0x73 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_z_s8:
+ * The value of accel manual offset compensation of z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_offset_compensation_zaxis(
+s8 *v_accel_off_z_s8);
+/*!
+ * @brief This API write accel manual offset compensation of z axis
+ * from the register 0x73 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_z_s8:
+ * The value of accel manual offset compensation of z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_offset_compensation_zaxis(
+s8 v_accel_off_z_s8);
+/***************************************************/
+/**\name FUNCTION FOR GYRO MANUAL OFFSET COMPENSATION */
+/***************************************************/
+/*!
+ * @brief This API read gyro manual offset compensation of x axis
+ * from the register 0x74 bit 0 to 7 and 0x77 bit 0 and 1
+ *
+ *
+ *
+ * @param v_gyro_off_x_s16:
+ * The value of gyro manual offset compensation of x axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_offset_compensation_xaxis(
+s16 *v_gyro_off_x_s16);
+/*!
+ * @brief This API write gyro manual offset compensation of x axis
+ * from the register 0x74 bit 0 to 7 and 0x77 bit 0 and 1
+ *
+ *
+ *
+ * @param v_gyro_off_x_s16:
+ * The value of gyro manual offset compensation of x axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_offset_compensation_xaxis(
+s16 v_gyro_off_x_s16);
+/*!
+ * @brief This API read gyro manual offset compensation of y axis
+ * from the register 0x75 bit 0 to 7 and 0x77 bit 2 and 3
+ *
+ *
+ *
+ * @param v_gyro_off_y_s16:
+ * The value of gyro manual offset compensation of y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_offset_compensation_yaxis(
+s16 *v_gyro_off_y_s16);
+/*!
+ * @brief This API write gyro manual offset compensation of y axis
+ * from the register 0x75 bit 0 to 7 and 0x77 bit 2 and 3
+ *
+ *
+ *
+ * @param v_gyro_off_y_s16:
+ * The value of gyro manual offset compensation of y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_offset_compensation_yaxis(
+s16 v_gyro_off_y_s16);
+/*!
+ * @brief This API read gyro manual offset compensation of z axis
+ * from the register 0x76 bit 0 to 7 and 0x77 bit 4 and 5
+ *
+ *
+ *
+ * @param v_gyro_off_z_s16:
+ * The value of gyro manual offset compensation of z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_offset_compensation_zaxis(
+s16 *v_gyro_off_z_s16);
+/*!
+ * @brief This API write gyro manual offset compensation of z axis
+ * from the register 0x76 bit 0 to 7 and 0x77 bit 4 and 5
+ *
+ *
+ *
+ * @param v_gyro_off_z_s16:
+ * The value of gyro manual offset compensation of z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_offset_compensation_zaxis(
+s16 v_gyro_off_z_s16);
+/*!
+ * @brief This API writes accel fast offset compensation
+ * from the register 0x69 bit 0 to 5
+ * @brief This API writes each axis individually
+ * FOC_X_AXIS - bit 4 and 5
+ * FOC_Y_AXIS - bit 2 and 3
+ * FOC_Z_AXIS - bit 0 and 1
+ *
+ * @param v_foc_accel_u8: The value of accel offset compensation
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @param v_axis_u8: The value of accel offset axis selection
+ * value | axis
+ * ----------|-------------------
+ * 0 | FOC_X_AXIS
+ * 1 | FOC_Y_AXIS
+ * 2 | FOC_Z_AXIS
+ *
+ * @param v_accel_offset_s8: The accel offset value
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_foc_trigger(u8 axis,
+u8 foc_acc, s8 *accel_offset);
+/*!
+ * @brief This API write fast accel offset compensation
+ * it writes all axis together.To the register 0x69 bit 0 to 5
+ * FOC_X_AXIS - bit 4 and 5
+ * FOC_Y_AXIS - bit 2 and 3
+ * FOC_Z_AXIS - bit 0 and 1
+ *
+ * @param v_foc_accel_x_u8: The value of accel offset x compensation
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @param v_foc_accel_y_u8: The value of accel offset y compensation
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @param v_foc_accel_z_u8: The value of accel offset z compensation
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @param v_accel_off_x_s8: The value of accel offset x axis
+ * @param v_accel_off_y_s8: The value of accel offset y axis
+ * @param v_accel_off_z_s8: The value of accel offset z axis
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_accel_foc_trigger_xyz(u8 v_foc_accel_x_u8,
+u8 v_foc_accel_y_u8, u8 v_foc_accel_z_u8,
+s8 *acc_off_x, s8 *acc_off_y, s8 *acc_off_z);
+/***************************************************/
+/**\name FUNCTION FOR ACEL AND GYRO OFFSET ENABLE */
+/***************************************************/
+/*!
+ * @brief This API read the accel offset enable bit
+ * from the register 0x77 bit 6
+ *
+ *
+ *
+ * @param v_accel_off_enable_u8: The value of accel offset enable
+ * value | Description
+ * ----------|--------------
+ * 0x01 | ENABLE
+ * 0x00 | DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_accel_offset_enable(
+u8 *acc_off_en);
+/*!
+ * @brief This API write the accel offset enable bit
+ * from the register 0x77 bit 6
+ *
+ *
+ *
+ * @param v_accel_off_enable_u8: The value of accel offset enable
+ * value | Description
+ * ----------|--------------
+ * 0x01 | ENABLE
+ * 0x00 | DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_accel_offset_enable(
+u8 acc_off_en);
+/*!
+ * @brief This API read the accel offset enable bit
+ * from the register 0x77 bit 7
+ *
+ *
+ *
+ * @param v_gyro_off_enable_u8: The value of gyro offset enable
+ * value | Description
+ * ----------|--------------
+ * 0x01 | ENABLE
+ * 0x00 | DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_gyro_offset_enable(
+u8 *v_gyro_off_enable_u8);
+/*!
+ * @brief This API write the accel offset enable bit
+ * from the register 0x77 bit 7
+ *
+ *
+ *
+ * @param v_gyro_off_enable_u8: The value of gyro offset enable
+ * value | Description
+ * ----------|--------------
+ * 0x01 | ENABLE
+ * 0x00 | DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_gyro_offset_enable(
+u8 v_gyro_off_enable_u8);
+/***************************************************/
+/**\name FUNCTION FOR STEP COUNTER INTERRUPT */
+/***************************************************/
+/*!
+ * @brief This API reads step counter value
+ * form the register 0x78 and 0x79
+ *
+ *
+ *
+ *
+ * @param v_step_cnt_s16 : The value of step counter
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_step_count(u16 *v_step_cnt_s16);
+ /*!
+ * @brief This API Reads
+ * step counter configuration
+ * from the register 0x7A bit 0 to 7
+ * and from the register 0x7B bit 0 to 2 and 4 to 7
+ *
+ *
+ * @param v_step_config_u16 : The value of step configuration
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_step_config(
+u16 *v_step_config_u16);
+ /*!
+ * @brief This API write
+ * step counter configuration
+ * from the register 0x7A bit 0 to 7
+ * and from the register 0x7B bit 0 to 2 and 4 to 7
+ *
+ *
+ * @param v_step_config_u16 :
+ * the value of Enable step configuration
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_step_config(
+u16 v_step_config_u16);
+ /*!
+ * @brief This API read enable step counter
+ * from the register 0x7B bit 3
+ *
+ *
+ * @param v_step_counter_u8 : The value of step counter enable
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_step_counter_enable(
+u8 *v_step_counter_u8);
+ /*!
+ * @brief This API write enable step counter
+ * from the register 0x7B bit 3
+ *
+ *
+ * @param v_step_counter_u8 : The value of step counter enable
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_step_counter_enable(
+u8 v_step_counter_u8);
+ /*!
+ * @brief This API set Step counter modes
+ *
+ *
+ * @param v_step_mode_u8 : The value of step counter mode
+ * value | mode
+ * ----------|-----------
+ * 0 | BMI160_STEP_NORMAL_MODE
+ * 1 | BMI160_STEP_SENSITIVE_MODE
+ * 2 | BMI160_STEP_ROBUST_MODE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_step_mode(u8 v_step_mode_u8);
+/*!
+ * @brief This API used to trigger the signification motion
+ * interrupt
+ *
+ *
+ * @param v_significant_u8 : The value of interrupt selection
+ * value | interrupt
+ * ----------|-----------
+ * 0 | BMI160_MAP_INTR1
+ * 1 | BMI160_MAP_INTR2
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_map_significant_motion_intr(
+u8 v_significant_u8);
+/*!
+ * @brief This API used to trigger the step detector
+ * interrupt
+ *
+ *
+ * @param v_step_detector_u8 : The value of interrupt selection
+ * value | interrupt
+ * ----------|-----------
+ * 0 | BMI160_MAP_INTR1
+ * 1 | BMI160_MAP_INTR2
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_map_step_detector_intr(
+u8 v_step_detector_u8);
+ /*!
+ * @brief This API used to clear the step counter interrupt
+ * interrupt
+ *
+ *
+ * @param : None
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_clear_step_counter(void);
+/***************************************************/
+/**\name FUNCTION FOR STEP COMMAND REGISTER WRITE */
+/***************************************************/
+ /*!
+ * @brief This API writes value to the register 0x7E bit 0 to 7
+ *
+ *
+ * @param v_command_reg_u8 : The value to write command register
+ * value | Description
+ * ---------|--------------------------------------------------------
+ * 0x00 | Reserved
+ * 0x03 | Starts fast offset calibration for the accel and gyro
+ * 0x10 | Sets the PMU mode for the Accelerometer to suspend
+ * 0x11 | Sets the PMU mode for the Accelerometer to normal
+ * 0x12 | Sets the PMU mode for the Accelerometer Lowpower
+ * 0x14 | Sets the PMU mode for the Gyroscope to suspend
+ * 0x15 | Sets the PMU mode for the Gyroscope to normal
+ * 0x16 | Reserved
+ * 0x17 | Sets the PMU mode for the Gyroscope to fast start-up
+ * 0x18 | Sets the PMU mode for the Magnetometer to suspend
+ * 0x19 | Sets the PMU mode for the Magnetometer to normal
+ * 0x1A | Sets the PMU mode for the Magnetometer to Lowpower
+ * 0xB0 | Clears all data in the FIFO
+ * 0xB1 | Resets the interrupt engine
+ * 0xB2 | step_cnt_clr Clears the step counter
+ * 0xB6 | Triggers a reset
+ * 0x37 | See extmode_en_last
+ * 0x9A | See extmode_en_last
+ * 0xC0 | Enable the extended mode
+ * 0xC4 | Erase NVM cell
+ * 0xC8 | Load NVM cell
+ * 0xF0 | Reset acceleration data path
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_command_register(
+u8 v_command_reg_u8);
+/***************************************************/
+/**\name FUNCTION FOR PAGE ENABLE */
+/***************************************************/
+ /*!
+ * @brief This API read target page from the register 0x7F bit 4 and 5
+ *
+ * @param v_target_page_u8: The value of target page
+ * value | page
+ * ---------|-----------
+ * 0 | User data/configure page
+ * 1 | Chip level trim/test page
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_target_page(
+u8 *v_target_page_u8);
+ /*!
+ * @brief This API write target page from the register 0x7F bit 4 and 5
+ *
+ * @param v_target_page_u8: The value of target page
+ * value | page
+ * ---------|-----------
+ * 0 | User data/configure page
+ * 1 | Chip level trim/test page
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_target_page(
+u8 v_target_page_u8);
+ /*!
+ * @brief This API read page enable from the register 0x7F bit 7
+ *
+ *
+ *
+ * @param v_page_enable_u8: The value of page enable
+ * value | page
+ * ---------|-----------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_paging_enable(
+u8 *v_page_enable_u8);
+ /*!
+ * @brief This API write page enable from the register 0x7F bit 7
+ *
+ *
+ *
+ * @param v_page_enable_u8: The value of page enable
+ * value | page
+ * ---------|-----------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_paging_enable(
+u8 v_page_enable_u8);
+ /*!
+ * @brief This API read
+ * pull up configuration from the register 0X85 bit 4 an 5
+ *
+ *
+ *
+ * @param v_control_pullup_u8: The value of pull up register
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_get_pullup_configuration(
+u8 *v_control_pullup_u8);
+ /*!
+ * @brief This API write
+ * pull up configuration from the register 0X85 bit 4 an 5
+ *
+ *
+ *
+ * @param v_control_pullup_u8: The value of pull up register
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_pullup_configuration(
+u8 v_control_pullup_u8);
+/***************************************************/
+/**\name FUNCTION FOR BMM150 */
+/***************************************************/
+ /*!
+ * @brief This function used for initialize the bmm150 sensor
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_bmm150_mag_interface_init(void);
+ /*!
+ * @brief This function used for set the mag power control
+ * bit enable
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_bmm150_mag_wakeup(void);
+ /*!
+ * @brief This function used for read the trim values of magnetometer
+ *
+ * @note
+ * Before reading the mag trimming values
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_bmm150_mag_trim(void);
+ /*!
+ * @brief This function used for read the compensated value of mag
+ * Before start reading the mag compensated data's
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_bmm150_mag_compensate_xyz(
+struct bmi160_mag_xyz_s32_t *mag_comp_xyz);
+BMI160_RETURN_FUNCTION_TYPE bmi160_bmm150_mag_compensate_xyz_raw(
+struct bmi160_mag_xyz_s32_t *mag_comp_xyz, struct bmi160_mag_xyzr_t mag_xyzr);
+
+/*!
+ * @brief This API used to get the compensated BMM150-X data
+ * the out put of X as s32
+ * Before start reading the mag compensated X data
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ *
+ *
+ * @param v_mag_data_x_s16 : The value of mag raw X data
+ * @param v_data_r_u16 : The value of mag R data
+ *
+ * @return results of compensated X data value output as s32
+ *
+ */
+s32 bmi160_bmm150_mag_compensate_X(s16 v_mag_data_x_s16, u16 v_data_r_u16);
+/*!
+ * @brief This API used to get the compensated BMM150-Y data
+ * the out put of Y as s32
+ * Before start reading the mag compensated Y data
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ *
+ *
+ * @param v_mag_data_y_s16 : The value of mag raw Y data
+ * @param v_data_r_u16 : The value of mag R data
+ *
+ * @return results of compensated Y data value output as s32
+ */
+s32 bmi160_bmm150_mag_compensate_Y(s16 v_mag_data_y_s16, u16 v_data_r_u16);
+/*!
+ * @brief This API used to get the compensated BMM150-Z data
+ * the out put of Z as s32
+ * Before start reading the mag compensated Z data
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ *
+ *
+ * @param v_mag_data_z_s16 : The value of mag raw Z data
+ * @param v_data_r_u16 : The value of mag R data
+ *
+ * @return results of compensated Z data value output as s32
+ */
+s32 bmi160_bmm150_mag_compensate_Z(s16 v_mag_data_z_s16, u16 v_data_r_u16);
+/*!
+ * @brief This API used to set the pre-set modes of bmm150
+ * The pre-set mode setting is depend on data rate and xy and z repetitions
+ *
+ * @note
+ * Before set the mag preset mode
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ *
+ * @param v_mode_u8: The value of pre-set mode selection value
+ * value | pre_set mode
+ * ----------|------------
+ * 1 | BMI160_MAG_PRESETMODE_LOWPOWER
+ * 2 | BMI160_MAG_PRESETMODE_REGULAR
+ * 3 | BMI160_MAG_PRESETMODE_HIGHACCURACY
+ * 4 | BMI160_MAG_PRESETMODE_ENHANCED
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_bmm150_mag_presetmode(u8 mode);
+/*!
+ * @brief This function used for set the magnetometer
+ * power mode.
+ * @note
+ * Before set the mag power mode
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ * @param v_mag_pow_mode_u8 : The value of mag power mode
+ * value | mode
+ * ----------|------------
+ * 0 | FORCE_MODE
+ * 1 | SUSPEND_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_bmm150_mag_set_power_mode(u8 mag_pow_mode);
+ /*!
+ * @brief This function used for set the magnetometer
+ * power mode.
+ * @note
+ * Before set the mag power mode
+ * make sure the following two point is addressed
+ * Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ *
+ * @param v_mag_sec_if_pow_mode_u8 : The value of mag power mode
+ * value | mode
+ * ----------|------------
+ * 0 | BMI160_MAG_FORCE_MODE
+ * 1 | BMI160_MAG_SUSPEND_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_bmm150_mag_and_secondary_if_power_mode(
+u8 v_mag_sec_if_pow_mode_u8);
+/***************************************************/
+/**\name FUNCTIONS FOR AKM09911 AND AKM09912*/
+/***************************************************/
+ /*!
+ * @brief This function used for initialize
+ * the AKM09911 and AKM09912 sensor
+ *
+ *
+ * @param v_akm_i2c_address_u8: The value of device address
+ * AKM sensor | Slave address
+ * --------------|---------------------
+ * AKM09911 | AKM09911_I2C_ADDR_1
+ * - | and AKM09911_I2C_ADDR_2
+ * AKM09912 | AKM09912_I2C_ADDR_1
+ * - | AKM09912_I2C_ADDR_2
+ * - | AKM09912_I2C_ADDR_3
+ * - | AKM09912_I2C_ADDR_4
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_akm_mag_interface_init(
+u8 v_akm_i2c_address_u8);
+ /*!
+ * @brief This function used for read the sensitivity data of
+ * AKM09911 and AKM09912
+ *
+ * @note Before reading the mag sensitivity values
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_bst_akm_sensitivity_data(void);
+/*!
+ * @brief This API used to get the compensated X data
+ * of AKM09911 the out put of X as s32
+ * @note Before start reading the mag compensated X data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bst_akm_x_s16 : The value of X data
+ *
+ * @return results of compensated X data value output as s32
+ *
+ */
+s32 bmi160_bst_akm09911_compensate_X(s16 v_bst_akm_x_s16);
+/*!
+ * @brief This API used to get the compensated Y data
+ * of AKM09911 the out put of Y as s32
+ * @note Before start reading the mag compensated Y data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bst_akm_y_s16 : The value of Y data
+ *
+ * @return results of compensated Y data value output as s32
+ *
+ */
+s32 bmi160_bst_akm09911_compensate_Y(s16 v_bst_akm_y_s16);
+/*!
+ * @brief This API used to get the compensated Z data
+ * of AKM09911 the out put of Z as s32
+ * @note Before start reading the mag compensated Z data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bst_akm_z_s16 : The value of Z data
+ *
+ * @return results of compensated Z data value output as s32
+ *
+ */
+s32 bmi160_bst_akm09911_compensate_Z(s16 v_bst_akm_z_s16);
+/*!
+ * @brief This API used to get the compensated X data
+ * of AKM09912 the out put of X as s32
+ * @note Before start reading the mag compensated X data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bst_akm_x_s16 : The value of X data
+ *
+ * @return results of compensated X data value output as s32
+ *
+ */
+s32 bmi160_bst_akm09912_compensate_X(s16 v_bst_akm_x_s16);
+/*!
+ * @brief This API used to get the compensated Y data
+ * of AKM09912 the out put of Y as s32
+ * @note Before start reading the mag compensated Y data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bst_akm_y_s16 : The value of Y data
+ *
+ * @return results of compensated Y data value output as s32
+ *
+ */
+s32 bmi160_bst_akm09912_compensate_Y(s16 v_bst_akm_y_s16);
+/*!
+ * @brief This API used to get the compensated Z data
+ * of AKM09912 the out put of Z as s32
+ * @note Before start reading the mag compensated Z data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bst_akm_z_s16 : The value of Z data
+ *
+ * @return results of compensated Z data value output as s32
+ *
+ */
+s32 bmi160_bst_akm09912_compensate_Z(s16 v_bst_akm_z_s16);
+ /*!
+ * @brief This function used for read the compensated value of
+ * AKM09911
+ * @note Before start reading the mag compensated data's
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_akm09911_compensate_xyz(
+struct bmi160_mag_xyz_s32_t *bst_akm_xyz);
+ /*!
+ * @brief This function used for read the compensated value of
+ * AKM09912
+ * @note Before start reading the mag compensated data's
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_akm09912_compensate_xyz(
+struct bmi160_mag_xyz_s32_t *bst_akm_xyz);
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_akm09912_compensate_xyz_raw(
+struct bmi160_mag_xyz_s32_t *bst_akm_xyz);
+/*!
+ * @brief This function used for set the AKM09911 and AKM09912
+ * power mode.
+ * @note Before set the AKM power mode
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function bmi160_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * bmi160_set_command_register(0x19) function.
+ *
+ * @param v_akm_pow_mode_u8 : The value of akm power mode
+ * value | Description
+ * ---------|--------------------
+ * 0 | AKM_POWER_DOWN_MODE
+ * 1 | AKM_SINGLE_MEAS_MODE
+ * 2 | FUSE_ROM_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_akm_set_powermode(u8 v_akm_pow_mode_u8);
+ /*!
+ * @brief This function used for set the magnetometer
+ * power mode of AKM09911 and AKM09912
+ * @note Before set the mag power mode
+ * make sure the following two point is addressed
+ * Make sure the mag interface is enabled or not,
+ * by using the bmi160_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function bmi160_get_if_mode(0x02)
+ *
+ * @param v_mag_sec_if_pow_mode_u8 : The value of secondary if power mode
+ * value | Description
+ * ---------|--------------------
+ * 0 | BMI160_MAG_FORCE_MODE
+ * 1 | BMI160_MAG_SUSPEND_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_set_bst_akm_and_secondary_if_powermode(
+u8 v_mag_sec_if_pow_mode_u8);
+/***************************************************/
+/**\name FUNCTIONS FOR YAMAH-YAS532 */
+/***************************************************/
+/*!
+ * @brief This function used for read the YAMAH-YAS532 init
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yamaha_yas532_mag_interface_init(
+void);
+/*!
+ * @brief This function used to set the YAS532 initial values
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas532_set_initial_values(void);
+/*!
+ * @brief This function used for YAS532 offset correction
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas532_magnetic_measure_set_offset(
+void);
+/*!
+ * @brief This function used for read the
+ * YAMAHA YAS532 calibration data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yamaha_yas532_calib_values(void);
+/*!
+ * @brief This function used for calculate the
+ * YAS532 read the linear data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas532_xy1y2_to_linear(
+u16 *v_xy1y2_u16, s32 *xy1y2_linear);
+/*!
+ * @brief This function used for read the YAS532 sensor data
+ * @param v_acquisition_command_u8: used to set the data acquisition
+ * acquisition_command | operation
+ * ---------------------|-------------------------
+ * 0x17 | turn on the acquisition coil
+ * - | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Deferred acquisition mode
+ * 0x07 | turn on the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Normal acquisition mode
+ * 0x11 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Deferred acquisition mode
+ * 0x01 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Normal acquisition mode
+ *
+ * @param v_busy_u8 : used to get the busy flay for sensor data read
+ * @param v_temp_u16 : used to get the temperature data
+ * @param v_xy1y2_u16 : used to get the sensor xy1y2 data
+ * @param v_overflow_u8 : used to get the overflow data
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas532_normal_measurement_data(
+u8 v_acquisition_command_u8, u8 *v_busy_u8,
+u16 *v_temp_u16, u16 *v_xy1y2_u16, u8 *v_overflow_u8);
+/*!
+ * @brief This function used for YAS532 sensor data
+ * @param v_acquisition_command_u8 : the value of CMDR
+ * acquisition_command | operation
+ * ---------------------|-------------------------
+ * 0x17 | turn on the acquisition coil
+ * - | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Deferred acquisition mode
+ * 0x07 | turn on the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Normal acquisition mode
+ * 0x11 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Deferred acquisition mode
+ * 0x01 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Normal acquisition mode
+ *
+ * @param xyz_data : the vector xyz output
+ * @param v_overflow_s8 : the value of overflow
+ * @param v_temp_correction_u8 : the value of temperate correction enable
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas532_measurement_xyz_data(
+struct yas532_vector *xyz_data, u8 *v_overflow_s8, u8 v_temp_correction_u8,
+u8 v_acquisition_command_u8);
+/*!
+ * @brief This function used for YAS532 write data acquisition
+ * command register write
+ * @param v_command_reg_data_u8 : the value of data acquisition
+ * acquisition_command | operation
+ * ---------------------|-------------------------
+ * 0x17 | turn on the acquisition coil
+ * - | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Deferred acquisition mode
+ * 0x07 | turn on the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Normal acquisition mode
+ * 0x11 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Deferred acquisition mode
+ * 0x01 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Normal acquisition mode
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas532_acquisition_command_register(
+u8 v_command_reg_data_u8);
+/*!
+ * @brief This function used write offset of YAS532
+ *
+ * @param p_offset_s8 : The value of offset to write
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas532_set_offset(
+const s8 *p_offset_s8);
+/*!
+ * @brief This function used to init the YAMAH-YAS537
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yamaha_yas537_mag_interface_init(
+void);
+/*!
+ * @brief This function used for read the
+ * YAMAHA YAS537 calibration data
+ *
+ *
+ * @param v_rcoil_u8 : The value of r coil
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yamaha_yas537_calib_values(
+u8 v_rcoil_u8);
+/*!
+ * @brief This function used for YAS537 write data acquisition
+ * command register write
+ * @param v_command_reg_data_u8 : the value of data acquisition
+ * acquisition_command | operation
+ * ---------------------|-------------------------
+ * 0x17 | turn on the acquisition coil
+ * - | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Deferred acquisition mode
+ * 0x07 | turn on the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Normal acquisition mode
+ * 0x11 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Deferred acquisition mode
+ * 0x01 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Normal acquisition mode
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yas537_acquisition_command_register(
+u8 v_command_reg_data_u8);
+
+/*!
+ * @brief This function used for read the
+ * YAMAHA YAS537 xy1y2 data
+ *
+ * @param v_coil_stat_u8: The value of R coil status
+ * @param v_busy_u8: The value of busy status
+ * @param v_temperature_u16: The value of temperature
+ * @param xy1y2: The value of raw xy1y2 data
+ * @param v_ouflow_u8: The value of overflow
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yamaha_yas537_read_xy1y2_data(
+u8 *v_coil_stat_u8, u8 *v_busy_u8,
+u16 *v_temperature_u16, u16 *xy1y2, u8 *v_ouflow_u8);
+/*!
+ * @brief This function used for read the
+ * YAMAHA YAS537 xy1y2 data
+ *
+ * @param v_ouflow_u8: The value of overflow
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_bst_yamaha_yas537_measure_xyz_data(
+u8 *v_ouflow_u8, struct yas_vector *vector_xyz);
+
+/***************************************************/
+/**\name FUNCTIONS FOR FIFO DATA READ */
+/***************************************************/
+/*!
+ * @brief This function used for reading the
+ * fifo data of header less mode
+ *
+ *
+ *
+ * @note Configure the below functions for FIFO header less mode
+ * @note 1. bmi160_set_fifo_down_gyro
+ * @note 2. bmi160_set_gyro_fifo_filter_data
+ * @note 3. bmi160_set_fifo_down_accel
+ * @note 4. bmi160_set_accel_fifo_filter_dat
+ * @note 5. bmi160_set_fifo_mag_enable
+ * @note 6. bmi160_set_fifo_accel_enable
+ * @note 7. bmi160_set_fifo_gyro_enable
+ * @note For interrupt configuration
+ * @note 1. bmi160_set_intr_fifo_full
+ * @note 2. bmi160_set_intr_fifo_wm
+ * @note 3. bmi160_set_fifo_tag_intr2_enable
+ * @note 4. bmi160_set_fifo_tag_intr1_enable
+ *
+ * @note The fifo reads the whole 1024 bytes
+ * and processing the data
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_fifo_headerless_mode(
+void);
+/*!
+ * @brief This function used for reading the
+ * fifo data of header less mode for using user defined length
+ *
+ *
+ * @param v_fifo_user_length_u16: The value of length of fifo read data
+ *
+ * @note Configure the below functions for FIFO header less mode
+ * @note 1. bmi160_set_fifo_down_gyro
+ * @note 2. bmi160_set_gyro_fifo_filter_data
+ * @note 3. bmi160_set_fifo_down_accel
+ * @note 4. bmi160_set_accel_fifo_filter_dat
+ * @note 5. bmi160_set_fifo_mag_enable
+ * @note 6. bmi160_set_fifo_accel_enable
+ * @note 7. bmi160_set_fifo_gyro_enable
+ * @note For interrupt configuration
+ * @note 1. bmi160_set_intr_fifo_full
+ * @note 2. bmi160_set_intr_fifo_wm
+ * @note 3. bmi160_set_fifo_tag_intr2_enable
+ * @note 4. bmi160_set_fifo_tag_intr1_enable
+ *
+ * @note The fifo reads the whole 1024 bytes
+ * and processing the data
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE
+bmi160_read_fifo_headerless_mode_user_defined_length(
+u16 v_fifo_user_length_u16);
+/*!
+ * @brief This function used for reading the
+ * fifo data of header mode
+ *
+ *
+ * @note Configure the below functions for FIFO header mode
+ * @note 1. bmi160_set_fifo_down_gyro()
+ * @note 2. bmi160_set_gyro_fifo_filter_data()
+ * @note 3. bmi160_set_fifo_down_accel()
+ * @note 4. bmi160_set_accel_fifo_filter_dat()
+ * @note 5. bmi160_set_fifo_mag_enable()
+ * @note 6. bmi160_set_fifo_accel_enable()
+ * @note 7. bmi160_set_fifo_gyro_enable()
+ * @note 8. bmi160_set_fifo_header_enable()
+ * @note For interrupt configuration
+ * @note 1. bmi160_set_intr_fifo_full()
+ * @note 2. bmi160_set_intr_fifo_wm()
+ * @note 3. bmi160_set_fifo_tag_intr2_enable()
+ * @note 4. bmi160_set_fifo_tag_intr1_enable()
+ *
+ * @note The fifo reads the whole 1024 bytes
+ * and processing the data
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_fifo_header_data(
+void);
+/*!
+ * @brief This function used for reading the
+ * fifo data of header mode for using user defined length
+ *
+ *
+ * @note Configure the below functions for FIFO header mode
+ * @note 1. bmi160_set_fifo_down_gyro()
+ * @note 2. bmi160_set_gyro_fifo_filter_data()
+ * @note 3. bmi160_set_fifo_down_accel()
+ * @note 4. bmi160_set_accel_fifo_filter_dat()
+ * @note 5. bmi160_set_fifo_mag_enable()
+ * @note 6. bmi160_set_fifo_accel_enable()
+ * @note 7. bmi160_set_fifo_gyro_enable()
+ * @note 8. bmi160_set_fifo_header_enable()
+ * @note For interrupt configuration
+ * @note 1. bmi160_set_intr_fifo_full()
+ * @note 2. bmi160_set_intr_fifo_wm()
+ * @note 3. bmi160_set_fifo_tag_intr2_enable()
+ * @note 4. bmi160_set_fifo_tag_intr1_enable()
+ *
+ * @note The fifo reads the whole 1024 bytes
+ * and processing the data
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+BMI160_RETURN_FUNCTION_TYPE bmi160_read_fifo_header_data_user_defined_length(
+u16 v_fifo_user_length_u16);
+/*!
+ * @brief This function used for reading
+ * bmi160_t structure
+ *
+ * @return the reference and values of bmi160_t
+ *
+ *
+*/
+struct bmi160_t *bmi160_get_ptr(void);
+
+#endif
+
diff --git a/drivers/input/sensors/bmi160/bmi160_driver.c b/drivers/input/sensors/bmi160/bmi160_driver.c
new file mode 100644
index 0000000..66d2248
--- /dev/null
+++ b/drivers/input/sensors/bmi160/bmi160_driver.c
@@ -0,0 +1,4021 @@
+/*!
+ * @section LICENSE
+ * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved
+ *
+ * This software program is licensed subject to the GNU General
+ * Public License (GPL).Version 2,June 1991,
+ * available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * @filename bmi160_driver.c
+ * @date 2016/08/01 14:40
+ * @id "b5ff23a"
+ * @version 1.3
+ *
+ * @brief
+ * The core code of BMI160 device driver
+ *
+ * @detail
+ * This file implements the core code of BMI160 device driver,
+ * which includes hardware related functions, input device register,
+ * device attribute files, etc.
+*/
+
+#include "bmi160.h"
+#include "bmi160_driver.h"
+#include <linux/device.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/of_irq.h>
+
+
+#define DRIVER_VERSION "0.0.53.0"
+#define I2C_BURST_READ_MAX_LEN (256)
+#define BMI160_STORE_COUNT (6000)
+#define LMADA (1)
+uint64_t g_current_apts_us;
+
+
+enum BMI_SENSOR_INT_T {
+ /* Interrupt enable0*/
+ BMI_ANYMO_X_INT = 0,
+ BMI_ANYMO_Y_INT,
+ BMI_ANYMO_Z_INT,
+ BMI_D_TAP_INT,
+ BMI_S_TAP_INT,
+ BMI_ORIENT_INT,
+ BMI_FLAT_INT,
+ /* Interrupt enable1*/
+ BMI_HIGH_X_INT,
+ BMI_HIGH_Y_INT,
+ BMI_HIGH_Z_INT,
+ BMI_LOW_INT,
+ BMI_DRDY_INT,
+ BMI_FFULL_INT,
+ BMI_FWM_INT,
+ /* Interrupt enable2 */
+ BMI_NOMOTION_X_INT,
+ BMI_NOMOTION_Y_INT,
+ BMI_NOMOTION_Z_INT,
+ BMI_STEP_DETECTOR_INT,
+ INT_TYPE_MAX
+};
+
+/*bmi fifo sensor type combination*/
+enum BMI_SENSOR_FIFO_COMBINATION {
+ BMI_FIFO_A = 0,
+ BMI_FIFO_G,
+ BMI_FIFO_M,
+ BMI_FIFO_G_A,
+ BMI_FIFO_M_A,
+ BMI_FIFO_M_G,
+ BMI_FIFO_M_G_A,
+ BMI_FIFO_COM_MAX
+};
+
+/*bmi fifo analyse return err status*/
+enum BMI_FIFO_ANALYSE_RETURN_T {
+ FIFO_OVER_READ_RETURN = -10,
+ FIFO_SENSORTIME_RETURN = -9,
+ FIFO_SKIP_OVER_LEN = -8,
+ FIFO_M_G_A_OVER_LEN = -7,
+ FIFO_M_G_OVER_LEN = -6,
+ FIFO_M_A_OVER_LEN = -5,
+ FIFO_G_A_OVER_LEN = -4,
+ FIFO_M_OVER_LEN = -3,
+ FIFO_G_OVER_LEN = -2,
+ FIFO_A_OVER_LEN = -1
+};
+
+/*!bmi sensor generic power mode enum */
+enum BMI_DEV_OP_MODE {
+ SENSOR_PM_NORMAL = 0,
+ SENSOR_PM_LP1,
+ SENSOR_PM_SUSPEND,
+ SENSOR_PM_LP2
+};
+
+/*! bmi acc sensor power mode enum */
+enum BMI_ACC_PM_TYPE {
+ BMI_ACC_PM_NORMAL = 0,
+ BMI_ACC_PM_LP1,
+ BMI_ACC_PM_SUSPEND,
+ BMI_ACC_PM_LP2,
+ BMI_ACC_PM_MAX
+};
+
+/*! bmi gyro sensor power mode enum */
+enum BMI_GYRO_PM_TYPE {
+ BMI_GYRO_PM_NORMAL = 0,
+ BMI_GYRO_PM_FAST_START,
+ BMI_GYRO_PM_SUSPEND,
+ BMI_GYRO_PM_MAX
+};
+
+/*! bmi mag sensor power mode enum */
+enum BMI_MAG_PM_TYPE {
+ BMI_MAG_PM_NORMAL = 0,
+ BMI_MAG_PM_LP1,
+ BMI_MAG_PM_SUSPEND,
+ BMI_MAG_PM_LP2,
+ BMI_MAG_PM_MAX
+};
+
+
+/*! bmi sensor support type*/
+enum BMI_SENSOR_TYPE {
+ BMI_ACC_SENSOR,
+ BMI_GYRO_SENSOR,
+ BMI_MAG_SENSOR,
+ BMI_SENSOR_TYPE_MAX
+};
+
+/*!bmi sensor generic power mode enum */
+enum BMI_AXIS_TYPE {
+ X_AXIS = 0,
+ Y_AXIS,
+ Z_AXIS,
+ AXIS_MAX
+};
+
+/*!bmi sensor generic intterrupt enum */
+enum BMI_INT_TYPE {
+ BMI160_INT0 = 0,
+ BMI160_INT1,
+ BMI160_INT_MAX
+};
+
+/*! bmi sensor time resolution definition*/
+enum BMI_SENSOR_TIME_RS_TYPE {
+ TS_0_78_HZ = 1,/*0.78HZ*/
+ TS_1_56_HZ,/*1.56HZ*/
+ TS_3_125_HZ,/*3.125HZ*/
+ TS_6_25_HZ,/*6.25HZ*/
+ TS_12_5_HZ,/*12.5HZ*/
+ TS_25_HZ,/*25HZ, odr=6*/
+ TS_50_HZ,/*50HZ*/
+ TS_100_HZ,/*100HZ*/
+ TS_200_HZ,/*200HZ*/
+ TS_400_HZ,/*400HZ*/
+ TS_800_HZ,/*800HZ*/
+ TS_1600_HZ,/*1600HZ*/
+ TS_MAX_HZ
+};
+
+/*! bmi sensor interface mode */
+enum BMI_SENSOR_IF_MODE_TYPE {
+ /*primary interface:autoconfig/secondary interface off*/
+ P_AUTO_S_OFF = 0,
+ /*primary interface:I2C/secondary interface:OIS*/
+ P_I2C_S_OIS,
+ /*primary interface:autoconfig/secondary interface:Magnetometer*/
+ P_AUTO_S_MAG,
+ /*interface mode reseved*/
+ IF_MODE_RESEVED
+
+};
+
+/*! bmi160 acc/gyro calibration status in H/W layer */
+enum BMI_CALIBRATION_STATUS_TYPE {
+ /*BMI FAST Calibration ready x/y/z status*/
+ BMI_ACC_X_FAST_CALI_RDY = 0,
+ BMI_ACC_Y_FAST_CALI_RDY,
+ BMI_ACC_Z_FAST_CALI_RDY
+};
+
+unsigned int reg_op_addr;
+
+static const int bmi_pmu_cmd_acc_arr[BMI_ACC_PM_MAX] = {
+ /*!bmi pmu for acc normal, low power1,
+ * suspend, low power2 mode command */
+ CMD_PMU_ACC_NORMAL,
+ CMD_PMU_ACC_LP1,
+ CMD_PMU_ACC_SUSPEND,
+ CMD_PMU_ACC_LP2
+};
+
+static const int bmi_pmu_cmd_gyro_arr[BMI_GYRO_PM_MAX] = {
+ /*!bmi pmu for gyro normal, fast startup,
+ * suspend mode command */
+ CMD_PMU_GYRO_NORMAL,
+ CMD_PMU_GYRO_FASTSTART,
+ CMD_PMU_GYRO_SUSPEND
+};
+
+static const int bmi_pmu_cmd_mag_arr[BMI_MAG_PM_MAX] = {
+ /*!bmi pmu for mag normal, low power1,
+ * suspend, low power2 mode command */
+ CMD_PMU_MAG_NORMAL,
+ CMD_PMU_MAG_LP1,
+ CMD_PMU_MAG_SUSPEND,
+ CMD_PMU_MAG_LP2
+};
+
+static const char *bmi_axis_name[AXIS_MAX] = {"x", "y", "z"};
+
+static const int bmi_interrupt_type[] = {
+ /*!bmi interrupt type */
+ /* Interrupt enable0 , index=0~6*/
+ BMI160_ANY_MOTION_X_ENABLE,
+ BMI160_ANY_MOTION_Y_ENABLE,
+ BMI160_ANY_MOTION_Z_ENABLE,
+ BMI160_DOUBLE_TAP_ENABLE,
+ BMI160_SINGLE_TAP_ENABLE,
+ BMI160_ORIENT_ENABLE,
+ BMI160_FLAT_ENABLE,
+ /* Interrupt enable1, index=7~13*/
+ BMI160_HIGH_G_X_ENABLE,
+ BMI160_HIGH_G_Y_ENABLE,
+ BMI160_HIGH_G_Z_ENABLE,
+ BMI160_LOW_G_ENABLE,
+ BMI160_DATA_RDY_ENABLE,
+ BMI160_FIFO_FULL_ENABLE,
+ BMI160_FIFO_WM_ENABLE,
+ /* Interrupt enable2, index = 14~17*/
+ BMI160_NOMOTION_X_ENABLE,
+ BMI160_NOMOTION_Y_ENABLE,
+ BMI160_NOMOTION_Z_ENABLE,
+ BMI160_STEP_DETECTOR_EN
+};
+
+/*! bmi sensor time depend on ODR*/
+struct bmi_sensor_time_odr_tbl {
+ u32 ts_duration_lsb;
+ u32 ts_duration_us;
+ u32 ts_delat;/*sub current delat fifo_time*/
+};
+
+struct bmi160_axis_data_t {
+ s16 x;
+ s16 y;
+ s16 z;
+};
+
+struct bmi160_type_mapping_type {
+
+ /*! bmi16x sensor chip id */
+ uint16_t chip_id;
+
+ /*! bmi16x chip revision code */
+ uint16_t revision_id;
+
+ /*! bma2x2 sensor name */
+ const char *sensor_name;
+};
+
+struct bmi160_store_info_t {
+ uint8_t current_frm_cnt;
+ uint64_t current_apts_us[2];
+ uint8_t fifo_ts_total_frmcnt;
+ uint64_t fifo_time;
+};
+
+uint64_t get_current_timestamp(void)
+{
+ uint64_t ts_ap;
+ struct timespec tmp_time;
+ get_monotonic_boottime(&tmp_time);
+ ts_ap = (uint64_t)tmp_time.tv_sec * 1000000000 + tmp_time.tv_nsec;
+ return ts_ap;
+
+}
+
+/*! sensor support type map */
+static const struct bmi160_type_mapping_type sensor_type_map[] = {
+
+ {SENSOR_CHIP_ID_BMI, SENSOR_CHIP_REV_ID_BMI, "BMI160/162AB"},
+ {SENSOR_CHIP_ID_BMI_C2, SENSOR_CHIP_REV_ID_BMI, "BMI160C2"},
+ {SENSOR_CHIP_ID_BMI_C3, SENSOR_CHIP_REV_ID_BMI, "BMI160C3"},
+
+};
+
+/*!bmi160 sensor time depends on ODR */
+static const struct bmi_sensor_time_odr_tbl
+ sensortime_duration_tbl[TS_MAX_HZ] = {
+ {0x010000, 2560000, 0x00ffff},/*2560ms, 0.39hz, odr=resver*/
+ {0x008000, 1280000, 0x007fff},/*1280ms, 0.78hz, odr_acc=1*/
+ {0x004000, 640000, 0x003fff},/*640ms, 1.56hz, odr_acc=2*/
+ {0x002000, 320000, 0x001fff},/*320ms, 3.125hz, odr_acc=3*/
+ {0x001000, 160000, 0x000fff},/*160ms, 6.25hz, odr_acc=4*/
+ {0x000800, 80000, 0x0007ff},/*80ms, 12.5hz*/
+ {0x000400, 40000, 0x0003ff},/*40ms, 25hz, odr_acc = odr_gyro =6*/
+ {0x000200, 20000, 0x0001ff},/*20ms, 50hz, odr = 7*/
+ {0x000100, 10000, 0x0000ff},/*10ms, 100hz, odr=8*/
+ {0x000080, 5000, 0x00007f},/*5ms, 200hz, odr=9*/
+ {0x000040, 2500, 0x00003f},/*2.5ms, 400hz, odr=10*/
+ {0x000020, 1250, 0x00001f},/*1.25ms, 800hz, odr=11*/
+ {0x000010, 625, 0x00000f},/*0.625ms, 1600hz, odr=12*/
+
+};
+
+#if defined(CONFIG_USE_QUALCOMM_HAL)
+#define POLL_INTERVAL_MIN_MS 10
+#define POLL_INTERVAL_MAX_MS 4000
+#define POLL_DEFAULT_INTERVAL_MS 200
+#define BMI160_ACCEL_MIN_VALUE -32768
+#define BMI160_ACCEL_MAX_VALUE 32767
+#define BMI160_GYRO_MIN_VALUE -32768
+#define BMI160_GYRO_MAX_VALUE 32767
+#define BMI160_ACCEL_DEFAULT_POLL_INTERVAL_MS 200
+#define BMI160_GYRO_DEFAULT_POLL_INTERVAL_MS 200
+#define BMI160_ACCEL_MIN_POLL_INTERVAL_MS 10
+#define BMI160_ACCEL_MAX_POLL_INTERVAL_MS 5000
+#define BMI160_GYRO_MIN_POLL_INTERVAL_MS 10
+#define BMI160_GYRO_MAX_POLL_INTERVAL_MS 5000
+static struct sensors_classdev bmi160_accel_cdev = {
+ .name = "bmi160-accel",
+ .vendor = "bosch",
+ .version = 1,
+ .handle = SENSORS_ACCELERATION_HANDLE,
+ .type = SENSOR_TYPE_ACCELEROMETER,
+ .max_range = "156.8", /* 16g */
+ .resolution = "0.153125", /* 15.6mg */
+ .sensor_power = "0.13", /* typical value */
+ .min_delay = POLL_INTERVAL_MIN_MS * 1000, /* in microseconds */
+ .max_delay = POLL_INTERVAL_MAX_MS,
+ .delay_msec = POLL_DEFAULT_INTERVAL_MS, /* in millisecond */
+ .fifo_reserved_event_count = 0,
+ .fifo_max_event_count = 0,
+ .enabled = 0,
+ .max_latency = 0,
+ .flags = 0,
+ .sensors_enable = NULL,
+ .sensors_poll_delay = NULL,
+ .sensors_set_latency = NULL,
+ .sensors_flush = NULL,
+ .sensors_self_test = NULL,
+};
+static struct sensors_classdev bmi160_gyro_cdev = {
+ .name = "bmi160-gyro",
+ .vendor = "bosch",
+ .version = 1,
+ .handle = SENSORS_GYROSCOPE_HANDLE,
+ .type = SENSOR_TYPE_GYROSCOPE,
+ .max_range = "34.906586", /* rad/s */
+ .resolution = "0.0010681152", /* rad/s */
+ .sensor_power = "3.6", /* 3.6 mA */
+ .min_delay = BMI160_GYRO_MIN_POLL_INTERVAL_MS * 1000,
+ .max_delay = BMI160_GYRO_MAX_POLL_INTERVAL_MS,
+ .delay_msec = BMI160_GYRO_DEFAULT_POLL_INTERVAL_MS,
+ .fifo_reserved_event_count = 0,
+ .fifo_max_event_count = 0,
+ .enabled = 0,
+ .max_latency = 0,
+ .flags = 0, /* SENSOR_FLAG_CONTINUOUS_MODE */
+ .sensors_enable = NULL,
+ .sensors_poll_delay = NULL,
+ .sensors_enable_wakeup = NULL,
+ .sensors_set_latency = NULL,
+ .sensors_flush = NULL,
+};
+#endif
+static void bmi_delay(u32 msec)
+{
+ if (msec <= 20)
+ usleep_range(msec * 1000, msec * 1000);
+ else
+ msleep(msec);
+}
+
+static void bmi_dump_reg(struct bmi_client_data *client_data)
+{
+ #define REG_MAX0 0x24
+ #define REG_MAX1 0x56
+ int i;
+ u8 dbg_buf0[REG_MAX0];
+ u8 dbg_buf1[REG_MAX1];
+ u8 dbg_buf_str0[REG_MAX0 * 3 + 1] = "";
+ u8 dbg_buf_str1[REG_MAX1 * 3 + 1] = "";
+
+ dev_notice(client_data->dev, "\nFrom 0x00:\n");
+
+ client_data->device.bus_read(client_data->device.dev_addr,
+ BMI_REG_NAME(USER_CHIP_ID), dbg_buf0, REG_MAX0);
+ for (i = 0; i < REG_MAX0; i++) {
+ snprintf(dbg_buf_str0 + i * 3, 16, "%02x%c", dbg_buf0[i],
+ (((i + 1) % BYTES_PER_LINE == 0) ? '\n' : ' '));
+ }
+ dev_notice(client_data->dev, "%s\n", dbg_buf_str0);
+
+ client_data->device.bus_read(client_data->device.dev_addr,
+ BMI160_USER_ACCEL_CONFIG_ADDR, dbg_buf1, REG_MAX1);
+ dev_notice(client_data->dev, "\nFrom 0x40:\n");
+ for (i = 0; i < REG_MAX1; i++) {
+ snprintf(dbg_buf_str1 + i * 3, 16, "%02x%c", dbg_buf1[i],
+ (((i + 1) % BYTES_PER_LINE == 0) ? '\n' : ' '));
+ }
+ dev_notice(client_data->dev, "\n%s\n", dbg_buf_str1);
+ }
+
+
+void bmi_fifo_frame_bytes_extend_calc(
+ struct bmi_client_data *client_data,
+ unsigned int *fifo_frmbytes_extend)
+{
+
+ switch (client_data->fifo_data_sel) {
+ case BMI_FIFO_A_SEL:
+ case BMI_FIFO_G_SEL:
+ *fifo_frmbytes_extend = 7;
+ break;
+ case BMI_FIFO_G_A_SEL:
+ *fifo_frmbytes_extend = 13;
+ break;
+ case BMI_FIFO_M_SEL:
+ *fifo_frmbytes_extend = 9;
+ break;
+ case BMI_FIFO_M_A_SEL:
+ case BMI_FIFO_M_G_SEL:
+ /*8(mag) + 6(gyro or acc) +1(head) = 15*/
+ *fifo_frmbytes_extend = 15;
+ break;
+ case BMI_FIFO_M_G_A_SEL:
+ /*8(mag) + 6(gyro or acc) + 6 + 1 = 21*/
+ *fifo_frmbytes_extend = 21;
+ break;
+ default:
+ *fifo_frmbytes_extend = 0;
+ break;
+
+ };
+
+}
+
+
+static int bmi_input_init(struct bmi_client_data *client_data)
+{
+ struct input_dev *dev;
+ int err = 0;
+
+ dev = input_allocate_device();
+ if (NULL == dev)
+ return -ENOMEM;
+#if defined(CONFIG_USE_QUALCOMM_HAL)
+ dev->name = "bmi160-accel";
+#else
+ dev->name = SENSOR_NAME;
+#endif
+ dev->id.bustype = BUS_I2C;
+
+ input_set_capability(dev, EV_MSC, MSC_GESTURE);
+ input_set_capability(dev, EV_MSC, INPUT_EVENT_SGM);
+
+ input_set_capability(dev, EV_MSC, INPUT_EVENT_FAST_GYRO_CALIB_DONE);
+ input_set_capability(dev, EV_MSC, INPUT_EVENT_STEP_DETECTOR);
+ input_set_capability(dev, EV_MSC, INPUT_EVENT_FAST_ACC_CALIB_DONE);
+
+
+ input_set_capability(dev, EV_REL, REL_X);
+ input_set_capability(dev, EV_REL, REL_Y);
+ input_set_capability(dev, EV_REL, REL_Z);
+ #if defined(CONFIG_USE_QUALCOMM_HAL)
+ input_set_capability(dev, EV_ABS, ABS_MISC);
+ input_set_abs_params(dev, ABS_X,
+ BMI160_ACCEL_MIN_VALUE, BMI160_ACCEL_MAX_VALUE,
+ 0, 0);
+ input_set_abs_params(dev, ABS_Y,
+ BMI160_ACCEL_MIN_VALUE, BMI160_ACCEL_MAX_VALUE,
+ 0, 0);
+ input_set_abs_params(dev, ABS_Z,
+ BMI160_ACCEL_MIN_VALUE, BMI160_ACCEL_MAX_VALUE,
+ 0, 0);
+ #endif
+ input_set_drvdata(dev, client_data);
+
+ err = input_register_device(dev);
+ if (err < 0) {
+ input_free_device(dev);
+ dev_notice(client_data->dev, "bmi160 input free!\n");
+ return err;
+ }
+ client_data->input = dev;
+ dev_notice(client_data->dev,
+ "bmi160 input register successfully, %s!\n",
+ client_data->input->name);
+ return err;
+}
+
+//#if defined(CONFIG_USE_QUALCOMM_HAL)
+static int bmi_gyro_input_init(struct bmi_client_data *client_data)
+{
+ struct input_dev *dev;
+ int err = 0;
+
+ dev = input_allocate_device();
+ if (NULL == dev)
+ return -ENOMEM;
+ dev->name = "bmi160-gyro";
+ dev->id.bustype = BUS_I2C;
+ input_set_capability(dev, EV_ABS, ABS_MISC);
+ input_set_capability(dev, EV_MSC, MSC_GESTURE);
+ input_set_capability(dev, EV_MSC, INPUT_EVENT_SGM);
+
+ input_set_capability(dev, EV_MSC, INPUT_EVENT_FAST_GYRO_CALIB_DONE);
+ input_set_capability(dev, EV_MSC, INPUT_EVENT_STEP_DETECTOR);
+ input_set_capability(dev, EV_MSC, INPUT_EVENT_FAST_ACC_CALIB_DONE);
+ #if defined(CONFIG_USE_QUALCOMM_HAL)
+ input_set_abs_params(dev, ABS_RX,
+ BMI160_ACCEL_MIN_VALUE, BMI160_ACCEL_MAX_VALUE,
+ 0, 0);
+ input_set_abs_params(dev, ABS_RY,
+ BMI160_ACCEL_MIN_VALUE, BMI160_ACCEL_MAX_VALUE,
+ 0, 0);
+ input_set_abs_params(dev, ABS_RZ,
+ BMI160_ACCEL_MIN_VALUE, BMI160_ACCEL_MAX_VALUE,
+ 0, 0);
+ #endif
+ input_set_drvdata(dev, client_data);
+ err = input_register_device(dev);
+ if (err < 0) {
+ input_free_device(dev);
+ dev_notice(client_data->dev, "bmi160 input free!\n");
+ return err;
+ }
+ client_data->gyro_input = dev;
+ dev_notice(client_data->dev,
+ "bmi160 input register successfully, %s!\n",
+ client_data->gyro_input->name);
+ return err;
+}
+//#endif
+static void bmi_input_destroy(struct bmi_client_data *client_data)
+{
+ struct input_dev *dev = client_data->input;
+
+ input_unregister_device(dev);
+ input_free_device(dev);
+}
+
+static int bmi_check_chip_id(struct bmi_client_data *client_data)
+{
+ int8_t err = 0;
+ int8_t i = 0;
+ uint8_t chip_id = 0;
+ uint8_t read_count = 0;
+ u8 bmi_sensor_cnt = sizeof(sensor_type_map)
+ / sizeof(struct bmi160_type_mapping_type);
+ /* read and check chip id */
+ while (read_count++ < CHECK_CHIP_ID_TIME_MAX) {
+ if (client_data->device.bus_read(client_data->device.dev_addr,
+ BMI_REG_NAME(USER_CHIP_ID), &chip_id, 1) < 0) {
+
+ dev_err(client_data->dev,
+ "Bosch Sensortec Device not found"
+ "read chip_id:%d\n", chip_id);
+ continue;
+ } else {
+ for (i = 0; i < bmi_sensor_cnt; i++) {
+ if (sensor_type_map[i].chip_id == chip_id) {
+ client_data->chip_id = chip_id;
+ dev_notice(client_data->dev,
+ "Bosch Sensortec Device detected, "
+ "HW IC name: %s\n", sensor_type_map[i].sensor_name);
+ break;
+ }
+ }
+ if (i < bmi_sensor_cnt)
+ break;
+ else {
+ if (read_count == CHECK_CHIP_ID_TIME_MAX) {
+ dev_err(client_data->dev,
+ "Failed!Bosch Sensortec Device not found"
+ " mismatch chip_id:%d\n", chip_id);
+ err = -ENODEV;
+ return err;
+ }
+ }
+ bmi_delay(1);
+ }
+ }
+ return err;
+
+}
+
+static int bmi_pmu_set_suspend(struct bmi_client_data *client_data)
+{
+ int err = 0;
+ if (client_data == NULL)
+ return -EINVAL;
+ else {
+ err += BMI_CALL_API(set_command_register)
+ (bmi_pmu_cmd_acc_arr[SENSOR_PM_SUSPEND]);
+ err += BMI_CALL_API(set_command_register)
+ (bmi_pmu_cmd_gyro_arr[SENSOR_PM_SUSPEND]);
+ err += BMI_CALL_API(set_command_register)
+ (bmi_pmu_cmd_mag_arr[SENSOR_PM_SUSPEND]);
+ client_data->pw.acc_pm = BMI_ACC_PM_SUSPEND;
+ client_data->pw.gyro_pm = BMI_GYRO_PM_SUSPEND;
+ client_data->pw.mag_pm = BMI_MAG_PM_SUSPEND;
+ }
+
+ return err;
+}
+
+static int bmi_get_err_status(struct bmi_client_data *client_data)
+{
+ int err = 0;
+
+ err = BMI_CALL_API(get_error_status)(&client_data->err_st.fatal_err,
+ &client_data->err_st.err_code, &client_data->err_st.i2c_fail,
+ &client_data->err_st.drop_cmd, &client_data->err_st.mag_drdy_err);
+ return err;
+}
+
+static void bmi_work_func(struct work_struct *work)
+{
+ struct bmi_client_data *client_data =
+ container_of((struct delayed_work *)work,
+ struct bmi_client_data, work);
+ unsigned long delay =
+ msecs_to_jiffies(atomic_read(&client_data->delay));
+ struct bmi160_accel_t data;
+ int err;
+
+ err = BMI_CALL_API(read_accel_xyz)(&data);
+ if (err < 0)
+ return;
+
+ /*report current frame via input event*/
+ input_event(client_data->input, EV_REL, REL_X, data.x);
+ input_event(client_data->input, EV_REL, REL_Y, data.y);
+ input_event(client_data->input, EV_REL, REL_Z, data.z);
+ input_sync(client_data->input);
+
+ schedule_delayed_work(&client_data->work, delay);
+}
+
+static ssize_t bmi160_chip_id_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+
+ return snprintf(buf, 16, "0x%x\n", client_data->chip_id);
+}
+
+static ssize_t bmi160_err_st_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+ int err = 0;
+ err = bmi_get_err_status(client_data);
+ if (err)
+ return err;
+ else {
+ return snprintf(buf, 128, "fatal_err:0x%x, err_code:%d,\n\n"
+ "i2c_fail_err:%d, drop_cmd_err:%d, mag_drdy_err:%d\n",
+ client_data->err_st.fatal_err,
+ client_data->err_st.err_code,
+ client_data->err_st.i2c_fail,
+ client_data->err_st.drop_cmd,
+ client_data->err_st.mag_drdy_err);
+
+ }
+}
+
+static ssize_t bmi160_sensor_time_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err = 0;
+ u32 sensor_time;
+ err = BMI_CALL_API(get_sensor_time)(&sensor_time);
+ if (err)
+ return err;
+ else
+ return snprintf(buf, 16, "0x%x\n", (unsigned int)sensor_time);
+}
+
+static ssize_t bmi160_fifo_flush_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long enable;
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &enable);
+ if (err)
+ return err;
+ if (enable)
+ err = BMI_CALL_API(set_command_register)(CMD_CLR_FIFO_DATA);
+
+ if (err)
+ dev_err(client_data->dev, "fifo flush failed!\n");
+
+ return count;
+
+}
+
+
+static ssize_t bmi160_fifo_bytecount_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned int fifo_bytecount = 0;
+
+ BMI_CALL_API(fifo_length)(&fifo_bytecount);
+ err = snprintf(buf, 16, "%u\n", fifo_bytecount);
+ return err;
+}
+
+static ssize_t bmi160_fifo_bytecount_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+ int err;
+ unsigned long data;
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+ client_data->fifo_bytecount = (unsigned int) data;
+
+ return count;
+}
+
+int bmi160_fifo_data_sel_get(struct bmi_client_data *client_data)
+{
+ int err = 0;
+ unsigned char fifo_acc_en, fifo_gyro_en, fifo_mag_en;
+ unsigned char fifo_datasel;
+
+ err += BMI_CALL_API(get_fifo_accel_enable)(&fifo_acc_en);
+ err += BMI_CALL_API(get_fifo_gyro_enable)(&fifo_gyro_en);
+ err += BMI_CALL_API(get_fifo_mag_enable)(&fifo_mag_en);
+
+ if (err)
+ return err;
+
+ fifo_datasel = (fifo_acc_en << BMI_ACC_SENSOR) |
+ (fifo_gyro_en << BMI_GYRO_SENSOR) |
+ (fifo_mag_en << BMI_MAG_SENSOR);
+
+ client_data->fifo_data_sel = fifo_datasel;
+
+ return err;
+
+
+}
+
+static ssize_t bmi160_fifo_data_sel_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err = 0;
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+ err = bmi160_fifo_data_sel_get(client_data);
+ if (err) {
+ dev_err(client_data->dev, "get fifo_sel failed!\n");
+ return -EINVAL;
+ }
+ return snprintf(buf, 16, "%d\n", client_data->fifo_data_sel);
+}
+
+/* write any value to clear all the fifo data. */
+static ssize_t bmi160_fifo_data_sel_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+ int err;
+ unsigned long data;
+ unsigned char fifo_datasel;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+ /* data format: aimed 0b0000 0x(m)x(g)x(a), x:1 enable, 0:disable*/
+ if (data > 7)
+ return -EINVAL;
+
+
+ fifo_datasel = (unsigned char)data;
+
+
+ err += BMI_CALL_API(set_fifo_accel_enable)
+ ((fifo_datasel & (1 << BMI_ACC_SENSOR)) ? 1 : 0);
+ err += BMI_CALL_API(set_fifo_gyro_enable)
+ (fifo_datasel & (1 << BMI_GYRO_SENSOR) ? 1 : 0);
+ err += BMI_CALL_API(set_fifo_mag_enable)
+ ((fifo_datasel & (1 << BMI_MAG_SENSOR)) ? 1 : 0);
+
+ err += BMI_CALL_API(set_command_register)(CMD_CLR_FIFO_DATA);
+ if (err)
+ return -EIO;
+ else {
+ dev_notice(client_data->dev, "FIFO A_en:%d, G_en:%d, M_en:%d\n",
+ (fifo_datasel & (1 << BMI_ACC_SENSOR)) ? 1 : 0,
+ (fifo_datasel & (1 << BMI_GYRO_SENSOR) ? 1 : 0),
+ ((fifo_datasel & (1 << BMI_MAG_SENSOR)) ? 1 : 0));
+ client_data->fifo_data_sel = fifo_datasel;
+ }
+ return count;
+}
+
+static ssize_t bmi160_fifo_data_out_frame_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+
+ int err = 0;
+ uint32_t fifo_bytecount = 0;
+
+ err = BMI_CALL_API(fifo_length)(&fifo_bytecount);
+ if (err < 0) {
+ dev_err(client_data->dev, "read fifo_length err");
+ return -EINVAL;
+ }
+ if (fifo_bytecount == 0)
+ return 0;
+ err = bmi_burst_read_wrapper(client_data->device.dev_addr,
+ BMI160_USER_FIFO_DATA__REG, buf,
+ fifo_bytecount);
+ if (err) {
+ dev_err(client_data->dev, "read fifo err");
+ BMI_CALL_API(set_command_register)(CMD_CLR_FIFO_DATA);
+ return -EINVAL;
+ }
+ return fifo_bytecount;
+
+}
+
+static ssize_t bmi160_fifo_watermark_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char data = 0xff;
+
+ err = BMI_CALL_API(get_fifo_wm)(&data);
+
+ if (err)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t bmi160_fifo_watermark_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long data;
+ unsigned char fifo_watermark;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ fifo_watermark = (unsigned char)data;
+ err = BMI_CALL_API(set_fifo_wm)(fifo_watermark);
+ if (err)
+ return -EIO;
+
+ return count;
+}
+
+
+static ssize_t bmi160_fifo_header_en_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char data = 0xff;
+
+ err = BMI_CALL_API(get_fifo_header_enable)(&data);
+
+ if (err)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t bmi160_fifo_header_en_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+ int err;
+ unsigned long data;
+ unsigned char fifo_header_en;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+ if (data > 1)
+ return -ENOENT;
+
+ fifo_header_en = (unsigned char)data;
+ err = BMI_CALL_API(set_fifo_header_enable)(fifo_header_en);
+ if (err)
+ return -EIO;
+
+ client_data->fifo_head_en = fifo_header_en;
+
+ return count;
+}
+
+static ssize_t bmi160_fifo_time_en_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char data = 0;
+
+ err = BMI_CALL_API(get_fifo_time_enable)(&data);
+
+ if (!err)
+ err = snprintf(buf, 16, "%d\n", data);
+
+ return err;
+}
+
+static ssize_t bmi160_fifo_time_en_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long data;
+ unsigned char fifo_ts_en;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ fifo_ts_en = (unsigned char)data;
+
+ err = BMI_CALL_API(set_fifo_time_enable)(fifo_ts_en);
+ if (err)
+ return -EIO;
+
+ return count;
+}
+
+static ssize_t bmi160_fifo_int_tag_en_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err = 0;
+ unsigned char fifo_tag_int1 = 0;
+ unsigned char fifo_tag_int2 = 0;
+ unsigned char fifo_tag_int;
+
+ err += BMI_CALL_API(get_fifo_tag_intr1_enable)(&fifo_tag_int1);
+ err += BMI_CALL_API(get_fifo_tag_intr2_enable)(&fifo_tag_int2);
+
+ fifo_tag_int = (fifo_tag_int1 << BMI160_INT0) |
+ (fifo_tag_int2 << BMI160_INT1);
+
+ if (!err)
+ err = snprintf(buf, 16, "%d\n", fifo_tag_int);
+
+ return err;
+}
+
+static ssize_t bmi160_fifo_int_tag_en_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+ int err;
+ unsigned long data;
+ unsigned char fifo_tag_int_en;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+ if (data > 3)
+ return -EINVAL;
+
+ fifo_tag_int_en = (unsigned char)data;
+
+ err += BMI_CALL_API(set_fifo_tag_intr1_enable)
+ ((fifo_tag_int_en & (1 << BMI160_INT0)) ? 1 : 0);
+ err += BMI_CALL_API(set_fifo_tag_intr2_enable)
+ ((fifo_tag_int_en & (1 << BMI160_INT1)) ? 1 : 0);
+
+ if (err) {
+ dev_err(client_data->dev, "fifo int tag en err:%d\n", err);
+ return -EIO;
+ }
+ client_data->fifo_int_tag_en = fifo_tag_int_en;
+
+ return count;
+}
+
+static int bmi160_set_acc_op_mode(struct bmi_client_data *client_data,
+ unsigned long op_mode)
+{
+ int err = 0;
+ unsigned char stc_enable;
+ unsigned char std_enable;
+ mutex_lock(&client_data->mutex_op_mode);
+
+ if (op_mode < BMI_ACC_PM_MAX) {
+ switch (op_mode) {
+ case BMI_ACC_PM_NORMAL:
+ err = BMI_CALL_API(set_command_register)
+ (bmi_pmu_cmd_acc_arr[BMI_ACC_PM_NORMAL]);
+ client_data->pw.acc_pm = BMI_ACC_PM_NORMAL;
+ bmi_delay(10);
+ break;
+ case BMI_ACC_PM_LP1:
+ err = BMI_CALL_API(set_command_register)
+ (bmi_pmu_cmd_acc_arr[BMI_ACC_PM_LP1]);
+ client_data->pw.acc_pm = BMI_ACC_PM_LP1;
+ bmi_delay(3);
+ break;
+ case BMI_ACC_PM_SUSPEND:
+ BMI_CALL_API(get_step_counter_enable)(&stc_enable);
+ BMI_CALL_API(get_step_detector_enable)(&std_enable);
+ if ((stc_enable == 0) && (std_enable == 0) &&
+ (client_data->sig_flag == 0)) {
+ err = BMI_CALL_API(set_command_register)
+ (bmi_pmu_cmd_acc_arr[BMI_ACC_PM_SUSPEND]);
+ client_data->pw.acc_pm = BMI_ACC_PM_SUSPEND;
+ bmi_delay(10);
+ }
+ break;
+ case BMI_ACC_PM_LP2:
+ err = BMI_CALL_API(set_command_register)
+ (bmi_pmu_cmd_acc_arr[BMI_ACC_PM_LP2]);
+ client_data->pw.acc_pm = BMI_ACC_PM_LP2;
+ bmi_delay(3);
+ break;
+ default:
+ mutex_unlock(&client_data->mutex_op_mode);
+ return -EINVAL;
+ }
+ } else {
+ mutex_unlock(&client_data->mutex_op_mode);
+ return -EINVAL;
+ }
+
+ mutex_unlock(&client_data->mutex_op_mode);
+
+ return err;
+
+
+}
+
+static ssize_t bmi160_temperature_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ s16 temp = 0xff;
+
+ err = BMI_CALL_API(get_temp)(&temp);
+
+ if (!err)
+ err = snprintf(buf, 16, "0x%x\n", temp);
+
+ return err;
+}
+
+static ssize_t bmi160_place_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+ int place = BOSCH_SENSOR_PLACE_UNKNOWN;
+
+ if (NULL != client_data->bst_pd)
+ place = client_data->bst_pd->place;
+
+ return snprintf(buf, 16, "%d\n", place);
+}
+
+static ssize_t bmi160_delay_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+
+ return snprintf(buf, 16, "%d\n", atomic_read(&client_data->delay));
+
+}
+
+static ssize_t bmi160_delay_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+ int err;
+ unsigned long data;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ if (data == 0) {
+ err = -EINVAL;
+ return err;
+ }
+
+ if (data < BMI_DELAY_MIN)
+ data = BMI_DELAY_MIN;
+
+ atomic_set(&client_data->delay, (unsigned int)data);
+
+ return count;
+}
+
+static ssize_t bmi160_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+
+ return snprintf(buf, 16, "%d\n", atomic_read(&client_data->wkqueue_en));
+
+}
+
+static ssize_t bmi160_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+ int err;
+ unsigned long enable;
+ int pre_enable = atomic_read(&client_data->wkqueue_en);
+
+ err = kstrtoul(buf, 10, &enable);
+ if (err)
+ return err;
+
+ enable = enable ? 1 : 0;
+ mutex_lock(&client_data->mutex_enable);
+ if (enable) {
+ if (pre_enable == 0) {
+ bmi160_set_acc_op_mode(client_data,
+ BMI_ACC_PM_NORMAL);
+ schedule_delayed_work(&client_data->work,
+ msecs_to_jiffies(atomic_read(&client_data->delay)));
+ atomic_set(&client_data->wkqueue_en, 1);
+ }
+
+ } else {
+ if (pre_enable == 1) {
+ bmi160_set_acc_op_mode(client_data,
+ BMI_ACC_PM_SUSPEND);
+
+ cancel_delayed_work_sync(&client_data->work);
+ atomic_set(&client_data->wkqueue_en, 0);
+ }
+ }
+
+ mutex_unlock(&client_data->mutex_enable);
+
+ return count;
+}
+
+#if defined(BMI160_ENABLE_INT1) || defined(BMI160_ENABLE_INT2)
+/* accel sensor part */
+static ssize_t bmi160_anymot_duration_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char data;
+
+ err = BMI_CALL_API(get_intr_any_motion_durn)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t bmi160_anymot_duration_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = BMI_CALL_API(set_intr_any_motion_durn)((unsigned char)data);
+ if (err < 0)
+ return -EIO;
+
+ return count;
+}
+
+static ssize_t bmi160_anymot_threshold_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+
+ err = BMI_CALL_API(get_intr_any_motion_thres)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t bmi160_anymot_threshold_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = BMI_CALL_API(set_intr_any_motion_thres)((unsigned char)data);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t bmi160_step_detector_status_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ u8 data = 0;
+ u8 step_det;
+ int err;
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+ err = BMI_CALL_API(get_step_detector_enable)(&step_det);
+ /*bmi160_get_status0_step_int*/
+ if (err < 0)
+ return err;
+/*client_data->std will be updated in bmi_stepdetector_interrupt_handle */
+ if ((step_det == 1) && (client_data->std == 1)) {
+ data = 1;
+ client_data->std = 0;
+ }
+ else {
+ data = 0;
+ }
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t bmi160_step_detector_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+
+ err = BMI_CALL_API(get_step_detector_enable)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t bmi160_step_detector_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = BMI_CALL_API(set_step_detector_enable)((unsigned char)data);
+ if (err < 0)
+ return -EIO;
+ if (data == 0)
+ client_data->pedo_data.wkar_step_detector_status = 0;
+ return count;
+}
+
+static ssize_t bmi160_signification_motion_enable_store(
+ struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+ /*0x62 (bit 1) INT_MOTION_3 int_sig_mot_sel*/
+ err = BMI_CALL_API(set_intr_significant_motion_select)(
+ (unsigned char)data);
+ if (err < 0)
+ return -EIO;
+ if (data == 1) {
+ err = BMI_CALL_API(set_intr_enable_0)
+ (BMI160_ANY_MOTION_X_ENABLE, 1);
+ err += BMI_CALL_API(set_intr_enable_0)
+ (BMI160_ANY_MOTION_Y_ENABLE, 1);
+ err += BMI_CALL_API(set_intr_enable_0)
+ (BMI160_ANY_MOTION_Z_ENABLE, 1);
+ if (err < 0)
+ return -EIO;
+ enable_irq_wake(client_data->IRQ);
+ client_data->sig_flag = 1;
+ } else {
+ err = BMI_CALL_API(set_intr_enable_0)
+ (BMI160_ANY_MOTION_X_ENABLE, 0);
+ err += BMI_CALL_API(set_intr_enable_0)
+ (BMI160_ANY_MOTION_Y_ENABLE, 0);
+ err += BMI_CALL_API(set_intr_enable_0)
+ (BMI160_ANY_MOTION_Z_ENABLE, 0);
+ if (err < 0)
+ return -EIO;
+ disable_irq_wake(client_data->IRQ);
+ client_data->sig_flag = 0;
+ }
+ return count;
+}
+
+static ssize_t bmi160_signification_motion_enable_show(
+ struct device *dev, struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+ /*0x62 (bit 1) INT_MOTION_3 int_sig_mot_sel*/
+ err = BMI_CALL_API(get_intr_significant_motion_select)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static int sigmotion_init_interrupts(u8 sig_map_int_pin)
+{
+ int ret = 0;
+/*0x60 */
+ ret += bmi160_set_intr_any_motion_thres(0x1e);
+/* 0x62(bit 3~2) 0=1.5s */
+ ret += bmi160_set_intr_significant_motion_skip(0);
+/*0x62(bit 5~4) 1=0.5s*/
+ ret += bmi160_set_intr_significant_motion_proof(1);
+/*0x50 (bit 0, 1, 2) INT_EN_0 anymo x y z*/
+ ret += bmi160_map_significant_motion_intr(sig_map_int_pin);
+/*0x62 (bit 1) INT_MOTION_3 int_sig_mot_sel
+close the signification_motion*/
+ ret += bmi160_set_intr_significant_motion_select(0);
+/*close the anymotion interrupt*/
+ ret += BMI_CALL_API(set_intr_enable_0)
+ (BMI160_ANY_MOTION_X_ENABLE, 0);
+ ret += BMI_CALL_API(set_intr_enable_0)
+ (BMI160_ANY_MOTION_Y_ENABLE, 0);
+ ret += BMI_CALL_API(set_intr_enable_0)
+ (BMI160_ANY_MOTION_Z_ENABLE, 0);
+ if (ret)
+ printk(KERN_ERR "bmi160 sig motion failed setting,%d!\n", ret);
+ return ret;
+
+}
+#endif
+
+static ssize_t bmi160_acc_range_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char range;
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+
+ err = BMI_CALL_API(get_accel_range)(&range);
+ if (err)
+ return err;
+
+ client_data->range.acc_range = range;
+ return snprintf(buf, 16, "%d\n", range);
+}
+
+static ssize_t bmi160_acc_range_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long range;
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+
+
+ err = kstrtoul(buf, 10, &range);
+ if (err)
+ return err;
+
+ err = BMI_CALL_API(set_accel_range)(range);
+ if (err)
+ return -EIO;
+
+ client_data->range.acc_range = range;
+ return count;
+}
+
+static ssize_t bmi160_acc_odr_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char acc_odr;
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+
+ err = BMI_CALL_API(get_accel_output_data_rate)(&acc_odr);
+ if (err)
+ return err;
+
+ client_data->odr.acc_odr = acc_odr;
+ return snprintf(buf, 16, "%d\n", acc_odr);
+}
+
+static ssize_t bmi160_acc_odr_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long acc_odr;
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &acc_odr);
+ if (err)
+ return err;
+
+ if (acc_odr < 1 || acc_odr > 12)
+ return -EIO;
+
+ if (acc_odr < 5)
+ err = BMI_CALL_API(set_accel_under_sampling_parameter)(1);
+ else
+ err = BMI_CALL_API(set_accel_under_sampling_parameter)(0);
+
+ if (err)
+ return err;
+
+ err = BMI_CALL_API(set_accel_output_data_rate)(acc_odr);
+ if (err)
+ return -EIO;
+ client_data->odr.acc_odr = acc_odr;
+ return count;
+}
+
+static ssize_t bmi160_acc_op_mode_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+ int err = 0;
+ u8 accel_pmu_status = 0;
+ err = BMI_CALL_API(get_accel_power_mode_stat)(
+ &accel_pmu_status);
+
+ if (err)
+ return err;
+ else
+ return snprintf(buf, 32, "reg:%d, val:%d\n", accel_pmu_status,
+ client_data->pw.acc_pm);
+}
+
+static ssize_t bmi160_acc_op_mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+ int err;
+ unsigned long op_mode;
+ err = kstrtoul(buf, 10, &op_mode);
+ if (err)
+ return err;
+
+ err = bmi160_set_acc_op_mode(client_data, op_mode);
+ if (err)
+ return err;
+ else
+ return count;
+
+}
+
+static ssize_t bmi160_acc_value_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct bmi160_accel_t data;
+
+ int err;
+
+ err = BMI_CALL_API(read_accel_xyz)(&data);
+ if (err < 0)
+ return err;
+
+ return snprintf(buf, 48, "%hd %hd %hd\n",
+ data.x, data.y, data.z);
+}
+
+static ssize_t bmi160_acc_fast_calibration_x_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+
+ err = BMI_CALL_API(get_foc_accel_x)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t bmi160_acc_fast_calibration_x_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+ s8 accel_offset_x = 0;
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+ /* 0: disable, 1: +1g, 2: -1g, 3: 0g */
+ if (data > 3)
+ return -EINVAL;
+
+ err = BMI_CALL_API(set_accel_foc_trigger)(X_AXIS,
+ data, &accel_offset_x);
+ if (err)
+ return -EIO;
+ else
+ client_data->calib_status |=
+ BMI_FAST_CALI_TRUE << BMI_ACC_X_FAST_CALI_RDY;
+ return count;
+}
+
+static ssize_t bmi160_acc_fast_calibration_y_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+
+ err = BMI_CALL_API(get_foc_accel_y)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t bmi160_acc_fast_calibration_y_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+ s8 accel_offset_y = 0;
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+ /* 0: disable, 1: +1g, 2: -1g, 3: 0g */
+ if (data > 3)
+ return -EINVAL;
+
+ err = BMI_CALL_API(set_accel_foc_trigger)(Y_AXIS,
+ data, &accel_offset_y);
+ if (err)
+ return -EIO;
+ else
+ client_data->calib_status |=
+ BMI_FAST_CALI_TRUE << BMI_ACC_Y_FAST_CALI_RDY;
+ return count;
+}
+
+static ssize_t bmi160_acc_fast_calibration_z_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+
+ err = BMI_CALL_API(get_foc_accel_z)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t bmi160_acc_fast_calibration_z_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+ s8 accel_offset_z = 0;
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+ unsigned char data1[3] = {0};
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+ /* 0: disable, 1: +1g, 2: -1g, 3: 0g */
+ if (data > 3)
+ return -EINVAL;
+
+ err = BMI_CALL_API(set_accel_foc_trigger)(Z_AXIS,
+ data, &accel_offset_z);
+ if (err)
+ return -EIO;
+ else
+ client_data->calib_status |=
+ BMI_FAST_CALI_TRUE << BMI_ACC_Z_FAST_CALI_RDY;
+
+ if (client_data->calib_status == BMI_FAST_CALI_ALL_RDY) {
+ err = BMI_CALL_API(get_accel_offset_compensation_xaxis)(
+ &data1[0]);
+ err += BMI_CALL_API(get_accel_offset_compensation_yaxis)(
+ &data1[1]);
+ err += BMI_CALL_API(get_accel_offset_compensation_zaxis)(
+ &data1[2]);
+ dev_info(client_data->dev, "accx %d, accy %d, accz %d\n",
+ data1[0], data1[1], data1[2]);
+ if (err)
+ return -EIO;
+ input_event(client_data->input, EV_MSC,
+ INPUT_EVENT_FAST_ACC_CALIB_DONE,
+ (data1[0] | (data1[1] << 8) | (data1[2] << 16)));
+ input_sync(client_data->input);
+ client_data->calib_status = 0;
+ }
+
+ return count;
+}
+
+static ssize_t bmi160_acc_offset_x_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+
+ err = BMI_CALL_API(get_accel_offset_compensation_xaxis)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+
+static ssize_t bmi160_acc_offset_x_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = BMI_CALL_API(set_accel_offset_compensation_xaxis)
+ ((unsigned char)data);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t bmi160_acc_offset_y_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+
+ err = BMI_CALL_API(get_accel_offset_compensation_yaxis)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t bmi160_acc_offset_y_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = BMI_CALL_API(set_accel_offset_compensation_yaxis)
+ ((unsigned char)data);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t bmi160_acc_offset_z_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+
+ err = BMI_CALL_API(get_accel_offset_compensation_zaxis)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t bmi160_acc_offset_z_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = BMI_CALL_API(set_accel_offset_compensation_zaxis)
+ ((unsigned char)data);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t bmi160_test_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+ u8 raw_data[15] = {0};
+ unsigned int sensor_time = 0;
+
+ int err;
+ memset(raw_data, 0, sizeof(raw_data));
+
+ err = client_data->device.bus_read(client_data->device.dev_addr,
+ BMI160_USER_DATA_8_GYRO_X_LSB__REG, raw_data, 15);
+ if (err)
+ return err;
+
+ udelay(10);
+ sensor_time = (u32)(raw_data[14] << 16 | raw_data[13] << 8
+ | raw_data[12]);
+
+ return snprintf(buf, 128, "%d %d %d %d %d %d %u",
+ (s16)(raw_data[1] << 8 | raw_data[0]),
+ (s16)(raw_data[3] << 8 | raw_data[2]),
+ (s16)(raw_data[5] << 8 | raw_data[4]),
+ (s16)(raw_data[7] << 8 | raw_data[6]),
+ (s16)(raw_data[9] << 8 | raw_data[8]),
+ (s16)(raw_data[11] << 8 | raw_data[10]),
+ sensor_time);
+
+}
+
+static ssize_t bmi160_step_counter_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+
+ err = BMI_CALL_API(get_step_counter_enable)(&data);
+
+ client_data->stc_enable = data;
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t bmi160_step_counter_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = BMI_CALL_API(set_step_counter_enable)((unsigned char)data);
+
+ client_data->stc_enable = data;
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+
+static ssize_t bmi160_step_counter_mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = BMI_CALL_API(set_step_mode)((unsigned char)data);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t bmi160_step_counter_clc_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = bmi160_clear_step_counter();
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t bmi160_step_counter_value_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ u16 data;
+ int err;
+ static u16 last_stc_value;
+
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+
+ err = BMI_CALL_API(read_step_count)(&data);
+
+ if (err < 0)
+ return err;
+ if (data >= last_stc_value) {
+ client_data->pedo_data.last_step_counter_value += (
+ data - last_stc_value);
+ last_stc_value = data;
+ } else
+ last_stc_value = data;
+ return snprintf(buf, 16, "%d\n",
+ client_data->pedo_data.last_step_counter_value);
+}
+
+static ssize_t bmi160_bmi_value_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+ u8 raw_data[12] = {0};
+
+ int err;
+ memset(raw_data, 0, sizeof(raw_data));
+
+ err = client_data->device.bus_read(client_data->device.dev_addr,
+ BMI160_USER_DATA_8_GYRO_X_LSB__REG, raw_data, 12);
+ if (err)
+ return err;
+ /*output:gyro x y z acc x y z*/
+ return snprintf(buf, 96, "%hd %d %hd %hd %hd %hd\n",
+ (s16)(raw_data[1] << 8 | raw_data[0]),
+ (s16)(raw_data[3] << 8 | raw_data[2]),
+ (s16)(raw_data[5] << 8 | raw_data[4]),
+ (s16)(raw_data[7] << 8 | raw_data[6]),
+ (s16)(raw_data[9] << 8 | raw_data[8]),
+ (s16)(raw_data[11] << 8 | raw_data[10]));
+
+}
+
+
+static ssize_t bmi160_selftest_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+
+ return snprintf(buf, 16, "0x%x\n",
+ atomic_read(&client_data->selftest_result));
+}
+
+static int bmi_restore_hw_cfg(struct bmi_client_data *client);
+
+/*!
+ * @brief store selftest result which make up of acc and gyro
+ * format: 0b 0000 xxxx x:1 failed, 0 success
+ * bit3: gyro_self
+ * bit2..0: acc_self z y x
+ */
+static ssize_t bmi160_selftest_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+ int err = 0;
+ int i = 0;
+
+ u8 acc_selftest = 0;
+ u8 gyro_selftest = 0;
+ u8 bmi_selftest = 0;
+ s16 axis_p_value, axis_n_value;
+ u16 diff_axis[3] = {0xff, 0xff, 0xff};
+ u8 acc_odr, range, acc_selftest_amp, acc_selftest_sign;
+
+ dev_notice(client_data->dev, "Selftest for BMI16x starting.\n");
+
+ client_data->selftest = 1;
+
+ /*soft reset*/
+ err = BMI_CALL_API(set_command_register)(CMD_RESET_USER_REG);
+ msleep(70);
+ err += BMI_CALL_API(set_command_register)
+ (bmi_pmu_cmd_acc_arr[BMI_ACC_PM_NORMAL]);
+ err += BMI_CALL_API(set_command_register)
+ (bmi_pmu_cmd_gyro_arr[BMI_GYRO_PM_NORMAL]);
+ err += BMI_CALL_API(set_accel_under_sampling_parameter)(0);
+ err += BMI_CALL_API(set_accel_output_data_rate)(
+ BMI160_ACCEL_OUTPUT_DATA_RATE_1600HZ);
+
+ /* set to 8G range*/
+ err += BMI_CALL_API(set_accel_range)(BMI160_ACCEL_RANGE_8G);
+ /* set to self amp high */
+ err += BMI_CALL_API(set_accel_selftest_amp)(BMI_SELFTEST_AMP_HIGH);
+
+
+ err += BMI_CALL_API(get_accel_output_data_rate)(&acc_odr);
+ err += BMI_CALL_API(get_accel_range)(&range);
+ err += BMI_CALL_API(get_accel_selftest_amp)(&acc_selftest_amp);
+ err += BMI_CALL_API(read_accel_x)(&axis_n_value);
+
+ dev_info(client_data->dev,
+ "acc_odr:%d, acc_range:%d, acc_selftest_amp:%d, acc_x:%d\n",
+ acc_odr, range, acc_selftest_amp, axis_n_value);
+
+ for (i = X_AXIS; i < AXIS_MAX; i++) {
+ axis_n_value = 0;
+ axis_p_value = 0;
+ /* set every selftest axis */
+ /*set_acc_selftest_axis(param),param x:1, y:2, z:3
+ * but X_AXIS:0, Y_AXIS:1, Z_AXIS:2
+ * so we need to +1*/
+ err += BMI_CALL_API(set_accel_selftest_axis)(i + 1);
+ msleep(50);
+ switch (i) {
+ case X_AXIS:
+ /* set negative sign */
+ err += BMI_CALL_API(set_accel_selftest_sign)(0);
+ err += BMI_CALL_API(get_accel_selftest_sign)(
+ &acc_selftest_sign);
+
+ msleep(60);
+ err += BMI_CALL_API(read_accel_x)(&axis_n_value);
+ dev_info(client_data->dev,
+ "acc_x_selftest_sign:%d, axis_n_value:%d\n",
+ acc_selftest_sign, axis_n_value);
+
+ /* set postive sign */
+ err += BMI_CALL_API(set_accel_selftest_sign)(1);
+ err += BMI_CALL_API(get_accel_selftest_sign)(
+ &acc_selftest_sign);
+
+ msleep(60);
+ err += BMI_CALL_API(read_accel_x)(&axis_p_value);
+ dev_info(client_data->dev,
+ "acc_x_selftest_sign:%d, axis_p_value:%d\n",
+ acc_selftest_sign, axis_p_value);
+ diff_axis[i] = abs(axis_p_value - axis_n_value);
+ break;
+
+ case Y_AXIS:
+ /* set negative sign */
+ err += BMI_CALL_API(set_accel_selftest_sign)(0);
+ msleep(60);
+ err += BMI_CALL_API(read_accel_y)(&axis_n_value);
+ /* set postive sign */
+ err += BMI_CALL_API(set_accel_selftest_sign)(1);
+ msleep(60);
+ err += BMI_CALL_API(read_accel_y)(&axis_p_value);
+ diff_axis[i] = abs(axis_p_value - axis_n_value);
+ break;
+
+ case Z_AXIS:
+ /* set negative sign */
+ err += BMI_CALL_API(set_accel_selftest_sign)(0);
+ msleep(60);
+ err += BMI_CALL_API(read_accel_z)(&axis_n_value);
+ /* set postive sign */
+ err += BMI_CALL_API(set_accel_selftest_sign)(1);
+ msleep(60);
+ err += BMI_CALL_API(read_accel_z)(&axis_p_value);
+ /* also start gyro self test */
+ err += BMI_CALL_API(set_gyro_selftest_start)(1);
+ msleep(60);
+ err += BMI_CALL_API(get_gyro_selftest)(&gyro_selftest);
+
+ diff_axis[i] = abs(axis_p_value - axis_n_value);
+ break;
+ default:
+ err += -EINVAL;
+ break;
+ }
+ if (err) {
+ dev_err(client_data->dev,
+ "Failed selftest axis:%s, p_val=%d, n_val=%d\n",
+ bmi_axis_name[i], axis_p_value, axis_n_value);
+ client_data->selftest = 0;
+ return -EINVAL;
+ }
+
+ /*400mg for acc z axis*/
+ if (Z_AXIS == i) {
+ if (diff_axis[i] < 1639) {
+ acc_selftest |= 1 << i;
+ dev_err(client_data->dev,
+ "Over selftest minimum for "
+ "axis:%s,diff=%d,p_val=%d, n_val=%d\n",
+ bmi_axis_name[i], diff_axis[i],
+ axis_p_value, axis_n_value);
+ }
+ } else {
+ /*800mg for x or y axis*/
+ if (diff_axis[i] < 3277) {
+ acc_selftest |= 1 << i;
+
+ if (bmi_get_err_status(client_data) < 0)
+ return err;
+ dev_err(client_data->dev,
+ "Over selftest minimum for "
+ "axis:%s,diff=%d, p_val=%d, n_val=%d\n",
+ bmi_axis_name[i], diff_axis[i],
+ axis_p_value, axis_n_value);
+ dev_err(client_data->dev, "err_st:0x%x\n",
+ client_data->err_st.err_st_all);
+
+ }
+ }
+
+ }
+ /* gyro_selftest==1,gyro selftest successfully,
+ * but bmi_result bit4 0 is successful, 1 is failed*/
+ bmi_selftest = (acc_selftest & 0x0f) | ((!gyro_selftest) << AXIS_MAX);
+ atomic_set(&client_data->selftest_result, bmi_selftest);
+ /*soft reset*/
+ err = BMI_CALL_API(set_command_register)(CMD_RESET_USER_REG);
+ if (err) {
+ client_data->selftest = 0;
+ return err;
+ }
+ msleep(50);
+
+ bmi_restore_hw_cfg(client_data);
+
+ client_data->selftest = 0;
+ dev_notice(client_data->dev, "Selftest for BMI16x finished\n");
+
+ return count;
+}
+
+/* gyro sensor part */
+static ssize_t bmi160_gyro_op_mode_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+ int err = 0;
+ u8 gyro_pmu_status = 0;
+
+ err = BMI_CALL_API(get_gyro_power_mode_stat)(
+ &gyro_pmu_status);
+
+ if (err)
+ return err;
+ else
+ return snprintf(buf, 32, "reg:%d, val:%d\n", gyro_pmu_status,
+ client_data->pw.gyro_pm);
+}
+
+static ssize_t bmi160_gyro_op_mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+ unsigned long op_mode;
+ int err;
+
+ err = kstrtoul(buf, 10, &op_mode);
+ if (err)
+ return err;
+
+ mutex_lock(&client_data->mutex_op_mode);
+
+ if (op_mode < BMI_GYRO_PM_MAX) {
+ switch (op_mode) {
+ case BMI_GYRO_PM_NORMAL:
+ err = BMI_CALL_API(set_command_register)
+ (bmi_pmu_cmd_gyro_arr[BMI_GYRO_PM_NORMAL]);
+ client_data->pw.gyro_pm = BMI_GYRO_PM_NORMAL;
+ bmi_delay(60);
+ break;
+ case BMI_GYRO_PM_FAST_START:
+ err = BMI_CALL_API(set_command_register)
+ (bmi_pmu_cmd_gyro_arr[BMI_GYRO_PM_FAST_START]);
+ client_data->pw.gyro_pm = BMI_GYRO_PM_FAST_START;
+ bmi_delay(60);
+ break;
+ case BMI_GYRO_PM_SUSPEND:
+ err = BMI_CALL_API(set_command_register)
+ (bmi_pmu_cmd_gyro_arr[BMI_GYRO_PM_SUSPEND]);
+ client_data->pw.gyro_pm = BMI_GYRO_PM_SUSPEND;
+ bmi_delay(60);
+ break;
+ default:
+ mutex_unlock(&client_data->mutex_op_mode);
+ return -EINVAL;
+ }
+ } else {
+ mutex_unlock(&client_data->mutex_op_mode);
+ return -EINVAL;
+ }
+
+ mutex_unlock(&client_data->mutex_op_mode);
+
+ if (err)
+ return err;
+ else
+ return count;
+
+}
+
+static ssize_t bmi160_gyro_value_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct bmi160_gyro_t data;
+ int err;
+
+ err = BMI_CALL_API(read_gyro_xyz)(&data);
+ if (err < 0)
+ return err;
+
+
+ return snprintf(buf, 48, "%hd %hd %hd\n", data.x,
+ data.y, data.z);
+}
+
+static ssize_t bmi160_gyro_range_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char range;
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+
+ err = BMI_CALL_API(get_gyro_range)(&range);
+ if (err)
+ return err;
+
+ client_data->range.gyro_range = range;
+ return snprintf(buf, 16, "%d\n", range);
+}
+
+static ssize_t bmi160_gyro_range_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long range;
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &range);
+ if (err)
+ return err;
+
+ err = BMI_CALL_API(set_gyro_range)(range);
+ if (err)
+ return -EIO;
+
+ client_data->range.gyro_range = range;
+ return count;
+}
+
+static ssize_t bmi160_gyro_odr_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char gyro_odr;
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+
+ err = BMI_CALL_API(get_gyro_output_data_rate)(&gyro_odr);
+ if (err)
+ return err;
+
+ client_data->odr.gyro_odr = gyro_odr;
+ return snprintf(buf, 16, "%d\n", gyro_odr);
+}
+
+static ssize_t bmi160_gyro_odr_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long gyro_odr;
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &gyro_odr);
+ if (err)
+ return err;
+
+ if (gyro_odr < 6 || gyro_odr > 13)
+ return -EIO;
+
+ err = BMI_CALL_API(set_gyro_output_data_rate)(gyro_odr);
+ if (err)
+ return -EIO;
+
+ client_data->odr.gyro_odr = gyro_odr;
+ return count;
+}
+
+static ssize_t bmi160_gyro_fast_calibration_en_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+
+ err = BMI_CALL_API(get_foc_gyro_enable)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t bmi160_gyro_fast_calibration_en_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long enable;
+ s8 err;
+ s16 gyr_off_x;
+ s16 gyr_off_y;
+ s16 gyr_off_z;
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &enable);
+ if (err)
+ return err;
+
+ err = BMI_CALL_API(set_foc_gyro_enable)((u8)enable,
+ &gyr_off_x, &gyr_off_y, &gyr_off_z);
+
+ if (err < 0)
+ return -EIO;
+ else {
+ input_event(client_data->input, EV_MSC,
+ INPUT_EVENT_FAST_GYRO_CALIB_DONE, 1);
+ input_sync(client_data->input);
+ }
+ return count;
+}
+
+static ssize_t bmi160_gyro_offset_x_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ s16 data = 0;
+ s8 err = 0;
+
+ err = BMI_CALL_API(get_gyro_offset_compensation_xaxis)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t bmi160_gyro_offset_x_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ s8 err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = BMI_CALL_API(set_gyro_offset_compensation_xaxis)((s16)data);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t bmi160_gyro_offset_y_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ s16 data = 0;
+ s8 err = 0;
+
+ err = BMI_CALL_API(get_gyro_offset_compensation_yaxis)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t bmi160_gyro_offset_y_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ s8 err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = BMI_CALL_API(set_gyro_offset_compensation_yaxis)((s16)data);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t bmi160_gyro_offset_z_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ s16 data = 0;
+ int err = 0;
+
+ err = BMI_CALL_API(get_gyro_offset_compensation_zaxis)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t bmi160_gyro_offset_z_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = BMI_CALL_API(set_gyro_offset_compensation_zaxis)((s16)data);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+
+/* mag sensor part */
+#ifdef BMI160_MAG_INTERFACE_SUPPORT
+static ssize_t bmi160_mag_op_mode_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+ u8 mag_op_mode;
+ s8 err;
+ err = bmi160_get_mag_power_mode_stat(&mag_op_mode);
+ if (err) {
+ dev_err(client_data->dev,
+ "Failed to get BMI160 mag power mode:%d\n", err);
+ return err;
+ } else
+ return snprintf(buf, 32, "%d, reg:%d\n",
+ client_data->pw.mag_pm, mag_op_mode);
+}
+
+static ssize_t bmi160_mag_op_mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+ unsigned long op_mode;
+ int err;
+
+ err = kstrtoul(buf, 10, &op_mode);
+ if (err)
+ return err;
+
+ if (op_mode == client_data->pw.mag_pm)
+ return count;
+
+ mutex_lock(&client_data->mutex_op_mode);
+
+
+ if (op_mode < BMI_MAG_PM_MAX) {
+ switch (op_mode) {
+ case BMI_MAG_PM_NORMAL:
+ /* need to modify as mag sensor connected,
+ * set write address to 0x4c and triggers
+ * write operation
+ * 0x4c(op mode control reg)
+ * enables normal mode in magnetometer */
+#if defined(BMI160_AKM09912_SUPPORT)
+ err = bmi160_set_bst_akm_and_secondary_if_powermode(
+ BMI160_MAG_FORCE_MODE);
+#else
+ err = bmi160_set_bmm150_mag_and_secondary_if_power_mode(
+ BMI160_MAG_FORCE_MODE);
+#endif
+ client_data->pw.mag_pm = BMI_MAG_PM_NORMAL;
+ bmi_delay(5);
+ break;
+ case BMI_MAG_PM_LP1:
+ /* need to modify as mag sensor connected,
+ * set write address to 0x4 band triggers
+ * write operation
+ * 0x4b(bmm150, power control reg, bit0)
+ * enables power in magnetometer*/
+#if defined(BMI160_AKM09912_SUPPORT)
+ err = bmi160_set_bst_akm_and_secondary_if_powermode(
+ BMI160_MAG_FORCE_MODE);
+#else
+ err = bmi160_set_bmm150_mag_and_secondary_if_power_mode(
+ BMI160_MAG_FORCE_MODE);
+#endif
+ client_data->pw.mag_pm = BMI_MAG_PM_LP1;
+ bmi_delay(5);
+ break;
+ case BMI_MAG_PM_SUSPEND:
+ case BMI_MAG_PM_LP2:
+#if defined(BMI160_AKM09912_SUPPORT)
+ err = bmi160_set_bst_akm_and_secondary_if_powermode(
+ BMI160_MAG_SUSPEND_MODE);
+#else
+ err = bmi160_set_bmm150_mag_and_secondary_if_power_mode(
+ BMI160_MAG_SUSPEND_MODE);
+#endif
+ client_data->pw.mag_pm = op_mode;
+ bmi_delay(5);
+ break;
+ default:
+ mutex_unlock(&client_data->mutex_op_mode);
+ return -EINVAL;
+ }
+ } else {
+ mutex_unlock(&client_data->mutex_op_mode);
+ return -EINVAL;
+ }
+
+ mutex_unlock(&client_data->mutex_op_mode);
+
+ if (err) {
+ dev_err(client_data->dev,
+ "Failed to switch BMI160 mag power mode:%d\n",
+ client_data->pw.mag_pm);
+ return err;
+ } else
+ return count;
+
+}
+
+static ssize_t bmi160_mag_odr_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err = 0;
+ unsigned char mag_odr = 0;
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+
+ err = BMI_CALL_API(get_mag_output_data_rate)(&mag_odr);
+ if (err)
+ return err;
+
+ client_data->odr.mag_odr = mag_odr;
+ return snprintf(buf, 16, "%d\n", mag_odr);
+}
+
+static ssize_t bmi160_mag_odr_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long mag_odr;
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &mag_odr);
+ if (err)
+ return err;
+ /*1~25/32hz,..6(25hz),7(50hz),... */
+ err = BMI_CALL_API(set_mag_output_data_rate)(mag_odr);
+ if (err)
+ return -EIO;
+
+ client_data->odr.mag_odr = mag_odr;
+ return count;
+}
+
+static ssize_t bmi160_mag_i2c_address_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ u8 data;
+ s8 err;
+
+ err = BMI_CALL_API(set_mag_manual_enable)(1);
+ err += BMI_CALL_API(get_i2c_device_addr)(&data);
+ err += BMI_CALL_API(set_mag_manual_enable)(0);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "0x%x\n", data);
+}
+
+static ssize_t bmi160_mag_i2c_address_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err += BMI_CALL_API(set_mag_manual_enable)(1);
+ if (!err)
+ err += BMI_CALL_API(set_i2c_device_addr)((unsigned char)data);
+ err += BMI_CALL_API(set_mag_manual_enable)(0);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t bmi160_mag_value_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+ struct bmi160_mag_xyz_s32_t data;
+ int err;
+ /* raw data with compensation */
+#if defined(BMI160_AKM09912_SUPPORT)
+ err = bmi160_bst_akm09912_compensate_xyz(&data);
+#else
+ err = bmi160_bmm150_mag_compensate_xyz(&data);
+#endif
+
+ if (err < 0) {
+ memset(&data, 0, sizeof(data));
+ dev_err(client_data->dev, "mag not ready!\n");
+ }
+ return snprintf(buf, 48, "%hd %hd %hd\n", data.x,
+ data.y, data.z);
+}
+static ssize_t bmi160_mag_offset_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err = 0;
+ unsigned char mag_offset;
+ err = BMI_CALL_API(get_mag_offset)(&mag_offset);
+ if (err)
+ return err;
+
+ return snprintf(buf, 16, "%d\n", mag_offset);
+
+}
+
+static ssize_t bmi160_mag_offset_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err += BMI_CALL_API(set_mag_manual_enable)(1);
+ if (err == 0)
+ err += BMI_CALL_API(set_mag_offset)((unsigned char)data);
+ err += BMI_CALL_API(set_mag_manual_enable)(0);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t bmi160_mag_chip_id_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ s8 err = 0;
+ u8 mag_chipid;
+
+ err = bmi160_set_mag_manual_enable(0x01);
+ /* read mag chip_id value */
+#if defined(BMI160_AKM09912_SUPPORT)
+ err += bmi160_set_mag_read_addr(AKM09912_CHIP_ID_REG);
+ /* 0x04 is mag_x lsb register */
+ err += bmi160_read_reg(BMI160_USER_DATA_0_MAG_X_LSB__REG,
+ &mag_chipid, 1);
+
+ /* Must add this commands to re-set data register addr of mag sensor */
+ err += bmi160_set_mag_read_addr(AKM_DATA_REGISTER);
+#else
+ err += bmi160_set_mag_read_addr(BMI160_BMM150_CHIP_ID);
+ /* 0x04 is mag_x lsb register */
+ err += bmi160_read_reg(BMI160_USER_DATA_0_MAG_X_LSB__REG,
+ &mag_chipid, 1);
+
+ /* Must add this commands to re-set data register addr of mag sensor */
+ /* 0x42 is bmm150 data register address */
+ err += bmi160_set_mag_read_addr(BMI160_BMM150_DATA_REG);
+#endif
+
+ err += bmi160_set_mag_manual_enable(0x00);
+
+ if (err)
+ return err;
+
+ return snprintf(buf, 16, "%x\n", mag_chipid);
+
+}
+
+static ssize_t bmi160_mag_chip_name_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ u8 mag_chipid = 0;
+#if defined(BMI160_AKM09912_SUPPORT)
+ mag_chipid = 15;
+#else
+ mag_chipid = 150;
+#endif
+ return snprintf(buf, 16, "%d\n", mag_chipid);
+}
+
+struct bmi160_mag_xyz_s32_t mag_compensate;
+static ssize_t bmi160_mag_compensate_xyz_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ memcpy(buf, &mag_compensate, sizeof(mag_compensate));
+ return sizeof(mag_compensate);
+}
+static ssize_t bmi160_mag_compensate_xyz_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct bmi160_mag_xyzr_t mag_raw;
+ memset(&mag_compensate, 0, sizeof(mag_compensate));
+ memset(&mag_raw, 0, sizeof(mag_raw));
+ mag_raw.x = (buf[1] << 8 | buf[0]);
+ mag_raw.y = (buf[3] << 8 | buf[2]);
+ mag_raw.z = (buf[5] << 8 | buf[4]);
+ mag_raw.r = (buf[7] << 8 | buf[6]);
+ mag_raw.x = mag_raw.x >> 3;
+ mag_raw.y = mag_raw.y >> 3;
+ mag_raw.z = mag_raw.z >> 1;
+ mag_raw.r = mag_raw.r >> 2;
+ bmi160_bmm150_mag_compensate_xyz_raw(
+ &mag_compensate, mag_raw);
+ return count;
+}
+
+#endif
+
+#if defined(BMI160_ENABLE_INT1) || defined(BMI160_ENABLE_INT2)
+static ssize_t bmi_enable_int_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int interrupt_type, value;
+
+ sscanf(buf, "%3d %3d", &interrupt_type, &value);
+
+ if (interrupt_type < 0 || interrupt_type > 16)
+ return -EINVAL;
+
+ if (interrupt_type <= BMI_FLAT_INT) {
+ if (BMI_CALL_API(set_intr_enable_0)
+ (bmi_interrupt_type[interrupt_type], value) < 0)
+ return -EINVAL;
+ } else if (interrupt_type <= BMI_FWM_INT) {
+ if (BMI_CALL_API(set_intr_enable_1)
+ (bmi_interrupt_type[interrupt_type], value) < 0)
+ return -EINVAL;
+ } else {
+ if (BMI_CALL_API(set_intr_enable_2)
+ (bmi_interrupt_type[interrupt_type], value) < 0)
+ return -EINVAL;
+ }
+
+ return count;
+}
+
+#endif
+
+static ssize_t bmi160_show_reg_sel(struct device *dev
+ , struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+
+ if (client_data == NULL) {
+ printk(KERN_ERR "Invalid client_data pointer");
+ return -ENODEV;
+ }
+
+ return snprintf(buf, 64, "reg=0X%02X, len=%d\n",
+ client_data->reg_sel, client_data->reg_len);
+}
+
+static ssize_t bmi160_store_reg_sel(struct device *dev
+ , struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+ ssize_t ret;
+
+ if (client_data == NULL) {
+ printk(KERN_ERR "Invalid client_data pointer");
+ return -ENODEV;
+ }
+ ret = sscanf(buf, "%11X %11d",
+ &client_data->reg_sel, &client_data->reg_len);
+ if (ret != 2) {
+ dev_err(client_data->dev, "Invalid argument");
+ return -EINVAL;
+ }
+
+ return count;
+}
+
+static ssize_t bmi160_show_reg_val(struct device *dev
+ , struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+
+ ssize_t ret;
+ u8 reg_data[128], i;
+ int pos;
+
+ if (client_data == NULL) {
+ printk(KERN_ERR "Invalid client_data pointer");
+ return -ENODEV;
+ }
+
+ ret = bmi_burst_read_wrapper(client_data->device.dev_addr,
+ client_data->reg_sel,
+ reg_data, client_data->reg_len);
+ if (ret < 0) {
+ dev_err(client_data->dev, "Reg op failed");
+ return ret;
+ }
+
+ pos = 0;
+ for (i = 0; i < client_data->reg_len; ++i) {
+ pos += snprintf(buf + pos, 16, "%02X", reg_data[i]);
+ buf[pos++] = (i + 1) % 16 == 0 ? '\n' : ' ';
+ }
+ if (buf[pos - 1] == ' ')
+ buf[pos - 1] = '\n';
+
+ return pos;
+}
+
+static ssize_t bmi160_store_reg_val(struct device *dev
+ , struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+ ssize_t ret;
+ u8 reg_data[32];
+ int i, j, status, digit;
+
+ if (client_data == NULL) {
+ printk(KERN_ERR "Invalid client_data pointer");
+ return -ENODEV;
+ }
+ status = 0;
+ for (i = j = 0; i < count && j < client_data->reg_len; ++i) {
+ if (buf[i] == ' ' || buf[i] == '\n' || buf[i] == '\t' ||
+ buf[i] == '\r') {
+ status = 0;
+ ++j;
+ continue;
+ }
+ digit = buf[i] & 0x10 ? (buf[i] & 0xF) : ((buf[i] & 0xF) + 9);
+ printk(KERN_INFO "digit is %d", digit);
+ switch (status) {
+ case 2:
+ ++j; /* Fall thru */
+ case 0:
+ reg_data[j] = digit;
+ status = 1;
+ break;
+ case 1:
+ reg_data[j] = reg_data[j] * 16 + digit;
+ status = 2;
+ break;
+ }
+ }
+ if (status > 0)
+ ++j;
+ if (j > client_data->reg_len)
+ j = client_data->reg_len;
+ else if (j < client_data->reg_len) {
+ dev_err(client_data->dev, "Invalid argument");
+ return -EINVAL;
+ }
+ printk(KERN_INFO "Reg data read as");
+ for (i = 0; i < j; ++i)
+ printk(KERN_INFO "%d", reg_data[i]);
+
+ ret = BMI_CALL_API(write_reg)(
+ client_data->reg_sel,
+ reg_data, client_data->reg_len);
+ if (ret < 0) {
+ dev_err(client_data->dev, "Reg op failed");
+ return ret;
+ }
+
+ return count;
+}
+
+static ssize_t bmi160_driver_version_show(struct device *dev
+ , struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bmi_client_data *client_data = input_get_drvdata(input);
+ int ret;
+
+ if (client_data == NULL) {
+ printk(KERN_ERR "Invalid client_data pointer");
+ return -ENODEV;
+ }
+
+ ret = snprintf(buf, 128, "Driver version: %s\n",
+ DRIVER_VERSION);
+
+ return ret;
+}
+static DEVICE_ATTR(chip_id, S_IRUGO,
+ bmi160_chip_id_show, NULL);
+static DEVICE_ATTR(err_st, S_IRUGO,
+ bmi160_err_st_show, NULL);
+static DEVICE_ATTR(sensor_time, S_IRUGO,
+ bmi160_sensor_time_show, NULL);
+
+static DEVICE_ATTR(selftest, S_IRUGO | S_IWUSR,
+ bmi160_selftest_show, bmi160_selftest_store);
+static DEVICE_ATTR(fifo_flush, S_IRUGO | S_IWUSR,
+ NULL, bmi160_fifo_flush_store);
+static DEVICE_ATTR(fifo_bytecount, S_IRUGO | S_IWUSR,
+ bmi160_fifo_bytecount_show, bmi160_fifo_bytecount_store);
+static DEVICE_ATTR(fifo_data_sel, S_IRUGO | S_IWUSR,
+ bmi160_fifo_data_sel_show, bmi160_fifo_data_sel_store);
+static DEVICE_ATTR(fifo_data_frame, S_IRUGO,
+ bmi160_fifo_data_out_frame_show, NULL);
+
+static DEVICE_ATTR(fifo_watermark, S_IRUGO | S_IWUSR,
+ bmi160_fifo_watermark_show, bmi160_fifo_watermark_store);
+
+static DEVICE_ATTR(fifo_header_en, S_IRUGO | S_IWUSR,
+ bmi160_fifo_header_en_show, bmi160_fifo_header_en_store);
+static DEVICE_ATTR(fifo_time_en, S_IRUGO | S_IWUSR,
+ bmi160_fifo_time_en_show, bmi160_fifo_time_en_store);
+static DEVICE_ATTR(fifo_int_tag_en, S_IRUGO | S_IWUSR,
+ bmi160_fifo_int_tag_en_show, bmi160_fifo_int_tag_en_store);
+
+static DEVICE_ATTR(temperature, S_IRUGO,
+ bmi160_temperature_show, NULL);
+static DEVICE_ATTR(place, S_IRUGO,
+ bmi160_place_show, NULL);
+static DEVICE_ATTR(delay, S_IRUGO | S_IWUSR,
+ bmi160_delay_show, bmi160_delay_store);
+static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR,
+ bmi160_enable_show, bmi160_enable_store);
+static DEVICE_ATTR(acc_range, S_IRUGO | S_IWUSR,
+ bmi160_acc_range_show, bmi160_acc_range_store);
+static DEVICE_ATTR(acc_odr, S_IRUGO | S_IWUSR,
+ bmi160_acc_odr_show, bmi160_acc_odr_store);
+static DEVICE_ATTR(acc_op_mode, S_IRUGO | S_IWUSR,
+ bmi160_acc_op_mode_show, bmi160_acc_op_mode_store);
+static DEVICE_ATTR(acc_value, S_IRUGO,
+ bmi160_acc_value_show, NULL);
+static DEVICE_ATTR(acc_fast_calibration_x, S_IRUGO | S_IWUSR,
+ bmi160_acc_fast_calibration_x_show,
+ bmi160_acc_fast_calibration_x_store);
+static DEVICE_ATTR(acc_fast_calibration_y, S_IRUGO | S_IWUSR,
+ bmi160_acc_fast_calibration_y_show,
+ bmi160_acc_fast_calibration_y_store);
+static DEVICE_ATTR(acc_fast_calibration_z, S_IRUGO | S_IWUSR,
+ bmi160_acc_fast_calibration_z_show,
+ bmi160_acc_fast_calibration_z_store);
+static DEVICE_ATTR(acc_offset_x, S_IRUGO | S_IWUSR,
+ bmi160_acc_offset_x_show,
+ bmi160_acc_offset_x_store);
+static DEVICE_ATTR(acc_offset_y, S_IRUGO | S_IWUSR,
+ bmi160_acc_offset_y_show,
+ bmi160_acc_offset_y_store);
+static DEVICE_ATTR(acc_offset_z, S_IRUGO | S_IWUSR,
+ bmi160_acc_offset_z_show,
+ bmi160_acc_offset_z_store);
+static DEVICE_ATTR(test, S_IRUGO,
+ bmi160_test_show, NULL);
+static DEVICE_ATTR(stc_enable, S_IRUGO | S_IWUSR,
+ bmi160_step_counter_enable_show,
+ bmi160_step_counter_enable_store);
+static DEVICE_ATTR(stc_mode, S_IRUGO | S_IWUSR,
+ NULL, bmi160_step_counter_mode_store);
+static DEVICE_ATTR(stc_clc, S_IRUGO | S_IWUSR,
+ NULL, bmi160_step_counter_clc_store);
+static DEVICE_ATTR(stc_value, S_IRUGO,
+ bmi160_step_counter_value_show, NULL);
+static DEVICE_ATTR(reg_sel, S_IRUGO | S_IWUSR,
+ bmi160_show_reg_sel, bmi160_store_reg_sel);
+static DEVICE_ATTR(reg_val, S_IRUGO | S_IWUSR,
+ bmi160_show_reg_val, bmi160_store_reg_val);
+static DEVICE_ATTR(driver_version, S_IRUGO,
+ bmi160_driver_version_show, NULL);
+/* gyro part */
+static DEVICE_ATTR(gyro_op_mode, S_IRUGO | S_IWUSR,
+ bmi160_gyro_op_mode_show, bmi160_gyro_op_mode_store);
+static DEVICE_ATTR(gyro_value, S_IRUGO,
+ bmi160_gyro_value_show, NULL);
+static DEVICE_ATTR(gyro_range, S_IRUGO | S_IWUSR,
+ bmi160_gyro_range_show, bmi160_gyro_range_store);
+static DEVICE_ATTR(gyro_odr, S_IRUGO | S_IWUSR,
+ bmi160_gyro_odr_show, bmi160_gyro_odr_store);
+static DEVICE_ATTR(gyro_fast_calibration_en, S_IRUGO | S_IWUSR,
+bmi160_gyro_fast_calibration_en_show, bmi160_gyro_fast_calibration_en_store);
+static DEVICE_ATTR(gyro_offset_x, S_IRUGO | S_IWUSR,
+bmi160_gyro_offset_x_show, bmi160_gyro_offset_x_store);
+static DEVICE_ATTR(gyro_offset_y, S_IRUGO | S_IWUSR,
+bmi160_gyro_offset_y_show, bmi160_gyro_offset_y_store);
+static DEVICE_ATTR(gyro_offset_z, S_IRUGO | S_IWUSR,
+bmi160_gyro_offset_z_show, bmi160_gyro_offset_z_store);
+
+#ifdef BMI160_MAG_INTERFACE_SUPPORT
+static DEVICE_ATTR(mag_op_mode, S_IRUGO | S_IWUSR,
+ bmi160_mag_op_mode_show, bmi160_mag_op_mode_store);
+static DEVICE_ATTR(mag_odr, S_IRUGO | S_IWUSR,
+ bmi160_mag_odr_show, bmi160_mag_odr_store);
+static DEVICE_ATTR(mag_i2c_addr, S_IRUGO | S_IWUSR,
+ bmi160_mag_i2c_address_show, bmi160_mag_i2c_address_store);
+static DEVICE_ATTR(mag_value, S_IRUGO,
+ bmi160_mag_value_show, NULL);
+static DEVICE_ATTR(mag_offset, S_IRUGO | S_IWUSR,
+ bmi160_mag_offset_show, bmi160_mag_offset_store);
+static DEVICE_ATTR(mag_chip_id, S_IRUGO,
+ bmi160_mag_chip_id_show, NULL);
+static DEVICE_ATTR(mag_chip_name, S_IRUGO,
+ bmi160_mag_chip_name_show, NULL);
+static DEVICE_ATTR(mag_compensate, S_IRUGO | S_IWUSR,
+ bmi160_mag_compensate_xyz_show,
+ bmi160_mag_compensate_xyz_store);
+#endif
+
+
+#if defined(BMI160_ENABLE_INT1) || defined(BMI160_ENABLE_INT2)
+static DEVICE_ATTR(enable_int, S_IRUGO | S_IWUSR,
+ NULL, bmi_enable_int_store);
+static DEVICE_ATTR(anymot_duration, S_IRUGO | S_IWUSR,
+ bmi160_anymot_duration_show, bmi160_anymot_duration_store);
+static DEVICE_ATTR(anymot_threshold, S_IRUGO | S_IWUSR,
+ bmi160_anymot_threshold_show, bmi160_anymot_threshold_store);
+static DEVICE_ATTR(std_stu, S_IRUGO,
+ bmi160_step_detector_status_show, NULL);
+static DEVICE_ATTR(std_en, S_IRUGO | S_IWUSR,
+ bmi160_step_detector_enable_show,
+ bmi160_step_detector_enable_store);
+static DEVICE_ATTR(sig_en, S_IRUGO | S_IWUSR,
+ bmi160_signification_motion_enable_show,
+ bmi160_signification_motion_enable_store);
+
+#endif
+
+
+
+static DEVICE_ATTR(bmi_value, S_IRUGO,
+ bmi160_bmi_value_show, NULL);
+
+
+static struct attribute *bmi160_attributes[] = {
+ &dev_attr_chip_id.attr,
+ &dev_attr_err_st.attr,
+ &dev_attr_sensor_time.attr,
+ &dev_attr_selftest.attr,
+ &dev_attr_driver_version.attr,
+ &dev_attr_test.attr,
+ &dev_attr_fifo_flush.attr,
+ &dev_attr_fifo_header_en.attr,
+ &dev_attr_fifo_time_en.attr,
+ &dev_attr_fifo_int_tag_en.attr,
+ &dev_attr_fifo_bytecount.attr,
+ &dev_attr_fifo_data_sel.attr,
+ &dev_attr_fifo_data_frame.attr,
+
+ &dev_attr_fifo_watermark.attr,
+
+ &dev_attr_enable.attr,
+ &dev_attr_delay.attr,
+ &dev_attr_temperature.attr,
+ &dev_attr_place.attr,
+
+ &dev_attr_acc_range.attr,
+ &dev_attr_acc_odr.attr,
+ &dev_attr_acc_op_mode.attr,
+ &dev_attr_acc_value.attr,
+
+ &dev_attr_acc_fast_calibration_x.attr,
+ &dev_attr_acc_fast_calibration_y.attr,
+ &dev_attr_acc_fast_calibration_z.attr,
+ &dev_attr_acc_offset_x.attr,
+ &dev_attr_acc_offset_y.attr,
+ &dev_attr_acc_offset_z.attr,
+
+ &dev_attr_stc_enable.attr,
+ &dev_attr_stc_mode.attr,
+ &dev_attr_stc_clc.attr,
+ &dev_attr_stc_value.attr,
+
+ &dev_attr_gyro_op_mode.attr,
+ &dev_attr_gyro_value.attr,
+ &dev_attr_gyro_range.attr,
+ &dev_attr_gyro_odr.attr,
+ &dev_attr_gyro_fast_calibration_en.attr,
+ &dev_attr_gyro_offset_x.attr,
+ &dev_attr_gyro_offset_y.attr,
+ &dev_attr_gyro_offset_z.attr,
+
+#ifdef BMI160_MAG_INTERFACE_SUPPORT
+ &dev_attr_mag_chip_id.attr,
+ &dev_attr_mag_op_mode.attr,
+ &dev_attr_mag_odr.attr,
+ &dev_attr_mag_i2c_addr.attr,
+ &dev_attr_mag_chip_name.attr,
+ &dev_attr_mag_value.attr,
+ &dev_attr_mag_offset.attr,
+ &dev_attr_mag_compensate.attr,
+#endif
+
+#if defined(BMI160_ENABLE_INT1) || defined(BMI160_ENABLE_INT2)
+ &dev_attr_enable_int.attr,
+
+ &dev_attr_anymot_duration.attr,
+ &dev_attr_anymot_threshold.attr,
+ &dev_attr_std_stu.attr,
+ &dev_attr_std_en.attr,
+ &dev_attr_sig_en.attr,
+
+#endif
+ &dev_attr_reg_sel.attr,
+ &dev_attr_reg_val.attr,
+ &dev_attr_bmi_value.attr,
+ NULL
+};
+
+static struct attribute_group bmi160_attribute_group = {
+ .attrs = bmi160_attributes
+};
+
+#if defined(BMI160_ENABLE_INT1) || defined(BMI160_ENABLE_INT2)
+static void bmi_slope_interrupt_handle(struct bmi_client_data *client_data)
+{
+ /* anym_first[0..2]: x, y, z */
+ u8 anym_first[3] = {0};
+ u8 status2;
+ u8 anym_sign;
+ u8 i = 0;
+
+ client_data->device.bus_read(client_data->device.dev_addr,
+ BMI160_USER_INTR_STAT_2_ADDR, &status2, 1);
+ anym_first[0] = BMI160_GET_BITSLICE(status2,
+ BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_X);
+ anym_first[1] = BMI160_GET_BITSLICE(status2,
+ BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_Y);
+ anym_first[2] = BMI160_GET_BITSLICE(status2,
+ BMI160_USER_INTR_STAT_2_ANY_MOTION_FIRST_Z);
+ anym_sign = BMI160_GET_BITSLICE(status2,
+ BMI160_USER_INTR_STAT_2_ANY_MOTION_SIGN);
+
+ for (i = 0; i < 3; i++) {
+ if (anym_first[i]) {
+ /*1: negative*/
+ if (anym_sign)
+ dev_notice(client_data->dev,
+ "Anymotion interrupt happend!"
+ "%s axis, negative sign\n", bmi_axis_name[i]);
+ else
+ dev_notice(client_data->dev,
+ "Anymotion interrupt happend!"
+ "%s axis, postive sign\n", bmi_axis_name[i]);
+ }
+ }
+
+
+}
+
+static void bmi_fifo_watermark_interrupt_handle
+ (struct bmi_client_data *client_data)
+{
+ int err = 0;
+ unsigned int fifo_len0 = 0;
+ unsigned int fifo_frmbytes_ext = 0;
+ unsigned char *fifo_data = NULL;
+ fifo_data = kzalloc(FIFO_DATA_BUFSIZE, GFP_KERNEL);
+ /*TO DO*/
+ if (NULL == fifo_data) {
+ dev_err(client_data->dev, "no memory available");
+ err = -ENOMEM;
+ }
+ bmi_fifo_frame_bytes_extend_calc(client_data, &fifo_frmbytes_ext);
+
+ if (client_data->pw.acc_pm == 2 && client_data->pw.gyro_pm == 2
+ && client_data->pw.mag_pm == 2)
+ printk(KERN_INFO "pw_acc: %d, pw_gyro: %d\n",
+ client_data->pw.acc_pm, client_data->pw.gyro_pm);
+ if (!client_data->fifo_data_sel)
+ printk(KERN_INFO "no selsect sensor fifo, fifo_data_sel:%d\n",
+ client_data->fifo_data_sel);
+
+ err = BMI_CALL_API(fifo_length)(&fifo_len0);
+ client_data->fifo_bytecount = fifo_len0;
+
+ if (client_data->fifo_bytecount == 0 || err)
+ return;
+
+ if (client_data->fifo_bytecount + fifo_frmbytes_ext > FIFO_DATA_BUFSIZE)
+ client_data->fifo_bytecount = FIFO_DATA_BUFSIZE;
+ /* need give attention for the time of burst read*/
+ if (!err) {
+ err = bmi_burst_read_wrapper(client_data->device.dev_addr,
+ BMI160_USER_FIFO_DATA__REG, fifo_data,
+ client_data->fifo_bytecount + fifo_frmbytes_ext);
+ } else
+ dev_err(client_data->dev, "read fifo leght err");
+
+ if (err)
+ dev_err(client_data->dev, "brust read fifo err\n");
+ /*err = bmi_fifo_analysis_handle(client_data, fifo_data,
+ client_data->fifo_bytecount + 20, fifo_out_data);*/
+ if (fifo_data != NULL) {
+ kfree(fifo_data);
+ fifo_data = NULL;
+ }
+
+}
+static void bmi_data_ready_interrupt_handle(
+ struct bmi_client_data *client_data, uint8_t status)
+{
+ uint8_t data12[12] = {0};
+ struct bmi160_accel_t accel;
+ struct bmi160_gyro_t gyro;
+ struct timespec ts;
+ client_data->device.bus_read(client_data->device.dev_addr,
+ BMI160_USER_DATA_8_ADDR, data12, 12);
+ if (status & 0x80)
+ {
+ /*report acc data*/
+ /* Data X */
+ accel.x = (s16)((((s32)((s8)data12[7])) << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) | (data12[6]));
+ /* Data Y */
+ accel.y = (s16)((((s32)((s8)data12[9])) << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) | (data12[8]));
+ /* Data Z */
+ accel.z = (s16)((((s32)((s8)data12[11]))<< BMI160_SHIFT_BIT_POSITION_BY_08_BITS) | (data12[10]));
+ ts = ns_to_timespec(client_data->timestamp);
+ //printk("acc puneet ts.tv_sec %ld ts.tv_nsec %ld\n",ts.tv_sec,ts.tv_nsec);
+ input_event(client_data->input, EV_MSC, 6, ts.tv_sec);
+ input_event(client_data->input, EV_MSC, 6, ts.tv_nsec);
+ input_event(client_data->input, EV_MSC, MSC_GESTURE, accel.x);
+ input_event(client_data->input, EV_MSC, MSC_RAW, accel.y);
+ input_event(client_data->input, EV_MSC, MSC_SCAN, accel.z);
+ input_sync(client_data->input);
+ }
+ if (status & 0x40)
+ {
+ /*report gyro data*/
+ /* Data X */
+ gyro.x = (s16)((((s32)((s8)data12[1])) << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) | (data12[0]));
+ /* Data Y */
+ gyro.y = (s16)((((s32)((s8)data12[3])) << BMI160_SHIFT_BIT_POSITION_BY_08_BITS) | (data12[2]));
+ /* Data Z */
+ gyro.z = (s16)((((s32)((s8)data12[5]))<< BMI160_SHIFT_BIT_POSITION_BY_08_BITS) | (data12[4]));
+ ts = ns_to_timespec(client_data->timestamp);
+ //printk("gyro puneet ts.tv_sec %ld ts.tv_nsec %ld\n",ts.tv_sec,ts.tv_nsec);
+ input_event(client_data->gyro_input, EV_MSC, 6, ts.tv_sec);
+ input_event(client_data->gyro_input, EV_MSC, 6, ts.tv_nsec);
+ input_event(client_data->gyro_input, EV_MSC, MSC_GESTURE, gyro.x);
+ input_event(client_data->gyro_input, EV_MSC, MSC_RAW, gyro.y);
+ input_event(client_data->gyro_input, EV_MSC, MSC_SCAN, gyro.z);
+ input_sync(client_data->gyro_input);
+ }
+}
+
+static void bmi_signification_motion_interrupt_handle(
+ struct bmi_client_data *client_data)
+{
+ printk(KERN_INFO "bmi_signification_motion_interrupt_handle\n");
+ input_event(client_data->input, EV_MSC, INPUT_EVENT_SGM, 1);
+/*input_report_rel(client_data->input,INPUT_EVENT_SGM,1);*/
+ input_sync(client_data->input);
+ bmi160_set_command_register(CMD_RESET_INT_ENGINE);
+
+}
+static void bmi_stepdetector_interrupt_handle(
+ struct bmi_client_data *client_data)
+{
+ u8 current_step_dector_st = 0;
+ client_data->pedo_data.wkar_step_detector_status++;
+ current_step_dector_st =
+ client_data->pedo_data.wkar_step_detector_status;
+ client_data->std = ((current_step_dector_st == 1) ? 0 : 1);
+
+ input_event(client_data->input, EV_MSC, INPUT_EVENT_STEP_DETECTOR, 1);
+ input_sync(client_data->input);
+}
+
+static void bmi_irq_work_func(struct work_struct *work)
+{
+ struct bmi_client_data *client_data =
+ container_of((struct work_struct *)work,
+ struct bmi_client_data, irq_work);
+
+ unsigned char int_status[4] = {0, 0, 0, 0};
+ uint8_t status = 0;
+
+ //client_data->device.bus_read(client_data->device.dev_addr,
+ // BMI160_USER_INTR_STAT_0_ADDR, int_status, 4);
+ client_data->device.bus_read(client_data->device.dev_addr,
+ BMI160_USER_STAT_ADDR, &status, 1);
+ //printk("status = 0x%x", status);
+ if (BMI160_GET_BITSLICE(int_status[0],
+ BMI160_USER_INTR_STAT_0_ANY_MOTION))
+ bmi_slope_interrupt_handle(client_data);
+
+ if (BMI160_GET_BITSLICE(int_status[0],
+ BMI160_USER_INTR_STAT_0_STEP_INTR))
+ bmi_stepdetector_interrupt_handle(client_data);
+ if (BMI160_GET_BITSLICE(int_status[1],
+ BMI160_USER_INTR_STAT_1_FIFO_WM_INTR))
+ bmi_fifo_watermark_interrupt_handle(client_data);
+ if ((status & 0x80) || (status & 0x40))
+ bmi_data_ready_interrupt_handle(client_data, status);
+ /* Clear ALL inputerrupt status after handler sig mition*/
+ /* Put this commads intot the last one*/
+ if (BMI160_GET_BITSLICE(int_status[0],
+ BMI160_USER_INTR_STAT_0_SIGNIFICANT_INTR))
+ bmi_signification_motion_interrupt_handle(client_data);
+
+}
+
+static void bmi160_delay_sigmo_work_func(struct work_struct *work)
+{
+ struct bmi_client_data *client_data =
+ container_of(work, struct bmi_client_data,
+ delay_work_sig.work);
+ unsigned char int_status[4] = {0, 0, 0, 0};
+
+ client_data->device.bus_read(client_data->device.dev_addr,
+ BMI160_USER_INTR_STAT_0_ADDR, int_status, 4);
+ if (BMI160_GET_BITSLICE(int_status[0],
+ BMI160_USER_INTR_STAT_0_SIGNIFICANT_INTR))
+ bmi_signification_motion_interrupt_handle(client_data);
+}
+
+static irqreturn_t bmi_irq_handler(int irq, void *handle)
+{
+ struct bmi_client_data *client_data = handle;
+ int in_suspend_copy;
+ in_suspend_copy = atomic_read(&client_data->in_suspend);
+ client_data->timestamp= get_current_timestamp();
+ if (client_data == NULL)
+ return IRQ_HANDLED;
+ if (client_data->dev == NULL)
+ return IRQ_HANDLED;
+ /*this only deal with SIG_motion CTS test*/
+ if ((in_suspend_copy == 1) &&
+ (client_data->sig_flag == 1)) {
+ /*wake_lock_timeout(&client_data->wakelock, HZ);*/
+ schedule_delayed_work(&client_data->delay_work_sig,
+ msecs_to_jiffies(50));
+ }
+ schedule_work(&client_data->irq_work);
+
+ return IRQ_HANDLED;
+}
+#endif /* defined(BMI_ENABLE_INT1)||defined(BMI_ENABLE_INT2) */
+
+static int bmi_restore_hw_cfg(struct bmi_client_data *client)
+{
+ int err = 0;
+
+ if ((client->fifo_data_sel) & (1 << BMI_ACC_SENSOR)) {
+ err += BMI_CALL_API(set_accel_range)(client->range.acc_range);
+ err += BMI_CALL_API(set_accel_output_data_rate)
+ (client->odr.acc_odr);
+ err += BMI_CALL_API(set_fifo_accel_enable)(1);
+ }
+ if ((client->fifo_data_sel) & (1 << BMI_GYRO_SENSOR)) {
+ err += BMI_CALL_API(set_gyro_range)(client->range.gyro_range);
+ err += BMI_CALL_API(set_gyro_output_data_rate)
+ (client->odr.gyro_odr);
+ err += BMI_CALL_API(set_fifo_gyro_enable)(1);
+ }
+ if ((client->fifo_data_sel) & (1 << BMI_MAG_SENSOR)) {
+ err += BMI_CALL_API(set_mag_output_data_rate)
+ (client->odr.mag_odr);
+ err += BMI_CALL_API(set_fifo_mag_enable)(1);
+ }
+ err += BMI_CALL_API(set_command_register)(CMD_CLR_FIFO_DATA);
+
+ mutex_lock(&client->mutex_op_mode);
+ if (client->pw.acc_pm != BMI_ACC_PM_SUSPEND) {
+ err += BMI_CALL_API(set_command_register)
+ (bmi_pmu_cmd_acc_arr[BMI_ACC_PM_NORMAL]);
+ bmi_delay(3);
+ }
+ mutex_unlock(&client->mutex_op_mode);
+
+ mutex_lock(&client->mutex_op_mode);
+ if (client->pw.gyro_pm != BMI_GYRO_PM_SUSPEND) {
+ err += BMI_CALL_API(set_command_register)
+ (bmi_pmu_cmd_gyro_arr[BMI_GYRO_PM_NORMAL]);
+ bmi_delay(3);
+ }
+ mutex_unlock(&client->mutex_op_mode);
+
+ mutex_lock(&client->mutex_op_mode);
+
+ if (client->pw.mag_pm != BMI_MAG_PM_SUSPEND) {
+#ifdef BMI160_AKM09912_SUPPORT
+ err += bmi160_set_bst_akm_and_secondary_if_powermode
+ (BMI160_MAG_FORCE_MODE);
+#else
+ err += bmi160_set_bmm150_mag_and_secondary_if_power_mode
+ (BMI160_MAG_FORCE_MODE);
+#endif
+ bmi_delay(3);
+ }
+ mutex_unlock(&client->mutex_op_mode);
+
+ return err;
+}
+
+#if defined(CONFIG_USE_QUALCOMM_HAL)
+static void bmi160_accel_work_fn(struct work_struct *work)
+{
+ struct bmi_client_data *sensor;
+ ktime_t timestamp;
+ struct bmi160_accel_t data;
+ int err;
+ sensor = container_of((struct delayed_work *)work,
+ struct bmi_client_data, accel_poll_work);
+ timestamp = ktime_get();
+ err = BMI_CALL_API(read_accel_xyz)(&data);
+ if (err)
+ dev_err(sensor->dev, "read data err");
+ input_report_abs(sensor->input, ABS_X,
+ (data.x));
+ input_report_abs(sensor->input, ABS_Y,
+ (data.y));
+ input_report_abs(sensor->input, ABS_Z,
+ (data.z));
+ input_event(sensor->input,
+ EV_SYN, SYN_TIME_SEC,
+ ktime_to_timespec(timestamp).tv_sec);
+ input_event(sensor->input, EV_SYN,
+ SYN_TIME_NSEC,
+ ktime_to_timespec(timestamp).tv_nsec);
+ input_sync(sensor->input);
+ if (atomic_read(&sensor->accel_en))
+ queue_delayed_work(sensor->data_wq,
+ &sensor->accel_poll_work,
+ msecs_to_jiffies(sensor->accel_poll_ms));
+}
+static void bmi160_gyro_work_fn(struct work_struct *work)
+{
+ struct bmi_client_data *sensor;
+ ktime_t timestamp;
+ struct bmi160_gyro_t data;
+ int err;
+ sensor = container_of((struct delayed_work *)work,
+ struct bmi_client_data, gyro_poll_work);
+ timestamp = ktime_get();
+ err = BMI_CALL_API(read_gyro_xyz)(&data);
+ if (err)
+ dev_err(sensor->dev, "read data err");
+ input_report_abs(sensor->gyro_input, ABS_RX,
+ (data.x));
+ input_report_abs(sensor->gyro_input, ABS_RY,
+ (data.y));
+ input_report_abs(sensor->gyro_input, ABS_RZ,
+ (data.z));
+ input_event(sensor->gyro_input,
+ EV_SYN, SYN_TIME_SEC,
+ ktime_to_timespec(timestamp).tv_sec);
+ input_event(sensor->gyro_input, EV_SYN,
+ SYN_TIME_NSEC,
+ ktime_to_timespec(timestamp).tv_nsec);
+ input_sync(sensor->gyro_input);
+ if (atomic_read(&sensor->gyro_en))
+ queue_delayed_work(sensor->data_wq,
+ &sensor->gyro_poll_work,
+ msecs_to_jiffies(sensor->gyro_poll_ms));
+}
+static int bmi160_set_gyro_op_mode(struct bmi_client_data *client_data,
+ unsigned long op_mode)
+{
+ int err = 0;
+ mutex_lock(&client_data->mutex_op_mode);
+ if (op_mode < BMI_GYRO_PM_MAX) {
+ switch (op_mode) {
+ case BMI_GYRO_PM_NORMAL:
+ err = BMI_CALL_API(set_command_register)
+ (bmi_pmu_cmd_gyro_arr[BMI_GYRO_PM_NORMAL]);
+ client_data->pw.gyro_pm = BMI_GYRO_PM_NORMAL;
+ bmi_delay(60);
+ break;
+ case BMI_GYRO_PM_FAST_START:
+ err = BMI_CALL_API(set_command_register)
+ (bmi_pmu_cmd_gyro_arr[BMI_GYRO_PM_FAST_START]);
+ client_data->pw.gyro_pm = BMI_GYRO_PM_FAST_START;
+ bmi_delay(60);
+ break;
+ case BMI_GYRO_PM_SUSPEND:
+ err = BMI_CALL_API(set_command_register)
+ (bmi_pmu_cmd_gyro_arr[BMI_GYRO_PM_SUSPEND]);
+ client_data->pw.gyro_pm = BMI_GYRO_PM_SUSPEND;
+ bmi_delay(60);
+ break;
+ default:
+ mutex_unlock(&client_data->mutex_op_mode);
+ return -EINVAL;
+ }
+ } else {
+ mutex_unlock(&client_data->mutex_op_mode);
+ return -EINVAL;
+ }
+ mutex_unlock(&client_data->mutex_op_mode);
+ return err;
+}
+static int bmi160_accel_set_enable(
+ struct bmi_client_data *client_data, bool enable)
+{
+ int ret = 0;
+ dev_notice(client_data->dev,
+ "bmi160_accel_set_enable enable=%d\n", enable);
+ if (enable) {
+ ret = bmi160_set_acc_op_mode(client_data, 0);
+ if (ret) {
+ dev_err(client_data->dev,
+ "Fail to enable accel engine ret=%d\n", ret);
+ ret = -EBUSY;
+ goto exit;
+ }
+ queue_delayed_work(client_data->data_wq,
+ &client_data->accel_poll_work,
+ msecs_to_jiffies(client_data->accel_poll_ms));
+ atomic_set(&client_data->accel_en, 1);
+ } else {
+ atomic_set(&client_data->accel_en, 0);
+ cancel_delayed_work_sync(&client_data->accel_poll_work);
+ ret = bmi160_set_acc_op_mode(client_data, 2);
+ if (ret) {
+ dev_err(client_data->dev,
+ "Fail to disable accel engine ret=%d\n", ret);
+ ret = -EBUSY;
+ goto exit;
+ }
+ }
+exit:
+ return ret;
+}
+static int bmi160_accel_set_poll_delay(struct bmi_client_data *client_data,
+ unsigned long delay)
+{
+ dev_info(client_data->dev,
+ "bmi160_accel_set_poll_delay delay_ms=%ld\n", delay);
+ if (delay < BMI160_ACCEL_MIN_POLL_INTERVAL_MS)
+ delay = BMI160_ACCEL_MIN_POLL_INTERVAL_MS;
+ if (delay > BMI160_ACCEL_MAX_POLL_INTERVAL_MS)
+ delay = BMI160_ACCEL_MAX_POLL_INTERVAL_MS;
+ client_data->accel_poll_ms = delay;
+ if (!atomic_read(&client_data->accel_en))
+ goto exit;
+ cancel_delayed_work_sync(&client_data->accel_poll_work);
+ queue_delayed_work(client_data->data_wq,
+ &client_data->accel_poll_work,
+ msecs_to_jiffies(client_data->accel_poll_ms));
+exit:
+ return 0;
+}
+static int bmi160_gyro_set_enable(
+ struct bmi_client_data *client_data, bool enable)
+{
+ int ret = 0;
+ dev_notice(client_data->dev,
+ "bmi160_gyro_set_enable enable=%d\n", enable);
+ if (enable) {
+ ret = bmi160_set_gyro_op_mode(client_data, 0);
+ if (ret) {
+ dev_err(client_data->dev,
+ "Fail to enable gyro engine ret=%d\n", ret);
+ ret = -EBUSY;
+ goto exit;
+ }
+ queue_delayed_work(client_data->data_wq,
+ &client_data->gyro_poll_work,
+ msecs_to_jiffies(client_data->gyro_poll_ms));
+ atomic_set(&client_data->gyro_en, 1);
+ } else {
+ atomic_set(&client_data->gyro_en, 0);
+ cancel_delayed_work_sync(&client_data->gyro_poll_work);
+ ret = bmi160_set_gyro_op_mode(client_data, 2);
+ if (ret) {
+ dev_err(client_data->dev,
+ "Fail to disable accel engine ret=%d\n", ret);
+ ret = -EBUSY;
+ goto exit;
+ }
+ }
+exit:
+ return ret;
+}
+static int bmi160_gyro_set_poll_delay(struct bmi_client_data *client_data,
+ unsigned long delay)
+{
+ dev_info(client_data->dev,
+ "bmi160_accel_set_poll_delay delay_ms=%ld\n", delay);
+ if (delay < BMI160_GYRO_MIN_POLL_INTERVAL_MS)
+ delay = BMI160_GYRO_MIN_POLL_INTERVAL_MS;
+ if (delay > BMI160_GYRO_MAX_POLL_INTERVAL_MS)
+ delay = BMI160_GYRO_MAX_POLL_INTERVAL_MS;
+ client_data->gyro_poll_ms = delay;
+ if (!atomic_read(&client_data->gyro_en))
+ goto exit;
+ cancel_delayed_work_sync(&client_data->gyro_poll_work);
+ queue_delayed_work(client_data->data_wq,
+ &client_data->gyro_poll_work,
+ msecs_to_jiffies(client_data->gyro_poll_ms));
+exit:
+ return 0;
+}
+static int bmi160_accel_cdev_enable(struct sensors_classdev *sensors_cdev,
+ unsigned int enable)
+{
+ struct bmi_client_data *sensor = container_of(sensors_cdev,
+ struct bmi_client_data, accel_cdev);
+ return bmi160_accel_set_enable(sensor, enable);
+}
+static int bmi160_accel_cdev_poll_delay(struct sensors_classdev *sensors_cdev,
+ unsigned int delay_ms)
+{
+ struct bmi_client_data *sensor = container_of(sensors_cdev,
+ struct bmi_client_data, accel_cdev);
+
+ return bmi160_accel_set_poll_delay(sensor, delay_ms);
+}
+
+static int bmi160_gyro_cdev_enable(struct sensors_classdev *sensors_cdev,
+ unsigned int enable)
+{
+ struct bmi_client_data *sensor = container_of(sensors_cdev,
+ struct bmi_client_data, gyro_cdev);
+
+ return bmi160_gyro_set_enable(sensor, enable);
+}
+
+static int bmi160_gyro_cdev_poll_delay(struct sensors_classdev *sensors_cdev,
+ unsigned int delay_ms)
+{
+ struct bmi_client_data *sensor = container_of(sensors_cdev,
+ struct bmi_client_data, gyro_cdev);
+
+ return bmi160_gyro_set_poll_delay(sensor, delay_ms);
+}
+#endif
+
+int bmi_probe(struct bmi_client_data *client_data, struct device *dev)
+{
+ int err = 0;
+#ifdef BMI160_MAG_INTERFACE_SUPPORT
+ u8 mag_dev_addr;
+ u8 mag_urst_len;
+ u8 mag_op_mode;
+#endif
+ /* check chip id */
+ err = bmi_check_chip_id(client_data);
+ if (err)
+ goto exit_err_clean;
+
+ dev_set_drvdata(dev, client_data);
+ client_data->dev = dev;
+
+ mutex_init(&client_data->mutex_enable);
+ mutex_init(&client_data->mutex_op_mode);
+
+ /* input device init */
+ err = bmi_input_init(client_data);
+ if (err < 0)
+ goto exit_err_clean;
+
+ /* sysfs node creation */
+ err = sysfs_create_group(&client_data->input->dev.kobj,
+ &bmi160_attribute_group);
+
+ if (err < 0)
+ goto exit_err_sysfs;
+
+ if (NULL != dev->platform_data) {
+ client_data->bst_pd = kzalloc(sizeof(*client_data->bst_pd),
+ GFP_KERNEL);
+
+ if (NULL != client_data->bst_pd) {
+ memcpy(client_data->bst_pd, dev->platform_data,
+ sizeof(*client_data->bst_pd));
+ dev_notice(dev, "%s sensor driver set place: p%d\n",
+ client_data->bst_pd->name,
+ client_data->bst_pd->place);
+ }
+ }
+
+ if (NULL != client_data->bst_pd) {
+ memcpy(client_data->bst_pd, dev->platform_data,
+ sizeof(*client_data->bst_pd));
+ dev_notice(dev, "%s sensor driver set place: p%d\n",
+ client_data->bst_pd->name,
+ client_data->bst_pd->place);
+ }
+
+
+ /* workqueue init */
+ INIT_DELAYED_WORK(&client_data->work, bmi_work_func);
+ atomic_set(&client_data->delay, BMI_DELAY_DEFAULT);
+ atomic_set(&client_data->wkqueue_en, 0);
+
+ /* h/w init */
+ client_data->device.delay_msec = bmi_delay;
+ err = BMI_CALL_API(init)(&client_data->device);
+
+ bmi_dump_reg(client_data);
+
+ /*power on detected*/
+ /*or softrest(cmd 0xB6) */
+ /*fatal err check*/
+ /*soft reset*/
+ err += BMI_CALL_API(set_command_register)(CMD_RESET_USER_REG);
+ bmi_delay(3);
+ if (err)
+ dev_err(dev, "Failed soft reset, er=%d", err);
+ /*usr data config page*/
+ err += BMI_CALL_API(set_target_page)(USER_DAT_CFG_PAGE);
+ if (err)
+ dev_err(dev, "Failed cffg page, er=%d", err);
+ err += bmi_get_err_status(client_data);
+ if (err) {
+ dev_err(dev, "Failed to bmi16x init!err_st=0x%x\n",
+ client_data->err_st.err_st_all);
+ goto exit_err_sysfs;
+ }
+
+#ifdef BMI160_MAG_INTERFACE_SUPPORT
+ err += bmi160_set_command_register(MAG_MODE_NORMAL);
+ bmi_delay(2);
+ err += bmi160_get_mag_power_mode_stat(&mag_op_mode);
+ bmi_delay(2);
+ err += BMI_CALL_API(get_i2c_device_addr)(&mag_dev_addr);
+ bmi_delay(2);
+#if defined(BMI160_AKM09912_SUPPORT)
+ err += BMI_CALL_API(set_i2c_device_addr)(BMI160_AKM09912_I2C_ADDRESS);
+ bmi160_bst_akm_mag_interface_init(BMI160_AKM09912_I2C_ADDRESS);
+#else
+ err += BMI_CALL_API(set_i2c_device_addr)(
+ BMI160_AUX_BMM150_I2C_ADDRESS);
+ bmi160_bmm150_mag_interface_init();
+#endif
+
+ err += bmi160_set_mag_burst(3);
+ err += bmi160_get_mag_burst(&mag_urst_len);
+ if (err)
+ dev_err(client_data->dev, "Failed cffg mag, er=%d", err);
+ dev_info(client_data->dev,
+ "BMI160 mag_urst_len:%d, mag_add:0x%x, mag_op_mode:%d\n",
+ mag_urst_len, mag_dev_addr, mag_op_mode);
+#endif
+ if (err < 0)
+ goto exit_err_sysfs;
+
+
+#if defined(BMI160_ENABLE_INT1) || defined(BMI160_ENABLE_INT2)
+ /*wake_lock_init(&client_data->wakelock,
+ WAKE_LOCK_SUSPEND, "bmi160");*/
+ client_data->gpio_pin = of_get_named_gpio_flags(dev->of_node,
+ "bmi,gpio_irq", 0, NULL);
+ dev_info(client_data->dev, "BMI160 qpio number:%d\n",
+ client_data->gpio_pin);
+ err += gpio_request_one(client_data->gpio_pin,
+ GPIOF_IN, "bmi160_int");
+ err += gpio_direction_input(client_data->gpio_pin);
+ client_data->IRQ = gpio_to_irq(client_data->gpio_pin);
+ if (err) {
+ dev_err(client_data->dev,
+ "can not request gpio to irq number\n");
+ client_data->gpio_pin = 0;
+ }
+ INIT_DELAYED_WORK(&client_data->delay_work_sig,
+ bmi160_delay_sigmo_work_func);
+#ifdef BMI160_ENABLE_INT1
+ /* maps interrupt to INT1/InT2 pin */
+ BMI_CALL_API(set_intr_any_motion)(BMI_INT0, ENABLE);
+ BMI_CALL_API(set_intr_fifo_wm)(BMI_INT0, ENABLE);
+ BMI_CALL_API(set_intr_data_rdy)(BMI_INT0, ENABLE);
+
+ /*Set interrupt trige level way */
+ BMI_CALL_API(set_intr_edge_ctrl)(BMI_INT0, BMI_INT_LEVEL);
+ bmi160_set_intr_level(BMI_INT0, 1);
+ /*set interrupt latch temporary, 5 ms*/
+ /*bmi160_set_latch_int(5);*/
+
+ BMI_CALL_API(set_output_enable)(
+ BMI160_INTR1_OUTPUT_ENABLE, ENABLE);
+ sigmotion_init_interrupts(BMI160_MAP_INTR1);
+ BMI_CALL_API(map_step_detector_intr)(BMI160_MAP_INTR1);
+ /*close step_detector in init function*/
+ BMI_CALL_API(set_step_detector_enable)(0);
+#endif
+
+#ifdef BMI160_ENABLE_INT2
+ /* maps interrupt to INT1/InT2 pin */
+ BMI_CALL_API(set_intr_any_motion)(BMI_INT1, ENABLE);
+ BMI_CALL_API(set_intr_fifo_wm)(BMI_INT1, ENABLE);
+ BMI_CALL_API(set_intr_data_rdy)(BMI_INT1, ENABLE);
+
+ /*Set interrupt trige level way */
+ BMI_CALL_API(set_intr_edge_ctrl)(BMI_INT1, BMI_INT_LEVEL);
+ bmi160_set_intr_level(BMI_INT1, 1);
+ /*set interrupt latch temporary, 5 ms*/
+ /*bmi160_set_latch_int(5);*/
+
+ BMI_CALL_API(set_output_enable)(
+ BMI160_INTR2_OUTPUT_ENABLE, ENABLE);
+ sigmotion_init_interrupts(BMI160_MAP_INTR2);
+ BMI_CALL_API(map_step_detector_intr)(BMI160_MAP_INTR2);
+ /*close step_detector in init function*/
+ BMI_CALL_API(set_step_detector_enable)(0);
+#endif
+ err = request_irq(client_data->IRQ, bmi_irq_handler,
+ IRQF_TRIGGER_RISING, "bmi160", client_data);
+ if (err)
+ dev_err(client_data->dev, "could not request irq\n");
+
+ INIT_WORK(&client_data->irq_work, bmi_irq_work_func);
+#endif
+
+ client_data->selftest = 0;
+
+ client_data->fifo_data_sel = 0;
+ #if defined(CONFIG_USE_QUALCOMM_HAL)
+ BMI_CALL_API(set_accel_output_data_rate)(9);/*defalut odr 200HZ*/
+ BMI_CALL_API(set_gyro_output_data_rate)(9);/*defalut odr 200HZ*/
+ #endif
+ BMI_CALL_API(get_accel_output_data_rate)(&client_data->odr.acc_odr);
+ BMI_CALL_API(get_gyro_output_data_rate)(&client_data->odr.gyro_odr);
+ BMI_CALL_API(get_mag_output_data_rate)(&client_data->odr.mag_odr);
+ BMI_CALL_API(set_fifo_time_enable)(1);
+ BMI_CALL_API(get_accel_range)(&client_data->range.acc_range);
+ BMI_CALL_API(get_gyro_range)(&client_data->range.gyro_range);
+ /* now it's power on which is considered as resuming from suspend */
+
+ /* gyro input device init */
+ err = bmi_gyro_input_init(client_data);
+ #if defined(CONFIG_USE_QUALCOMM_HAL)
+ /* gyro input device init */
+ err = bmi_gyro_input_init(client_data);
+ if (err < 0)
+ goto exit_err_clean;
+ client_data->accel_poll_ms = BMI160_ACCEL_DEFAULT_POLL_INTERVAL_MS;
+ client_data->gyro_poll_ms = BMI160_GYRO_DEFAULT_POLL_INTERVAL_MS;
+ client_data->data_wq = create_freezable_workqueue("bmi160_data_work");
+ if (!client_data->data_wq) {
+ dev_err(dev, "Cannot create workqueue!\n");
+ goto exit_err_clean;
+ }
+ INIT_DELAYED_WORK(&client_data->accel_poll_work,
+ bmi160_accel_work_fn);
+ client_data->accel_cdev = bmi160_accel_cdev;
+ client_data->accel_cdev.delay_msec = client_data->accel_poll_ms;
+ client_data->accel_cdev.sensors_enable = bmi160_accel_cdev_enable;
+ client_data->accel_cdev.sensors_poll_delay =
+ bmi160_accel_cdev_poll_delay;
+ err = sensors_classdev_register(dev, &client_data->accel_cdev);
+ if (err) {
+ dev_err(dev,
+ "create accel class device file failed!\n");
+ goto exit_err_clean;
+ }
+ INIT_DELAYED_WORK(&client_data->gyro_poll_work, bmi160_gyro_work_fn);
+ client_data->gyro_cdev = bmi160_gyro_cdev;
+ client_data->gyro_cdev.delay_msec = client_data->gyro_poll_ms;
+ client_data->gyro_cdev.sensors_enable = bmi160_gyro_cdev_enable;
+ client_data->gyro_cdev.sensors_poll_delay = bmi160_gyro_cdev_poll_delay;
+ err = sensors_classdev_register(dev, &client_data->gyro_cdev);
+ if (err) {
+ dev_err(dev,
+ "create accel class device file failed!\n");
+ goto exit_err_clean;
+ }
+ #endif
+ /* set sensor PMU into suspend power mode for all */
+ if (bmi_pmu_set_suspend(client_data) < 0) {
+ dev_err(dev, "Failed to set BMI160 to suspend power mode\n");
+ goto exit_err_sysfs;
+ }
+ /*enable the data ready interrupt*/
+ BMI_CALL_API(set_intr_enable_1)(BMI160_DATA_RDY_ENABLE, 1);
+ dev_notice(dev, "sensor_time:%d, %d, %d",
+ sensortime_duration_tbl[0].ts_delat,
+ sensortime_duration_tbl[0].ts_duration_lsb,
+ sensortime_duration_tbl[0].ts_duration_us);
+ dev_notice(dev, "sensor %s probed successfully", SENSOR_NAME);
+
+ return 0;
+
+exit_err_sysfs:
+ if (err)
+ bmi_input_destroy(client_data);
+
+exit_err_clean:
+ if (err) {
+ if (client_data != NULL) {
+ if (NULL != client_data->bst_pd) {
+ kfree(client_data->bst_pd);
+ client_data->bst_pd = NULL;
+ }
+ }
+ }
+ return err;
+}
+EXPORT_SYMBOL(bmi_probe);
+
+/*!
+ * @brief remove bmi client
+ *
+ * @param dev the pointer of device
+ *
+ * @return zero
+ * @retval zero
+*/
+int bmi_remove(struct device *dev)
+{
+ int err = 0;
+ struct bmi_client_data *client_data = dev_get_drvdata(dev);
+
+ if (NULL != client_data) {
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ unregister_early_suspend(&client_data->early_suspend_handler);
+#endif
+ mutex_lock(&client_data->mutex_enable);
+ if (BMI_ACC_PM_NORMAL == client_data->pw.acc_pm ||
+ BMI_GYRO_PM_NORMAL == client_data->pw.gyro_pm ||
+ BMI_MAG_PM_NORMAL == client_data->pw.mag_pm) {
+ cancel_delayed_work_sync(&client_data->work);
+ }
+ mutex_unlock(&client_data->mutex_enable);
+
+ err = bmi_pmu_set_suspend(client_data);
+
+ bmi_delay(5);
+
+ sysfs_remove_group(&client_data->input->dev.kobj,
+ &bmi160_attribute_group);
+ bmi_input_destroy(client_data);
+
+ if (NULL != client_data->bst_pd) {
+ kfree(client_data->bst_pd);
+ client_data->bst_pd = NULL;
+ }
+ kfree(client_data);
+ }
+
+ return err;
+}
+EXPORT_SYMBOL(bmi_remove);
+
+static int bmi_post_resume(struct bmi_client_data *client_data)
+{
+ int err = 0;
+
+ mutex_lock(&client_data->mutex_enable);
+
+ if (atomic_read(&client_data->wkqueue_en) == 1) {
+ bmi160_set_acc_op_mode(client_data, BMI_ACC_PM_NORMAL);
+ schedule_delayed_work(&client_data->work,
+ msecs_to_jiffies(
+ atomic_read(&client_data->delay)));
+ }
+ mutex_unlock(&client_data->mutex_enable);
+
+ return err;
+}
+
+
+int bmi_suspend(struct device *dev)
+{
+ int err = 0;
+ struct bmi_client_data *client_data = dev_get_drvdata(dev);
+ unsigned char stc_enable;
+ unsigned char std_enable;
+ dev_err(client_data->dev, "bmi suspend function entrance");
+
+ atomic_set(&client_data->in_suspend, 1);
+ if (atomic_read(&client_data->wkqueue_en) == 1) {
+ bmi160_set_acc_op_mode(client_data, BMI_ACC_PM_SUSPEND);
+ cancel_delayed_work_sync(&client_data->work);
+ }
+ BMI_CALL_API(get_step_counter_enable)(&stc_enable);
+ BMI_CALL_API(get_step_detector_enable)(&std_enable);
+ if (client_data->pw.acc_pm != BMI_ACC_PM_SUSPEND &&
+ (stc_enable != 1) && (std_enable != 1) &&
+ (client_data->sig_flag != 1)) {
+ err += BMI_CALL_API(set_command_register)
+ (bmi_pmu_cmd_acc_arr[BMI_ACC_PM_SUSPEND]);
+ bmi_delay(3);
+ }
+ if (client_data->pw.gyro_pm != BMI_GYRO_PM_SUSPEND) {
+ err += BMI_CALL_API(set_command_register)
+ (bmi_pmu_cmd_gyro_arr[BMI_GYRO_PM_SUSPEND]);
+ bmi_delay(3);
+ }
+
+ if (client_data->pw.mag_pm != BMI_MAG_PM_SUSPEND) {
+#if defined(BMI160_AKM09912_SUPPORT)
+ err += bmi160_set_bst_akm_and_secondary_if_powermode(
+ BMI160_MAG_SUSPEND_MODE);
+#else
+ err += bmi160_set_bmm150_mag_and_secondary_if_power_mode(
+ BMI160_MAG_SUSPEND_MODE);
+#endif
+ bmi_delay(3);
+ }
+
+ return err;
+}
+EXPORT_SYMBOL(bmi_suspend);
+
+int bmi_resume(struct device *dev)
+{
+ int err = 0;
+ struct bmi_client_data *client_data = dev_get_drvdata(dev);
+ atomic_set(&client_data->in_suspend, 0);
+ if (client_data->pw.acc_pm != BMI_ACC_PM_SUSPEND) {
+ err += BMI_CALL_API(set_command_register)
+ (bmi_pmu_cmd_acc_arr[BMI_ACC_PM_NORMAL]);
+ bmi_delay(3);
+ }
+ if (client_data->pw.gyro_pm != BMI_GYRO_PM_SUSPEND) {
+ err += BMI_CALL_API(set_command_register)
+ (bmi_pmu_cmd_gyro_arr[BMI_GYRO_PM_NORMAL]);
+ bmi_delay(3);
+ }
+
+ if (client_data->pw.mag_pm != BMI_MAG_PM_SUSPEND) {
+#if defined(BMI160_AKM09912_SUPPORT)
+ err += bmi160_set_bst_akm_and_secondary_if_powermode
+ (BMI160_MAG_FORCE_MODE);
+#else
+ err += bmi160_set_bmm150_mag_and_secondary_if_power_mode
+ (BMI160_MAG_FORCE_MODE);
+#endif
+ bmi_delay(3);
+ }
+ /* post resume operation */
+ err += bmi_post_resume(client_data);
+
+ return err;
+}
+EXPORT_SYMBOL(bmi_resume);
+
diff --git a/drivers/input/sensors/bmi160/bmi160_driver.h b/drivers/input/sensors/bmi160/bmi160_driver.h
new file mode 100644
index 0000000..993a885
--- /dev/null
+++ b/drivers/input/sensors/bmi160/bmi160_driver.h
@@ -0,0 +1,409 @@
+/*!
+ * @section LICENSE
+ * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved
+ *
+ * This software program is licensed subject to the GNU General
+ * Public License (GPL).Version 2,June 1991,
+ * available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * @filename bmi160_driver.h
+ * @date 2015/08/17 14:40
+ * @id "e90a329"
+ * @version 1.3
+ *
+ * @brief
+ * The head file of BMI160 device driver core code
+*/
+#ifndef _BMI160_DRIVER_H
+#define _BMI160_DRIVER_H
+
+#ifdef __KERNEL__
+#include <linux/kernel.h>
+#include <linux/unistd.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#else
+#include <unistd.h>
+#include <sys/types.h>
+#include <string.h>
+#endif
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/time.h>
+#include <linux/ktime.h>
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+
+#include "bmi160.h"
+
+#if defined(CONFIG_USE_QUALCOMM_HAL)
+#include <linux/sensors.h>
+#endif
+/* sensor specific */
+#define SENSOR_NAME "bmi160"
+#define BMI160_ENABLE_INT1 1
+//#define BMI160_ENABLE_INT2 1
+/*#define BMI160_MAG_INTERFACE_SUPPORT 1*/
+
+/*#define BMI160_AKM09912_SUPPORT 1*/
+#define BMI_USE_BASIC_I2C_FUNC 1
+#define SENSOR_CHIP_ID_BMI (0xD0)
+#define SENSOR_CHIP_ID_BMI_C2 (0xD1)
+#define SENSOR_CHIP_ID_BMI_C3 (0xD3)
+
+#define SENSOR_CHIP_REV_ID_BMI (0x00)
+
+#define CHECK_CHIP_ID_TIME_MAX 5
+
+#define BMI_REG_NAME(name) BMI160_##name##__REG
+#define BMI_VAL_NAME(name) BMI160_##name
+#define BMI_CALL_API(name) bmi160_##name
+
+#define BMI_I2C_WRITE_DELAY_TIME (1)
+
+/* generic */
+#define BMI_MAX_RETRY_I2C_XFER (10)
+#define BMI_MAX_RETRY_WAKEUP (5)
+#define BMI_MAX_RETRY_WAIT_DRDY (100)
+
+#define BMI_DELAY_MIN (1)
+#define BMI_DELAY_DEFAULT (200)
+
+#define BMI_VALUE_MAX (32767)
+#define BMI_VALUE_MIN (-32768)
+
+#define BYTES_PER_LINE (16)
+
+#define BUF_SIZE_PRINT (16)
+
+#define BMI_FAST_CALI_TRUE (1)
+#define BMI_FAST_CALI_ALL_RDY (7)
+
+/*! FIFO 1024 byte, max fifo frame count not over 150 */
+#define FIFO_FRAME_CNT 170
+#define FIFO_DATA_BUFSIZE 1024
+
+
+#define FRAME_LEN_ACC 6
+#define FRAME_LEN_GYRO 6
+#define FRAME_LEN_MAG 8
+
+/*! BMI Self test */
+#define BMI_SELFTEST_AMP_HIGH 1
+
+/* CMD */
+#define CMD_FOC_START 0x03
+#define CMD_PMU_ACC_SUSPEND 0x10
+#define CMD_PMU_ACC_NORMAL 0x11
+#define CMD_PMU_ACC_LP1 0x12
+#define CMD_PMU_ACC_LP2 0x13
+#define CMD_PMU_GYRO_SUSPEND 0x14
+#define CMD_PMU_GYRO_NORMAL 0x15
+#define CMD_PMU_GYRO_FASTSTART 0x17
+#define CMD_PMU_MAG_SUSPEND 0x18
+#define CMD_PMU_MAG_NORMAL 0x19
+#define CMD_PMU_MAG_LP1 0x1A
+#define CMD_PMU_MAG_LP2 0x1B
+#define CMD_CLR_FIFO_DATA 0xB0
+#define CMD_RESET_INT_ENGINE 0xB1
+#define CMD_RESET_USER_REG 0xB6
+
+#define USER_DAT_CFG_PAGE 0x00
+
+/*! FIFO Head definition*/
+#define FIFO_HEAD_A 0x84
+#define FIFO_HEAD_G 0x88
+#define FIFO_HEAD_M 0x90
+
+#define FIFO_HEAD_G_A (FIFO_HEAD_G | FIFO_HEAD_A)
+#define FIFO_HEAD_M_A (FIFO_HEAD_M | FIFO_HEAD_A)
+#define FIFO_HEAD_M_G (FIFO_HEAD_M | FIFO_HEAD_G)
+
+#define FIFO_HEAD_M_G_A (FIFO_HEAD_M | FIFO_HEAD_G | FIFO_HEAD_A)
+
+#define FIFO_HEAD_SENSOR_TIME 0x44
+#define FIFO_HEAD_SKIP_FRAME 0x40
+#define FIFO_HEAD_OVER_READ_LSB 0x80
+#define FIFO_HEAD_OVER_READ_MSB 0x00
+
+/*! FIFO head mode Frame bytes number definition */
+#define A_BYTES_FRM 6
+#define G_BYTES_FRM 6
+#define M_BYTES_FRM 8
+#define GA_BYTES_FRM 12
+#define MG_BYTES_FRM 14
+#define MA_BYTES_FRM 14
+#define MGA_BYTES_FRM 20
+
+#define ACC_FIFO_HEAD "acc"
+#define GYRO_FIFO_HEAD "gyro"
+#define MAG_FIFO_HEAD "mag"
+
+/*! Bosch sensor unknown place*/
+#define BOSCH_SENSOR_PLACE_UNKNOWN (-1)
+/*! Bosch sensor remapping table size P0~P7*/
+#define MAX_AXIS_REMAP_TAB_SZ 8
+
+#define ENABLE 1
+#define DISABLE 0
+
+/* bmi sensor HW interrupt pin number */
+#define BMI_INT0 0
+#define BMI_INT1 1
+
+#define BMI_INT_LEVEL 0
+#define BMI_INT_EDGE 1
+
+/*! BMI mag interface */
+
+
+/* compensated output value returned if sensor had overflow */
+#define BMM050_OVERFLOW_OUTPUT -32768
+#define BMM050_OVERFLOW_OUTPUT_S32 ((s32)(-2147483647-1))
+
+/* Trim Extended Registers */
+#define BMM050_DIG_X1 0x5D
+#define BMM050_DIG_Y1 0x5E
+#define BMM050_DIG_Z4_LSB 0x62
+#define BMM050_DIG_Z4_MSB 0x63
+#define BMM050_DIG_X2 0x64
+#define BMM050_DIG_Y2 0x65
+#define BMM050_DIG_Z2_LSB 0x68
+#define BMM050_DIG_Z2_MSB 0x69
+#define BMM050_DIG_Z1_LSB 0x6A
+#define BMM050_DIG_Z1_MSB 0x6B
+#define BMM050_DIG_XYZ1_LSB 0x6C
+#define BMM050_DIG_XYZ1_MSB 0x6D
+#define BMM050_DIG_Z3_LSB 0x6E
+#define BMM050_DIG_Z3_MSB 0x6F
+#define BMM050_DIG_XY2 0x70
+#define BMM050_DIG_XY1 0x71
+
+struct bmi160mag_compensate_t {
+ signed char dig_x1;
+ signed char dig_y1;
+
+ signed char dig_x2;
+ signed char dig_y2;
+
+ u16 dig_z1;
+ s16 dig_z2;
+ s16 dig_z3;
+ s16 dig_z4;
+
+ unsigned char dig_xy1;
+ signed char dig_xy2;
+
+ u16 dig_xyz1;
+};
+
+/*bmi fifo sensor type combination*/
+enum BMI_FIFO_DATA_SELECT_T {
+ BMI_FIFO_A_SEL = 1,
+ BMI_FIFO_G_SEL,
+ BMI_FIFO_G_A_SEL,
+ BMI_FIFO_M_SEL,
+ BMI_FIFO_M_A_SEL,
+ BMI_FIFO_M_G_SEL,
+ BMI_FIFO_M_G_A_SEL,
+ BMI_FIFO_DATA_SEL_MAX
+};
+
+/*bmi interrupt about step_detector and sgm*/
+#define INPUT_EVENT_STEP_DETECTOR 5
+#define INPUT_EVENT_SGM 3/*7*/
+#define INPUT_EVENT_FAST_ACC_CALIB_DONE 6
+#define INPUT_EVENT_FAST_GYRO_CALIB_DONE 4
+
+
+/*!
+* Bst sensor common definition,
+* please give parameters in BSP file.
+*/
+struct bosch_sensor_specific {
+ char *name;
+ /* 0 to 7 */
+ unsigned int place:3;
+ int irq;
+ int (*irq_gpio_cfg)(void);
+};
+
+/*! bmi160 sensor spec of power mode */
+struct pw_mode {
+ u8 acc_pm;
+ u8 gyro_pm;
+ u8 mag_pm;
+};
+
+/*! bmi160 sensor spec of odr */
+struct odr_t {
+ u8 acc_odr;
+ u8 gyro_odr;
+ u8 mag_odr;
+};
+
+/*! bmi160 sensor spec of range */
+struct range_t {
+ u8 acc_range;
+ u8 gyro_range;
+};
+
+/*! bmi160 sensor error status */
+struct err_status {
+ u8 fatal_err;
+ u8 err_code;
+ u8 i2c_fail;
+ u8 drop_cmd;
+ u8 mag_drdy_err;
+ u8 err_st_all;
+};
+
+/*! bmi160 fifo frame for all sensors */
+struct fifo_frame_t {
+ struct bmi160_accel_t *acc_farr;
+ struct bmi160_gyro_t *gyro_farr;
+ struct bmi160_mag_xyz_s32_t *mag_farr;
+
+ unsigned char acc_frame_cnt;
+ unsigned char gyro_frame_cnt;
+ unsigned char mag_frame_cnt;
+
+ u32 acc_lastf_ts;
+ u32 gyro_lastf_ts;
+ u32 mag_lastf_ts;
+};
+
+/*! bmi160 fifo sensor time */
+struct fifo_sensor_time_t {
+ u32 acc_ts;
+ u32 gyro_ts;
+ u32 mag_ts;
+};
+
+struct pedometer_data_t {
+ /*! Fix step detector misinformation for the first time*/
+ u8 wkar_step_detector_status;
+ u_int32_t last_step_counter_value;
+};
+
+struct bmi_client_data {
+ struct bmi160_t device;
+ struct device *dev;
+ struct input_dev *input;/*acc_device*/
+ struct input_dev *gyro_input;
+ #if defined(CONFIG_USE_QUALCOMM_HAL)
+ struct input_dev *gyro_input;
+ struct sensors_classdev accel_cdev;
+ struct sensors_classdev gyro_cdev;
+ struct delayed_work accel_poll_work;
+ struct delayed_work gyro_poll_work;
+ u32 accel_poll_ms;
+ u32 gyro_poll_ms;
+ u32 accel_latency_ms;
+ u32 gyro_latency_ms;
+ atomic_t accel_en;
+ atomic_t gyro_en;
+ struct workqueue_struct *data_wq;
+ #endif
+ struct delayed_work work;
+ struct work_struct irq_work;
+
+ u8 chip_id;
+
+ struct pw_mode pw;
+ struct odr_t odr;
+ struct range_t range; /*TO DO*/
+ struct err_status err_st;
+ struct pedometer_data_t pedo_data;
+ s8 place;
+ u8 selftest;
+ /*struct wake_lock wakelock;*/
+ struct delayed_work delay_work_sig;
+ atomic_t in_suspend;
+
+ atomic_t wkqueue_en; /*TO DO acc gyro mag*/
+ atomic_t delay;
+ atomic_t selftest_result;
+
+ u8 fifo_data_sel;
+ u16 fifo_bytecount;
+ u8 fifo_head_en;
+ unsigned char fifo_int_tag_en;
+ struct fifo_frame_t fifo_frame;
+
+ unsigned char *fifo_data;
+ u64 fifo_time;
+ u8 stc_enable;
+ uint16_t gpio_pin;
+ u8 std;
+ u8 sig_flag;
+ unsigned char calib_status;
+ struct mutex mutex_op_mode;
+ struct mutex mutex_enable;
+ struct bosch_sensor_specific *bst_pd;
+ int IRQ;
+ int reg_sel;
+ int reg_len;
+ uint64_t timestamp;
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ struct early_suspend early_suspend_handler;
+#endif
+};
+
+
+/*!
+ * we use a typedef to hide the detail,
+ * because this type might be changed
+ */
+struct bosch_sensor_axis_remap {
+ /* src means which source will be mapped to target x, y, z axis */
+ /* if an target OS axis is remapped from (-)x,
+ * src is 0, sign_* is (-)1 */
+ /* if an target OS axis is remapped from (-)y,
+ * src is 1, sign_* is (-)1 */
+ /* if an target OS axis is remapped from (-)z,
+ * src is 2, sign_* is (-)1 */
+ int src_x:3;
+ int src_y:3;
+ int src_z:3;
+
+ int sign_x:2;
+ int sign_y:2;
+ int sign_z:2;
+};
+
+
+struct bosch_sensor_data {
+ union {
+ int16_t v[3];
+ struct {
+ int16_t x;
+ int16_t y;
+ int16_t z;
+ };
+ };
+};
+
+s8 bmi_burst_read_wrapper(u8 dev_addr, u8 reg_addr, u8 *data, u16 len);
+int bmi_probe(struct bmi_client_data *client_data, struct device *dev);
+int bmi_remove(struct device *dev);
+int bmi_suspend(struct device *dev);
+int bmi_resume(struct device *dev);
+
+
+
+
+#endif/*_BMI160_DRIVER_H*/
+/*@}*/
+
diff --git a/drivers/input/sensors/bmi160/bmi160_i2c.c b/drivers/input/sensors/bmi160/bmi160_i2c.c
new file mode 100644
index 0000000..57d42c62
--- /dev/null
+++ b/drivers/input/sensors/bmi160/bmi160_i2c.c
@@ -0,0 +1,369 @@
+/*!
+ * @section LICENSE
+ * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved
+ *
+ * This software program is licensed subject to the GNU General
+ * Public License (GPL).Version 2,June 1991,
+ * available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * @filename bmi160_i2c.c
+ * @date 2014/11/25 14:40
+ * @id "20f77db"
+ * @version 1.3
+ *
+ * @brief
+ * This file implements moudle function, which add
+ * the driver to I2C core.
+*/
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include "bmi160_driver.h"
+
+/*! @defgroup bmi160_i2c_src
+ * @brief bmi160 i2c driver module
+ @{*/
+
+static struct i2c_client *bmi_client;
+/*!
+ * @brief define i2c wirte function
+ *
+ * @param client the pointer of i2c client
+ * @param reg_addr register address
+ * @param data the pointer of data buffer
+ * @param len block size need to write
+ *
+ * @return zero success, non-zero failed
+ * @retval zero success
+ * @retval non-zero failed
+*/
+/* i2c read routine for API*/
+static s8 bmi_i2c_read(struct i2c_client *client, u8 reg_addr,
+ u8 *data, u8 len)
+ {
+#if !defined BMI_USE_BASIC_I2C_FUNC
+ s32 dummy;
+ if (NULL == client)
+ return -EINVAL;
+
+ while (0 != len--) {
+#ifdef BMI_SMBUS
+ dummy = i2c_smbus_read_byte_data(client, reg_addr);
+ if (dummy < 0) {
+ dev_err(&client->dev, "i2c smbus read error");
+ return -EIO;
+ }
+ *data = (u8)(dummy & 0xff);
+#else
+ dummy = i2c_master_send(client, (char *)®_addr, 1);
+ if (dummy < 0) {
+ dev_err(&client->dev, "i2c bus master write error");
+ return -EIO;
+ }
+
+ dummy = i2c_master_recv(client, (char *)data, 1);
+ if (dummy < 0) {
+ dev_err(&client->dev, "i2c bus master read error");
+ return -EIO;
+ }
+#endif
+ reg_addr++;
+ data++;
+ }
+ return 0;
+#else
+ int retry;
+
+ struct i2c_msg msg[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 1,
+ .buf = ®_addr,
+ },
+
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = len,
+ .buf = data,
+ },
+ };
+
+ for (retry = 0; retry < BMI_MAX_RETRY_I2C_XFER; retry++) {
+ if (i2c_transfer(client->adapter, msg,
+ ARRAY_SIZE(msg)) > 0)
+ break;
+ else
+ usleep_range(BMI_I2C_WRITE_DELAY_TIME * 1000,
+ BMI_I2C_WRITE_DELAY_TIME * 1000);
+ }
+
+ if (BMI_MAX_RETRY_I2C_XFER <= retry) {
+ dev_err(&client->dev, "I2C xfer error");
+ return -EIO;
+ }
+
+ return 0;
+#endif
+ }
+
+
+static s8 bmi_i2c_burst_read(struct i2c_client *client, u8 reg_addr,
+ u8 *data, u16 len)
+{
+ int retry;
+
+ struct i2c_msg msg[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 1,
+ .buf = ®_addr,
+ },
+
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = len,
+ .buf = data,
+ },
+ };
+
+ for (retry = 0; retry < BMI_MAX_RETRY_I2C_XFER; retry++) {
+ if (i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)) > 0)
+ break;
+ else
+ usleep_range(BMI_I2C_WRITE_DELAY_TIME * 1000,
+ BMI_I2C_WRITE_DELAY_TIME * 1000);
+ }
+
+ if (BMI_MAX_RETRY_I2C_XFER <= retry) {
+ dev_err(&client->dev, "I2C xfer error");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+
+/* i2c write routine for */
+static s8 bmi_i2c_write(struct i2c_client *client, u8 reg_addr,
+ u8 *data, u8 len)
+{
+#if !defined BMI_USE_BASIC_I2C_FUNC
+ s32 dummy;
+
+#ifndef BMI_SMBUS
+ u8 buffer[2];
+#endif
+
+ if (NULL == client)
+ return -EPERM;
+
+ while (0 != len--) {
+#ifdef BMI_SMBUS
+ dummy = i2c_smbus_write_byte_data(client, reg_addr, *data);
+#else
+ buffer[0] = reg_addr;
+ buffer[1] = *data;
+ dummy = i2c_master_send(client, (char *)buffer, 2);
+#endif
+ reg_addr++;
+ data++;
+ if (dummy < 0) {
+ dev_err(&client->dev, "error writing i2c bus");
+ return -EPERM;
+ }
+
+ }
+ usleep_range(BMI_I2C_WRITE_DELAY_TIME * 1000,
+ BMI_I2C_WRITE_DELAY_TIME * 1000);
+ return 0;
+#else
+ u8 buffer[2];
+ int retry;
+ struct i2c_msg msg[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 2,
+ .buf = buffer,
+ },
+ };
+
+ while (0 != len--) {
+ buffer[0] = reg_addr;
+ buffer[1] = *data;
+ for (retry = 0; retry < BMI_MAX_RETRY_I2C_XFER; retry++) {
+ if (i2c_transfer(client->adapter, msg,
+ ARRAY_SIZE(msg)) > 0) {
+ break;
+ } else {
+ usleep_range(BMI_I2C_WRITE_DELAY_TIME * 1000,
+ BMI_I2C_WRITE_DELAY_TIME * 1000);
+ }
+ }
+ if (BMI_MAX_RETRY_I2C_XFER <= retry) {
+ dev_err(&client->dev, "I2C xfer error");
+ return -EIO;
+ }
+ reg_addr++;
+ data++;
+ }
+
+ usleep_range(BMI_I2C_WRITE_DELAY_TIME * 1000,
+ BMI_I2C_WRITE_DELAY_TIME * 1000);
+ return 0;
+#endif
+}
+
+
+static s8 bmi_i2c_read_wrapper(u8 dev_addr, u8 reg_addr, u8 *data, u8 len)
+{
+ int err = 0;
+ err = bmi_i2c_read(bmi_client, reg_addr, data, len);
+ return err;
+}
+
+static s8 bmi_i2c_write_wrapper(u8 dev_addr, u8 reg_addr, u8 *data, u8 len)
+{
+ int err = 0;
+ err = bmi_i2c_write(bmi_client, reg_addr, data, len);
+ return err;
+}
+
+s8 bmi_burst_read_wrapper(u8 dev_addr, u8 reg_addr, u8 *data, u16 len)
+{
+ int err = 0;
+ err = bmi_i2c_burst_read(bmi_client, reg_addr, data, len);
+ return err;
+}
+EXPORT_SYMBOL(bmi_burst_read_wrapper);
+/*!
+ * @brief BMI probe function via i2c bus
+ *
+ * @param client the pointer of i2c client
+ * @param id the pointer of i2c device id
+ *
+ * @return zero success, non-zero failed
+ * @retval zero success
+ * @retval non-zero failed
+*/
+static int bmi_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int err = 0;
+ struct bmi_client_data *client_data = NULL;
+
+ dev_info(&client->dev, "BMI160 i2c function probe entrance");
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ dev_err(&client->dev, "i2c_check_functionality error!");
+ err = -EIO;
+ goto exit_err_clean;
+ }
+
+ if (NULL == bmi_client) {
+ bmi_client = client;
+ } else {
+ dev_err(&client->dev,
+ "this driver does not support multiple clients");
+ err = -EBUSY;
+ goto exit_err_clean;
+ }
+
+ client_data = kzalloc(sizeof(struct bmi_client_data),
+ GFP_KERNEL);
+ if (NULL == client_data) {
+ dev_err(&client->dev, "no memory available");
+ err = -ENOMEM;
+ goto exit_err_clean;
+ }
+
+ client_data->device.bus_read = bmi_i2c_read_wrapper;
+ client_data->device.bus_write = bmi_i2c_write_wrapper;
+
+ return bmi_probe(client_data, &client->dev);
+
+exit_err_clean:
+ if (err)
+ bmi_client = NULL;
+ return err;
+}
+/*
+static int bmi_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+ int err = 0;
+ err = bmi_suspend(&client->dev);
+ return err;
+}
+
+static int bmi_i2c_resume(struct i2c_client *client)
+{
+ int err = 0;
+
+ err = bmi_resume(&client->dev);
+
+ return err;
+}
+*/
+
+static int bmi_i2c_remove(struct i2c_client *client)
+{
+ int err = 0;
+ err = bmi_remove(&client->dev);
+ bmi_client = NULL;
+
+ return err;
+}
+
+
+
+static const struct i2c_device_id bmi_id[] = {
+ {SENSOR_NAME, 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, bmi_id);
+
+static const struct of_device_id bmi160_of_match[] = {
+ { .compatible = "bosch-sensortec,bmi160", },
+ { .compatible = "bmi160", },
+ { .compatible = "bosch, bmi160", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, bmi160_of_match);
+
+static struct i2c_driver bmi_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = SENSOR_NAME,
+ .of_match_table = bmi160_of_match,
+ },
+ .class = I2C_CLASS_HWMON,
+ .id_table = bmi_id,
+ .probe = bmi_i2c_probe,
+ .remove = bmi_i2c_remove,
+ /*.suspend = bmi_i2c_suspend,
+ .resume = bmi_i2c_resume,*/
+};
+
+static int __init BMI_i2c_init(void)
+{
+ return i2c_add_driver(&bmi_i2c_driver);
+}
+
+static void __exit BMI_i2c_exit(void)
+{
+ i2c_del_driver(&bmi_i2c_driver);
+}
+
+MODULE_AUTHOR("Contact <contact@bosch-sensortec.com>");
+MODULE_DESCRIPTION("driver for " SENSOR_NAME);
+MODULE_LICENSE("GPL v2");
+
+module_init(BMI_i2c_init);
+module_exit(BMI_i2c_exit);
+
diff --git a/drivers/input/sensors/bmi160/bmi160_spi.c b/drivers/input/sensors/bmi160/bmi160_spi.c
new file mode 100644
index 0000000..8da1e21
--- /dev/null
+++ b/drivers/input/sensors/bmi160/bmi160_spi.c
@@ -0,0 +1,299 @@
+/*!
+ * @section LICENSE
+ * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved
+ *
+ * This software program is licensed subject to the GNU General
+ * Public License (GPL).Version 2,June 1991,
+ * available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * @filename bmi160_spi.c
+ * @date 2014/11/25 14:40
+ * @id "20f77db"
+ * @version 1.3
+ *
+ * @brief
+ * This file implements moudle function, which add
+ * the driver to SPI core.
+*/
+
+#include <linux/module.h>
+#include <linux/spi/spi.h>
+#include <linux/delay.h>
+#include "bmi160_driver.h"
+
+/*! @defgroup bmi160_spi_src
+ * @brief bmi160 spi driver module
+ @{*/
+/*! the maximum of transfer buffer size */
+#define BMI_MAX_BUFFER_SIZE 32
+
+static struct spi_device *bmi_spi_client;
+
+/*!
+ * @brief define spi wirte function
+ *
+ * @param dev_addr sensor device address
+ * @param reg_addr register address
+ * @param data the pointer of data buffer
+ * @param len block size need to write
+ *
+ * @return zero success, non-zero failed
+ * @retval zero success
+ * @retval non-zero failed
+*/
+static char bmi_spi_write_block(u8 dev_addr, u8 reg_addr, u8 *data, u8 len)
+{
+ struct spi_device *client = bmi_spi_client;
+ u8 buffer[BMI_MAX_BUFFER_SIZE + 1];
+ struct spi_transfer xfer = {
+ .tx_buf = buffer,
+ .len = len + 1,
+ };
+ struct spi_message msg;
+
+ if (len > BMI_MAX_BUFFER_SIZE)
+ return -EINVAL;
+
+ buffer[0] = reg_addr&0x7F;/* write: MSB = 0 */
+ memcpy(&buffer[1], data, len);
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ return spi_sync(client, &msg);
+}
+
+/*!
+ * @brief define spi read function
+ *
+ * @param dev_addr sensor device address
+ * @param reg_addr register address
+ * @param data the pointer of data buffer
+ * @param len block size need to read
+ *
+ * @return zero success, non-zero failed
+ * @retval zero success
+ * @retval non-zero failed
+*/
+static char bmi_spi_read_block(u8 dev_addr, u8 reg_addr, u8 *data, u8 len)
+{
+ struct spi_device *client = bmi_spi_client;
+ u8 reg = reg_addr | 0x80;/* read: MSB = 1 */
+ struct spi_transfer xfer[2] = {
+ [0] = {
+ .tx_buf = ®,
+ .len = 1,
+ },
+ [1] = {
+ .rx_buf = data,
+ .len = len,
+ }
+ };
+ struct spi_message msg;
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer[0], &msg);
+ spi_message_add_tail(&xfer[1], &msg);
+ return spi_sync(client, &msg);
+}
+
+s8 bmi_burst_read_wrapper(u8 dev_addr, u8 reg_addr, u8 *data, u16 len)
+{
+ struct spi_device *client = bmi_spi_client;
+ u8 reg = reg_addr | 0x80;/* read: MSB = 1 */
+ struct spi_transfer xfer[2] = {
+ [0] = {
+ .tx_buf = ®,
+ .len = 1,
+ },
+ [1] = {
+ .rx_buf = data,
+ .len = len,
+ }
+ };
+ struct spi_message msg;
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer[0], &msg);
+ spi_message_add_tail(&xfer[1], &msg);
+ return spi_sync(client, &msg);
+}
+EXPORT_SYMBOL(bmi_burst_read_wrapper);
+/*!
+ * @brief BMI probe function via spi bus
+ *
+ * @param client the pointer of spi client
+ *
+ * @return zero success, non-zero failed
+ * @retval zero success
+ * @retval non-zero failed
+*/
+static int bmi_spi_probe(struct spi_device *client)
+{
+ int status;
+ int err = 0;
+ struct bmi_client_data *client_data = NULL;
+
+ if (NULL == bmi_spi_client)
+ bmi_spi_client = client;
+ else{
+ dev_err(&client->dev, "This driver does not support multiple clients!\n");
+ return -EBUSY;
+ }
+
+ client->bits_per_word = 8;
+ status = spi_setup(client);
+ if (status < 0) {
+ dev_err(&client->dev, "spi_setup failed!\n");
+ return status;
+ }
+
+ client_data = kzalloc(sizeof(struct bmi_client_data), GFP_KERNEL);
+ if (NULL == client_data) {
+ dev_err(&client->dev, "no memory available");
+ err = -ENOMEM;
+ goto exit_err_clean;
+ }
+
+ client_data->device.bus_read = bmi_spi_read_block;
+ client_data->device.bus_write = bmi_spi_write_block;
+
+ return bmi_probe(client_data, &client->dev);
+
+exit_err_clean:
+ if (err)
+ bmi_spi_client = NULL;
+ return err;
+}
+
+/*!
+ * @brief shutdown bmi device in spi driver
+ *
+ * @param client the pointer of spi client
+ *
+ * @return no return value
+*/
+static void bmi_spi_shutdown(struct spi_device *client)
+{
+#ifdef CONFIG_PM
+ bmi_suspend(&client->dev);
+#endif
+}
+
+/*!
+ * @brief remove bmi spi client
+ *
+ * @param client the pointer of spi client
+ *
+ * @return zero
+ * @retval zero
+*/
+static int bmi_spi_remove(struct spi_device *client)
+{
+ int err = 0;
+ err = bmi_remove(&client->dev);
+ bmi_spi_client = NULL;
+
+ return err;
+}
+
+#ifdef CONFIG_PM
+/*!
+ * @brief suspend bmi device in spi driver
+ *
+ * @param dev the pointer of device
+ *
+ * @return zero
+ * @retval zero
+*/
+static int bmi_spi_suspend(struct device *dev)
+{
+ int err = 0;
+ err = bmi_suspend(dev);
+ return err;
+}
+
+/*!
+ * @brief resume bmi device in spi driver
+ *
+ * @param dev the pointer of device
+ *
+ * @return zero
+ * @retval zero
+*/
+static int bmi_spi_resume(struct device *dev)
+{
+ int err = 0;
+ /* post resume operation */
+ err = bmi_resume(dev);
+
+ return err;
+}
+
+/*!
+ * @brief register spi device power manager hooks
+*/
+static const struct dev_pm_ops bmi_spi_pm_ops = {
+ /**< device suspend */
+ .suspend = bmi_spi_suspend,
+ /**< device resume */
+ .resume = bmi_spi_resume
+};
+#endif
+
+/*!
+ * @brief register spi device id
+*/
+static const struct spi_device_id bmi_id[] = {
+ { SENSOR_NAME, 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(spi, bmi_id);
+
+/*!
+ * @brief register spi driver hooks
+*/
+static struct spi_driver bmi_spi_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = SENSOR_NAME,
+#ifdef CONFIG_PM
+ .pm = &bmi_spi_pm_ops,
+#endif
+ },
+ .id_table = bmi_id,
+ .probe = bmi_spi_probe,
+ .shutdown = bmi_spi_shutdown,
+ .remove = bmi_spi_remove
+};
+
+/*!
+ * @brief initialize bmi spi module
+ *
+ * @return zero success, non-zero failed
+ * @retval zero success
+ * @retval non-zero failed
+*/
+static int __init bmi_spi_init(void)
+{
+ return spi_register_driver(&bmi_spi_driver);
+}
+
+/*!
+ * @brief remove bmi spi module
+ *
+ * @return no return value
+*/
+static void __exit bmi_spi_exit(void)
+{
+ spi_unregister_driver(&bmi_spi_driver);
+}
+
+
+MODULE_AUTHOR("Contact <contact@bosch-sensortec.com>");
+MODULE_DESCRIPTION("BMI160 SPI DRIVER");
+MODULE_LICENSE("GPL v2");
+
+module_init(bmi_spi_init);
+module_exit(bmi_spi_exit);
+/*@}*/
+
diff --git a/drivers/input/sensors/bmi160/bs_log.c b/drivers/input/sensors/bmi160/bs_log.c
new file mode 100644
index 0000000..6574607
--- /dev/null
+++ b/drivers/input/sensors/bmi160/bs_log.c
@@ -0,0 +1,50 @@
+/*!
+ * @section LICENSE
+ * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved
+ *
+ * This software program is licensed subject to the GNU General
+ * Public License (GPL).Version 2,June 1991,
+ * available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * @filename bs_log.c
+ * @date "Wed Sep 24 15:27:12 2014 +0800"
+ * @id "e416c14"
+ *
+ * @brief
+ * The source file of BOSCH SENSOR LOG
+*/
+
+
+#ifdef __KERNEL__
+#include <linux/kernel.h>
+#include <linux/unistd.h>
+#include <linux/types.h>
+#else
+#include <unistd.h>
+#include <sys/types.h>
+#endif
+
+#include <linux/time.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#ifdef BOSCH_DRIVER_LOG_FUNC
+#define BSLOG_VAR_DEF
+#include "bs_log.h"
+
+void set_debug_log_level(uint8_t level)
+{
+ debug_log_level = level;
+}
+
+uint8_t get_debug_log_level(void)
+{
+ return debug_log_level;
+}
+
+EXPORT_SYMBOL(set_debug_log_level);
+EXPORT_SYMBOL(get_debug_log_level);
+
+#endif/*BOSCH_DRIVER_LOG_FUNC*/
+/*@}*/
diff --git a/drivers/input/sensors/bmi160/bs_log.h b/drivers/input/sensors/bmi160/bs_log.h
new file mode 100644
index 0000000..ed2d2b3
--- /dev/null
+++ b/drivers/input/sensors/bmi160/bs_log.h
@@ -0,0 +1,171 @@
+/*!
+ * @section LICENSE
+ * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved
+ *
+ * This software program is licensed subject to the GNU General
+ * Public License (GPL).Version 2,June 1991,
+ * available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * @filename bs_log.h
+ * @date "Sat Oct 11 16:12:16 2014 +0800"
+ * @id "762cc9e"
+ *
+ * @brief
+ * The head file of BOSCH SENSOR LOG
+*/
+
+#ifndef __BS_LOG_H
+#define __BS_LOG_H
+
+#include <linux/kernel.h>
+
+/*! @ trace functions
+ @{*/
+/*! ERROR LOG LEVEL */
+#define LOG_LEVEL_E 3
+/*! NOTICE LOG LEVEL */
+#define LOG_LEVEL_N 5
+/*! INFORMATION LOG LEVEL */
+#define LOG_LEVEL_I 6
+/*! DEBUG LOG LEVEL */
+#define LOG_LEVEL_D 7
+/*! DEBUG_FWDL LOG LEVEL */
+#define LOG_LEVEL_DF 10
+/*! DEBUG_DATA LOG LEVEL */
+#define LOG_LEVEL_DA 15
+/*! ALL LOG LEVEL */
+#define LOG_LEVEL_A 20
+
+#ifndef MODULE_TAG
+/*! MODULE TAG DEFINATION */
+#define MODULE_TAG "<BS_LOG>"
+#endif
+
+#ifndef LOG_LEVEL
+/*! LOG LEVEL DEFINATION */
+#define LOG_LEVEL LOG_LEVEL_I
+#endif
+
+#ifdef BOSCH_DRIVER_LOG_FUNC
+ #ifdef BSLOG_VAR_DEF
+ uint8_t debug_log_level = LOG_LEVEL;
+ #else
+ extern uint8_t debug_log_level;
+ #endif
+
+ /*! print error message */
+ #define PERR(fmt, args...) do\
+ {\
+ if (debug_log_level >= LOG_LEVEL_E)\
+ printk(KERN_INFO "\n" "[E]" KERN_ERR MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args);\
+ } while (0)
+
+ /*! print notice message */
+ #define PNOTICE(fmt, args...) do\
+ {\
+ if (debug_log_level >= LOG_LEVEL_N)\
+ printk(KERN_INFO "\n" "[N]" KERN_NOTICE MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args);\
+ } while (0)
+
+ /*! print information message */
+ #define PINFO(fmt, args...) do\
+ {\
+ if (debug_log_level >= LOG_LEVEL_I)\
+ printk(KERN_INFO "\n" "[I]" KERN_INFO MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args);\
+ } while (0)
+
+ /*! print debug message */
+ #define PDEBUG(fmt, args...) do\
+ {\
+ if (debug_log_level >= LOG_LEVEL_D)\
+ printk(KERN_INFO "\n" "[D]" KERN_DEBUG MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args);\
+ } while (0)
+
+ /*! print debug fw download message */
+ #define PDEBUG_FWDL(fmt, args...) do\
+ {\
+ if (debug_log_level >= LOG_LEVEL_DF)\
+ printk(KERN_INFO "\n" "[DF]" KERN_DEBUG MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args);\
+ } while (0)
+
+ /*! print debug data log message */
+ #define PDEBUG_DLOG(fmt, args...) do\
+ {\
+ if (debug_log_level >= LOG_LEVEL_DA)\
+ printk(KERN_INFO "\n" "[DA]" KERN_DEBUG MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args);\
+ } while (0)
+
+ void set_debug_log_level(uint8_t level);
+ uint8_t get_debug_log_level(void);
+
+#else
+
+ #if (LOG_LEVEL >= LOG_LEVEL_E)
+ /*! print error message */
+ #define PERR(fmt, args...) \
+ printk(KERN_INFO "\n" "[E]" KERN_ERR MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args)
+ #else
+ /*! invalid message */
+ #define PERR(fmt, args...)
+ #endif
+
+ #if (LOG_LEVEL >= LOG_LEVEL_N)
+ /*! print notice message */
+ #define PNOTICE(fmt, args...) \
+ printk(KERN_INFO "\n" "[N]" KERN_NOTICE MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args)
+ #else
+ /*! invalid message */
+ #define PNOTICE(fmt, args...)
+ #endif
+
+ #if (LOG_LEVEL >= LOG_LEVEL_I)
+ /*! print information message */
+ #define PINFO(fmt, args...) printk(KERN_INFO "\n" "[I]" KERN_INFO MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args)
+ #else
+ /*! invalid message */
+ #define PINFO(fmt, args...)
+ #endif
+
+ #if (LOG_LEVEL >= LOG_LEVEL_D)
+ /*! print debug message */
+ #define PDEBUG(fmt, args...) printk(KERN_INFO "\n" "[D]" KERN_DEBUG MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args)
+ #else
+ /*! invalid message */
+ #define PDEBUG(fmt, args...)
+ #endif
+
+ #if (LOG_LEVEL >= LOG_LEVEL_DF)
+ /*! print debug fw download message */
+ #define PDEBUG_FWDL(fmt, args...) printk(KERN_INFO "\n" "[DF]" KERN_DEBUG MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args)
+ #else
+ /*! invalid message */
+ #define PDEBUG_FWDL(fmt, args...)
+ #endif
+
+ #if (LOG_LEVEL >= LOG_LEVEL_DA)
+ /*! print debug data log message */
+ #define PDEBUG_DLOG(fmt, args...) printk(KERN_INFO "\n" "[DA]" KERN_DEBUG MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args)
+ #else
+ /*! invalid message */
+ #define PDEBUG_DLOG(fmt, args...)
+ #endif
+
+ #define set_debug_log_level(level) {}
+ #define get_debug_log_level() (LOG_LEVEL)
+
+#endif
+
+#endif/*__BS_LOG_H*/
+/*@}*/
diff --git a/drivers/input/sensors/bmi160/bstclass.c b/drivers/input/sensors/bmi160/bstclass.c
new file mode 100644
index 0000000..4937cca
--- /dev/null
+++ b/drivers/input/sensors/bmi160/bstclass.c
@@ -0,0 +1,238 @@
+/*!
+ * @section LICENSE
+ * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved
+ *
+ * This software program is licensed subject to the GNU General
+ * Public License (GPL).Version 2,June 1991,
+ * available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * @filename bstclass.c
+ * @date 2015/11/17 13:44
+ * @id "836294d"
+ * @version 1.5.9
+ *
+ * @brief
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+#include <linux/poll.h>
+#include <linux/mutex.h>
+#include <linux/rcupdate.h>
+#include <linux/compiler.h>
+#include <linux/compat.h>
+#include "bstclass.h"
+#include "bs_log.h"
+
+static LIST_HEAD(bst_dev_list);
+
+/*
+ * bst_mutex protects access to both bst_dev_list and input_handler_list.
+ * This also causes bst_[un]register_device and bst_[un]register_handler
+ * be mutually exclusive which simplifies locking in drivers implementing
+ * input handlers.
+ */
+static DEFINE_MUTEX(bst_mutex);
+
+
+static void bst_dev_release(struct device *device)
+{
+ struct bst_dev *dev = to_bst_dev(device);
+ if (NULL != dev)
+ kfree(dev);
+ module_put(THIS_MODULE);
+}
+
+
+#ifdef CONFIG_PM
+static int bst_dev_suspend(struct device *dev)
+{
+ return 0;
+}
+
+static int bst_dev_resume(struct device *dev)
+{
+ return 0;
+}
+
+static const struct dev_pm_ops bst_dev_pm_ops = {
+ .suspend = bst_dev_suspend,
+ .resume = bst_dev_resume,
+ .poweroff = bst_dev_suspend,
+ .restore = bst_dev_resume,
+};
+#endif /* CONFIG_PM */
+
+static const struct attribute_group *bst_dev_attr_groups[] = {
+ NULL
+};
+
+static struct device_type bst_dev_type = {
+ .groups = bst_dev_attr_groups,
+ .release = bst_dev_release,
+#ifdef CONFIG_PM
+ .pm = &bst_dev_pm_ops,
+#endif
+};
+
+
+
+static char *bst_devnode(struct device *dev, mode_t *mode)
+{
+ return kasprintf(GFP_KERNEL, "%s", dev_name(dev));
+}
+
+struct class bst_class = {
+ .name = "bst",
+ .owner = THIS_MODULE,
+ .devnode = (void*)bst_devnode,
+ .dev_release = bst_dev_release,
+};
+EXPORT_SYMBOL_GPL(bst_class);
+
+/**
+ * bst_allocate_device - allocate memory for new input device
+ *
+ * Returns prepared struct bst_dev or NULL.
+ *
+ * NOTE: Use bst_free_device() to free devices that have not been
+ * registered; bst_unregister_device() should be used for already
+ * registered devices.
+ */
+struct bst_dev *bst_allocate_device(void)
+{
+ struct bst_dev *dev;
+
+ dev = kzalloc(sizeof(struct bst_dev), GFP_KERNEL);
+ if (dev) {
+ dev->dev.type = &bst_dev_type;
+ dev->dev.class = &bst_class;
+ device_initialize(&dev->dev);
+ mutex_init(&dev->mutex);
+ INIT_LIST_HEAD(&dev->node);
+ __module_get(THIS_MODULE);
+ }
+ return dev;
+}
+EXPORT_SYMBOL(bst_allocate_device);
+
+
+
+/**
+ * bst_free_device - free memory occupied by bst_dev structure
+ * @dev: input device to free
+ *
+ * This function should only be used if bst_register_device()
+ * was not called yet or if it failed. Once device was registered
+ * use bst_unregister_device() and memory will be freed once last
+ * reference to the device is dropped.
+ *
+ * Device should be allocated by bst_allocate_device().
+ *
+ * NOTE: If there are references to the input device then memory
+ * will not be freed until last reference is dropped.
+ */
+void bst_free_device(struct bst_dev *dev)
+{
+ if (dev)
+ bst_put_device(dev);
+}
+EXPORT_SYMBOL(bst_free_device);
+
+/**
+ * bst_register_device - register device with input core
+ * @dev: device to be registered
+ *
+ * This function registers device with input core. The device must be
+ * allocated with bst_allocate_device() and all it's capabilities
+ * set up before registering.
+ * If function fails the device must be freed with bst_free_device().
+ * Once device has been successfully registered it can be unregistered
+ * with bst_unregister_device(); bst_free_device() should not be
+ * called in this case.
+ */
+int bst_register_device(struct bst_dev *dev)
+{
+ const char *path;
+ int error;
+
+
+ /*
+ * If delay and period are pre-set by the driver, then autorepeating
+ * is handled by the driver itself and we don't do it in input.c.
+ */
+ dev_set_name(&dev->dev, dev->name);
+
+ error = device_add(&dev->dev);
+ if (error)
+ return error;
+
+ path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
+ PINFO("%s as %s\n",
+ dev->name ? dev->name : "Unspecified device",
+ path ? path : "N/A");
+ kfree(path);
+ error = mutex_lock_interruptible(&bst_mutex);
+ if (error) {
+ device_del(&dev->dev);
+ return error;
+ }
+
+ list_add_tail(&dev->node, &bst_dev_list);
+
+ mutex_unlock(&bst_mutex);
+ return 0;
+}
+EXPORT_SYMBOL(bst_register_device);
+
+/**
+ * bst_unregister_device - unregister previously registered device
+ * @dev: device to be unregistered
+ *
+ * This function unregisters an input device. Once device is unregistered
+ * the caller should not try to access it as it may get freed at any moment.
+ */
+void bst_unregister_device(struct bst_dev *dev)
+{
+ int ret = 0;
+ ret = mutex_lock_interruptible(&bst_mutex);
+ if(ret){
+ return;
+ }
+
+ list_del_init(&dev->node);
+ mutex_unlock(&bst_mutex);
+ device_unregister(&dev->dev);
+}
+EXPORT_SYMBOL(bst_unregister_device);
+
+static int __init bst_init(void)
+{
+ int err;
+ /*bst class register*/
+ err = class_register(&bst_class);
+ if (err) {
+ pr_err("unable to register bst_dev class\n");
+ return err;
+ }
+ return err;
+}
+
+static void __exit bst_exit(void)
+{
+ /*bst class*/
+ class_unregister(&bst_class);
+}
+
+/*subsys_initcall(bst_init);*/
+
+MODULE_AUTHOR("contact@bosch-sensortec.com");
+MODULE_DESCRIPTION("BST CLASS CORE");
+MODULE_LICENSE("GPL V2");
+
+module_init(bst_init);
+module_exit(bst_exit);
diff --git a/drivers/input/sensors/bmi160/bstclass.h b/drivers/input/sensors/bmi160/bstclass.h
new file mode 100644
index 0000000..7aa7760
--- /dev/null
+++ b/drivers/input/sensors/bmi160/bstclass.h
@@ -0,0 +1,78 @@
+/*!
+ * @section LICENSE
+ * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved
+ *
+ * This software program is licensed subject to the GNU General
+ * Public License (GPL).Version 2,June 1991,
+ * available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * @filename bstcalss.h
+ * @date 2015/11/17 13:44
+ * @id "836294d"
+ * @version 1.5.9
+ *
+ * @brief
+ */
+
+#ifndef _BSTCLASS_H
+#define _BSTCLASS_H
+
+#ifdef __KERNEL__
+#include <linux/time.h>
+#include <linux/list.h>
+#else
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <linux/types.h>
+#endif
+
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/mod_devicetable.h>
+
+struct bst_dev {
+ const char *name;
+
+ int (*open)(struct bst_dev *dev);
+ void (*close)(struct bst_dev *dev);
+ struct mutex mutex;
+ struct device dev;
+ struct list_head node;
+};
+
+#define to_bst_dev(d) container_of(d, struct bst_dev, dev)
+
+struct bst_dev *bst_allocate_device(void);
+void bst_free_device(struct bst_dev *dev);
+
+static inline struct bst_dev *bst_get_device(struct bst_dev *dev)
+{
+ return dev ? to_bst_dev(get_device(&dev->dev)) : NULL;
+}
+
+static inline void bst_put_device(struct bst_dev *dev)
+{
+ if (dev)
+ put_device(&dev->dev);
+}
+
+static inline void *bst_get_drvdata(struct bst_dev *dev)
+{
+ return dev_get_drvdata(&dev->dev);
+}
+
+static inline void bst_set_drvdata(struct bst_dev *dev, void *data)
+{
+ dev_set_drvdata(&dev->dev, data);
+}
+
+int __must_check bst_register_device(struct bst_dev *);
+void bst_unregister_device(struct bst_dev *);
+
+void bst_reset_device(struct bst_dev *);
+
+
+extern struct class bst_class;
+
+#endif
diff --git a/drivers/input/sensors/smi130/Kconfig b/drivers/input/sensors/smi130/Kconfig
new file mode 100644
index 0000000..0dd0b39
--- /dev/null
+++ b/drivers/input/sensors/smi130/Kconfig
@@ -0,0 +1,121 @@
+#
+# Makefile for Bosch sensors driver.
+#
+config BOSCH_DRIVER_LOG_FUNC
+ tristate "Bosch Sensortec driver smart log function support"
+ depends on (I2C || SPI_MASTER) && SYSFS
+ help
+ If you say yes here, you get support for smart log function in Bosch Sensortec driver.
+
+config SENSORS_SMI_ACC2X2
+ tristate "SMI130_ACC acceleration sensor support"
+ depends on I2C
+ help
+ If you say yes here, you get support for Bosch Sensortec's
+ acceleration sensors SMI_ACC255/SMI_ACC254/SMI_ACC355/SMI_ACC250E/SMI_ACC222E/SMI_ACC280.
+
+config SENSORS_SMI_ACC2X2_ENABLE_INT1
+ tristate "SMI_ACC2X2 acceleration sensor interrupt INT1 support"
+ depends on SENSORS_SMI_ACC2X2
+ help
+ If you say yes here, you get INT1 support for Bosch Sensortec
+ acceleration sensors SMI_ACC255/SMI_ACC250E/SMI_ACC222E/SMI_ACC280.
+ Select it will disable interrupt INT2 support
+
+config SENSORS_SMI_ACC2X2_ENABLE_INT2
+ tristate "SMI_ACC2X2 acceleration sensor interrupt INT2 support"
+ depends on SENSORS_SMI_ACC2X2 && !SENSORS_SMI_ACC2X2_ENABLE_INT1
+ help
+ If you say yes here, you get INT2 support for Bosch Sensortec
+ acceleration sensors SMI_ACC255/SMI_ACC250E/SMI_ACC222E/SMI_ACC280.
+ Can only open if you do NOT open interrupt INT1 support
+
+config SIG_MOTION
+ tristate "support significant motion sensor function"
+ depends on SENSORS_SMI_ACC2X2 && ( SENSORS_SMI_ACC2X2_ENABLE_INT1 || SENSORS_SMI_ACC2X2_ENABLE_INT2)
+ help
+ If you say yes here, if you want to support Bosch significant motion sensor function
+
+config DOUBLE_TAP
+ tristate "support double tap sensor function"
+ depends on SENSORS_SMI_ACC2X2 && ( SENSORS_SMI_ACC2X2_ENABLE_INT1 || SENSORS_SMI_ACC2X2_ENABLE_INT2)
+ help
+ If you say yes here, you get support Bosch double tap sensor function
+
+config SENSORS_SMI_GYRO
+ tristate "Bosch Gyroscope Sensor Driver"
+ depends on I2C
+ help
+ If you say yes here, you get support for Bosch Sensortec's
+ gyroscope sensor drivers of SMI130_GYRO/SMI055/BMI058 e.t.c.
+
+config SENSORS_SMI_GYRO_FIFO
+ tristate "Bosch Gyroscope FIFO Support"
+ depends on SENSORS_SMI_GYRO
+ help
+ If you say yes here, you get support for Gyroscope sensor FIFO operations.
+ Please check whether the chip supports fifo feature to open it.
+
+config SENSORS_BMI058
+ tristate "BMI058 Sensor Support"
+ depends on (SENSORS_SMI_GYRO || SENSORS_SMI_ACC2X2)
+ help
+ If you say yes here, you get support for Bosch Sensortec's
+ sensor driver of BMI058.
+
+config SENSORS_YAS537
+ tristate "YAS537 Magnetic Sensor Driver"
+ depends on I2C
+ help
+ If you say yes here, you get support for YAMAHA
+ sensor YAS537 Magnetic Sensor
+
+config SENSORS_BMM050
+ tristate "BMM050 Magnetic Sensor Driver"
+ depends on I2C
+ help
+ If you say yes here, you get support for Bosch Sensortec's
+ sensor BMM050 Magnetic Sensor
+
+config SENSORS_AKM09911
+ tristate "AKM09911 Mag Sensor Driver"
+ depends on I2C
+ help
+ If you say yes here, you get support AKM09911 Sensor support.
+
+config SENSORS_AKM09912
+ tristate "AKM09912 Mag Sensor Driver"
+ depends on I2C
+ help
+ If you say yes here, you get support AKM09912 Sensor support.
+
+config SENSORS_SMI_ACC420
+ tristate "SMI_ACC4XY Sensor Support"
+ depends on I2C || SPI_MASTER
+ help
+ If you say yes here, you get support for Bosch Sensortec's sensor driver of SMI_ACC420.
+config SENSORS_SMI_ACC421
+ tristate "SMI_ACC4XY Sensor Support"
+ depends on I2C || SPI_MASTER
+ help
+ If you say yes here, you get support for Bosch Sensortec's sensor driver of SMI_ACC421.
+config SENSORS_SMI_ACC422
+ tristate "SMI_ACC4XY Sensor Support"
+ depends on I2C || SPI_MASTER
+ help
+ If you say yes here, you get support for Bosch Sensortec's sensor driver of SMI_ACC422.
+config SENSORS_SMI_ACC455
+ tristate "SMI_ACC4XY Sensor Support"
+ depends on I2C || SPI_MASTER
+ help
+ If you say yes here, you get support for Bosch Sensortec's sensor driver of SMI_ACC455.
+
+config SMI_ACC4XY_MAG_INTERFACE_SUPPORT
+tristate "SMI_ACC4XY Sensor mag interface support"
+depends on SENSORS_SMI_ACC4XY
+ help
+ If you say yes here, you get support for Bosch Sensortec's
+ sensor driver of SMI_ACC4XY with mag sensor support.
+
+
+
diff --git a/drivers/input/sensors/smi130/Makefile b/drivers/input/sensors/smi130/Makefile
new file mode 100644
index 0000000..ad1e543
--- /dev/null
+++ b/drivers/input/sensors/smi130/Makefile
@@ -0,0 +1,47 @@
+#
+# Makefile for Bosch sensor driver.
+#
+
+obj-$(CONFIG_BOSCH_DRIVER_LOG_FUNC) += bs_log.o
+obj-y += boschclass.o
+ifeq ($(CONFIG_BOSCH_DRIVER_LOG_FUNC),y)
+ EXTRA_CFLAGS += -DBOSCH_DRIVER_LOG_FUNC
+endif
+
+obj-y += smi130_acc.o
+
+ifeq ($(CONFIG_SENSORS_SMI_ACC2X2_ENABLE_INT1),y)
+ EXTRA_CFLAGS += -DSMI_ACC2X2_ENABLE_INT1
+endif
+
+ifeq ($(CONFIG_BOSCH_SMI_ACC2X2_ENABLE_INT2),y)
+ EXTRA_CFLAGS += -DSMI_ACC2X2_ENABLE_INT2
+endif
+
+obj-y += smi130_gyro_driver.o smi130_gyro.o
+EXTRA_CFLAGS += -DSMI_GYRO_USE_BASIC_I2C_FUNC
+
+obj-y += smi130_driver.o smi130.o
+ifeq ($(CONFIG_SMI130_MAG_INTERFACE_SUPPORT),y)
+ EXTRA_CFLAGS += -DSMI130_MAG_INTERFACE_SUPPORT
+endif
+ifeq ($(CONFIG_SENSORS_SMI130_ENABLE_INT1),y)
+ EXTRA_CFLAGS += -DSMI130_ENABLE_INT1
+endif
+
+ifeq ($(CONFIG_SENSORS_SMI130_ENABLE_INT2),y)
+ EXTRA_CFLAGS += -DSMI130_ENABLE_INT2
+endif
+
+obj-y += smi130_i2c.o
+
+EXTRA_CFLAGS += -DSMI_USE_BASIC_I2C_FUNC
+
+obj-$(CONFIG_SENSORS_SMI130_SPI) += smi130_spi.o
+
+
+
+
+
+
+
diff --git a/drivers/input/sensors/smi130/boschclass.c b/drivers/input/sensors/smi130/boschclass.c
new file mode 100644
index 0000000..8c28ab1
--- /dev/null
+++ b/drivers/input/sensors/smi130/boschclass.c
@@ -0,0 +1,341 @@
+/*!
+ * @section LICENSE
+ * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved
+ *
+ * (C) Modification Copyright 2018 Robert Bosch Kft All Rights Reserved
+ *
+ * This software program is licensed subject to the GNU General
+ * Public License (GPL).Version 2,June 1991,
+ * available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * Special: Description of the Software:
+ *
+ * This software module (hereinafter called "Software") and any
+ * information on application-sheets (hereinafter called "Information") is
+ * provided free of charge for the sole purpose to support your application
+ * work.
+ *
+ * As such, the Software is merely an experimental software, not tested for
+ * safety in the field and only intended for inspiration for further development
+ * and testing. Any usage in a safety-relevant field of use (like automotive,
+ * seafaring, spacefaring, industrial plants etc.) was not intended, so there are
+ * no precautions for such usage incorporated in the Software.
+ *
+ * The Software is specifically designed for the exclusive use for Bosch
+ * Sensortec products by personnel who have special experience and training. Do
+ * not use this Software if you do not have the proper experience or training.
+ *
+ * This Software package is provided as is and without any expressed or
+ * implied warranties, including without limitation, the implied warranties of
+ * merchantability and fitness for a particular purpose.
+ *
+ * Bosch Sensortec and their representatives and agents deny any liability for
+ * the functional impairment of this Software in terms of fitness, performance
+ * and safety. Bosch Sensortec and their representatives and agents shall not be
+ * liable for any direct or indirect damages or injury, except as otherwise
+ * stipulated in mandatory applicable law.
+ * The Information provided is believed to be accurate and reliable. Bosch
+ * Sensortec assumes no responsibility for the consequences of use of such
+ * Information nor for any infringement of patents or other rights of third
+ * parties which may result from its use.
+ *
+ *------------------------------------------------------------------------------
+ * The following Product Disclaimer does not apply to the BSX4-HAL-4.1NoFusion Software
+ * which is licensed under the Apache License, Version 2.0 as stated above.
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Product Disclaimer
+ *
+ * Common:
+ *
+ * Assessment of Products Returned from Field
+ *
+ * Returned products are considered good if they fulfill the specifications /
+ * test data for 0-mileage and field listed in this document.
+ *
+ * Engineering Samples
+ *
+ * Engineering samples are marked with (e) or (E). Samples may vary from the
+ * valid technical specifications of the series product contained in this
+ * data sheet. Therefore, they are not intended or fit for resale to
+ * third parties or for use in end products. Their sole purpose is internal
+ * client testing. The testing of an engineering sample may in no way replace
+ * the testing of a series product. Bosch assumes no liability for the use
+ * of engineering samples. The purchaser shall indemnify Bosch from all claims
+ * arising from the use of engineering samples.
+ *
+ * Intended use
+ *
+ * Provided that SMI130 is used within the conditions (environment, application,
+ * installation, loads) as described in this TCD and the corresponding
+ * agreed upon documents, Bosch ensures that the product complies with
+ * the agreed properties. Agreements beyond this require
+ * the written approval by Bosch. The product is considered fit for the intended
+ * use when the product successfully has passed the tests
+ * in accordance with the TCD and agreed upon documents.
+ *
+ * It is the responsibility of the customer to ensure the proper application
+ * of the product in the overall system/vehicle.
+ *
+ * Bosch does not assume any responsibility for changes to the environment
+ * of the product that deviate from the TCD and the agreed upon documents
+ * as well as all applications not released by Bosch
+ *
+ * The resale and/or use of products are at the purchaser’s own risk and
+ * responsibility. The examination and testing of the SMI130
+ * is the sole responsibility of the purchaser.
+ *
+ * The purchaser shall indemnify Bosch from all third party claims
+ * arising from any product use not covered by the parameters of
+ * this product data sheet or not approved by Bosch and reimburse Bosch
+ * for all costs and damages in connection with such claims.
+ *
+ * The purchaser must monitor the market for the purchased products,
+ * particularly with regard to product safety, and inform Bosch without delay
+ * of all security relevant incidents.
+ *
+ * Application Examples and Hints
+ *
+ * With respect to any application examples, advice, normal values
+ * and/or any information regarding the application of the device,
+ * Bosch hereby disclaims any and all warranties and liabilities of any kind,
+ * including without limitation warranties of
+ * non-infringement of intellectual property rights or copyrights
+ * of any third party.
+ * The information given in this document shall in no event be regarded
+ * as a guarantee of conditions or characteristics. They are provided
+ * for illustrative purposes only and no evaluation regarding infringement
+ * of intellectual property rights or copyrights or regarding functionality,
+ * performance or error has been made.
+ *
+ * @filename boschclass.c
+ * @date 2015/11/17 13:44
+ * @Modification Date 2018/08/28 18:20
+ * @id "836294d"
+ * @version 1.5.9
+ *
+ * @brief
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+#include <linux/poll.h>
+#include <linux/mutex.h>
+#include <linux/rcupdate.h>
+#include <linux/compiler.h>
+#include <linux/compat.h>
+#include "boschclass.h"
+#include "bs_log.h"
+
+static LIST_HEAD(bosch_dev_list);
+
+/*
+ * bosch_mutex protects access to both bosch_dev_list and input_handler_list.
+ * This also causes bosch_[un]register_device and bosch_[un]register_handler
+ * be mutually exclusive which simplifies locking in drivers implementing
+ * input handlers.
+ */
+static DEFINE_MUTEX(bosch_mutex);
+
+
+static void bosch_dev_release(struct device *device)
+{
+ struct bosch_dev *dev = to_bosch_dev(device);
+ if (NULL != dev)
+ kfree(dev);
+ module_put(THIS_MODULE);
+}
+
+
+#ifdef CONFIG_PM
+static int bosch_dev_suspend(struct device *dev)
+{
+ return 0;
+}
+
+static int bosch_dev_resume(struct device *dev)
+{
+ return 0;
+}
+
+static const struct dev_pm_ops bosch_dev_pm_ops = {
+ .suspend = bosch_dev_suspend,
+ .resume = bosch_dev_resume,
+ .poweroff = bosch_dev_suspend,
+ .restore = bosch_dev_resume,
+};
+#endif /* CONFIG_PM */
+
+static const struct attribute_group *bosch_dev_attr_groups[] = {
+ NULL
+};
+
+static struct device_type bosch_dev_type = {
+ .groups = bosch_dev_attr_groups,
+ .release = bosch_dev_release,
+#ifdef CONFIG_PM
+ .pm = &bosch_dev_pm_ops,
+#endif
+};
+
+
+
+static char *bosch_devnode(struct device *dev, mode_t *mode)
+{
+ return kasprintf(GFP_KERNEL, "%s", dev_name(dev));
+}
+
+struct class bosch_class = {
+ .name = "bosch",
+ .owner = THIS_MODULE,
+ .devnode = (void*)bosch_devnode,
+ .dev_release = bosch_dev_release,
+};
+EXPORT_SYMBOL_GPL(bosch_class);
+
+/**
+ * bosch_allocate_device - allocate memory for new input device
+ *
+ * Returns prepared struct bosch_dev or NULL.
+ *
+ * NOTE: Use bosch_free_device() to free devices that have not been
+ * registered; bosch_unregister_device() should be used for already
+ * registered devices.
+ */
+struct bosch_dev *bosch_allocate_device(void)
+{
+ struct bosch_dev *dev;
+
+ dev = kzalloc(sizeof(struct bosch_dev), GFP_KERNEL);
+ if (dev) {
+ dev->dev.type = &bosch_dev_type;
+ dev->dev.class = &bosch_class;
+ device_initialize(&dev->dev);
+ mutex_init(&dev->mutex);
+ INIT_LIST_HEAD(&dev->node);
+ __module_get(THIS_MODULE);
+ }
+ return dev;
+}
+EXPORT_SYMBOL(bosch_allocate_device);
+
+
+
+/**
+ * bosch_free_device - free memory occupied by bosch_dev structure
+ * @dev: input device to free
+ *
+ * This function should only be used if bosch_register_device()
+ * was not called yet or if it failed. Once device was registered
+ * use bosch_unregister_device() and memory will be freed once last
+ * reference to the device is dropped.
+ *
+ * Device should be allocated by bosch_allocate_device().
+ *
+ * NOTE: If there are references to the input device then memory
+ * will not be freed until last reference is dropped.
+ */
+void bosch_free_device(struct bosch_dev *dev)
+{
+ if (dev)
+ bosch_put_device(dev);
+}
+EXPORT_SYMBOL(bosch_free_device);
+
+/**
+ * bosch_register_device - register device with input core
+ * @dev: device to be registered
+ *
+ * This function registers device with input core. The device must be
+ * allocated with bosch_allocate_device() and all it's capabilities
+ * set up before registering.
+ * If function fails the device must be freed with bosch_free_device().
+ * Once device has been successfully registered it can be unregistered
+ * with bosch_unregister_device(); bosch_free_device() should not be
+ * called in this case.
+ */
+int bosch_register_device(struct bosch_dev *dev)
+{
+ const char *path;
+ int error;
+
+
+ /*
+ * If delay and period are pre-set by the driver, then autorepeating
+ * is handled by the driver itself and we don't do it in input.c.
+ */
+ dev_set_name(&dev->dev, dev->name);
+
+ error = device_add(&dev->dev);
+ if (error)
+ return error;
+
+ path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
+ PINFO("%s as %s\n",
+ dev->name ? dev->name : "Unspecified device",
+ path ? path : "N/A");
+ kfree(path);
+ error = mutex_lock_interruptible(&bosch_mutex);
+ if (error) {
+ device_del(&dev->dev);
+ return error;
+ }
+
+ list_add_tail(&dev->node, &bosch_dev_list);
+
+ mutex_unlock(&bosch_mutex);
+ return 0;
+}
+EXPORT_SYMBOL(bosch_register_device);
+
+/**
+ * bosch_unregister_device - unregister previously registered device
+ * @dev: device to be unregistered
+ *
+ * This function unregisters an input device. Once device is unregistered
+ * the caller should not try to access it as it may get freed at any moment.
+ */
+void bosch_unregister_device(struct bosch_dev *dev)
+{
+ int ret = 0;
+ ret = mutex_lock_interruptible(&bosch_mutex);
+ if(ret){
+ return;
+ }
+
+ list_del_init(&dev->node);
+ mutex_unlock(&bosch_mutex);
+ device_unregister(&dev->dev);
+}
+EXPORT_SYMBOL(bosch_unregister_device);
+
+static int __init bosch_init(void)
+{
+ int err;
+ /*bosch class register*/
+ err = class_register(&bosch_class);
+ if (err) {
+ pr_err("unable to register bosch_dev class\n");
+ return err;
+ }
+ return err;
+}
+
+static void __exit bosch_exit(void)
+{
+ /*bosch class*/
+ class_unregister(&bosch_class);
+}
+
+/*subsys_initcall(bosch_init);*/
+
+MODULE_AUTHOR("contact@bosch-sensortec.com");
+MODULE_DESCRIPTION("BST CLASS CORE");
+MODULE_LICENSE("GPL V2");
+
+module_init(bosch_init);
+module_exit(bosch_exit);
diff --git a/drivers/input/sensors/smi130/boschclass.h b/drivers/input/sensors/smi130/boschclass.h
new file mode 100644
index 0000000..a89cc5d
--- /dev/null
+++ b/drivers/input/sensors/smi130/boschclass.h
@@ -0,0 +1,181 @@
+/*!
+ * @section LICENSE
+ * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved
+ *
+ * (C) Modification Copyright 2018 Robert Bosch Kft All Rights Reserved
+ *
+ * This software program is licensed subject to the GNU General
+ * Public License (GPL).Version 2,June 1991,
+ * available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * Special: Description of the Software:
+ *
+ * This software module (hereinafter called "Software") and any
+ * information on application-sheets (hereinafter called "Information") is
+ * provided free of charge for the sole purpose to support your application
+ * work.
+ *
+ * As such, the Software is merely an experimental software, not tested for
+ * safety in the field and only intended for inspiration for further development
+ * and testing. Any usage in a safety-relevant field of use (like automotive,
+ * seafaring, spacefaring, industrial plants etc.) was not intended, so there are
+ * no precautions for such usage incorporated in the Software.
+ *
+ * The Software is specifically designed for the exclusive use for Bosch
+ * Sensortec products by personnel who have special experience and training. Do
+ * not use this Software if you do not have the proper experience or training.
+ *
+ * This Software package is provided as is and without any expressed or
+ * implied warranties, including without limitation, the implied warranties of
+ * merchantability and fitness for a particular purpose.
+ *
+ * Bosch Sensortec and their representatives and agents deny any liability for
+ * the functional impairment of this Software in terms of fitness, performance
+ * and safety. Bosch Sensortec and their representatives and agents shall not be
+ * liable for any direct or indirect damages or injury, except as otherwise
+ * stipulated in mandatory applicable law.
+ * The Information provided is believed to be accurate and reliable. Bosch
+ * Sensortec assumes no responsibility for the consequences of use of such
+ * Information nor for any infringement of patents or other rights of third
+ * parties which may result from its use.
+ *
+ *------------------------------------------------------------------------------
+ * The following Product Disclaimer does not apply to the BSX4-HAL-4.1NoFusion Software
+ * which is licensed under the Apache License, Version 2.0 as stated above.
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Product Disclaimer
+ *
+ * Common:
+ *
+ * Assessment of Products Returned from Field
+ *
+ * Returned products are considered good if they fulfill the specifications /
+ * test data for 0-mileage and field listed in this document.
+ *
+ * Engineering Samples
+ *
+ * Engineering samples are marked with (e) or (E). Samples may vary from the
+ * valid technical specifications of the series product contained in this
+ * data sheet. Therefore, they are not intended or fit for resale to
+ * third parties or for use in end products. Their sole purpose is internal
+ * client testing. The testing of an engineering sample may in no way replace
+ * the testing of a series product. Bosch assumes no liability for the use
+ * of engineering samples. The purchaser shall indemnify Bosch from all claims
+ * arising from the use of engineering samples.
+ *
+ * Intended use
+ *
+ * Provided that SMI130 is used within the conditions (environment, application,
+ * installation, loads) as described in this TCD and the corresponding
+ * agreed upon documents, Bosch ensures that the product complies with
+ * the agreed properties. Agreements beyond this require
+ * the written approval by Bosch. The product is considered fit for the intended
+ * use when the product successfully has passed the tests
+ * in accordance with the TCD and agreed upon documents.
+ *
+ * It is the responsibility of the customer to ensure the proper application
+ * of the product in the overall system/vehicle.
+ *
+ * Bosch does not assume any responsibility for changes to the environment
+ * of the product that deviate from the TCD and the agreed upon documents
+ * as well as all applications not released by Bosch
+ *
+ * The resale and/or use of products are at the purchaser’s own risk and
+ * responsibility. The examination and testing of the SMI130
+ * is the sole responsibility of the purchaser.
+ *
+ * The purchaser shall indemnify Bosch from all third party claims
+ * arising from any product use not covered by the parameters of
+ * this product data sheet or not approved by Bosch and reimburse Bosch
+ * for all costs and damages in connection with such claims.
+ *
+ * The purchaser must monitor the market for the purchased products,
+ * particularly with regard to product safety, and inform Bosch without delay
+ * of all security relevant incidents.
+ *
+ * Application Examples and Hints
+ *
+ * With respect to any application examples, advice, normal values
+ * and/or any information regarding the application of the device,
+ * Bosch hereby disclaims any and all warranties and liabilities of any kind,
+ * including without limitation warranties of
+ * non-infringement of intellectual property rights or copyrights
+ * of any third party.
+ * The information given in this document shall in no event be regarded
+ * as a guarantee of conditions or characteristics. They are provided
+ * for illustrative purposes only and no evaluation regarding infringement
+ * of intellectual property rights or copyrights or regarding functionality,
+ * performance or error has been made.
+ *
+ * @filename boschcalss.h
+ * @date 2015/11/17 13:44
+ * @Modification Date 2018/08/28 18:20
+ * @id "836294d"
+ * @version 1.5.9
+ *
+ * @brief
+ */
+
+#ifndef _BSTCLASS_H
+#define _BSTCLASS_H
+
+#ifdef __KERNEL__
+#include <linux/time.h>
+#include <linux/list.h>
+#else
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <linux/types.h>
+#endif
+
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/mod_devicetable.h>
+
+struct bosch_dev {
+ const char *name;
+
+ int (*open)(struct bosch_dev *dev);
+ void (*close)(struct bosch_dev *dev);
+ struct mutex mutex;
+ struct device dev;
+ struct list_head node;
+};
+
+#define to_bosch_dev(d) container_of(d, struct bosch_dev, dev)
+
+struct bosch_dev *bosch_allocate_device(void);
+void bosch_free_device(struct bosch_dev *dev);
+
+static inline struct bosch_dev *bosch_get_device(struct bosch_dev *dev)
+{
+ return dev ? to_bosch_dev(get_device(&dev->dev)) : NULL;
+}
+
+static inline void bosch_put_device(struct bosch_dev *dev)
+{
+ if (dev)
+ put_device(&dev->dev);
+}
+
+static inline void *bosch_get_drvdata(struct bosch_dev *dev)
+{
+ return dev_get_drvdata(&dev->dev);
+}
+
+static inline void bosch_set_drvdata(struct bosch_dev *dev, void *data)
+{
+ dev_set_drvdata(&dev->dev, data);
+}
+
+int __must_check bosch_register_device(struct bosch_dev *);
+void bosch_unregister_device(struct bosch_dev *);
+
+void bosch_reset_device(struct bosch_dev *);
+
+
+extern struct class bosch_class;
+
+#endif
diff --git a/drivers/input/sensors/smi130/bs_log.c b/drivers/input/sensors/smi130/bs_log.c
new file mode 100644
index 0000000..05ddddd
--- /dev/null
+++ b/drivers/input/sensors/smi130/bs_log.c
@@ -0,0 +1,153 @@
+/*!
+ * @section LICENSE
+ * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved
+ *
+ * (C) Modification Copyright 2018 Robert Bosch Kft All Rights Reserved
+ *
+ * This software program is licensed subject to the GNU General
+ * Public License (GPL).Version 2,June 1991,
+ * available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * Special: Description of the Software:
+ *
+ * This software module (hereinafter called "Software") and any
+ * information on application-sheets (hereinafter called "Information") is
+ * provided free of charge for the sole purpose to support your application
+ * work.
+ *
+ * As such, the Software is merely an experimental software, not tested for
+ * safety in the field and only intended for inspiration for further development
+ * and testing. Any usage in a safety-relevant field of use (like automotive,
+ * seafaring, spacefaring, industrial plants etc.) was not intended, so there are
+ * no precautions for such usage incorporated in the Software.
+ *
+ * The Software is specifically designed for the exclusive use for Bosch
+ * Sensortec products by personnel who have special experience and training. Do
+ * not use this Software if you do not have the proper experience or training.
+ *
+ * This Software package is provided as is and without any expressed or
+ * implied warranties, including without limitation, the implied warranties of
+ * merchantability and fitness for a particular purpose.
+ *
+ * Bosch Sensortec and their representatives and agents deny any liability for
+ * the functional impairment of this Software in terms of fitness, performance
+ * and safety. Bosch Sensortec and their representatives and agents shall not be
+ * liable for any direct or indirect damages or injury, except as otherwise
+ * stipulated in mandatory applicable law.
+ * The Information provided is believed to be accurate and reliable. Bosch
+ * Sensortec assumes no responsibility for the consequences of use of such
+ * Information nor for any infringement of patents or other rights of third
+ * parties which may result from its use.
+ *
+ *------------------------------------------------------------------------------
+ * The following Product Disclaimer does not apply to the BSX4-HAL-4.1NoFusion Software
+ * which is licensed under the Apache License, Version 2.0 as stated above.
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Product Disclaimer
+ *
+ * Common:
+ *
+ * Assessment of Products Returned from Field
+ *
+ * Returned products are considered good if they fulfill the specifications /
+ * test data for 0-mileage and field listed in this document.
+ *
+ * Engineering Samples
+ *
+ * Engineering samples are marked with (e) or (E). Samples may vary from the
+ * valid technical specifications of the series product contained in this
+ * data sheet. Therefore, they are not intended or fit for resale to
+ * third parties or for use in end products. Their sole purpose is internal
+ * client testing. The testing of an engineering sample may in no way replace
+ * the testing of a series product. Bosch assumes no liability for the use
+ * of engineering samples. The purchaser shall indemnify Bosch from all claims
+ * arising from the use of engineering samples.
+ *
+ * Intended use
+ *
+ * Provided that SMI130 is used within the conditions (environment, application,
+ * installation, loads) as described in this TCD and the corresponding
+ * agreed upon documents, Bosch ensures that the product complies with
+ * the agreed properties. Agreements beyond this require
+ * the written approval by Bosch. The product is considered fit for the intended
+ * use when the product successfully has passed the tests
+ * in accordance with the TCD and agreed upon documents.
+ *
+ * It is the responsibility of the customer to ensure the proper application
+ * of the product in the overall system/vehicle.
+ *
+ * Bosch does not assume any responsibility for changes to the environment
+ * of the product that deviate from the TCD and the agreed upon documents
+ * as well as all applications not released by Bosch
+ *
+ * The resale and/or use of products are at the purchaser’s own risk and
+ * responsibility. The examination and testing of the SMI130
+ * is the sole responsibility of the purchaser.
+ *
+ * The purchaser shall indemnify Bosch from all third party claims
+ * arising from any product use not covered by the parameters of
+ * this product data sheet or not approved by Bosch and reimburse Bosch
+ * for all costs and damages in connection with such claims.
+ *
+ * The purchaser must monitor the market for the purchased products,
+ * particularly with regard to product safety, and inform Bosch without delay
+ * of all security relevant incidents.
+ *
+ * Application Examples and Hints
+ *
+ * With respect to any application examples, advice, normal values
+ * and/or any information regarding the application of the device,
+ * Bosch hereby disclaims any and all warranties and liabilities of any kind,
+ * including without limitation warranties of
+ * non-infringement of intellectual property rights or copyrights
+ * of any third party.
+ * The information given in this document shall in no event be regarded
+ * as a guarantee of conditions or characteristics. They are provided
+ * for illustrative purposes only and no evaluation regarding infringement
+ * of intellectual property rights or copyrights or regarding functionality,
+ * performance or error has been made.
+ *
+ * @filename bs_log.c
+ * @date "Wed Sep 24 15:27:12 2014 +0800"
+ * @Modification Date 2018/08/28 18:20
+ * @id "e416c14"
+ *
+ * @brief
+ * The source file of BOSCH SENSOR LOG
+*/
+
+
+#ifdef __KERNEL__
+#include <linux/kernel.h>
+#include <linux/unistd.h>
+#include <linux/types.h>
+#else
+#include <unistd.h>
+#include <sys/types.h>
+#endif
+
+#include <linux/time.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#ifdef BOSCH_DRIVER_LOG_FUNC
+#define BSLOG_VAR_DEF
+#include "bs_log.h"
+
+void set_debug_log_level(uint8_t level)
+{
+ debug_log_level = level;
+}
+
+uint8_t get_debug_log_level(void)
+{
+ return debug_log_level;
+}
+
+EXPORT_SYMBOL(set_debug_log_level);
+EXPORT_SYMBOL(get_debug_log_level);
+
+#endif/*BOSCH_DRIVER_LOG_FUNC*/
+/*@}*/
diff --git a/drivers/input/sensors/smi130/bs_log.h b/drivers/input/sensors/smi130/bs_log.h
new file mode 100644
index 0000000..86ef153
--- /dev/null
+++ b/drivers/input/sensors/smi130/bs_log.h
@@ -0,0 +1,274 @@
+/*!
+ * @section LICENSE
+ * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved
+ *
+ * (C) Modification Copyright 2018 Robert Bosch Kft All Rights Reserved
+ *
+ * This software program is licensed subject to the GNU General
+ * Public License (GPL).Version 2,June 1991,
+ * available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * Special: Description of the Software:
+ *
+ * This software module (hereinafter called "Software") and any
+ * information on application-sheets (hereinafter called "Information") is
+ * provided free of charge for the sole purpose to support your application
+ * work.
+ *
+ * As such, the Software is merely an experimental software, not tested for
+ * safety in the field and only intended for inspiration for further development
+ * and testing. Any usage in a safety-relevant field of use (like automotive,
+ * seafaring, spacefaring, industrial plants etc.) was not intended, so there are
+ * no precautions for such usage incorporated in the Software.
+ *
+ * The Software is specifically designed for the exclusive use for Bosch
+ * Sensortec products by personnel who have special experience and training. Do
+ * not use this Software if you do not have the proper experience or training.
+ *
+ * This Software package is provided as is and without any expressed or
+ * implied warranties, including without limitation, the implied warranties of
+ * merchantability and fitness for a particular purpose.
+ *
+ * Bosch Sensortec and their representatives and agents deny any liability for
+ * the functional impairment of this Software in terms of fitness, performance
+ * and safety. Bosch Sensortec and their representatives and agents shall not be
+ * liable for any direct or indirect damages or injury, except as otherwise
+ * stipulated in mandatory applicable law.
+ * The Information provided is believed to be accurate and reliable. Bosch
+ * Sensortec assumes no responsibility for the consequences of use of such
+ * Information nor for any infringement of patents or other rights of third
+ * parties which may result from its use.
+ *
+ *------------------------------------------------------------------------------
+ * The following Product Disclaimer does not apply to the BSX4-HAL-4.1NoFusion Software
+ * which is licensed under the Apache License, Version 2.0 as stated above.
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Product Disclaimer
+ *
+ * Common:
+ *
+ * Assessment of Products Returned from Field
+ *
+ * Returned products are considered good if they fulfill the specifications /
+ * test data for 0-mileage and field listed in this document.
+ *
+ * Engineering Samples
+ *
+ * Engineering samples are marked with (e) or (E). Samples may vary from the
+ * valid technical specifications of the series product contained in this
+ * data sheet. Therefore, they are not intended or fit for resale to
+ * third parties or for use in end products. Their sole purpose is internal
+ * client testing. The testing of an engineering sample may in no way replace
+ * the testing of a series product. Bosch assumes no liability for the use
+ * of engineering samples. The purchaser shall indemnify Bosch from all claims
+ * arising from the use of engineering samples.
+ *
+ * Intended use
+ *
+ * Provided that SMI130 is used within the conditions (environment, application,
+ * installation, loads) as described in this TCD and the corresponding
+ * agreed upon documents, Bosch ensures that the product complies with
+ * the agreed properties. Agreements beyond this require
+ * the written approval by Bosch. The product is considered fit for the intended
+ * use when the product successfully has passed the tests
+ * in accordance with the TCD and agreed upon documents.
+ *
+ * It is the responsibility of the customer to ensure the proper application
+ * of the product in the overall system/vehicle.
+ *
+ * Bosch does not assume any responsibility for changes to the environment
+ * of the product that deviate from the TCD and the agreed upon documents
+ * as well as all applications not released by Bosch
+ *
+ * The resale and/or use of products are at the purchaser’s own risk and
+ * responsibility. The examination and testing of the SMI130
+ * is the sole responsibility of the purchaser.
+ *
+ * The purchaser shall indemnify Bosch from all third party claims
+ * arising from any product use not covered by the parameters of
+ * this product data sheet or not approved by Bosch and reimburse Bosch
+ * for all costs and damages in connection with such claims.
+ *
+ * The purchaser must monitor the market for the purchased products,
+ * particularly with regard to product safety, and inform Bosch without delay
+ * of all security relevant incidents.
+ *
+ * Application Examples and Hints
+ *
+ * With respect to any application examples, advice, normal values
+ * and/or any information regarding the application of the device,
+ * Bosch hereby disclaims any and all warranties and liabilities of any kind,
+ * including without limitation warranties of
+ * non-infringement of intellectual property rights or copyrights
+ * of any third party.
+ * The information given in this document shall in no event be regarded
+ * as a guarantee of conditions or characteristics. They are provided
+ * for illustrative purposes only and no evaluation regarding infringement
+ * of intellectual property rights or copyrights or regarding functionality,
+ * performance or error has been made.
+ *
+ * @filename bs_log.h
+ * @date "Sat Oct 11 16:12:16 2014 +0800"
+ * @Modification Date 2018/08/28 18:20
+ * @id "762cc9e"
+ *
+ * @brief
+ * The head file of BOSCH SENSOR LOG
+*/
+
+#ifndef __BS_LOG_H
+#define __BS_LOG_H
+
+#include <linux/kernel.h>
+
+/*! @ trace functions
+ @{*/
+/*! ERROR LOG LEVEL */
+#define LOG_LEVEL_E 3
+/*! NOTICE LOG LEVEL */
+#define LOG_LEVEL_N 5
+/*! INFORMATION LOG LEVEL */
+#define LOG_LEVEL_I 6
+/*! DEBUG LOG LEVEL */
+#define LOG_LEVEL_D 7
+/*! DEBUG_FWDL LOG LEVEL */
+#define LOG_LEVEL_DF 10
+/*! DEBUG_DATA LOG LEVEL */
+#define LOG_LEVEL_DA 15
+/*! ALL LOG LEVEL */
+#define LOG_LEVEL_A 20
+
+#ifndef MODULE_TAG
+/*! MODULE TAG DEFINATION */
+#define MODULE_TAG "<BS_LOG>"
+#endif
+
+#ifndef LOG_LEVEL
+/*! LOG LEVEL DEFINATION */
+#define LOG_LEVEL LOG_LEVEL_I
+#endif
+
+#ifdef BOSCH_DRIVER_LOG_FUNC
+ #ifdef BSLOG_VAR_DEF
+ uint8_t debug_log_level = LOG_LEVEL;
+ #else
+ extern uint8_t debug_log_level;
+ #endif
+
+ /*! print error message */
+ #define PERR(fmt, args...) do\
+ {\
+ if (debug_log_level >= LOG_LEVEL_E)\
+ printk(KERN_INFO "\n" "[E]" KERN_ERR MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args);\
+ } while (0)
+
+ /*! print notice message */
+ #define PNOTICE(fmt, args...) do\
+ {\
+ if (debug_log_level >= LOG_LEVEL_N)\
+ printk(KERN_INFO "\n" "[N]" KERN_NOTICE MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args);\
+ } while (0)
+
+ /*! print information message */
+ #define PINFO(fmt, args...) do\
+ {\
+ if (debug_log_level >= LOG_LEVEL_I)\
+ printk(KERN_INFO "\n" "[I]" KERN_INFO MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args);\
+ } while (0)
+
+ /*! print debug message */
+ #define PDEBUG(fmt, args...) do\
+ {\
+ if (debug_log_level >= LOG_LEVEL_D)\
+ printk(KERN_INFO "\n" "[D]" KERN_DEBUG MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args);\
+ } while (0)
+
+ /*! print debug fw download message */
+ #define PDEBUG_FWDL(fmt, args...) do\
+ {\
+ if (debug_log_level >= LOG_LEVEL_DF)\
+ printk(KERN_INFO "\n" "[DF]" KERN_DEBUG MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args);\
+ } while (0)
+
+ /*! print debug data log message */
+ #define PDEBUG_DLOG(fmt, args...) do\
+ {\
+ if (debug_log_level >= LOG_LEVEL_DA)\
+ printk(KERN_INFO "\n" "[DA]" KERN_DEBUG MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args);\
+ } while (0)
+
+ void set_debug_log_level(uint8_t level);
+ uint8_t get_debug_log_level(void);
+
+#else
+
+ #if (LOG_LEVEL >= LOG_LEVEL_E)
+ /*! print error message */
+ #define PERR(fmt, args...) \
+ printk(KERN_INFO "\n" "[E]" KERN_ERR MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args)
+ #else
+ /*! invalid message */
+ #define PERR(fmt, args...)
+ #endif
+
+ #if (LOG_LEVEL >= LOG_LEVEL_N)
+ /*! print notice message */
+ #define PNOTICE(fmt, args...) \
+ printk(KERN_INFO "\n" "[N]" KERN_NOTICE MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args)
+ #else
+ /*! invalid message */
+ #define PNOTICE(fmt, args...)
+ #endif
+
+ #if (LOG_LEVEL >= LOG_LEVEL_I)
+ /*! print information message */
+ #define PINFO(fmt, args...) printk(KERN_INFO "\n" "[I]" KERN_INFO MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args)
+ #else
+ /*! invalid message */
+ #define PINFO(fmt, args...)
+ #endif
+
+ #if (LOG_LEVEL >= LOG_LEVEL_D)
+ /*! print debug message */
+ #define PDEBUG(fmt, args...) printk(KERN_INFO "\n" "[D]" KERN_DEBUG MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args)
+ #else
+ /*! invalid message */
+ #define PDEBUG(fmt, args...)
+ #endif
+
+ #if (LOG_LEVEL >= LOG_LEVEL_DF)
+ /*! print debug fw download message */
+ #define PDEBUG_FWDL(fmt, args...) printk(KERN_INFO "\n" "[DF]" KERN_DEBUG MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args)
+ #else
+ /*! invalid message */
+ #define PDEBUG_FWDL(fmt, args...)
+ #endif
+
+ #if (LOG_LEVEL >= LOG_LEVEL_DA)
+ /*! print debug data log message */
+ #define PDEBUG_DLOG(fmt, args...) printk(KERN_INFO "\n" "[DA]" KERN_DEBUG MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args)
+ #else
+ /*! invalid message */
+ #define PDEBUG_DLOG(fmt, args...)
+ #endif
+
+ #define set_debug_log_level(level) {}
+ #define get_debug_log_level() (LOG_LEVEL)
+
+#endif
+
+#endif/*__BS_LOG_H*/
+/*@}*/
diff --git a/drivers/input/sensors/smi130/modules.order b/drivers/input/sensors/smi130/modules.order
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/drivers/input/sensors/smi130/modules.order
diff --git a/drivers/input/sensors/smi130/readme.md b/drivers/input/sensors/smi130/readme.md
new file mode 100644
index 0000000..48b2cc1
--- /dev/null
+++ b/drivers/input/sensors/smi130/readme.md
@@ -0,0 +1,49 @@
+# SMI130 sensor API
+## Introduction
+This package contains the Robert Bosch GmbH's SMI130 sensor driver (sensor API)
+
+## Version
+File | Version | Date
+---------------------|---------|---------------
+smi130.h | 2.0.9 | 2018/08/28
+smi130.c | 2.0.9 | 2018/08/28
+smi130_spi.c | 1.3 | 2018/08/28
+smi130_i2c.c | 1.3 | 2018/08/28
+smi130_gyro_driver.c | 1.5.9 | 2018/08/28
+smi130_gyro.c | 1.5 | 2018/08/28
+smi130_gyro.h | 1.5 | 2018/08/28
+smi130_driver.h | 1.3 | 2018/08/28
+smi130_driver.c | 1.3 | 2018/08/28
+smi130_acc.c | 2.1.2 | 2018/08/28
+bs_log.h | | 2018/08/28
+bs_log.c | | 2018/08/28
+boschcalss.h | 1.5.9 | 2018/08/28
+boschclass.c | 1.5.9 | 2018/08/28
+
+
+
+## File information
+* smi130.h : The head file of SMI130API
+* smi130.c : Sensor Driver for SMI130 sensor
+* smi130_spi.c : This file implements moudle function, which add the driver to SPI core.
+* smi130_i2c.c : This file implements moudle function, which add the driver to I2C core.
+* smi130_driver.h : The head file of SMI130 device driver core code
+* smi130_driver.c : This file implements the core code of SMI130 device driver
+* bs_log.h : The head file of BOSCH SENSOR LOG
+* bs_log.c : The source file of BOSCH SENSOR LOG
+* boschcalss.h :
+* boschclass.c :
+
+
+## Supported sensor interface
+* SPI 4-wire
+* I2C
+
+## Copyright
+
+Copyright (C) 2016 - 2017 Bosch Sensortec GmbH
+Modification Copyright (C) 2018 Robert Bosch Kft All Rights Reserved
+
+This software program is licensed subject to the GNU General
+Public License (GPL).Version 2,June 1991,
+available at http://www.fsf.org/copyleft/gpl.html
\ No newline at end of file
diff --git a/drivers/input/sensors/smi130/smi130.c b/drivers/input/sensors/smi130/smi130.c
new file mode 100644
index 0000000..1ddd3b5
--- /dev/null
+++ b/drivers/input/sensors/smi130/smi130.c
@@ -0,0 +1,18785 @@
+/*!
+ * @section LICENSE
+ * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved
+ *
+ * (C) Modification Copyright 2018 Robert Bosch Kft All Rights Reserved
+ *
+ * This software program is licensed subject to the GNU General
+ * Public License (GPL).Version 2,June 1991,
+ * available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * Special: Description of the Software:
+ *
+ * This software module (hereinafter called "Software") and any
+ * information on application-sheets (hereinafter called "Information") is
+ * provided free of charge for the sole purpose to support your application
+ * work.
+ *
+ * As such, the Software is merely an experimental software, not tested for
+ * safety in the field and only intended for inspiration for further development
+ * and testing. Any usage in a safety-relevant field of use (like automotive,
+ * seafaring, spacefaring, industrial plants etc.) was not intended, so there are
+ * no precautions for such usage incorporated in the Software.
+ *
+ * The Software is specifically designed for the exclusive use for Bosch
+ * Sensortec products by personnel who have special experience and training. Do
+ * not use this Software if you do not have the proper experience or training.
+ *
+ * This Software package is provided as is and without any expressed or
+ * implied warranties, including without limitation, the implied warranties of
+ * merchantability and fitness for a particular purpose.
+ *
+ * Bosch Sensortec and their representatives and agents deny any liability for
+ * the functional impairment of this Software in terms of fitness, performance
+ * and safety. Bosch Sensortec and their representatives and agents shall not be
+ * liable for any direct or indirect damages or injury, except as otherwise
+ * stipulated in mandatory applicable law.
+ * The Information provided is believed to be accurate and reliable. Bosch
+ * Sensortec assumes no responsibility for the consequences of use of such
+ * Information nor for any infringement of patents or other rights of third
+ * parties which may result from its use.
+ *
+ *------------------------------------------------------------------------------
+ * The following Product Disclaimer does not apply to the BSX4-HAL-4.1NoFusion Software
+ * which is licensed under the Apache License, Version 2.0 as stated above.
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Product Disclaimer
+ *
+ * Common:
+ *
+ * Assessment of Products Returned from Field
+ *
+ * Returned products are considered good if they fulfill the specifications /
+ * test data for 0-mileage and field listed in this document.
+ *
+ * Engineering Samples
+ *
+ * Engineering samples are marked with (e) or (E). Samples may vary from the
+ * valid technical specifications of the series product contained in this
+ * data sheet. Therefore, they are not intended or fit for resale to
+ * third parties or for use in end products. Their sole purpose is internal
+ * client testing. The testing of an engineering sample may in no way replace
+ * the testing of a series product. Bosch assumes no liability for the use
+ * of engineering samples. The purchaser shall indemnify Bosch from all claims
+ * arising from the use of engineering samples.
+ *
+ * Intended use
+ *
+ * Provided that SMI130 is used within the conditions (environment, application,
+ * installation, loads) as described in this TCD and the corresponding
+ * agreed upon documents, Bosch ensures that the product complies with
+ * the agreed properties. Agreements beyond this require
+ * the written approval by Bosch. The product is considered fit for the intended
+ * use when the product successfully has passed the tests
+ * in accordance with the TCD and agreed upon documents.
+ *
+ * It is the responsibility of the customer to ensure the proper application
+ * of the product in the overall system/vehicle.
+ *
+ * Bosch does not assume any responsibility for changes to the environment
+ * of the product that deviate from the TCD and the agreed upon documents
+ * as well as all applications not released by Bosch
+ *
+ * The resale and/or use of products are at the purchaser’s own risk and
+ * responsibility. The examination and testing of the SMI130
+ * is the sole responsibility of the purchaser.
+ *
+ * The purchaser shall indemnify Bosch from all third party claims
+ * arising from any product use not covered by the parameters of
+ * this product data sheet or not approved by Bosch and reimburse Bosch
+ * for all costs and damages in connection with such claims.
+ *
+ * The purchaser must monitor the market for the purchased products,
+ * particularly with regard to product safety, and inform Bosch without delay
+ * of all security relevant incidents.
+ *
+ * Application Examples and Hints
+ *
+ * With respect to any application examples, advice, normal values
+ * and/or any information regarding the application of the device,
+ * Bosch hereby disclaims any and all warranties and liabilities of any kind,
+ * including without limitation warranties of
+ * non-infringement of intellectual property rights or copyrights
+ * of any third party.
+ * The information given in this document shall in no event be regarded
+ * as a guarantee of conditions or characteristics. They are provided
+ * for illustrative purposes only and no evaluation regarding infringement
+ * of intellectual property rights or copyrights or regarding functionality,
+ * performance or error has been made.
+*
+* @filename smi130.c
+* @Date: 2015/04/02
+* @Modification Date 2018/08/28 18:20
+* @id 836294d
+* @Revision: 2.0.9 $
+*
+* Usage: Sensor Driver for SMI130 sensor
+*/
+
+
+#include "smi130.h"
+#include <linux/kernel.h>
+
+/* user defined code to be added here ... */
+struct smi130_t *p_smi130;
+/* used for reading the mag trim values for compensation*/
+struct trim_data_t mag_trim_mbl;
+/* the following variable used for avoiding the selecting of auto mode
+when it is running in the manual mode of BMM150 mag interface*/
+u8 V_bmm150_maual_auto_condition_u8_mbl = SMI130_INIT_VALUE;
+/* used for reading the AKM compensating data */
+struct bosch_akm_sensitivity_data_t akm_asa_data_mbl;
+/* Assign the fifo time */
+u32 V_fifo_time_U32_mbl = SMI130_INIT_VALUE;
+
+/* FIFO data read for 1024 bytes of data */
+u8 v_fifo_data_u8_mbl[FIFO_FRAME] = {SMI130_INIT_VALUE};
+/* YAMAHA-YAS532*/
+/* value of coeff*/
+static const int yas532_version_ac_coef[] = {YAS532_VERSION_AC_COEF_X,
+YAS532_VERSION_AC_COEF_Y1, YAS532_VERSION_AC_COEF_Y2};
+/* used for reading the yas532 calibration data*/
+struct yas532_t yas532_data_mbl;
+/* used for reading the yas537 calibration data*/
+struct yas537_t yas537_data_mbl;
+/*!
+ * @brief
+ * This function is used for initialize
+ * bus read and bus write functions
+ * assign the chip id and device address
+ * chip id is read in the register 0x00 bit from 0 to 7
+ *
+ * @param smi130 : structure pointer
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ * @note
+ * While changing the parameter of the smi130_t
+ * consider the following point:
+ * Changing the reference value of the parameter
+ * will changes the local copy or local reference
+ * make sure your changes will not
+ * affect the reference value of the parameter
+ * (Better case don't change the reference value of the parameter)
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_init(struct smi130_t *smi130)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ u8 v_pmu_data_u8 = SMI130_INIT_VALUE;
+ /* assign smi130 ptr */
+ p_smi130 = smi130;
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_CHIP_ID__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ /* read Chip Id */
+ p_smi130->chip_id = v_data_u8;
+ /* To avoid gyro wakeup it is required to write 0x00 to 0x6C*/
+ com_rslt += smi130_write_reg(SMI130_USER_PMU_TRIGGER_ADDR,
+ &v_pmu_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ return com_rslt;
+}
+/*!
+ * @brief
+ * This API write the data to
+ * the given register
+ *
+ *
+ * @param v_addr_u8 -> Address of the register
+ * @param v_data_u8 -> The data from the register
+ * @param v_len_u8 -> no of bytes to read
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_write_reg(u8 v_addr_u8,
+u8 *v_data_u8, u8 v_len_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write data from register*/
+ com_rslt =
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->dev_addr,
+ v_addr_u8, v_data_u8, v_len_u8);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief
+ * This API reads the data from
+ * the given register
+ *
+ *
+ * @param v_addr_u8 -> Address of the register
+ * @param v_data_u8 -> The data from the register
+ * @param v_len_u8 -> no of bytes to read
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_read_reg(u8 v_addr_u8,
+u8 *v_data_u8, u8 v_len_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* Read data from register*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ v_addr_u8, v_data_u8, v_len_u8);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API used to reads the fatal error
+ * from the Register 0x02 bit 0
+ * This flag will be reset only by power-on-reset and soft reset
+ *
+ *
+ * @param v_fatal_err_u8 : The status of fatal error
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fatal_err(u8
+*v_fatal_err_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* reading the fatal error status*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FATAL_ERR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fatal_err_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FATAL_ERR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API used to read the error code
+ * from register 0x02 bit 1 to 4
+ *
+ *
+ * @param v_err_code_u8 : The status of error codes
+ * error_code | description
+ * ------------|---------------
+ * 0x00 |no error
+ * 0x01 |ACC_CONF error (accel ODR and bandwidth not compatible)
+ * 0x02 |GYR_CONF error (Gyroscope ODR and bandwidth not compatible)
+ * 0x03 |Under sampling mode and interrupt uses pre filtered data
+ * 0x04 |reserved
+ * 0x05 |Selected trigger-readout offset in
+ * - |MAG_IF greater than selected ODR
+ * 0x06 |FIFO configuration error for header less mode
+ * 0x07 |Under sampling mode and pre filtered data as FIFO source
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_err_code(u8
+*v_err_code_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_ERR_CODE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_err_code_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_ERR_CODE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API Reads the i2c error code from the
+ * Register 0x02 bit 5.
+ * This error occurred in I2C master detected
+ *
+ * @param v_i2c_err_code_u8 : The status of i2c fail error
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_i2c_fail_err(u8
+*v_i2c_err_code_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_I2C_FAIL_ERR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_i2c_err_code_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_I2C_FAIL_ERR);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API Reads the dropped command error
+ * from the register 0x02 bit 6
+ *
+ *
+ * @param v_drop_cmd_err_u8 : The status of drop command error
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_drop_cmd_err(u8
+*v_drop_cmd_err_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_DROP_CMD_ERR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_drop_cmd_err_u8 = SMI130_GET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_DROP_CMD_ERR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the magnetometer data ready
+ * interrupt not active.
+ * It reads from the error register 0x0x2 bit 7
+ *
+ *
+ *
+ *
+ * @param v_mag_data_rdy_err_u8 : The status of mag data ready interrupt
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_dada_rdy_err(
+u8 *v_mag_data_rdy_err_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_MAG_DADA_RDY_ERR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_mag_data_rdy_err_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_MAG_DADA_RDY_ERR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the error status
+ * from the error register 0x02 bit 0 to 7
+ *
+ * @param v_mag_data_rdy_err_u8 : The status of mag data ready interrupt
+ * @param v_fatal_er_u8r : The status of fatal error
+ * @param v_err_code_u8 : The status of error code
+ * @param v_i2c_fail_err_u8 : The status of I2C fail error
+ * @param v_drop_cmd_err_u8 : The status of drop command error
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_error_status(u8 *v_fatal_er_u8r,
+u8 *v_err_code_u8, u8 *v_i2c_fail_err_u8,
+u8 *v_drop_cmd_err_u8, u8 *v_mag_data_rdy_err_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the error codes*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_ERR_STAT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ /* fatal error*/
+ *v_fatal_er_u8r =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FATAL_ERR);
+ /* user error*/
+ *v_err_code_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_ERR_CODE);
+ /* i2c fail error*/
+ *v_i2c_fail_err_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_I2C_FAIL_ERR);
+ /* drop command error*/
+ *v_drop_cmd_err_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_DROP_CMD_ERR);
+ /* mag data ready error*/
+ *v_mag_data_rdy_err_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_MAG_DADA_RDY_ERR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the magnetometer power mode from
+ * PMU status register 0x03 bit 0 and 1
+ *
+ * @param v_mag_power_mode_stat_u8 : The value of mag power mode
+ * mag_powermode | value
+ * ------------------|----------
+ * SUSPEND | 0x00
+ * NORMAL | 0x01
+ * LOW POWER | 0x02
+ *
+ *
+ * @note The power mode of mag set by the 0x7E command register
+ * @note using the function "smi130_set_command_register()"
+ * value | mode
+ * ---------|----------------
+ * 0x18 | MAG_MODE_SUSPEND
+ * 0x19 | MAG_MODE_NORMAL
+ * 0x1A | MAG_MODE_LOWPOWER
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_power_mode_stat(u8
+*v_mag_power_mode_stat_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_MAG_POWER_MODE_STAT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_mag_power_mode_stat_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_MAG_POWER_MODE_STAT);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the gyroscope power mode from
+ * PMU status register 0x03 bit 2 and 3
+ *
+ * @param v_gyro_power_mode_stat_u8 : The value of gyro power mode
+ * gyro_powermode | value
+ * ------------------|----------
+ * SUSPEND | 0x00
+ * NORMAL | 0x01
+ * FAST POWER UP | 0x03
+ *
+ * @note The power mode of gyro set by the 0x7E command register
+ * @note using the function "smi130_set_command_register()"
+ * value | mode
+ * ---------|----------------
+ * 0x14 | GYRO_MODE_SUSPEND
+ * 0x15 | GYRO_MODE_NORMAL
+ * 0x17 | GYRO_MODE_FASTSTARTUP
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_power_mode_stat(u8
+*v_gyro_power_mode_stat_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_GYRO_POWER_MODE_STAT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_gyro_power_mode_stat_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_GYRO_POWER_MODE_STAT);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the accelerometer power mode from
+ * PMU status register 0x03 bit 4 and 5
+ *
+ *
+ * @param v_accel_power_mode_stat_u8 : The value of accel power mode
+ * accel_powermode | value
+ * ------------------|----------
+ * SUSPEND | 0x00
+ * NORMAL | 0x01
+ * LOW POWER | 0x02
+ *
+ * @note The power mode of accel set by the 0x7E command register
+ * @note using the function "smi130_set_command_register()"
+ * value | mode
+ * ---------|----------------
+ * 0x11 | ACCEL_MODE_NORMAL
+ * 0x12 | ACCEL_LOWPOWER
+ * 0x10 | ACCEL_SUSPEND
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_power_mode_stat(u8
+*v_accel_power_mode_stat_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_ACCEL_POWER_MODE_STAT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_power_mode_stat_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_ACCEL_POWER_MODE_STAT);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API switch mag interface to normal mode
+ * and confirm whether the mode switching done successfully or not
+*
+ * @return results of bus communication function and current MAG_PMU result
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_interface_normal(void)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = SMI130_INIT_VALUE;
+ /* aim to check the result of switching mag normal */
+ u8 v_try_times_u8 = SMI130_MAG_NOAMRL_SWITCH_TIMES;
+ u8 v_mag_pum_status_u8 = SMI130_INIT_VALUE;
+
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt = smi130_set_command_register(MAG_MODE_NORMAL);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ while (v_try_times_u8) {
+ com_rslt = smi130_get_mag_power_mode_stat(&v_mag_pum_status_u8);
+ if (v_mag_pum_status_u8 == MAG_INTERFACE_PMU_ENABLE)
+ break;
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ v_try_times_u8--;
+ }
+ if (v_mag_pum_status_u8 == MAG_INTERFACE_PMU_ENABLE)
+ com_rslt += SUCCESS;
+ else
+ com_rslt += E_SMI130_COMM_RES;
+
+ return com_rslt;
+}
+/*!
+ * @brief This API reads magnetometer data X values
+ * from the register 0x04 and 0x05
+ * @brief The mag sensor data read form auxiliary mag
+ *
+ * @param v_mag_x_s16 : The value of mag x
+ * @param v_sensor_select_u8 : Mag selection value
+ * value | sensor
+ * ---------|----------------
+ * 0 | BMM150
+ * 1 | AKM09911 or AKM09912
+ *
+ * @note For mag data output rate configuration use the following function
+ * @note smi130_set_mag_output_data_rate()
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_mag_x(s16 *v_mag_x_s16,
+u8 v_sensor_select_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the mag X lSB and MSB data
+ v_data_u8[0] - LSB
+ v_data_u8[1] - MSB*/
+ u8 v_data_u8[SMI130_MAG_X_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_sensor_select_u8) {
+ case BST_BMM:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_DATA_MAG_X_LSB__REG,
+ v_data_u8, SMI130_MAG_X_DATA_LENGTH);
+ /* X axis*/
+ v_data_u8[SMI130_MAG_X_LSB_BYTE] =
+ SMI130_GET_BITSLICE(v_data_u8[SMI130_MAG_X_LSB_BYTE],
+ SMI130_USER_DATA_MAG_X_LSB);
+ *v_mag_x_s16 = (s16)
+ ((((s32)((s8)v_data_u8[SMI130_MAG_X_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_05_BITS) |
+ (v_data_u8[SMI130_MAG_X_LSB_BYTE]));
+ break;
+ case BST_AKM:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_DATA_0_MAG_X_LSB__REG,
+ v_data_u8, SMI130_MAG_X_DATA_LENGTH);
+ *v_mag_x_s16 = (s16)
+ ((((s32)((s8)v_data_u8[SMI130_MAG_X_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[SMI130_MAG_X_LSB_BYTE]));
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads magnetometer data Y values
+ * from the register 0x06 and 0x07
+ * @brief The mag sensor data read form auxiliary mag
+ *
+ * @param v_mag_y_s16 : The value of mag y
+ * @param v_sensor_select_u8 : Mag selection value
+ * value | sensor
+ * ---------|----------------
+ * 0 | BMM150
+ * 1 | AKM09911 or AKM09912
+ *
+ * @note For mag data output rate configuration use the following function
+ * @note smi130_set_mag_output_data_rate()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_mag_y(s16 *v_mag_y_s16,
+u8 v_sensor_select_u8)
+{
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_OUT_OF_RANGE;
+ /* Array contains the mag Y lSB and MSB data
+ v_data_u8[0] - LSB
+ v_data_u8[1] - MSB*/
+ u8 v_data_u8[SMI130_MAG_Y_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_sensor_select_u8) {
+ case BST_BMM:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_DATA_MAG_Y_LSB__REG,
+ v_data_u8, SMI130_MAG_Y_DATA_LENGTH);
+ /*Y-axis lsb value shifting*/
+ v_data_u8[SMI130_MAG_Y_LSB_BYTE] =
+ SMI130_GET_BITSLICE(v_data_u8[SMI130_MAG_Y_LSB_BYTE],
+ SMI130_USER_DATA_MAG_Y_LSB);
+ *v_mag_y_s16 = (s16)
+ ((((s32)((s8)v_data_u8[SMI130_MAG_Y_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_05_BITS) |
+ (v_data_u8[SMI130_MAG_Y_LSB_BYTE]));
+ break;
+ case BST_AKM:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_DATA_2_MAG_Y_LSB__REG,
+ v_data_u8, SMI130_MAG_Y_DATA_LENGTH);
+ *v_mag_y_s16 = (s16)
+ ((((s32)((s8)v_data_u8[SMI130_MAG_Y_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[SMI130_MAG_Y_LSB_BYTE]));
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads magnetometer data Z values
+ * from the register 0x08 and 0x09
+ * @brief The mag sensor data read form auxiliary mag
+ *
+ * @param v_mag_z_s16 : The value of mag z
+ * @param v_sensor_select_u8 : Mag selection value
+ * value | sensor
+ * ---------|----------------
+ * 0 | BMM150
+ * 1 | AKM09911 or AKM09912
+ *
+ * @note For mag data output rate configuration use the following function
+ * @note smi130_set_mag_output_data_rate()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_mag_z(s16 *v_mag_z_s16,
+u8 v_sensor_select_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the mag Z lSB and MSB data
+ v_data_u8[0] - LSB
+ v_data_u8[1] - MSB*/
+ u8 v_data_u8[SMI130_MAG_Z_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_sensor_select_u8) {
+ case BST_BMM:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_DATA_MAG_Z_LSB__REG,
+ v_data_u8, SMI130_MAG_Z_DATA_LENGTH);
+ /*Z-axis lsb value shifting*/
+ v_data_u8[SMI130_MAG_Z_LSB_BYTE] =
+ SMI130_GET_BITSLICE(v_data_u8[SMI130_MAG_Z_LSB_BYTE],
+ SMI130_USER_DATA_MAG_Z_LSB);
+ *v_mag_z_s16 = (s16)
+ ((((s32)((s8)v_data_u8[SMI130_MAG_Z_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_07_BITS) |
+ (v_data_u8[SMI130_MAG_Z_LSB_BYTE]));
+ break;
+ case BST_AKM:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_DATA_4_MAG_Z_LSB__REG,
+ v_data_u8, SMI130_MAG_Z_DATA_LENGTH);
+ *v_mag_z_s16 = (s16)
+ ((((s32)((s8)v_data_u8[SMI130_MAG_Z_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) | (
+ v_data_u8[SMI130_MAG_Z_LSB_BYTE]));
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads magnetometer data RHALL values
+ * from the register 0x0A and 0x0B
+ *
+ *
+ * @param v_mag_r_s16 : The value of BMM150 r data
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_mag_r(s16 *v_mag_r_s16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the mag R lSB and MSB data
+ v_data_u8[0] - LSB
+ v_data_u8[1] - MSB*/
+ u8 v_data_u8[SMI130_MAG_R_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_DATA_6_RHALL_LSB__REG,
+ v_data_u8, SMI130_MAG_R_DATA_LENGTH);
+ /*R-axis lsb value shifting*/
+ v_data_u8[SMI130_MAG_R_LSB_BYTE] =
+ SMI130_GET_BITSLICE(v_data_u8[SMI130_MAG_R_LSB_BYTE],
+ SMI130_USER_DATA_MAG_R_LSB);
+ *v_mag_r_s16 = (s16)
+ ((((s32)((s8)v_data_u8[SMI130_MAG_R_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_06_BITS) |
+ (v_data_u8[SMI130_MAG_R_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads magnetometer data X,Y,Z values
+ * from the register 0x04 to 0x09
+ *
+ * @brief The mag sensor data read form auxiliary mag
+ *
+ * @param mag : The value of mag xyz data
+ * @param v_sensor_select_u8 : Mag selection value
+ * value | sensor
+ * ---------|----------------
+ * 0 | BMM150
+ * 1 | AKM09911 or AKM09912
+ *
+ * @note For mag data output rate configuration use the following function
+ * @note smi130_set_mag_output_data_rate()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_mag_xyz(
+struct smi130_mag_t *mag, u8 v_sensor_select_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the mag XYZ lSB and MSB data
+ v_data_u8[0] - X-LSB
+ v_data_u8[1] - X-MSB
+ v_data_u8[0] - Y-LSB
+ v_data_u8[1] - Y-MSB
+ v_data_u8[0] - Z-LSB
+ v_data_u8[1] - Z-MSB
+ */
+ u8 v_data_u8[SMI130_MAG_XYZ_DATA_SIZE] = {
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_sensor_select_u8) {
+ case BST_BMM:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_DATA_MAG_X_LSB__REG,
+ v_data_u8, SMI130_MAG_XYZ_DATA_LENGTH);
+ /*X-axis lsb value shifting*/
+ v_data_u8[SMI130_DATA_FRAME_MAG_X_LSB_BYTE] =
+ SMI130_GET_BITSLICE(
+ v_data_u8[SMI130_DATA_FRAME_MAG_X_LSB_BYTE],
+ SMI130_USER_DATA_MAG_X_LSB);
+ /* Data X */
+ mag->x = (s16)
+ ((((s32)((s8)v_data_u8[
+ SMI130_DATA_FRAME_MAG_X_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_05_BITS) |
+ (v_data_u8[SMI130_DATA_FRAME_MAG_X_LSB_BYTE]));
+ /* Data Y */
+ /*Y-axis lsb value shifting*/
+ v_data_u8[SMI130_DATA_FRAME_MAG_Y_LSB_BYTE] =
+ SMI130_GET_BITSLICE(
+ v_data_u8[SMI130_DATA_FRAME_MAG_Y_LSB_BYTE],
+ SMI130_USER_DATA_MAG_Y_LSB);
+ mag->y = (s16)
+ ((((s32)((s8)v_data_u8[
+ SMI130_DATA_FRAME_MAG_Y_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_05_BITS) |
+ (v_data_u8[SMI130_DATA_FRAME_MAG_Y_LSB_BYTE]));
+
+ /* Data Z */
+ /*Z-axis lsb value shifting*/
+ v_data_u8[SMI130_DATA_FRAME_MAG_Z_LSB_BYTE]
+ = SMI130_GET_BITSLICE(
+ v_data_u8[SMI130_DATA_FRAME_MAG_Z_LSB_BYTE],
+ SMI130_USER_DATA_MAG_Z_LSB);
+ mag->z = (s16)
+ ((((s32)((s8)v_data_u8[
+ SMI130_DATA_FRAME_MAG_Z_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_07_BITS) |
+ (v_data_u8[SMI130_DATA_FRAME_MAG_Z_LSB_BYTE]));
+ break;
+ case BST_AKM:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_DATA_0_MAG_X_LSB__REG,
+ v_data_u8, SMI130_MAG_XYZ_DATA_LENGTH);
+ /* Data X */
+ mag->x = (s16)
+ ((((s32)((s8)v_data_u8[
+ SMI130_DATA_FRAME_MAG_X_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[SMI130_DATA_FRAME_MAG_X_LSB_BYTE]));
+ /* Data Y */
+ mag->y = ((((s32)((s8)v_data_u8[
+ SMI130_DATA_FRAME_MAG_Y_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[SMI130_DATA_FRAME_MAG_Y_LSB_BYTE]));
+ /* Data Z */
+ mag->z = (s16)
+ ((((s32)((s8)v_data_u8[
+ SMI130_DATA_FRAME_MAG_Z_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[SMI130_DATA_FRAME_MAG_Z_LSB_BYTE]));
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+ /*!*
+ * @brief This API reads magnetometer data X,Y,Z,r
+ * values from the register 0x04 to 0x0B
+ *
+ * @brief The mag sensor data read form auxiliary mag
+ *
+ * @param mag : The value of mag-BMM150 xyzr data
+ *
+ * @note For mag data output rate configuration use the following function
+ * @note smi130_set_mag_output_data_rate()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_mag_xyzr(
+struct smi130_mag_xyzr_t *mag)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8[SMI130_MAG_XYZR_DATA_SIZE] = {
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_DATA_MAG_X_LSB__REG,
+ v_data_u8, SMI130_MAG_XYZR_DATA_LENGTH);
+
+ /* Data X */
+ /*X-axis lsb value shifting*/
+ v_data_u8[SMI130_DATA_FRAME_MAG_X_LSB_BYTE]
+ = SMI130_GET_BITSLICE(
+ v_data_u8[SMI130_DATA_FRAME_MAG_X_LSB_BYTE],
+ SMI130_USER_DATA_MAG_X_LSB);
+ mag->x = (s16)
+ ((((s32)((s8)v_data_u8[
+ SMI130_DATA_FRAME_MAG_X_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_05_BITS)
+ | (v_data_u8[SMI130_DATA_FRAME_MAG_X_LSB_BYTE]));
+ /* Data Y */
+ /*Y-axis lsb value shifting*/
+ v_data_u8[SMI130_DATA_FRAME_MAG_Y_LSB_BYTE]
+ = SMI130_GET_BITSLICE(
+ v_data_u8[SMI130_DATA_FRAME_MAG_Y_LSB_BYTE],
+ SMI130_USER_DATA_MAG_Y_LSB);
+ mag->y = (s16)
+ ((((s32)((s8)v_data_u8[
+ SMI130_DATA_FRAME_MAG_Y_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_05_BITS)
+ | (v_data_u8[
+ SMI130_DATA_FRAME_MAG_Y_LSB_BYTE]));
+
+ /* Data Z */
+ /*Z-axis lsb value shifting*/
+ v_data_u8[SMI130_DATA_FRAME_MAG_Z_LSB_BYTE]
+ = SMI130_GET_BITSLICE(
+ v_data_u8[SMI130_DATA_FRAME_MAG_Z_LSB_BYTE],
+ SMI130_USER_DATA_MAG_Z_LSB);
+ mag->z = (s16)
+ ((((s32)((s8)v_data_u8[
+ SMI130_DATA_FRAME_MAG_Z_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_07_BITS)
+ | (v_data_u8[SMI130_DATA_FRAME_MAG_Z_LSB_BYTE]));
+
+ /* RHall */
+ /*R-axis lsb value shifting*/
+ v_data_u8[SMI130_DATA_FRAME_MAG_R_LSB_BYTE]
+ = SMI130_GET_BITSLICE(
+ v_data_u8[SMI130_DATA_FRAME_MAG_R_LSB_BYTE],
+ SMI130_USER_DATA_MAG_R_LSB);
+ mag->r = (s16)
+ ((((s32)((s8)v_data_u8[
+ SMI130_DATA_FRAME_MAG_R_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_06_BITS)
+ | (v_data_u8[SMI130_DATA_FRAME_MAG_R_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads gyro data X values
+ * form the register 0x0C and 0x0D
+ *
+ *
+ *
+ *
+ * @param v_gyro_x_s16 : The value of gyro x data
+ *
+ * @note Gyro Configuration use the following function
+ * @note smi130_set_gyro_output_data_rate()
+ * @note smi130_set_gyro_bw()
+ * @note smi130_set_gyro_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_gyro_x(s16 *v_gyro_x_s16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the gyro X lSB and MSB data
+ v_data_u8[0] - LSB
+ v_data_u8[MSB_ONE] - MSB*/
+ u8 v_data_u8[SMI130_GYRO_X_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_DATA_8_GYRO_X_LSB__REG,
+ v_data_u8, SMI130_GYRO_DATA_LENGTH);
+
+ *v_gyro_x_s16 = (s16)
+ ((((s32)((s8)v_data_u8[SMI130_GYRO_X_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (v_data_u8[SMI130_GYRO_X_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads gyro data Y values
+ * form the register 0x0E and 0x0F
+ *
+ *
+ *
+ *
+ * @param v_gyro_y_s16 : The value of gyro y data
+ *
+ * @note Gyro Configuration use the following function
+ * @note smi130_set_gyro_output_data_rate()
+ * @note smi130_set_gyro_bw()
+ * @note smi130_set_gyro_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error result of communication routines
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_gyro_y(s16 *v_gyro_y_s16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the gyro Y lSB and MSB data
+ v_data_u8[LSB_ZERO] - LSB
+ v_data_u8[MSB_ONE] - MSB*/
+ u8 v_data_u8[SMI130_GYRO_Y_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read gyro y data*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_DATA_10_GYRO_Y_LSB__REG,
+ v_data_u8, SMI130_GYRO_DATA_LENGTH);
+
+ *v_gyro_y_s16 = (s16)
+ ((((s32)((s8)v_data_u8[SMI130_GYRO_Y_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (v_data_u8[SMI130_GYRO_Y_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads gyro data Z values
+ * form the register 0x10 and 0x11
+ *
+ *
+ *
+ *
+ * @param v_gyro_z_s16 : The value of gyro z data
+ *
+ * @note Gyro Configuration use the following function
+ * @note smi130_set_gyro_output_data_rate()
+ * @note smi130_set_gyro_bw()
+ * @note smi130_set_gyro_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_gyro_z(s16 *v_gyro_z_s16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the gyro Z lSB and MSB data
+ v_data_u8[LSB_ZERO] - LSB
+ v_data_u8[MSB_ONE] - MSB*/
+ u8 v_data_u8[SMI130_GYRO_Z_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read gyro z data */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_DATA_12_GYRO_Z_LSB__REG,
+ v_data_u8, SMI130_GYRO_DATA_LENGTH);
+
+ *v_gyro_z_s16 = (s16)
+ ((((s32)((s8)v_data_u8[SMI130_GYRO_Z_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (v_data_u8[SMI130_GYRO_Z_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads gyro data X,Y,Z values
+ * from the register 0x0C to 0x11
+ *
+ *
+ *
+ *
+ * @param gyro : The value of gyro xyz
+ *
+ * @note Gyro Configuration use the following function
+ * @note smi130_set_gyro_output_data_rate()
+ * @note smi130_set_gyro_bw()
+ * @note smi130_set_gyro_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_gyro_xyz(struct smi130_gyro_t *gyro)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the mag XYZ lSB and MSB data
+ v_data_u8[0] - X-LSB
+ v_data_u8[1] - X-MSB
+ v_data_u8[0] - Y-LSB
+ v_data_u8[1] - Y-MSB
+ v_data_u8[0] - Z-LSB
+ v_data_u8[1] - Z-MSB
+ */
+ u8 v_data_u8[SMI130_GYRO_XYZ_DATA_SIZE] = {
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the gyro xyz data*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_DATA_8_GYRO_X_LSB__REG,
+ v_data_u8, SMI130_GYRO_XYZ_DATA_LENGTH);
+
+ /* Data X */
+ gyro->x = (s16)
+ ((((s32)((s8)v_data_u8[
+ SMI130_DATA_FRAME_GYRO_X_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (v_data_u8[SMI130_DATA_FRAME_GYRO_X_LSB_BYTE]));
+ /* Data Y */
+ gyro->y = (s16)
+ ((((s32)((s8)v_data_u8[
+ SMI130_DATA_FRAME_GYRO_Y_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (v_data_u8[SMI130_DATA_FRAME_GYRO_Y_LSB_BYTE]));
+
+ /* Data Z */
+ gyro->z = (s16)
+ ((((s32)((s8)v_data_u8[
+ SMI130_DATA_FRAME_GYRO_Z_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (v_data_u8[SMI130_DATA_FRAME_GYRO_Z_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads accelerometer data X values
+ * form the register 0x12 and 0x13
+ *
+ *
+ *
+ *
+ * @param v_accel_x_s16 : The value of accel x
+ *
+ * @note For accel configuration use the following functions
+ * @note smi130_set_accel_output_data_rate()
+ * @note smi130_set_accel_bw()
+ * @note smi130_set_accel_under_sampling_parameter()
+ * @note smi130_set_accel_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_accel_x(s16 *v_accel_x_s16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the accel X lSB and MSB data
+ v_data_u8[0] - LSB
+ v_data_u8[1] - MSB*/
+ u8 v_data_u8[SMI130_ACCEL_X_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_DATA_14_ACCEL_X_LSB__REG,
+ v_data_u8, SMI130_ACCEL_DATA_LENGTH);
+
+ *v_accel_x_s16 = (s16)
+ ((((s32)((s8)v_data_u8[SMI130_ACCEL_X_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (v_data_u8[SMI130_ACCEL_X_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads accelerometer data Y values
+ * form the register 0x14 and 0x15
+ *
+ *
+ *
+ *
+ * @param v_accel_y_s16 : The value of accel y
+ *
+ * @note For accel configuration use the following functions
+ * @note smi130_set_accel_output_data_rate()
+ * @note smi130_set_accel_bw()
+ * @note smi130_set_accel_under_sampling_parameter()
+ * @note smi130_set_accel_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_accel_y(s16 *v_accel_y_s16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the accel Y lSB and MSB data
+ v_data_u8[0] - LSB
+ v_data_u8[1] - MSB*/
+ u8 v_data_u8[SMI130_ACCEL_Y_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_DATA_16_ACCEL_Y_LSB__REG,
+ v_data_u8, SMI130_ACCEL_DATA_LENGTH);
+
+ *v_accel_y_s16 = (s16)
+ ((((s32)((s8)v_data_u8[SMI130_ACCEL_Y_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (v_data_u8[SMI130_ACCEL_Y_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads accelerometer data Z values
+ * form the register 0x16 and 0x17
+ *
+ *
+ *
+ *
+ * @param v_accel_z_s16 : The value of accel z
+ *
+ * @note For accel configuration use the following functions
+ * @note smi130_set_accel_output_data_rate()
+ * @note smi130_set_accel_bw()
+ * @note smi130_set_accel_under_sampling_parameter()
+ * @note smi130_set_accel_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_accel_z(s16 *v_accel_z_s16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the accel Z lSB and MSB data
+ a_data_u8r[LSB_ZERO] - LSB
+ a_data_u8r[MSB_ONE] - MSB*/
+ u8 a_data_u8r[SMI130_ACCEL_Z_DATA_SIZE] = {
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_DATA_18_ACCEL_Z_LSB__REG,
+ a_data_u8r, SMI130_ACCEL_DATA_LENGTH);
+
+ *v_accel_z_s16 = (s16)
+ ((((s32)((s8)a_data_u8r[SMI130_ACCEL_Z_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (a_data_u8r[SMI130_ACCEL_Z_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads accelerometer data X,Y,Z values
+ * from the register 0x12 to 0x17
+ *
+ *
+ *
+ *
+ * @param accel :The value of accel xyz
+ *
+ * @note For accel configuration use the following functions
+ * @note smi130_set_accel_output_data_rate()
+ * @note smi130_set_accel_bw()
+ * @note smi130_set_accel_under_sampling_parameter()
+ * @note smi130_set_accel_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_accel_xyz(
+struct smi130_accel_t *accel)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the accel XYZ lSB and MSB data
+ a_data_u8r[0] - X-LSB
+ a_data_u8r[1] - X-MSB
+ a_data_u8r[0] - Y-LSB
+ a_data_u8r[1] - Y-MSB
+ a_data_u8r[0] - Z-LSB
+ a_data_u8r[1] - Z-MSB
+ */
+ u8 a_data_u8r[SMI130_ACCEL_XYZ_DATA_SIZE] = {
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_DATA_14_ACCEL_X_LSB__REG,
+ a_data_u8r, SMI130_ACCEL_XYZ_DATA_LENGTH);
+
+ /* Data X */
+ accel->x = (s16)
+ ((((s32)((s8)a_data_u8r[
+ SMI130_DATA_FRAME_ACCEL_X_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (a_data_u8r[SMI130_DATA_FRAME_ACCEL_X_LSB_BYTE]));
+ /* Data Y */
+ accel->y = (s16)
+ ((((s32)((s8)a_data_u8r[
+ SMI130_DATA_FRAME_ACCEL_Y_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (a_data_u8r[SMI130_DATA_FRAME_ACCEL_Y_LSB_BYTE]));
+
+ /* Data Z */
+ accel->z = (s16)
+ ((((s32)((s8)a_data_u8r[
+ SMI130_DATA_FRAME_ACCEL_Z_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (a_data_u8r[SMI130_DATA_FRAME_ACCEL_Z_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads sensor_time from the register
+ * 0x18 to 0x1A
+ *
+ *
+ * @param v_sensor_time_u32 : The value of sensor time
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_sensor_time(u32 *v_sensor_time_u32)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the sensor time it is 32 bit data
+ a_data_u8r[0] - sensor time
+ a_data_u8r[1] - sensor time
+ a_data_u8r[0] - sensor time
+ */
+ u8 a_data_u8r[SMI130_SENSOR_TIME_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_SENSORTIME_0_SENSOR_TIME_LSB__REG,
+ a_data_u8r, SMI130_SENSOR_TIME_LENGTH);
+
+ *v_sensor_time_u32 = (u32)
+ ((((u32)a_data_u8r[SMI130_SENSOR_TIME_MSB_BYTE])
+ << SMI130_SHIFT_BIT_POSITION_BY_16_BITS)
+ |(((u32)a_data_u8r[SMI130_SENSOR_TIME_XLSB_BYTE])
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (a_data_u8r[SMI130_SENSOR_TIME_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the Gyroscope self test
+ * status from the register 0x1B bit 1
+ *
+ *
+ * @param v_gyro_selftest_u8 : The value of gyro self test status
+ * value | status
+ * ---------|----------------
+ * 0 | Gyroscope self test is running or failed
+ * 1 | Gyroscope self test completed successfully
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_selftest(u8
+*v_gyro_selftest_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_STAT_GYRO_SELFTEST_OK__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_gyro_selftest_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_STAT_GYRO_SELFTEST_OK);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the status of
+ * mag manual interface operation form the register 0x1B bit 2
+ *
+ *
+ *
+ * @param v_mag_manual_stat_u8 : The value of mag manual operation status
+ * value | status
+ * ---------|----------------
+ * 0 | Indicates no manual magnetometer
+ * - | interface operation is ongoing
+ * 1 | Indicates manual magnetometer
+ * - | interface operation is ongoing
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_manual_operation_stat(u8
+*v_mag_manual_stat_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read manual operation*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_STAT_MAG_MANUAL_OPERATION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_mag_manual_stat_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_STAT_MAG_MANUAL_OPERATION);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the fast offset compensation
+ * status form the register 0x1B bit 3
+ *
+ *
+ * @param v_foc_rdy_u8 : The status of fast compensation
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_foc_rdy(u8
+*v_foc_rdy_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the FOC status*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_STAT_FOC_RDY__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_foc_rdy_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_STAT_FOC_RDY);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API Reads the nvm_rdy status from the
+ * resister 0x1B bit 4
+ *
+ *
+ * @param v_nvm_rdy_u8 : The value of NVM ready status
+ * value | status
+ * ---------|----------------
+ * 0 | NVM write operation in progress
+ * 1 | NVM is ready to accept a new write trigger
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_nvm_rdy(u8
+*v_nvm_rdy_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the nvm ready status*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_STAT_NVM_RDY__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_nvm_rdy_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_STAT_NVM_RDY);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the status of mag data ready
+ * from the register 0x1B bit 5
+ * The status get reset when one mag data register is read out
+ *
+ * @param v_data_rdy_u8 : The value of mag data ready status
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_data_rdy_mag(u8
+*v_data_rdy_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_STAT_DATA_RDY_MAG__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_data_rdy_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_STAT_DATA_RDY_MAG);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the status of gyro data ready form the
+ * register 0x1B bit 6
+ * The status get reset when gyro data register read out
+ *
+ *
+ * @param v_data_rdy_u8 : The value of gyro data ready
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_data_rdy(u8
+*v_data_rdy_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_STAT_DATA_RDY_GYRO__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_data_rdy_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_STAT_DATA_RDY_GYRO);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the status of accel data ready form the
+ * register 0x1B bit 7
+ * The status get reset when accel data register read out
+ *
+ *
+ * @param v_data_rdy_u8 : The value of accel data ready status
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_data_rdy(u8
+*v_data_rdy_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /*reads the status of accel data ready*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_STAT_DATA_RDY_ACCEL__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_data_rdy_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_STAT_DATA_RDY_ACCEL);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the step detector interrupt status
+ * from the register 0x1C bit 0
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_step_intr_u8 : The status of step detector interrupt
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_step_intr(u8
+*v_step_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_0_STEP_INTR__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_step_intr_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_0_STEP_INTR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the
+ * significant motion interrupt status
+ * from the register 0x1C bit 1
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ *
+ * @param v_significant_intr_u8 : The status of step
+ * motion interrupt
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_significant_intr(u8
+*v_significant_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_0_SIGNIFICANT_INTR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_significant_intr_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_0_SIGNIFICANT_INTR);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API reads the any motion interrupt status
+ * from the register 0x1C bit 2
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ * @param v_any_motion_intr_u8 : The status of any-motion interrupt
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_any_motion_intr(u8
+*v_any_motion_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_0_ANY_MOTION__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_any_motion_intr_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_0_ANY_MOTION);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the power mode trigger interrupt status
+ * from the register 0x1C bit 3
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ *
+ * @param v_pmu_trigger_intr_u8 : The status of power mode trigger interrupt
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_pmu_trigger_intr(u8
+*v_pmu_trigger_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_0_PMU_TRIGGER__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_pmu_trigger_intr_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_0_PMU_TRIGGER);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the double tab status
+ * from the register 0x1C bit 4
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_double_tap_intr_u8 :The status of double tab interrupt
+ *
+ * @note Double tap interrupt can be configured by the following functions
+ * @note INTERRUPT MAPPING
+ * @note smi130_set_intr_double_tap()
+ * @note AXIS MAPPING
+ * @note smi130_get_stat2_tap_first_x()
+ * @note smi130_get_stat2_tap_first_y()
+ * @note smi130_get_stat2_tap_first_z()
+ * @note DURATION
+ * @note smi130_set_intr_tap_durn()
+ * @note THRESHOLD
+ * @note smi130_set_intr_tap_thres()
+ * @note TAP QUIET
+ * @note smi130_set_intr_tap_quiet()
+ * @note TAP SHOCK
+ * @note smi130_set_intr_tap_shock()
+ * @note TAP SOURCE
+ * @note smi130_set_intr_tap_source()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_double_tap_intr(u8
+*v_double_tap_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_0_DOUBLE_TAP_INTR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_double_tap_intr_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_0_DOUBLE_TAP_INTR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the single tab status
+ * from the register 0x1C bit 5
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_single_tap_intr_u8 :The status of single tap interrupt
+ *
+ * @note Single tap interrupt can be configured by the following functions
+ * @note INTERRUPT MAPPING
+ * @note smi130_set_intr_single_tap()
+ * @note AXIS MAPPING
+ * @note smi130_get_stat2_tap_first_x()
+ * @note smi130_get_stat2_tap_first_y()
+ * @note smi130_get_stat2_tap_first_z()
+ * @note DURATION
+ * @note smi130_set_intr_tap_durn()
+ * @note THRESHOLD
+ * @note smi130_set_intr_tap_thres()
+ * @note TAP QUIET
+ * @note smi130_set_intr_tap_quiet()
+ * @note TAP SHOCK
+ * @note smi130_set_intr_tap_shock()
+ * @note TAP SOURCE
+ * @note smi130_set_intr_tap_source()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_single_tap_intr(u8
+*v_single_tap_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_0_SINGLE_TAP_INTR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_single_tap_intr_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_0_SINGLE_TAP_INTR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the orient_mbl status
+ * from the register 0x1C bit 6
+ * flag is associated with a specific interrupt function.
+ * It is set when the orient_mbl interrupt triggers. The
+ * setting of INT_LATCH controls if the
+ * interrupt signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_orient_mbl_intr_u8 : The status of orient_mbl interrupt
+ *
+ * @note For orient_mbl interrupt configuration use the following functions
+ * @note STATUS
+ * @note smi130_get_stat0_orient_mbl_intr()
+ * @note AXIS MAPPING
+ * @note smi130_get_stat3_orient_mbl_xy()
+ * @note smi130_get_stat3_orient_mbl_z()
+ * @note smi130_set_intr_orient_mbl_axes_enable()
+ * @note INTERRUPT MAPPING
+ * @note smi130_set_intr_orient_mbl()
+ * @note INTERRUPT OUTPUT
+ * @note smi130_set_intr_orient_mbl_ud_enable()
+ * @note THETA
+ * @note smi130_set_intr_orient_mbl_theta()
+ * @note HYSTERESIS
+ * @note smi130_set_intr_orient_mbl_hyst()
+ * @note BLOCKING
+ * @note smi130_set_intr_orient_mbl_blocking()
+ * @note MODE
+ * @note smi130_set_intr_orient_mbl_mode()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_orient_mbl_intr(u8
+*v_orient_mbl_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_0_ORIENT__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_orient_mbl_intr_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_0_ORIENT);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the flat interrupt status
+ * from the register 0x1C bit 7
+ * flag is associated with a specific interrupt function.
+ * It is set when the flat interrupt triggers. The
+ * setting of INT_LATCH controls if the
+ * interrupt signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_flat_intr_u8 : The status of flat interrupt
+ *
+ * @note For flat configuration use the following functions
+ * @note STATS
+ * @note smi130_get_stat0_flat_intr()
+ * @note smi130_get_stat3_flat()
+ * @note INTERRUPT MAPPING
+ * @note smi130_set_intr_flat()
+ * @note THETA
+ * @note smi130_set_intr_flat_theta()
+ * @note HOLD TIME
+ * @note smi130_set_intr_flat_hold()
+ * @note HYSTERESIS
+ * @note smi130_set_intr_flat_hyst()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_flat_intr(u8
+*v_flat_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_0_FLAT__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_flat_intr_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_0_FLAT);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the high_g interrupt status
+ * from the register 0x1D bit 2
+ * flag is associated with a specific interrupt function.
+ * It is set when the high g interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt signal and hence the
+ * respective interrupt flag will be permanently
+ * latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_high_g_intr_u8 : The status of high_g interrupt
+ *
+ * @note High_g interrupt configured by following functions
+ * @note STATUS
+ * @note smi130_get_stat1_high_g_intr()
+ * @note AXIS MAPPING
+ * @note smi130_get_stat3_high_g_first_x()
+ * @note smi130_get_stat3_high_g_first_y()
+ * @note smi130_get_stat3_high_g_first_z()
+ * @note SIGN MAPPING
+ * @note smi130_get_stat3_high_g_first_sign()
+ * @note INTERRUPT MAPPING
+ * @note smi130_set_intr_high_g()
+ * @note HYSTERESIS
+ * @note smi130_set_intr_high_g_hyst()
+ * @note DURATION
+ * @note smi130_set_intr_high_g_durn()
+ * @note THRESHOLD
+ * @note smi130_set_intr_high_g_thres()
+ * @note SOURCE
+ * @note smi130_set_intr_low_high_source()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat1_high_g_intr(u8
+*v_high_g_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_1_HIGH_G_INTR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_high_g_intr_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_1_HIGH_G_INTR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the low g interrupt status
+ * from the register 0x1D bit 3
+ * flag is associated with a specific interrupt function.
+ * It is set when the low g interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_low_g_intr_u8 : The status of low_g interrupt
+ *
+ * @note Low_g interrupt configured by following functions
+ * @note STATUS
+ * @note smi130_get_stat1_low_g_intr()
+ * @note INTERRUPT MAPPING
+ * @note smi130_set_intr_low_g()
+ * @note SOURCE
+ * @note smi130_set_intr_low_high_source()
+ * @note DURATION
+ * @note smi130_set_intr_low_g_durn()
+ * @note THRESHOLD
+ * @note smi130_set_intr_low_g_thres()
+ * @note HYSTERESIS
+ * @note smi130_set_intr_low_g_hyst()
+ * @note MODE
+ * @note smi130_set_intr_low_g_mode()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat1_low_g_intr(u8
+*v_low_g_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_1_LOW_G_INTR__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_low_g_intr_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_1_LOW_G_INTR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads data ready interrupt status
+ * from the register 0x1D bit 4
+ * flag is associated with a specific interrupt function.
+ * It is set when the data ready interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_data_rdy_intr_u8 : The status of data ready interrupt
+ *
+ * @note Data ready interrupt configured by following functions
+ * @note STATUS
+ * @note smi130_get_stat1_data_rdy_intr()
+ * @note INTERRUPT MAPPING
+ * @note smi130_set_intr_data_rdy()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat1_data_rdy_intr(u8
+*v_data_rdy_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_1_DATA_RDY_INTR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_data_rdy_intr_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_1_DATA_RDY_INTR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads data ready FIFO full interrupt status
+ * from the register 0x1D bit 5
+ * flag is associated with a specific interrupt function.
+ * It is set when the FIFO full interrupt triggers. The
+ * setting of INT_LATCH controls if the
+ * interrupt signal and hence the
+ * respective interrupt flag will
+ * be permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_fifo_full_intr_u8 : The status of fifo full interrupt
+ *
+ * @note FIFO full interrupt can be configured by following functions
+ * @note smi130_set_intr_fifo_full()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat1_fifo_full_intr(u8
+*v_fifo_full_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_1_FIFO_FULL_INTR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_full_intr_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_1_FIFO_FULL_INTR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads data
+ * ready FIFO watermark interrupt status
+ * from the register 0x1D bit 6
+ * flag is associated with a specific interrupt function.
+ * It is set when the FIFO watermark interrupt triggers. The
+ * setting of INT_LATCH controls if the
+ * interrupt signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_fifo_wm_intr_u8 : The status of fifo water mark interrupt
+ *
+ * @note FIFO full interrupt can be configured by following functions
+ * @note smi130_set_intr_fifo_wm()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat1_fifo_wm_intr(u8
+*v_fifo_wm_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_1_FIFO_WM_INTR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_wm_intr_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_1_FIFO_WM_INTR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads data ready no motion interrupt status
+ * from the register 0x1D bit 7
+ * flag is associated with a specific interrupt function.
+ * It is set when the no motion interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt signal and hence the
+ * respective interrupt flag will be permanently
+ * latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_nomotion_intr_u8 : The status of no motion interrupt
+ *
+ * @note No motion interrupt can be configured by following function
+ * @note STATUS
+ * @note smi130_get_stat1_nomotion_intr()
+ * @note INTERRUPT MAPPING
+ * @note smi130_set_intr_nomotion()
+ * @note DURATION
+ * @note smi130_set_intr_slow_no_motion_durn()
+ * @note THRESHOLD
+ * @note smi130_set_intr_slow_no_motion_thres()
+ * @note SLOW/NO MOTION SELECT
+ * @note smi130_set_intr_slow_no_motion_select()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat1_nomotion_intr(u8
+*v_nomotion_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the no motion interrupt*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_1_NOMOTION_INTR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_nomotion_intr_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_1_NOMOTION_INTR);
+ }
+ return com_rslt;
+}
+/*!
+ *@brief This API reads the status of any motion first x
+ * from the register 0x1E bit 0
+ *
+ *
+ *@param v_anymotion_first_x_u8 : The status of any motion first x interrupt
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by x axis
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_any_motion_first_x(u8
+*v_anymotion_first_x_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the any motion first x interrupt*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_X__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_anymotion_first_x_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_X);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the status of any motion first y interrupt
+ * from the register 0x1E bit 1
+ *
+ *
+ *
+ *@param v_any_motion_first_y_u8 : The status of any motion first y interrupt
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_any_motion_first_y(u8
+*v_any_motion_first_y_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the any motion first y interrupt*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_Y__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_any_motion_first_y_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_Y);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the status of any motion first z interrupt
+ * from the register 0x1E bit 2
+ *
+ *
+ *
+ *
+ *@param v_any_motion_first_z_u8 : The status of any motion first z interrupt
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_any_motion_first_z(u8
+*v_any_motion_first_z_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the any motion first z interrupt*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_Z__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_any_motion_first_z_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_Z);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the any motion sign status from the
+ * register 0x1E bit 3
+ *
+ *
+ *
+ *
+ * @param v_anymotion_sign_u8 : The status of any motion sign
+ * value | sign
+ * -----------|-------------
+ * 0 | positive
+ * 1 | negative
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_any_motion_sign(u8
+*v_anymotion_sign_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read any motion sign interrupt status */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_2_ANY_MOTION_SIGN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_anymotion_sign_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_2_ANY_MOTION_SIGN);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the any motion tap first x status from the
+ * register 0x1E bit 4
+ *
+ *
+ *
+ *
+ * @param v_tap_first_x_u8 :The status of any motion tap first x
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by x axis
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_tap_first_x(u8
+*v_tap_first_x_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read tap first x interrupt status */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_2_TAP_FIRST_X__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_tap_first_x_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_2_TAP_FIRST_X);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the tap first y interrupt status from the
+ * register 0x1E bit 5
+ *
+ *
+ *
+ *
+ * @param v_tap_first_y_u8 :The status of tap first y interrupt
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_tap_first_y(u8
+*v_tap_first_y_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read tap first y interrupt status */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_2_TAP_FIRST_Y__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_tap_first_y_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_2_TAP_FIRST_Y);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the tap first z interrupt status from the
+ * register 0x1E bit 6
+ *
+ *
+ *
+ *
+ * @param v_tap_first_z_u8 :The status of tap first z interrupt
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_tap_first_z(u8
+*v_tap_first_z_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read tap first z interrupt status */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_2_TAP_FIRST_Z__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_tap_first_z_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_2_TAP_FIRST_Z);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the tap sign status from the
+ * register 0x1E bit 7
+ *
+ *
+ *
+ *
+ * @param v_tap_sign_u8 : The status of tap sign
+ * value | sign
+ * -----------|-------------
+ * 0 | positive
+ * 1 | negative
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_tap_sign(u8
+*v_tap_sign_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read tap_sign interrupt status */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_2_TAP_SIGN__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_tap_sign_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_2_TAP_SIGN);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the high_g first x status from the
+ * register 0x1F bit 0
+ *
+ *
+ *
+ *
+ * @param v_high_g_first_x_u8 :The status of high_g first x
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by x axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat3_high_g_first_x(u8
+*v_high_g_first_x_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read highg_x interrupt status */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_X__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_high_g_first_x_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_X);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the high_g first y status from the
+ * register 0x1F bit 1
+ *
+ *
+ *
+ *
+ * @param v_high_g_first_y_u8 : The status of high_g first y
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat3_high_g_first_y(u8
+*v_high_g_first_y_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read highg_y interrupt status */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_Y__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_high_g_first_y_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_Y);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the high_g first z status from the
+ * register 0x1F bit 3
+ *
+ *
+ *
+ *
+ * @param v_high_g_first_z_u8 : The status of high_g first z
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat3_high_g_first_z(u8
+*v_high_g_first_z_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read highg_z interrupt status */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_Z__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_high_g_first_z_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_Z);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the high sign status from the
+ * register 0x1F bit 3
+ *
+ *
+ *
+ *
+ * @param v_high_g_sign_u8 :The status of high sign
+ * value | sign
+ * -----------|-------------
+ * 0 | positive
+ * 1 | negative
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat3_high_g_sign(u8
+*v_high_g_sign_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read highg_sign interrupt status */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_3_HIGH_G_SIGN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_high_g_sign_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_3_HIGH_G_SIGN);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the status of orient_mbl_xy plane
+ * from the register 0x1F bit 4 and 5
+ *
+ *
+ * @param v_orient_mbl_xy_u8 :The status of orient_mbl_xy plane
+ * value | status
+ * -----------|-------------
+ * 0x00 | portrait upright
+ * 0x01 | portrait upside down
+ * 0x02 | landscape left
+ * 0x03 | landscape right
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat3_orient_mbl_xy(u8
+*v_orient_mbl_xy_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read orient_mbl plane xy interrupt status */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_3_ORIENT_XY__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_orient_mbl_xy_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_3_ORIENT_XY);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the status of orient_mbl z plane
+ * from the register 0x1F bit 6
+ *
+ *
+ * @param v_orient_mbl_z_u8 :The status of orient_mbl z
+ * value | status
+ * -----------|-------------
+ * 0x00 | upward looking
+ * 0x01 | downward looking
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat3_orient_mbl_z(u8
+*v_orient_mbl_z_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read orient_mbl z plane interrupt status */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_3_ORIENT_Z__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_orient_mbl_z_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_3_ORIENT_Z);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the flat status from the register
+ * 0x1F bit 7
+ *
+ *
+ * @param v_flat_u8 : The status of flat interrupt
+ * value | status
+ * -----------|-------------
+ * 0x00 | non flat
+ * 0x01 | flat position
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat3_flat(u8
+*v_flat_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read flat interrupt status */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_3_FLAT__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_flat_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_3_FLAT);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the temperature of the sensor
+ * from the register 0x21 bit 0 to 7
+ *
+ *
+ *
+ * @param v_temp_s16 : The value of temperature
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_temp(s16
+*v_temp_s16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the temperature lSB and MSB data
+ v_data_u8[0] - LSB
+ v_data_u8[1] - MSB*/
+ u8 v_data_u8[SMI130_TEMP_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read temperature data */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_TEMP_LSB_VALUE__REG, v_data_u8,
+ SMI130_TEMP_DATA_LENGTH);
+ *v_temp_s16 =
+ (s16)(((s32)((s8) (v_data_u8[SMI130_TEMP_MSB_BYTE]) <<
+ SMI130_SHIFT_BIT_POSITION_BY_08_BITS))
+ | v_data_u8[SMI130_TEMP_LSB_BYTE]);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the of the sensor
+ * form the register 0x23 and 0x24 bit 0 to 7 and 0 to 2
+ * @brief this byte counter is updated each time a complete frame
+ * was read or writtern
+ *
+ *
+ * @param v_fifo_length_u32 : The value of fifo byte counter
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_fifo_length(u32 *v_fifo_length_u32)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the fifo length data
+ v_data_u8[0] - fifo length
+ v_data_u8[1] - fifo length*/
+ u8 a_data_u8r[SMI130_FIFO_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read fifo length*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_BYTE_COUNTER_LSB__REG, a_data_u8r,
+ SMI130_FIFO_DATA_LENGTH);
+
+ a_data_u8r[SMI130_FIFO_LENGTH_MSB_BYTE] =
+ SMI130_GET_BITSLICE(
+ a_data_u8r[SMI130_FIFO_LENGTH_MSB_BYTE],
+ SMI130_USER_FIFO_BYTE_COUNTER_MSB);
+
+ *v_fifo_length_u32 =
+ (u32)(((u32)((u8) (
+ a_data_u8r[SMI130_FIFO_LENGTH_MSB_BYTE]) <<
+ SMI130_SHIFT_BIT_POSITION_BY_08_BITS))
+ | a_data_u8r[SMI130_FIFO_LENGTH_LSB_BYTE]);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the fifo data of the sensor
+ * from the register 0x24
+ * @brief Data format depends on the setting of register FIFO_CONFIG
+ *
+ *
+ *
+ * @param v_fifodata_u8 : Pointer holding the fifo data
+ * @param fifo_length_u16 : The value of fifo length maximum
+ * 1024
+ *
+ * @note For reading FIFO data use the following functions
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_fifo_data(
+u8 *v_fifodata_u8, u16 v_fifo_length_u16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read fifo data*/
+ com_rslt =
+ p_smi130->SMI130_BURST_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_DATA__REG,
+ v_fifodata_u8, v_fifo_length_u16);
+
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to get the
+ * accel output date rate form the register 0x40 bit 0 to 3
+ *
+ *
+ * @param v_output_data_rate_u8 :The value of accel output date rate
+ * value | output data rate
+ * -------|--------------------------
+ * 0 | SMI130_ACCEL_OUTPUT_DATA_RATE_RESERVED
+ * 1 | SMI130_ACCEL_OUTPUT_DATA_RATE_0_78HZ
+ * 2 | SMI130_ACCEL_OUTPUT_DATA_RATE_1_56HZ
+ * 3 | SMI130_ACCEL_OUTPUT_DATA_RATE_3_12HZ
+ * 4 | SMI130_ACCEL_OUTPUT_DATA_RATE_6_25HZ
+ * 5 | SMI130_ACCEL_OUTPUT_DATA_RATE_12_5HZ
+ * 6 | SMI130_ACCEL_OUTPUT_DATA_RATE_25HZ
+ * 7 | SMI130_ACCEL_OUTPUT_DATA_RATE_50HZ
+ * 8 | SMI130_ACCEL_OUTPUT_DATA_RATE_100HZ
+ * 9 | SMI130_ACCEL_OUTPUT_DATA_RATE_200HZ
+ * 10 | SMI130_ACCEL_OUTPUT_DATA_RATE_400HZ
+ * 11 | SMI130_ACCEL_OUTPUT_DATA_RATE_800HZ
+ * 12 | SMI130_ACCEL_OUTPUT_DATA_RATE_1600HZ
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_output_data_rate(
+u8 *v_output_data_rate_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the accel output data rate*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_output_data_rate_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set the
+ * accel output date rate form the register 0x40 bit 0 to 3
+ *
+ *
+ * @param v_output_data_rate_u8 :The value of accel output date rate
+ * value | output data rate
+ * -------|--------------------------
+ * 0 | SMI130_ACCEL_OUTPUT_DATA_RATE_RESERVED
+ * 1 | SMI130_ACCEL_OUTPUT_DATA_RATE_0_78HZ
+ * 2 | SMI130_ACCEL_OUTPUT_DATA_RATE_1_56HZ
+ * 3 | SMI130_ACCEL_OUTPUT_DATA_RATE_3_12HZ
+ * 4 | SMI130_ACCEL_OUTPUT_DATA_RATE_6_25HZ
+ * 5 | SMI130_ACCEL_OUTPUT_DATA_RATE_12_5HZ
+ * 6 | SMI130_ACCEL_OUTPUT_DATA_RATE_25HZ
+ * 7 | SMI130_ACCEL_OUTPUT_DATA_RATE_50HZ
+ * 8 | SMI130_ACCEL_OUTPUT_DATA_RATE_100HZ
+ * 9 | SMI130_ACCEL_OUTPUT_DATA_RATE_200HZ
+ * 10 | SMI130_ACCEL_OUTPUT_DATA_RATE_400HZ
+ * 11 | SMI130_ACCEL_OUTPUT_DATA_RATE_800HZ
+ * 12 | SMI130_ACCEL_OUTPUT_DATA_RATE_1600HZ
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_output_data_rate(
+u8 v_output_data_rate_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* accel output data rate selection */
+ if ((v_output_data_rate_u8 != SMI130_INIT_VALUE) &&
+ (v_output_data_rate_u8 <= SMI130_MAX_ACCEL_OUTPUT_DATA_RATE)) {
+ /* write accel output data rate */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE,
+ v_output_data_rate_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to get the
+ * accel bandwidth from the register 0x40 bit 4 to 6
+ * @brief bandwidth parameter determines filter configuration(acc_us=0)
+ * and averaging for under sampling mode(acc_us=1)
+ *
+ *
+ * @param v_bw_u8 : The value of accel bandwidth
+ *
+ * @note accel bandwidth depends on under sampling parameter
+ * @note under sampling parameter cab be set by the function
+ * "SMI130_SET_ACCEL_UNDER_SAMPLING_PARAMETER"
+ *
+ * @note Filter configuration
+ * accel_us | Filter configuration
+ * -----------|---------------------
+ * 0x00 | OSR4 mode
+ * 0x01 | OSR2 mode
+ * 0x02 | normal mode
+ * 0x03 | CIC mode
+ * 0x04 | Reserved
+ * 0x05 | Reserved
+ * 0x06 | Reserved
+ * 0x07 | Reserved
+ *
+ * @note accel under sampling mode
+ * accel_us | Under sampling mode
+ * -----------|---------------------
+ * 0x00 | no averaging
+ * 0x01 | average 2 samples
+ * 0x02 | average 4 samples
+ * 0x03 | average 8 samples
+ * 0x04 | average 16 samples
+ * 0x05 | average 32 samples
+ * 0x06 | average 64 samples
+ * 0x07 | average 128 samples
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_bw(u8 *v_bw_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the accel bandwidth */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_ACCEL_CONFIG_ACCEL_BW__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_bw_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_ACCEL_CONFIG_ACCEL_BW);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set the
+ * accel bandwidth from the register 0x40 bit 4 to 6
+ * @brief bandwidth parameter determines filter configuration(acc_us=0)
+ * and averaging for under sampling mode(acc_us=1)
+ *
+ *
+ * @param v_bw_u8 : The value of accel bandwidth
+ *
+ * @note accel bandwidth depends on under sampling parameter
+ * @note under sampling parameter cab be set by the function
+ * "SMI130_SET_ACCEL_UNDER_SAMPLING_PARAMETER"
+ *
+ * @note Filter configuration
+ * accel_us | Filter configuration
+ * -----------|---------------------
+ * 0x00 | OSR4 mode
+ * 0x01 | OSR2 mode
+ * 0x02 | normal mode
+ * 0x03 | CIC mode
+ * 0x04 | Reserved
+ * 0x05 | Reserved
+ * 0x06 | Reserved
+ * 0x07 | Reserved
+ *
+ * @note accel under sampling mode
+ * accel_us | Under sampling mode
+ * -----------|---------------------
+ * 0x00 | no averaging
+ * 0x01 | average 2 samples
+ * 0x02 | average 4 samples
+ * 0x03 | average 8 samples
+ * 0x04 | average 16 samples
+ * 0x05 | average 32 samples
+ * 0x06 | average 64 samples
+ * 0x07 | average 128 samples
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_bw(u8 v_bw_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* select accel bandwidth*/
+ if (v_bw_u8 <= SMI130_MAX_ACCEL_BW) {
+ /* write accel bandwidth*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_ACCEL_CONFIG_ACCEL_BW__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_ACCEL_CONFIG_ACCEL_BW,
+ v_bw_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_ACCEL_CONFIG_ACCEL_BW__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to get the accel
+ * under sampling parameter form the register 0x40 bit 7
+ *
+ *
+ *
+ *
+ * @param v_accel_under_sampling_u8 : The value of accel under sampling
+ * value | under_sampling
+ * ----------|---------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_under_sampling_parameter(
+u8 *v_accel_under_sampling_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the accel under sampling parameter */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_under_sampling_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set the accel
+ * under sampling parameter form the register 0x40 bit 7
+ *
+ *
+ *
+ *
+ * @param v_accel_under_sampling_u8 : The value of accel under sampling
+ * value | under_sampling
+ * ----------|---------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_under_sampling_parameter(
+u8 v_accel_under_sampling_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_accel_under_sampling_u8 <= SMI130_MAX_UNDER_SAMPLING) {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ /* write the accel under sampling parameter */
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING,
+ v_accel_under_sampling_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+}
+return com_rslt;
+}
+/*!
+ * @brief This API is used to get the ranges
+ * (g values) of the accel from the register 0x41 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_range_u8 : The value of accel g range
+ * value | g_range
+ * ----------|-----------
+ * 0x03 | SMI130_ACCEL_RANGE_2G
+ * 0x05 | SMI130_ACCEL_RANGE_4G
+ * 0x08 | SMI130_ACCEL_RANGE_8G
+ * 0x0C | SMI130_ACCEL_RANGE_16G
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_range(
+u8 *v_range_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the accel range*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_ACCEL_RANGE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_range_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_ACCEL_RANGE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set the ranges
+ * (g values) of the accel from the register 0x41 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_range_u8 : The value of accel g range
+ * value | g_range
+ * ----------|-----------
+ * 0x03 | SMI130_ACCEL_RANGE_2G
+ * 0x05 | SMI130_ACCEL_RANGE_4G
+ * 0x08 | SMI130_ACCEL_RANGE_8G
+ * 0x0C | SMI130_ACCEL_RANGE_16G
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_range(u8 v_range_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if ((v_range_u8 == SMI130_ACCEL_RANGE0) ||
+ (v_range_u8 == SMI130_ACCEL_RANGE1) ||
+ (v_range_u8 == SMI130_ACCEL_RANGE3) ||
+ (v_range_u8 == SMI130_ACCEL_RANGE4)) {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_ACCEL_RANGE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(
+ v_data_u8, SMI130_USER_ACCEL_RANGE,
+ v_range_u8);
+ /* write the accel range*/
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_ACCEL_RANGE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to get the
+ * gyroscope output data rate from the register 0x42 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_output_data_rate_u8 :The value of gyro output data rate
+ * value | gyro output data rate
+ * -----------|-----------------------------
+ * 0x00 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x01 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x02 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x03 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x04 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x05 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x06 | SMI130_GYRO_OUTPUT_DATA_RATE_25HZ
+ * 0x07 | SMI130_GYRO_OUTPUT_DATA_RATE_50HZ
+ * 0x08 | SMI130_GYRO_OUTPUT_DATA_RATE_100HZ
+ * 0x09 | SMI130_GYRO_OUTPUT_DATA_RATE_200HZ
+ * 0x0A | SMI130_GYRO_OUTPUT_DATA_RATE_400HZ
+ * 0x0B | SMI130_GYRO_OUTPUT_DATA_RATE_800HZ
+ * 0x0C | SMI130_GYRO_OUTPUT_DATA_RATE_1600HZ
+ * 0x0D | SMI130_GYRO_OUTPUT_DATA_RATE_3200HZ
+ * 0x0E | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x0F | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_output_data_rate(
+u8 *v_output_data_rate_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the gyro output data rate*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_GYRO_CONFIG_OUTPUT_DATA_RATE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_output_data_rate_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_GYRO_CONFIG_OUTPUT_DATA_RATE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set the
+ * gyroscope output data rate from the register 0x42 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_output_data_rate_u8 :The value of gyro output data rate
+ * value | gyro output data rate
+ * -----------|-----------------------------
+ * 0x00 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x01 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x02 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x03 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x04 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x05 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x06 | SMI130_GYRO_OUTPUT_DATA_RATE_25HZ
+ * 0x07 | SMI130_GYRO_OUTPUT_DATA_RATE_50HZ
+ * 0x08 | SMI130_GYRO_OUTPUT_DATA_RATE_100HZ
+ * 0x09 | SMI130_GYRO_OUTPUT_DATA_RATE_200HZ
+ * 0x0A | SMI130_GYRO_OUTPUT_DATA_RATE_400HZ
+ * 0x0B | SMI130_GYRO_OUTPUT_DATA_RATE_800HZ
+ * 0x0C | SMI130_GYRO_OUTPUT_DATA_RATE_1600HZ
+ * 0x0D | SMI130_GYRO_OUTPUT_DATA_RATE_3200HZ
+ * 0x0E | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x0F | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_output_data_rate(
+u8 v_output_data_rate_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* select the gyro output data rate*/
+ if ((v_output_data_rate_u8 < SMI130_OUTPUT_DATA_RATE6) &&
+ (v_output_data_rate_u8 != SMI130_INIT_VALUE)
+ && (v_output_data_rate_u8 != SMI130_OUTPUT_DATA_RATE1)
+ && (v_output_data_rate_u8 != SMI130_OUTPUT_DATA_RATE2)
+ && (v_output_data_rate_u8 != SMI130_OUTPUT_DATA_RATE3)
+ && (v_output_data_rate_u8 != SMI130_OUTPUT_DATA_RATE4)
+ && (v_output_data_rate_u8 != SMI130_OUTPUT_DATA_RATE5)
+ && (v_output_data_rate_u8 != SMI130_OUTPUT_DATA_RATE6)
+ && (v_output_data_rate_u8 != SMI130_OUTPUT_DATA_RATE7)) {
+ /* write the gyro output data rate */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_GYRO_CONFIG_OUTPUT_DATA_RATE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_GYRO_CONFIG_OUTPUT_DATA_RATE,
+ v_output_data_rate_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_GYRO_CONFIG_OUTPUT_DATA_RATE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to get the
+ * data of gyro from the register 0x42 bit 4 to 5
+ *
+ *
+ *
+ *
+ * @param v_bw_u8 : The value of gyro bandwidth
+ * value | gyro bandwidth
+ * ----------|----------------
+ * 0x00 | SMI130_GYRO_OSR4_MODE
+ * 0x01 | SMI130_GYRO_OSR2_MODE
+ * 0x02 | SMI130_GYRO_NORMAL_MODE
+ * 0x03 | SMI130_GYRO_CIC_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_bw(u8 *v_bw_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read gyro bandwidth*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_GYRO_CONFIG_BW__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_bw_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_GYRO_CONFIG_BW);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set the
+ * data of gyro from the register 0x42 bit 4 to 5
+ *
+ *
+ *
+ *
+ * @param v_bw_u8 : The value of gyro bandwidth
+ * value | gyro bandwidth
+ * ----------|----------------
+ * 0x00 | SMI130_GYRO_OSR4_MODE
+ * 0x01 | SMI130_GYRO_OSR2_MODE
+ * 0x02 | SMI130_GYRO_NORMAL_MODE
+ * 0x03 | SMI130_GYRO_CIC_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_bw(u8 v_bw_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_bw_u8 <= SMI130_MAX_GYRO_BW) {
+ /* write the gyro bandwidth*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_GYRO_CONFIG_BW__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_GYRO_CONFIG_BW, v_bw_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_CONFIG_BW__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads the range
+ * of gyro from the register 0x43 bit 0 to 2
+ *
+ * @param v_range_u8 : The value of gyro range
+ * value | range
+ * ----------|-------------------------------
+ * 0x00 | SMI130_GYRO_RANGE_2000_DEG_SEC
+ * 0x01 | SMI130_GYRO_RANGE_1000_DEG_SEC
+ * 0x02 | SMI130_GYRO_RANGE_500_DEG_SEC
+ * 0x03 | SMI130_GYRO_RANGE_250_DEG_SEC
+ * 0x04 | SMI130_GYRO_RANGE_125_DEG_SEC
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_range(u8 *v_range_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the gyro range */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_GYRO_RANGE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_range_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_GYRO_RANGE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API set the range
+ * of gyro from the register 0x43 bit 0 to 2
+ *
+ * @param v_range_u8 : The value of gyro range
+ * value | range
+ * ----------|-------------------------------
+ * 0x00 | SMI130_GYRO_RANGE_2000_DEG_SEC
+ * 0x01 | SMI130_GYRO_RANGE_1000_DEG_SEC
+ * 0x02 | SMI130_GYRO_RANGE_500_DEG_SEC
+ * 0x03 | SMI130_GYRO_RANGE_250_DEG_SEC
+ * 0x04 | SMI130_GYRO_RANGE_125_DEG_SEC
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_range(u8 v_range_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_range_u8 <= SMI130_MAX_GYRO_RANGE) {
+ /* write the gyro range value */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_GYRO_RANGE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_GYRO_RANGE,
+ v_range_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_GYRO_RANGE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to get the
+ * output data rate of magnetometer from the register 0x44 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_output_data_rat_u8e : The value of mag output data rate
+ * value | mag output data rate
+ * ---------|---------------------------
+ * 0x00 |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED
+ * 0x01 |SMI130_MAG_OUTPUT_DATA_RATE_0_78HZ
+ * 0x02 |SMI130_MAG_OUTPUT_DATA_RATE_1_56HZ
+ * 0x03 |SMI130_MAG_OUTPUT_DATA_RATE_3_12HZ
+ * 0x04 |SMI130_MAG_OUTPUT_DATA_RATE_6_25HZ
+ * 0x05 |SMI130_MAG_OUTPUT_DATA_RATE_12_5HZ
+ * 0x06 |SMI130_MAG_OUTPUT_DATA_RATE_25HZ
+ * 0x07 |SMI130_MAG_OUTPUT_DATA_RATE_50HZ
+ * 0x08 |SMI130_MAG_OUTPUT_DATA_RATE_100HZ
+ * 0x09 |SMI130_MAG_OUTPUT_DATA_RATE_200HZ
+ * 0x0A |SMI130_MAG_OUTPUT_DATA_RATE_400HZ
+ * 0x0B |SMI130_MAG_OUTPUT_DATA_RATE_800HZ
+ * 0x0C |SMI130_MAG_OUTPUT_DATA_RATE_1600HZ
+ * 0x0D |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED0
+ * 0x0E |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED1
+ * 0x0F |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED2
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_output_data_rate(
+u8 *v_output_data_rat_u8e)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the mag data output rate*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_MAG_CONFIG_OUTPUT_DATA_RATE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_output_data_rat_u8e = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_MAG_CONFIG_OUTPUT_DATA_RATE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set the
+ * output data rate of magnetometer from the register 0x44 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_output_data_rat_u8e : The value of mag output data rate
+ * value | mag output data rate
+ * ---------|---------------------------
+ * 0x00 |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED
+ * 0x01 |SMI130_MAG_OUTPUT_DATA_RATE_0_78HZ
+ * 0x02 |SMI130_MAG_OUTPUT_DATA_RATE_1_56HZ
+ * 0x03 |SMI130_MAG_OUTPUT_DATA_RATE_3_12HZ
+ * 0x04 |SMI130_MAG_OUTPUT_DATA_RATE_6_25HZ
+ * 0x05 |SMI130_MAG_OUTPUT_DATA_RATE_12_5HZ
+ * 0x06 |SMI130_MAG_OUTPUT_DATA_RATE_25HZ
+ * 0x07 |SMI130_MAG_OUTPUT_DATA_RATE_50HZ
+ * 0x08 |SMI130_MAG_OUTPUT_DATA_RATE_100HZ
+ * 0x09 |SMI130_MAG_OUTPUT_DATA_RATE_200HZ
+ * 0x0A |SMI130_MAG_OUTPUT_DATA_RATE_400HZ
+ * 0x0B |SMI130_MAG_OUTPUT_DATA_RATE_800HZ
+ * 0x0C |SMI130_MAG_OUTPUT_DATA_RATE_1600HZ
+ * 0x0D |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED0
+ * 0x0E |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED1
+ * 0x0F |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED2
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_output_data_rate(
+u8 v_output_data_rat_u8e)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* select the mag data output rate*/
+ if ((v_output_data_rat_u8e
+ <= SMI130_MAX_ACCEL_OUTPUT_DATA_RATE)
+ && (v_output_data_rat_u8e
+ != SMI130_OUTPUT_DATA_RATE0)
+ && (v_output_data_rat_u8e
+ != SMI130_OUTPUT_DATA_RATE6)
+ && (v_output_data_rat_u8e
+ != SMI130_OUTPUT_DATA_RATE7)) {
+ /* write the mag data output rate*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_MAG_CONFIG_OUTPUT_DATA_RATE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_MAG_CONFIG_OUTPUT_DATA_RATE,
+ v_output_data_rat_u8e);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_MAG_CONFIG_OUTPUT_DATA_RATE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API is used to read Down sampling
+ * for gyro (2**downs_gyro) in the register 0x45 bit 0 to 2
+ *
+ *
+ *
+ *
+ * @param v_fifo_down_gyro_u8 :The value of gyro fifo down
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_down_gyro(
+u8 *v_fifo_down_gyro_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the gyro fifo down*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_DOWN_GYRO__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_down_gyro_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_DOWN_GYRO);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API is used to set Down sampling
+ * for gyro (2**downs_gyro) in the register 0x45 bit 0 to 2
+ *
+ *
+ *
+ *
+ * @param v_fifo_down_gyro_u8 :The value of gyro fifo down
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_down_gyro(
+u8 v_fifo_down_gyro_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write the gyro fifo down*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_DOWN_GYRO__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_FIFO_DOWN_GYRO,
+ v_fifo_down_gyro_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FIFO_DOWN_GYRO__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read gyro fifo filter data
+ * from the register 0x45 bit 3
+ *
+ *
+ *
+ * @param v_gyro_fifo_filter_data_u8 :The value of gyro filter data
+ * value | gyro_fifo_filter_data
+ * ------------|-------------------------
+ * 0x00 | Unfiltered data
+ * 0x01 | Filtered data
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_fifo_filter_data(
+u8 *v_gyro_fifo_filter_data_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the gyro fifo filter data */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_FILTER_GYRO__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_gyro_fifo_filter_data_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_FILTER_GYRO);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set gyro fifo filter data
+ * from the register 0x45 bit 3
+ *
+ *
+ *
+ * @param v_gyro_fifo_filter_data_u8 :The value of gyro filter data
+ * value | gyro_fifo_filter_data
+ * ------------|-------------------------
+ * 0x00 | Unfiltered data
+ * 0x01 | Filtered data
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_fifo_filter_data(
+u8 v_gyro_fifo_filter_data_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_gyro_fifo_filter_data_u8
+ <= SMI130_MAX_VALUE_FIFO_FILTER) {
+ /* write the gyro fifo filter data */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_FILTER_GYRO__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_FIFO_FILTER_GYRO,
+ v_gyro_fifo_filter_data_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FIFO_FILTER_GYRO__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read Down sampling
+ * for accel (2*downs_accel) from the register 0x45 bit 4 to 6
+ *
+ *
+ *
+ *
+ * @param v_fifo_down_u8 :The value of accel fifo down
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_down_accel(
+u8 *v_fifo_down_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the accel fifo down data */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_DOWN_ACCEL__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_down_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_DOWN_ACCEL);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API is used to set Down sampling
+ * for accel (2*downs_accel) from the register 0x45 bit 4 to 6
+ *
+ *
+ *
+ *
+ * @param v_fifo_down_u8 :The value of accel fifo down
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_down_accel(
+u8 v_fifo_down_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write the accel fifo down data */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_DOWN_ACCEL__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_DOWN_ACCEL, v_fifo_down_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FIFO_DOWN_ACCEL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read accel fifo filter data
+ * from the register 0x45 bit 7
+ *
+ *
+ *
+ * @param v_accel_fifo_filter_u8 :The value of accel filter data
+ * value | accel_fifo_filter_data
+ * ------------|-------------------------
+ * 0x00 | Unfiltered data
+ * 0x01 | Filtered data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_fifo_filter_data(
+u8 *v_accel_fifo_filter_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the accel fifo filter data */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_FILTER_ACCEL__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_fifo_filter_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_FILTER_ACCEL);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set accel fifo filter data
+ * from the register 0x45 bit 7
+ *
+ *
+ *
+ * @param v_accel_fifo_filter_u8 :The value of accel filter data
+ * value | accel_fifo_filter_data
+ * ------------|-------------------------
+ * 0x00 | Unfiltered data
+ * 0x01 | Filtered data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_fifo_filter_data(
+u8 v_accel_fifo_filter_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_accel_fifo_filter_u8 <= SMI130_MAX_VALUE_FIFO_FILTER) {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_FILTER_ACCEL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ /* write accel fifo filter data */
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_FILTER_ACCEL,
+ v_accel_fifo_filter_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FIFO_FILTER_ACCEL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to Trigger an interrupt
+ * when FIFO contains water mark level from the register 0x46 bit 0 to 7
+ *
+ *
+ *
+ * @param v_fifo_wm_u8 : The value of fifo water mark level
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_wm(
+u8 *v_fifo_wm_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the fifo water mark level*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_WM__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_wm_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_WM);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to Trigger an interrupt
+ * when FIFO contains water mark level from the register 0x46 bit 0 to 7
+ *
+ *
+ *
+ * @param v_fifo_wm_u8 : The value of fifo water mark level
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_wm(
+u8 v_fifo_wm_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write the fifo water mark level*/
+ com_rslt =
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_WM__REG,
+ &v_fifo_wm_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads fifo sensor time
+ * frame after the last valid data frame form the register 0x47 bit 1
+ *
+ *
+ *
+ *
+ * @param v_fifo_time_enable_u8 : The value of sensor time
+ * value | fifo sensor time
+ * ------------|-------------------------
+ * 0x00 | do not return sensortime frame
+ * 0x01 | return sensortime frame
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_time_enable(
+u8 *v_fifo_time_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the fifo sensor time*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_TIME_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_time_enable_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_TIME_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API set fifo sensor time
+ * frame after the last valid data frame form the register 0x47 bit 1
+ *
+ *
+ *
+ *
+ * @param v_fifo_time_enable_u8 : The value of sensor time
+ * value | fifo sensor time
+ * ------------|-------------------------
+ * 0x00 | do not return sensortime frame
+ * 0x01 | return sensortime frame
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_time_enable(
+u8 v_fifo_time_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_fifo_time_enable_u8 <= SMI130_MAX_VALUE_FIFO_TIME) {
+ /* write the fifo sensor time*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_TIME_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_TIME_ENABLE,
+ v_fifo_time_enable_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FIFO_TIME_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads FIFO tag interrupt2 enable status
+ * from the resister 0x47 bit 2
+ *
+ * @param v_fifo_tag_intr2_u8 : The value of fifo tag interrupt
+ * value | fifo tag interrupt
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_tag_intr2_enable(
+u8 *v_fifo_tag_intr2_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the fifo tag interrupt2*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_TAG_INTR2_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_tag_intr2_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_TAG_INTR2_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API set FIFO tag interrupt2 enable status
+ * from the resister 0x47 bit 2
+ *
+ * @param v_fifo_tag_intr2_u8 : The value of fifo tag interrupt
+ * value | fifo tag interrupt
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_tag_intr2_enable(
+u8 v_fifo_tag_intr2_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_fifo_tag_intr2_u8 <= SMI130_MAX_VALUE_FIFO_INTR) {
+ /* write the fifo tag interrupt2*/
+ com_rslt = smi130_set_input_enable(1,
+ v_fifo_tag_intr2_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_TAG_INTR2_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_TAG_INTR2_ENABLE,
+ v_fifo_tag_intr2_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FIFO_TAG_INTR2_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API get FIFO tag interrupt1 enable status
+ * from the resister 0x47 bit 3
+ *
+ * @param v_fifo_tag_intr1_u8 :The value of fifo tag interrupt1
+ * value | fifo tag interrupt
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_tag_intr1_enable(
+u8 *v_fifo_tag_intr1_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read fifo tag interrupt*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_TAG_INTR1_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_tag_intr1_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_TAG_INTR1_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API set FIFO tag interrupt1 enable status
+ * from the resister 0x47 bit 3
+ *
+ * @param v_fifo_tag_intr1_u8 :The value of fifo tag interrupt1
+ * value | fifo tag interrupt
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_tag_intr1_enable(
+u8 v_fifo_tag_intr1_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_fifo_tag_intr1_u8 <= SMI130_MAX_VALUE_FIFO_INTR) {
+ /* write the fifo tag interrupt*/
+ com_rslt = smi130_set_input_enable(SMI130_INIT_VALUE,
+ v_fifo_tag_intr1_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_TAG_INTR1_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_TAG_INTR1_ENABLE,
+ v_fifo_tag_intr1_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FIFO_TAG_INTR1_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads FIFO frame
+ * header enable from the register 0x47 bit 4
+ *
+ * @param v_fifo_header_u8 :The value of fifo header
+ * value | fifo header
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_header_enable(
+u8 *v_fifo_header_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read fifo header */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_HEADER_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_header_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_HEADER_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API set FIFO frame
+ * header enable from the register 0x47 bit 4
+ *
+ * @param v_fifo_header_u8 :The value of fifo header
+ * value | fifo header
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_header_enable(
+u8 v_fifo_header_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_fifo_header_u8 <= SMI130_MAX_VALUE_FIFO_HEADER) {
+ /* write the fifo header */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_HEADER_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_HEADER_ENABLE,
+ v_fifo_header_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FIFO_HEADER_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read stored
+ * magnetometer data in FIFO (all 3 axes) from the register 0x47 bit 5
+ *
+ * @param v_fifo_mag_u8 : The value of fifo mag enble
+ * value | fifo mag
+ * ----------|-------------------
+ * 0x00 | no magnetometer data is stored
+ * 0x01 | magnetometer data is stored
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_mag_enable(
+u8 *v_fifo_mag_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the fifo mag enable*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_MAG_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_mag_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_MAG_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set stored
+ * magnetometer data in FIFO (all 3 axes) from the register 0x47 bit 5
+ *
+ * @param v_fifo_mag_u8 : The value of fifo mag enble
+ * value | fifo mag
+ * ----------|-------------------
+ * 0x00 | no magnetometer data is stored
+ * 0x01 | magnetometer data is stored
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_mag_enable(
+u8 v_fifo_mag_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_fifo_mag_u8 <= SMI130_MAX_VALUE_FIFO_MAG) {
+ /* write the fifo mag enable*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_FIFO_MAG_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_MAG_ENABLE,
+ v_fifo_mag_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_FIFO_MAG_ENABLE__REG,
+ &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read stored
+ * accel data in FIFO (all 3 axes) from the register 0x47 bit 6
+ *
+ * @param v_fifo_accel_u8 : The value of fifo accel enble
+ * value | fifo accel
+ * ----------|-------------------
+ * 0x00 | no accel data is stored
+ * 0x01 | accel data is stored
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_accel_enable(
+u8 *v_fifo_accel_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the accel fifo enable*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_ACCEL_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_accel_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_ACCEL_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set stored
+ * accel data in FIFO (all 3 axes) from the register 0x47 bit 6
+ *
+ * @param v_fifo_accel_u8 : The value of fifo accel enble
+ * value | fifo accel
+ * ----------|-------------------
+ * 0x00 | no accel data is stored
+ * 0x01 | accel data is stored
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_accel_enable(
+u8 v_fifo_accel_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_fifo_accel_u8 <= SMI130_MAX_VALUE_FIFO_ACCEL) {
+ /* write the fifo mag enables*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_ACCEL_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_ACCEL_ENABLE, v_fifo_accel_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FIFO_ACCEL_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read stored
+ * gyro data in FIFO (all 3 axes) from the resister 0x47 bit 7
+ *
+ *
+ * @param v_fifo_gyro_u8 : The value of fifo gyro enble
+ * value | fifo gyro
+ * ----------|-------------------
+ * 0x00 | no gyro data is stored
+ * 0x01 | gyro data is stored
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_gyro_enable(
+u8 *v_fifo_gyro_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read fifo gyro enable */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_GYRO_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_gyro_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_GYRO_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set stored
+ * gyro data in FIFO (all 3 axes) from the resister 0x47 bit 7
+ *
+ *
+ * @param v_fifo_gyro_u8 : The value of fifo gyro enble
+ * value | fifo gyro
+ * ----------|-------------------
+ * 0x00 | no gyro data is stored
+ * 0x01 | gyro data is stored
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_gyro_enable(
+u8 v_fifo_gyro_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_fifo_gyro_u8 <= SMI130_MAX_VALUE_FIFO_GYRO) {
+ /* write fifo gyro enable*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_GYRO_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_GYRO_ENABLE, v_fifo_gyro_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FIFO_GYRO_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read
+ * I2C device address of auxiliary mag from the register 0x4B bit 1 to 7
+ *
+ *
+ *
+ *
+ * @param v_i2c_device_addr_u8 : The value of mag I2C device address
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_i2c_device_addr(
+u8 *v_i2c_device_addr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the mag I2C device address*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_I2C_DEVICE_ADDR__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_i2c_device_addr_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_I2C_DEVICE_ADDR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set
+ * I2C device address of auxiliary mag from the register 0x4B bit 1 to 7
+ *
+ *
+ *
+ *
+ * @param v_i2c_device_addr_u8 : The value of mag I2C device address
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_i2c_device_addr(
+u8 v_i2c_device_addr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write the mag I2C device address*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_I2C_DEVICE_ADDR__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_I2C_DEVICE_ADDR,
+ v_i2c_device_addr_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_I2C_DEVICE_ADDR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read
+ * Burst data length (1,2,6,8 byte) from the register 0x4C bit 0 to 1
+ *
+ *
+ *
+ *
+ * @param v_mag_burst_u8 : The data of mag burst read lenth
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_burst(
+u8 *v_mag_burst_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read mag burst mode length*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_MAG_BURST__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_mag_burst_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_MAG_BURST);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set
+ * Burst data length (1,2,6,8 byte) from the register 0x4C bit 0 to 1
+ *
+ *
+ *
+ *
+ * @param v_mag_burst_u8 : The data of mag burst read lenth
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_burst(
+u8 v_mag_burst_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write mag burst mode length*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_MAG_BURST__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_MAG_BURST, v_mag_burst_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_MAG_BURST__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read
+ * trigger-readout offset in units of 2.5 ms. If set to zero,
+ * the offset is maximum, i.e. after readout a trigger
+ * is issued immediately. from the register 0x4C bit 2 to 5
+ *
+ *
+ *
+ *
+ * @param v_mag_offset_u8 : The value of mag offset
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_offset(
+u8 *v_mag_offset_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_MAG_OFFSET__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_mag_offset_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_MAG_OFFSET);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set
+ * trigger-readout offset in units of 2.5 ms. If set to zero,
+ * the offset is maximum, i.e. after readout a trigger
+ * is issued immediately. from the register 0x4C bit 2 to 5
+ *
+ *
+ *
+ *
+ * @param v_mag_offset_u8 : The value of mag offset
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_offset(
+u8 v_mag_offset_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_MAG_OFFSET__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_MAG_OFFSET, v_mag_offset_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->dev_addr,
+ SMI130_USER_MAG_OFFSET__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+return com_rslt;
+}
+/*!
+ * @brief This API is used to read
+ * Enable register access on MAG_IF[2] or MAG_IF[3] writes.
+ * This implies that the DATA registers are not updated with
+ * magnetometer values. Accessing magnetometer requires
+ * the magnetometer in normal mode in PMU_STATUS.
+ * from the register 0x4C bit 7
+ *
+ *
+ *
+ * @param v_mag_manual_u8 : The value of mag manual enable
+ * value | mag manual
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_manual_enable(
+u8 *v_mag_manual_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read mag manual */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_MAG_MANUAL_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_mag_manual_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_MAG_MANUAL_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set
+ * Enable register access on MAG_IF[2] or MAG_IF[3] writes.
+ * This implies that the DATA registers are not updated with
+ * magnetometer values. Accessing magnetometer requires
+ * the magnetometer in normal mode in PMU_STATUS.
+ * from the register 0x4C bit 7
+ *
+ *
+ *
+ * @param v_mag_manual_u8 : The value of mag manual enable
+ * value | mag manual
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_manual_enable(
+u8 v_mag_manual_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = SMI130_INIT_VALUE;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write the mag manual*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_MAG_MANUAL_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ if (com_rslt == SUCCESS) {
+ /* set the bit of mag manual enable*/
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_MAG_MANUAL_ENABLE, v_mag_manual_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->dev_addr,
+ SMI130_USER_MAG_MANUAL_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ if (com_rslt == SUCCESS)
+ p_smi130->mag_manual_enable = v_mag_manual_u8;
+ else
+ p_smi130->mag_manual_enable = E_SMI130_COMM_RES;
+ }
+return com_rslt;
+}
+/*!
+ * @brief This API is used to read data
+ * magnetometer address to read from the register 0x4D bit 0 to 7
+ * @brief It used to provide mag read address of auxiliary mag
+ *
+ *
+ *
+ *
+ * @param v_mag_read_addr_u8 : The value of address need to be read
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_read_addr(
+u8 *v_mag_read_addr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the written address*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_READ_ADDR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_mag_read_addr_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_READ_ADDR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set
+ * magnetometer write address from the register 0x4D bit 0 to 7
+ * @brief mag write address writes the address of auxiliary mag to write
+ *
+ *
+ *
+ * @param v_mag_read_addr_u8:
+ * The data of auxiliary mag address to write data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_read_addr(
+u8 v_mag_read_addr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write the mag read address*/
+ com_rslt =
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->dev_addr,
+ SMI130_USER_READ_ADDR__REG, &v_mag_read_addr_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read
+ * magnetometer write address from the register 0x4E bit 0 to 7
+ * @brief mag write address writes the address of auxiliary mag to write
+ *
+ *
+ *
+ * @param v_mag_write_addr_u8:
+ * The data of auxiliary mag address to write data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_write_addr(
+u8 *v_mag_write_addr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the address of last written */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_WRITE_ADDR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_mag_write_addr_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_WRITE_ADDR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set
+ * magnetometer write address from the register 0x4E bit 0 to 7
+ * @brief mag write address writes the address of auxiliary mag to write
+ *
+ *
+ *
+ * @param v_mag_write_addr_u8:
+ * The data of auxiliary mag address to write data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_write_addr(
+u8 v_mag_write_addr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write the data of mag address to write data */
+ com_rslt =
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->dev_addr,
+ SMI130_USER_WRITE_ADDR__REG, &v_mag_write_addr_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read magnetometer write data
+ * form the resister 0x4F bit 0 to 7
+ * @brief This writes the data will be wrote to mag
+ *
+ *
+ *
+ * @param v_mag_write_data_u8: The value of mag data
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_write_data(
+u8 *v_mag_write_data_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_WRITE_DATA__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_mag_write_data_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_WRITE_DATA);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set magnetometer write data
+ * form the resister 0x4F bit 0 to 7
+ * @brief This writes the data will be wrote to mag
+ *
+ *
+ *
+ * @param v_mag_write_data_u8: The value of mag data
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_write_data(
+u8 v_mag_write_data_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->dev_addr,
+ SMI130_USER_WRITE_DATA__REG, &v_mag_write_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read
+ * interrupt enable from the register 0x50 bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_enable_u8 : Value to decided to select interrupt
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_ANY_MOTION_X_ENABLE
+ * 1 | SMI130_ANY_MOTION_Y_ENABLE
+ * 2 | SMI130_ANY_MOTION_Z_ENABLE
+ * 3 | SMI130_DOUBLE_TAP_ENABLE
+ * 4 | SMI130_SINGLE_TAP_ENABLE
+ * 5 | SMI130_ORIENT_ENABLE
+ * 6 | SMI130_FLAT_ENABLE
+ *
+ * @param v_intr_enable_zero_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_enable_0(
+u8 v_enable_u8, u8 *v_intr_enable_zero_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* select interrupt to read*/
+ switch (v_enable_u8) {
+ case SMI130_ANY_MOTION_X_ENABLE:
+ /* read the any motion interrupt x data */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_zero_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE);
+ break;
+ case SMI130_ANY_MOTION_Y_ENABLE:
+ /* read the any motion interrupt y data */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_zero_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE);
+ break;
+ case SMI130_ANY_MOTION_Z_ENABLE:
+ /* read the any motion interrupt z data */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_zero_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE);
+ break;
+ case SMI130_DOUBLE_TAP_ENABLE:
+ /* read the double tap interrupt data */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_zero_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE);
+ break;
+ case SMI130_SINGLE_TAP_ENABLE:
+ /* read the single tap interrupt data */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_zero_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE);
+ break;
+ case SMI130_ORIENT_ENABLE:
+ /* read the orient_mbl interrupt data */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_ENABLE_0_ORIENT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_zero_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_0_ORIENT_ENABLE);
+ break;
+ case SMI130_FLAT_ENABLE:
+ /* read the flat interrupt data */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_ENABLE_0_FLAT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_zero_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_0_FLAT_ENABLE);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set
+ * interrupt enable from the register 0x50 bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_enable_u8 : Value to decided to select interrupt
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_ANY_MOTION_X_ENABLE
+ * 1 | SMI130_ANY_MOTION_Y_ENABLE
+ * 2 | SMI130_ANY_MOTION_Z_ENABLE
+ * 3 | SMI130_DOUBLE_TAP_ENABLE
+ * 4 | SMI130_SINGLE_TAP_ENABLE
+ * 5 | SMI130_ORIENT_ENABLE
+ * 6 | SMI130_FLAT_ENABLE
+ *
+ * @param v_intr_enable_zero_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_enable_0(
+u8 v_enable_u8, u8 v_intr_enable_zero_u8)
+{
+/* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_enable_u8) {
+ case SMI130_ANY_MOTION_X_ENABLE:
+ /* write any motion x*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE,
+ v_intr_enable_zero_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_ANY_MOTION_Y_ENABLE:
+ /* write any motion y*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE,
+ v_intr_enable_zero_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_ANY_MOTION_Z_ENABLE:
+ /* write any motion z*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE,
+ v_intr_enable_zero_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_DOUBLE_TAP_ENABLE:
+ /* write double tap*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE,
+ v_intr_enable_zero_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_SINGLE_TAP_ENABLE:
+ /* write single tap */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE,
+ v_intr_enable_zero_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_ORIENT_ENABLE:
+ /* write orient_mbl interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_ENABLE_0_ORIENT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_0_ORIENT_ENABLE,
+ v_intr_enable_zero_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_0_ORIENT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_FLAT_ENABLE:
+ /* write flat interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_ENABLE_0_FLAT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_0_FLAT_ENABLE,
+ v_intr_enable_zero_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_0_FLAT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+/*!
+ * @brief This API is used to read
+ * interrupt enable byte1 from the register 0x51 bit 0 to 6
+ * @brief It read the high_g_x,high_g_y,high_g_z,low_g_enable
+ * data ready, fifo full and fifo water mark.
+ *
+ *
+ *
+ * @param v_enable_u8 : The value of interrupt enable
+ * @param v_enable_u8 : Value to decided to select interrupt
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_HIGH_G_X_ENABLE
+ * 1 | SMI130_HIGH_G_Y_ENABLE
+ * 2 | SMI130_HIGH_G_Z_ENABLE
+ * 3 | SMI130_LOW_G_ENABLE
+ * 4 | SMI130_DATA_RDY_ENABLE
+ * 5 | SMI130_FIFO_FULL_ENABLE
+ * 6 | SMI130_FIFO_WM_ENABLE
+ *
+ * @param v_intr_enable_1_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_enable_1(
+u8 v_enable_u8, u8 *v_intr_enable_1_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_enable_u8) {
+ case SMI130_HIGH_G_X_ENABLE:
+ /* read high_g_x interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_1_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE);
+ break;
+ case SMI130_HIGH_G_Y_ENABLE:
+ /* read high_g_y interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_1_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE);
+ break;
+ case SMI130_HIGH_G_Z_ENABLE:
+ /* read high_g_z interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_1_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE);
+ break;
+ case SMI130_LOW_G_ENABLE:
+ /* read low_g interrupt */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_1_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_1_LOW_G_ENABLE);
+ break;
+ case SMI130_DATA_RDY_ENABLE:
+ /* read data ready interrupt */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_DATA_RDY_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_1_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_1_DATA_RDY_ENABLE);
+ break;
+ case SMI130_FIFO_FULL_ENABLE:
+ /* read fifo full interrupt */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_1_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE);
+ break;
+ case SMI130_FIFO_WM_ENABLE:
+ /* read fifo water mark interrupt */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_FIFO_WM_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_1_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_1_FIFO_WM_ENABLE);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set
+ * interrupt enable byte1 from the register 0x51 bit 0 to 6
+ * @brief It read the high_g_x,high_g_y,high_g_z,low_g_enable
+ * data ready, fifo full and fifo water mark.
+ *
+ *
+ *
+ * @param v_enable_u8 : The value of interrupt enable
+ * @param v_enable_u8 : Value to decided to select interrupt
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_HIGH_G_X_ENABLE
+ * 1 | SMI130_HIGH_G_Y_ENABLE
+ * 2 | SMI130_HIGH_G_Z_ENABLE
+ * 3 | SMI130_LOW_G_ENABLE
+ * 4 | SMI130_DATA_RDY_ENABLE
+ * 5 | SMI130_FIFO_FULL_ENABLE
+ * 6 | SMI130_FIFO_WM_ENABLE
+ *
+ * @param v_intr_enable_1_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_enable_1(
+u8 v_enable_u8, u8 v_intr_enable_1_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_enable_u8) {
+ case SMI130_HIGH_G_X_ENABLE:
+ /* write high_g_x interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE,
+ v_intr_enable_1_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_HIGH_G_Y_ENABLE:
+ /* write high_g_y interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE,
+ v_intr_enable_1_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_HIGH_G_Z_ENABLE:
+ /* write high_g_z interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE,
+ v_intr_enable_1_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_LOW_G_ENABLE:
+ /* write low_g interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_1_LOW_G_ENABLE,
+ v_intr_enable_1_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_DATA_RDY_ENABLE:
+ /* write data ready interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_DATA_RDY_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_1_DATA_RDY_ENABLE,
+ v_intr_enable_1_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_DATA_RDY_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_FIFO_FULL_ENABLE:
+ /* write fifo full interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE,
+ v_intr_enable_1_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_FIFO_WM_ENABLE:
+ /* write fifo water mark interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_ENABLE_1_FIFO_WM_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_1_FIFO_WM_ENABLE,
+ v_intr_enable_1_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_FIFO_WM_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read
+ * interrupt enable byte2 from the register bit 0x52 bit 0 to 3
+ * @brief It reads no motion x,y and z
+ *
+ *
+ *
+ * @param v_enable_u8: The value of interrupt enable
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_NOMOTION_X_ENABLE
+ * 1 | SMI130_NOMOTION_Y_ENABLE
+ * 2 | SMI130_NOMOTION_Z_ENABLE
+ *
+ * @param v_intr_enable_2_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_enable_2(
+u8 v_enable_u8, u8 *v_intr_enable_2_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_enable_u8) {
+ case SMI130_NOMOTION_X_ENABLE:
+ /* read no motion x */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_2_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE);
+ break;
+ case SMI130_NOMOTION_Y_ENABLE:
+ /* read no motion y */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_2_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE);
+ break;
+ case SMI130_NOMOTION_Z_ENABLE:
+ /* read no motion z */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_2_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to set
+ * interrupt enable byte2 from the register bit 0x52 bit 0 to 3
+ * @brief It reads no motion x,y and z
+ *
+ *
+ *
+ * @param v_enable_u8: The value of interrupt enable
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_NOMOTION_X_ENABLE
+ * 1 | SMI130_NOMOTION_Y_ENABLE
+ * 2 | SMI130_NOMOTION_Z_ENABLE
+ *
+ * @param v_intr_enable_2_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_enable_2(
+u8 v_enable_u8, u8 v_intr_enable_2_u8)
+{
+/* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_enable_u8) {
+ case SMI130_NOMOTION_X_ENABLE:
+ /* write no motion x */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE,
+ v_intr_enable_2_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_NOMOTION_Y_ENABLE:
+ /* write no motion y */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE,
+ v_intr_enable_2_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_NOMOTION_Z_ENABLE:
+ /* write no motion z */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE,
+ v_intr_enable_2_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+ /*!
+ * @brief This API is used to read
+ * interrupt enable step detector interrupt from
+ * the register bit 0x52 bit 3
+ *
+ *
+ *
+ *
+ * @param v_step_intr_u8 : The value of step detector interrupt enable
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_get_step_detector_enable(
+u8 *v_step_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the step detector interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_step_intr_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API is used to set
+ * interrupt enable step detector interrupt from
+ * the register bit 0x52 bit 3
+ *
+ *
+ *
+ *
+ * @param v_step_intr_u8 : The value of step detector interrupt enable
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_step_detector_enable(
+u8 v_step_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE,
+ v_step_intr_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Configure trigger condition of interrupt1
+ * and interrupt2 pin from the register 0x53
+ * @brief interrupt1 - bit 0
+ * @brief interrupt2 - bit 4
+ *
+ * @param v_channel_u8: The value of edge trigger selection
+ * v_channel_u8 | Edge trigger
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_EDGE_CTRL
+ * 1 | SMI130_INTR2_EDGE_CTRL
+ *
+ * @param v_intr_edge_ctrl_u8 : The value of edge trigger enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_EDGE
+ * 0x00 | SMI130_LEVEL
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_edge_ctrl(
+u8 v_channel_u8, u8 *v_intr_edge_ctrl_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ case SMI130_INTR1_EDGE_CTRL:
+ /* read the edge trigger interrupt1*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_EDGE_CTRL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_edge_ctrl_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR1_EDGE_CTRL);
+ break;
+ case SMI130_INTR2_EDGE_CTRL:
+ /* read the edge trigger interrupt2*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_EDGE_CTRL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_edge_ctrl_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR2_EDGE_CTRL);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Configure trigger condition of interrupt1
+ * and interrupt2 pin from the register 0x53
+ * @brief interrupt1 - bit 0
+ * @brief interrupt2 - bit 4
+ *
+ * @param v_channel_u8: The value of edge trigger selection
+ * v_channel_u8 | Edge trigger
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_EDGE_CTRL
+ * 1 | SMI130_INTR2_EDGE_CTRL
+ *
+ * @param v_intr_edge_ctrl_u8 : The value of edge trigger enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_EDGE
+ * 0x00 | SMI130_LEVEL
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_edge_ctrl(
+u8 v_channel_u8, u8 v_intr_edge_ctrl_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ case SMI130_INTR1_EDGE_CTRL:
+ /* write the edge trigger interrupt1*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_EDGE_CTRL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR1_EDGE_CTRL,
+ v_intr_edge_ctrl_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_EDGE_CTRL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_EDGE_CTRL:
+ /* write the edge trigger interrupt2*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_EDGE_CTRL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR2_EDGE_CTRL,
+ v_intr_edge_ctrl_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_EDGE_CTRL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief API used for get the Configure level condition of interrupt1
+ * and interrupt2 pin form the register 0x53
+ * @brief interrupt1 - bit 1
+ * @brief interrupt2 - bit 5
+ *
+ * @param v_channel_u8: The value of level condition selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_LEVEL
+ * 1 | SMI130_INTR2_LEVEL
+ *
+ * @param v_intr_level_u8 : The value of level of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | SMI130_LEVEL_HIGH
+ * 0x00 | SMI130_LEVEL_LOW
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_level(
+u8 v_channel_u8, u8 *v_intr_level_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ case SMI130_INTR1_LEVEL:
+ /* read the interrupt1 level*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_LEVEL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_level_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR1_LEVEL);
+ break;
+ case SMI130_INTR2_LEVEL:
+ /* read the interrupt2 level*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_LEVEL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_level_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR2_LEVEL);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief API used for set the Configure level condition of interrupt1
+ * and interrupt2 pin form the register 0x53
+ * @brief interrupt1 - bit 1
+ * @brief interrupt2 - bit 5
+ *
+ * @param v_channel_u8: The value of level condition selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_LEVEL
+ * 1 | SMI130_INTR2_LEVEL
+ *
+ * @param v_intr_level_u8 : The value of level of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | SMI130_LEVEL_HIGH
+ * 0x00 | SMI130_LEVEL_LOW
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_level(
+u8 v_channel_u8, u8 v_intr_level_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ case SMI130_INTR1_LEVEL:
+ /* write the interrupt1 level*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_LEVEL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR1_LEVEL, v_intr_level_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_LEVEL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_LEVEL:
+ /* write the interrupt2 level*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_LEVEL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR2_LEVEL, v_intr_level_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_LEVEL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief API used to get configured output enable of interrupt1
+ * and interrupt2 from the register 0x53
+ * @brief interrupt1 - bit 2
+ * @brief interrupt2 - bit 6
+ *
+ *
+ * @param v_channel_u8: The value of output type enable selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_OUTPUT_TYPE
+ * 1 | SMI130_INTR2_OUTPUT_TYPE
+ *
+ * @param v_intr_output_type_u8 :
+ * The value of output type of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | SMI130_OPEN_DRAIN
+ * 0x00 | SMI130_PUSH_PULL
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_output_type(
+u8 v_channel_u8, u8 *v_intr_output_type_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ case SMI130_INTR1_OUTPUT_TYPE:
+ /* read the output type of interrupt1*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_OUTPUT_TYPE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_output_type_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR1_OUTPUT_TYPE);
+ break;
+ case SMI130_INTR2_OUTPUT_TYPE:
+ /* read the output type of interrupt2*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_OUTPUT_TYPE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_output_type_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR2_OUTPUT_TYPE);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief API used to set output enable of interrupt1
+ * and interrupt2 from the register 0x53
+ * @brief interrupt1 - bit 2
+ * @brief interrupt2 - bit 6
+ *
+ *
+ * @param v_channel_u8: The value of output type enable selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_OUTPUT_TYPE
+ * 1 | SMI130_INTR2_OUTPUT_TYPE
+ *
+ * @param v_intr_output_type_u8 :
+ * The value of output type of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | SMI130_OPEN_DRAIN
+ * 0x00 | SMI130_PUSH_PULL
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_output_type(
+u8 v_channel_u8, u8 v_intr_output_type_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ case SMI130_INTR1_OUTPUT_TYPE:
+ /* write the output type of interrupt1*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_OUTPUT_TYPE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR1_OUTPUT_TYPE,
+ v_intr_output_type_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_OUTPUT_TYPE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_OUTPUT_TYPE:
+ /* write the output type of interrupt2*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_OUTPUT_TYPE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR2_OUTPUT_TYPE,
+ v_intr_output_type_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_OUTPUT_TYPE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief API used to get the Output enable for interrupt1
+ * and interrupt1 pin from the register 0x53
+ * @brief interrupt1 - bit 3
+ * @brief interrupt2 - bit 7
+ *
+ * @param v_channel_u8: The value of output enable selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_OUTPUT_TYPE
+ * 1 | SMI130_INTR2_OUTPUT_TYPE
+ *
+ * @param v_output_enable_u8 :
+ * The value of output enable of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | SMI130_INPUT
+ * 0x00 | SMI130_OUTPUT
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_output_enable(
+u8 v_channel_u8, u8 *v_output_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ case SMI130_INTR1_OUTPUT_ENABLE:
+ /* read the output enable of interrupt1*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_OUTPUT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_output_enable_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR1_OUTPUT_ENABLE);
+ break;
+ case SMI130_INTR2_OUTPUT_ENABLE:
+ /* read the output enable of interrupt2*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_OUTPUT_EN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_output_enable_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR2_OUTPUT_EN);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief API used to set the Output enable for interrupt1
+ * and interrupt1 pin from the register 0x53
+ * @brief interrupt1 - bit 3
+ * @brief interrupt2 - bit 7
+ *
+ * @param v_channel_u8: The value of output enable selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_OUTPUT_TYPE
+ * 1 | SMI130_INTR2_OUTPUT_TYPE
+ *
+ * @param v_output_enable_u8 :
+ * The value of output enable of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | SMI130_INPUT
+ * 0x00 | SMI130_OUTPUT
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_output_enable(
+u8 v_channel_u8, u8 v_output_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ case SMI130_INTR1_OUTPUT_ENABLE:
+ /* write the output enable of interrupt1*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_OUTPUT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR1_OUTPUT_ENABLE,
+ v_output_enable_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_OUTPUT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_OUTPUT_ENABLE:
+ /* write the output enable of interrupt2*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_OUTPUT_EN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR2_OUTPUT_EN,
+ v_output_enable_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_OUTPUT_EN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to get the latch duration
+* from the register 0x54 bit 0 to 3
+* @brief This latch selection is not applicable for data ready,
+* orient_mblation and flat interrupts.
+*
+*
+*
+* @param v_latch_intr_u8 : The value of latch duration
+* Latch Duration | value
+* --------------------------------------|------------------
+* SMI130_LATCH_DUR_NONE | 0x00
+* SMI130_LATCH_DUR_312_5_MICRO_SEC | 0x01
+* SMI130_LATCH_DUR_625_MICRO_SEC | 0x02
+* SMI130_LATCH_DUR_1_25_MILLI_SEC | 0x03
+* SMI130_LATCH_DUR_2_5_MILLI_SEC | 0x04
+* SMI130_LATCH_DUR_5_MILLI_SEC | 0x05
+* SMI130_LATCH_DUR_10_MILLI_SEC | 0x06
+* SMI130_LATCH_DUR_20_MILLI_SEC | 0x07
+* SMI130_LATCH_DUR_40_MILLI_SEC | 0x08
+* SMI130_LATCH_DUR_80_MILLI_SEC | 0x09
+* SMI130_LATCH_DUR_160_MILLI_SEC | 0x0A
+* SMI130_LATCH_DUR_320_MILLI_SEC | 0x0B
+* SMI130_LATCH_DUR_640_MILLI_SEC | 0x0C
+* SMI130_LATCH_DUR_1_28_SEC | 0x0D
+* SMI130_LATCH_DUR_2_56_SEC | 0x0E
+* SMI130_LATCHED | 0x0F
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_latch_intr(
+u8 *v_latch_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the latch duration value */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_LATCH__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_latch_intr_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_LATCH);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to set the latch duration
+* from the register 0x54 bit 0 to 3
+* @brief This latch selection is not applicable for data ready,
+* orient_mblation and flat interrupts.
+*
+*
+*
+* @param v_latch_intr_u8 : The value of latch duration
+* Latch Duration | value
+* --------------------------------------|------------------
+* SMI130_LATCH_DUR_NONE | 0x00
+* SMI130_LATCH_DUR_312_5_MICRO_SEC | 0x01
+* SMI130_LATCH_DUR_625_MICRO_SEC | 0x02
+* SMI130_LATCH_DUR_1_25_MILLI_SEC | 0x03
+* SMI130_LATCH_DUR_2_5_MILLI_SEC | 0x04
+* SMI130_LATCH_DUR_5_MILLI_SEC | 0x05
+* SMI130_LATCH_DUR_10_MILLI_SEC | 0x06
+* SMI130_LATCH_DUR_20_MILLI_SEC | 0x07
+* SMI130_LATCH_DUR_40_MILLI_SEC | 0x08
+* SMI130_LATCH_DUR_80_MILLI_SEC | 0x09
+* SMI130_LATCH_DUR_160_MILLI_SEC | 0x0A
+* SMI130_LATCH_DUR_320_MILLI_SEC | 0x0B
+* SMI130_LATCH_DUR_640_MILLI_SEC | 0x0C
+* SMI130_LATCH_DUR_1_28_SEC | 0x0D
+* SMI130_LATCH_DUR_2_56_SEC | 0x0E
+* SMI130_LATCHED | 0x0F
+*
+*
+*
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_latch_intr(u8 v_latch_intr_u8)
+{
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_latch_intr_u8 <= SMI130_MAX_LATCH_INTR) {
+ /* write the latch duration value */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_LATCH__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_LATCH, v_latch_intr_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_LATCH__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief API used to get input enable for interrupt1
+ * and interrupt2 pin from the register 0x54
+ * @brief interrupt1 - bit 4
+ * @brief interrupt2 - bit 5
+ *
+ * @param v_channel_u8: The value of input enable selection
+ * v_channel_u8 | input selection
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_INPUT_ENABLE
+ * 1 | SMI130_INTR2_INPUT_ENABLE
+ *
+ * @param v_input_en_u8 :
+ * The value of input enable of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | SMI130_INPUT
+ * 0x00 | SMI130_OUTPUT
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_input_enable(
+u8 v_channel_u8, u8 *v_input_en_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* read input enable of interrup1 and interrupt2*/
+ case SMI130_INTR1_INPUT_ENABLE:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_INPUT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_input_en_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR1_INPUT_ENABLE);
+ break;
+ case SMI130_INTR2_INPUT_ENABLE:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_INPUT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_input_en_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR2_INPUT_ENABLE);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief API used to set input enable for interrupt1
+ * and interrupt2 pin from the register 0x54
+ * @brief interrupt1 - bit 4
+ * @brief interrupt2 - bit 5
+ *
+ * @param v_channel_u8: The value of input enable selection
+ * v_channel_u8 | input selection
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_INPUT_ENABLE
+ * 1 | SMI130_INTR2_INPUT_ENABLE
+ *
+ * @param v_input_en_u8 :
+ * The value of input enable of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | SMI130_INPUT
+ * 0x00 | SMI130_OUTPUT
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_input_enable(
+u8 v_channel_u8, u8 v_input_en_u8)
+{
+/* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* write input enable of interrup1 and interrupt2*/
+ case SMI130_INTR1_INPUT_ENABLE:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_INPUT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR1_INPUT_ENABLE, v_input_en_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_INPUT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_INPUT_ENABLE:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_INPUT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR2_INPUT_ENABLE, v_input_en_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_INPUT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+ /*!
+ * @brief reads the Low g interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 0 in the register 0x55
+ * @brief interrupt2 bit 0 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of low_g selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_LOW_G
+ * 1 | SMI130_INTR2_MAP_LOW_G
+ *
+ * @param v_intr_low_g_u8 : The value of low_g enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_low_g(
+u8 v_channel_u8, u8 *v_intr_low_g_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* read the low_g interrupt */
+ case SMI130_INTR1_MAP_LOW_G:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_LOW_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_low_g_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_LOW_G);
+ break;
+ case SMI130_INTR2_MAP_LOW_G:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_LOW_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_low_g_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_LOW_G);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief set the Low g interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 0 in the register 0x55
+ * @brief interrupt2 bit 0 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of low_g selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_LOW_G
+ * 1 | SMI130_INTR2_MAP_LOW_G
+ *
+ * @param v_intr_low_g_u8 : The value of low_g enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_low_g(
+u8 v_channel_u8, u8 v_intr_low_g_u8)
+{
+/* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+u8 v_step_cnt_stat_u8 = SMI130_INIT_VALUE;
+u8 v_step_det_stat_u8 = SMI130_INIT_VALUE;
+
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* check the step detector interrupt enable status*/
+ com_rslt = smi130_get_step_detector_enable(&v_step_det_stat_u8);
+ /* disable the step detector interrupt */
+ if (v_step_det_stat_u8 != SMI130_INIT_VALUE)
+ com_rslt += smi130_set_step_detector_enable(SMI130_INIT_VALUE);
+ /* check the step counter interrupt enable status*/
+ com_rslt += smi130_get_step_counter_enable(&v_step_cnt_stat_u8);
+ /* disable the step counter interrupt */
+ if (v_step_cnt_stat_u8 != SMI130_INIT_VALUE)
+ com_rslt += smi130_set_step_counter_enable(
+ SMI130_INIT_VALUE);
+ switch (v_channel_u8) {
+ /* write the low_g interrupt*/
+ case SMI130_INTR1_MAP_LOW_G:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_LOW_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_LOW_G, v_intr_low_g_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_LOW_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_MAP_LOW_G:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_LOW_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_LOW_G, v_intr_low_g_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_LOW_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+/*!
+ * @brief Reads the HIGH g interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 1 in the register 0x55
+ * @brief interrupt2 bit 1 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of high_g selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_HIGH_G
+ * 1 | SMI130_INTR2_MAP_HIGH_G
+ *
+ * @param v_intr_high_g_u8 : The value of high_g enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_high_g(
+u8 v_channel_u8, u8 *v_intr_high_g_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the high_g interrupt*/
+ switch (v_channel_u8) {
+ case SMI130_INTR1_MAP_HIGH_G:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_HIGH_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_high_g_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_HIGH_G);
+ break;
+ case SMI130_INTR2_MAP_HIGH_G:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_HIGH_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_high_g_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_HIGH_G);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Write the HIGH g interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 1 in the register 0x55
+ * @brief interrupt2 bit 1 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of high_g selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_HIGH_G
+ * 1 | SMI130_INTR2_MAP_HIGH_G
+ *
+ * @param v_intr_high_g_u8 : The value of high_g enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_high_g(
+u8 v_channel_u8, u8 v_intr_high_g_u8)
+{
+/* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* write the high_g interrupt*/
+ case SMI130_INTR1_MAP_HIGH_G:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_HIGH_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_HIGH_G, v_intr_high_g_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_HIGH_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_MAP_HIGH_G:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_HIGH_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_HIGH_G, v_intr_high_g_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_HIGH_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+/*!
+ * @brief Reads the Any motion interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 2 in the register 0x55
+ * @brief interrupt2 bit 2 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of any motion selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_ANY_MOTION
+ * 1 | SMI130_INTR2_MAP_ANY_MOTION
+ *
+ * @param v_intr_any_motion_u8 : The value of any motion enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_any_motion(
+u8 v_channel_u8, u8 *v_intr_any_motion_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* read the any motion interrupt */
+ case SMI130_INTR1_MAP_ANY_MOTION:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_ANY_MOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_any_motion_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_ANY_MOTION);
+ break;
+ case SMI130_INTR2_MAP_ANY_MOTION:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_ANY_MOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_any_motion_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_ANY_MOTION);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Write the Any motion interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 2 in the register 0x55
+ * @brief interrupt2 bit 2 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of any motion selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_ANY_MOTION
+ * 1 | SMI130_INTR2_MAP_ANY_MOTION
+ *
+ * @param v_intr_any_motion_u8 : The value of any motion enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_any_motion(
+u8 v_channel_u8, u8 v_intr_any_motion_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+u8 sig_mot_stat = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the status of significant motion interrupt */
+ com_rslt = smi130_get_intr_significant_motion_select(&sig_mot_stat);
+ /* disable the significant motion interrupt */
+ if (sig_mot_stat != SMI130_INIT_VALUE)
+ com_rslt += smi130_set_intr_significant_motion_select(
+ SMI130_INIT_VALUE);
+ switch (v_channel_u8) {
+ /* write the any motion interrupt */
+ case SMI130_INTR1_MAP_ANY_MOTION:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_ANY_MOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_ANY_MOTION,
+ v_intr_any_motion_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_ANY_MOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_MAP_ANY_MOTION:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_ANY_MOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_ANY_MOTION,
+ v_intr_any_motion_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_ANY_MOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+/*!
+ * @brief Reads the No motion interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 3 in the register 0x55
+ * @brief interrupt2 bit 3 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of no motion selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_NOMO
+ * 1 | SMI130_INTR2_MAP_NOMO
+ *
+ * @param v_intr_nomotion_u8 : The value of no motion enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_nomotion(
+u8 v_channel_u8, u8 *v_intr_nomotion_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* read the no motion interrupt*/
+ case SMI130_INTR1_MAP_NOMO:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_NOMOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_nomotion_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_NOMOTION);
+ break;
+ case SMI130_INTR2_MAP_NOMO:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_NOMOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_nomotion_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_NOMOTION);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Write the No motion interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 3 in the register 0x55
+ * @brief interrupt2 bit 3 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of no motion selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_NOMO
+ * 1 | SMI130_INTR2_MAP_NOMO
+ *
+ * @param v_intr_nomotion_u8 : The value of no motion enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_nomotion(
+u8 v_channel_u8, u8 v_intr_nomotion_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* write the no motion interrupt*/
+ case SMI130_INTR1_MAP_NOMO:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_NOMOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_NOMOTION,
+ v_intr_nomotion_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_NOMOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_MAP_NOMO:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_NOMOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_NOMOTION,
+ v_intr_nomotion_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_NOMOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+/*!
+ * @brief Reads the Double Tap interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 4 in the register 0x55
+ * @brief interrupt2 bit 4 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of double tap interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_DOUBLE_TAP
+ * 1 | SMI130_INTR2_MAP_DOUBLE_TAP
+ *
+ * @param v_intr_double_tap_u8 : The value of double tap enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_double_tap(
+u8 v_channel_u8, u8 *v_intr_double_tap_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ case SMI130_INTR1_MAP_DOUBLE_TAP:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_DOUBLE_TAP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_double_tap_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_DOUBLE_TAP);
+ break;
+ case SMI130_INTR2_MAP_DOUBLE_TAP:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_DOUBLE_TAP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_double_tap_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_DOUBLE_TAP);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Write the Double Tap interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 4 in the register 0x55
+ * @brief interrupt2 bit 4 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of double tap interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_DOUBLE_TAP
+ * 1 | SMI130_INTR2_MAP_DOUBLE_TAP
+ *
+ * @param v_intr_double_tap_u8 : The value of double tap enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_double_tap(
+u8 v_channel_u8, u8 v_intr_double_tap_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* set the double tap interrupt */
+ case SMI130_INTR1_MAP_DOUBLE_TAP:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_DOUBLE_TAP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_DOUBLE_TAP,
+ v_intr_double_tap_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_DOUBLE_TAP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_MAP_DOUBLE_TAP:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_DOUBLE_TAP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_DOUBLE_TAP,
+ v_intr_double_tap_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_DOUBLE_TAP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+/*!
+ * @brief Reads the Single Tap interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 5 in the register 0x55
+ * @brief interrupt2 bit 5 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of single tap interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_SINGLE_TAP
+ * 1 | SMI130_INTR2_MAP_SINGLE_TAP
+ *
+ * @param v_intr_single_tap_u8 : The value of single tap enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_single_tap(
+u8 v_channel_u8, u8 *v_intr_single_tap_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* reads the single tap interrupt*/
+ case SMI130_INTR1_MAP_SINGLE_TAP:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_SINGLE_TAP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_single_tap_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_SINGLE_TAP);
+ break;
+ case SMI130_INTR2_MAP_SINGLE_TAP:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_SINGLE_TAP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_single_tap_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_SINGLE_TAP);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Write the Single Tap interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 5 in the register 0x55
+ * @brief interrupt2 bit 5 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of single tap interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_SINGLE_TAP
+ * 1 | SMI130_INTR2_MAP_SINGLE_TAP
+ *
+ * @param v_intr_single_tap_u8 : The value of single tap enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_single_tap(
+u8 v_channel_u8, u8 v_intr_single_tap_u8)
+{
+/* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* write the single tap interrupt */
+ case SMI130_INTR1_MAP_SINGLE_TAP:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_SINGLE_TAP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_SINGLE_TAP,
+ v_intr_single_tap_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_SINGLE_TAP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_MAP_SINGLE_TAP:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_SINGLE_TAP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_SINGLE_TAP,
+ v_intr_single_tap_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_SINGLE_TAP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+/*!
+ * @brief Reads the Orient interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 6 in the register 0x55
+ * @brief interrupt2 bit 6 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of orient_mbl interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_ORIENT
+ * 1 | SMI130_INTR2_MAP_ORIENT
+ *
+ * @param v_intr_orient_mbl_u8 : The value of orient_mbl enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_orient_mbl(
+u8 v_channel_u8, u8 *v_intr_orient_mbl_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* read the orient_mblation interrupt*/
+ case SMI130_INTR1_MAP_ORIENT:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_ORIENT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_orient_mbl_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_ORIENT);
+ break;
+ case SMI130_INTR2_MAP_ORIENT:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_ORIENT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_orient_mbl_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_ORIENT);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Write the Orient interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 6 in the register 0x55
+ * @brief interrupt2 bit 6 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of orient_mbl interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_ORIENT
+ * 1 | SMI130_INTR2_MAP_ORIENT
+ *
+ * @param v_intr_orient_mbl_u8 : The value of orient_mbl enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_orient_mbl(
+u8 v_channel_u8, u8 v_intr_orient_mbl_u8)
+{
+/* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* write the orient_mblation interrupt*/
+ case SMI130_INTR1_MAP_ORIENT:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_ORIENT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_ORIENT, v_intr_orient_mbl_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_ORIENT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_MAP_ORIENT:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_ORIENT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_ORIENT, v_intr_orient_mbl_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_ORIENT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+ /*!
+ * @brief Reads the Flat interrupt
+ * mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 7 in the register 0x55
+ * @brief interrupt2 bit 7 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of flat interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_FLAT
+ * 1 | SMI130_INTR2_MAP_FLAT
+ *
+ * @param v_intr_flat_u8 : The value of flat enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_flat(
+u8 v_channel_u8, u8 *v_intr_flat_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* read the flat interrupt*/
+ case SMI130_INTR1_MAP_FLAT:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_FLAT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_flat_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_FLAT);
+ break;
+ case SMI130_INTR2_MAP_FLAT:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_FLAT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_flat_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_FLAT);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief Write the Flat interrupt
+ * mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 7 in the register 0x55
+ * @brief interrupt2 bit 7 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of flat interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_FLAT
+ * 1 | SMI130_INTR2_MAP_FLAT
+ *
+ * @param v_intr_flat_u8 : The value of flat enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_flat(
+u8 v_channel_u8, u8 v_intr_flat_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* write the flat interrupt */
+ case SMI130_INTR1_MAP_FLAT:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_FLAT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_FLAT,
+ v_intr_flat_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_MAP_0_INTR1_FLAT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_MAP_FLAT:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_FLAT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_FLAT,
+ v_intr_flat_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_MAP_2_INTR2_FLAT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Reads PMU trigger interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 0 and 4
+ * @brief interrupt1 bit 0 in the register 0x56
+ * @brief interrupt2 bit 4 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of pmu trigger selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_PMUTRIG
+ * 1 | SMI130_INTR2_MAP_PMUTRIG
+ *
+ * @param v_intr_pmu_trig_u8 : The value of pmu trigger enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_pmu_trig(
+u8 v_channel_u8, u8 *v_intr_pmu_trig_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* read the pmu trigger interrupt*/
+ case SMI130_INTR1_MAP_PMUTRIG:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR1_PMU_TRIG__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_pmu_trig_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR1_PMU_TRIG);
+ break;
+ case SMI130_INTR2_MAP_PMUTRIG:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR2_PMU_TRIG__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_pmu_trig_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR2_PMU_TRIG);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Write PMU trigger interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 0 and 4
+ * @brief interrupt1 bit 0 in the register 0x56
+ * @brief interrupt2 bit 4 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of pmu trigger selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_PMUTRIG
+ * 1 | SMI130_INTR2_MAP_PMUTRIG
+ *
+ * @param v_intr_pmu_trig_u8 : The value of pmu trigger enable
+ * value | trigger enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_pmu_trig(
+u8 v_channel_u8, u8 v_intr_pmu_trig_u8)
+{
+/* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* write the pmu trigger interrupt */
+ case SMI130_INTR1_MAP_PMUTRIG:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR1_PMU_TRIG__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR1_PMU_TRIG,
+ v_intr_pmu_trig_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR1_PMU_TRIG__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_MAP_PMUTRIG:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR2_PMU_TRIG__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR2_PMU_TRIG,
+ v_intr_pmu_trig_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR2_PMU_TRIG__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+/*!
+ * @brief Reads FIFO Full interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 5 and 1
+ * @brief interrupt1 bit 5 in the register 0x56
+ * @brief interrupt2 bit 1 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of fifo full interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_FIFO_FULL
+ * 1 | SMI130_INTR2_MAP_FIFO_FULL
+ *
+ * @param v_intr_fifo_full_u8 : The value of fifo full interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_fifo_full(
+u8 v_channel_u8, u8 *v_intr_fifo_full_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* read the fifo full interrupt */
+ case SMI130_INTR1_MAP_FIFO_FULL:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR1_FIFO_FULL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_fifo_full_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR1_FIFO_FULL);
+ break;
+ case SMI130_INTR2_MAP_FIFO_FULL:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR2_FIFO_FULL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_fifo_full_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR2_FIFO_FULL);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Write FIFO Full interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 5 and 1
+ * @brief interrupt1 bit 5 in the register 0x56
+ * @brief interrupt2 bit 1 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of fifo full interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_FIFO_FULL
+ * 1 | SMI130_INTR2_MAP_FIFO_FULL
+ *
+ * @param v_intr_fifo_full_u8 : The value of fifo full interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_fifo_full(
+u8 v_channel_u8, u8 v_intr_fifo_full_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* write the fifo full interrupt */
+ case SMI130_INTR1_MAP_FIFO_FULL:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR1_FIFO_FULL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR1_FIFO_FULL,
+ v_intr_fifo_full_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_MAP_1_INTR1_FIFO_FULL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_MAP_FIFO_FULL:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR2_FIFO_FULL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR2_FIFO_FULL,
+ v_intr_fifo_full_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_MAP_1_INTR2_FIFO_FULL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Reads FIFO Watermark interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 6 and 2
+ * @brief interrupt1 bit 6 in the register 0x56
+ * @brief interrupt2 bit 2 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of fifo Watermark interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_FIFO_WM
+ * 1 | SMI130_INTR2_MAP_FIFO_WM
+ *
+ * @param v_intr_fifo_wm_u8 : The value of fifo Watermark interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_fifo_wm(
+u8 v_channel_u8, u8 *v_intr_fifo_wm_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* read the fifo water mark interrupt */
+ case SMI130_INTR1_MAP_FIFO_WM:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR1_FIFO_WM__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_fifo_wm_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR1_FIFO_WM);
+ break;
+ case SMI130_INTR2_MAP_FIFO_WM:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR2_FIFO_WM__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_fifo_wm_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR2_FIFO_WM);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Write FIFO Watermark interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 6 and 2
+ * @brief interrupt1 bit 6 in the register 0x56
+ * @brief interrupt2 bit 2 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of fifo Watermark interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_FIFO_WM
+ * 1 | SMI130_INTR2_MAP_FIFO_WM
+ *
+ * @param v_intr_fifo_wm_u8 : The value of fifo Watermark interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_fifo_wm(
+u8 v_channel_u8, u8 v_intr_fifo_wm_u8)
+{
+/* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* write the fifo water mark interrupt */
+ case SMI130_INTR1_MAP_FIFO_WM:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR1_FIFO_WM__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR1_FIFO_WM,
+ v_intr_fifo_wm_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_MAP_1_INTR1_FIFO_WM__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_MAP_FIFO_WM:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR2_FIFO_WM__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR2_FIFO_WM,
+ v_intr_fifo_wm_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_MAP_1_INTR2_FIFO_WM__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Reads Data Ready interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56
+ * @brief interrupt1 bit 7 in the register 0x56
+ * @brief interrupt2 bit 3 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of data ready interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_DATA_RDY
+ * 1 | SMI130_INTR2_MAP_DATA_RDY
+ *
+ * @param v_intr_data_rdy_u8 : The value of data ready interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_data_rdy(
+u8 v_channel_u8, u8 *v_intr_data_rdy_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /*Read Data Ready interrupt*/
+ case SMI130_INTR1_MAP_DATA_RDY:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR1_DATA_RDY__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_data_rdy_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR1_DATA_RDY);
+ break;
+ case SMI130_INTR2_MAP_DATA_RDY:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR2_DATA_RDY__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_data_rdy_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR2_DATA_RDY);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief Write Data Ready interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56
+ * @brief interrupt1 bit 7 in the register 0x56
+ * @brief interrupt2 bit 3 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of data ready interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_DATA_RDY
+ * 1 | SMI130_INTR2_MAP_DATA_RDY
+ *
+ * @param v_intr_data_rdy_u8 : The value of data ready interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_data_rdy(
+u8 v_channel_u8, u8 v_intr_data_rdy_u8)
+{
+/* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /*Write Data Ready interrupt*/
+ case SMI130_INTR1_MAP_DATA_RDY:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR1_DATA_RDY__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR1_DATA_RDY,
+ v_intr_data_rdy_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR1_DATA_RDY__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_MAP_DATA_RDY:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR2_DATA_RDY__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR2_DATA_RDY,
+ v_intr_data_rdy_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR2_DATA_RDY__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+ /*!
+ * @brief This API reads data source for the interrupt
+ * engine for the single and double tap interrupts from the register
+ * 0x58 bit 3
+ *
+ *
+ * @param v_tap_source_u8 : The value of the tap source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_tap_source(u8 *v_tap_source_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the tap source interrupt */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_DATA_0_INTR_TAP_SOURCE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_tap_source_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_DATA_0_INTR_TAP_SOURCE);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write data source for the interrupt
+ * engine for the single and double tap interrupts from the register
+ * 0x58 bit 3
+ *
+ *
+ * @param v_tap_source_u8 : The value of the tap source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_tap_source(
+u8 v_tap_source_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_tap_source_u8 <= SMI130_MAX_VALUE_SOURCE_INTR) {
+ /* write the tap source interrupt */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_DATA_0_INTR_TAP_SOURCE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_DATA_0_INTR_TAP_SOURCE,
+ v_tap_source_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_DATA_0_INTR_TAP_SOURCE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API Reads Data source for the
+ * interrupt engine for the low and high g interrupts
+ * from the register 0x58 bit 7
+ *
+ * @param v_low_high_source_u8 : The value of the tap source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_low_high_source(
+u8 *v_low_high_source_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the high_low_g source interrupt */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_low_high_source_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write Data source for the
+ * interrupt engine for the low and high g interrupts
+ * from the register 0x58 bit 7
+ *
+ * @param v_low_high_source_u8 : The value of the tap source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_low_high_source(
+u8 v_low_high_source_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_low_high_source_u8 <= SMI130_MAX_VALUE_SOURCE_INTR) {
+ /* write the high_low_g source interrupt */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE,
+ v_low_high_source_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+}
+return com_rslt;
+}
+ /*!
+ * @brief This API reads Data source for the
+ * interrupt engine for the nomotion and anymotion interrupts
+ * from the register 0x59 bit 7
+ *
+ * @param v_motion_source_u8 :
+ * The value of the any/no motion interrupt source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_motion_source(
+u8 *v_motion_source_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the any/no motion interrupt */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_DATA_1_INTR_MOTION_SOURCE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_motion_source_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_DATA_1_INTR_MOTION_SOURCE);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write Data source for the
+ * interrupt engine for the nomotion and anymotion interrupts
+ * from the register 0x59 bit 7
+ *
+ * @param v_motion_source_u8 :
+ * The value of the any/no motion interrupt source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_motion_source(
+u8 v_motion_source_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_motion_source_u8 <= SMI130_MAX_VALUE_SOURCE_INTR) {
+ /* write the any/no motion interrupt */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_DATA_1_INTR_MOTION_SOURCE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_DATA_1_INTR_MOTION_SOURCE,
+ v_motion_source_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_DATA_1_INTR_MOTION_SOURCE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API is used to read the low_g duration from register
+ * 0x5A bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_low_g_durn_u8 : The value of low_g duration
+ *
+ * @note Low_g duration trigger trigger delay according to
+ * "(v_low_g_durn_u8 * 2.5)ms" in a range from 2.5ms to 640ms.
+ * the default corresponds delay is 20ms
+ * @note When low_g data source of interrupt is unfiltered
+ * the sensor must not be in low power mode
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_low_g_durn(
+u8 *v_low_g_durn_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the low_g interrupt */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_0_INTR_LOW_DURN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_low_g_durn_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_LOWHIGH_0_INTR_LOW_DURN);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API is used to write the low_g duration from register
+ * 0x5A bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_low_g_durn_u8 : The value of low_g duration
+ *
+ * @note Low_g duration trigger trigger delay according to
+ * "(v_low_g_durn_u8 * 2.5)ms" in a range from 2.5ms to 640ms.
+ * the default corresponds delay is 20ms
+ * @note When low_g data source of interrupt is unfiltered
+ * the sensor must not be in low power mode
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_low_g_durn(u8 v_low_g_durn_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write the low_g interrupt */
+ com_rslt = p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_0_INTR_LOW_DURN__REG,
+ &v_low_g_durn_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read Threshold
+ * definition for the low-g interrupt from the register 0x5B bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_low_g_thres_u8 : The value of low_g threshold
+ *
+ * @note Low_g interrupt trigger threshold according to
+ * (v_low_g_thres_u8 * 7.81)mg for v_low_g_thres_u8 > 0
+ * 3.91 mg for v_low_g_thres_u8 = 0
+ * The threshold range is form 3.91mg to 2.000mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_low_g_thres(
+u8 *v_low_g_thres_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read low_g threshold */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_1_INTR_LOW_THRES__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_low_g_thres_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_LOWHIGH_1_INTR_LOW_THRES);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to write Threshold
+ * definition for the low-g interrupt from the register 0x5B bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_low_g_thres_u8 : The value of low_g threshold
+ *
+ * @note Low_g interrupt trigger threshold according to
+ * (v_low_g_thres_u8 * 7.81)mg for v_low_g_thres_u8 > 0
+ * 3.91 mg for v_low_g_thres_u8 = 0
+ * The threshold range is form 3.91mg to 2.000mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_low_g_thres(
+u8 v_low_g_thres_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write low_g threshold */
+ com_rslt = p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_1_INTR_LOW_THRES__REG,
+ &v_low_g_thres_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API Reads Low-g interrupt hysteresis
+ * from the register 0x5C bit 0 to 1
+ *
+ * @param v_low_hyst_u8 :The value of low_g hysteresis
+ *
+ * @note Low_g hysteresis calculated by v_low_hyst_u8*125 mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_low_g_hyst(
+u8 *v_low_hyst_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read low_g hysteresis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_low_hyst_u8 = SMI130_GET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write Low-g interrupt hysteresis
+ * from the register 0x5C bit 0 to 1
+ *
+ * @param v_low_hyst_u8 :The value of low_g hysteresis
+ *
+ * @note Low_g hysteresis calculated by v_low_hyst_u8*125 mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_low_g_hyst(
+u8 v_low_hyst_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write low_g hysteresis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST,
+ v_low_hyst_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads Low-g interrupt mode
+ * from the register 0x5C bit 2
+ *
+ * @param v_low_g_mode_u8 : The value of low_g mode
+ * Value | Description
+ * ----------|-----------------
+ * 0 | single-axis
+ * 1 | axis-summing
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_low_g_mode(u8 *v_low_g_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /*read Low-g interrupt mode*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_low_g_mode_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write Low-g interrupt mode
+ * from the register 0x5C bit 2
+ *
+ * @param v_low_g_mode_u8 : The value of low_g mode
+ * Value | Description
+ * ----------|-----------------
+ * 0 | single-axis
+ * 1 | axis-summing
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_low_g_mode(
+u8 v_low_g_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_low_g_mode_u8 <= SMI130_MAX_VALUE_LOW_G_MODE) {
+ /*write Low-g interrupt mode*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE,
+ v_low_g_mode_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads High-g interrupt hysteresis
+ * from the register 0x5C bit 6 and 7
+ *
+ * @param v_high_g_hyst_u8 : The value of high hysteresis
+ *
+ * @note High_g hysteresis changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | high_g hysteresis
+ * ----------------|---------------------
+ * 2g | high_hy*125 mg
+ * 4g | high_hy*250 mg
+ * 8g | high_hy*500 mg
+ * 16g | high_hy*1000 mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_high_g_hyst(
+u8 *v_high_g_hyst_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read high_g hysteresis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_high_g_hyst_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write High-g interrupt hysteresis
+ * from the register 0x5C bit 6 and 7
+ *
+ * @param v_high_g_hyst_u8 : The value of high hysteresis
+ *
+ * @note High_g hysteresis changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | high_g hysteresis
+ * ----------------|---------------------
+ * 2g | high_hy*125 mg
+ * 4g | high_hy*250 mg
+ * 8g | high_hy*500 mg
+ * 16g | high_hy*1000 mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_high_g_hyst(
+u8 v_high_g_hyst_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write high_g hysteresis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST,
+ v_high_g_hyst_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+return com_rslt;
+}
+/*!
+ * @brief This API is used to read Delay
+ * time definition for the high-g interrupt from the register
+ * 0x5D bit 0 to 7
+ *
+ *
+ *
+ * @param v_high_g_durn_u8 : The value of high duration
+ *
+ * @note High_g interrupt delay triggered according to
+ * v_high_g_durn_u8 * 2.5ms in a range from 2.5ms to 640ms
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_high_g_durn(
+u8 *v_high_g_durn_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read high_g duration*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_3_INTR_HIGH_G_DURN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_high_g_durn_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_LOWHIGH_3_INTR_HIGH_G_DURN);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to write Delay
+ * time definition for the high-g interrupt from the register
+ * 0x5D bit 0 to 7
+ *
+ *
+ *
+ * @param v_high_g_durn_u8 : The value of high duration
+ *
+ * @note High_g interrupt delay triggered according to
+ * v_high_g_durn_u8 * 2.5ms in a range from 2.5ms to 640ms
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_high_g_durn(
+u8 v_high_g_durn_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write high_g duration*/
+ com_rslt = p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_3_INTR_HIGH_G_DURN__REG,
+ &v_high_g_durn_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to read Threshold
+ * definition for the high-g interrupt from the register 0x5E 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_high_g_thres_u8 : Pointer holding the value of Threshold
+ * @note High_g threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | high_g threshold
+ * ----------------|---------------------
+ * 2g | v_high_g_thres_u8*7.81 mg
+ * 4g | v_high_g_thres_u8*15.63 mg
+ * 8g | v_high_g_thres_u8*31.25 mg
+ * 16g | v_high_g_thres_u8*62.5 mg
+ * @note when v_high_g_thres_u8 = 0
+ * accel_range | high_g threshold
+ * ----------------|---------------------
+ * 2g | 3.91 mg
+ * 4g | 7.81 mg
+ * 8g | 15.63 mg
+ * 16g | 31.25 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_high_g_thres(
+u8 *v_high_g_thres_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_4_INTR_HIGH_THRES__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_high_g_thres_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_LOWHIGH_4_INTR_HIGH_THRES);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to write Threshold
+ * definition for the high-g interrupt from the register 0x5E 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_high_g_thres_u8 : Pointer holding the value of Threshold
+ * @note High_g threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | high_g threshold
+ * ----------------|---------------------
+ * 2g | v_high_g_thres_u8*7.81 mg
+ * 4g | v_high_g_thres_u8*15.63 mg
+ * 8g | v_high_g_thres_u8*31.25 mg
+ * 16g | v_high_g_thres_u8*62.5 mg
+ * @note when v_high_g_thres_u8 = 0
+ * accel_range | high_g threshold
+ * ----------------|---------------------
+ * 2g | 3.91 mg
+ * 4g | 7.81 mg
+ * 8g | 15.63 mg
+ * 16g | 31.25 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_high_g_thres(
+u8 v_high_g_thres_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt = p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_4_INTR_HIGH_THRES__REG,
+ &v_high_g_thres_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads any motion duration
+ * from the register 0x5F bit 0 and 1
+ *
+ * @param v_any_motion_durn_u8 : The value of any motion duration
+ *
+ * @note Any motion duration can be calculated by "v_any_motion_durn_u8 + 1"
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_any_motion_durn(
+u8 *v_any_motion_durn_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read any motion duration*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_any_motion_durn_u8 = SMI130_GET_BITSLICE
+ (v_data_u8,
+ SMI130_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write any motion duration
+ * from the register 0x5F bit 0 and 1
+ *
+ * @param v_any_motion_durn_u8 : The value of any motion duration
+ *
+ * @note Any motion duration can be calculated by "v_any_motion_durn_u8 + 1"
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_any_motion_durn(
+u8 v_any_motion_durn_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write any motion duration*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN,
+ v_any_motion_durn_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API read Slow/no-motion
+ * interrupt trigger delay duration from the register 0x5F bit 2 to 7
+ *
+ * @param v_slow_no_motion_u8 :The value of slow no motion duration
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ * @note
+ * @note v_slow_no_motion_u8(5:4)=0b00 ->
+ * [v_slow_no_motion_u8(3:0) + 1] * 1.28s (1.28s-20.48s)
+ * @note v_slow_no_motion_u8(5:4)=1 ->
+ * [v_slow_no_motion_u8(3:0)+5] * 5.12s (25.6s-102.4s)
+ * @note v_slow_no_motion_u8(5)='1' ->
+ * [(v_slow_no_motion_u8:0)+11] * 10.24s (112.64s-430.08s);
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_slow_no_motion_durn(
+u8 *v_slow_no_motion_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read slow no motion duration*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_slow_no_motion_u8 = SMI130_GET_BITSLICE
+ (v_data_u8,
+ SMI130_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN);
+ }
+return com_rslt;
+}
+ /*!
+ * @brief This API write Slow/no-motion
+ * interrupt trigger delay duration from the register 0x5F bit 2 to 7
+ *
+ * @param v_slow_no_motion_u8 :The value of slow no motion duration
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ * @note
+ * @note v_slow_no_motion_u8(5:4)=0b00 ->
+ * [v_slow_no_motion_u8(3:0) + 1] * 1.28s (1.28s-20.48s)
+ * @note v_slow_no_motion_u8(5:4)=1 ->
+ * [v_slow_no_motion_u8(3:0)+5] * 5.12s (25.6s-102.4s)
+ * @note v_slow_no_motion_u8(5)='1' ->
+ * [(v_slow_no_motion_u8:0)+11] * 10.24s (112.64s-430.08s);
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_slow_no_motion_durn(
+u8 v_slow_no_motion_u8)
+{
+/* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write slow no motion duration*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE
+ (v_data_u8,
+ SMI130_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN,
+ v_slow_no_motion_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+}
+return com_rslt;
+}
+/*!
+ * @brief This API is used to read threshold
+ * definition for the any-motion interrupt
+ * from the register 0x60 bit 0 to 7
+ *
+ *
+ * @param v_any_motion_thres_u8 : The value of any motion threshold
+ *
+ * @note any motion threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | any motion threshold
+ * ----------------|---------------------
+ * 2g | v_any_motion_thres_u8*3.91 mg
+ * 4g | v_any_motion_thres_u8*7.81 mg
+ * 8g | v_any_motion_thres_u8*15.63 mg
+ * 16g | v_any_motion_thres_u8*31.25 mg
+ * @note when v_any_motion_thres_u8 = 0
+ * accel_range | any motion threshold
+ * ----------------|---------------------
+ * 2g | 1.95 mg
+ * 4g | 3.91 mg
+ * 8g | 7.81 mg
+ * 16g | 15.63 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_any_motion_thres(
+u8 *v_any_motion_thres_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read any motion threshold*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_MOTION_1_INTR_ANY_MOTION_THRES__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_any_motion_thres_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MOTION_1_INTR_ANY_MOTION_THRES);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to write threshold
+ * definition for the any-motion interrupt
+ * from the register 0x60 bit 0 to 7
+ *
+ *
+ * @param v_any_motion_thres_u8 : The value of any motion threshold
+ *
+ * @note any motion threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | any motion threshold
+ * ----------------|---------------------
+ * 2g | v_any_motion_thres_u8*3.91 mg
+ * 4g | v_any_motion_thres_u8*7.81 mg
+ * 8g | v_any_motion_thres_u8*15.63 mg
+ * 16g | v_any_motion_thres_u8*31.25 mg
+ * @note when v_any_motion_thres_u8 = 0
+ * accel_range | any motion threshold
+ * ----------------|---------------------
+ * 2g | 1.95 mg
+ * 4g | 3.91 mg
+ * 8g | 7.81 mg
+ * 16g | 15.63 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_any_motion_thres(
+u8 v_any_motion_thres_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write any motion threshold*/
+ com_rslt = p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_MOTION_1_INTR_ANY_MOTION_THRES__REG,
+ &v_any_motion_thres_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API is used to read threshold
+ * for the slow/no-motion interrupt
+ * from the register 0x61 bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_slow_no_motion_thres_u8 : The value of slow no motion threshold
+ * @note slow no motion threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | slow no motion threshold
+ * ----------------|---------------------
+ * 2g | v_slow_no_motion_thres_u8*3.91 mg
+ * 4g | v_slow_no_motion_thres_u8*7.81 mg
+ * 8g | v_slow_no_motion_thres_u8*15.63 mg
+ * 16g | v_slow_no_motion_thres_u8*31.25 mg
+ * @note when v_slow_no_motion_thres_u8 = 0
+ * accel_range | slow no motion threshold
+ * ----------------|---------------------
+ * 2g | 1.95 mg
+ * 4g | 3.91 mg
+ * 8g | 7.81 mg
+ * 16g | 15.63 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_slow_no_motion_thres(
+u8 *v_slow_no_motion_thres_u8)
+{
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read slow no motion threshold*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_MOTION_2_INTR_SLOW_NO_MOTION_THRES__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_slow_no_motion_thres_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MOTION_2_INTR_SLOW_NO_MOTION_THRES);
+ }
+return com_rslt;
+}
+ /*!
+ * @brief This API is used to write threshold
+ * for the slow/no-motion interrupt
+ * from the register 0x61 bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_slow_no_motion_thres_u8 : The value of slow no motion threshold
+ * @note slow no motion threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | slow no motion threshold
+ * ----------------|---------------------
+ * 2g | v_slow_no_motion_thres_u8*3.91 mg
+ * 4g | v_slow_no_motion_thres_u8*7.81 mg
+ * 8g | v_slow_no_motion_thres_u8*15.63 mg
+ * 16g | v_slow_no_motion_thres_u8*31.25 mg
+ * @note when v_slow_no_motion_thres_u8 = 0
+ * accel_range | slow no motion threshold
+ * ----------------|---------------------
+ * 2g | 1.95 mg
+ * 4g | 3.91 mg
+ * 8g | 7.81 mg
+ * 16g | 15.63 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_slow_no_motion_thres(
+u8 v_slow_no_motion_thres_u8)
+{
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write slow no motion threshold*/
+ com_rslt = p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_MOTION_2_INTR_SLOW_NO_MOTION_THRES__REG,
+ &v_slow_no_motion_thres_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+return com_rslt;
+}
+ /*!
+ * @brief This API is used to read
+ * the slow/no-motion selection from the register 0x62 bit 0
+ *
+ *
+ *
+ *
+ * @param v_intr_slow_no_motion_select_u8 :
+ * The value of slow/no-motion select
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | SLOW_MOTION
+ * 0x01 | NO_MOTION
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_slow_no_motion_select(
+u8 *v_intr_slow_no_motion_select_u8)
+{
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read slow no motion select*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_slow_no_motion_select_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT);
+ }
+return com_rslt;
+}
+ /*!
+ * @brief This API is used to write
+ * the slow/no-motion selection from the register 0x62 bit 0
+ *
+ *
+ *
+ *
+ * @param v_intr_slow_no_motion_select_u8 :
+ * The value of slow/no-motion select
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | SLOW_MOTION
+ * 0x01 | NO_MOTION
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_slow_no_motion_select(
+u8 v_intr_slow_no_motion_select_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+} else {
+if (v_intr_slow_no_motion_select_u8 <= SMI130_MAX_VALUE_NO_MOTION) {
+ /* write slow no motion select*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT,
+ v_intr_slow_no_motion_select_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+} else {
+com_rslt = E_SMI130_OUT_OF_RANGE;
+}
+}
+return com_rslt;
+}
+ /*!
+ * @brief This API is used to select
+ * the significant or any motion interrupt from the register 0x62 bit 1
+ *
+ *
+ *
+ *
+ * @param v_intr_significant_motion_select_u8 :
+ * the value of significant or any motion interrupt selection
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | ANY_MOTION
+ * 0x01 | SIGNIFICANT_MOTION
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_significant_motion_select(
+u8 *v_intr_significant_motion_select_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the significant or any motion interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_SIGNIFICATION_MOTION_SELECT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_significant_motion_select_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_SIGNIFICATION_MOTION_SELECT);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API is used to write, select
+ * the significant or any motion interrupt from the register 0x62 bit 1
+ *
+ *
+ *
+ *
+ * @param v_intr_significant_motion_select_u8 :
+ * the value of significant or any motion interrupt selection
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | ANY_MOTION
+ * 0x01 | SIGNIFICANT_MOTION
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_significant_motion_select(
+u8 v_intr_significant_motion_select_u8)
+{
+/* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_intr_significant_motion_select_u8 <=
+ SMI130_MAX_VALUE_SIGNIFICANT_MOTION) {
+ /* write the significant or any motion interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_SIGNIFICATION_MOTION_SELECT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_SIGNIFICATION_MOTION_SELECT,
+ v_intr_significant_motion_select_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_SIGNIFICATION_MOTION_SELECT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+}
+return com_rslt;
+}
+ /*!
+ * @brief This API is used to read
+ * the significant skip time from the register 0x62 bit 2 and 3
+ *
+ *
+ *
+ *
+ * @param v_int_sig_mot_skip_u8 : the value of significant skip time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | skip time 1.5 seconds
+ * 0x01 | skip time 3 seconds
+ * 0x02 | skip time 6 seconds
+ * 0x03 | skip time 12 seconds
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_significant_motion_skip(
+u8 *v_int_sig_mot_skip_u8)
+{
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read significant skip time*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_SIGNIFICANT_MOTION_SKIP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_int_sig_mot_skip_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_SIGNIFICANT_MOTION_SKIP);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API is used to write
+ * the significant skip time from the register 0x62 bit 2 and 3
+ *
+ *
+ *
+ *
+ * @param v_int_sig_mot_skip_u8 : the value of significant skip time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | skip time 1.5 seconds
+ * 0x01 | skip time 3 seconds
+ * 0x02 | skip time 6 seconds
+ * 0x03 | skip time 12 seconds
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_significant_motion_skip(
+u8 v_int_sig_mot_skip_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_int_sig_mot_skip_u8 <= SMI130_MAX_UNDER_SIG_MOTION) {
+ /* write significant skip time*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_SIGNIFICANT_MOTION_SKIP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_SIGNIFICANT_MOTION_SKIP,
+ v_int_sig_mot_skip_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_SIGNIFICANT_MOTION_SKIP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API is used to read
+ * the significant proof time from the register 0x62 bit 4 and 5
+ *
+ *
+ *
+ *
+ * @param v_significant_motion_proof_u8 :
+ * the value of significant proof time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | proof time 0.25 seconds
+ * 0x01 | proof time 0.5 seconds
+ * 0x02 | proof time 1 seconds
+ * 0x03 | proof time 2 seconds
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_significant_motion_proof(
+u8 *v_significant_motion_proof_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read significant proof time */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_SIGNIFICANT_MOTION_PROOF__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_significant_motion_proof_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_SIGNIFICANT_MOTION_PROOF);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API is used to write
+ * the significant proof time from the register 0x62 bit 4 and 5
+ *
+ *
+ *
+ *
+ * @param v_significant_motion_proof_u8 :
+ * the value of significant proof time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | proof time 0.25 seconds
+ * 0x01 | proof time 0.5 seconds
+ * 0x02 | proof time 1 seconds
+ * 0x03 | proof time 2 seconds
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_significant_motion_proof(
+u8 v_significant_motion_proof_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_significant_motion_proof_u8
+ <= SMI130_MAX_UNDER_SIG_MOTION) {
+ /* write significant proof time */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_SIGNIFICANT_MOTION_PROOF__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_SIGNIFICANT_MOTION_PROOF,
+ v_significant_motion_proof_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_SIGNIFICANT_MOTION_PROOF__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to get the tap duration
+ * from the register 0x63 bit 0 to 2
+ *
+ *
+ *
+ * @param v_tap_durn_u8 : The value of tap duration
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | SMI130_TAP_DURN_50MS
+ * 0x01 | SMI130_TAP_DURN_100MS
+ * 0x03 | SMI130_TAP_DURN_150MS
+ * 0x04 | SMI130_TAP_DURN_200MS
+ * 0x05 | SMI130_TAP_DURN_250MS
+ * 0x06 | SMI130_TAP_DURN_375MS
+ * 0x07 | SMI130_TAP_DURN_700MS
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_tap_durn(
+u8 *v_tap_durn_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read tap duration*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_DURN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_tap_durn_u8 = SMI130_GET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_DURN);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API is used to write the tap duration
+ * from the register 0x63 bit 0 to 2
+ *
+ *
+ *
+ * @param v_tap_durn_u8 : The value of tap duration
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | SMI130_TAP_DURN_50MS
+ * 0x01 | SMI130_TAP_DURN_100MS
+ * 0x03 | SMI130_TAP_DURN_150MS
+ * 0x04 | SMI130_TAP_DURN_200MS
+ * 0x05 | SMI130_TAP_DURN_250MS
+ * 0x06 | SMI130_TAP_DURN_375MS
+ * 0x07 | SMI130_TAP_DURN_700MS
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_tap_durn(
+u8 v_tap_durn_u8)
+{
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_tap_durn_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_tap_durn_u8 <= SMI130_MAX_TAP_TURN) {
+ switch (v_tap_durn_u8) {
+ case SMI130_TAP_DURN_50MS:
+ v_data_tap_durn_u8 = SMI130_TAP_DURN_50MS;
+ break;
+ case SMI130_TAP_DURN_100MS:
+ v_data_tap_durn_u8 = SMI130_TAP_DURN_100MS;
+ break;
+ case SMI130_TAP_DURN_150MS:
+ v_data_tap_durn_u8 = SMI130_TAP_DURN_150MS;
+ break;
+ case SMI130_TAP_DURN_200MS:
+ v_data_tap_durn_u8 = SMI130_TAP_DURN_200MS;
+ break;
+ case SMI130_TAP_DURN_250MS:
+ v_data_tap_durn_u8 = SMI130_TAP_DURN_250MS;
+ break;
+ case SMI130_TAP_DURN_375MS:
+ v_data_tap_durn_u8 = SMI130_TAP_DURN_375MS;
+ break;
+ case SMI130_TAP_DURN_500MS:
+ v_data_tap_durn_u8 = SMI130_TAP_DURN_500MS;
+ break;
+ case SMI130_TAP_DURN_700MS:
+ v_data_tap_durn_u8 = SMI130_TAP_DURN_700MS;
+ break;
+ default:
+ break;
+ }
+ /* write tap duration*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_DURN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_DURN,
+ v_data_tap_durn_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_DURN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API read the
+ * tap shock duration from the register 0x63 bit 2
+ *
+ * @param v_tap_shock_u8 :The value of tap shock
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | SMI130_TAP_SHOCK_50MS
+ * 0x01 | SMI130_TAP_SHOCK_75MS
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_tap_shock(
+u8 *v_tap_shock_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read tap shock duration*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_SHOCK__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_tap_shock_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_SHOCK);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write the
+ * tap shock duration from the register 0x63 bit 2
+ *
+ * @param v_tap_shock_u8 :The value of tap shock
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | SMI130_TAP_SHOCK_50MS
+ * 0x01 | SMI130_TAP_SHOCK_75MS
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_tap_shock(u8 v_tap_shock_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_tap_shock_u8 <= SMI130_MAX_VALUE_TAP_SHOCK) {
+ /* write tap shock duration*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_SHOCK__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_SHOCK,
+ v_tap_shock_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_SHOCK__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read
+ * tap quiet duration from the register 0x63 bit 7
+ *
+ *
+ * @param v_tap_quiet_u8 : The value of tap quiet
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | SMI130_TAP_QUIET_30MS
+ * 0x01 | SMI130_TAP_QUIET_20MS
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_tap_quiet(
+u8 *v_tap_quiet_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read tap quiet duration*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_QUIET__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_tap_quiet_u8 = SMI130_GET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_QUIET);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write
+ * tap quiet duration from the register 0x63 bit 7
+ *
+ *
+ * @param v_tap_quiet_u8 : The value of tap quiet
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | SMI130_TAP_QUIET_30MS
+ * 0x01 | SMI130_TAP_QUIET_20MS
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_tap_quiet(u8 v_tap_quiet_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_tap_quiet_u8 <= SMI130_MAX_VALUE_TAP_QUIET) {
+ /* write tap quiet duration*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_QUIET__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_QUIET,
+ v_tap_quiet_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_QUIET__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API read Threshold of the
+ * single/double tap interrupt from the register 0x64 bit 0 to 4
+ *
+ *
+ * @param v_tap_thres_u8 : The value of single/double tap threshold
+ *
+ * @note single/double tap threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | single/double tap threshold
+ * ----------------|---------------------
+ * 2g | ((v_tap_thres_u8 + 1) * 62.5)mg
+ * 4g | ((v_tap_thres_u8 + 1) * 125)mg
+ * 8g | ((v_tap_thres_u8 + 1) * 250)mg
+ * 16g | ((v_tap_thres_u8 + 1) * 500)mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_tap_thres(
+u8 *v_tap_thres_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read tap threshold*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_TAP_1_INTR_TAP_THRES__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_tap_thres_u8 = SMI130_GET_BITSLICE
+ (v_data_u8,
+ SMI130_USER_INTR_TAP_1_INTR_TAP_THRES);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write Threshold of the
+ * single/double tap interrupt from the register 0x64 bit 0 to 4
+ *
+ *
+ * @param v_tap_thres_u8 : The value of single/double tap threshold
+ *
+ * @note single/double tap threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | single/double tap threshold
+ * ----------------|---------------------
+ * 2g | ((v_tap_thres_u8 + 1) * 62.5)mg
+ * 4g | ((v_tap_thres_u8 + 1) * 125)mg
+ * 8g | ((v_tap_thres_u8 + 1) * 250)mg
+ * 16g | ((v_tap_thres_u8 + 1) * 500)mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_tap_thres(
+u8 v_tap_thres_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write tap threshold*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_TAP_1_INTR_TAP_THRES__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_TAP_1_INTR_TAP_THRES,
+ v_tap_thres_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_TAP_1_INTR_TAP_THRES__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API read the threshold for orient_mblation interrupt
+ * from the register 0x65 bit 0 and 1
+ *
+ * @param v_orient_mbl_mode_u8 : The value of threshold for orient_mblation
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | symmetrical
+ * 0x01 | high-asymmetrical
+ * 0x02 | low-asymmetrical
+ * 0x03 | symmetrical
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_orient_mbl_mode(
+u8 *v_orient_mbl_mode_u8)
+{
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read orient_mblation threshold*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_MODE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_orient_mbl_mode_u8 = SMI130_GET_BITSLICE
+ (v_data_u8,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_MODE);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write the threshold for orient_mblation interrupt
+ * from the register 0x65 bit 0 and 1
+ *
+ * @param v_orient_mbl_mode_u8 : The value of threshold for orient_mblation
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | symmetrical
+ * 0x01 | high-asymmetrical
+ * 0x02 | low-asymmetrical
+ * 0x03 | symmetrical
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_orient_mbl_mode(
+u8 v_orient_mbl_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_orient_mbl_mode_u8 <= SMI130_MAX_ORIENT_MODE) {
+ /* write orient_mblation threshold*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_MODE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_MODE,
+ v_orient_mbl_mode_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_MODE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read the orient_mbl blocking mode
+ * that is used for the generation of the orient_mblation interrupt.
+ * from the register 0x65 bit 2 and 3
+ *
+ * @param v_orient_mbl_blocking_u8 : The value of orient_mbl blocking mode
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | No blocking
+ * 0x01 | Theta blocking or acceleration in any axis > 1.5g
+ * 0x02 | Theta blocking or acceleration slope in any axis >
+ * - | 0.2g or acceleration in any axis > 1.5g
+ * 0x03 | Theta blocking or acceleration slope in any axis >
+ * - | 0.4g or acceleration in any axis >
+ * - | 1.5g and value of orient_mbl is not stable
+ * - | for at least 100 ms
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_orient_mbl_blocking(
+u8 *v_orient_mbl_blocking_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read orient_mbl blocking mode*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_orient_mbl_blocking_u8 = SMI130_GET_BITSLICE
+ (v_data_u8,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write the orient_mbl blocking mode
+ * that is used for the generation of the orient_mblation interrupt.
+ * from the register 0x65 bit 2 and 3
+ *
+ * @param v_orient_mbl_blocking_u8 : The value of orient_mbl blocking mode
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | No blocking
+ * 0x01 | Theta blocking or acceleration in any axis > 1.5g
+ * 0x02 | Theta blocking or acceleration slope in any axis >
+ * - | 0.2g or acceleration in any axis > 1.5g
+ * 0x03 | Theta blocking or acceleration slope in any axis >
+ * - | 0.4g or acceleration in any axis >
+ * - | 1.5g and value of orient_mbl is not stable
+ * - | for at least 100 ms
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_orient_mbl_blocking(
+u8 v_orient_mbl_blocking_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_orient_mbl_blocking_u8 <= SMI130_MAX_ORIENT_BLOCKING) {
+ /* write orient_mbl blocking mode*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING,
+ v_orient_mbl_blocking_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+}
+return com_rslt;
+}
+/*!
+ * @brief This API read Orient interrupt
+ * hysteresis, from the register 0x64 bit 4 to 7
+ *
+ *
+ *
+ * @param v_orient_mbl_hyst_u8 : The value of orient_mbl hysteresis
+ *
+ * @note 1 LSB corresponds to 62.5 mg,
+ * irrespective of the selected accel range
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_orient_mbl_hyst(
+u8 *v_orient_mbl_hyst_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read orient_mbl hysteresis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_HYST__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_orient_mbl_hyst_u8 = SMI130_GET_BITSLICE
+ (v_data_u8,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_HYST);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write Orient interrupt
+ * hysteresis, from the register 0x64 bit 4 to 7
+ *
+ *
+ *
+ * @param v_orient_mbl_hyst_u8 : The value of orient_mbl hysteresis
+ *
+ * @note 1 LSB corresponds to 62.5 mg,
+ * irrespective of the selected accel range
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_orient_mbl_hyst(
+u8 v_orient_mbl_hyst_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write orient_mbl hysteresis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_HYST__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_HYST,
+ v_orient_mbl_hyst_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_HYST__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API read Orient
+ * blocking angle (0 to 44.8) from the register 0x66 bit 0 to 5
+ *
+ * @param v_orient_mbl_theta_u8 : The value of Orient blocking angle
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_orient_mbl_theta(
+u8 *v_orient_mbl_theta_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read Orient blocking angle*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_THETA__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_orient_mbl_theta_u8 = SMI130_GET_BITSLICE
+ (v_data_u8,
+ SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_THETA);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write Orient
+ * blocking angle (0 to 44.8) from the register 0x66 bit 0 to 5
+ *
+ * @param v_orient_mbl_theta_u8 : The value of Orient blocking angle
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_orient_mbl_theta(
+u8 v_orient_mbl_theta_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_orient_mbl_theta_u8 <= SMI130_MAX_ORIENT_THETA) {
+ /* write Orient blocking angle*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_THETA__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_THETA,
+ v_orient_mbl_theta_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_THETA__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+}
+return com_rslt;
+}
+/*!
+ * @brief This API read orient_mbl change
+ * of up/down bit from the register 0x66 bit 6
+ *
+ * @param v_orient_mbl_ud_u8 : The value of orient_mbl change of up/down
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | Is ignored
+ * 0x01 | Generates orient_mblation interrupt
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_orient_mbl_ud_enable(
+u8 *v_orient_mbl_ud_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read orient_mbl up/down enable*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_orient_mbl_ud_u8 = SMI130_GET_BITSLICE
+ (v_data_u8,
+ SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write orient_mbl change
+ * of up/down bit from the register 0x66 bit 6
+ *
+ * @param v_orient_mbl_ud_u8 : The value of orient_mbl change of up/down
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | Is ignored
+ * 0x01 | Generates orient_mblation interrupt
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_orient_mbl_ud_enable(
+u8 v_orient_mbl_ud_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_orient_mbl_ud_u8 <= SMI130_MAX_VALUE_ORIENT_UD) {
+ /* write orient_mbl up/down enable */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE,
+ v_orient_mbl_ud_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+}
+return com_rslt;
+}
+ /*!
+ * @brief This API read orient_mblation axes changes
+ * from the register 0x66 bit 7
+ *
+ * @param v_orient_mbl_axes_u8 : The value of orient_mbl axes assignment
+ * value | Behaviour | Name
+ * ----------|--------------------|------
+ * 0x00 | x = x, y = y, z = z|orient_mbl_ax_noex
+ * 0x01 | x = y, y = z, z = x|orient_mbl_ax_ex
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_orient_mbl_axes_enable(
+u8 *v_orient_mbl_axes_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read orient_mblation axes changes */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_orient_mbl_axes_u8 = SMI130_GET_BITSLICE
+ (v_data_u8,
+ SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write orient_mblation axes changes
+ * from the register 0x66 bit 7
+ *
+ * @param v_orient_mbl_axes_u8 : The value of orient_mbl axes assignment
+ * value | Behaviour | Name
+ * ----------|--------------------|------
+ * 0x00 | x = x, y = y, z = z|orient_mbl_ax_noex
+ * 0x01 | x = y, y = z, z = x|orient_mbl_ax_ex
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_orient_mbl_axes_enable(
+u8 v_orient_mbl_axes_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_orient_mbl_axes_u8 <= SMI130_MAX_VALUE_ORIENT_AXES) {
+ /*write orient_mblation axes changes */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX,
+ v_orient_mbl_axes_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+}
+return com_rslt;
+}
+ /*!
+ * @brief This API read Flat angle (0 to 44.8) for flat interrupt
+ * from the register 0x67 bit 0 to 5
+ *
+ * @param v_flat_theta_u8 : The value of flat angle
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_flat_theta(
+u8 *v_flat_theta_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read Flat angle*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_FLAT_0_INTR_FLAT_THETA__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_flat_theta_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_FLAT_0_INTR_FLAT_THETA);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write Flat angle (0 to 44.8) for flat interrupt
+ * from the register 0x67 bit 0 to 5
+ *
+ * @param v_flat_theta_u8 : The value of flat angle
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_flat_theta(
+u8 v_flat_theta_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_flat_theta_u8 <= SMI130_MAX_FLAT_THETA) {
+ /* write Flat angle */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_FLAT_0_INTR_FLAT_THETA__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_FLAT_0_INTR_FLAT_THETA,
+ v_flat_theta_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_FLAT_0_INTR_FLAT_THETA__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read Flat interrupt hold time;
+ * from the register 0x68 bit 4 and 5
+ *
+ * @param v_flat_hold_u8 : The value of flat hold time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | 0ms
+ * 0x01 | 512ms
+ * 0x01 | 1024ms
+ * 0x01 | 2048ms
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_flat_hold(
+u8 *v_flat_hold_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read flat hold time*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_FLAT_1_INTR_FLAT_HOLD__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_flat_hold_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_FLAT_1_INTR_FLAT_HOLD);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write Flat interrupt hold time;
+ * from the register 0x68 bit 4 and 5
+ *
+ * @param v_flat_hold_u8 : The value of flat hold time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | 0ms
+ * 0x01 | 512ms
+ * 0x01 | 1024ms
+ * 0x01 | 2048ms
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_flat_hold(
+u8 v_flat_hold_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_flat_hold_u8 <= SMI130_MAX_FLAT_HOLD) {
+ /* write flat hold time*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_FLAT_1_INTR_FLAT_HOLD__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_FLAT_1_INTR_FLAT_HOLD,
+ v_flat_hold_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_FLAT_1_INTR_FLAT_HOLD__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read flat interrupt hysteresis
+ * from the register 0x68 bit 0 to 3
+ *
+ * @param v_flat_hyst_u8 : The value of flat hysteresis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_flat_hyst(
+u8 *v_flat_hyst_u8)
+{
+ /* variable used to return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the flat hysteresis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_FLAT_1_INTR_FLAT_HYST__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_flat_hyst_u8 = SMI130_GET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_INTR_FLAT_1_INTR_FLAT_HYST);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write flat interrupt hysteresis
+ * from the register 0x68 bit 0 to 3
+ *
+ * @param v_flat_hyst_u8 : The value of flat hysteresis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_flat_hyst(
+u8 v_flat_hyst_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_flat_hyst_u8 <= SMI130_MAX_FLAT_HYST) {
+ /* read the flat hysteresis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_FLAT_1_INTR_FLAT_HYST__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_FLAT_1_INTR_FLAT_HYST,
+ v_flat_hyst_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_FLAT_1_INTR_FLAT_HYST__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API read accel offset compensation
+ * target value for z-axis from the register 0x69 bit 0 and 1
+ *
+ * @param v_foc_accel_z_u8 : the value of accel offset compensation z axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_foc_accel_z(u8 *v_foc_accel_z_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the accel offset compensation for z axis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_Z__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_foc_accel_z_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FOC_ACCEL_Z);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write accel offset compensation
+ * target value for z-axis from the register 0x69 bit 0 and 1
+ *
+ * @param v_foc_accel_z_u8 : the value of accel offset compensation z axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_foc_accel_z(
+u8 v_foc_accel_z_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write the accel offset compensation for z axis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_Z__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FOC_ACCEL_Z,
+ v_foc_accel_z_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_Z__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read accel offset compensation
+ * target value for y-axis
+ * from the register 0x69 bit 2 and 3
+ *
+ * @param v_foc_accel_y_u8 : the value of accel offset compensation y axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_foc_accel_y(u8 *v_foc_accel_y_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the accel offset compensation for y axis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_Y__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_foc_accel_y_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FOC_ACCEL_Y);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write accel offset compensation
+ * target value for y-axis
+ * from the register 0x69 bit 2 and 3
+ *
+ * @param v_foc_accel_y_u8 : the value of accel offset compensation y axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x02 | -1g
+ * 0x03 | 0g
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_foc_accel_y(u8 v_foc_accel_y_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_foc_accel_y_u8 <= SMI130_MAX_ACCEL_FOC) {
+ /* write the accel offset compensation for y axis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_Y__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FOC_ACCEL_Y,
+ v_foc_accel_y_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_Y__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read accel offset compensation
+ * target value for x-axis is
+ * from the register 0x69 bit 4 and 5
+ *
+ * @param v_foc_accel_x_u8 : the value of accel offset compensation x axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x02 | -1g
+ * 0x03 | 0g
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_foc_accel_x(u8 *v_foc_accel_x_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the accel offset compensation for x axis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_X__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_foc_accel_x_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FOC_ACCEL_X);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write accel offset compensation
+ * target value for x-axis is
+ * from the register 0x69 bit 4 and 5
+ *
+ * @param v_foc_accel_x_u8 : the value of accel offset compensation x axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_foc_accel_x(u8 v_foc_accel_x_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_foc_accel_x_u8 <= SMI130_MAX_ACCEL_FOC) {
+ /* write the accel offset compensation for x axis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_X__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FOC_ACCEL_X,
+ v_foc_accel_x_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_X__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API writes accel fast offset compensation
+ * from the register 0x69 bit 0 to 5
+ * @brief This API writes each axis individually
+ * FOC_X_AXIS - bit 4 and 5
+ * FOC_Y_AXIS - bit 2 and 3
+ * FOC_Z_AXIS - bit 0 and 1
+ *
+ * @param v_foc_accel_u8: The value of accel offset compensation
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @param v_axis_u8: The value of accel offset axis selection
+ * value | axis
+ * ----------|-------------------
+ * 0 | FOC_X_AXIS
+ * 1 | FOC_Y_AXIS
+ * 2 | FOC_Z_AXIS
+ *
+ * @param v_accel_offset_s8: The accel offset value
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_foc_trigger(u8 v_axis_u8,
+u8 v_foc_accel_u8, s8 *v_accel_offset_s8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+s8 v_status_s8 = SUCCESS;
+u8 v_timeout_u8 = SMI130_INIT_VALUE;
+s8 v_foc_accel_offset_x_s8 = SMI130_INIT_VALUE;
+s8 v_foc_accel_offset_y_s8 = SMI130_INIT_VALUE;
+s8 v_foc_accel_offset_z_s8 = SMI130_INIT_VALUE;
+u8 focstatus = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+} else {
+ v_status_s8 = smi130_set_accel_offset_enable(
+ ACCEL_OFFSET_ENABLE);
+ if (v_status_s8 == SUCCESS) {
+ switch (v_axis_u8) {
+ case FOC_X_AXIS:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_X__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FOC_ACCEL_X,
+ v_foc_accel_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_X__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ /* trigger the
+ FOC need to write
+ 0x03 in the register 0x7e*/
+ com_rslt +=
+ smi130_set_command_register(
+ START_FOC_ACCEL_GYRO);
+
+ com_rslt +=
+ smi130_get_foc_rdy(&focstatus);
+ if ((com_rslt != SUCCESS) ||
+ (focstatus != SMI130_FOC_STAT_HIGH)) {
+ while ((com_rslt != SUCCESS) ||
+ (focstatus != SMI130_FOC_STAT_HIGH
+ && v_timeout_u8 <
+ SMI130_MAXIMUM_TIMEOUT)) {
+ p_smi130->delay_msec(
+ SMI130_DELAY_SETTLING_TIME);
+ com_rslt = smi130_get_foc_rdy(
+ &focstatus);
+ v_timeout_u8++;
+ }
+ }
+ if ((com_rslt == SUCCESS) &&
+ (focstatus == SMI130_FOC_STAT_HIGH)) {
+ com_rslt +=
+ smi130_get_accel_offset_compensation_xaxis(
+ &v_foc_accel_offset_x_s8);
+ *v_accel_offset_s8 =
+ v_foc_accel_offset_x_s8;
+ }
+ break;
+ case FOC_Y_AXIS:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_Y__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FOC_ACCEL_Y,
+ v_foc_accel_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_Y__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ /* trigger the FOC
+ need to write 0x03
+ in the register 0x7e*/
+ com_rslt +=
+ smi130_set_command_register(
+ START_FOC_ACCEL_GYRO);
+
+ com_rslt +=
+ smi130_get_foc_rdy(&focstatus);
+ if ((com_rslt != SUCCESS) ||
+ (focstatus != SMI130_FOC_STAT_HIGH)) {
+ while ((com_rslt != SUCCESS) ||
+ (focstatus != SMI130_FOC_STAT_HIGH
+ && v_timeout_u8 <
+ SMI130_MAXIMUM_TIMEOUT)) {
+ p_smi130->delay_msec(
+ SMI130_DELAY_SETTLING_TIME);
+ com_rslt = smi130_get_foc_rdy(
+ &focstatus);
+ v_timeout_u8++;
+ }
+ }
+ if ((com_rslt == SUCCESS) &&
+ (focstatus == SMI130_FOC_STAT_HIGH)) {
+ com_rslt +=
+ smi130_get_accel_offset_compensation_yaxis(
+ &v_foc_accel_offset_y_s8);
+ *v_accel_offset_s8 =
+ v_foc_accel_offset_y_s8;
+ }
+ break;
+ case FOC_Z_AXIS:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_Z__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FOC_ACCEL_Z,
+ v_foc_accel_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_Z__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ /* trigger the FOC need to write
+ 0x03 in the register 0x7e*/
+ com_rslt +=
+ smi130_set_command_register(
+ START_FOC_ACCEL_GYRO);
+
+ com_rslt +=
+ smi130_get_foc_rdy(&focstatus);
+ if ((com_rslt != SUCCESS) ||
+ (focstatus != SMI130_FOC_STAT_HIGH)) {
+ while ((com_rslt != SUCCESS) ||
+ (focstatus != SMI130_FOC_STAT_HIGH
+ && v_timeout_u8 <
+ SMI130_MAXIMUM_TIMEOUT)) {
+ p_smi130->delay_msec(
+ SMI130_DELAY_SETTLING_TIME);
+ com_rslt = smi130_get_foc_rdy(
+ &focstatus);
+ v_timeout_u8++;
+ }
+ }
+ if ((com_rslt == SUCCESS) &&
+ (focstatus == SMI130_FOC_STAT_HIGH)) {
+ com_rslt +=
+ smi130_get_accel_offset_compensation_zaxis(
+ &v_foc_accel_offset_z_s8);
+ *v_accel_offset_s8 =
+ v_foc_accel_offset_z_s8;
+ }
+ break;
+ default:
+ break;
+ }
+ } else {
+ com_rslt = ERROR;
+ }
+}
+return com_rslt;
+}
+/*!
+ * @brief This API write fast accel offset compensation
+ * it writes all axis together.To the register 0x69 bit 0 to 5
+ * FOC_X_AXIS - bit 4 and 5
+ * FOC_Y_AXIS - bit 2 and 3
+ * FOC_Z_AXIS - bit 0 and 1
+ *
+ * @param v_foc_accel_x_u8: The value of accel offset x compensation
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @param v_foc_accel_y_u8: The value of accel offset y compensation
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @param v_foc_accel_z_u8: The value of accel offset z compensation
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @param v_accel_off_x_s8: The value of accel offset x axis
+ * @param v_accel_off_y_s8: The value of accel offset y axis
+ * @param v_accel_off_z_s8: The value of accel offset z axis
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_accel_foc_trigger_xyz(u8 v_foc_accel_x_u8,
+u8 v_foc_accel_y_u8, u8 v_foc_accel_z_u8, s8 *v_accel_off_x_s8,
+s8 *v_accel_off_y_s8, s8 *v_accel_off_z_s8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 focx = SMI130_INIT_VALUE;
+u8 focy = SMI130_INIT_VALUE;
+u8 focz = SMI130_INIT_VALUE;
+s8 v_foc_accel_offset_x_s8 = SMI130_INIT_VALUE;
+s8 v_foc_accel_offset_y_s8 = SMI130_INIT_VALUE;
+s8 v_foc_accel_offset_z_s8 = SMI130_INIT_VALUE;
+u8 v_status_s8 = SUCCESS;
+u8 v_timeout_u8 = SMI130_INIT_VALUE;
+u8 focstatus = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ v_status_s8 = smi130_set_accel_offset_enable(
+ ACCEL_OFFSET_ENABLE);
+ if (v_status_s8 == SUCCESS) {
+ /* foc x axis*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_X__REG,
+ &focx, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ focx = SMI130_SET_BITSLICE(focx,
+ SMI130_USER_FOC_ACCEL_X,
+ v_foc_accel_x_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_X__REG,
+ &focx, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ /* foc y axis*/
+ com_rslt +=
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_Y__REG,
+ &focy, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ focy = SMI130_SET_BITSLICE(focy,
+ SMI130_USER_FOC_ACCEL_Y,
+ v_foc_accel_y_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_Y__REG,
+ &focy, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ /* foc z axis*/
+ com_rslt +=
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_Z__REG,
+ &focz, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ focz = SMI130_SET_BITSLICE(focz,
+ SMI130_USER_FOC_ACCEL_Z,
+ v_foc_accel_z_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_Z__REG,
+ &focz, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ /* trigger the FOC need to
+ write 0x03 in the register 0x7e*/
+ com_rslt += smi130_set_command_register(
+ START_FOC_ACCEL_GYRO);
+
+ com_rslt += smi130_get_foc_rdy(
+ &focstatus);
+ if ((com_rslt != SUCCESS) ||
+ (focstatus != SMI130_FOC_STAT_HIGH)) {
+ while ((com_rslt != SUCCESS) ||
+ (focstatus != SMI130_FOC_STAT_HIGH
+ && v_timeout_u8 <
+ SMI130_MAXIMUM_TIMEOUT)) {
+ p_smi130->delay_msec(
+ SMI130_DELAY_SETTLING_TIME);
+ com_rslt = smi130_get_foc_rdy(
+ &focstatus);
+ v_timeout_u8++;
+ }
+ }
+ if ((com_rslt == SUCCESS) &&
+ (focstatus == SMI130_GEN_READ_WRITE_DATA_LENGTH)) {
+ com_rslt +=
+ smi130_get_accel_offset_compensation_xaxis(
+ &v_foc_accel_offset_x_s8);
+ *v_accel_off_x_s8 =
+ v_foc_accel_offset_x_s8;
+ com_rslt +=
+ smi130_get_accel_offset_compensation_yaxis(
+ &v_foc_accel_offset_y_s8);
+ *v_accel_off_y_s8 =
+ v_foc_accel_offset_y_s8;
+ com_rslt +=
+ smi130_get_accel_offset_compensation_zaxis(
+ &v_foc_accel_offset_z_s8);
+ *v_accel_off_z_s8 =
+ v_foc_accel_offset_z_s8;
+ }
+ } else {
+ com_rslt = ERROR;
+ }
+ }
+return com_rslt;
+}
+/*!
+ * @brief This API read gyro fast offset enable
+ * from the register 0x69 bit 6
+ *
+ * @param v_foc_gyro_u8 : The value of gyro fast offset enable
+ * value | Description
+ * ----------|-------------
+ * 0 | fast offset compensation disabled
+ * 1 | fast offset compensation enabled
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_foc_gyro_enable(
+u8 *v_foc_gyro_u8)
+{
+ /* used for return the status of bus communication */
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the gyro fast offset enable*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_GYRO_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_foc_gyro_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FOC_GYRO_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write gyro fast offset enable
+ * from the register 0x69 bit 6
+ *
+ * @param v_foc_gyro_u8 : The value of gyro fast offset enable
+ * value | Description
+ * ----------|-------------
+ * 0 | fast offset compensation disabled
+ * 1 | fast offset compensation enabled
+ *
+ * @param v_gyro_off_x_s16 : The value of gyro fast offset x axis data
+ * @param v_gyro_off_y_s16 : The value of gyro fast offset y axis data
+ * @param v_gyro_off_z_s16 : The value of gyro fast offset z axis data
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_foc_gyro_enable(
+u8 v_foc_gyro_u8, s16 *v_gyro_off_x_s16,
+s16 *v_gyro_off_y_s16, s16 *v_gyro_off_z_s16)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+u8 v_status_s8 = SUCCESS;
+u8 v_timeout_u8 = SMI130_INIT_VALUE;
+s16 offsetx = SMI130_INIT_VALUE;
+s16 offsety = SMI130_INIT_VALUE;
+s16 offsetz = SMI130_INIT_VALUE;
+u8 focstatus = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ v_status_s8 = smi130_set_gyro_offset_enable(
+ GYRO_OFFSET_ENABLE);
+ if (v_status_s8 == SUCCESS) {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_FOC_GYRO_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FOC_GYRO_ENABLE,
+ v_foc_gyro_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_FOC_GYRO_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ /* trigger the FOC need to write 0x03
+ in the register 0x7e*/
+ com_rslt += smi130_set_command_register
+ (START_FOC_ACCEL_GYRO);
+
+ com_rslt += smi130_get_foc_rdy(&focstatus);
+ if ((com_rslt != SUCCESS) ||
+ (focstatus != SMI130_FOC_STAT_HIGH)) {
+ while ((com_rslt != SUCCESS) ||
+ (focstatus != SMI130_FOC_STAT_HIGH
+ && v_timeout_u8 <
+ SMI130_MAXIMUM_TIMEOUT)) {
+ p_smi130->delay_msec(
+ SMI130_DELAY_SETTLING_TIME);
+ com_rslt = smi130_get_foc_rdy(
+ &focstatus);
+ v_timeout_u8++;
+ }
+ }
+ if ((com_rslt == SUCCESS) &&
+ (focstatus == SMI130_FOC_STAT_HIGH)) {
+ com_rslt +=
+ smi130_get_gyro_offset_compensation_xaxis
+ (&offsetx);
+ *v_gyro_off_x_s16 = offsetx;
+
+ com_rslt +=
+ smi130_get_gyro_offset_compensation_yaxis
+ (&offsety);
+ *v_gyro_off_y_s16 = offsety;
+
+ com_rslt +=
+ smi130_get_gyro_offset_compensation_zaxis(
+ &offsetz);
+ *v_gyro_off_z_s16 = offsetz;
+ }
+ } else {
+ com_rslt = ERROR;
+ }
+ }
+return com_rslt;
+}
+ /*!
+ * @brief This API read NVM program enable
+ * from the register 0x6A bit 1
+ *
+ * @param v_nvm_prog_u8 : The value of NVM program enable
+ * Value | Description
+ * --------|-------------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_nvm_prog_enable(
+u8 *v_nvm_prog_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read NVM program*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_CONFIG_NVM_PROG_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_nvm_prog_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_CONFIG_NVM_PROG_ENABLE);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write NVM program enable
+ * from the register 0x6A bit 1
+ *
+ * @param v_nvm_prog_u8 : The value of NVM program enable
+ * Value | Description
+ * --------|-------------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_nvm_prog_enable(
+u8 v_nvm_prog_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_nvm_prog_u8 <= SMI130_MAX_VALUE_NVM_PROG) {
+ /* write the NVM program*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_CONFIG_NVM_PROG_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_CONFIG_NVM_PROG_ENABLE,
+ v_nvm_prog_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_CONFIG_NVM_PROG_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read to configure SPI
+ * Interface Mode for primary and OIS interface
+ * from the register 0x6B bit 0
+ *
+ * @param v_spi3_u8 : The value of SPI mode selection
+ * Value | Description
+ * --------|-------------
+ * 0 | SPI 4-wire mode
+ * 1 | SPI 3-wire mode
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_get_spi3(
+u8 *v_spi3_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read SPI mode*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_IF_CONFIG_SPI3__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_spi3_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_IF_CONFIG_SPI3);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write to configure SPI
+ * Interface Mode for primary and OIS interface
+ * from the register 0x6B bit 0
+ *
+ * @param v_spi3_u8 : The value of SPI mode selection
+ * Value | Description
+ * --------|-------------
+ * 0 | SPI 4-wire mode
+ * 1 | SPI 3-wire mode
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_spi3(
+u8 v_spi3_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_spi3_u8 <= SMI130_MAX_VALUE_SPI3) {
+ /* write SPI mode*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_IF_CONFIG_SPI3__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_IF_CONFIG_SPI3,
+ v_spi3_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_IF_CONFIG_SPI3__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read I2C Watchdog timer
+ * from the register 0x70 bit 1
+ *
+ * @param v_i2c_wdt_u8 : The value of I2C watch dog timer
+ * Value | Description
+ * --------|-------------
+ * 0 | I2C watchdog v_timeout_u8 after 1 ms
+ * 1 | I2C watchdog v_timeout_u8 after 50 ms
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_i2c_wdt_select(
+u8 *v_i2c_wdt_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read I2C watch dog timer */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_IF_CONFIG_I2C_WDT_SELECT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_i2c_wdt_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_IF_CONFIG_I2C_WDT_SELECT);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write I2C Watchdog timer
+ * from the register 0x70 bit 1
+ *
+ * @param v_i2c_wdt_u8 : The value of I2C watch dog timer
+ * Value | Description
+ * --------|-------------
+ * 0 | I2C watchdog v_timeout_u8 after 1 ms
+ * 1 | I2C watchdog v_timeout_u8 after 50 ms
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_i2c_wdt_select(
+u8 v_i2c_wdt_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_i2c_wdt_u8 <= SMI130_MAX_VALUE_I2C_WDT) {
+ /* write I2C watch dog timer */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_IF_CONFIG_I2C_WDT_SELECT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_IF_CONFIG_I2C_WDT_SELECT,
+ v_i2c_wdt_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_IF_CONFIG_I2C_WDT_SELECT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read I2C watchdog enable
+ * from the register 0x70 bit 2
+ *
+ * @param v_i2c_wdt_u8 : The value of I2C watchdog enable
+ * Value | Description
+ * --------|-------------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_i2c_wdt_enable(
+u8 *v_i2c_wdt_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read i2c watch dog eneble */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_IF_CONFIG_I2C_WDT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_i2c_wdt_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_IF_CONFIG_I2C_WDT_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write I2C watchdog enable
+ * from the register 0x70 bit 2
+ *
+ * @param v_i2c_wdt_u8 : The value of I2C watchdog enable
+ * Value | Description
+ * --------|-------------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_i2c_wdt_enable(
+u8 v_i2c_wdt_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_i2c_wdt_u8 <= SMI130_MAX_VALUE_I2C_WDT) {
+ /* write i2c watch dog eneble */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_IF_CONFIG_I2C_WDT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_IF_CONFIG_I2C_WDT_ENABLE,
+ v_i2c_wdt_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_IF_CONFIG_I2C_WDT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read I2C interface configuration(if) moe
+ * from the register 0x6B bit 4 and 5
+ *
+ * @param v_if_mode_u8 : The value of interface configuration mode
+ * Value | Description
+ * --------|-------------
+ * 0x00 | Primary interface:autoconfig / secondary interface:off
+ * 0x01 | Primary interface:I2C / secondary interface:OIS
+ * 0x02 | Primary interface:autoconfig/secondary interface:Magnetometer
+ * 0x03 | Reserved
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_if_mode(
+u8 *v_if_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read if mode*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_IF_CONFIG_IF_MODE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_if_mode_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_IF_CONFIG_IF_MODE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write I2C interface configuration(if) moe
+ * from the register 0x6B bit 4 and 5
+ *
+ * @param v_if_mode_u8 : The value of interface configuration mode
+ * Value | Description
+ * --------|-------------
+ * 0x00 | Primary interface:autoconfig / secondary interface:off
+ * 0x01 | Primary interface:I2C / secondary interface:OIS
+ * 0x02 | Primary interface:autoconfig/secondary interface:Magnetometer
+ * 0x03 | Reserved
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_if_mode(
+u8 v_if_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_if_mode_u8 <= SMI130_MAX_IF_MODE) {
+ /* write if mode*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_IF_CONFIG_IF_MODE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_IF_CONFIG_IF_MODE,
+ v_if_mode_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_IF_CONFIG_IF_MODE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read gyro sleep trigger
+ * from the register 0x6C bit 0 to 2
+ *
+ * @param v_gyro_sleep_trigger_u8 : The value of gyro sleep trigger
+ * Value | Description
+ * --------|-------------
+ * 0x00 | nomotion: no / Not INT1 pin: no / INT2 pin: no
+ * 0x01 | nomotion: no / Not INT1 pin: no / INT2 pin: yes
+ * 0x02 | nomotion: no / Not INT1 pin: yes / INT2 pin: no
+ * 0x03 | nomotion: no / Not INT1 pin: yes / INT2 pin: yes
+ * 0x04 | nomotion: yes / Not INT1 pin: no / INT2 pin: no
+ * 0x05 | anymotion: yes / Not INT1 pin: no / INT2 pin: yes
+ * 0x06 | anymotion: yes / Not INT1 pin: yes / INT2 pin: no
+ * 0x07 | anymotion: yes / Not INT1 pin: yes / INT2 pin: yes
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_sleep_trigger(
+u8 *v_gyro_sleep_trigger_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read gyro sleep trigger */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_SLEEP_TRIGGER__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_gyro_sleep_trigger_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_GYRO_SLEEP_TRIGGER);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write gyro sleep trigger
+ * from the register 0x6C bit 0 to 2
+ *
+ * @param v_gyro_sleep_trigger_u8 : The value of gyro sleep trigger
+ * Value | Description
+ * --------|-------------
+ * 0x00 | nomotion: no / Not INT1 pin: no / INT2 pin: no
+ * 0x01 | nomotion: no / Not INT1 pin: no / INT2 pin: yes
+ * 0x02 | nomotion: no / Not INT1 pin: yes / INT2 pin: no
+ * 0x03 | nomotion: no / Not INT1 pin: yes / INT2 pin: yes
+ * 0x04 | nomotion: yes / Not INT1 pin: no / INT2 pin: no
+ * 0x05 | anymotion: yes / Not INT1 pin: no / INT2 pin: yes
+ * 0x06 | anymotion: yes / Not INT1 pin: yes / INT2 pin: no
+ * 0x07 | anymotion: yes / Not INT1 pin: yes / INT2 pin: yes
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_sleep_trigger(
+u8 v_gyro_sleep_trigger_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_gyro_sleep_trigger_u8 <= SMI130_MAX_GYRO_SLEEP_TIGGER) {
+ /* write gyro sleep trigger */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_SLEEP_TRIGGER__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_GYRO_SLEEP_TRIGGER,
+ v_gyro_sleep_trigger_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_SLEEP_TRIGGER__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read gyro wakeup trigger
+ * from the register 0x6C bit 3 and 4
+ *
+ * @param v_gyro_wakeup_trigger_u8 : The value of gyro wakeup trigger
+ * Value | Description
+ * --------|-------------
+ * 0x00 | anymotion: no / INT1 pin: no
+ * 0x01 | anymotion: no / INT1 pin: yes
+ * 0x02 | anymotion: yes / INT1 pin: no
+ * 0x03 | anymotion: yes / INT1 pin: yes
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_wakeup_trigger(
+u8 *v_gyro_wakeup_trigger_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read gyro wakeup trigger */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_WAKEUP_TRIGGER__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_gyro_wakeup_trigger_u8 = SMI130_GET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_GYRO_WAKEUP_TRIGGER);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write gyro wakeup trigger
+ * from the register 0x6C bit 3 and 4
+ *
+ * @param v_gyro_wakeup_trigger_u8 : The value of gyro wakeup trigger
+ * Value | Description
+ * --------|-------------
+ * 0x00 | anymotion: no / INT1 pin: no
+ * 0x01 | anymotion: no / INT1 pin: yes
+ * 0x02 | anymotion: yes / INT1 pin: no
+ * 0x03 | anymotion: yes / INT1 pin: yes
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_wakeup_trigger(
+u8 v_gyro_wakeup_trigger_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_gyro_wakeup_trigger_u8
+ <= SMI130_MAX_GYRO_WAKEUP_TRIGGER) {
+ /* write gyro wakeup trigger */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_WAKEUP_TRIGGER__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_GYRO_WAKEUP_TRIGGER,
+ v_gyro_wakeup_trigger_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_WAKEUP_TRIGGER__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read Target state for gyro sleep mode
+ * from the register 0x6C bit 5
+ *
+ * @param v_gyro_sleep_state_u8 : The value of gyro sleep mode
+ * Value | Description
+ * --------|-------------
+ * 0x00 | Sleep transition to fast wake up state
+ * 0x01 | Sleep transition to suspend state
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_sleep_state(
+u8 *v_gyro_sleep_state_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read gyro sleep state*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_SLEEP_STATE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_gyro_sleep_state_u8 = SMI130_GET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_GYRO_SLEEP_STATE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write Target state for gyro sleep mode
+ * from the register 0x6C bit 5
+ *
+ * @param v_gyro_sleep_state_u8 : The value of gyro sleep mode
+ * Value | Description
+ * --------|-------------
+ * 0x00 | Sleep transition to fast wake up state
+ * 0x01 | Sleep transition to suspend state
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_sleep_state(
+u8 v_gyro_sleep_state_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_gyro_sleep_state_u8 <= SMI130_MAX_VALUE_SLEEP_STATE) {
+ /* write gyro sleep state*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_SLEEP_STATE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_GYRO_SLEEP_STATE,
+ v_gyro_sleep_state_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_SLEEP_STATE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read gyro wakeup interrupt
+ * from the register 0x6C bit 6
+ *
+ * @param v_gyro_wakeup_intr_u8 : The valeu of gyro wakeup interrupt
+ * Value | Description
+ * --------|-------------
+ * 0x00 | DISABLE
+ * 0x01 | ENABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_wakeup_intr(
+u8 *v_gyro_wakeup_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read gyro wakeup interrupt */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_WAKEUP_INTR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_gyro_wakeup_intr_u8 = SMI130_GET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_GYRO_WAKEUP_INTR);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write gyro wakeup interrupt
+ * from the register 0x6C bit 6
+ *
+ * @param v_gyro_wakeup_intr_u8 : The valeu of gyro wakeup interrupt
+ * Value | Description
+ * --------|-------------
+ * 0x00 | DISABLE
+ * 0x01 | ENABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_wakeup_intr(
+u8 v_gyro_wakeup_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_gyro_wakeup_intr_u8 <= SMI130_MAX_VALUE_WAKEUP_INTR) {
+ /* write gyro wakeup interrupt */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_WAKEUP_INTR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_GYRO_WAKEUP_INTR,
+ v_gyro_wakeup_intr_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_WAKEUP_INTR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read accel select axis to be self-test
+ *
+ * @param v_accel_selftest_axis_u8 :
+ * The value of accel self test axis selection
+ * Value | Description
+ * --------|-------------
+ * 0x00 | disabled
+ * 0x01 | x-axis
+ * 0x02 | y-axis
+ * 0x03 | z-axis
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_selftest_axis(
+u8 *v_accel_selftest_axis_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read accel self test axis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_ACCEL_SELFTEST_AXIS__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_selftest_axis_u8 = SMI130_GET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_ACCEL_SELFTEST_AXIS);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write accel select axis to be self-test
+ *
+ * @param v_accel_selftest_axis_u8 :
+ * The value of accel self test axis selection
+ * Value | Description
+ * --------|-------------
+ * 0x00 | disabled
+ * 0x01 | x-axis
+ * 0x02 | y-axis
+ * 0x03 | z-axis
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_selftest_axis(
+u8 v_accel_selftest_axis_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_accel_selftest_axis_u8
+ <= SMI130_MAX_ACCEL_SELFTEST_AXIS) {
+ /* write accel self test axis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_ACCEL_SELFTEST_AXIS__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_ACCEL_SELFTEST_AXIS,
+ v_accel_selftest_axis_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_ACCEL_SELFTEST_AXIS__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read accel self test axis sign
+ * from the register 0x6D bit 2
+ *
+ * @param v_accel_selftest_sign_u8: The value of accel self test axis sign
+ * Value | Description
+ * --------|-------------
+ * 0x00 | negative
+ * 0x01 | positive
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_selftest_sign(
+u8 *v_accel_selftest_sign_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read accel self test axis sign*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_ACCEL_SELFTEST_SIGN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_selftest_sign_u8 = SMI130_GET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_ACCEL_SELFTEST_SIGN);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write accel self test axis sign
+ * from the register 0x6D bit 2
+ *
+ * @param v_accel_selftest_sign_u8: The value of accel self test axis sign
+ * Value | Description
+ * --------|-------------
+ * 0x00 | negative
+ * 0x01 | positive
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_selftest_sign(
+u8 v_accel_selftest_sign_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_accel_selftest_sign_u8 <=
+ SMI130_MAX_VALUE_SELFTEST_SIGN) {
+ /* write accel self test axis sign*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_ACCEL_SELFTEST_SIGN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_ACCEL_SELFTEST_SIGN,
+ v_accel_selftest_sign_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_ACCEL_SELFTEST_SIGN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read accel self test amplitude
+ * from the register 0x6D bit 3
+ * select amplitude of the selftest deflection:
+ *
+ * @param v_accel_selftest_amp_u8 : The value of accel self test amplitude
+ * Value | Description
+ * --------|-------------
+ * 0x00 | LOW
+ * 0x01 | HIGH
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_selftest_amp(
+u8 *v_accel_selftest_amp_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read self test amplitude*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_SELFTEST_AMP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_selftest_amp_u8 = SMI130_GET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_SELFTEST_AMP);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write accel self test amplitude
+ * from the register 0x6D bit 3
+ * select amplitude of the selftest deflection:
+ *
+ * @param v_accel_selftest_amp_u8 : The value of accel self test amplitude
+ * Value | Description
+ * --------|-------------
+ * 0x00 | LOW
+ * 0x01 | HIGH
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_selftest_amp(
+u8 v_accel_selftest_amp_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_accel_selftest_amp_u8 <=
+ SMI130_MAX_VALUE_SELFTEST_AMP) {
+ /* write self test amplitude*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_SELFTEST_AMP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_SELFTEST_AMP,
+ v_accel_selftest_amp_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_SELFTEST_AMP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read gyro self test trigger
+ *
+ * @param v_gyro_selftest_start_u8: The value of gyro self test start
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_selftest_start(
+u8 *v_gyro_selftest_start_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read gyro self test start */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_SELFTEST_START__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_gyro_selftest_start_u8 = SMI130_GET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_GYRO_SELFTEST_START);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write gyro self test trigger
+ *
+ * @param v_gyro_selftest_start_u8: The value of gyro self test start
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_selftest_start(
+u8 v_gyro_selftest_start_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_gyro_selftest_start_u8 <=
+ SMI130_MAX_VALUE_SELFTEST_START) {
+ /* write gyro self test start */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_SELFTEST_START__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_GYRO_SELFTEST_START,
+ v_gyro_selftest_start_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_SELFTEST_START__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API read primary interface selection I2C or SPI
+ * from the register 0x70 bit 0
+ *
+ * @param v_spi_enable_u8: The value of Interface selection
+ * Value | Description
+ * --------|-------------
+ * 0x00 | I2C Enable
+ * 0x01 | I2C DISBALE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_spi_enable(u8 *v_spi_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read interface section*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_NV_CONFIG_SPI_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_spi_enable_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_NV_CONFIG_SPI_ENABLE);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write primary interface selection I2C or SPI
+ * from the register 0x70 bit 0
+ *
+ * @param v_spi_enable_u8: The value of Interface selection
+ * Value | Description
+ * --------|-------------
+ * 0x00 | I2C Enable
+ * 0x01 | I2C DISBALE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_spi_enable(u8 v_spi_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write interface section*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_NV_CONFIG_SPI_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_NV_CONFIG_SPI_ENABLE,
+ v_spi_enable_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_NV_CONFIG_SPI_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API read the spare zero
+ * form register 0x70 bit 3
+ *
+ *
+ * @param v_spare0_trim_u8: The value of spare zero
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_spare0_trim(u8 *v_spare0_trim_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read spare zero*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_NV_CONFIG_SPARE0__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_spare0_trim_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_NV_CONFIG_SPARE0);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write the spare zero
+ * form register 0x70 bit 3
+ *
+ *
+ * @param v_spare0_trim_u8: The value of spare zero
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_spare0_trim(u8 v_spare0_trim_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write spare zero*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_NV_CONFIG_SPARE0__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_NV_CONFIG_SPARE0,
+ v_spare0_trim_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_NV_CONFIG_SPARE0__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API read the NVM counter
+ * form register 0x70 bit 4 to 7
+ *
+ *
+ * @param v_nvm_counter_u8: The value of NVM counter
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_nvm_counter(u8 *v_nvm_counter_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read NVM counter*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_NV_CONFIG_NVM_COUNTER__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_nvm_counter_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_NV_CONFIG_NVM_COUNTER);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write the NVM counter
+ * form register 0x70 bit 4 to 7
+ *
+ *
+ * @param v_nvm_counter_u8: The value of NVM counter
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_nvm_counter(
+u8 v_nvm_counter_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write NVM counter*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_NV_CONFIG_NVM_COUNTER__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_NV_CONFIG_NVM_COUNTER,
+ v_nvm_counter_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_NV_CONFIG_NVM_COUNTER__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read accel manual offset compensation of x axis
+ * from the register 0x71 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_x_s8:
+ * The value of accel manual offset compensation of x axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_offset_compensation_xaxis(
+s8 *v_accel_off_x_s8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read accel manual offset compensation of x axis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_0_ACCEL_OFF_X__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_off_x_s8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_OFFSET_0_ACCEL_OFF_X);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write accel manual offset compensation of x axis
+ * from the register 0x71 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_x_s8:
+ * The value of accel manual offset compensation of x axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_offset_compensation_xaxis(
+s8 v_accel_off_x_s8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+u8 v_status_s8 = SUCCESS;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* enable accel offset */
+ v_status_s8 = smi130_set_accel_offset_enable(
+ ACCEL_OFFSET_ENABLE);
+ if (v_status_s8 == SUCCESS) {
+ /* write accel manual offset compensation of x axis*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_0_ACCEL_OFF_X__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_OFFSET_0_ACCEL_OFF_X,
+ v_accel_off_x_s8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_0_ACCEL_OFF_X__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = ERROR;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read accel manual offset compensation of y axis
+ * from the register 0x72 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_y_s8:
+ * The value of accel manual offset compensation of y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_offset_compensation_yaxis(
+s8 *v_accel_off_y_s8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read accel manual offset compensation of y axis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_1_ACCEL_OFF_Y__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_off_y_s8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_OFFSET_1_ACCEL_OFF_Y);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write accel manual offset compensation of y axis
+ * from the register 0x72 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_y_s8:
+ * The value of accel manual offset compensation of y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_offset_compensation_yaxis(
+s8 v_accel_off_y_s8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+u8 v_status_s8 = SUCCESS;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* enable accel offset */
+ v_status_s8 = smi130_set_accel_offset_enable(
+ ACCEL_OFFSET_ENABLE);
+ if (v_status_s8 == SUCCESS) {
+ /* write accel manual offset compensation of y axis*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_1_ACCEL_OFF_Y__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_OFFSET_1_ACCEL_OFF_Y,
+ v_accel_off_y_s8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_1_ACCEL_OFF_Y__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = ERROR;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read accel manual offset compensation of z axis
+ * from the register 0x73 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_z_s8:
+ * The value of accel manual offset compensation of z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_offset_compensation_zaxis(
+s8 *v_accel_off_z_s8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read accel manual offset compensation of z axis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_2_ACCEL_OFF_Z__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_off_z_s8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_OFFSET_2_ACCEL_OFF_Z);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write accel manual offset compensation of z axis
+ * from the register 0x73 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_z_s8:
+ * The value of accel manual offset compensation of z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_offset_compensation_zaxis(
+s8 v_accel_off_z_s8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ u8 v_status_s8 = SUCCESS;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* enable accel offset */
+ v_status_s8 = smi130_set_accel_offset_enable(
+ ACCEL_OFFSET_ENABLE);
+ if (v_status_s8 == SUCCESS) {
+ /* write accel manual offset
+ compensation of z axis*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_2_ACCEL_OFF_Z__REG,
+ &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_OFFSET_2_ACCEL_OFF_Z,
+ v_accel_off_z_s8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_2_ACCEL_OFF_Z__REG,
+ &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = ERROR;
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read gyro manual offset compensation of x axis
+ * from the register 0x74 bit 0 to 7 and 0x77 bit 0 and 1
+ *
+ *
+ *
+ * @param v_gyro_off_x_s16:
+ * The value of gyro manual offset compensation of x axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_offset_compensation_xaxis(
+s16 *v_gyro_off_x_s16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data1_u8r = SMI130_INIT_VALUE;
+ u8 v_data2_u8r = SMI130_INIT_VALUE;
+ s16 v_data3_u8r, v_data4_u8r = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read gyro offset x*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_3_GYRO_OFF_X__REG,
+ &v_data1_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data1_u8r = SMI130_GET_BITSLICE(v_data1_u8r,
+ SMI130_USER_OFFSET_3_GYRO_OFF_X);
+ com_rslt += p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_GYRO_OFF_X__REG,
+ &v_data2_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data2_u8r = SMI130_GET_BITSLICE(v_data2_u8r,
+ SMI130_USER_OFFSET_6_GYRO_OFF_X);
+ v_data3_u8r = v_data2_u8r
+ << SMI130_SHIFT_BIT_POSITION_BY_14_BITS;
+ v_data4_u8r = v_data1_u8r
+ << SMI130_SHIFT_BIT_POSITION_BY_06_BITS;
+ v_data3_u8r = v_data3_u8r | v_data4_u8r;
+ *v_gyro_off_x_s16 = v_data3_u8r
+ >> SMI130_SHIFT_BIT_POSITION_BY_06_BITS;
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write gyro manual offset compensation of x axis
+ * from the register 0x74 bit 0 to 7 and 0x77 bit 0 and 1
+ *
+ *
+ *
+ * @param v_gyro_off_x_s16:
+ * The value of gyro manual offset compensation of x axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_offset_compensation_xaxis(
+s16 v_gyro_off_x_s16)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data1_u8r, v_data2_u8r = SMI130_INIT_VALUE;
+u16 v_data3_u8r = SMI130_INIT_VALUE;
+u8 v_status_s8 = SUCCESS;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write gyro offset x*/
+ v_status_s8 = smi130_set_gyro_offset_enable(
+ GYRO_OFFSET_ENABLE);
+ if (v_status_s8 == SUCCESS) {
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_3_GYRO_OFF_X__REG,
+ &v_data2_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data1_u8r =
+ ((s8) (v_gyro_off_x_s16 &
+ SMI130_GYRO_MANUAL_OFFSET_0_7));
+ v_data2_u8r = SMI130_SET_BITSLICE(
+ v_data2_u8r,
+ SMI130_USER_OFFSET_3_GYRO_OFF_X,
+ v_data1_u8r);
+ /* write 0x74 bit 0 to 7*/
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_3_GYRO_OFF_X__REG,
+ &v_data2_u8r,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ com_rslt += p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_GYRO_OFF_X__REG,
+ &v_data2_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data3_u8r =
+ (u16) (v_gyro_off_x_s16 &
+ SMI130_GYRO_MANUAL_OFFSET_8_9);
+ v_data1_u8r = (u8)(v_data3_u8r
+ >> SMI130_SHIFT_BIT_POSITION_BY_08_BITS);
+ v_data2_u8r = SMI130_SET_BITSLICE(
+ v_data2_u8r,
+ SMI130_USER_OFFSET_6_GYRO_OFF_X,
+ v_data1_u8r);
+ /* write 0x77 bit 0 and 1*/
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_GYRO_OFF_X__REG,
+ &v_data2_u8r,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ return ERROR;
+ }
+ }
+return com_rslt;
+}
+/*!
+ * @brief This API read gyro manual offset compensation of y axis
+ * from the register 0x75 bit 0 to 7 and 0x77 bit 2 and 3
+ *
+ *
+ *
+ * @param v_gyro_off_y_s16:
+ * The value of gyro manual offset compensation of y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_offset_compensation_yaxis(
+s16 *v_gyro_off_y_s16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data1_u8r = SMI130_INIT_VALUE;
+ u8 v_data2_u8r = SMI130_INIT_VALUE;
+ s16 v_data3_u8r, v_data4_u8r = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read gyro offset y*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_4_GYRO_OFF_Y__REG,
+ &v_data1_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data1_u8r = SMI130_GET_BITSLICE(v_data1_u8r,
+ SMI130_USER_OFFSET_4_GYRO_OFF_Y);
+ com_rslt += p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_GYRO_OFF_Y__REG,
+ &v_data2_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data2_u8r = SMI130_GET_BITSLICE(v_data2_u8r,
+ SMI130_USER_OFFSET_6_GYRO_OFF_Y);
+ v_data3_u8r = v_data2_u8r
+ << SMI130_SHIFT_BIT_POSITION_BY_14_BITS;
+ v_data4_u8r = v_data1_u8r
+ << SMI130_SHIFT_BIT_POSITION_BY_06_BITS;
+ v_data3_u8r = v_data3_u8r | v_data4_u8r;
+ *v_gyro_off_y_s16 = v_data3_u8r
+ >> SMI130_SHIFT_BIT_POSITION_BY_06_BITS;
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write gyro manual offset compensation of y axis
+ * from the register 0x75 bit 0 to 7 and 0x77 bit 2 and 3
+ *
+ *
+ *
+ * @param v_gyro_off_y_s16:
+ * The value of gyro manual offset compensation of y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_offset_compensation_yaxis(
+s16 v_gyro_off_y_s16)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data1_u8r, v_data2_u8r = SMI130_INIT_VALUE;
+u16 v_data3_u8r = SMI130_INIT_VALUE;
+u8 v_status_s8 = SUCCESS;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* enable gyro offset bit */
+ v_status_s8 = smi130_set_gyro_offset_enable(
+ GYRO_OFFSET_ENABLE);
+ /* write gyro offset y*/
+ if (v_status_s8 == SUCCESS) {
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_OFFSET_4_GYRO_OFF_Y__REG,
+ &v_data2_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data1_u8r =
+ ((s8) (v_gyro_off_y_s16 &
+ SMI130_GYRO_MANUAL_OFFSET_0_7));
+ v_data2_u8r = SMI130_SET_BITSLICE(
+ v_data2_u8r,
+ SMI130_USER_OFFSET_4_GYRO_OFF_Y,
+ v_data1_u8r);
+ /* write 0x75 bit 0 to 7*/
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_OFFSET_4_GYRO_OFF_Y__REG,
+ &v_data2_u8r,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ com_rslt += p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_GYRO_OFF_Y__REG,
+ &v_data2_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data3_u8r =
+ (u16) (v_gyro_off_y_s16 &
+ SMI130_GYRO_MANUAL_OFFSET_8_9);
+ v_data1_u8r = (u8)(v_data3_u8r
+ >> SMI130_SHIFT_BIT_POSITION_BY_08_BITS);
+ v_data2_u8r = SMI130_SET_BITSLICE(
+ v_data2_u8r,
+ SMI130_USER_OFFSET_6_GYRO_OFF_Y,
+ v_data1_u8r);
+ /* write 0x77 bit 2 and 3*/
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_GYRO_OFF_Y__REG,
+ &v_data2_u8r,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ return ERROR;
+ }
+ }
+return com_rslt;
+}
+/*!
+ * @brief This API read gyro manual offset compensation of z axis
+ * from the register 0x76 bit 0 to 7 and 0x77 bit 4 and 5
+ *
+ *
+ *
+ * @param v_gyro_off_z_s16:
+ * The value of gyro manual offset compensation of z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_offset_compensation_zaxis(
+s16 *v_gyro_off_z_s16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data1_u8r = SMI130_INIT_VALUE;
+ u8 v_data2_u8r = SMI130_INIT_VALUE;
+ s16 v_data3_u8r, v_data4_u8r = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read gyro manual offset z axis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_OFFSET_5_GYRO_OFF_Z__REG,
+ &v_data1_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data1_u8r = SMI130_GET_BITSLICE
+ (v_data1_u8r,
+ SMI130_USER_OFFSET_5_GYRO_OFF_Z);
+ com_rslt +=
+ p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_GYRO_OFF_Z__REG,
+ &v_data2_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data2_u8r = SMI130_GET_BITSLICE(
+ v_data2_u8r,
+ SMI130_USER_OFFSET_6_GYRO_OFF_Z);
+ v_data3_u8r = v_data2_u8r
+ << SMI130_SHIFT_BIT_POSITION_BY_14_BITS;
+ v_data4_u8r = v_data1_u8r
+ << SMI130_SHIFT_BIT_POSITION_BY_06_BITS;
+ v_data3_u8r = v_data3_u8r | v_data4_u8r;
+ *v_gyro_off_z_s16 = v_data3_u8r
+ >> SMI130_SHIFT_BIT_POSITION_BY_06_BITS;
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write gyro manual offset compensation of z axis
+ * from the register 0x76 bit 0 to 7 and 0x77 bit 4 and 5
+ *
+ *
+ *
+ * @param v_gyro_off_z_s16:
+ * The value of gyro manual offset compensation of z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_offset_compensation_zaxis(
+s16 v_gyro_off_z_s16)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data1_u8r, v_data2_u8r = SMI130_INIT_VALUE;
+u16 v_data3_u8r = SMI130_INIT_VALUE;
+u8 v_status_s8 = SUCCESS;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* enable gyro offset*/
+ v_status_s8 = smi130_set_gyro_offset_enable(
+ GYRO_OFFSET_ENABLE);
+ /* write gyro manual offset z axis*/
+ if (v_status_s8 == SUCCESS) {
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_OFFSET_5_GYRO_OFF_Z__REG,
+ &v_data2_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data1_u8r =
+ ((u8) (v_gyro_off_z_s16 &
+ SMI130_GYRO_MANUAL_OFFSET_0_7));
+ v_data2_u8r = SMI130_SET_BITSLICE(
+ v_data2_u8r,
+ SMI130_USER_OFFSET_5_GYRO_OFF_Z,
+ v_data1_u8r);
+ /* write 0x76 bit 0 to 7*/
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_OFFSET_5_GYRO_OFF_Z__REG,
+ &v_data2_u8r,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ com_rslt += p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_GYRO_OFF_Z__REG,
+ &v_data2_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data3_u8r =
+ (u16) (v_gyro_off_z_s16 &
+ SMI130_GYRO_MANUAL_OFFSET_8_9);
+ v_data1_u8r = (u8)(v_data3_u8r
+ >> SMI130_SHIFT_BIT_POSITION_BY_08_BITS);
+ v_data2_u8r = SMI130_SET_BITSLICE(
+ v_data2_u8r,
+ SMI130_USER_OFFSET_6_GYRO_OFF_Z,
+ v_data1_u8r);
+ /* write 0x77 bit 4 and 5*/
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_GYRO_OFF_Z__REG,
+ &v_data2_u8r,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ return ERROR;
+ }
+ }
+return com_rslt;
+}
+/*!
+ * @brief This API read the accel offset enable bit
+ * from the register 0x77 bit 6
+ *
+ *
+ *
+ * @param v_accel_off_enable_u8: The value of accel offset enable
+ * value | Description
+ * ----------|--------------
+ * 0x01 | ENABLE
+ * 0x00 | DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_offset_enable(
+u8 *v_accel_off_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read accel offset enable */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_ACCEL_OFF_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_off_enable_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_OFFSET_6_ACCEL_OFF_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write the accel offset enable bit
+ * from the register 0x77 bit 6
+ *
+ *
+ *
+ * @param v_accel_off_enable_u8: The value of accel offset enable
+ * value | Description
+ * ----------|--------------
+ * 0x01 | ENABLE
+ * 0x00 | DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_offset_enable(
+u8 v_accel_off_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write accel offset enable */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_ACCEL_OFF_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_OFFSET_6_ACCEL_OFF_ENABLE,
+ v_accel_off_enable_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_ACCEL_OFF_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API read the accel offset enable bit
+ * from the register 0x77 bit 7
+ *
+ *
+ *
+ * @param v_gyro_off_enable_u8: The value of gyro offset enable
+ * value | Description
+ * ----------|--------------
+ * 0x01 | ENABLE
+ * 0x00 | DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_offset_enable(
+u8 *v_gyro_off_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read gyro offset*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_GYRO_OFF_EN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_gyro_off_enable_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_OFFSET_6_GYRO_OFF_EN);
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API write the accel offset enable bit
+ * from the register 0x77 bit 7
+ *
+ *
+ *
+ * @param v_gyro_off_enable_u8: The value of gyro offset enable
+ * value | Description
+ * ----------|--------------
+ * 0x01 | ENABLE
+ * 0x00 | DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_offset_enable(
+u8 v_gyro_off_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write gyro offset*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_GYRO_OFF_EN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_OFFSET_6_GYRO_OFF_EN,
+ v_gyro_off_enable_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_GYRO_OFF_EN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API reads step counter value
+ * form the register 0x78 and 0x79
+ *
+ *
+ *
+ *
+ * @param v_step_cnt_s16 : The value of step counter
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_step_count(u16 *v_step_cnt_s16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* array having the step counter LSB and MSB data
+ v_data_u8[0] - LSB
+ v_data_u8[1] - MSB*/
+ u8 a_data_u8r[SMI130_STEP_COUNT_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read step counter */
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_STEP_COUNT_LSB__REG,
+ a_data_u8r, SMI130_STEP_COUNTER_LENGTH);
+
+ *v_step_cnt_s16 = (s16)
+ ((((s32)((s8)a_data_u8r[SMI130_STEP_COUNT_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (a_data_u8r[SMI130_STEP_COUNT_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API Reads
+ * step counter configuration
+ * from the register 0x7A bit 0 to 7
+ * and from the register 0x7B bit 0 to 2 and 4 to 7
+ *
+ *
+ * @param v_step_config_u16 : The value of step configuration
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_step_config(
+u16 *v_step_config_u16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data1_u8r = SMI130_INIT_VALUE;
+ u8 v_data2_u8r = SMI130_INIT_VALUE;
+ u16 v_data3_u8r = SMI130_INIT_VALUE;
+ /* Read the 0 to 7 bit*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_STEP_CONFIG_ZERO__REG,
+ &v_data1_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ /* Read the 8 to 10 bit*/
+ com_rslt +=
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_STEP_CONFIG_ONE_CNF1__REG,
+ &v_data2_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data2_u8r = SMI130_GET_BITSLICE(v_data2_u8r,
+ SMI130_USER_STEP_CONFIG_ONE_CNF1);
+ v_data3_u8r = ((u16)((((u32)
+ ((u8)v_data2_u8r))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) | (v_data1_u8r)));
+ /* Read the 11 to 14 bit*/
+ com_rslt +=
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_STEP_CONFIG_ONE_CNF2__REG,
+ &v_data1_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data1_u8r = SMI130_GET_BITSLICE(v_data1_u8r,
+ SMI130_USER_STEP_CONFIG_ONE_CNF2);
+ *v_step_config_u16 = ((u16)((((u32)
+ ((u8)v_data1_u8r))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) | (v_data3_u8r)));
+
+ return com_rslt;
+}
+ /*!
+ * @brief This API write
+ * step counter configuration
+ * from the register 0x7A bit 0 to 7
+ * and from the register 0x7B bit 0 to 2 and 4 to 7
+ *
+ *
+ * @param v_step_config_u16 :
+ * the value of Enable step configuration
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_step_config(
+u16 v_step_config_u16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data1_u8r = SMI130_INIT_VALUE;
+ u8 v_data2_u8r = SMI130_INIT_VALUE;
+ u16 v_data3_u16 = SMI130_INIT_VALUE;
+
+ /* write the 0 to 7 bit*/
+ v_data1_u8r = (u8)(v_step_config_u16 &
+ SMI130_STEP_CONFIG_0_7);
+ p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_STEP_CONFIG_ZERO__REG,
+ &v_data1_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ /* write the 8 to 10 bit*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_STEP_CONFIG_ONE_CNF1__REG,
+ &v_data2_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data3_u16 = (u16) (v_step_config_u16 &
+ SMI130_STEP_CONFIG_8_10);
+ v_data1_u8r = (u8)(v_data3_u16
+ >> SMI130_SHIFT_BIT_POSITION_BY_08_BITS);
+ v_data2_u8r = SMI130_SET_BITSLICE(v_data2_u8r,
+ SMI130_USER_STEP_CONFIG_ONE_CNF1, v_data1_u8r);
+ p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_STEP_CONFIG_ONE_CNF1__REG,
+ &v_data2_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ /* write the 11 to 14 bit*/
+ com_rslt += p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_STEP_CONFIG_ONE_CNF2__REG,
+ &v_data2_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data3_u16 = (u16) (v_step_config_u16 &
+ SMI130_STEP_CONFIG_11_14);
+ v_data1_u8r = (u8)(v_data3_u16
+ >> SMI130_SHIFT_BIT_POSITION_BY_12_BITS);
+ v_data2_u8r = SMI130_SET_BITSLICE(v_data2_u8r,
+ SMI130_USER_STEP_CONFIG_ONE_CNF2, v_data1_u8r);
+ p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_STEP_CONFIG_ONE_CNF2__REG,
+ &v_data2_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ return com_rslt;
+}
+ /*!
+ * @brief This API read enable step counter
+ * from the register 0x7B bit 3
+ *
+ *
+ * @param v_step_counter_u8 : The value of step counter enable
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_step_counter_enable(
+u8 *v_step_counter_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the step counter */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_step_counter_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write enable step counter
+ * from the register 0x7B bit 3
+ *
+ *
+ * @param v_step_counter_u8 : The value of step counter enable
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_step_counter_enable(u8 v_step_counter_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+} else {
+ if (v_step_counter_u8 <= SMI130_MAX_GYRO_STEP_COUNTER) {
+ /* write the step counter */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE,
+ v_step_counter_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+}
+ return com_rslt;
+}
+ /*!
+ * @brief This API set Step counter modes
+ *
+ *
+ * @param v_step_mode_u8 : The value of step counter mode
+ * value | mode
+ * ----------|-----------
+ * 0 | SMI130_STEP_NORMAL_MODE
+ * 1 | SMI130_STEP_SENSITIVE_MODE
+ * 2 | SMI130_STEP_ROBUST_MODE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_step_mode(u8 v_step_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+
+ switch (v_step_mode_u8) {
+ case SMI130_STEP_NORMAL_MODE:
+ com_rslt = smi130_set_step_config(
+ STEP_CONFIG_NORMAL);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ break;
+ case SMI130_STEP_SENSITIVE_MODE:
+ com_rslt = smi130_set_step_config(
+ STEP_CONFIG_SENSITIVE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ break;
+ case SMI130_STEP_ROBUST_MODE:
+ com_rslt = smi130_set_step_config(
+ STEP_CONFIG_ROBUST);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+
+ return com_rslt;
+}
+/*!
+ * @brief This API used to trigger the signification motion
+ * interrupt
+ *
+ *
+ * @param v_significant_u8 : The value of interrupt selection
+ * value | interrupt
+ * ----------|-----------
+ * 0 | SMI130_MAP_INTR1
+ * 1 | SMI130_MAP_INTR2
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_map_significant_motion_intr(
+u8 v_significant_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_sig_motion_u8 = SMI130_INIT_VALUE;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ u8 v_any_motion_intr1_stat_u8 = SMI130_ENABLE_ANY_MOTION_INTR1;
+ u8 v_any_motion_intr2_stat_u8 = SMI130_ENABLE_ANY_MOTION_INTR2;
+ u8 v_any_motion_axis_stat_u8 = SMI130_ENABLE_ANY_MOTION_AXIS;
+ /* enable the significant motion interrupt */
+ com_rslt = smi130_get_intr_significant_motion_select(&v_sig_motion_u8);
+ if (v_sig_motion_u8 != SMI130_SIG_MOTION_STAT_HIGH)
+ com_rslt += smi130_set_intr_significant_motion_select(
+ SMI130_SIG_MOTION_INTR_ENABLE);
+ switch (v_significant_u8) {
+ case SMI130_MAP_INTR1:
+ /* interrupt */
+ com_rslt += smi130_read_reg(
+ SMI130_USER_INTR_MAP_0_INTR1_ANY_MOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data_u8 |= v_any_motion_intr1_stat_u8;
+ /* map the signification interrupt to any-motion interrupt1*/
+ com_rslt += smi130_write_reg(
+ SMI130_USER_INTR_MAP_0_INTR1_ANY_MOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* axis*/
+ com_rslt = smi130_read_reg(SMI130_USER_INTR_ENABLE_0_ADDR,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data_u8 |= v_any_motion_axis_stat_u8;
+ com_rslt += smi130_write_reg(
+ SMI130_USER_INTR_ENABLE_0_ADDR,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ break;
+
+ case SMI130_MAP_INTR2:
+ /* map the signification interrupt to any-motion interrupt2*/
+ com_rslt += smi130_read_reg(
+ SMI130_USER_INTR_MAP_2_INTR2_ANY_MOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data_u8 |= v_any_motion_intr2_stat_u8;
+ com_rslt += smi130_write_reg(
+ SMI130_USER_INTR_MAP_2_INTR2_ANY_MOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* axis*/
+ com_rslt = smi130_read_reg(SMI130_USER_INTR_ENABLE_0_ADDR,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data_u8 |= v_any_motion_axis_stat_u8;
+ com_rslt += smi130_write_reg(
+ SMI130_USER_INTR_ENABLE_0_ADDR,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ break;
+
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This API used to trigger the step detector
+ * interrupt
+ *
+ *
+ * @param v_step_detector_u8 : The value of interrupt selection
+ * value | interrupt
+ * ----------|-----------
+ * 0 | SMI130_MAP_INTR1
+ * 1 | SMI130_MAP_INTR2
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_map_step_detector_intr(
+u8 v_step_detector_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_step_det_u8 = SMI130_INIT_VALUE;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ u8 v_low_g_intr_u81_stat_u8 = SMI130_LOW_G_INTR_STAT;
+ u8 v_low_g_intr_u82_stat_u8 = SMI130_LOW_G_INTR_STAT;
+ u8 v_low_g_enable_u8 = SMI130_ENABLE_LOW_G;
+ /* read the v_status_s8 of step detector interrupt*/
+ com_rslt = smi130_get_step_detector_enable(&v_step_det_u8);
+ if (v_step_det_u8 != SMI130_STEP_DET_STAT_HIGH)
+ com_rslt += smi130_set_step_detector_enable(
+ SMI130_STEP_DETECT_INTR_ENABLE);
+ switch (v_step_detector_u8) {
+ case SMI130_MAP_INTR1:
+ com_rslt += smi130_read_reg(
+ SMI130_USER_INTR_MAP_0_INTR1_LOW_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data_u8 |= v_low_g_intr_u81_stat_u8;
+ /* map the step detector interrupt
+ to Low-g interrupt 1*/
+ com_rslt += smi130_write_reg(
+ SMI130_USER_INTR_MAP_0_INTR1_LOW_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* Enable the Low-g interrupt*/
+ com_rslt = smi130_read_reg(
+ SMI130_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data_u8 |= v_low_g_enable_u8;
+ com_rslt += smi130_write_reg(
+ SMI130_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ break;
+ case SMI130_MAP_INTR2:
+ /* map the step detector interrupt
+ to Low-g interrupt 1*/
+ com_rslt += smi130_read_reg(
+ SMI130_USER_INTR_MAP_2_INTR2_LOW_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data_u8 |= v_low_g_intr_u82_stat_u8;
+
+ com_rslt += smi130_write_reg(
+ SMI130_USER_INTR_MAP_2_INTR2_LOW_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* Enable the Low-g interrupt*/
+ com_rslt = smi130_read_reg(
+ SMI130_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data_u8 |= v_low_g_enable_u8;
+ com_rslt += smi130_write_reg(
+ SMI130_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API used to clear the step counter interrupt
+ * interrupt
+ *
+ *
+ * @param : None
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_clear_step_counter(void)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* clear the step counter*/
+ com_rslt = smi130_set_command_register(RESET_STEP_COUNTER);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+
+ return com_rslt;
+
+}
+ /*!
+ * @brief This API writes value to the register 0x7E bit 0 to 7
+ *
+ *
+ * @param v_command_reg_u8 : The value to write command register
+ * value | Description
+ * ---------|--------------------------------------------------------
+ * 0x00 | Reserved
+ * 0x03 | Starts fast offset calibration for the accel and gyro
+ * 0x10 | Sets the PMU mode for the Accelerometer to suspend
+ * 0x11 | Sets the PMU mode for the Accelerometer to normal
+ * 0x12 | Sets the PMU mode for the Accelerometer Lowpower
+ * 0x14 | Sets the PMU mode for the Gyroscope to suspend
+ * 0x15 | Sets the PMU mode for the Gyroscope to normal
+ * 0x16 | Reserved
+ * 0x17 | Sets the PMU mode for the Gyroscope to fast start-up
+ * 0x18 | Sets the PMU mode for the Magnetometer to suspend
+ * 0x19 | Sets the PMU mode for the Magnetometer to normal
+ * 0x1A | Sets the PMU mode for the Magnetometer to Lowpower
+ * 0xB0 | Clears all data in the FIFO
+ * 0xB1 | Resets the interrupt engine
+ * 0xB2 | step_cnt_clr Clears the step counter
+ * 0xB6 | Triggers a reset
+ * 0x37 | See extmode_en_last
+ * 0x9A | See extmode_en_last
+ * 0xC0 | Enable the extended mode
+ * 0xC4 | Erase NVM cell
+ * 0xC8 | Load NVM cell
+ * 0xF0 | Reset acceleration data path
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_command_register(u8 v_command_reg_u8)
+{
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write command register */
+ com_rslt = p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_CMD_COMMANDS__REG,
+ &v_command_reg_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API read target page from the register 0x7F bit 4 and 5
+ *
+ * @param v_target_page_u8: The value of target page
+ * value | page
+ * ---------|-----------
+ * 0 | User data/configure page
+ * 1 | Chip level trim/test page
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_target_page(u8 *v_target_page_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the page*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_CMD_TARGET_PAGE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_target_page_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_CMD_TARGET_PAGE);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write target page from the register 0x7F bit 4 and 5
+ *
+ * @param v_target_page_u8: The value of target page
+ * value | page
+ * ---------|-----------
+ * 0 | User data/configure page
+ * 1 | Chip level trim/test page
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_target_page(u8 v_target_page_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_target_page_u8 <= SMI130_MAX_TARGET_PAGE) {
+ /* write the page*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_CMD_TARGET_PAGE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_CMD_TARGET_PAGE,
+ v_target_page_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_CMD_TARGET_PAGE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API read page enable from the register 0x7F bit 7
+ *
+ *
+ *
+ * @param v_page_enable_u8: The value of page enable
+ * value | page
+ * ---------|-----------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_paging_enable(u8 *v_page_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the page enable */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_CMD_PAGING_EN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_page_enable_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_CMD_PAGING_EN);
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API write page enable from the register 0x7F bit 7
+ *
+ *
+ *
+ * @param v_page_enable_u8: The value of page enable
+ * value | page
+ * ---------|-----------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_paging_enable(
+u8 v_page_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_page_enable_u8 <= SMI130_MAX_VALUE_PAGE) {
+ /* write the page enable */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_CMD_PAGING_EN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_CMD_PAGING_EN,
+ v_page_enable_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_CMD_PAGING_EN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+ * @brief This API read
+ * pull up configuration from the register 0X85 bit 4 an 5
+ *
+ *
+ *
+ * @param v_control_pullup_u8: The value of pull up register
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_pullup_configuration(
+u8 *v_control_pullup_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read pull up value */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_COM_C_TRIM_FIVE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_control_pullup_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_COM_C_TRIM_FIVE);
+ }
+ return com_rslt;
+
+}
+ /*!
+ * @brief This API write
+ * pull up configuration from the register 0X85 bit 4 an 5
+ *
+ *
+ *
+ * @param v_control_pullup_u8: The value of pull up register
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_pullup_configuration(
+u8 v_control_pullup_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write pull up value */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_COM_C_TRIM_FIVE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_COM_C_TRIM_FIVE,
+ v_control_pullup_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_COM_C_TRIM_FIVE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+
+/*!
+ * @brief This function used for read the compensated value of mag
+ * Before start reading the mag compensated data's
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bmm150_mag_compensate_xyz(
+struct smi130_mag_xyz_s32_t *mag_comp_xyz)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ struct smi130_mag_xyzr_t mag_xyzr;
+ com_rslt = smi130_read_mag_xyzr(&mag_xyzr);
+ if (com_rslt)
+ return com_rslt;
+ /* Compensation for X axis */
+ mag_comp_xyz->x = smi130_bmm150_mag_compensate_X(
+ mag_xyzr.x, mag_xyzr.r);
+
+ /* Compensation for Y axis */
+ mag_comp_xyz->y = smi130_bmm150_mag_compensate_Y(
+ mag_xyzr.y, mag_xyzr.r);
+
+ /* Compensation for Z axis */
+ mag_comp_xyz->z = smi130_bmm150_mag_compensate_Z(
+ mag_xyzr.z, mag_xyzr.r);
+
+ return com_rslt;
+}
+
+/*!
+ * @brief This function used for read the compensated value of mag
+ * Before start reading the mag compensated data's
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bmm150_mag_compensate_xyz_raw(
+struct smi130_mag_xyz_s32_t *mag_comp_xyz, struct smi130_mag_xyzr_t mag_xyzr)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+
+ /* Compensation for X axis */
+ mag_comp_xyz->x = smi130_bmm150_mag_compensate_X(
+ mag_xyzr.x, mag_xyzr.r);
+
+ /* Compensation for Y axis */
+ mag_comp_xyz->y = smi130_bmm150_mag_compensate_Y(
+ mag_xyzr.y, mag_xyzr.r);
+
+ /* Compensation for Z axis */
+ mag_comp_xyz->z = smi130_bmm150_mag_compensate_Z(
+ mag_xyzr.z, mag_xyzr.r);
+
+ return com_rslt;
+}
+/*!
+ * @brief This API used to get the compensated BMM150-X data
+ * the out put of X as s32
+ * Before start reading the mag compensated X data
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ *
+ * @param v_mag_data_x_s16 : The value of mag raw X data
+ * @param v_data_r_u16 : The value of mag R data
+ *
+ * @return results of compensated X data value output as s32
+ *
+ */
+s32 smi130_bmm150_mag_compensate_X(s16 v_mag_data_x_s16, u16 v_data_r_u16)
+{
+s32 inter_retval = SMI130_INIT_VALUE;
+/* no overflow */
+if (v_mag_data_x_s16 != SMI130_MAG_FLIP_OVERFLOW_ADCVAL) {
+ if ((v_data_r_u16 != 0)
+ && (mag_trim_mbl.dig_xyz1 != 0)) {
+ inter_retval = ((s32)(((u16)
+ ((((s32)mag_trim_mbl.dig_xyz1)
+ << SMI130_SHIFT_BIT_POSITION_BY_14_BITS)/
+ (v_data_r_u16 != 0 ?
+ v_data_r_u16 : mag_trim_mbl.dig_xyz1))) -
+ ((u16)0x4000)));
+ } else {
+ inter_retval = SMI130_MAG_OVERFLOW_OUTPUT;
+ return inter_retval;
+ }
+ inter_retval = ((s32)((((s32)v_mag_data_x_s16) *
+ ((((((((s32)mag_trim_mbl.dig_xy2) *
+ ((((s32)inter_retval) *
+ ((s32)inter_retval))
+ >> SMI130_SHIFT_BIT_POSITION_BY_07_BITS)) +
+ (((s32)inter_retval) *
+ ((s32)(((s16)mag_trim_mbl.dig_xy1)
+ << SMI130_SHIFT_BIT_POSITION_BY_07_BITS))))
+ >> SMI130_SHIFT_BIT_POSITION_BY_09_BITS) +
+ ((s32)0x100000)) *
+ ((s32)(((s16)mag_trim_mbl.dig_x2) +
+ ((s16)0xA0))))
+ >> SMI130_SHIFT_BIT_POSITION_BY_12_BITS))
+ >> SMI130_SHIFT_BIT_POSITION_BY_13_BITS)) +
+ (((s16)mag_trim_mbl.dig_x1)
+ << SMI130_SHIFT_BIT_POSITION_BY_03_BITS);
+ /* check the overflow output */
+ if (inter_retval == (s32)SMI130_MAG_OVERFLOW_OUTPUT)
+ inter_retval = SMI130_MAG_OVERFLOW_OUTPUT_S32;
+} else {
+ /* overflow */
+ inter_retval = SMI130_MAG_OVERFLOW_OUTPUT;
+}
+return inter_retval;
+}
+/*!
+ * @brief This API used to get the compensated BMM150-Y data
+ * the out put of Y as s32
+ * Before start reading the mag compensated Y data
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ *
+ * @param v_mag_data_y_s16 : The value of mag raw Y data
+ * @param v_data_r_u16 : The value of mag R data
+ *
+ * @return results of compensated Y data value output as s32
+ */
+s32 smi130_bmm150_mag_compensate_Y(s16 v_mag_data_y_s16, u16 v_data_r_u16)
+{
+s32 inter_retval = SMI130_INIT_VALUE;
+/* no overflow */
+if (v_mag_data_y_s16 != SMI130_MAG_FLIP_OVERFLOW_ADCVAL) {
+ if ((v_data_r_u16 != 0)
+ && (mag_trim_mbl.dig_xyz1 != 0)) {
+ inter_retval = ((s32)(((u16)(((
+ (s32)mag_trim_mbl.dig_xyz1)
+ << SMI130_SHIFT_BIT_POSITION_BY_14_BITS) /
+ (v_data_r_u16 != 0 ?
+ v_data_r_u16 : mag_trim_mbl.dig_xyz1))) -
+ ((u16)0x4000)));
+ } else {
+ inter_retval = SMI130_MAG_OVERFLOW_OUTPUT;
+ return inter_retval;
+ }
+ inter_retval = ((s32)((((s32)v_mag_data_y_s16) * ((((((((s32)
+ mag_trim_mbl.dig_xy2) * ((((s32) inter_retval) *
+ ((s32)inter_retval)) >> SMI130_SHIFT_BIT_POSITION_BY_07_BITS))
+ + (((s32)inter_retval) *
+ ((s32)(((s16)mag_trim_mbl.dig_xy1)
+ << SMI130_SHIFT_BIT_POSITION_BY_07_BITS))))
+ >> SMI130_SHIFT_BIT_POSITION_BY_09_BITS) +
+ ((s32)0x100000))
+ * ((s32)(((s16)mag_trim_mbl.dig_y2)
+ + ((s16)0xA0))))
+ >> SMI130_SHIFT_BIT_POSITION_BY_12_BITS))
+ >> SMI130_SHIFT_BIT_POSITION_BY_13_BITS)) +
+ (((s16)mag_trim_mbl.dig_y1)
+ << SMI130_SHIFT_BIT_POSITION_BY_03_BITS);
+ /* check the overflow output */
+ if (inter_retval == (s32)SMI130_MAG_OVERFLOW_OUTPUT)
+ inter_retval = SMI130_MAG_OVERFLOW_OUTPUT_S32;
+} else {
+ /* overflow */
+ inter_retval = SMI130_MAG_OVERFLOW_OUTPUT;
+}
+return inter_retval;
+}
+/*!
+ * @brief This API used to get the compensated BMM150-Z data
+ * the out put of Z as s32
+ * Before start reading the mag compensated Z data
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ *
+ * @param v_mag_data_z_s16 : The value of mag raw Z data
+ * @param v_data_r_u16 : The value of mag R data
+ *
+ * @return results of compensated Z data value output as s32
+ */
+s32 smi130_bmm150_mag_compensate_Z(s16 v_mag_data_z_s16, u16 v_data_r_u16)
+{
+ s32 retval = SMI130_INIT_VALUE;
+
+ if (v_mag_data_z_s16 != SMI130_MAG_HALL_OVERFLOW_ADCVAL) {
+ if ((v_data_r_u16 != 0)
+ && (mag_trim_mbl.dig_z2 != 0)
+ /* && (mag_trim_mbl.dig_z3 != 0)*/
+ && (mag_trim_mbl.dig_z1 != 0)
+ && (mag_trim_mbl.dig_xyz1 != 0)) {
+ retval = (((((s32)(v_mag_data_z_s16 - mag_trim_mbl.dig_z4))
+ << SMI130_SHIFT_BIT_POSITION_BY_15_BITS) -
+ ((((s32)mag_trim_mbl.dig_z3) *
+ ((s32)(((s16)v_data_r_u16) -
+ ((s16)mag_trim_mbl.dig_xyz1))))
+ >> SMI130_SHIFT_BIT_POSITION_BY_02_BITS))/
+ (mag_trim_mbl.dig_z2 +
+ ((s16)(((((s32)mag_trim_mbl.dig_z1) *
+ ((((s16)v_data_r_u16)
+ << SMI130_SHIFT_BIT_POSITION_BY_01_BIT))) +
+ (1 << SMI130_SHIFT_BIT_POSITION_BY_15_BITS))
+ >> SMI130_SHIFT_BIT_POSITION_BY_16_BITS))));
+ }
+ } else {
+ retval = SMI130_MAG_OVERFLOW_OUTPUT;
+ }
+ return retval;
+}
+ /*!
+ * @brief This function used for initialize the bmm150 sensor
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bmm150_mag_interface_init(void)
+{
+ /* This variable used for provide the communication
+ results*/
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = SMI130_INIT_VALUE;
+ u8 v_pull_value_u8 = SMI130_INIT_VALUE;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* accel operation mode to normal*/
+ com_rslt = smi130_set_command_register(ACCEL_MODE_NORMAL);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* write the mag power mode as NORMAL*/
+ com_rslt += smi130_set_mag_interface_normal();
+
+ /* register 0x7E write the 0x37, 0x9A and 0x30*/
+ com_rslt += smi130_set_command_register(SMI130_COMMAND_REG_ONE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_command_register(SMI130_COMMAND_REG_TWO);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_command_register(SMI130_COMMAND_REG_THREE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /*switch the page1*/
+ com_rslt += smi130_set_target_page(SMI130_WRITE_TARGET_PAGE1);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_target_page(&v_data_u8);
+ com_rslt += smi130_set_paging_enable(SMI130_WRITE_ENABLE_PAGE1);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_paging_enable(&v_data_u8);
+ /* enable the pullup configuration from
+ the register 0x05 bit 4 and 5 as 10*/
+ smi130_get_pullup_configuration(&v_pull_value_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ v_pull_value_u8 = v_pull_value_u8 | SMI130_PULL_UP_DATA;
+ com_rslt += smi130_set_pullup_configuration(v_pull_value_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /*switch the page0*/
+ com_rslt += smi130_set_target_page(SMI130_WRITE_TARGET_PAGE0);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_target_page(&v_data_u8);
+ /* Write the BMM150 i2c address*/
+ com_rslt += smi130_set_i2c_device_addr(SMI130_AUX_BMM150_I2C_ADDRESS);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* enable the mag interface to manual mode*/
+ com_rslt += smi130_set_mag_manual_enable(SMI130_MANUAL_ENABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_mag_manual_enable(&v_data_u8);
+ /*Enable the MAG interface */
+ com_rslt += smi130_set_if_mode(SMI130_ENABLE_MAG_IF_MODE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_if_mode(&v_data_u8);
+ /* Mag normal mode*/
+ com_rslt += smi130_bmm150_mag_wakeup();
+ printk(KERN_INFO "com_rslt:%d, <%s><%d>\n",
+ com_rslt, __func__, __LINE__);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* Read the BMM150 device id is 0x32*/
+ /*com_rslt += smi130_set_mag_read_addr(SMI130_BMM150_CHIP_ID);*/
+ /*p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);*/
+ /*com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);*/
+ /**v_chip_id_u8 = v_data_u8;*/
+ /*p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);*/
+ /* write the power mode register*/
+ com_rslt += smi130_set_mag_write_data(SMI130_BMM_POWER_MODE_REG);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /*write 0x4C register to write set power mode to normal*/
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_POWE_MODE_REG);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* read the mag trim values*/
+ com_rslt += smi130_read_bmm150_mag_trim_mbl();
+ printk(KERN_INFO "com_rslt:%d, <%s><%d>\n",
+ com_rslt, __func__, __LINE__);
+ /* To avoid the auto mode enable when manual mode operation running*/
+ V_bmm150_maual_auto_condition_u8_mbl = SMI130_MANUAL_ENABLE;
+ /* write the XY and Z repetitions*/
+ com_rslt += smi130_set_bmm150_mag_presetmode(
+ SMI130_MAG_PRESETMODE_REGULAR);
+ printk(KERN_INFO "com_rslt:%d, <%s><%d>\n",
+ com_rslt, __func__, __LINE__);
+ /* To avoid the auto mode enable when manual mode operation running*/
+ V_bmm150_maual_auto_condition_u8_mbl = SMI130_MANUAL_DISABLE;
+ /* Set the power mode of mag as force mode*/
+ /* The data have to write for the register
+ It write the value in the register 0x4F */
+ com_rslt += smi130_set_mag_write_data(SMI130_BMM150_FORCE_MODE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ printk(KERN_INFO "com_rslt:%d, <%s><%d>\n",
+ com_rslt, __func__, __LINE__);
+ /* write into power mode register*/
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_POWE_MODE_REG);
+ /* write the mag v_data_bw_u8 as 25Hz*/
+ com_rslt += smi130_set_mag_output_data_rate(
+ SMI130_MAG_OUTPUT_DATA_RATE_25HZ);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+
+ /* When mag interface is auto mode - The mag read address
+ starts the register 0x42*/
+ com_rslt += smi130_set_mag_read_addr(
+ SMI130_BMM150_DATA_REG);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* enable mag interface to auto mode*/
+ com_rslt += smi130_set_mag_manual_enable(SMI130_MANUAL_DISABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_mag_manual_enable(&v_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+
+ return com_rslt;
+}
+ /*!
+ * @brief This function used for set the mag power control
+ * bit enable
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bmm150_mag_wakeup(void)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = SMI130_INIT_VALUE;
+ u8 v_try_times_u8 = SMI130_BMM150_MAX_RETRY_WAKEUP;
+ u8 v_power_control_bit_u8 = SMI130_INIT_VALUE;
+ u8 i = SMI130_INIT_VALUE;
+
+ for (i = SMI130_INIT_VALUE; i < v_try_times_u8; i++) {
+ com_rslt = smi130_set_mag_write_data(SMI130_BMM150_POWER_ON);
+ p_smi130->delay_msec(SMI130_BMM150_WAKEUP_DELAY1);
+ /*write 0x4B register to enable power control bit*/
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_POWE_CONTROL_REG);
+ p_smi130->delay_msec(SMI130_BMM150_WAKEUP_DELAY2);
+ com_rslt += smi130_set_mag_read_addr(
+ SMI130_BMM150_POWE_CONTROL_REG);
+ /* 0x04 is secondary read mag x lsb register */
+ p_smi130->delay_msec(SMI130_BMM150_WAKEUP_DELAY3);
+ com_rslt += smi130_read_reg(SMI130_USER_DATA_0_ADDR,
+ &v_power_control_bit_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_power_control_bit_u8 = SMI130_BMM150_SET_POWER_CONTROL
+ & v_power_control_bit_u8;
+ if (v_power_control_bit_u8 == SMI130_BMM150_POWER_ON)
+ break;
+ }
+ com_rslt = (i >= v_try_times_u8) ?
+ SMI130_BMM150_POWER_ON_FAIL : SMI130_BMM150_POWER_ON_SUCCESS;
+ return com_rslt;
+}
+ /*!
+ * @brief This function used for set the magnetometer
+ * power mode.
+ * @note
+ * Before set the mag power mode
+ * make sure the following two point is addressed
+ * Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ *
+ * @param v_mag_sec_if_pow_mode_u8 : The value of mag power mode
+ * value | mode
+ * ----------|------------
+ * 0 | SMI130_MAG_FORCE_MODE
+ * 1 | SMI130_MAG_SUSPEND_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_bmm150_mag_and_secondary_if_power_mode(
+u8 v_mag_sec_if_pow_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = SMI130_INIT_VALUE;
+ /* set the accel power mode to NORMAL*/
+ com_rslt = smi130_set_command_register(ACCEL_MODE_NORMAL);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_smi130->mag_manual_enable, __func__, __LINE__);
+ /* set mag interface manual mode*/
+ if (p_smi130->mag_manual_enable != SMI130_MANUAL_ENABLE) {
+ com_rslt += smi130_set_mag_manual_enable(
+ SMI130_MANUAL_ENABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ }
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_smi130->mag_manual_enable, __func__, __LINE__);
+
+ switch (v_mag_sec_if_pow_mode_u8) {
+ case SMI130_MAG_FORCE_MODE:
+ /* set the secondary mag power mode as NORMAL*/
+ com_rslt += smi130_set_mag_interface_normal();
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_smi130->mag_manual_enable, __func__, __LINE__);
+ /* set the mag power mode as FORCE mode*/
+ com_rslt += smi130_bmm150_mag_set_power_mode(FORCE_MODE);
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_smi130->mag_manual_enable, __func__, __LINE__);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ break;
+ case SMI130_MAG_SUSPEND_MODE:
+ /* set the mag power mode as SUSPEND mode*/
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_smi130->mag_manual_enable, __func__, __LINE__);
+ com_rslt += smi130_bmm150_mag_set_power_mode(SUSPEND_MODE);
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_smi130->mag_manual_enable, __func__, __LINE__);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* set the secondary mag power mode as SUSPEND*/
+ com_rslt += smi130_set_command_register(MAG_MODE_SUSPEND);
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_smi130->mag_manual_enable, __func__, __LINE__);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ if (p_smi130->mag_manual_enable == SMI130_MANUAL_ENABLE) {
+ /* set mag interface auto mode*/
+ com_rslt += smi130_set_mag_manual_enable(
+ SMI130_MANUAL_DISABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ }
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_smi130->mag_manual_enable, __func__, __LINE__);
+ return com_rslt;
+}
+/*!
+ * @brief This function used for set the magnetometer
+ * power mode.
+ * @note
+ * Before set the mag power mode
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ * @param v_mag_pow_mode_u8 : The value of mag power mode
+ * value | mode
+ * ----------|------------
+ * 0 | FORCE_MODE
+ * 1 | SUSPEND_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bmm150_mag_set_power_mode(
+u8 v_mag_pow_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = SMI130_INIT_VALUE;
+ u8 manual_enable_status = 0;
+ /* set mag interface manual mode*/
+ if (p_smi130->mag_manual_enable != SMI130_MANUAL_ENABLE) {
+ com_rslt = smi130_set_mag_manual_enable(
+ SMI130_MANUAL_ENABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_get_mag_manual_enable(&manual_enable_status);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ printk(KERN_INFO "1com_rslt:%d, manual:%d, manual_read:%d\n",
+ com_rslt, p_smi130->mag_manual_enable, manual_enable_status);
+ }
+ printk(KERN_INFO "2com_rslt:%d, manual:%d, manual_read:%d\n",
+ com_rslt, p_smi130->mag_manual_enable, manual_enable_status);
+
+ switch (v_mag_pow_mode_u8) {
+ case FORCE_MODE:
+ /* Set the power control bit enabled */
+ com_rslt = smi130_bmm150_mag_wakeup();
+ /* write the mag power mode as FORCE mode*/
+ com_rslt += smi130_set_mag_write_data(
+ SMI130_BMM150_FORCE_MODE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_POWE_MODE_REG);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* To avoid the auto mode enable when manual
+ mode operation running*/
+ V_bmm150_maual_auto_condition_u8_mbl = SMI130_MANUAL_ENABLE;
+ /* set the preset mode */
+ com_rslt += smi130_set_bmm150_mag_presetmode(
+ SMI130_MAG_PRESETMODE_REGULAR);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* To avoid the auto mode enable when manual
+ mode operation running*/
+ V_bmm150_maual_auto_condition_u8_mbl = SMI130_MANUAL_DISABLE;
+ /* set the mag read address to data registers*/
+ com_rslt += smi130_set_mag_read_addr(
+ SMI130_BMM150_DATA_REG);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ break;
+ case SUSPEND_MODE:
+ printk(KERN_INFO "3com_rslt:%d, manual:%d, read_manual:%d\n",
+ com_rslt, p_smi130->mag_manual_enable, manual_enable_status);
+ /* Set the power mode of mag as suspend mode*/
+ com_rslt += smi130_set_mag_write_data(
+ SMI130_BMM150_POWER_OFF);
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_smi130->mag_manual_enable, __func__, __LINE__);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_POWE_CONTROL_REG);
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_smi130->mag_manual_enable, __func__, __LINE__);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ printk(KERN_INFO "4com_rslt:%d, manual:%d, manual_read:%d\n",
+ com_rslt, p_smi130->mag_manual_enable, manual_enable_status);
+ /* set mag interface auto mode*/
+ if (p_smi130->mag_manual_enable == SMI130_MANUAL_ENABLE) {
+ com_rslt += smi130_set_mag_manual_enable(
+ SMI130_MANUAL_DISABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_get_mag_manual_enable(&manual_enable_status);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ }
+ printk(KERN_INFO "5com_rslt:%d, manual:%d, manual_read:%d\n",
+ com_rslt, p_smi130->mag_manual_enable, manual_enable_status);
+ return com_rslt;
+}
+/*!
+ * @brief This API used to set the pre-set modes of bmm150
+ * The pre-set mode setting is depend on data rate and xy and z repetitions
+ *
+ * @note
+ * Before set the mag preset mode
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ * @param v_mode_u8: The value of pre-set mode selection value
+ * value | pre_set mode
+ * ----------|------------
+ * 1 | SMI130_MAG_PRESETMODE_LOWPOWER
+ * 2 | SMI130_MAG_PRESETMODE_REGULAR
+ * 3 | SMI130_MAG_PRESETMODE_HIGHACCURACY
+ * 4 | SMI130_MAG_PRESETMODE_ENHANCED
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_bmm150_mag_presetmode(u8 v_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ switch (v_mode_u8) {
+ case SMI130_MAG_PRESETMODE_LOWPOWER:
+ /* write the XY and Z repetitions*/
+ /* The v_data_u8 have to write for the register
+ It write the value in the register 0x4F*/
+ com_rslt = smi130_set_mag_write_data(
+ SMI130_MAG_LOWPOWER_REPXY);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_XY_REP);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* write the Z repetitions*/
+ /* The v_data_u8 have to write for the register
+ It write the value in the register 0x4F*/
+ com_rslt += smi130_set_mag_write_data(
+ SMI130_MAG_LOWPOWER_REPZ);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_Z_REP);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* set the mag v_data_u8 rate as 10 to the register 0x4C*/
+ com_rslt += smi130_set_mag_write_data(
+ SMI130_MAG_LOWPOWER_DR);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_POWE_MODE_REG);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ break;
+ case SMI130_MAG_PRESETMODE_REGULAR:
+ /* write the XY and Z repetitions*/
+ /* The v_data_u8 have to write for the register
+ It write the value in the register 0x4F*/
+ com_rslt = smi130_set_mag_write_data(
+ SMI130_MAG_REGULAR_REPXY);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_XY_REP);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* write the Z repetitions*/
+ /* The v_data_u8 have to write for the register
+ It write the value in the register 0x4F*/
+ com_rslt += smi130_set_mag_write_data(
+ SMI130_MAG_REGULAR_REPZ);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_Z_REP);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* set the mag v_data_u8 rate as 10 to the register 0x4C*/
+ com_rslt += smi130_set_mag_write_data(
+ SMI130_MAG_REGULAR_DR);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_POWE_MODE_REG);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ break;
+ case SMI130_MAG_PRESETMODE_HIGHACCURACY:
+ /* write the XY and Z repetitions*/
+ /* The v_data_u8 have to write for the register
+ It write the value in the register 0x4F*/
+ com_rslt = smi130_set_mag_write_data(
+ SMI130_MAG_HIGHACCURACY_REPXY);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_XY_REP);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* write the Z repetitions*/
+ /* The v_data_u8 have to write for the register
+ It write the value in the register 0x4F*/
+ com_rslt += smi130_set_mag_write_data(
+ SMI130_MAG_HIGHACCURACY_REPZ);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_Z_REP);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* set the mag v_data_u8 rate as 20 to the register 0x4C*/
+ com_rslt += smi130_set_mag_write_data(
+ SMI130_MAG_HIGHACCURACY_DR);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_POWE_MODE_REG);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ break;
+ case SMI130_MAG_PRESETMODE_ENHANCED:
+ /* write the XY and Z repetitions*/
+ /* The v_data_u8 have to write for the register
+ It write the value in the register 0x4F*/
+ com_rslt = smi130_set_mag_write_data(
+ SMI130_MAG_ENHANCED_REPXY);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_XY_REP);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* write the Z repetitions*/
+ /* The v_data_u8 have to write for the register
+ It write the value in the register 0x4F*/
+ com_rslt += smi130_set_mag_write_data(
+ SMI130_MAG_ENHANCED_REPZ);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_Z_REP);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* set the mag v_data_u8 rate as 10 to the register 0x4C*/
+ com_rslt += smi130_set_mag_write_data(
+ SMI130_MAG_ENHANCED_DR);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_POWE_MODE_REG);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+
+ return com_rslt;
+}
+ /*!
+ * @brief This function used for read the trim values of magnetometer
+ *
+ * @note
+ * Before reading the mag trimming values
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_bmm150_mag_trim_mbl(void)
+{
+ /* This variable used for provide the communication
+ results*/
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array holding the bmm150 trim data
+ */
+ u8 v_data_u8[SMI130_MAG_TRIM_DATA_SIZE] = {
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE};
+ /* read dig_x1 value */
+ com_rslt = smi130_set_mag_read_addr(
+ SMI130_MAG_DIG_X1);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_X1],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ mag_trim_mbl.dig_x1 = v_data_u8[SMI130_BMM150_DIG_X1];
+ /* read dig_y1 value */
+ com_rslt += smi130_set_mag_read_addr(
+ SMI130_MAG_DIG_Y1);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_Y1],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ mag_trim_mbl.dig_y1 = v_data_u8[SMI130_BMM150_DIG_Y1];
+
+ /* read dig_x2 value */
+ com_rslt += smi130_set_mag_read_addr(
+ SMI130_MAG_DIG_X2);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_X2],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ mag_trim_mbl.dig_x2 = v_data_u8[SMI130_BMM150_DIG_X2];
+ /* read dig_y2 value */
+ com_rslt += smi130_set_mag_read_addr(
+ SMI130_MAG_DIG_Y2);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_Y3],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ mag_trim_mbl.dig_y2 = v_data_u8[SMI130_BMM150_DIG_Y3];
+
+ /* read dig_xy1 value */
+ com_rslt += smi130_set_mag_read_addr(
+ SMI130_MAG_DIG_XY1);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_XY1],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ mag_trim_mbl.dig_xy1 = v_data_u8[SMI130_BMM150_DIG_XY1];
+ /* read dig_xy2 value */
+ com_rslt += smi130_set_mag_read_addr(
+ SMI130_MAG_DIG_XY2);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is v_mag_x_s16 ls register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_XY2],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ mag_trim_mbl.dig_xy2 = v_data_u8[SMI130_BMM150_DIG_XY2];
+
+ /* read dig_z1 lsb value */
+ com_rslt += smi130_set_mag_read_addr(
+ SMI130_MAG_DIG_Z1_LSB);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_Z1_LSB],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* read dig_z1 msb value */
+ com_rslt += smi130_set_mag_read_addr(SMI130_MAG_DIG_Z1_MSB);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is v_mag_x_s16 msb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_Z1_MSB],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ mag_trim_mbl.dig_z1 =
+ (u16)((((u32)((u8)v_data_u8[SMI130_BMM150_DIG_Z1_MSB]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[SMI130_BMM150_DIG_Z1_LSB]));
+
+ /* read dig_z2 lsb value */
+ com_rslt += smi130_set_mag_read_addr(SMI130_MAG_DIG_Z2_LSB);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_Z2_LSB],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* read dig_z2 msb value */
+ com_rslt += smi130_set_mag_read_addr(SMI130_MAG_DIG_Z2_MSB);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is v_mag_x_s16 msb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_Z2_MSB],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ mag_trim_mbl.dig_z2 =
+ (s16)((((s32)((s8)v_data_u8[SMI130_BMM150_DIG_Z2_MSB]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[SMI130_BMM150_DIG_Z2_LSB]));
+
+ /* read dig_z3 lsb value */
+ com_rslt += smi130_set_mag_read_addr(SMI130_MAG_DIG_Z3_LSB);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_DIG_Z3_LSB],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* read dig_z3 msb value */
+ com_rslt += smi130_set_mag_read_addr(SMI130_MAG_DIG_Z3_MSB);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is v_mag_x_s16 msb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_DIG_Z3_MSB],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ mag_trim_mbl.dig_z3 =
+ (s16)((((s32)((s8)v_data_u8[SMI130_BMM150_DIG_DIG_Z3_MSB]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[SMI130_BMM150_DIG_DIG_Z3_LSB]));
+
+ /* read dig_z4 lsb value */
+ com_rslt += smi130_set_mag_read_addr(SMI130_MAG_DIG_Z4_LSB);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_DIG_Z4_LSB],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* read dig_z4 msb value */
+ com_rslt += smi130_set_mag_read_addr(SMI130_MAG_DIG_Z4_MSB);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is v_mag_x_s16 msb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_DIG_Z4_MSB],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ mag_trim_mbl.dig_z4 =
+ (s16)((((s32)((s8)v_data_u8[SMI130_BMM150_DIG_DIG_Z4_MSB]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[SMI130_BMM150_DIG_DIG_Z4_LSB]));
+
+ /* read dig_xyz1 lsb value */
+ com_rslt += smi130_set_mag_read_addr(SMI130_MAG_DIG_XYZ1_LSB);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_DIG_XYZ1_LSB],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* read dig_xyz1 msb value */
+ com_rslt += smi130_set_mag_read_addr(SMI130_MAG_DIG_XYZ1_MSB);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is v_mag_x_s16 msb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_DIG_XYZ1_MSB],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ mag_trim_mbl.dig_xyz1 =
+ (u16)((((u32)((u8)v_data_u8[SMI130_BMM150_DIG_DIG_XYZ1_MSB]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[SMI130_BMM150_DIG_DIG_XYZ1_LSB]));
+
+ return com_rslt;
+}
+ /*!
+ * @brief This function used for initialize
+ * the AKM09911 and AKM09912 sensor
+ *
+ *
+ * @param v_akm_i2c_address_u8: The value of device address
+ * AKM sensor | Slave address
+ * --------------|---------------------
+ * AKM09911 | AKM09911_I2C_ADDR_1
+ * - | and AKM09911_I2C_ADDR_2
+ * AKM09912 | AKM09912_I2C_ADDR_1
+ * - | AKM09912_I2C_ADDR_2
+ * - | AKM09912_I2C_ADDR_3
+ * - | AKM09912_I2C_ADDR_4
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_akm_mag_interface_init(
+u8 v_akm_i2c_address_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_pull_value_u8 = SMI130_INIT_VALUE;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ u8 v_akm_chip_id_u8 = SMI130_INIT_VALUE;
+ /* accel operation mode to normal*/
+ com_rslt = smi130_set_command_register(ACCEL_MODE_NORMAL);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_command_register(MAG_MODE_NORMAL);
+ p_smi130->delay_msec(SMI130_AKM_INIT_DELAY);
+ smi130_get_mag_power_mode_stat(&v_data_u8);
+ /* register 0x7E write the 0x37, 0x9A and 0x30*/
+ com_rslt += smi130_set_command_register(SMI130_COMMAND_REG_ONE);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_command_register(SMI130_COMMAND_REG_TWO);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_command_register(SMI130_COMMAND_REG_THREE);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /*switch the page1*/
+ com_rslt += smi130_set_target_page(SMI130_WRITE_TARGET_PAGE1);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_target_page(&v_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_paging_enable(SMI130_WRITE_ENABLE_PAGE1);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_paging_enable(&v_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* enable the pullup configuration from
+ the register 0x05 bit 4 and 5 to 10*/
+ smi130_get_pullup_configuration(&v_pull_value_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ v_pull_value_u8 = v_pull_value_u8 | SMI130_PULL_UP_DATA;
+ com_rslt += smi130_set_pullup_configuration(v_pull_value_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+
+ /*switch the page0*/
+ com_rslt += smi130_set_target_page(SMI130_WRITE_TARGET_PAGE0);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_target_page(&v_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* Write the AKM09911 0r AKM09912 i2c address*/
+ com_rslt += smi130_set_i2c_device_addr(v_akm_i2c_address_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* enable the mag interface to manual mode*/
+ com_rslt += smi130_set_mag_manual_enable(SMI130_MANUAL_ENABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_mag_manual_enable(&v_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /*Enable the MAG interface */
+ com_rslt += smi130_set_if_mode(SMI130_ENABLE_MAG_IF_MODE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_if_mode(&v_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+
+ /* Set the AKM Fuse ROM mode */
+ /* Set value for fuse ROM mode*/
+ com_rslt += smi130_set_mag_write_data(AKM_FUSE_ROM_MODE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* AKM mode address is 0x31*/
+ com_rslt += smi130_set_mag_write_addr(AKM_POWER_MODE_REG);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* Read the Fuse ROM v_data_u8 from registers
+ 0x60,0x61 and 0x62*/
+ /* ASAX v_data_u8 */
+ com_rslt += smi130_read_bosch_akm_sensitivity_data();
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* read the device id of the AKM sensor
+ if device id is 0x05 - AKM09911
+ if device id is 0x04 - AKM09912*/
+ com_rslt += smi130_set_mag_read_addr(AKM09912_CHIP_ID_REG);
+ /* 0x04 is mag_x lsb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_akm_chip_id_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ printk(KERN_INFO "smi130,addr:0x%x, akm_chip_id:0x%x",
+ v_akm_i2c_address_u8, v_akm_chip_id_u8);
+ /* Set value power down mode mode*/
+ com_rslt += smi130_set_mag_write_data(AKM_POWER_DOWN_MODE_DATA);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* AKM mode address is 0x31*/
+ com_rslt += smi130_set_mag_write_addr(AKM_POWER_MODE_REG);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* Set AKM Force mode*/
+ com_rslt += smi130_set_mag_write_data(
+ AKM_SINGLE_MEASUREMENT_MODE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* AKM mode address is 0x31*/
+ com_rslt += smi130_set_mag_write_addr(AKM_POWER_MODE_REG);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* Set the AKM read xyz v_data_u8 address*/
+ com_rslt += smi130_set_mag_read_addr(AKM_DATA_REGISTER);
+ /* write the mag v_data_bw_u8 as 25Hz*/
+ com_rslt += smi130_set_mag_output_data_rate(
+ SMI130_MAG_OUTPUT_DATA_RATE_25HZ);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* Enable mag interface to auto mode*/
+ com_rslt += smi130_set_mag_manual_enable(SMI130_MANUAL_DISABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_mag_manual_enable(&v_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+
+ return com_rslt;
+}
+ /*!
+ * @brief This function used for read the sensitivity data of
+ * AKM09911 and AKM09912
+ *
+ * @note Before reading the mag sensitivity values
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_bosch_akm_sensitivity_data(void)
+{
+ /* This variable used for provide the communication
+ results*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array holding the sensitivity ax,ay and az data*/
+ u8 v_data_u8[SMI130_AKM_SENSITIVITY_DATA_SIZE] = {
+ SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ /* read asax value */
+ com_rslt = smi130_set_mag_read_addr(SMI130_BST_AKM_ASAX);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[AKM_ASAX],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ akm_asa_data_mbl.asax = v_data_u8[AKM_ASAX];
+ /* read asay value */
+ com_rslt += smi130_set_mag_read_addr(SMI130_BST_AKM_ASAY);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[AKM_ASAY],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ akm_asa_data_mbl.asay = v_data_u8[AKM_ASAY];
+ /* read asaz value */
+ com_rslt += smi130_set_mag_read_addr(SMI130_BST_AKM_ASAZ);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[AKM_ASAZ],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ akm_asa_data_mbl.asaz = v_data_u8[AKM_ASAZ];
+
+ return com_rslt;
+}
+/*!
+ * @brief This API used to get the compensated X data
+ * of AKM09911 the out put of X as s32
+ * @note Before start reading the mag compensated X data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bosch_akm_x_s16 : The value of X data
+ *
+ * @return results of compensated X data value output as s32
+ *
+ */
+s32 smi130_bosch_akm09911_compensate_X(s16 v_bosch_akm_x_s16)
+{
+ /*Return value of AKM x compensated v_data_u8*/
+ s32 retval = SMI130_INIT_VALUE;
+ /* Convert raw v_data_u8 into compensated v_data_u8*/
+ retval = (v_bosch_akm_x_s16 *
+ ((akm_asa_data_mbl.asax/AKM09911_SENSITIVITY_DIV) +
+ SMI130_GEN_READ_WRITE_DATA_LENGTH));
+ return retval;
+}
+/*!
+ * @brief This API used to get the compensated Y data
+ * of AKM09911 the out put of Y as s32
+ * @note Before start reading the mag compensated Y data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bosch_akm_y_s16 : The value of Y data
+ *
+ * @return results of compensated Y data value output as s32
+ *
+ */
+s32 smi130_bosch_akm09911_compensate_Y(s16 v_bosch_akm_y_s16)
+{
+ /*Return value of AKM y compensated v_data_u8*/
+ s32 retval = SMI130_INIT_VALUE;
+ /* Convert raw v_data_u8 into compensated v_data_u8*/
+ retval = (v_bosch_akm_y_s16 *
+ ((akm_asa_data_mbl.asay/AKM09911_SENSITIVITY_DIV) +
+ SMI130_GEN_READ_WRITE_DATA_LENGTH));
+ return retval;
+}
+/*!
+ * @brief This API used to get the compensated Z data
+ * of AKM09911 the out put of Z as s32
+ * @note Before start reading the mag compensated Z data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bosch_akm_z_s16 : The value of Z data
+ *
+ * @return results of compensated Z data value output as s32
+ *
+ */
+s32 smi130_bosch_akm09911_compensate_Z(s16 v_bosch_akm_z_s16)
+{
+ /*Return value of AKM z compensated v_data_u8*/
+ s32 retval = SMI130_INIT_VALUE;
+ /* Convert raw v_data_u8 into compensated v_data_u8*/
+ retval = (v_bosch_akm_z_s16 *
+ ((akm_asa_data_mbl.asaz/AKM09911_SENSITIVITY_DIV) +
+ SMI130_GEN_READ_WRITE_DATA_LENGTH));
+ return retval;
+}
+/*!
+ * @brief This API used to get the compensated X data
+ * of AKM09912 the out put of X as s32
+ * @note Before start reading the mag compensated X data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bosch_akm_x_s16 : The value of X data
+ *
+ * @return results of compensated X data value output as s32
+ *
+ */
+s32 smi130_bosch_akm09912_compensate_X(s16 v_bosch_akm_x_s16)
+{
+ /*Return value of AKM x compensated data*/
+ s32 retval = SMI130_INIT_VALUE;
+ /* Convert raw data into compensated data*/
+ retval = v_bosch_akm_x_s16 *
+ (akm_asa_data_mbl.asax + AKM09912_SENSITIVITY)
+ / AKM09912_SENSITIVITY_DIV;
+ return retval;
+}
+/*!
+ * @brief This API used to get the compensated Y data
+ * of AKM09912 the out put of Y as s32
+ * @note Before start reading the mag compensated Y data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bosch_akm_y_s16 : The value of Y data
+ *
+ * @return results of compensated Y data value output as s32
+ *
+ */
+s32 smi130_bosch_akm09912_compensate_Y(s16 v_bosch_akm_y_s16)
+{
+ /*Return value of AKM y compensated data*/
+ s32 retval = SMI130_INIT_VALUE;
+ /* Convert raw data into compensated data*/
+ retval = v_bosch_akm_y_s16 *
+ (akm_asa_data_mbl.asax + AKM09912_SENSITIVITY)
+ / AKM09912_SENSITIVITY_DIV;
+ return retval;
+}
+/*!
+ * @brief This API used to get the compensated Z data
+ * of AKM09912 the out put of Z as s32
+ * @note Before start reading the mag compensated Z data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bosch_akm_z_s16 : The value of Z data
+ *
+ * @return results of compensated Z data value output as s32
+ *
+ */
+s32 smi130_bosch_akm09912_compensate_Z(s16 v_bosch_akm_z_s16)
+{
+ /*Return value of AKM z compensated data*/
+ s32 retval = SMI130_INIT_VALUE;
+ /* Convert raw data into compensated data*/
+ retval = v_bosch_akm_z_s16 *
+ (akm_asa_data_mbl.asax + AKM09912_SENSITIVITY)
+ / AKM09912_SENSITIVITY_DIV;
+ return retval;
+}
+ /*!
+ * @brief This function used for read the compensated value of
+ * AKM09911
+ * @note Before start reading the mag compensated data's
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_akm09911_compensate_xyz(
+struct smi130_mag_xyz_s32_t *bosch_akm_xyz)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ struct smi130_mag_t mag_xyz;
+
+ com_rslt = smi130_read_mag_xyz(&mag_xyz, BST_AKM);
+ /* Compensation for X axis */
+ bosch_akm_xyz->x = smi130_bosch_akm09911_compensate_X(mag_xyz.x);
+
+ /* Compensation for Y axis */
+ bosch_akm_xyz->y = smi130_bosch_akm09911_compensate_Y(mag_xyz.y);
+
+ /* Compensation for Z axis */
+ bosch_akm_xyz->z = smi130_bosch_akm09911_compensate_Z(mag_xyz.z);
+
+ return com_rslt;
+}
+ /*!
+ * @brief This function used for read the compensated value of
+ * AKM09912
+ * @note Before start reading the mag compensated data's
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_akm09912_compensate_xyz(
+struct smi130_mag_xyz_s32_t *bosch_akm_xyz)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ struct smi130_mag_t mag_xyz;
+
+ com_rslt = smi130_read_mag_xyz(&mag_xyz, BST_AKM);
+ printk(KERN_INFO "akm09912_raw_x:%d, %d, %d, <%s>,<%d>",
+ mag_xyz.x, mag_xyz.y, mag_xyz.z, __func__, __LINE__);
+ /* Compensation for X axis */
+ bosch_akm_xyz->x = smi130_bosch_akm09912_compensate_X(mag_xyz.x);
+
+ /* Compensation for Y axis */
+ bosch_akm_xyz->y = smi130_bosch_akm09912_compensate_Y(mag_xyz.y);
+
+ /* Compensation for Z axis */
+ bosch_akm_xyz->z = smi130_bosch_akm09912_compensate_Z(mag_xyz.z);
+ return com_rslt;
+}
+ /*!
+ * @brief This function used for read the compensated value of
+ * AKM09912
+ * @note Before start reading the mag compensated data's
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_akm09912_compensate_xyz_raw(
+struct smi130_mag_xyz_s32_t *bosch_akm_xyz)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Compensation for X axis */
+ bosch_akm_xyz->x = smi130_bosch_akm09912_compensate_X(bosch_akm_xyz->x);
+
+ /* Compensation for Y axis */
+ bosch_akm_xyz->y = smi130_bosch_akm09912_compensate_Y(bosch_akm_xyz->y);
+
+ /* Compensation for Z axis */
+ bosch_akm_xyz->z = smi130_bosch_akm09912_compensate_Z(bosch_akm_xyz->z);
+
+ return com_rslt;
+}
+/*!
+ * @brief This function used for set the AKM09911 and AKM09912
+ * power mode.
+ * @note Before set the AKM power mode
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ * @param v_akm_pow_mode_u8 : The value of akm power mode
+ * value | Description
+ * ---------|--------------------
+ * 0 | AKM_POWER_DOWN_MODE
+ * 1 | AKM_SINGLE_MEAS_MODE
+ * 2 | FUSE_ROM_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_akm_set_powermode(
+u8 v_akm_pow_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = SMI130_INIT_VALUE;
+ /* set mag interface manual mode*/
+ if (p_smi130->mag_manual_enable != SMI130_MANUAL_ENABLE) {
+ com_rslt = smi130_set_mag_manual_enable(
+ SMI130_MANUAL_ENABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ }
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s>\n",
+ com_rslt, p_smi130->mag_manual_enable, __func__);
+ switch (v_akm_pow_mode_u8) {
+ case AKM_POWER_DOWN_MODE:
+ /* Set the power mode of AKM as power down mode*/
+ com_rslt += smi130_set_mag_write_data(AKM_POWER_DOWN_MODE_DATA);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(AKM_POWER_MODE_REG);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ break;
+ case AKM_SINGLE_MEAS_MODE:
+ /* Set the power mode of AKM as
+ single measurement mode*/
+ com_rslt += smi130_set_mag_write_data
+ (AKM_SINGLE_MEASUREMENT_MODE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(AKM_POWER_MODE_REG);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_read_addr(AKM_DATA_REGISTER);
+ break;
+ case FUSE_ROM_MODE:
+ /* Set the power mode of AKM as
+ Fuse ROM mode*/
+ com_rslt += smi130_set_mag_write_data(AKM_FUSE_ROM_MODE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(AKM_POWER_MODE_REG);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* Sensitivity v_data_u8 */
+ com_rslt += smi130_read_bosch_akm_sensitivity_data();
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* power down mode*/
+ com_rslt += smi130_set_mag_write_data(AKM_POWER_DOWN_MODE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(AKM_POWER_MODE_REG);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ /* set mag interface auto mode*/
+ if (p_smi130->mag_manual_enable == SMI130_MANUAL_ENABLE) {
+ com_rslt += smi130_set_mag_manual_enable(
+ SMI130_MANUAL_DISABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ }
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_smi130->mag_manual_enable, __func__, __LINE__);
+ return com_rslt;
+}
+ /*!
+ * @brief This function used for set the magnetometer
+ * power mode of AKM09911 and AKM09912
+ * @note Before set the mag power mode
+ * make sure the following two point is addressed
+ * Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ *
+ * @param v_mag_sec_if_pow_mode_u8 : The value of secondary if power mode
+ * value | Description
+ * ---------|--------------------
+ * 0 | SMI130_MAG_FORCE_MODE
+ * 1 | SMI130_MAG_SUSPEND_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_bosch_akm_and_secondary_if_powermode(
+u8 v_mag_sec_if_pow_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* accel operation mode to normal*/
+ com_rslt = smi130_set_command_register(ACCEL_MODE_NORMAL);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* set mag interface manual mode*/
+ if (p_smi130->mag_manual_enable != SMI130_MANUAL_ENABLE) {
+ com_rslt = smi130_set_mag_manual_enable(
+ SMI130_MANUAL_ENABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ }
+ printk(KERN_ERR "com_rslt:%d, manual:%d,after setacc normal mode\n",
+ com_rslt, p_smi130->mag_manual_enable);
+ switch (v_mag_sec_if_pow_mode_u8) {
+ case SMI130_MAG_FORCE_MODE:
+ /* set the secondary mag power mode as NORMAL*/
+ com_rslt += smi130_set_mag_interface_normal();
+ /* set the akm power mode as single measurement mode*/
+ com_rslt += smi130_bosch_akm_set_powermode(AKM_SINGLE_MEAS_MODE);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_read_addr(AKM_DATA_REGISTER);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ break;
+ case SMI130_MAG_SUSPEND_MODE:
+ /* set the akm power mode as power down mode*/
+ com_rslt += smi130_bosch_akm_set_powermode(AKM_POWER_DOWN_MODE);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* set the secondary mag power mode as SUSPEND*/
+ com_rslt += smi130_set_command_register(MAG_MODE_SUSPEND);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ /* set mag interface auto mode*/
+ if (p_smi130->mag_manual_enable == SMI130_MANUAL_ENABLE)
+ com_rslt += smi130_set_mag_manual_enable(
+ SMI130_MANUAL_DISABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ return com_rslt;
+}
+/*!
+ * @brief This function used for read the YAMAH-YAS532 init
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yamaha_yas532_mag_interface_init(
+void)
+{
+ /* This variable used for provide the communication
+ results*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_pull_value_u8 = SMI130_INIT_VALUE;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ u8 i = SMI130_INIT_VALUE;
+ /* accel operation mode to normal*/
+ com_rslt = smi130_set_command_register(ACCEL_MODE_NORMAL);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* write mag power mode as NORMAL*/
+ com_rslt += smi130_set_mag_interface_normal();
+ /* register 0x7E write the 0x37, 0x9A and 0x30*/
+ com_rslt += smi130_set_command_register(SMI130_COMMAND_REG_ONE);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_command_register(SMI130_COMMAND_REG_TWO);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_command_register(SMI130_COMMAND_REG_THREE);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /*switch the page1*/
+ com_rslt += smi130_set_target_page(SMI130_WRITE_TARGET_PAGE1);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_target_page(&v_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_paging_enable(SMI130_WRITE_ENABLE_PAGE1);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_paging_enable(&v_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* enable the pullup configuration from
+ the register 0x05 bit 4 and 5 as 10*/
+ smi130_get_pullup_configuration(&v_pull_value_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ v_pull_value_u8 = v_pull_value_u8 | SMI130_PULL_UP_DATA;
+ com_rslt += smi130_set_pullup_configuration(v_pull_value_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /*switch the page0*/
+ com_rslt += smi130_set_target_page(SMI130_WRITE_TARGET_PAGE0);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_target_page(&v_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* Write the YAS532 i2c address*/
+ com_rslt += smi130_set_i2c_device_addr(SMI130_AUX_YAS532_I2C_ADDRESS);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* enable the mag interface to manual mode*/
+ com_rslt += smi130_set_mag_manual_enable(SMI130_MANUAL_ENABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_mag_manual_enable(&v_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /*Enable the MAG interface */
+ com_rslt += smi130_set_if_mode(SMI130_ENABLE_MAG_IF_MODE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_if_mode(&v_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ v_data_u8 = SMI130_MANUAL_DISABLE;
+ /* Read the YAS532 device id is 0x02*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_YAS_DEVICE_ID_REG);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* Read the YAS532 calibration data*/
+ com_rslt += smi130_bosch_yamaha_yas532_calib_values();
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* Assign the data acquisition mode*/
+ yas532_data_mbl.measure_state = YAS532_MAG_STATE_INIT_COIL;
+ /* Set the default offset as invalid offset*/
+ set_vector(yas532_data_mbl.v_hard_offset_s8, INVALID_OFFSET);
+ /* set the transform to zero */
+ yas532_data_mbl.transform = SMI130_NULL;
+ /* Assign overflow as zero*/
+ yas532_data_mbl.overflow = 0;
+ #if YAS532_MAG_LOG < YAS532_MAG_TEMPERATURE_LOG
+ yas532_data_mbl.temp_data.num =
+ yas532_data_mbl.temp_data.idx = 0;
+ #endif
+ /* Assign the coef value*/
+ for (i = 0; i < 3; i++) {
+ yas532_data_mbl.coef[i] = yas532_version_ac_coef[i];
+ yas532_data_mbl.last_raw[i] = 0;
+ }
+ yas532_data_mbl.last_raw[3] = 0;
+ /* Set the initial values of yas532*/
+ com_rslt += smi130_bosch_yas532_set_initial_values();
+ /* write the mag v_data_bw_u8 as 25Hz*/
+ com_rslt += smi130_set_mag_output_data_rate(
+ SMI130_MAG_OUTPUT_DATA_RATE_25HZ);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* Enable mag interface to auto mode*/
+ com_rslt += smi130_set_mag_manual_enable(
+ SMI130_MANUAL_DISABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_mag_manual_enable(&v_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+
+ return com_rslt;
+}
+/*!
+ * @brief This function used to set the YAS532 initial values
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas532_set_initial_values(void)
+{
+/* This variable used for provide the communication
+ results*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* write testr1 as 0x00*/
+ com_rslt = smi130_set_mag_write_data(
+ SMI130_YAS532_WRITE_TESTR1);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(SMI130_YAS532_TESTR1);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* write testr2 as 0x00*/
+ com_rslt += smi130_set_mag_write_data(
+ SMI130_YAS532_WRITE_TESTR2);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(SMI130_YAS532_TESTR2);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* write Rcoil as 0x00*/
+ com_rslt += smi130_set_mag_write_data(
+ SMI130_YAS532_WRITE_RCOIL);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(SMI130_YAS532_RCOIL);
+ p_smi130->delay_msec(SMI130_YAS532_SET_INITIAL_VALUE_DELAY);
+ /* check the valid offset*/
+ if (is_valid_offset(yas532_data_mbl.v_hard_offset_s8)) {
+ com_rslt += smi130_bosch_yas532_set_offset(
+ yas532_data_mbl.v_hard_offset_s8);
+ yas532_data_mbl.measure_state = YAS532_MAG_STATE_NORMAL;
+ } else {
+ /* set the default offset as invalid offset*/
+ set_vector(yas532_data_mbl.v_hard_offset_s8, INVALID_OFFSET);
+ /*Set the default measure state for offset correction*/
+ yas532_data_mbl.measure_state = YAS532_MAG_STATE_MEASURE_OFFSET;
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This function used for YAS532 offset correction
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas532_magnetic_measure_set_offset(
+void)
+{
+ /* This variable used for provide the communication
+ results*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* used for offset value set to the offset register*/
+ s8 v_hard_offset_s8[SMI130_HARD_OFFSET_DATA_SIZE] = {
+ SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ /* offset correction factors*/
+ static const u8 v_correct_u8[SMI130_YAS_CORRECT_DATA_SIZE] = {
+ 16, 8, 4, 2, 1};
+ /* used for the temperature */
+ u16 v_temp_u16 = SMI130_INIT_VALUE;
+ /* used for the xy1y2 read*/
+ u16 v_xy1y2_u16[SMI130_YAS_XY1Y2_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ /* local flag for assign the values*/
+ s32 v_flag_s32[SMI130_YAS_FLAG_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ u8 i, j, v_busy_u8, v_overflow_u8 = SMI130_INIT_VALUE;
+
+ for (i = 0; i < 5; i++) {
+ /* set the offset values*/
+ com_rslt = smi130_bosch_yas532_set_offset(v_hard_offset_s8);
+ /* read the sensor data*/
+ com_rslt += smi130_bosch_yas532_normal_measurement_data(
+ SMI130_YAS532_ACQ_START, &v_busy_u8, &v_temp_u16,
+ v_xy1y2_u16, &v_overflow_u8);
+ /* check the sensor busy status*/
+ if (v_busy_u8)
+ return E_SMI130_BUSY;
+ /* calculate the magnetic correction with
+ offset and assign the values
+ to the offset register */
+ for (j = 0; j < 3; j++) {
+ if (YAS532_DATA_CENTER == v_xy1y2_u16[j])
+ v_flag_s32[j] = 0;
+ if (YAS532_DATA_CENTER < v_xy1y2_u16[j])
+ v_flag_s32[j] = 1;
+ if (v_xy1y2_u16[j] < YAS532_DATA_CENTER)
+ v_flag_s32[j] = -1;
+ }
+ for (j = 0; j < 3; j++) {
+ if (v_flag_s32[j])
+ v_hard_offset_s8[j] = (s8)(v_hard_offset_s8[j]
+ + v_flag_s32[j] * v_correct_u8[i]);
+ }
+ }
+ /* set the offset */
+ com_rslt += smi130_bosch_yas532_set_offset(v_hard_offset_s8);
+ return com_rslt;
+}
+/*!
+ * @brief This function used for read the
+ * YAMAHA YAS532 calibration data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yamaha_yas532_calib_values(void)
+{
+ /* This variable used for provide the communication
+ results*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array holding the YAS532 calibration values */
+ u8 v_data_u8[SMI130_YAS532_CALIB_DATA_SIZE] = {
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ /* Read the DX value */
+ com_rslt = smi130_set_mag_read_addr(SMI130_YAS532_CALIB_CX);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[0], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ yas532_data_mbl.calib_yas532.cx = (s32)((v_data_u8[0]
+ * 10) - 1280);
+ /* Read the DY1 value */
+ com_rslt += smi130_set_mag_read_addr(SMI130_YAS532_CALIB_CY1);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[1], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ yas532_data_mbl.calib_yas532.cy1 =
+ (s32)((v_data_u8[1] * 10) - 1280);
+ /* Read the DY2 value */
+ com_rslt += smi130_set_mag_read_addr(SMI130_YAS532_CALIB_CY2);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[2], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ yas532_data_mbl.calib_yas532.cy2 =
+ (s32)((v_data_u8[2] * 10) - 1280);
+ /* Read the D2 and D3 value */
+ com_rslt += smi130_set_mag_read_addr(SMI130_YAS532_CALIB1);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[3], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ yas532_data_mbl.calib_yas532.a2 =
+ (s32)(((v_data_u8[3] >>
+ SMI130_SHIFT_BIT_POSITION_BY_02_BITS)
+ & 0x03F) - 32);
+ /* Read the D3 and D4 value */
+ com_rslt += smi130_set_mag_read_addr(SMI130_YAS532_CALIB2);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[4], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ /* calculate a3*/
+ yas532_data_mbl.calib_yas532.a3 = (s32)((((v_data_u8[3] <<
+ SMI130_SHIFT_BIT_POSITION_BY_02_BITS) & 0x0C) |
+ ((v_data_u8[4]
+ >> SMI130_SHIFT_BIT_POSITION_BY_06_BITS)
+ & 0x03)) - 8);
+ /* calculate a4*/
+ yas532_data_mbl.calib_yas532.a4 = (s32)((v_data_u8[4]
+ & 0x3F) - 32);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* Read the D5 and D6 value */
+ com_rslt += smi130_set_mag_read_addr(SMI130_YAS532_CALIB3);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[5], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ /* calculate a5*/
+ yas532_data_mbl.calib_yas532.a5 =
+ (s32)(((v_data_u8[5]
+ >> SMI130_SHIFT_BIT_POSITION_BY_02_BITS)
+ & 0x3F) + 38);
+ /* Read the D6 and D7 value */
+ com_rslt += smi130_set_mag_read_addr(SMI130_YAS532_CALIB4);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[6], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ /* calculate a6*/
+ yas532_data_mbl.calib_yas532.a6 =
+ (s32)((((v_data_u8[5]
+ << SMI130_SHIFT_BIT_POSITION_BY_04_BITS)
+ & 0x30) | ((v_data_u8[6] >>
+ SMI130_SHIFT_BIT_POSITION_BY_04_BITS)
+ & 0x0F)) - 32);
+ /* Read the D7 and D8 value */
+ com_rslt += smi130_set_mag_read_addr(SMI130_YAS532_CALIB5);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[7], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ /* calculate a7*/
+ yas532_data_mbl.calib_yas532.a7 = (s32)((((v_data_u8[6]
+ << SMI130_SHIFT_BIT_POSITION_BY_03_BITS)
+ & 0x78) |
+ ((v_data_u8[7]
+ >> SMI130_SHIFT_BIT_POSITION_BY_05_BITS) &
+ 0x07)) - 64);
+ /* Read the D8 and D9 value */
+ com_rslt += smi130_set_mag_read_addr(SMI130_YAS532_CLAIB6);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[8], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ /* calculate a8*/
+ yas532_data_mbl.calib_yas532.a8 = (s32)((((v_data_u8[7] <<
+ SMI130_GEN_READ_WRITE_DATA_LENGTH) & 0x3E) |
+ ((v_data_u8[8] >>
+ SMI130_SHIFT_BIT_POSITION_BY_07_BITS) & 0x01)) -
+ 32);
+
+ /* Read the D8 and D9 value */
+ com_rslt += smi130_set_mag_read_addr(SMI130_YAS532_CALIB7);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[9], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ /* calculate a9*/
+ yas532_data_mbl.calib_yas532.a9 = (s32)(((v_data_u8[8] <<
+ SMI130_GEN_READ_WRITE_DATA_LENGTH) & 0xFE) |
+ ((v_data_u8[9] >>
+ SMI130_SHIFT_BIT_POSITION_BY_07_BITS) & 0x01));
+ /* calculate k*/
+ yas532_data_mbl.calib_yas532.k = (s32)((v_data_u8[9] >>
+ SMI130_SHIFT_BIT_POSITION_BY_02_BITS) & 0x1F);
+ /* Read the value from register 0x9A*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_YAS532_CALIB8);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[10],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ /* Read the value from register 0x9B*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_YAS532_CALIIB9);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[11],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ /* Read the value from register 0x9C*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_YAS532_CALIB10);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[12],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ /* Read the value from register 0x9D*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_YAS532_CALIB11);
+ /* 0x04 is secondary read mag x lsb register */
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[13],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ /* Calculate the fxy1y2 and rxy1y1*/
+ yas532_data_mbl.calib_yas532.fxy1y2[0] =
+ (u8)(((v_data_u8[10]
+ & 0x01)
+ << SMI130_SHIFT_BIT_POSITION_BY_01_BIT)
+ | ((v_data_u8[11] >>
+ SMI130_SHIFT_BIT_POSITION_BY_07_BITS) & 0x01));
+ yas532_data_mbl.calib_yas532.rxy1y2[0] =
+ ((s8)(((v_data_u8[10]
+ >> SMI130_SHIFT_BIT_POSITION_BY_01_BIT) & 0x3F)
+ << SMI130_SHIFT_BIT_POSITION_BY_02_BITS))
+ >> SMI130_SHIFT_BIT_POSITION_BY_02_BITS;
+ yas532_data_mbl.calib_yas532.fxy1y2[1] =
+ (u8)(((v_data_u8[11] & 0x01)
+ << SMI130_SHIFT_BIT_POSITION_BY_01_BIT)
+ | ((v_data_u8[12] >>
+ SMI130_SHIFT_BIT_POSITION_BY_07_BITS) & 0x01));
+ yas532_data_mbl.calib_yas532.rxy1y2[1] =
+ ((s8)(((v_data_u8[11]
+ >> SMI130_SHIFT_BIT_POSITION_BY_01_BIT) & 0x3F)
+ << SMI130_SHIFT_BIT_POSITION_BY_02_BITS))
+ >> SMI130_SHIFT_BIT_POSITION_BY_02_BITS;
+ yas532_data_mbl.calib_yas532.fxy1y2[2] =
+ (u8)(((v_data_u8[12] & 0x01)
+ << SMI130_SHIFT_BIT_POSITION_BY_01_BIT)
+ | ((v_data_u8[13]
+ >> SMI130_SHIFT_BIT_POSITION_BY_07_BITS) & 0x01));
+ yas532_data_mbl.calib_yas532.rxy1y2[2] =
+ ((s8)(((v_data_u8[12]
+ >> SMI130_SHIFT_BIT_POSITION_BY_01_BIT) & 0x3F)
+ << SMI130_SHIFT_BIT_POSITION_BY_02_BITS))
+ >> SMI130_SHIFT_BIT_POSITION_BY_02_BITS;
+
+ return com_rslt;
+}
+/*!
+ * @brief This function used for calculate the
+ * YAS532 read the linear data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas532_xy1y2_to_linear(
+u16 *v_xy1y2_u16, s32 *xy1y2_linear)
+{
+ /* This variable used for provide the communication
+ results*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = SUCCESS;
+ static const u16 v_calib_data[] = {
+ 3721, 3971, 4221, 4471};
+ u8 i = SMI130_INIT_VALUE;
+
+ for (i = 0; i < 3; i++)
+ xy1y2_linear[i] = v_xy1y2_u16[i] -
+ v_calib_data[yas532_data_mbl.calib_yas532.fxy1y2[i]]
+ + (yas532_data_mbl.v_hard_offset_s8[i] -
+ yas532_data_mbl.calib_yas532.rxy1y2[i])
+ * yas532_data_mbl.coef[i];
+ return com_rslt;
+}
+/*!
+ * @brief This function used for read the YAS532 sensor data
+ * @param v_acquisition_command_u8: used to set the data acquisition
+ * acquisition_command | operation
+ * ---------------------|-------------------------
+ * 0x17 | turn on the acquisition coil
+ * - | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Deferred acquisition mode
+ * 0x07 | turn on the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Normal acquisition mode
+ * 0x11 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Deferred acquisition mode
+ * 0x01 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Normal acquisition mode
+ *
+ * @param v_busy_u8 : used to get the busy flay for sensor data read
+ * @param v_temp_u16 : used to get the temperature data
+ * @param v_xy1y2_u16 : used to get the sensor xy1y2 data
+ * @param v_overflow_u8 : used to get the overflow data
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas532_normal_measurement_data(
+u8 v_acquisition_command_u8, u8 *v_busy_u8,
+u16 *v_temp_u16, u16 *v_xy1y2_u16, u8 *v_overflow_u8)
+{
+ /* This variable used for provide the communication
+ results*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = SMI130_INIT_VALUE;
+ /* Array holding the YAS532 xyy1 data*/
+ u8 v_data_u8[SMI130_YAS_XY1Y2T_DATA_SIZE] = {
+ SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ u8 i = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the sensor data */
+ com_rslt = smi130_bosch_yas532_acquisition_command_register(
+ v_acquisition_command_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_DATA_MAG_X_LSB__REG,
+ v_data_u8, SMI130_MAG_YAS_DATA_LENGTH);
+ /* read the xyy1 data*/
+ *v_busy_u8 =
+ ((v_data_u8[0]
+ >> SMI130_SHIFT_BIT_POSITION_BY_07_BITS) & 0x01);
+ *v_temp_u16 =
+ (u16)((((s32)v_data_u8[0]
+ << SMI130_SHIFT_BIT_POSITION_BY_03_BITS)
+ & 0x3F8) | ((v_data_u8[1]
+ >> SMI130_SHIFT_BIT_POSITION_BY_05_BITS) & 0x07));
+ v_xy1y2_u16[0] =
+ (u16)((((s32)v_data_u8[2]
+ << SMI130_SHIFT_BIT_POSITION_BY_06_BITS) & 0x1FC0)
+ | ((v_data_u8[3] >>
+ SMI130_SHIFT_BIT_POSITION_BY_02_BITS) & 0x3F));
+ v_xy1y2_u16[1] =
+ (u16)((((s32)v_data_u8[4]
+ << SMI130_SHIFT_BIT_POSITION_BY_06_BITS)
+ & 0x1FC0)
+ | ((v_data_u8[5]
+ >> SMI130_SHIFT_BIT_POSITION_BY_02_BITS) & 0x3F));
+ v_xy1y2_u16[2] =
+ (u16)((((s32)v_data_u8[6]
+ << SMI130_SHIFT_BIT_POSITION_BY_06_BITS)
+ & 0x1FC0)
+ | ((v_data_u8[7]
+ >> SMI130_SHIFT_BIT_POSITION_BY_02_BITS) & 0x3F));
+ *v_overflow_u8 = 0;
+ for (i = 0; i < 3; i++) {
+ if (v_xy1y2_u16[i] == YAS532_DATA_OVERFLOW)
+ *v_overflow_u8 |= (1 << (i * 2));
+ if (v_xy1y2_u16[i] == YAS532_DATA_UNDERFLOW)
+ *v_overflow_u8 |= (1 << (i * 2 + 1));
+ }
+ }
+ return com_rslt;
+}
+/*!
+ * @brief This function used for YAS532 sensor data
+ * @param v_acquisition_command_u8 : the value of CMDR
+ * acquisition_command | operation
+ * ---------------------|-------------------------
+ * 0x17 | turn on the acquisition coil
+ * - | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Deferred acquisition mode
+ * 0x07 | turn on the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Normal acquisition mode
+ * 0x11 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Deferred acquisition mode
+ * 0x01 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Normal acquisition mode
+ *
+ * @param xyz_data : the vector xyz output
+ * @param v_overflow_s8 : the value of overflow
+ * @param v_temp_correction_u8 : the value of temperate correction enable
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas532_measurement_xyz_data(
+struct yas532_vector *xyz_data, u8 *v_overflow_s8, u8 v_temp_correction_u8,
+u8 v_acquisition_command_u8)
+{
+ /* This variable used for provide the communication
+ results*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = SMI130_INIT_VALUE;
+ /* Array holding the linear calculation output*/
+ s32 v_xy1y2_linear_s32[SMI130_YAS_XY1Y2_DATA_SIZE] = {
+ SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ /* Array holding the temperature data */
+ s32 v_xyz_tmp_s32[SMI130_YAS_TEMP_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ s32 tmp = SMI130_INIT_VALUE;
+ s32 sx, sy1, sy2, sy, sz = SMI130_INIT_VALUE;
+ u8 i, v_busy_u8 = SMI130_INIT_VALUE;
+ u16 v_temp_u16 = SMI130_INIT_VALUE;
+ /* Array holding the xyy1 sensor raw data*/
+ u16 v_xy1y2_u16[SMI130_YAS_XY1Y2_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ #if YAS532_MAG_LOG < YAS532_MAG_TEMPERATURE_LOG
+ s32 sum = SMI130_INIT_VALUE;
+ #endif
+ *v_overflow_s8 = SMI130_INIT_VALUE;
+ switch (yas532_data_mbl.measure_state) {
+ case YAS532_MAG_STATE_INIT_COIL:
+ if (p_smi130->mag_manual_enable != SMI130_MANUAL_ENABLE)
+ com_rslt = smi130_set_mag_manual_enable(
+ SMI130_MANUAL_ENABLE);
+ /* write Rcoil*/
+ com_rslt += smi130_set_mag_write_data(
+ SMI130_YAS_DISABLE_RCOIL);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(SMI130_YAS532_RCOIL);
+ p_smi130->delay_msec(SMI130_YAS532_MEASUREMENT_DELAY);
+ if (!yas532_data_mbl.overflow && is_valid_offset(
+ yas532_data_mbl.v_hard_offset_s8))
+ yas532_data_mbl.measure_state = 0;
+ break;
+ case YAS532_MAG_STATE_MEASURE_OFFSET:
+ com_rslt = smi130_bosch_yas532_magnetic_measure_set_offset();
+ yas532_data_mbl.measure_state = 0;
+ break;
+ default:
+ break;
+ }
+ /* Read sensor data*/
+ com_rslt += smi130_bosch_yas532_normal_measurement_data(
+ v_acquisition_command_u8, &v_busy_u8, &v_temp_u16,
+ v_xy1y2_u16, v_overflow_s8);
+ /* Calculate the linear data*/
+ com_rslt += smi130_bosch_yas532_xy1y2_to_linear(v_xy1y2_u16,
+ v_xy1y2_linear_s32);
+ /* Calculate temperature correction */
+ #if YAS532_MAG_LOG < YAS532_MAG_TEMPERATURE_LOG
+ yas532_data_mbl.temp_data.log[yas532_data_mbl.temp_data.idx++] =
+ v_temp_u16;
+ if (YAS532_MAG_TEMPERATURE_LOG <= yas532_data_mbl.temp_data.idx)
+ yas532_data_mbl.temp_data.idx = 0;
+ yas532_data_mbl.temp_data.num++;
+ if (YAS532_MAG_TEMPERATURE_LOG <= yas532_data_mbl.temp_data.num)
+ yas532_data_mbl.temp_data.num = YAS532_MAG_TEMPERATURE_LOG;
+ for (i = 0; i < yas532_data_mbl.temp_data.num; i++)
+ sum += yas532_data_mbl.temp_data.log[i];
+ tmp = sum * 10 / yas532_data_mbl.temp_data.num
+ - YAS532_TEMP20DEGREE_TYPICAL * 10;
+ #else
+ tmp = (v_temp_u16 - YAS532_TEMP20DEGREE_TYPICAL)
+ * 10;
+ #endif
+ sx = v_xy1y2_linear_s32[0];
+ sy1 = v_xy1y2_linear_s32[1];
+ sy2 = v_xy1y2_linear_s32[2];
+ /* Temperature correction */
+ if (v_temp_correction_u8) {
+ sx -= (yas532_data_mbl.calib_yas532.cx * tmp)
+ / 1000;
+ sy1 -= (yas532_data_mbl.calib_yas532.cy1 * tmp)
+ / 1000;
+ sy2 -= (yas532_data_mbl.calib_yas532.cy2 * tmp)
+ / 1000;
+ }
+ sy = sy1 - sy2;
+ sz = -sy1 - sy2;
+
+ xyz_data->yas532_vector_xyz[0] = yas532_data_mbl.calib_yas532.k *
+ ((100 * sx + yas532_data_mbl.calib_yas532.a2 * sy +
+ yas532_data_mbl.calib_yas532.a3 * sz) / 10);
+ xyz_data->yas532_vector_xyz[1] = yas532_data_mbl.calib_yas532.k *
+ ((yas532_data_mbl.calib_yas532.a4 * sx + yas532_data_mbl.calib_yas532.a5 * sy +
+ yas532_data_mbl.calib_yas532.a6 * sz) / 10);
+ xyz_data->yas532_vector_xyz[2] = yas532_data_mbl.calib_yas532.k *
+ ((yas532_data_mbl.calib_yas532.a7 * sx + yas532_data_mbl.calib_yas532.a8 * sy +
+ yas532_data_mbl.calib_yas532.a9 * sz) / 10);
+ if (yas532_data_mbl.transform != SMI130_NULL) {
+ for (i = 0; i < 3; i++) {
+ v_xyz_tmp_s32[i] = yas532_data_mbl.transform[i
+ * 3] *
+ xyz_data->yas532_vector_xyz[0]
+ + yas532_data_mbl.transform[i * 3 + 1] *
+ xyz_data->yas532_vector_xyz[1]
+ + yas532_data_mbl.transform[i * 3 + 2] *
+ xyz_data->yas532_vector_xyz[2];
+ }
+ set_vector(xyz_data->yas532_vector_xyz, v_xyz_tmp_s32);
+ }
+ for (i = 0; i < 3; i++) {
+ xyz_data->yas532_vector_xyz[i] -=
+ xyz_data->yas532_vector_xyz[i] % 10;
+ if (*v_overflow_s8 & (1
+ << (i * 2)))
+ xyz_data->yas532_vector_xyz[i] +=
+ 1; /* set overflow */
+ if (*v_overflow_s8 & (1 <<
+ (i * 2 + 1)))
+ xyz_data->yas532_vector_xyz[i] += 2; /* set underflow */
+ }
+
+
+if (v_busy_u8)
+ return com_rslt;
+ if (0 < *v_overflow_s8) {
+ if (!yas532_data_mbl.overflow)
+ yas532_data_mbl.overflow = 1;
+ yas532_data_mbl.measure_state = YAS532_MAG_STATE_INIT_COIL;
+ } else
+ yas532_data_mbl.overflow = 0;
+ for (i = 0; i < 3; i++)
+ yas532_data_mbl.last_raw[i] = v_xy1y2_u16[i];
+ yas532_data_mbl.last_raw[i] = v_temp_u16;
+ return com_rslt;
+}
+/*!
+ * @brief This function used for YAS532 write data acquisition
+ * command register write
+ * @param v_command_reg_data_u8 : the value of data acquisition
+ * acquisition_command | operation
+ * ---------------------|-------------------------
+ * 0x17 | turn on the acquisition coil
+ * - | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Deferred acquisition mode
+ * 0x07 | turn on the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Normal acquisition mode
+ * 0x11 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Deferred acquisition mode
+ * 0x01 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Normal acquisition mode
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas532_acquisition_command_register(
+u8 v_command_reg_data_u8)
+{
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+
+ if (p_smi130->mag_manual_enable != SMI130_MANUAL_ENABLE)
+ com_rslt = smi130_set_mag_manual_enable(
+ SMI130_MANUAL_ENABLE);
+
+ com_rslt = smi130_set_mag_write_data(v_command_reg_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* YAMAHA YAS532-0x82*/
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_YAS532_COMMAND_REGISTER);
+ p_smi130->delay_msec(SMI130_YAS_ACQ_COMMAND_DELAY);
+ com_rslt += smi130_set_mag_read_addr(
+ SMI130_YAS532_DATA_REGISTER);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+
+ if (p_smi130->mag_manual_enable == SMI130_MANUAL_ENABLE)
+ com_rslt += smi130_set_mag_manual_enable(SMI130_MANUAL_DISABLE);
+
+ return com_rslt;
+
+}
+/*!
+ * @brief This function used write offset of YAS532
+ *
+ * @param p_offset_s8 : The value of offset to write
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas532_set_offset(
+const s8 *p_offset_s8)
+{
+ /* This variable used for provide the communication
+ results*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+
+ if (p_smi130->mag_manual_enable != SMI130_MANUAL_ENABLE)
+ com_rslt = smi130_set_mag_manual_enable(SMI130_MANUAL_ENABLE);
+ p_smi130->delay_msec(SMI130_YAS532_OFFSET_DELAY);
+
+ /* Write offset X data*/
+ com_rslt = smi130_set_mag_write_data(p_offset_s8[0]);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* YAS532 offset x write*/
+ com_rslt += smi130_set_mag_write_addr(SMI130_YAS532_OFFSET_X);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+
+ /* Write offset Y data*/
+ com_rslt = smi130_set_mag_write_data(p_offset_s8[1]);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* YAS532 offset y write*/
+ com_rslt += smi130_set_mag_write_addr(SMI130_YAS532_OFFSET_Y);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+
+ /* Write offset Z data*/
+ com_rslt = smi130_set_mag_write_data(p_offset_s8[2]);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* YAS532 offset z write*/
+ com_rslt += smi130_set_mag_write_addr(SMI130_YAS532_OFFSET_Z);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ set_vector(yas532_data_mbl.v_hard_offset_s8, p_offset_s8);
+
+ if (p_smi130->mag_manual_enable == SMI130_MANUAL_ENABLE)
+ com_rslt = smi130_set_mag_manual_enable(SMI130_MANUAL_DISABLE);
+ return com_rslt;
+}
+/*!
+ * @brief This function used to init the YAMAH-YAS537
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yamaha_yas537_mag_interface_init(
+void)
+{
+/* This variable used for provide the communication
+results*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_pull_value_u8 = SMI130_INIT_VALUE;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+u8 i = SMI130_INIT_VALUE;
+/* accel operation mode to normal*/
+com_rslt = smi130_set_command_register(ACCEL_MODE_NORMAL);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* write mag power mode as NORMAL*/
+com_rslt += smi130_set_mag_interface_normal();
+/* register 0x7E write the 0x37, 0x9A and 0x30*/
+com_rslt += smi130_set_command_register(SMI130_COMMAND_REG_ONE);
+p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+com_rslt += smi130_set_command_register(SMI130_COMMAND_REG_TWO);
+p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+com_rslt += smi130_set_command_register(SMI130_COMMAND_REG_THREE);
+p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+/*switch the page1*/
+com_rslt += smi130_set_target_page(SMI130_WRITE_TARGET_PAGE1);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+smi130_get_target_page(&v_data_u8);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+com_rslt += smi130_set_paging_enable(SMI130_WRITE_ENABLE_PAGE1);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+smi130_get_paging_enable(&v_data_u8);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* enable the pullup configuration from
+the register 0x05 bit 4 and 5 as 10*/
+smi130_get_pullup_configuration(&v_pull_value_u8);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+v_pull_value_u8 = v_pull_value_u8 | SMI130_PULL_UP_DATA;
+com_rslt += smi130_set_pullup_configuration(v_pull_value_u8);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/*switch the page0*/
+com_rslt += smi130_set_target_page(SMI130_WRITE_TARGET_PAGE0);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+smi130_get_target_page(&v_data_u8);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* Write the YAS532 i2c address*/
+com_rslt += smi130_set_i2c_device_addr(SMI130_YAS537_I2C_ADDRESS);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* enable the mag interface to manual mode*/
+com_rslt += smi130_set_mag_manual_enable(SMI130_MANUAL_ENABLE);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+smi130_get_mag_manual_enable(&v_data_u8);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/*Enable the MAG interface */
+com_rslt += smi130_set_if_mode(SMI130_ENABLE_MAG_IF_MODE);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+smi130_get_if_mode(&v_data_u8);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+v_data_u8 = SMI130_MANUAL_DISABLE;
+/* Read the YAS537 device id*/
+com_rslt += smi130_set_mag_read_addr(SMI130_YAS_DEVICE_ID_REG);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+yas537_data_mbl.dev_id = v_data_u8;
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* Read the YAS532 calibration data*/
+com_rslt +=
+smi130_bosch_yamaha_yas537_calib_values(
+SMI130_GEN_READ_WRITE_DATA_LENGTH);
+p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+/* set the mode to NORMAL*/
+yas537_data_mbl.measure_state = YAS537_MAG_STATE_NORMAL;
+/* set the transform to zero */
+yas537_data_mbl.transform = SMI130_NULL;
+yas537_data_mbl.average = 32;
+for (i = 0; i < 3; i++) {
+ yas537_data_mbl.hard_offset[i] = -128;
+ yas537_data_mbl.last_after_rcoil[i] = 0;
+}
+for (i = 0; i < 4; i++)
+ yas537_data_mbl.last_raw[i] = 0;
+/* write the mag bandwidth as 25Hz*/
+com_rslt += smi130_set_mag_output_data_rate(
+SMI130_MAG_OUTPUT_DATA_RATE_25HZ);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* Enable mag interface to auto mode*/
+com_rslt += smi130_set_mag_manual_enable(
+SMI130_MANUAL_DISABLE);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+smi130_get_mag_manual_enable(&v_data_u8);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+return com_rslt;
+}
+/*!
+* @brief This function used for read the
+* YAMAHA YAS537 calibration data
+*
+*
+* @param v_rcoil_u8 : The value of r coil
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yamaha_yas537_calib_values(
+u8 v_rcoil_u8)
+{
+/* This variable used for provide the communication
+results*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+/* Array holding the YAS532 calibration values */
+u8 a_data_u8[SMI130_YAS537_CALIB_DATA_SIZE] = {
+SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+};
+static const u8 v_avrr_u8[] = {0x50, 0x60, 0x70};
+u8 v_cal_valid_u8 = SMI130_INIT_VALUE, i;
+/* write soft reset as 0x02*/
+com_rslt = smi130_set_mag_write_data(
+YAS537_SRSTR_DATA);
+p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+com_rslt += smi130_set_mag_write_addr(YAS537_REG_SRSTR);
+p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+/* Read the DX value */
+com_rslt = smi130_set_mag_read_addr(YAS537_REG_CALR_C0);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[0], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the DY1 value */
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_C1);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[1], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the DY2 value */
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_C2);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[2], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the D2 value */
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_C3);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[3], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the D3 value */
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_C4);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[4], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the D4 value */
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_C5);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[5], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the D5 value */
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_C6);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[6], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the D6 value */
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_C7);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[7], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the D7 value */
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_C8);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[8], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the D8 value */
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_C9);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[9], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the D9 value */
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_CA);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[10], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the RX value */
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_CB);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[11], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the RY1 value */
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_CC);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[12], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the RY2 value */
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_CD);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[13], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the RY2 value */
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_CE);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[14], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the CHF value */
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_CF);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[15], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the VER value */
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_DO);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register */
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[16], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* get the calib ver*/
+yas537_data_mbl.calib_yas537.ver =
+(a_data_u8[16] >> SMI130_SHIFT_BIT_POSITION_BY_06_BITS);
+for (i = 0; i < 17; i++) {
+ if (((i < 16 && a_data_u8[i]) != 0))
+ v_cal_valid_u8 = 1;
+ if ((i < 16 &&
+ (a_data_u8[i] & 0x3F)) != 0)
+ v_cal_valid_u8 = 1;
+}
+if (!v_cal_valid_u8)
+ return ERROR;
+if (yas537_data_mbl.calib_yas537.ver == 0) {
+ for (i = 0; i < 17; i++) {
+ if (i < 12) {
+ /* write offset*/
+ com_rslt += smi130_set_mag_write_data(
+ a_data_u8[i]);
+ p_smi130->delay_msec(
+ SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ YAS537_REG_MTCR + i);
+ p_smi130->delay_msec(
+ SMI130_GEN_READ_WRITE_DELAY);
+ } else if (i < 15) {
+ /* write offset correction*/
+ com_rslt += smi130_set_mag_write_data(
+ a_data_u8[i]);
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr((
+ (YAS537_REG_OXR + i) - 12));
+ p_smi130->delay_msec(
+ SMI130_GEN_READ_WRITE_DELAY);
+ yas537_data_mbl.hard_offset[i - 12]
+ = a_data_u8[i];
+ } else {
+ /* write offset correction*/
+ com_rslt += smi130_set_mag_write_data(
+ a_data_u8[i]);
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr((
+ (YAS537_REG_OXR + i) - 11));
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ }
+
+}
+} else if (yas537_data_mbl.calib_yas537.ver == 1) {
+ for (i = 0; i < 3; i++) {
+ /* write offset*/
+ com_rslt += smi130_set_mag_write_data(
+ a_data_u8[i]);
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ YAS537_REG_MTCR + i);
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ if (com_rslt == SUCCESS) {
+ /* write offset*/
+ com_rslt += smi130_set_mag_write_data(
+ a_data_u8[i + 12]);
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ YAS537_REG_OXR + i);
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ yas537_data_mbl.hard_offset[i] =
+ a_data_u8[i + 12];
+ } else {
+ com_rslt = ERROR;
+ }
+ }
+ /* write offset*/
+ com_rslt += smi130_set_mag_write_data(
+ ((a_data_u8[i] & 0xE0) | 0x10));
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ YAS537_REG_MTCR + i);
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* write offset*/
+ com_rslt += smi130_set_mag_write_data(
+ ((a_data_u8[15]
+ >> SMI130_SHIFT_BIT_POSITION_BY_03_BITS)
+ & 0x1E));
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(YAS537_REG_HCKR);
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* write offset*/
+ com_rslt += smi130_set_mag_write_data(
+ ((a_data_u8[15] << 1) & 0x1E));
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(YAS537_REG_LCKR);
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* write offset*/
+ com_rslt += smi130_set_mag_write_data(
+ (a_data_u8[16] & 0x3F));
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(YAS537_REG_OCR);
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+
+ /* Assign the calibration values*/
+ /* a2 */
+ yas537_data_mbl.calib_yas537.a2 =
+ ((((a_data_u8[3]
+ << SMI130_SHIFT_BIT_POSITION_BY_02_BITS)
+ & 0x7C)
+ | (a_data_u8[4]
+ >> SMI130_SHIFT_BIT_POSITION_BY_06_BITS)) - 64);
+ /* a3 */
+ yas537_data_mbl.calib_yas537.a3 =
+ ((((a_data_u8[4] << SMI130_SHIFT_BIT_POSITION_BY_01_BIT)
+ & 0x7E)
+ | (a_data_u8[5]
+ >> SMI130_SHIFT_BIT_POSITION_BY_07_BITS)) - 64);
+ /* a4 */
+ yas537_data_mbl.calib_yas537.a4 =
+ ((((a_data_u8[5]
+ << SMI130_SHIFT_BIT_POSITION_BY_01_BIT)
+ & 0xFE)
+ | (a_data_u8[6]
+ >> SMI130_SHIFT_BIT_POSITION_BY_07_BITS))
+ - 128);
+ /* a5 */
+ yas537_data_mbl.calib_yas537.a5 =
+ ((((a_data_u8[6]
+ << SMI130_SHIFT_BIT_POSITION_BY_02_BITS)
+ & 0x1FC)
+ | (a_data_u8[7]
+ >> SMI130_SHIFT_BIT_POSITION_BY_06_BITS))
+ - 112);
+ /* a6 */
+ yas537_data_mbl.calib_yas537.a6 =
+ ((((a_data_u8[7]
+ << SMI130_SHIFT_BIT_POSITION_BY_01_BIT)
+ & 0x7E)
+ | (a_data_u8[8]
+ >> SMI130_SHIFT_BIT_POSITION_BY_07_BITS)) - 64);
+ /* a7 */
+ yas537_data_mbl.calib_yas537.a7 =
+ ((((a_data_u8[8]
+ << SMI130_SHIFT_BIT_POSITION_BY_01_BIT)
+ & 0xFE)
+ | (a_data_u8[9]
+ >> SMI130_SHIFT_BIT_POSITION_BY_07_BITS))
+ - 128);
+ /* a8 */
+ yas537_data_mbl.calib_yas537.a8 = ((a_data_u8[9] &
+ 0x7F) - 64);
+ /* a9 */
+ yas537_data_mbl.calib_yas537.a9 = ((((a_data_u8[10]
+ << SMI130_SHIFT_BIT_POSITION_BY_01_BIT) & 0x1FE)
+ | (a_data_u8[11]
+ >> SMI130_SHIFT_BIT_POSITION_BY_07_BITS))
+ - 112);
+ /* k */
+ yas537_data_mbl.calib_yas537.k = (
+ a_data_u8[11] & 0x7F);
+ } else {
+ return ERROR;
+ }
+/* write A/D converter*/
+com_rslt += smi130_set_mag_write_data(
+YAS537_WRITE_A_D_CONVERTER);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+com_rslt += smi130_set_mag_write_addr(YAS537_REG_ADCCALR);
+p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+/* write A/D converter second register*/
+com_rslt += smi130_set_mag_write_data(
+YAS537_WRITE_A_D_CONVERTER2);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+com_rslt += smi130_set_mag_write_addr(YAS537_REG_ADCCALR_ONE);
+p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+/* write temperature calibration register*/
+com_rslt += smi130_set_mag_write_data(YAS537_WRITE_TEMP_CALIB);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+com_rslt += smi130_set_mag_write_addr(YAS537_REG_TRMR);
+p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+/* write average filter register*/
+com_rslt += smi130_set_mag_write_data(
+v_avrr_u8[yas537_data_mbl.average]);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+com_rslt += smi130_set_mag_write_addr(YAS537_REG_AVRR);
+p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+if (v_rcoil_u8) {
+ /* write average; filter register*/
+ com_rslt += smi130_set_mag_write_data(
+ YAS537_WRITE_FILTER);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(YAS537_REG_CONFR);
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+}
+
+return com_rslt;
+
+}
+/*!
+ * @brief This function used for YAS537 write data acquisition
+ * command register write
+ * @param v_command_reg_data_u8 : the value of data acquisition
+ * acquisition_command | operation
+ * ---------------------|-------------------------
+ * 0x17 | turn on the acquisition coil
+ * - | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Deferred acquisition mode
+ * 0x07 | turn on the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Normal acquisition mode
+ * 0x11 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Deferred acquisition mode
+ * 0x01 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Normal acquisition mode
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas537_acquisition_command_register(
+u8 v_command_reg_data_u8)
+{
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+
+ if (p_smi130->mag_manual_enable != SMI130_MANUAL_ENABLE)
+ com_rslt = smi130_set_mag_manual_enable(
+ SMI130_MANUAL_ENABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+
+ com_rslt = smi130_set_mag_write_data(v_command_reg_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* YAMAHA YAS532-0x82*/
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_REG_YAS537_CMDR);
+ /* set the mode to RECORD*/
+ yas537_data_mbl.measure_state = YAS537_MAG_STATE_RECORD_DATA;
+ p_smi130->delay_msec(SMI130_YAS_ACQ_COMMAND_DELAY);
+ com_rslt += smi130_set_mag_read_addr(
+ YAS537_REG_TEMPERATURE_0);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+
+ if (p_smi130->mag_manual_enable == SMI130_MANUAL_ENABLE)
+ com_rslt += smi130_set_mag_manual_enable(
+ SMI130_MANUAL_DISABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+
+ return com_rslt;
+
+}
+/*!
+ * @brief This function used for read the
+ * YAMAHA YAS537 xy1y2 data
+ *
+ * @param xy1y2: The value of raw xy1y2 data
+ * @param xyz: The value of xyz data
+ *
+ *
+ * @return None
+ *
+ *
+ */
+static void xy1y2_to_xyz(u16 *xy1y2, s32 *xyz)
+{
+ xyz[0] = ((xy1y2[0] - 8192)
+ * 300);
+ xyz[1] = (((xy1y2[1] - xy1y2[2])
+ * 1732) / 10);
+ xyz[2] = (((-xy1y2[2] - xy1y2[2])
+ + 16384) * 300);
+}
+/*!
+ * @brief This function used for read the
+ * YAMAHA YAS537 xy1y2 data
+ *
+ * @param v_coil_stat_u8: The value of R coil status
+ * @param v_busy_u8: The value of busy status
+ * @param v_temperature_u16: The value of temperature
+ * @param xy1y2: The value of raw xy1y2 data
+ * @param v_ouflow_u8: The value of overflow
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yamaha_yas537_read_xy1y2_data(
+u8 *v_coil_stat_u8, u8 *v_busy_u8,
+u16 *v_temperature_u16, u16 *xy1y2, u8 *v_ouflow_u8)
+{
+ /* This variable used for provide the communication
+ results*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array holding the YAS532 calibration values */
+ u8 a_data_u8[SMI130_YAS_XY1Y2T_DATA_SIZE] = {
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ };
+ u8 i = SMI130_INIT_VALUE;
+ s32 a_h_s32[SMI130_YAS_H_DATA_SIZE] = {
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ s32 a_s_s32[SMI130_YAS_S_DATA_SIZE] = {
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ /* set command register*/
+ com_rslt = smi130_bosch_yas537_acquisition_command_register(
+ YAS537_SET_COMMAND_REGISTER);
+ /* read the yas537 sensor data of xy1y2*/
+ com_rslt +=
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_DATA_MAG_X_LSB__REG,
+ a_data_u8, SMI130_MAG_YAS_DATA_LENGTH);
+ /* read the busy flag*/
+ *v_busy_u8 = a_data_u8[2]
+ >> SMI130_SHIFT_BIT_POSITION_BY_07_BITS;
+ /* read the coil status*/
+ *v_coil_stat_u8 =
+ ((a_data_u8[2] >>
+ SMI130_SHIFT_BIT_POSITION_BY_06_BITS) & 0X01);
+ /* read temperature data*/
+ *v_temperature_u16 = (u16)((a_data_u8[0]
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) | a_data_u8[1]);
+ /* read x data*/
+ xy1y2[0] = (u16)(((a_data_u8[2] &
+ 0x3F)
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (a_data_u8[3]));
+ /* read y1 data*/
+ xy1y2[1] = (u16)((a_data_u8[4]
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | a_data_u8[5]);
+ /* read y2 data*/
+ xy1y2[2] = (u16)((a_data_u8[6]
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | a_data_u8[7]);
+ for (i = 0; i < 3; i++)
+ yas537_data_mbl.last_raw[i] = xy1y2[i];
+ yas537_data_mbl.last_raw[i] = *v_temperature_u16;
+ if (yas537_data_mbl.calib_yas537.ver == 1) {
+ for (i = 0; i < 3; i++)
+ a_s_s32[i] = xy1y2[i] - 8192;
+ /* read hx*/
+ a_h_s32[0] = ((yas537_data_mbl.calib_yas537.k * (
+ (128 * a_s_s32[0]) +
+ (yas537_data_mbl.calib_yas537.a2 * a_s_s32[1]) +
+ (yas537_data_mbl.calib_yas537.a3 * a_s_s32[2])))
+ / (8192));
+ /* read hy1*/
+ a_h_s32[1] = ((yas537_data_mbl.calib_yas537.k * (
+ (yas537_data_mbl.calib_yas537.a4 * a_s_s32[0]) +
+ (yas537_data_mbl.calib_yas537.a5 * a_s_s32[1]) +
+ (yas537_data_mbl.calib_yas537.a6 * a_s_s32[2])))
+ / (8192));
+ /* read hy2*/
+ a_h_s32[2] = ((yas537_data_mbl.calib_yas537.k * (
+ (yas537_data_mbl.calib_yas537.a7 * a_s_s32[0]) +
+ (yas537_data_mbl.calib_yas537.a8 * a_s_s32[1]) +
+ (yas537_data_mbl.calib_yas537.a9 * a_s_s32[2])))
+ / (8192));
+
+ for (i = 0; i < 3; i++) {
+ if (a_h_s32[i] < -8192)
+ a_h_s32[i] = -8192;
+
+ if (8192 < a_h_s32[i])
+ a_h_s32[i] = 8192;
+
+ xy1y2[i] = a_h_s32[i] + 8192;
+
+ }
+ }
+ *v_ouflow_u8 = 0;
+ for (i = 0; i < 3; i++) {
+ if (YAS537_DATA_OVERFLOW <= xy1y2[i])
+ *v_ouflow_u8 |= (1 << (i * 2));
+ if (xy1y2[i] == YAS537_DATA_UNDERFLOW)
+ *v_ouflow_u8 |= (1 << (i * 2 + 1));
+ }
+
+ return com_rslt;
+
+}
+/*!
+ * @brief This function used for read the
+ * YAMAHA YAS537 xy1y2 data
+ *
+ * @param v_ouflow_u8: The value of overflow
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+static SMI130_RETURN_FUNCTION_TYPE invalid_magnetic_field(
+u16 *v_cur_u16, u16 *v_last_u16)
+{
+ s16 invalid_thresh[] = {1500, 1500, 1500};
+ u8 i = SMI130_INIT_VALUE;
+
+ for (i = 0; i < 3; i++)
+ if (invalid_thresh[i] < ABS(v_cur_u16[i] - v_last_u16[i]))
+ return 1;
+ return 0;
+}
+/*!
+ * @brief This function used for read the
+ * YAMAHA YAS537 xy1y2 data
+ *
+ * @param v_ouflow_u8: The value of overflow
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yamaha_yas537_measure_xyz_data(
+u8 *v_ouflow_u8, struct yas_vector *vector_xyz)
+{
+ s32 a_xyz_tmp_s32[SMI130_YAS_TEMP_DATA_SIZE] = {
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ u8 i = SMI130_INIT_VALUE;
+ s8 com_rslt = SMI130_INIT_VALUE;
+ u8 v_busy_u8 = SMI130_INIT_VALUE;
+ u8 v_rcoil_u8 = SMI130_INIT_VALUE;
+ u16 v_temperature_u16 = SMI130_INIT_VALUE;
+ u16 a_xy1y2_u16[SMI130_YAS_XY1Y2_DATA_SIZE] = {
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ *v_ouflow_u8 = 0;
+ /* read the yas537 xy1y2 data*/
+ com_rslt = smi130_bosch_yamaha_yas537_read_xy1y2_data(
+ &v_rcoil_u8, &v_busy_u8,
+ &v_temperature_u16, a_xy1y2_u16, v_ouflow_u8);
+ /* linear calculation*/
+ xy1y2_to_xyz(a_xy1y2_u16, vector_xyz->yas537_vector_xyz);
+ if (yas537_data_mbl.transform != SMI130_NULL) {
+ for (i = 0; i < 3; i++) {
+ a_xyz_tmp_s32[i] = ((
+ yas537_data_mbl.transform[i + 3]
+ * vector_xyz->yas537_vector_xyz[0])
+ + (yas537_data_mbl.transform[
+ i * 3 + 1]
+ * vector_xyz->yas537_vector_xyz[1])
+ + (yas537_data_mbl.transform[
+ i * 3 + 2]
+ * vector_xyz->yas537_vector_xyz[2]));
+ }
+ yas537_set_vector(
+ vector_xyz->yas537_vector_xyz, a_xyz_tmp_s32);
+ }
+ for (i = 0; i < 3; i++) {
+ vector_xyz->yas537_vector_xyz[i] -=
+ vector_xyz->yas537_vector_xyz[i] % 10;
+ if (*v_ouflow_u8 & (1 <<
+ (i * 2)))
+ vector_xyz->yas537_vector_xyz[i] +=
+ 1; /* set overflow */
+ if (*v_ouflow_u8 & (1 << (i * 2 + 1)))
+ /* set underflow */
+ vector_xyz->yas537_vector_xyz[i] += 2;
+ }
+ if (v_busy_u8)
+ return ERROR;
+ switch (yas537_data_mbl.measure_state) {
+ case YAS537_MAG_STATE_INIT_COIL:
+ if (p_smi130->mag_manual_enable != SMI130_MANUAL_ENABLE)
+ com_rslt = smi130_set_mag_manual_enable(
+ SMI130_MANUAL_ENABLE);
+ com_rslt += smi130_set_mag_write_data(YAS537_WRITE_CONFR);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(YAS537_REG_CONFR);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ yas537_data_mbl.measure_state = YAS537_MAG_STATE_RECORD_DATA;
+ if (p_smi130->mag_manual_enable == SMI130_MANUAL_ENABLE)
+ com_rslt = smi130_set_mag_manual_enable(
+ SMI130_MANUAL_DISABLE);
+ break;
+ case YAS537_MAG_STATE_RECORD_DATA:
+ if (v_rcoil_u8)
+ break;
+ yas537_set_vector(yas537_data_mbl.last_after_rcoil, a_xy1y2_u16);
+ yas537_data_mbl.measure_state = YAS537_MAG_STATE_NORMAL;
+ break;
+ case YAS537_MAG_STATE_NORMAL:
+ if (SMI130_INIT_VALUE < v_ouflow_u8
+ || invalid_magnetic_field(a_xy1y2_u16,
+ yas537_data_mbl.last_after_rcoil)) {
+ yas537_data_mbl.measure_state = YAS537_MAG_STATE_INIT_COIL;
+ for (i = 0; i < 3; i++) {
+ if (!*v_ouflow_u8)
+ vector_xyz->yas537_vector_xyz[i] += 3;
+ }
+ }
+ break;
+ }
+
+ return com_rslt;
+}
+/*!
+ * @brief This function used for reading
+ * smi130_t structure
+ *
+ * @return the reference and values of smi130_t
+ *
+ *
+*/
+struct smi130_t *smi130_get_ptr(void)
+{
+ return p_smi130;
+}
diff --git a/drivers/input/sensors/smi130/smi130.h b/drivers/input/sensors/smi130/smi130.h
new file mode 100644
index 0000000..c62f65c
--- /dev/null
+++ b/drivers/input/sensors/smi130/smi130.h
@@ -0,0 +1,11851 @@
+/*!
+ * @section LICENSE
+ * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved
+ *
+ * (C) Modification Copyright 2018 Robert Bosch Kft All Rights Reserved
+ *
+ * This software program is licensed subject to the GNU General
+ * Public License (GPL).Version 2,June 1991,
+ * available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * Special: Description of the Software:
+ *
+ * This software module (hereinafter called "Software") and any
+ * information on application-sheets (hereinafter called "Information") is
+ * provided free of charge for the sole purpose to support your application
+ * work.
+ *
+ * As such, the Software is merely an experimental software, not tested for
+ * safety in the field and only intended for inspiration for further development
+ * and testing. Any usage in a safety-relevant field of use (like automotive,
+ * seafaring, spacefaring, industrial plants etc.) was not intended, so there are
+ * no precautions for such usage incorporated in the Software.
+ *
+ * The Software is specifically designed for the exclusive use for Bosch
+ * Sensortec products by personnel who have special experience and training. Do
+ * not use this Software if you do not have the proper experience or training.
+ *
+ * This Software package is provided as is and without any expressed or
+ * implied warranties, including without limitation, the implied warranties of
+ * merchantability and fitness for a particular purpose.
+ *
+ * Bosch Sensortec and their representatives and agents deny any liability for
+ * the functional impairment of this Software in terms of fitness, performance
+ * and safety. Bosch Sensortec and their representatives and agents shall not be
+ * liable for any direct or indirect damages or injury, except as otherwise
+ * stipulated in mandatory applicable law.
+ * The Information provided is believed to be accurate and reliable. Bosch
+ * Sensortec assumes no responsibility for the consequences of use of such
+ * Information nor for any infringement of patents or other rights of third
+ * parties which may result from its use.
+ *
+ *------------------------------------------------------------------------------
+ * The following Product Disclaimer does not apply to the BSX4-HAL-4.1NoFusion Software
+ * which is licensed under the Apache License, Version 2.0 as stated above.
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Product Disclaimer
+ *
+ * Common:
+ *
+ * Assessment of Products Returned from Field
+ *
+ * Returned products are considered good if they fulfill the specifications /
+ * test data for 0-mileage and field listed in this document.
+ *
+ * Engineering Samples
+ *
+ * Engineering samples are marked with (e) or (E). Samples may vary from the
+ * valid technical specifications of the series product contained in this
+ * data sheet. Therefore, they are not intended or fit for resale to
+ * third parties or for use in end products. Their sole purpose is internal
+ * client testing. The testing of an engineering sample may in no way replace
+ * the testing of a series product. Bosch assumes no liability for the use
+ * of engineering samples. The purchaser shall indemnify Bosch from all claims
+ * arising from the use of engineering samples.
+ *
+ * Intended use
+ *
+ * Provided that SMI130 is used within the conditions (environment, application,
+ * installation, loads) as described in this TCD and the corresponding
+ * agreed upon documents, Bosch ensures that the product complies with
+ * the agreed properties. Agreements beyond this require
+ * the written approval by Bosch. The product is considered fit for the intended
+ * use when the product successfully has passed the tests
+ * in accordance with the TCD and agreed upon documents.
+ *
+ * It is the responsibility of the customer to ensure the proper application
+ * of the product in the overall system/vehicle.
+ *
+ * Bosch does not assume any responsibility for changes to the environment
+ * of the product that deviate from the TCD and the agreed upon documents
+ * as well as all applications not released by Bosch
+ *
+ * The resale and/or use of products are at the purchaser’s own risk and
+ * responsibility. The examination and testing of the SMI130
+ * is the sole responsibility of the purchaser.
+ *
+ * The purchaser shall indemnify Bosch from all third party claims
+ * arising from any product use not covered by the parameters of
+ * this product data sheet or not approved by Bosch and reimburse Bosch
+ * for all costs and damages in connection with such claims.
+ *
+ * The purchaser must monitor the market for the purchased products,
+ * particularly with regard to product safety, and inform Bosch without delay
+ * of all security relevant incidents.
+ *
+ * Application Examples and Hints
+ *
+ * With respect to any application examples, advice, normal values
+ * and/or any information regarding the application of the device,
+ * Bosch hereby disclaims any and all warranties and liabilities of any kind,
+ * including without limitation warranties of
+ * non-infringement of intellectual property rights or copyrights
+ * of any third party.
+ * The information given in this document shall in no event be regarded
+ * as a guarantee of conditions or characteristics. They are provided
+ * for illustrative purposes only and no evaluation regarding infringement
+ * of intellectual property rights or copyrights or regarding functionality,
+ * performance or error has been made.
+*
+* smi130.h
+* Date : 2015/04/02
+* @id 836294d
+* Revision : 2.0.9 $
+* @brief
+* The head file of SMI130API
+*
+
+**************************************************************************/
+/*! \file smi130.h
+ \brief SMI130 Sensor Driver Support Header File */
+/* user defined code to be added here ... */
+#ifndef __SMI130_H__
+#define __SMI130_H__
+
+/*!
+* @brief The following definition uses for define the data types
+*
+* @note While porting the API please consider the following
+* @note Please check the version of C standard
+* @note Are you using Linux platform
+*/
+
+/*!
+* @brief For the Linux platform support
+* Please use the types.h for your data types definitions
+*/
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+
+#else /* ! __KERNEL__ */
+/**********************************************************
+* These definition uses for define the C
+* standard version data types
+***********************************************************/
+# if !defined(__STDC_VERSION__)
+
+/************************************************
+ * compiler is C11 C standard
+************************************************/
+#if (__STDC_VERSION__ == 201112L)
+
+/************************************************/
+#include <stdint.h>
+/************************************************/
+
+/*unsigned integer types*/
+#define u8 uint8_t
+#define u16 uint16_t
+#define u32 uint32_t
+#define u64 uint64_t
+
+/*signed integer types*/
+#define s8 int8_t
+#define s16 int16_t
+#define s32 int32_t
+#define s64 int64_t
+/************************************************
+ * compiler is C99 C standard
+************************************************/
+
+#elif (__STDC_VERSION__ == 199901L)
+
+/* stdint.h is a C99 supported c library.
+which is used to fixed the integer size*/
+/************************************************/
+#include <stdint.h>
+/************************************************/
+
+/*unsigned integer types*/
+#define u8 uint8_t
+#define u16 uint16_t
+#define u32 uint32_t
+#define u64 uint64_t
+
+/*signed integer types*/
+#define s8 int8_t
+#define s16 int16_t
+#define s32 int32_t
+#define s64 int64_t
+/************************************************
+ * compiler is C89 or other C standard
+************************************************/
+#else /* !defined(__STDC_VERSION__) */
+/* By default it is defined as 32 bit machine configuration*/
+/* define the definition based on your machine configuration*/
+/* define the data types based on your
+ machine/compiler/controller configuration*/
+#define MACHINE_32_BIT
+
+/* If your machine support 16 bit
+define the MACHINE_16_BIT*/
+#ifdef MACHINE_16_BIT
+#include <limits.h>
+/*signed integer types*/
+#define s8 signed char
+#define s16 signed short int
+#define s32 signed long int
+
+#if defined(LONG_MAX) && LONG_MAX == 0x7fffffffffffffffL
+#define s64 long int
+#define u64 unsigned long int
+#elif defined(LLONG_MAX) && (LLONG_MAX == 0x7fffffffffffffffLL)
+#define s64 long long int
+#define u64 unsigned long long int
+#else
+#warning Either the correct data type for signed 64 bit integer \
+could not be found, or 64 bit integers are not supported in your environment.
+#warning If 64 bit integers are supported on your platform, \
+please set s64 manually.
+#endif
+
+/*unsigned integer types*/
+#define u8 unsigned char
+#define u16 unsigned short int
+#define u32 unsigned long int
+
+/* If your machine support 32 bit
+define the MACHINE_32_BIT*/
+#elif defined MACHINE_32_BIT
+/*signed integer types*/
+#define s8 signed char
+#define s16 signed short int
+#define s32 signed int
+#define s64 signed long long int
+
+/*unsigned integer types*/
+#define u8 unsigned char
+#define u16 unsigned short int
+#define u32 unsigned int
+#define u64 unsigned long long int
+
+/* If your machine support 64 bit
+define the MACHINE_64_BIT*/
+#elif defined MACHINE_64_BIT
+/*signed integer types*/
+#define s8 signed char
+#define s16 signed short int
+#define s32 signed int
+#define s64 signed long int
+
+/*unsigned integer types*/
+#define u8 unsigned char
+#define u16 unsigned short int
+#define u32 unsigned int
+#define u64 unsigned long int
+
+#else
+#warning The data types defined above which not supported \
+define the data types manually
+#endif
+#endif
+
+/*** This else will execute for the compilers
+ * which are not supported the C standards
+ * Like C89/C99/C11***/
+#else
+/* By default it is defined as 32 bit machine configuration*/
+/* define the definition based on your machine configuration*/
+/* define the data types based on your
+ machine/compiler/controller configuration*/
+#define MACHINE_32_BIT
+
+/* If your machine support 16 bit
+define the MACHINE_16_BIT*/
+#ifdef MACHINE_16_BIT
+#include <limits.h>
+/*signed integer types*/
+#define s8 signed char
+#define s16 signed short int
+#define s32 signed long int
+
+#if defined(LONG_MAX) && LONG_MAX == 0x7fffffffffffffffL
+#define s64 long int
+#define u64 unsigned long int
+#elif defined(LLONG_MAX) && (LLONG_MAX == 0x7fffffffffffffffLL)
+#define s64 long long int
+#define u64 unsigned long long int
+#else
+#warning Either the correct data type for signed 64 bit integer \
+could not be found, or 64 bit integers are not supported in your environment.
+#warning If 64 bit integers are supported on your platform, \
+please set s64 manually.
+#endif
+
+/*unsigned integer types*/
+#define u8 unsigned char
+#define u16 unsigned short int
+#define u32 unsigned long int
+
+/* If your machine support 32 bit
+define the MACHINE_32_BIT*/
+#elif defined MACHINE_32_BIT
+/*signed integer types*/
+#define s8 signed char
+#define s16 signed short int
+#define s32 signed int
+#define s64 signed long long int
+
+/*unsigned integer types*/
+#define u8 unsigned char
+#define u16 unsigned short int
+#define u32 unsigned int
+#define u64 unsigned long long int
+
+/* If your machine support 64 bit
+define the MACHINE_64_BIT*/
+#elif defined MACHINE_64_BIT
+/*signed integer types*/
+#define s8 signed char
+#define s16 signed short int
+#define s32 signed int
+#define s64 signed long int
+
+/*unsigned integer types*/
+#define u8 unsigned char
+#define u16 unsigned short int
+#define u32 unsigned int
+#define u64 unsigned long int
+
+#else
+#warning The data types defined above which not supported \
+define the data types manually
+#endif
+#endif
+#endif
+/***************************************************************/
+/**\name BUS READ AND WRITE FUNCTION POINTERS */
+/***************************************************************/
+/*!
+ @brief Define the calling convention of YOUR bus communication routine.
+ @note This includes types of parameters. This example shows the
+ configuration for an SPI bus link.
+
+ If your communication function looks like this:
+
+ write_my_bus_xy(u8 device_addr, u8 register_addr,
+ u8 * data, u8 length);
+
+ The SMI130_WR_FUNC_PTR would equal:
+
+ SMI130_WR_FUNC_PTR s8 (* bus_write)(u8,
+ u8, u8 *, u8)
+
+ Parameters can be mixed as needed refer to the
+ @ref SMI130_BUS_WRITE_FUNC macro.
+
+
+*/
+#define SMI130_WR_FUNC_PTR s8 (*bus_write)(u8, u8,\
+u8 *, u8)
+/**< link macro between API function calls and bus write function
+ @note The bus write function can change since this is a
+ system dependant issue.
+
+ If the bus_write parameter calling order is like: reg_addr,
+ reg_data, wr_len it would be as it is here.
+
+ If the parameters are differently ordered or your communication
+ function like I2C need to know the device address,
+ you can change this macro accordingly.
+
+
+ SMI130_BUS_WRITE_FUNC(dev_addr, reg_addr, reg_data, wr_len)\
+ bus_write(dev_addr, reg_addr, reg_data, wr_len)
+
+ This macro lets all API functions call YOUR communication routine in a
+ way that equals your definition in the
+ @ref SMI130_WR_FUNC_PTR definition.
+
+*/
+#define SMI130_BUS_WRITE_FUNC(dev_addr, reg_addr, reg_data, wr_len)\
+ bus_write(dev_addr, reg_addr, reg_data, wr_len)
+
+/**< Define the calling convention of YOUR bus communication routine.
+ @note This includes types of parameters. This example shows the
+ configuration for an SPI bus link.
+
+ If your communication function looks like this:
+
+ read_my_bus_xy(u8 device_addr, u8 register_addr,
+ u8 * data, u8 length);
+
+ The SMI130_RD_FUNC_PTR would equal:
+
+ SMI130_RD_FUNC_PTR s8 (* bus_read)(u8,
+ u8, u8 *, u8)
+
+ Parameters can be mixed as needed refer to the
+ refer SMI130_BUS_READ_FUNC macro.
+
+*/
+#define SMI130_SPI_RD_MASK (0x80) /* for spi read transactions on SPI the
+ MSB has to be set */
+#define SMI130_RD_FUNC_PTR s8 (*bus_read)(u8,\
+ u8, u8 *, u8)
+
+#define SMI130_BRD_FUNC_PTR s8 \
+(*burst_read)(u8, u8, u8 *, u32)
+
+/**< link macro between API function calls and bus read function
+ @note The bus write function can change since this is a
+ system dependant issue.
+
+ If the bus_read parameter calling order is like: reg_addr,
+ reg_data, wr_len it would be as it is here.
+
+ If the parameters are differently ordered or your communication
+ function like I2C need to know the device address,
+ you can change this macro accordingly.
+
+
+ SMI130_BUS_READ_FUNC(dev_addr, reg_addr, reg_data, wr_len)\
+ bus_read(dev_addr, reg_addr, reg_data, wr_len)
+
+ This macro lets all API functions call YOUR communication routine in a
+ way that equals your definition in the
+ refer SMI130_WR_FUNC_PTR definition.
+
+ @note: this macro also includes the "MSB='1'
+ for reading SMI130 addresses.
+
+*/
+#define SMI130_BUS_READ_FUNC(dev_addr, reg_addr, reg_data, r_len)\
+ bus_read(dev_addr, reg_addr, reg_data, r_len)
+
+#define SMI130_BURST_READ_FUNC(device_addr, \
+register_addr, register_data, rd_len)\
+burst_read(device_addr, register_addr, register_data, rd_len)
+
+
+#define SMI130_MDELAY_DATA_TYPE u32
+
+/***************************************************************/
+/**\name BUS READ AND WRITE FUNCTION POINTERS */
+/***************************************************************/
+#define SMI130_I2C_ADDR1 0x68 /**< I2C Address needs to be changed */
+#define SMI130_I2C_ADDR2 0x69 /**< I2C Address needs to be changed */
+#define SMI130_AUX_BMM150_I2C_ADDRESS (0x10)
+#define SMI130_AUX_YAS532_I2C_ADDRESS (0x2E)
+/**< I2C address of YAS532*/
+#define SMI130_AKM09911_I2C_ADDRESS 0x0C/**< I2C address of AKM09911*/
+/**< I2C address of AKM09911*/
+#define SMI130_AUX_AKM09911_I2C_ADDR_2 (0x0D)
+/**< I2C address of AKM09911*/
+#define SMI130_AUX_AKM09912_I2C_ADDR_1 (0x0C)
+/**< I2C address of AKM09912*/
+#define SMI130_AUX_AKM09912_I2C_ADDR_2 (0x0D)
+/**< I2C address of AKM09912*/
+#define SMI130_AUX_AKM09912_I2C_ADDR_3 (0x0E)
+/**< I2C address of AKM09912*/
+#define SMI130_AKM09912_I2C_ADDRESS 0x0F/**< I2C address of akm09912*/
+
+#define SMI130_YAS532_I2C_ADDRESS 0x2E/**< I2C address of YAS532*/
+/*******************************************/
+/**\name CONSTANTS */
+/******************************************/
+#define SMI130_INIT_VALUE (0)
+#define SMI130_GEN_READ_WRITE_DATA_LENGTH (1)
+#define SMI130_MAXIMUM_TIMEOUT (10)
+/* output data rate condition check*/
+#define SMI130_OUTPUT_DATA_RATE0 (0)
+#define SMI130_OUTPUT_DATA_RATE1 (1)
+#define SMI130_OUTPUT_DATA_RATE2 (2)
+#define SMI130_OUTPUT_DATA_RATE3 (3)
+#define SMI130_OUTPUT_DATA_RATE4 (4)
+#define SMI130_OUTPUT_DATA_RATE5 (5)
+#define SMI130_OUTPUT_DATA_RATE6 (14)
+#define SMI130_OUTPUT_DATA_RATE7 (15)
+/* accel range check*/
+#define SMI130_ACCEL_RANGE0 (3)
+#define SMI130_ACCEL_RANGE1 (5)
+#define SMI130_ACCEL_RANGE3 (8)
+#define SMI130_ACCEL_RANGE4 (12)
+/* check the status of registers*/
+#define SMI130_FOC_STAT_HIGH (1)
+#define SMI130_SIG_MOTION_STAT_HIGH (1)
+#define SMI130_STEP_DET_STAT_HIGH (1)
+
+/*condition check for reading and writing data*/
+#define SMI130_MAX_VALUE_SIGNIFICANT_MOTION (1)
+#define SMI130_MAX_VALUE_FIFO_FILTER (1)
+#define SMI130_MAX_VALUE_FIFO_TIME (1)
+#define SMI130_MAX_VALUE_FIFO_INTR (1)
+#define SMI130_MAX_VALUE_FIFO_HEADER (1)
+#define SMI130_MAX_VALUE_FIFO_MAG (1)
+#define SMI130_MAX_VALUE_FIFO_ACCEL (1)
+#define SMI130_MAX_VALUE_FIFO_GYRO (1)
+#define SMI130_MAX_VALUE_SOURCE_INTR (1)
+#define SMI130_MAX_VALUE_LOW_G_MODE (1)
+#define SMI130_MAX_VALUE_NO_MOTION (1)
+#define SMI130_MAX_VALUE_TAP_SHOCK (1)
+#define SMI130_MAX_VALUE_TAP_QUIET (1)
+#define SMI130_MAX_VALUE_ORIENT_UD (1)
+#define SMI130_MAX_VALUE_ORIENT_AXES (1)
+#define SMI130_MAX_VALUE_NVM_PROG (1)
+#define SMI130_MAX_VALUE_SPI3 (1)
+#define SMI130_MAX_VALUE_PAGE (1)
+#define SMI130_MAX_VALUE_I2C_WDT (1)
+#define SMI130_MAX_VALUE_SLEEP_STATE (1)
+#define SMI130_MAX_VALUE_WAKEUP_INTR (1)
+#define SMI130_MAX_VALUE_SELFTEST_SIGN (1)
+#define SMI130_MAX_VALUE_SELFTEST_AMP (1)
+#define SMI130_MAX_VALUE_SELFTEST_START (1)
+#define SMI130_MAX_GYRO_WAKEUP_TRIGGER (3)
+#define SMI130_MAX_ACCEL_SELFTEST_AXIS (3)
+#define SMI130_MAX_GYRO_STEP_COUNTER (1)
+#define SMI130_MAX_GYRO_BW (3)
+#define SMI130_MAX_ACCEL_BW (7)
+#define SMI130_MAX_ORIENT_MODE (3)
+#define SMI130_MAX_ORIENT_BLOCKING (3)
+#define SMI130_MAX_FLAT_HOLD (3)
+#define SMI130_MAX_ACCEL_FOC (3)
+#define SMI130_MAX_IF_MODE (3)
+#define SMI130_MAX_TARGET_PAGE (3)
+#define SMI130_MAX_GYRO_RANGE (4)
+#define SMI130_MAX_GYRO_SLEEP_TIGGER (7)
+#define SMI130_MAX_TAP_TURN (7)
+#define SMI130_MAX_UNDER_SAMPLING (1)
+#define SMI130_MAX_UNDER_SIG_MOTION (3)
+#define SMI130_MAX_ACCEL_OUTPUT_DATA_RATE (12)
+#define SMI130_MAX_LATCH_INTR (15)
+#define SMI130_MAX_FLAT_HYST (15)
+#define SMI130_MAX_ORIENT_THETA (63)
+#define SMI130_MAX_FLAT_THETA (63)
+
+/* FIFO index definitions*/
+#define SMI130_FIFO_X_LSB_DATA (0)
+#define SMI130_FIFO_X_MSB_DATA (1)
+#define SMI130_FIFO_Y_LSB_DATA (2)
+#define SMI130_FIFO_Y_MSB_DATA (3)
+#define SMI130_FIFO_Z_LSB_DATA (4)
+#define SMI130_FIFO_Z_MSB_DATA (5)
+#define SMI130_FIFO_R_LSB_DATA (6)
+#define SMI130_FIFO_R_MSB_DATA (7)
+/* FIFO gyro definition*/
+#define SMI130_GA_FIFO_G_X_LSB (0)
+#define SMI130_GA_FIFO_G_X_MSB (1)
+#define SMI130_GA_FIFO_G_Y_LSB (2)
+#define SMI130_GA_FIFO_G_Y_MSB (3)
+#define SMI130_GA_FIFO_G_Z_LSB (4)
+#define SMI130_GA_FIFO_G_Z_MSB (5)
+#define SMI130_GA_FIFO_A_X_LSB (6)
+#define SMI130_GA_FIFO_A_X_MSB (7)
+#define SMI130_GA_FIFO_A_Y_LSB (8)
+#define SMI130_GA_FIFO_A_Y_MSB (9)
+#define SMI130_GA_FIFO_A_Z_LSB (10)
+#define SMI130_GA_FIFO_A_Z_MSB (11)
+/* FIFO mag/gyro/accel definition*/
+#define SMI130_MGA_FIFO_M_X_LSB (0)
+#define SMI130_MGA_FIFO_M_X_MSB (1)
+#define SMI130_MGA_FIFO_M_Y_LSB (2)
+#define SMI130_MGA_FIFO_M_Y_MSB (3)
+#define SMI130_MGA_FIFO_M_Z_LSB (4)
+#define SMI130_MGA_FIFO_M_Z_MSB (5)
+#define SMI130_MGA_FIFO_M_R_LSB (6)
+#define SMI130_MGA_FIFO_M_R_MSB (7)
+#define SMI130_MGA_FIFO_G_X_LSB (8)
+#define SMI130_MGA_FIFO_G_X_MSB (9)
+#define SMI130_MGA_FIFO_G_Y_LSB (10)
+#define SMI130_MGA_FIFO_G_Y_MSB (11)
+#define SMI130_MGA_FIFO_G_Z_LSB (12)
+#define SMI130_MGA_FIFO_G_Z_MSB (13)
+#define SMI130_MGA_FIFO_A_X_LSB (14)
+#define SMI130_MGA_FIFO_A_X_MSB (15)
+#define SMI130_MGA_FIFO_A_Y_LSB (16)
+#define SMI130_MGA_FIFO_A_Y_MSB (17)
+#define SMI130_MGA_FIFO_A_Z_LSB (18)
+#define SMI130_MGA_FIFO_A_Z_MSB (19)
+/* FIFO mag definition*/
+#define SMI130_MA_FIFO_M_X_LSB (0)
+#define SMI130_MA_FIFO_M_X_MSB (1)
+#define SMI130_MA_FIFO_M_Y_LSB (2)
+#define SMI130_MA_FIFO_M_Y_MSB (3)
+#define SMI130_MA_FIFO_M_Z_LSB (4)
+#define SMI130_MA_FIFO_M_Z_MSB (5)
+#define SMI130_MA_FIFO_M_R_LSB (6)
+#define SMI130_MA_FIFO_M_R_MSB (7)
+#define SMI130_MA_FIFO_A_X_LSB (8)
+#define SMI130_MA_FIFO_A_X_MSB (9)
+#define SMI130_MA_FIFO_A_Y_LSB (10)
+#define SMI130_MA_FIFO_A_Y_MSB (11)
+#define SMI130_MA_FIFO_A_Z_LSB (12)
+#define SMI130_MA_FIFO_A_Z_MSB (13)
+/* FIFO mag/gyro definition*/
+#define SMI130_MG_FIFO_M_X_LSB (0)
+#define SMI130_MG_FIFO_M_X_MSB (1)
+#define SMI130_MG_FIFO_M_Y_LSB (2)
+#define SMI130_MG_FIFO_M_Y_MSB (3)
+#define SMI130_MG_FIFO_M_Z_LSB (4)
+#define SMI130_MG_FIFO_M_Z_MSB (5)
+#define SMI130_MG_FIFO_M_R_LSB (6)
+#define SMI130_MG_FIFO_M_R_MSB (7)
+#define SMI130_MG_FIFO_G_X_LSB (8)
+#define SMI130_MG_FIFO_G_X_MSB (9)
+#define SMI130_MG_FIFO_G_Y_LSB (10)
+#define SMI130_MG_FIFO_G_Y_MSB (11)
+#define SMI130_MG_FIFO_G_Z_LSB (12)
+#define SMI130_MG_FIFO_G_Z_MSB (13)
+/* FIFO length definitions*/
+#define SMI130_FIFO_SENSOR_TIME_LSB (0)
+#define SMI130_FIFO_SENSOR_TIME_XLSB (1)
+#define SMI130_FIFO_SENSOR_TIME_MSB (2)
+#define SMI130_FIFO_SENSOR_TIME_LENGTH (3)
+#define SMI130_FIFO_A_LENGTH (6)
+#define SMI130_FIFO_G_LENGTH (6)
+#define SMI130_FIFO_M_LENGTH (8)
+#define SMI130_FIFO_AG_LENGTH (12)
+#define SMI130_FIFO_AMG_LENGTH (20)
+#define SMI130_FIFO_MA_OR_MG_LENGTH (14)
+
+/* bus read and write length for mag, accel and gyro*/
+#define SMI130_MAG_X_DATA_LENGTH (2)
+#define SMI130_MAG_Y_DATA_LENGTH (2)
+#define SMI130_MAG_Z_DATA_LENGTH (2)
+#define SMI130_MAG_R_DATA_LENGTH (2)
+#define SMI130_MAG_XYZ_DATA_LENGTH (6)
+#define SMI130_MAG_XYZR_DATA_LENGTH (8)
+#define SMI130_MAG_YAS_DATA_LENGTH (8)
+#define SMI130_GYRO_DATA_LENGTH (2)
+#define SMI130_GYRO_XYZ_DATA_LENGTH (6)
+#define SMI130_ACCEL_DATA_LENGTH (2)
+#define SMI130_ACCEL_XYZ_DATA_LENGTH (6)
+#define SMI130_TEMP_DATA_LENGTH (2)
+#define SMI130_FIFO_DATA_LENGTH (2)
+#define SMI130_STEP_COUNTER_LENGTH (2)
+#define SMI130_SENSOR_TIME_LENGTH (3)
+
+/* Delay definitions*/
+#define SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY (5)
+#define SMI130_BMM150_WAKEUP_DELAY1 (2)
+#define SMI130_BMM150_WAKEUP_DELAY2 (3)
+#define SMI130_BMM150_WAKEUP_DELAY3 (1)
+#define SMI130_YAS532_OFFSET_DELAY (2)
+#define SMI130_GEN_READ_WRITE_DELAY (1)
+#define SMI130_YAS532_MEASUREMENT_DELAY (25)
+#define SMI130_YAS_ACQ_COMMAND_DELAY (50)
+#define SMI130_YAS532_SET_INITIAL_VALUE_DELAY (200)
+#define SMI130_AKM_INIT_DELAY (60)
+/****************************************************/
+/**\name ARRAY SIZE DEFINITIONS */
+/***************************************************/
+#define SMI130_ACCEL_X_DATA_SIZE (2)
+#define SMI130_ACCEL_Y_DATA_SIZE (2)
+#define SMI130_ACCEL_Z_DATA_SIZE (2)
+#define SMI130_ACCEL_XYZ_DATA_SIZE (6)
+
+#define SMI130_GYRO_X_DATA_SIZE (2)
+#define SMI130_GYRO_Y_DATA_SIZE (2)
+#define SMI130_GYRO_Z_DATA_SIZE (2)
+#define SMI130_GYRO_XYZ_DATA_SIZE (6)
+
+#define SMI130_MAG_X_DATA_SIZE (2)
+#define SMI130_MAG_Y_DATA_SIZE (2)
+#define SMI130_MAG_Z_DATA_SIZE (2)
+#define SMI130_MAG_R_DATA_SIZE (2)
+#define SMI130_MAG_XYZ_DATA_SIZE (6)
+#define SMI130_MAG_XYZR_DATA_SIZE (8)
+#define SMI130_MAG_TRIM_DATA_SIZE (16)
+
+
+#define SMI130_TEMP_DATA_SIZE (2)
+#define SMI130_FIFO_DATA_SIZE (2)
+#define SMI130_STEP_COUNT_DATA_SIZE (2)
+
+#define SMI130_SENSOR_TIME_DATA_SIZE (3)
+#define SMI130_AKM_SENSITIVITY_DATA_SIZE (3)
+#define SMI130_HARD_OFFSET_DATA_SIZE (3)
+#define SMI130_YAS_XY1Y2_DATA_SIZE (3)
+#define SMI130_YAS_FLAG_DATA_SIZE (3)
+#define SMI130_YAS_TEMP_DATA_SIZE (3)
+#define SMI130_YAS_H_DATA_SIZE (3)
+#define SMI130_YAS_S_DATA_SIZE (3)
+#define SMI130_YAS_CORRECT_DATA_SIZE (5)
+#define SMI130_YAS_XY1Y2T_DATA_SIZE (8)
+#define SMI130_YAS537_CALIB_DATA_SIZE (17)
+#define SMI130_YAS532_CALIB_DATA_SIZE (14)
+/****************************************************/
+/**\name ARRAY PARAMETER DEFINITIONS */
+/***************************************************/
+#define SMI130_SENSOR_TIME_MSB_BYTE (2)
+#define SMI130_SENSOR_TIME_XLSB_BYTE (1)
+#define SMI130_SENSOR_TIME_LSB_BYTE (0)
+
+#define SMI130_MAG_X_LSB_BYTE (0)
+#define SMI130_MAG_X_MSB_BYTE (1)
+#define SMI130_MAG_Y_LSB_BYTE (0)
+#define SMI130_MAG_Y_MSB_BYTE (1)
+#define SMI130_MAG_Z_LSB_BYTE (0)
+#define SMI130_MAG_Z_MSB_BYTE (1)
+#define SMI130_MAG_R_LSB_BYTE (0)
+#define SMI130_MAG_R_MSB_BYTE (1)
+#define SMI130_DATA_FRAME_MAG_X_LSB_BYTE (0)
+#define SMI130_DATA_FRAME_MAG_X_MSB_BYTE (1)
+#define SMI130_DATA_FRAME_MAG_Y_LSB_BYTE (2)
+#define SMI130_DATA_FRAME_MAG_Y_MSB_BYTE (3)
+#define SMI130_DATA_FRAME_MAG_Z_LSB_BYTE (4)
+#define SMI130_DATA_FRAME_MAG_Z_MSB_BYTE (5)
+#define SMI130_DATA_FRAME_MAG_R_LSB_BYTE (6)
+#define SMI130_DATA_FRAME_MAG_R_MSB_BYTE (7)
+
+#define SMI130_GYRO_X_LSB_BYTE (0)
+#define SMI130_GYRO_X_MSB_BYTE (1)
+#define SMI130_GYRO_Y_LSB_BYTE (0)
+#define SMI130_GYRO_Y_MSB_BYTE (1)
+#define SMI130_GYRO_Z_LSB_BYTE (0)
+#define SMI130_GYRO_Z_MSB_BYTE (1)
+#define SMI130_DATA_FRAME_GYRO_X_LSB_BYTE (0)
+#define SMI130_DATA_FRAME_GYRO_X_MSB_BYTE (1)
+#define SMI130_DATA_FRAME_GYRO_Y_LSB_BYTE (2)
+#define SMI130_DATA_FRAME_GYRO_Y_MSB_BYTE (3)
+#define SMI130_DATA_FRAME_GYRO_Z_LSB_BYTE (4)
+#define SMI130_DATA_FRAME_GYRO_Z_MSB_BYTE (5)
+
+#define SMI130_ACCEL_X_LSB_BYTE (0)
+#define SMI130_ACCEL_X_MSB_BYTE (1)
+#define SMI130_ACCEL_Y_LSB_BYTE (0)
+#define SMI130_ACCEL_Y_MSB_BYTE (1)
+#define SMI130_ACCEL_Z_LSB_BYTE (0)
+#define SMI130_ACCEL_Z_MSB_BYTE (1)
+#define SMI130_DATA_FRAME_ACCEL_X_LSB_BYTE (0)
+#define SMI130_DATA_FRAME_ACCEL_X_MSB_BYTE (1)
+#define SMI130_DATA_FRAME_ACCEL_Y_LSB_BYTE (2)
+#define SMI130_DATA_FRAME_ACCEL_Y_MSB_BYTE (3)
+#define SMI130_DATA_FRAME_ACCEL_Z_LSB_BYTE (4)
+#define SMI130_DATA_FRAME_ACCEL_Z_MSB_BYTE (5)
+
+#define SMI130_TEMP_LSB_BYTE (0)
+#define SMI130_TEMP_MSB_BYTE (1)
+
+#define SMI130_FIFO_LENGTH_LSB_BYTE (0)
+#define SMI130_FIFO_LENGTH_MSB_BYTE (1)
+
+#define SMI130_STEP_COUNT_LSB_BYTE (0)
+#define SMI130_STEP_COUNT_MSB_BYTE (1)
+/****************************************************/
+/**\name ERROR CODES */
+/***************************************************/
+
+#define E_SMI130_NULL_PTR ((s8)-127)
+#define E_SMI130_COMM_RES ((s8)-1)
+#define E_SMI130_OUT_OF_RANGE ((s8)-2)
+#define E_SMI130_BUSY ((s8)-3)
+#define SUCCESS ((u8)0)
+#define ERROR ((s8)-1)
+
+/* Constants */
+#define SMI130_NULL (0)
+#define SMI130_DELAY_SETTLING_TIME (5)
+/*This refers SMI130 return type as s8 */
+#define SMI130_RETURN_FUNCTION_TYPE s8
+/****************************************************/
+/**\name REGISTER DEFINITIONS */
+/***************************************************/
+/*******************/
+/**\name CHIP ID */
+/*******************/
+#define SMI130_USER_CHIP_ID_ADDR (0x00)
+/*******************/
+/**\name ERROR STATUS */
+/*******************/
+#define SMI130_USER_ERROR_ADDR (0X02)
+/*******************/
+/**\name POWER MODE STATUS */
+/*******************/
+#define SMI130_USER_PMU_STAT_ADDR (0X03)
+/*******************/
+/**\name MAG DATA REGISTERS */
+/*******************/
+#define SMI130_USER_DATA_0_ADDR (0X04)
+#define SMI130_USER_DATA_1_ADDR (0X05)
+#define SMI130_USER_DATA_2_ADDR (0X06)
+#define SMI130_USER_DATA_3_ADDR (0X07)
+#define SMI130_USER_DATA_4_ADDR (0X08)
+#define SMI130_USER_DATA_5_ADDR (0X09)
+#define SMI130_USER_DATA_6_ADDR (0X0A)
+#define SMI130_USER_DATA_7_ADDR (0X0B)
+/*******************/
+/**\name GYRO DATA REGISTERS */
+/*******************/
+#define SMI130_USER_DATA_8_ADDR (0X0C)
+#define SMI130_USER_DATA_9_ADDR (0X0D)
+#define SMI130_USER_DATA_10_ADDR (0X0E)
+#define SMI130_USER_DATA_11_ADDR (0X0F)
+#define SMI130_USER_DATA_12_ADDR (0X10)
+#define SMI130_USER_DATA_13_ADDR (0X11)
+#define SMI130_USER_DATA_14_ADDR (0X12)
+#define SMI130_USER_DATA_15_ADDR (0X13)
+/*******************/
+/**\name ACCEL DATA REGISTERS */
+/*******************/
+#define SMI130_USER_DATA_16_ADDR (0X14)
+#define SMI130_USER_DATA_17_ADDR (0X15)
+#define SMI130_USER_DATA_18_ADDR (0X16)
+#define SMI130_USER_DATA_19_ADDR (0X17)
+/*******************/
+/**\name SENSOR TIME REGISTERS */
+/*******************/
+#define SMI130_USER_SENSORTIME_0_ADDR (0X18)
+#define SMI130_USER_SENSORTIME_1_ADDR (0X19)
+#define SMI130_USER_SENSORTIME_2_ADDR (0X1A)
+/*******************/
+/**\name STATUS REGISTER FOR SENSOR STATUS FLAG */
+/*******************/
+#define SMI130_USER_STAT_ADDR (0X1B)
+/*******************/
+/**\name INTERRUPY STATUS REGISTERS */
+/*******************/
+#define SMI130_USER_INTR_STAT_0_ADDR (0X1C)
+#define SMI130_USER_INTR_STAT_1_ADDR (0X1D)
+#define SMI130_USER_INTR_STAT_2_ADDR (0X1E)
+#define SMI130_USER_INTR_STAT_3_ADDR (0X1F)
+/*******************/
+/**\name TEMPERATURE REGISTERS */
+/*******************/
+#define SMI130_USER_TEMPERATURE_0_ADDR (0X20)
+#define SMI130_USER_TEMPERATURE_1_ADDR (0X21)
+/*******************/
+/**\name FIFO REGISTERS */
+/*******************/
+#define SMI130_USER_FIFO_LENGTH_0_ADDR (0X22)
+#define SMI130_USER_FIFO_LENGTH_1_ADDR (0X23)
+#define SMI130_USER_FIFO_DATA_ADDR (0X24)
+/***************************************************/
+/**\name ACCEL CONFIG REGISTERS FOR ODR, BANDWIDTH AND UNDERSAMPLING*/
+/******************************************************/
+#define SMI130_USER_ACCEL_CONFIG_ADDR (0X40)
+/*******************/
+/**\name ACCEL RANGE */
+/*******************/
+#define SMI130_USER_ACCEL_RANGE_ADDR (0X41)
+/***************************************************/
+/**\name GYRO CONFIG REGISTERS FOR ODR AND BANDWIDTH */
+/******************************************************/
+#define SMI130_USER_GYRO_CONFIG_ADDR (0X42)
+/*******************/
+/**\name GYRO RANGE */
+/*******************/
+#define SMI130_USER_GYRO_RANGE_ADDR (0X43)
+/***************************************************/
+/**\name MAG CONFIG REGISTERS FOR ODR*/
+/******************************************************/
+#define SMI130_USER_MAG_CONFIG_ADDR (0X44)
+/***************************************************/
+/**\name REGISTER FOR GYRO AND ACCEL DOWNSAMPLING RATES FOR FIFO*/
+/******************************************************/
+#define SMI130_USER_FIFO_DOWN_ADDR (0X45)
+/***************************************************/
+/**\name FIFO CONFIG REGISTERS*/
+/******************************************************/
+#define SMI130_USER_FIFO_CONFIG_0_ADDR (0X46)
+#define SMI130_USER_FIFO_CONFIG_1_ADDR (0X47)
+/***************************************************/
+/**\name MAG INTERFACE REGISTERS*/
+/******************************************************/
+#define SMI130_USER_MAG_IF_0_ADDR (0X4B)
+#define SMI130_USER_MAG_IF_1_ADDR (0X4C)
+#define SMI130_USER_MAG_IF_2_ADDR (0X4D)
+#define SMI130_USER_MAG_IF_3_ADDR (0X4E)
+#define SMI130_USER_MAG_IF_4_ADDR (0X4F)
+/***************************************************/
+/**\name INTERRUPT ENABLE REGISTERS*/
+/******************************************************/
+#define SMI130_USER_INTR_ENABLE_0_ADDR (0X50)
+#define SMI130_USER_INTR_ENABLE_1_ADDR (0X51)
+#define SMI130_USER_INTR_ENABLE_2_ADDR (0X52)
+#define SMI130_USER_INTR_OUT_CTRL_ADDR (0X53)
+/***************************************************/
+/**\name LATCH DURATION REGISTERS*/
+/******************************************************/
+#define SMI130_USER_INTR_LATCH_ADDR (0X54)
+/***************************************************/
+/**\name MAP INTERRUPT 1 and 2 REGISTERS*/
+/******************************************************/
+#define SMI130_USER_INTR_MAP_0_ADDR (0X55)
+#define SMI130_USER_INTR_MAP_1_ADDR (0X56)
+#define SMI130_USER_INTR_MAP_2_ADDR (0X57)
+/***************************************************/
+/**\name DATA SOURCE REGISTERS*/
+/******************************************************/
+#define SMI130_USER_INTR_DATA_0_ADDR (0X58)
+#define SMI130_USER_INTR_DATA_1_ADDR (0X59)
+/***************************************************/
+/**\name
+INTERRUPT THRESHOLD, HYSTERESIS, DURATION, MODE CONFIGURATION REGISTERS*/
+/******************************************************/
+#define SMI130_USER_INTR_LOWHIGH_0_ADDR (0X5A)
+#define SMI130_USER_INTR_LOWHIGH_1_ADDR (0X5B)
+#define SMI130_USER_INTR_LOWHIGH_2_ADDR (0X5C)
+#define SMI130_USER_INTR_LOWHIGH_3_ADDR (0X5D)
+#define SMI130_USER_INTR_LOWHIGH_4_ADDR (0X5E)
+#define SMI130_USER_INTR_MOTION_0_ADDR (0X5F)
+#define SMI130_USER_INTR_MOTION_1_ADDR (0X60)
+#define SMI130_USER_INTR_MOTION_2_ADDR (0X61)
+#define SMI130_USER_INTR_MOTION_3_ADDR (0X62)
+#define SMI130_USER_INTR_TAP_0_ADDR (0X63)
+#define SMI130_USER_INTR_TAP_1_ADDR (0X64)
+#define SMI130_USER_INTR_ORIENT_0_ADDR (0X65)
+#define SMI130_USER_INTR_ORIENT_1_ADDR (0X66)
+#define SMI130_USER_INTR_FLAT_0_ADDR (0X67)
+#define SMI130_USER_INTR_FLAT_1_ADDR (0X68)
+/***************************************************/
+/**\name FAST OFFSET CONFIGURATION REGISTER*/
+/******************************************************/
+#define SMI130_USER_FOC_CONFIG_ADDR (0X69)
+/***************************************************/
+/**\name MISCELLANEOUS CONFIGURATION REGISTER*/
+/******************************************************/
+#define SMI130_USER_CONFIG_ADDR (0X6A)
+/***************************************************/
+/**\name SERIAL INTERFACE SETTINGS REGISTER*/
+/******************************************************/
+#define SMI130_USER_IF_CONFIG_ADDR (0X6B)
+/***************************************************/
+/**\name GYRO POWER MODE TRIGGER REGISTER */
+/******************************************************/
+#define SMI130_USER_PMU_TRIGGER_ADDR (0X6C)
+/***************************************************/
+/**\name SELF_TEST REGISTER*/
+/******************************************************/
+#define SMI130_USER_SELF_TEST_ADDR (0X6D)
+/***************************************************/
+/**\name SPI,I2C SELECTION REGISTER*/
+/******************************************************/
+#define SMI130_USER_NV_CONFIG_ADDR (0x70)
+/***************************************************/
+/**\name ACCEL AND GYRO OFFSET REGISTERS*/
+/******************************************************/
+#define SMI130_USER_OFFSET_0_ADDR (0X71)
+#define SMI130_USER_OFFSET_1_ADDR (0X72)
+#define SMI130_USER_OFFSET_2_ADDR (0X73)
+#define SMI130_USER_OFFSET_3_ADDR (0X74)
+#define SMI130_USER_OFFSET_4_ADDR (0X75)
+#define SMI130_USER_OFFSET_5_ADDR (0X76)
+#define SMI130_USER_OFFSET_6_ADDR (0X77)
+/***************************************************/
+/**\name STEP COUNTER INTERRUPT REGISTERS*/
+/******************************************************/
+#define SMI130_USER_STEP_COUNT_0_ADDR (0X78)
+#define SMI130_USER_STEP_COUNT_1_ADDR (0X79)
+/***************************************************/
+/**\name STEP COUNTER CONFIGURATION REGISTERS*/
+/******************************************************/
+#define SMI130_USER_STEP_CONFIG_0_ADDR (0X7A)
+#define SMI130_USER_STEP_CONFIG_1_ADDR (0X7B)
+/***************************************************/
+/**\name COMMAND REGISTER*/
+/******************************************************/
+#define SMI130_CMD_COMMANDS_ADDR (0X7E)
+/***************************************************/
+/**\name PAGE REGISTERS*/
+/******************************************************/
+#define SMI130_CMD_EXT_MODE_ADDR (0X7F)
+#define SMI130_COM_C_TRIM_FIVE_ADDR (0X05)
+
+/****************************************************/
+/**\name SHIFT VALUE DEFINITION */
+/***************************************************/
+#define SMI130_SHIFT_BIT_POSITION_BY_01_BIT (1)
+#define SMI130_SHIFT_BIT_POSITION_BY_02_BITS (2)
+#define SMI130_SHIFT_BIT_POSITION_BY_03_BITS (3)
+#define SMI130_SHIFT_BIT_POSITION_BY_04_BITS (4)
+#define SMI130_SHIFT_BIT_POSITION_BY_05_BITS (5)
+#define SMI130_SHIFT_BIT_POSITION_BY_06_BITS (6)
+#define SMI130_SHIFT_BIT_POSITION_BY_07_BITS (7)
+#define SMI130_SHIFT_BIT_POSITION_BY_08_BITS (8)
+#define SMI130_SHIFT_BIT_POSITION_BY_09_BITS (9)
+#define SMI130_SHIFT_BIT_POSITION_BY_12_BITS (12)
+#define SMI130_SHIFT_BIT_POSITION_BY_13_BITS (13)
+#define SMI130_SHIFT_BIT_POSITION_BY_14_BITS (14)
+#define SMI130_SHIFT_BIT_POSITION_BY_15_BITS (15)
+#define SMI130_SHIFT_BIT_POSITION_BY_16_BITS (16)
+
+/****************************************************/
+/**\name DEFINITIONS USED FOR YAMAHA-YAS532 */
+/***************************************************/
+#define YAS532_MAG_STATE_NORMAL (0)
+#define YAS532_MAG_STATE_INIT_COIL (1)
+#define YAS532_MAG_STATE_MEASURE_OFFSET (2)
+#define YAS532_MAG_INITCOIL_TIMEOUT (1000)
+#define YAS532_MAG_NOTRANS_POSITION (3)
+#define YAS532_DEFAULT_SENSOR_DELAY (50)
+#define YAS532_DATA_OVERFLOW (8190)
+#define YAS532_DATA_UNDERFLOW (0)
+#define YAS532_MAG_LOG (20)
+#define YAS532_MAG_TEMPERATURE_LOG (10)
+#define YAS532_TEMP20DEGREE_TYPICAL (390)
+#define YAS532_VERSION_AC_COEF_X (850)
+#define YAS532_VERSION_AC_COEF_Y1 (750)
+#define YAS532_VERSION_AC_COEF_Y2 (750)
+#define YAS532_DATA_CENTER (4096)
+/****************************************************/
+/**\name YAMAHA-YAS532 OFFSET DEFINITION */
+/***************************************************/
+static const s8 INVALID_OFFSET[] = {0x7f, 0x7f, 0x7f};
+#define set_vector(to, from) \
+ {int _l; for (_l = 0; _l < 3; _l++) (to)[_l] = (from)[_l]; }
+#define is_valid_offset(a) \
+ (((a)[0] <= 31) && ((a)[1] <= 31) && ((a)[2] <= 31) \
+ && (-31 <= (a)[0]) && (-31 <= (a)[1]) && (-31 <= (a)[2]))
+
+/**************************************************/
+/**\name YAS532 CALIB DATA DEFINITIONS */
+/*************************************************/
+
+
+/* register address of YAS532*/
+#define SMI130_YAS532_TESTR1 (0x88)
+#define SMI130_YAS532_TESTR2 (0x89)
+#define SMI130_YAS532_RCOIL (0x81)
+#define SMI130_YAS532_COMMAND_REGISTER (0x82)
+#define SMI130_YAS532_DATA_REGISTER (0xB0)
+/* calib data register definition*/
+#define SMI130_YAS532_CALIB_CX (0x90)
+#define SMI130_YAS532_CALIB_CY1 (0x91)
+#define SMI130_YAS532_CALIB_CY2 (0x92)
+#define SMI130_YAS532_CALIB1 (0x93)
+#define SMI130_YAS532_CALIB2 (0x94)
+#define SMI130_YAS532_CALIB3 (0x95)
+#define SMI130_YAS532_CALIB4 (0x96)
+#define SMI130_YAS532_CALIB5 (0x97)
+#define SMI130_YAS532_CLAIB6 (0x98)
+#define SMI130_YAS532_CALIB7 (0x99)
+#define SMI130_YAS532_CALIB8 (0x9A)
+#define SMI130_YAS532_CALIIB9 (0x9B)
+#define SMI130_YAS532_CALIB10 (0x9C)
+#define SMI130_YAS532_CALIB11 (0x9D)
+/* offset definition */
+#define SMI130_YAS532_OFFSET_X (0x85)
+#define SMI130_YAS532_OFFSET_Y (0x86)
+#define SMI130_YAS532_OFFSET_Z (0x87)
+/* data to write register for yas532*/
+#define SMI130_YAS532_WRITE_TESTR1 (0x00)
+#define SMI130_YAS532_WRITE_TESTR2 (0x00)
+#define SMI130_YAS532_WRITE_RCOIL (0x00)
+/**************************************************/
+/**\name YAS537 DEFINITION */
+/*************************************************/
+
+#define YAS537_SRSTR_DATA (0x02)
+#define YAS537_WRITE_A_D_CONVERTER (0x03)
+#define YAS537_WRITE_A_D_CONVERTER2 (0xF8)
+#define YAS537_WRITE_FILTER (0x08)
+#define YAS537_WRITE_CONFR (0x08)
+#define YAS537_WRITE_TEMP_CALIB (0xFF)
+#define YAS537_SET_COMMAND_REGISTER (0x01)
+
+/**************************************************/
+/**\name YAS537 REGISTER DEFINITION */
+/*************************************************/
+#define YAS537_REG_SRSTR (0x90)
+#define YAS537_REG_CALR_C0 (0xC0)
+#define YAS537_REG_CALR_C1 (0xC1)
+#define YAS537_REG_CALR_C2 (0xC2)
+#define YAS537_REG_CALR_C3 (0xC3)
+#define YAS537_REG_CALR_C4 (0xC4)
+#define YAS537_REG_CALR_C5 (0xC5)
+#define YAS537_REG_CALR_C6 (0xC6)
+#define YAS537_REG_CALR_C7 (0xC7)
+#define YAS537_REG_CALR_C8 (0xC8)
+#define YAS537_REG_CALR_C9 (0xC9)
+#define YAS537_REG_CALR_CA (0xCA)
+#define YAS537_REG_CALR_CB (0xCB)
+#define YAS537_REG_CALR_CC (0xCC)
+#define YAS537_REG_CALR_CD (0xCD)
+#define YAS537_REG_CALR_CE (0xCE)
+#define YAS537_REG_CALR_CF (0xCF)
+#define YAS537_REG_CALR_DO (0xD0)
+#define YAS537_REG_MTCR (0x93)
+#define YAS537_REG_CONFR (0x82)
+#define SMI130_REG_YAS537_CMDR (0x81)
+#define YAS537_REG_OXR (0x84)
+#define YAS537_REG_AVRR (0x87)
+#define YAS537_REG_HCKR (0x88)
+#define YAS537_REG_LCKR (0x89)
+#define YAS537_REG_ADCCALR (0x91)
+#define YAS537_REG_ADCCALR_ONE (0x92)
+#define YAS537_REG_OCR (0x9E)
+#define YAS537_REG_TRMR (0x9F)
+#define YAS537_REG_TEMPERATURE_0 (0xB0)
+#define YAS537_REG_TEMPERATURE_1 (0xB1)
+#define YAS537_REG_DATA_X_0 (0xB2)
+#define YAS537_REG_DATA_X_1 (0xB3)
+#define YAS537_REG_DATA_Y1_0 (0xB4)
+#define YAS537_REG_DATA_Y1_1 (0xB5)
+#define YAS537_REG_DATA_Y2_0 (0xB6)
+#define YAS537_REG_DATA_Y2_1 (0xB7)
+#define YAS537_MAG_STATE_NORMAL (0)
+#define YAS537_MAG_STATE_INIT_COIL (1)
+#define YAS537_MAG_STATE_RECORD_DATA (2)
+#define YAS537_DATA_UNDERFLOW (0)
+#define YAS537_DATA_OVERFLOW (16383)
+/****************************************************/
+/**\name YAS537_set vector */
+/***************************************************/
+#define yas537_set_vector(to, from) \
+ {int _l; for (_l = 0; _l < 3; _l++) (to)[_l] = (from)[_l]; }
+
+#ifndef ABS
+#define ABS(a) ((a) > 0 ? (a) : -(a)) /*!< Absolute value */
+#endif
+/****************************************************/
+/**\name AKM09911 AND AKM09912 DEFINITION */
+/***************************************************/
+#define AKM09912_SENSITIVITY_DIV (256)
+#define AKM09912_SENSITIVITY (128)
+#define AKM09911_SENSITIVITY_DIV (128)
+#define AKM_ASAX (0)
+#define AKM_ASAY (1)
+#define AKM_ASAZ (2)
+#define AKM_POWER_DOWN_MODE_DATA (0x00)
+#define AKM_FUSE_ROM_MODE (0x1F)
+#define AKM_POWER_MODE_REG (0x31)
+#define AKM_SINGLE_MEASUREMENT_MODE (0x01)
+#define AKM_DATA_REGISTER (0x11)
+/*! AKM09912 Register definition */
+#define AKM09912_CHIP_ID_REG (0x01)
+/****************************************************/
+/**\name BMM150 DEFINITION */
+/***************************************************/
+#define SMI130_BMM150_SET_POWER_CONTROL (0x01)
+#define SMI130_BMM150_MAX_RETRY_WAKEUP (5)
+#define SMI130_BMM150_POWER_ON (0x01)
+#define SMI130_BMM150_POWER_OFF (0x00)
+#define SMI130_BMM150_FORCE_MODE (0x02)
+#define SMI130_BMM150_POWER_ON_SUCCESS (0)
+#define SMI130_BMM150_POWER_ON_FAIL ((s8)-1)
+
+#define SMI130_BMM150_DIG_X1 (0)
+#define SMI130_BMM150_DIG_Y1 (1)
+#define SMI130_BMM150_DIG_X2 (2)
+#define SMI130_BMM150_DIG_Y3 (3)
+#define SMI130_BMM150_DIG_XY1 (4)
+#define SMI130_BMM150_DIG_XY2 (5)
+#define SMI130_BMM150_DIG_Z1_LSB (6)
+#define SMI130_BMM150_DIG_Z1_MSB (7)
+#define SMI130_BMM150_DIG_Z2_LSB (8)
+#define SMI130_BMM150_DIG_Z2_MSB (9)
+#define SMI130_BMM150_DIG_DIG_Z3_LSB (10)
+#define SMI130_BMM150_DIG_DIG_Z3_MSB (11)
+#define SMI130_BMM150_DIG_DIG_Z4_LSB (12)
+#define SMI130_BMM150_DIG_DIG_Z4_MSB (13)
+#define SMI130_BMM150_DIG_DIG_XYZ1_LSB (14)
+#define SMI130_BMM150_DIG_DIG_XYZ1_MSB (15)
+
+/**************************************************************/
+/**\name STRUCTURE DEFINITIONS */
+/**************************************************************/
+/*!
+* @brief smi130 structure
+* This structure holds all relevant information about smi130
+*/
+struct smi130_t {
+u8 chip_id;/**< chip id of SMI130 */
+u8 dev_addr;/**< device address of SMI130 */
+s8 mag_manual_enable;/**< used for check the mag manual/auto mode status */
+SMI130_WR_FUNC_PTR;/**< bus write function pointer */
+SMI130_RD_FUNC_PTR;/**< bus read function pointer */
+SMI130_BRD_FUNC_PTR;/**< burst write function pointer */
+void (*delay_msec)(SMI130_MDELAY_DATA_TYPE);/**< delay function pointer */
+};
+/*!
+ * @brief Structure containing bmm150 and akm09911
+ * magnetometer values for x,y and
+ * z-axis in s16
+ */
+struct smi130_mag_t {
+s16 x;/**< BMM150 and AKM09911 and AKM09912 X raw data*/
+s16 y;/**< BMM150 and AKM09911 and AKM09912 Y raw data*/
+s16 z;/**< BMM150 and AKM09911 and AKM09912 Z raw data*/
+};
+/*!
+ * @brief Structure containing bmm150 xyz data and temperature
+ */
+struct smi130_mag_xyzr_t {
+s16 x;/**< BMM150 X raw data*/
+s16 y;/**< BMM150 Y raw data*/
+s16 z;/**<BMM150 Z raw data*/
+u16 r;/**<BMM150 R raw data*/
+};
+/*!
+ * @brief Structure containing gyro xyz data
+ */
+struct smi130_gyro_t {
+s16 x;/**<gyro X data*/
+s16 y;/**<gyro Y data*/
+s16 z;/**<gyro Z data*/
+};
+/*!
+ * @brief Structure containing accel xyz data
+ */
+struct smi130_accel_t {
+s16 x;/**<accel X data*/
+s16 y;/**<accel Y data*/
+s16 z;/**<accel Z data*/
+};
+/*!
+ * @brief Structure bmm150 mag compensated data with s32 output
+ */
+struct smi130_mag_xyz_s32_t {
+s16 x;/**<BMM150 X compensated data*/
+s16 y;/**<BMM150 Y compensated data*/
+s16 z;/**<BMM150 Z compensated data*/
+};
+/*!
+ * @brief Structure bmm150 mag trim data
+ */
+struct trim_data_t {
+s8 dig_x1;/**<BMM150 trim x1 data*/
+s8 dig_y1;/**<BMM150 trim y1 data*/
+
+s8 dig_x2;/**<BMM150 trim x2 data*/
+s8 dig_y2;/**<BMM150 trim y2 data*/
+
+u16 dig_z1;/**<BMM150 trim z1 data*/
+s16 dig_z2;/**<BMM150 trim z2 data*/
+s16 dig_z3;/**<BMM150 trim z3 data*/
+s16 dig_z4;/**<BMM150 trim z4 data*/
+
+u8 dig_xy1;/**<BMM150 trim xy1 data*/
+s8 dig_xy2;/**<BMM150 trim xy2 data*/
+
+u16 dig_xyz1;/**<BMM150 trim xyz1 data*/
+};
+
+/*!
+* @brief Structure for reading AKM compensating data
+*/
+struct bosch_akm_sensitivity_data_t {
+u8 asax;/**<AKM09911 and AKM09912 X sensitivity data*/
+u8 asay;/**<AKM09911 and AKM09912 Y sensitivity data*/
+u8 asaz;/**<AKM09911 and AKM09912 Z sensitivity data*/
+};
+/*!
+* @brief YAMAHA-YAS532 struct
+* Calibration YAS532 data struct
+*/
+struct bosch_yas532_calib_data_t {
+s32 cx;/**<YAS532 calib cx data */
+s32 cy1;/**<YAS532 calib cy1 data */
+s32 cy2;/**<YAS532 calib cy2 data */
+s32 a2;/**<YAS532 calib a2 data */
+s32 a3;/**<YAS532 calib a3 data */
+s32 a4;/**<YAS532 calib a4 data */
+s32 a5;/**<YAS532 calib a5 data */
+s32 a6;/**<YAS532 calib a6 data */
+s32 a7;/**<YAS532 calib a7 data */
+s32 a8;/**<YAS532 calib a8 data */
+s32 a9;/**<YAS532 calib a9 data */
+s32 k;/**<YAS532 calib k data */
+s8 rxy1y2[3];/**<YAS532 calib rxy1y2 data */
+u8 fxy1y2[3];/**<YAS532 calib fxy1y2 data */
+};
+/*!
+* @brief YAS532 Temperature structure
+*/
+#if YAS532_MAG_LOG < YAS532_MAG_TEMPERATURE_LOG
+struct yas_temp_filter_t {
+u16 log[YAS532_MAG_TEMPERATURE_LOG];/**<YAS532 temp log array */
+u8 num;/**< used for increment the index */
+u8 idx;/**< used for increment the index */
+};
+#endif
+/*!
+* @brief YAS532 sensor initialization
+*/
+struct yas532_t {
+struct bosch_yas532_calib_data_t calib_yas532;/**< calib data */
+s8 measure_state;/**< update measure state */
+s8 v_hard_offset_s8[3];/**< offset write array*/
+s32 coef[3];/**< co efficient data */
+s8 overflow;/**< over flow condition check */
+u8 dev_id;/**< device id information */
+const s8 *transform;/**< transform condition check */
+#if YAS532_MAG_LOG < YAS532_MAG_TEMPERATURE_LOG
+struct yas_temp_filter_t temp_data;/**< temp data */
+#endif
+u16 last_raw[4];/**< raw data */
+};
+/*!
+* @brief Used for reading the YAS532 XYZ data
+*/
+struct yas532_vector {
+s32 yas532_vector_xyz[3];/**< YAS532 compensated xyz data*/
+};
+/**
+ * @struct yas_vector
+ * @brief Stores the sensor data
+ */
+struct yas_vector {
+ s32 yas537_vector_xyz[3]; /*!< vector data */
+};
+/*!
+* @brief YAMAHA-YAS532 struct
+* Calibration YAS532 data struct
+*/
+struct bosch_yas537_calib_data_t {
+s8 a2;/**<YAS532 calib a2 data */
+s8 a3;/**<YAS532 calib a3 data */
+s8 a4;/**<YAS532 calib a4 data */
+s16 a5;/**<YAS532 calib a5 data */
+s8 a6;/**<YAS532 calib a6 data */
+s8 a7;/**<YAS532 calib a7 data */
+s8 a8;/**<YAS532 calib a8 data */
+s16 a9;/**<YAS532 calib a9 data */
+u8 k;/**<YAS532 calib k data */
+u8 ver;/**<YAS532 calib ver data*/
+};
+/*!
+* @brief YAS537 sensor initialization
+*/
+struct yas537_t {
+struct bosch_yas537_calib_data_t calib_yas537;/**< calib data */
+s8 measure_state;/**< update measure state */
+s8 hard_offset[3];/**< offset write array*/
+u16 last_after_rcoil[3];/**< rcoil write array*/
+s32 coef[3];/**< co efficient data */
+s8 overflow;/**< over flow condition check */
+u8 dev_id;/**< device id information */
+u8 average;/**<average selection for offset configuration*/
+const s8 *transform;/**< transform condition check */
+u16 last_raw[4];/**< raw data */
+struct yas_vector xyz; /*!< X, Y, Z measurement data of the sensor */
+};
+/**************************************************************/
+/**\name USER DATA REGISTERS DEFINITION START */
+/**************************************************************/
+
+/**************************************************************/
+/**\name CHIP ID LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* Chip ID Description - Reg Addr --> (0x00), Bit --> 0...7 */
+#define SMI130_USER_CHIP_ID__POS (0)
+#define SMI130_USER_CHIP_ID__MSK (0xFF)
+#define SMI130_USER_CHIP_ID__LEN (8)
+#define SMI130_USER_CHIP_ID__REG (SMI130_USER_CHIP_ID_ADDR)
+/**************************************************************/
+/**\name ERROR STATUS LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* Error Description - Reg Addr --> (0x02), Bit --> 0 */
+#define SMI130_USER_ERR_STAT__POS (0)
+#define SMI130_USER_ERR_STAT__LEN (8)
+#define SMI130_USER_ERR_STAT__MSK (0xFF)
+#define SMI130_USER_ERR_STAT__REG (SMI130_USER_ERROR_ADDR)
+
+#define SMI130_USER_FATAL_ERR__POS (0)
+#define SMI130_USER_FATAL_ERR__LEN (1)
+#define SMI130_USER_FATAL_ERR__MSK (0x01)
+#define SMI130_USER_FATAL_ERR__REG (SMI130_USER_ERROR_ADDR)
+
+/* Error Description - Reg Addr --> (0x02), Bit --> 1...4 */
+#define SMI130_USER_ERR_CODE__POS (1)
+#define SMI130_USER_ERR_CODE__LEN (4)
+#define SMI130_USER_ERR_CODE__MSK (0x1E)
+#define SMI130_USER_ERR_CODE__REG (SMI130_USER_ERROR_ADDR)
+
+/* Error Description - Reg Addr --> (0x02), Bit --> 5 */
+#define SMI130_USER_I2C_FAIL_ERR__POS (5)
+#define SMI130_USER_I2C_FAIL_ERR__LEN (1)
+#define SMI130_USER_I2C_FAIL_ERR__MSK (0x20)
+#define SMI130_USER_I2C_FAIL_ERR__REG (SMI130_USER_ERROR_ADDR)
+
+/* Error Description - Reg Addr --> (0x02), Bit --> 6 */
+#define SMI130_USER_DROP_CMD_ERR__POS (6)
+#define SMI130_USER_DROP_CMD_ERR__LEN (1)
+#define SMI130_USER_DROP_CMD_ERR__MSK (0x40)
+#define SMI130_USER_DROP_CMD_ERR__REG (SMI130_USER_ERROR_ADDR)
+/**************************************************************/
+/**\name MAG DATA READY LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* Error Description - Reg Addr --> (0x02), Bit --> 7 */
+#define SMI130_USER_MAG_DADA_RDY_ERR__POS (7)
+#define SMI130_USER_MAG_DADA_RDY_ERR__LEN (1)
+#define SMI130_USER_MAG_DADA_RDY_ERR__MSK (0x80)
+#define SMI130_USER_MAG_DADA_RDY_ERR__REG (SMI130_USER_ERROR_ADDR)
+/**************************************************************/
+/**\name MAG POWER MODE LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* PMU_Status Description of MAG - Reg Addr --> (0x03), Bit --> 1..0 */
+#define SMI130_USER_MAG_POWER_MODE_STAT__POS (0)
+#define SMI130_USER_MAG_POWER_MODE_STAT__LEN (2)
+#define SMI130_USER_MAG_POWER_MODE_STAT__MSK (0x03)
+#define SMI130_USER_MAG_POWER_MODE_STAT__REG \
+(SMI130_USER_PMU_STAT_ADDR)
+/**************************************************************/
+/**\name GYRO POWER MODE LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* PMU_Status Description of GYRO - Reg Addr --> (0x03), Bit --> 3...2 */
+#define SMI130_USER_GYRO_POWER_MODE_STAT__POS (2)
+#define SMI130_USER_GYRO_POWER_MODE_STAT__LEN (2)
+#define SMI130_USER_GYRO_POWER_MODE_STAT__MSK (0x0C)
+#define SMI130_USER_GYRO_POWER_MODE_STAT__REG \
+(SMI130_USER_PMU_STAT_ADDR)
+/**************************************************************/
+/**\name ACCEL POWER MODE LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* PMU_Status Description of ACCEL - Reg Addr --> (0x03), Bit --> 5...4 */
+#define SMI130_USER_ACCEL_POWER_MODE_STAT__POS (4)
+#define SMI130_USER_ACCEL_POWER_MODE_STAT__LEN (2)
+#define SMI130_USER_ACCEL_POWER_MODE_STAT__MSK (0x30)
+#define SMI130_USER_ACCEL_POWER_MODE_STAT__REG \
+(SMI130_USER_PMU_STAT_ADDR)
+/**************************************************************/
+/**\name MAG DATA XYZ LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* Mag_X(LSB) Description - Reg Addr --> (0x04), Bit --> 0...7 */
+#define SMI130_USER_DATA_0_MAG_X_LSB__POS (0)
+#define SMI130_USER_DATA_0_MAG_X_LSB__LEN (8)
+#define SMI130_USER_DATA_0_MAG_X_LSB__MSK (0xFF)
+#define SMI130_USER_DATA_0_MAG_X_LSB__REG (SMI130_USER_DATA_0_ADDR)
+
+/* Mag_X(LSB) Description - Reg Addr --> (0x04), Bit --> 3...7 */
+#define SMI130_USER_DATA_MAG_X_LSB__POS (3)
+#define SMI130_USER_DATA_MAG_X_LSB__LEN (5)
+#define SMI130_USER_DATA_MAG_X_LSB__MSK (0xF8)
+#define SMI130_USER_DATA_MAG_X_LSB__REG (SMI130_USER_DATA_0_ADDR)
+
+/* Mag_X(MSB) Description - Reg Addr --> (0x05), Bit --> 0...7 */
+#define SMI130_USER_DATA_1_MAG_X_MSB__POS (0)
+#define SMI130_USER_DATA_1_MAG_X_MSB__LEN (8)
+#define SMI130_USER_DATA_1_MAG_X_MSB__MSK (0xFF)
+#define SMI130_USER_DATA_1_MAG_X_MSB__REG (SMI130_USER_DATA_1_ADDR)
+
+/* Mag_Y(LSB) Description - Reg Addr --> (0x06), Bit --> 0...7 */
+#define SMI130_USER_DATA_2_MAG_Y_LSB__POS (0)
+#define SMI130_USER_DATA_2_MAG_Y_LSB__LEN (8)
+#define SMI130_USER_DATA_2_MAG_Y_LSB__MSK (0xFF)
+#define SMI130_USER_DATA_2_MAG_Y_LSB__REG (SMI130_USER_DATA_2_ADDR)
+
+/* Mag_Y(LSB) Description - Reg Addr --> (0x06), Bit --> 3...7 */
+#define SMI130_USER_DATA_MAG_Y_LSB__POS (3)
+#define SMI130_USER_DATA_MAG_Y_LSB__LEN (5)
+#define SMI130_USER_DATA_MAG_Y_LSB__MSK (0xF8)
+#define SMI130_USER_DATA_MAG_Y_LSB__REG (SMI130_USER_DATA_2_ADDR)
+
+/* Mag_Y(MSB) Description - Reg Addr --> (0x07), Bit --> 0...7 */
+#define SMI130_USER_DATA_3_MAG_Y_MSB__POS (0)
+#define SMI130_USER_DATA_3_MAG_Y_MSB__LEN (8)
+#define SMI130_USER_DATA_3_MAG_Y_MSB__MSK (0xFF)
+#define SMI130_USER_DATA_3_MAG_Y_MSB__REG (SMI130_USER_DATA_3_ADDR)
+
+/* Mag_Z(LSB) Description - Reg Addr --> (0x08), Bit --> 0...7 */
+#define SMI130_USER_DATA_4_MAG_Z_LSB__POS (0)
+#define SMI130_USER_DATA_4_MAG_Z_LSB__LEN (8)
+#define SMI130_USER_DATA_4_MAG_Z_LSB__MSK (0xFF)
+#define SMI130_USER_DATA_4_MAG_Z_LSB__REG (SMI130_USER_DATA_4_ADDR)
+
+/* Mag_X(LSB) Description - Reg Addr --> (0x08), Bit --> 3...7 */
+#define SMI130_USER_DATA_MAG_Z_LSB__POS (1)
+#define SMI130_USER_DATA_MAG_Z_LSB__LEN (7)
+#define SMI130_USER_DATA_MAG_Z_LSB__MSK (0xFE)
+#define SMI130_USER_DATA_MAG_Z_LSB__REG (SMI130_USER_DATA_4_ADDR)
+
+/* Mag_Z(MSB) Description - Reg Addr --> (0x09), Bit --> 0...7 */
+#define SMI130_USER_DATA_5_MAG_Z_MSB__POS (0)
+#define SMI130_USER_DATA_5_MAG_Z_MSB__LEN (8)
+#define SMI130_USER_DATA_5_MAG_Z_MSB__MSK (0xFF)
+#define SMI130_USER_DATA_5_MAG_Z_MSB__REG (SMI130_USER_DATA_5_ADDR)
+
+/* RHALL(LSB) Description - Reg Addr --> (0x0A), Bit --> 0...7 */
+#define SMI130_USER_DATA_6_RHALL_LSB__POS (0)
+#define SMI130_USER_DATA_6_RHALL_LSB__LEN (8)
+#define SMI130_USER_DATA_6_RHALL_LSB__MSK (0xFF)
+#define SMI130_USER_DATA_6_RHALL_LSB__REG (SMI130_USER_DATA_6_ADDR)
+
+/* Mag_R(LSB) Description - Reg Addr --> (0x0A), Bit --> 3...7 */
+#define SMI130_USER_DATA_MAG_R_LSB__POS (2)
+#define SMI130_USER_DATA_MAG_R_LSB__LEN (6)
+#define SMI130_USER_DATA_MAG_R_LSB__MSK (0xFC)
+#define SMI130_USER_DATA_MAG_R_LSB__REG (SMI130_USER_DATA_6_ADDR)
+
+/* RHALL(MSB) Description - Reg Addr --> (0x0B), Bit --> 0...7 */
+#define SMI130_USER_DATA_7_RHALL_MSB__POS (0)
+#define SMI130_USER_DATA_7_RHALL_MSB__LEN (8)
+#define SMI130_USER_DATA_7_RHALL_MSB__MSK (0xFF)
+#define SMI130_USER_DATA_7_RHALL_MSB__REG (SMI130_USER_DATA_7_ADDR)
+/**************************************************************/
+/**\name GYRO DATA XYZ LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* GYR_X (LSB) Description - Reg Addr --> (0x0C), Bit --> 0...7 */
+#define SMI130_USER_DATA_8_GYRO_X_LSB__POS (0)
+#define SMI130_USER_DATA_8_GYRO_X_LSB__LEN (8)
+#define SMI130_USER_DATA_8_GYRO_X_LSB__MSK (0xFF)
+#define SMI130_USER_DATA_8_GYRO_X_LSB__REG (SMI130_USER_DATA_8_ADDR)
+
+/* GYR_X (MSB) Description - Reg Addr --> (0x0D), Bit --> 0...7 */
+#define SMI130_USER_DATA_9_GYRO_X_MSB__POS (0)
+#define SMI130_USER_DATA_9_GYRO_X_MSB__LEN (8)
+#define SMI130_USER_DATA_9_GYRO_X_MSB__MSK (0xFF)
+#define SMI130_USER_DATA_9_GYRO_X_MSB__REG (SMI130_USER_DATA_9_ADDR)
+
+/* GYR_Y (LSB) Description - Reg Addr --> 0x0E, Bit --> 0...7 */
+#define SMI130_USER_DATA_10_GYRO_Y_LSB__POS (0)
+#define SMI130_USER_DATA_10_GYRO_Y_LSB__LEN (8)
+#define SMI130_USER_DATA_10_GYRO_Y_LSB__MSK (0xFF)
+#define SMI130_USER_DATA_10_GYRO_Y_LSB__REG (SMI130_USER_DATA_10_ADDR)
+
+/* GYR_Y (MSB) Description - Reg Addr --> (0x0F), Bit --> 0...7 */
+#define SMI130_USER_DATA_11_GYRO_Y_MSB__POS (0)
+#define SMI130_USER_DATA_11_GYRO_Y_MSB__LEN (8)
+#define SMI130_USER_DATA_11_GYRO_Y_MSB__MSK (0xFF)
+#define SMI130_USER_DATA_11_GYRO_Y_MSB__REG (SMI130_USER_DATA_11_ADDR)
+
+/* GYR_Z (LSB) Description - Reg Addr --> (0x10), Bit --> 0...7 */
+#define SMI130_USER_DATA_12_GYRO_Z_LSB__POS (0)
+#define SMI130_USER_DATA_12_GYRO_Z_LSB__LEN (8)
+#define SMI130_USER_DATA_12_GYRO_Z_LSB__MSK (0xFF)
+#define SMI130_USER_DATA_12_GYRO_Z_LSB__REG (SMI130_USER_DATA_12_ADDR)
+
+/* GYR_Z (MSB) Description - Reg Addr --> (0x11), Bit --> 0...7 */
+#define SMI130_USER_DATA_13_GYRO_Z_MSB__POS (0)
+#define SMI130_USER_DATA_13_GYRO_Z_MSB__LEN (8)
+#define SMI130_USER_DATA_13_GYRO_Z_MSB__MSK (0xFF)
+#define SMI130_USER_DATA_13_GYRO_Z_MSB__REG (SMI130_USER_DATA_13_ADDR)
+/**************************************************************/
+/**\name ACCEL DATA XYZ LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* ACC_X (LSB) Description - Reg Addr --> (0x12), Bit --> 0...7 */
+#define SMI130_USER_DATA_14_ACCEL_X_LSB__POS (0)
+#define SMI130_USER_DATA_14_ACCEL_X_LSB__LEN (8)
+#define SMI130_USER_DATA_14_ACCEL_X_LSB__MSK (0xFF)
+#define SMI130_USER_DATA_14_ACCEL_X_LSB__REG (SMI130_USER_DATA_14_ADDR)
+
+/* ACC_X (MSB) Description - Reg Addr --> 0x13, Bit --> 0...7 */
+#define SMI130_USER_DATA_15_ACCEL_X_MSB__POS (0)
+#define SMI130_USER_DATA_15_ACCEL_X_MSB__LEN (8)
+#define SMI130_USER_DATA_15_ACCEL_X_MSB__MSK (0xFF)
+#define SMI130_USER_DATA_15_ACCEL_X_MSB__REG (SMI130_USER_DATA_15_ADDR)
+
+/* ACC_Y (LSB) Description - Reg Addr --> (0x14), Bit --> 0...7 */
+#define SMI130_USER_DATA_16_ACCEL_Y_LSB__POS (0)
+#define SMI130_USER_DATA_16_ACCEL_Y_LSB__LEN (8)
+#define SMI130_USER_DATA_16_ACCEL_Y_LSB__MSK (0xFF)
+#define SMI130_USER_DATA_16_ACCEL_Y_LSB__REG (SMI130_USER_DATA_16_ADDR)
+
+/* ACC_Y (MSB) Description - Reg Addr --> (0x15), Bit --> 0...7 */
+#define SMI130_USER_DATA_17_ACCEL_Y_MSB__POS (0)
+#define SMI130_USER_DATA_17_ACCEL_Y_MSB__LEN (8)
+#define SMI130_USER_DATA_17_ACCEL_Y_MSB__MSK (0xFF)
+#define SMI130_USER_DATA_17_ACCEL_Y_MSB__REG (SMI130_USER_DATA_17_ADDR)
+
+/* ACC_Z (LSB) Description - Reg Addr --> 0x16, Bit --> 0...7 */
+#define SMI130_USER_DATA_18_ACCEL_Z_LSB__POS (0)
+#define SMI130_USER_DATA_18_ACCEL_Z_LSB__LEN (8)
+#define SMI130_USER_DATA_18_ACCEL_Z_LSB__MSK (0xFF)
+#define SMI130_USER_DATA_18_ACCEL_Z_LSB__REG (SMI130_USER_DATA_18_ADDR)
+
+/* ACC_Z (MSB) Description - Reg Addr --> (0x17), Bit --> 0...7 */
+#define SMI130_USER_DATA_19_ACCEL_Z_MSB__POS (0)
+#define SMI130_USER_DATA_19_ACCEL_Z_MSB__LEN (8)
+#define SMI130_USER_DATA_19_ACCEL_Z_MSB__MSK (0xFF)
+#define SMI130_USER_DATA_19_ACCEL_Z_MSB__REG (SMI130_USER_DATA_19_ADDR)
+/**************************************************************/
+/**\name SENSOR TIME LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* SENSORTIME_0 (LSB) Description - Reg Addr --> (0x18), Bit --> 0...7 */
+#define SMI130_USER_SENSORTIME_0_SENSOR_TIME_LSB__POS (0)
+#define SMI130_USER_SENSORTIME_0_SENSOR_TIME_LSB__LEN (8)
+#define SMI130_USER_SENSORTIME_0_SENSOR_TIME_LSB__MSK (0xFF)
+#define SMI130_USER_SENSORTIME_0_SENSOR_TIME_LSB__REG \
+ (SMI130_USER_SENSORTIME_0_ADDR)
+
+/* SENSORTIME_1 (MSB) Description - Reg Addr --> (0x19), Bit --> 0...7 */
+#define SMI130_USER_SENSORTIME_1_SENSOR_TIME_MSB__POS (0)
+#define SMI130_USER_SENSORTIME_1_SENSOR_TIME_MSB__LEN (8)
+#define SMI130_USER_SENSORTIME_1_SENSOR_TIME_MSB__MSK (0xFF)
+#define SMI130_USER_SENSORTIME_1_SENSOR_TIME_MSB__REG \
+ (SMI130_USER_SENSORTIME_1_ADDR)
+
+/* SENSORTIME_2 (MSB) Description - Reg Addr --> (0x1A), Bit --> 0...7 */
+#define SMI130_USER_SENSORTIME_2_SENSOR_TIME_MSB__POS (0)
+#define SMI130_USER_SENSORTIME_2_SENSOR_TIME_MSB__LEN (8)
+#define SMI130_USER_SENSORTIME_2_SENSOR_TIME_MSB__MSK (0xFF)
+#define SMI130_USER_SENSORTIME_2_SENSOR_TIME_MSB__REG \
+ (SMI130_USER_SENSORTIME_2_ADDR)
+/**************************************************************/
+/**\name GYRO SELF TEST LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* Status Description - Reg Addr --> 0x1B, Bit --> 1 */
+#define SMI130_USER_STAT_GYRO_SELFTEST_OK__POS (1)
+#define SMI130_USER_STAT_GYRO_SELFTEST_OK__LEN (1)
+#define SMI130_USER_STAT_GYRO_SELFTEST_OK__MSK (0x02)
+#define SMI130_USER_STAT_GYRO_SELFTEST_OK__REG \
+ (SMI130_USER_STAT_ADDR)
+/**************************************************************/
+/**\name MAG MANUAL OPERATION LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* Status Description - Reg Addr --> 0x1B, Bit --> 2 */
+#define SMI130_USER_STAT_MAG_MANUAL_OPERATION__POS (2)
+#define SMI130_USER_STAT_MAG_MANUAL_OPERATION__LEN (1)
+#define SMI130_USER_STAT_MAG_MANUAL_OPERATION__MSK (0x04)
+#define SMI130_USER_STAT_MAG_MANUAL_OPERATION__REG \
+ (SMI130_USER_STAT_ADDR)
+/**************************************************************/
+/**\name FOC STATUS LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* Status Description - Reg Addr --> 0x1B, Bit --> 3 */
+#define SMI130_USER_STAT_FOC_RDY__POS (3)
+#define SMI130_USER_STAT_FOC_RDY__LEN (1)
+#define SMI130_USER_STAT_FOC_RDY__MSK (0x08)
+#define SMI130_USER_STAT_FOC_RDY__REG (SMI130_USER_STAT_ADDR)
+/**************************************************************/
+/**\name NVM READY LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* Status Description - Reg Addr --> 0x1B, Bit --> 4 */
+#define SMI130_USER_STAT_NVM_RDY__POS (4)
+#define SMI130_USER_STAT_NVM_RDY__LEN (1)
+#define SMI130_USER_STAT_NVM_RDY__MSK (0x10)
+#define SMI130_USER_STAT_NVM_RDY__REG (SMI130_USER_STAT_ADDR)
+/**************************************************************/
+/**\name DATA READY LENGTH, POSITION AND MASK FOR ACCEL, MAG AND GYRO*/
+/**************************************************************/
+/* Status Description - Reg Addr --> 0x1B, Bit --> 5 */
+#define SMI130_USER_STAT_DATA_RDY_MAG__POS (5)
+#define SMI130_USER_STAT_DATA_RDY_MAG__LEN (1)
+#define SMI130_USER_STAT_DATA_RDY_MAG__MSK (0x20)
+#define SMI130_USER_STAT_DATA_RDY_MAG__REG (SMI130_USER_STAT_ADDR)
+
+/* Status Description - Reg Addr --> 0x1B, Bit --> 6 */
+#define SMI130_USER_STAT_DATA_RDY_GYRO__POS (6)
+#define SMI130_USER_STAT_DATA_RDY_GYRO__LEN (1)
+#define SMI130_USER_STAT_DATA_RDY_GYRO__MSK (0x40)
+#define SMI130_USER_STAT_DATA_RDY_GYRO__REG (SMI130_USER_STAT_ADDR)
+
+/* Status Description - Reg Addr --> 0x1B, Bit --> 7 */
+#define SMI130_USER_STAT_DATA_RDY_ACCEL__POS (7)
+#define SMI130_USER_STAT_DATA_RDY_ACCEL__LEN (1)
+#define SMI130_USER_STAT_DATA_RDY_ACCEL__MSK (0x80)
+#define SMI130_USER_STAT_DATA_RDY_ACCEL__REG (SMI130_USER_STAT_ADDR)
+/**************************************************************/
+/**\name INTERRUPT STATUS LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 0 */
+#define SMI130_USER_INTR_STAT_0_STEP_INTR__POS (0)
+#define SMI130_USER_INTR_STAT_0_STEP_INTR__LEN (1)
+#define SMI130_USER_INTR_STAT_0_STEP_INTR__MSK (0x01)
+#define SMI130_USER_INTR_STAT_0_STEP_INTR__REG \
+ (SMI130_USER_INTR_STAT_0_ADDR)
+/**************************************************************/
+/**\name SIGNIFICANT INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 1 */
+#define SMI130_USER_INTR_STAT_0_SIGNIFICANT_INTR__POS (1)
+#define SMI130_USER_INTR_STAT_0_SIGNIFICANT_INTR__LEN (1)
+#define SMI130_USER_INTR_STAT_0_SIGNIFICANT_INTR__MSK (0x02)
+#define SMI130_USER_INTR_STAT_0_SIGNIFICANT_INTR__REG \
+ (SMI130_USER_INTR_STAT_0_ADDR)
+/**************************************************************/
+/**\name ANY_MOTION INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 2 */
+#define SMI130_USER_INTR_STAT_0_ANY_MOTION__POS (2)
+#define SMI130_USER_INTR_STAT_0_ANY_MOTION__LEN (1)
+#define SMI130_USER_INTR_STAT_0_ANY_MOTION__MSK (0x04)
+#define SMI130_USER_INTR_STAT_0_ANY_MOTION__REG \
+ (SMI130_USER_INTR_STAT_0_ADDR)
+/**************************************************************/
+/**\name PMU TRIGGER INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 3 */
+#define SMI130_USER_INTR_STAT_0_PMU_TRIGGER__POS 3
+#define SMI130_USER_INTR_STAT_0_PMU_TRIGGER__LEN (1)
+#define SMI130_USER_INTR_STAT_0_PMU_TRIGGER__MSK (0x08)
+#define SMI130_USER_INTR_STAT_0_PMU_TRIGGER__REG \
+ (SMI130_USER_INTR_STAT_0_ADDR)
+/**************************************************************/
+/**\name DOUBLE TAP INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 4 */
+#define SMI130_USER_INTR_STAT_0_DOUBLE_TAP_INTR__POS 4
+#define SMI130_USER_INTR_STAT_0_DOUBLE_TAP_INTR__LEN (1)
+#define SMI130_USER_INTR_STAT_0_DOUBLE_TAP_INTR__MSK (0x10)
+#define SMI130_USER_INTR_STAT_0_DOUBLE_TAP_INTR__REG \
+ (SMI130_USER_INTR_STAT_0_ADDR)
+/**************************************************************/
+/**\name SINGLE TAP INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 5 */
+#define SMI130_USER_INTR_STAT_0_SINGLE_TAP_INTR__POS 5
+#define SMI130_USER_INTR_STAT_0_SINGLE_TAP_INTR__LEN (1)
+#define SMI130_USER_INTR_STAT_0_SINGLE_TAP_INTR__MSK (0x20)
+#define SMI130_USER_INTR_STAT_0_SINGLE_TAP_INTR__REG \
+ (SMI130_USER_INTR_STAT_0_ADDR)
+/**************************************************************/
+/**\name ORIENT INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 6 */
+#define SMI130_USER_INTR_STAT_0_ORIENT__POS (6)
+#define SMI130_USER_INTR_STAT_0_ORIENT__LEN (1)
+#define SMI130_USER_INTR_STAT_0_ORIENT__MSK (0x40)
+#define SMI130_USER_INTR_STAT_0_ORIENT__REG \
+ (SMI130_USER_INTR_STAT_0_ADDR)
+/**************************************************************/
+/**\name FLAT INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 7 */
+#define SMI130_USER_INTR_STAT_0_FLAT__POS (7)
+#define SMI130_USER_INTR_STAT_0_FLAT__LEN (1)
+#define SMI130_USER_INTR_STAT_0_FLAT__MSK (0x80)
+#define SMI130_USER_INTR_STAT_0_FLAT__REG \
+ (SMI130_USER_INTR_STAT_0_ADDR)
+/**************************************************************/
+/**\name HIGH_G INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_1 Description - Reg Addr --> 0x1D, Bit --> 2 */
+#define SMI130_USER_INTR_STAT_1_HIGH_G_INTR__POS (2)
+#define SMI130_USER_INTR_STAT_1_HIGH_G_INTR__LEN (1)
+#define SMI130_USER_INTR_STAT_1_HIGH_G_INTR__MSK (0x04)
+#define SMI130_USER_INTR_STAT_1_HIGH_G_INTR__REG \
+ (SMI130_USER_INTR_STAT_1_ADDR)
+/**************************************************************/
+/**\name LOW_G INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_1 Description - Reg Addr --> 0x1D, Bit --> 3 */
+#define SMI130_USER_INTR_STAT_1_LOW_G_INTR__POS (3)
+#define SMI130_USER_INTR_STAT_1_LOW_G_INTR__LEN (1)
+#define SMI130_USER_INTR_STAT_1_LOW_G_INTR__MSK (0x08)
+#define SMI130_USER_INTR_STAT_1_LOW_G_INTR__REG \
+ (SMI130_USER_INTR_STAT_1_ADDR)
+/**************************************************************/
+/**\name DATA READY INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_1 Description - Reg Addr --> 0x1D, Bit --> 4 */
+#define SMI130_USER_INTR_STAT_1_DATA_RDY_INTR__POS (4)
+#define SMI130_USER_INTR_STAT_1_DATA_RDY_INTR__LEN (1)
+#define SMI130_USER_INTR_STAT_1_DATA_RDY_INTR__MSK (0x10)
+#define SMI130_USER_INTR_STAT_1_DATA_RDY_INTR__REG \
+ (SMI130_USER_INTR_STAT_1_ADDR)
+/**************************************************************/
+/**\name FIFO FULL INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_1 Description - Reg Addr --> 0x1D, Bit --> 5 */
+#define SMI130_USER_INTR_STAT_1_FIFO_FULL_INTR__POS (5)
+#define SMI130_USER_INTR_STAT_1_FIFO_FULL_INTR__LEN (1)
+#define SMI130_USER_INTR_STAT_1_FIFO_FULL_INTR__MSK (0x20)
+#define SMI130_USER_INTR_STAT_1_FIFO_FULL_INTR__REG \
+ (SMI130_USER_INTR_STAT_1_ADDR)
+/**************************************************************/
+/**\name FIFO WATERMARK INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_1 Description - Reg Addr --> 0x1D, Bit --> 6 */
+#define SMI130_USER_INTR_STAT_1_FIFO_WM_INTR__POS (6)
+#define SMI130_USER_INTR_STAT_1_FIFO_WM_INTR__LEN (1)
+#define SMI130_USER_INTR_STAT_1_FIFO_WM_INTR__MSK (0x40)
+#define SMI130_USER_INTR_STAT_1_FIFO_WM_INTR__REG \
+ (SMI130_USER_INTR_STAT_1_ADDR)
+/**************************************************************/
+/**\name NO MOTION INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_1 Description - Reg Addr --> 0x1D, Bit --> 7 */
+#define SMI130_USER_INTR_STAT_1_NOMOTION_INTR__POS (7)
+#define SMI130_USER_INTR_STAT_1_NOMOTION_INTR__LEN (1)
+#define SMI130_USER_INTR_STAT_1_NOMOTION_INTR__MSK (0x80)
+#define SMI130_USER_INTR_STAT_1_NOMOTION_INTR__REG \
+ (SMI130_USER_INTR_STAT_1_ADDR)
+/**************************************************************/
+/**\name ANY MOTION-XYZ AXIS INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 0 */
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_X__POS (0)
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_X__LEN (1)
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_X__MSK (0x01)
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_X__REG \
+ (SMI130_USER_INTR_STAT_2_ADDR)
+
+/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 1 */
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_Y__POS (1)
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_Y__LEN (1)
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_Y__MSK (0x02)
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_Y__REG \
+ (SMI130_USER_INTR_STAT_2_ADDR)
+
+/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 2 */
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_Z__POS (2)
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_Z__LEN (1)
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_Z__MSK (0x04)
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_Z__REG \
+ (SMI130_USER_INTR_STAT_2_ADDR)
+/**************************************************************/
+/**\name ANY MOTION SIGN LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 3 */
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_SIGN__POS (3)
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_SIGN__LEN (1)
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_SIGN__MSK (0x08)
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_SIGN__REG \
+ (SMI130_USER_INTR_STAT_2_ADDR)
+/**************************************************************/
+/**\name TAP_XYZ AND SIGN LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 4 */
+#define SMI130_USER_INTR_STAT_2_TAP_FIRST_X__POS (4)
+#define SMI130_USER_INTR_STAT_2_TAP_FIRST_X__LEN (1)
+#define SMI130_USER_INTR_STAT_2_TAP_FIRST_X__MSK (0x10)
+#define SMI130_USER_INTR_STAT_2_TAP_FIRST_X__REG \
+ (SMI130_USER_INTR_STAT_2_ADDR)
+
+/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 5 */
+#define SMI130_USER_INTR_STAT_2_TAP_FIRST_Y__POS (5)
+#define SMI130_USER_INTR_STAT_2_TAP_FIRST_Y__LEN (1)
+#define SMI130_USER_INTR_STAT_2_TAP_FIRST_Y__MSK (0x20)
+#define SMI130_USER_INTR_STAT_2_TAP_FIRST_Y__REG \
+ (SMI130_USER_INTR_STAT_2_ADDR)
+
+/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 6 */
+#define SMI130_USER_INTR_STAT_2_TAP_FIRST_Z__POS (6)
+#define SMI130_USER_INTR_STAT_2_TAP_FIRST_Z__LEN (1)
+#define SMI130_USER_INTR_STAT_2_TAP_FIRST_Z__MSK (0x40)
+#define SMI130_USER_INTR_STAT_2_TAP_FIRST_Z__REG \
+ (SMI130_USER_INTR_STAT_2_ADDR)
+
+/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 7 */
+#define SMI130_USER_INTR_STAT_2_TAP_SIGN__POS (7)
+#define SMI130_USER_INTR_STAT_2_TAP_SIGN__LEN (1)
+#define SMI130_USER_INTR_STAT_2_TAP_SIGN__MSK (0x80)
+#define SMI130_USER_INTR_STAT_2_TAP_SIGN__REG \
+ (SMI130_USER_INTR_STAT_2_ADDR)
+/**************************************************************/
+/**\name INTERRUPT SATAUS FOR WHOLE 0x1E LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 0...7 */
+#define SMI130_USER_INTR_STAT_2__POS (0)
+#define SMI130_USER_INTR_STAT_2__LEN (8)
+#define SMI130_USER_INTR_STAT_2__MSK (0xFF)
+#define SMI130_USER_INTR_STAT_2__REG \
+ (SMI130_USER_INTR_STAT_2_ADDR)
+/**************************************************************/
+/**\name HIGH_G-XYZ AND SIGN LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_3 Description - Reg Addr --> (0x1F), Bit --> 0 */
+#define SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_X__POS (0)
+#define SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_X__LEN (1)
+#define SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_X__MSK (0x01)
+#define SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_X__REG \
+ (SMI130_USER_INTR_STAT_3_ADDR)
+
+/* Int_Status_3 Description - Reg Addr --> 0x1E, Bit --> 1 */
+#define SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_Y__POS (1)
+#define SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_Y__LEN (1)
+#define SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_Y__MSK (0x02)
+#define SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_Y__REG \
+ (SMI130_USER_INTR_STAT_3_ADDR)
+
+/* Int_Status_3 Description - Reg Addr --> (0x1F), Bit --> 2 */
+#define SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_Z__POS (2)
+#define SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_Z__LEN (1)
+#define SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_Z__MSK (0x04)
+#define SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_Z__REG \
+ (SMI130_USER_INTR_STAT_3_ADDR)
+
+/* Int_Status_3 Description - Reg Addr --> (0x1F), Bit --> 3 */
+#define SMI130_USER_INTR_STAT_3_HIGH_G_SIGN__POS (3)
+#define SMI130_USER_INTR_STAT_3_HIGH_G_SIGN__LEN (1)
+#define SMI130_USER_INTR_STAT_3_HIGH_G_SIGN__MSK (0x08)
+#define SMI130_USER_INTR_STAT_3_HIGH_G_SIGN__REG \
+ (SMI130_USER_INTR_STAT_3_ADDR)
+/**************************************************************/
+/**\name ORIENT XY and Z AXIS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_3 Description - Reg Addr --> (0x1F), Bit --> 4...5 */
+#define SMI130_USER_INTR_STAT_3_ORIENT_XY__POS (4)
+#define SMI130_USER_INTR_STAT_3_ORIENT_XY__LEN (2)
+#define SMI130_USER_INTR_STAT_3_ORIENT_XY__MSK (0x30)
+#define SMI130_USER_INTR_STAT_3_ORIENT_XY__REG \
+ (SMI130_USER_INTR_STAT_3_ADDR)
+
+/* Int_Status_3 Description - Reg Addr --> (0x1F), Bit --> 6 */
+#define SMI130_USER_INTR_STAT_3_ORIENT_Z__POS (6)
+#define SMI130_USER_INTR_STAT_3_ORIENT_Z__LEN (1)
+#define SMI130_USER_INTR_STAT_3_ORIENT_Z__MSK (0x40)
+#define SMI130_USER_INTR_STAT_3_ORIENT_Z__REG \
+ (SMI130_USER_INTR_STAT_3_ADDR)
+/**************************************************************/
+/**\name FLAT LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_3 Description - Reg Addr --> (0x1F), Bit --> 7 */
+#define SMI130_USER_INTR_STAT_3_FLAT__POS (7)
+#define SMI130_USER_INTR_STAT_3_FLAT__LEN (1)
+#define SMI130_USER_INTR_STAT_3_FLAT__MSK (0x80)
+#define SMI130_USER_INTR_STAT_3_FLAT__REG \
+ (SMI130_USER_INTR_STAT_3_ADDR)
+/**************************************************************/
+/**\name (0x1F) LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_3 Description - Reg Addr --> (0x1F), Bit --> 0...7 */
+#define SMI130_USER_INTR_STAT_3__POS (0)
+#define SMI130_USER_INTR_STAT_3__LEN (8)
+#define SMI130_USER_INTR_STAT_3__MSK (0xFF)
+#define SMI130_USER_INTR_STAT_3__REG \
+ (SMI130_USER_INTR_STAT_3_ADDR)
+/**************************************************************/
+/**\name TEMPERATURE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Temperature Description - LSB Reg Addr --> (0x20), Bit --> 0...7 */
+#define SMI130_USER_TEMP_LSB_VALUE__POS (0)
+#define SMI130_USER_TEMP_LSB_VALUE__LEN (8)
+#define SMI130_USER_TEMP_LSB_VALUE__MSK (0xFF)
+#define SMI130_USER_TEMP_LSB_VALUE__REG \
+ (SMI130_USER_TEMPERATURE_0_ADDR)
+
+/* Temperature Description - LSB Reg Addr --> 0x21, Bit --> 0...7 */
+#define SMI130_USER_TEMP_MSB_VALUE__POS (0)
+#define SMI130_USER_TEMP_MSB_VALUE__LEN (8)
+#define SMI130_USER_TEMP_MSB_VALUE__MSK (0xFF)
+#define SMI130_USER_TEMP_MSB_VALUE__REG \
+ (SMI130_USER_TEMPERATURE_1_ADDR)
+/**************************************************************/
+/**\name FIFO BYTE COUNTER LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Length0 Description - Reg Addr --> 0x22, Bit --> 0...7 */
+#define SMI130_USER_FIFO_BYTE_COUNTER_LSB__POS (0)
+#define SMI130_USER_FIFO_BYTE_COUNTER_LSB__LEN (8)
+#define SMI130_USER_FIFO_BYTE_COUNTER_LSB__MSK (0xFF)
+#define SMI130_USER_FIFO_BYTE_COUNTER_LSB__REG \
+ (SMI130_USER_FIFO_LENGTH_0_ADDR)
+
+/*Fifo_Length1 Description - Reg Addr --> 0x23, Bit --> 0...2 */
+#define SMI130_USER_FIFO_BYTE_COUNTER_MSB__POS (0)
+#define SMI130_USER_FIFO_BYTE_COUNTER_MSB__LEN 3
+#define SMI130_USER_FIFO_BYTE_COUNTER_MSB__MSK (0x07)
+#define SMI130_USER_FIFO_BYTE_COUNTER_MSB__REG \
+ (SMI130_USER_FIFO_LENGTH_1_ADDR)
+
+/**************************************************************/
+/**\name FIFO DATA LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Data Description - Reg Addr --> 0x24, Bit --> 0...7 */
+#define SMI130_USER_FIFO_DATA__POS (0)
+#define SMI130_USER_FIFO_DATA__LEN (8)
+#define SMI130_USER_FIFO_DATA__MSK (0xFF)
+#define SMI130_USER_FIFO_DATA__REG (SMI130_USER_FIFO_DATA_ADDR)
+
+/**************************************************************/
+/**\name ACCEL CONFIGURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Acc_Conf Description - Reg Addr --> (0x40), Bit --> 0...3 */
+#define SMI130_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE__POS (0)
+#define SMI130_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE__LEN (4)
+#define SMI130_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE__MSK (0x0F)
+#define SMI130_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE__REG \
+(SMI130_USER_ACCEL_CONFIG_ADDR)
+
+/* Acc_Conf Description - Reg Addr --> (0x40), Bit --> 4...6 */
+#define SMI130_USER_ACCEL_CONFIG_ACCEL_BW__POS (4)
+#define SMI130_USER_ACCEL_CONFIG_ACCEL_BW__LEN (3)
+#define SMI130_USER_ACCEL_CONFIG_ACCEL_BW__MSK (0x70)
+#define SMI130_USER_ACCEL_CONFIG_ACCEL_BW__REG (SMI130_USER_ACCEL_CONFIG_ADDR)
+
+/* Acc_Conf Description - Reg Addr --> (0x40), Bit --> 7 */
+#define SMI130_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING__POS (7)
+#define SMI130_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING__LEN (1)
+#define SMI130_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING__MSK (0x80)
+#define SMI130_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING__REG \
+(SMI130_USER_ACCEL_CONFIG_ADDR)
+
+/* Acc_Range Description - Reg Addr --> 0x41, Bit --> 0...3 */
+#define SMI130_USER_ACCEL_RANGE__POS (0)
+#define SMI130_USER_ACCEL_RANGE__LEN (4)
+#define SMI130_USER_ACCEL_RANGE__MSK (0x0F)
+#define SMI130_USER_ACCEL_RANGE__REG \
+(SMI130_USER_ACCEL_RANGE_ADDR)
+/**************************************************************/
+/**\name GYRO CONFIGURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Gyro_Conf Description - Reg Addr --> (0x42), Bit --> 0...3 */
+#define SMI130_USER_GYRO_CONFIG_OUTPUT_DATA_RATE__POS (0)
+#define SMI130_USER_GYRO_CONFIG_OUTPUT_DATA_RATE__LEN (4)
+#define SMI130_USER_GYRO_CONFIG_OUTPUT_DATA_RATE__MSK (0x0F)
+#define SMI130_USER_GYRO_CONFIG_OUTPUT_DATA_RATE__REG \
+(SMI130_USER_GYRO_CONFIG_ADDR)
+
+/* Gyro_Conf Description - Reg Addr --> (0x42), Bit --> 4...5 */
+#define SMI130_USER_GYRO_CONFIG_BW__POS (4)
+#define SMI130_USER_GYRO_CONFIG_BW__LEN (2)
+#define SMI130_USER_GYRO_CONFIG_BW__MSK (0x30)
+#define SMI130_USER_GYRO_CONFIG_BW__REG \
+(SMI130_USER_GYRO_CONFIG_ADDR)
+
+/* Gyr_Range Description - Reg Addr --> 0x43, Bit --> 0...2 */
+#define SMI130_USER_GYRO_RANGE__POS (0)
+#define SMI130_USER_GYRO_RANGE__LEN (3)
+#define SMI130_USER_GYRO_RANGE__MSK (0x07)
+#define SMI130_USER_GYRO_RANGE__REG (SMI130_USER_GYRO_RANGE_ADDR)
+/**************************************************************/
+/**\name MAG CONFIGURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Mag_Conf Description - Reg Addr --> (0x44), Bit --> 0...3 */
+#define SMI130_USER_MAG_CONFIG_OUTPUT_DATA_RATE__POS (0)
+#define SMI130_USER_MAG_CONFIG_OUTPUT_DATA_RATE__LEN (4)
+#define SMI130_USER_MAG_CONFIG_OUTPUT_DATA_RATE__MSK (0x0F)
+#define SMI130_USER_MAG_CONFIG_OUTPUT_DATA_RATE__REG \
+(SMI130_USER_MAG_CONFIG_ADDR)
+/**************************************************************/
+/**\name FIFO DOWNS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Downs Description - Reg Addr --> 0x45, Bit --> 0...2 */
+#define SMI130_USER_FIFO_DOWN_GYRO__POS (0)
+#define SMI130_USER_FIFO_DOWN_GYRO__LEN (3)
+#define SMI130_USER_FIFO_DOWN_GYRO__MSK (0x07)
+#define SMI130_USER_FIFO_DOWN_GYRO__REG (SMI130_USER_FIFO_DOWN_ADDR)
+/**************************************************************/
+/**\name FIFO FILTER FOR ACCEL AND GYRO LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_filt Description - Reg Addr --> 0x45, Bit --> 3 */
+#define SMI130_USER_FIFO_FILTER_GYRO__POS (3)
+#define SMI130_USER_FIFO_FILTER_GYRO__LEN (1)
+#define SMI130_USER_FIFO_FILTER_GYRO__MSK (0x08)
+#define SMI130_USER_FIFO_FILTER_GYRO__REG (SMI130_USER_FIFO_DOWN_ADDR)
+
+/* Fifo_Downs Description - Reg Addr --> 0x45, Bit --> 4...6 */
+#define SMI130_USER_FIFO_DOWN_ACCEL__POS (4)
+#define SMI130_USER_FIFO_DOWN_ACCEL__LEN (3)
+#define SMI130_USER_FIFO_DOWN_ACCEL__MSK (0x70)
+#define SMI130_USER_FIFO_DOWN_ACCEL__REG (SMI130_USER_FIFO_DOWN_ADDR)
+
+/* Fifo_FILT Description - Reg Addr --> 0x45, Bit --> 7 */
+#define SMI130_USER_FIFO_FILTER_ACCEL__POS (7)
+#define SMI130_USER_FIFO_FILTER_ACCEL__LEN (1)
+#define SMI130_USER_FIFO_FILTER_ACCEL__MSK (0x80)
+#define SMI130_USER_FIFO_FILTER_ACCEL__REG (SMI130_USER_FIFO_DOWN_ADDR)
+/**************************************************************/
+/**\name FIFO WATER MARK LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Config_0 Description - Reg Addr --> 0x46, Bit --> 0...7 */
+#define SMI130_USER_FIFO_WM__POS (0)
+#define SMI130_USER_FIFO_WM__LEN (8)
+#define SMI130_USER_FIFO_WM__MSK (0xFF)
+#define SMI130_USER_FIFO_WM__REG (SMI130_USER_FIFO_CONFIG_0_ADDR)
+/**************************************************************/
+/**\name FIFO TIME LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Config_1 Description - Reg Addr --> 0x47, Bit --> 1 */
+#define SMI130_USER_FIFO_TIME_ENABLE__POS (1)
+#define SMI130_USER_FIFO_TIME_ENABLE__LEN (1)
+#define SMI130_USER_FIFO_TIME_ENABLE__MSK (0x02)
+#define SMI130_USER_FIFO_TIME_ENABLE__REG (SMI130_USER_FIFO_CONFIG_1_ADDR)
+/**************************************************************/
+/**\name FIFO TAG INTERRUPT LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Config_1 Description - Reg Addr --> 0x47, Bit --> 2 */
+#define SMI130_USER_FIFO_TAG_INTR2_ENABLE__POS (2)
+#define SMI130_USER_FIFO_TAG_INTR2_ENABLE__LEN (1)
+#define SMI130_USER_FIFO_TAG_INTR2_ENABLE__MSK (0x04)
+#define SMI130_USER_FIFO_TAG_INTR2_ENABLE__REG (SMI130_USER_FIFO_CONFIG_1_ADDR)
+
+/* Fifo_Config_1 Description - Reg Addr --> 0x47, Bit --> 3 */
+#define SMI130_USER_FIFO_TAG_INTR1_ENABLE__POS (3)
+#define SMI130_USER_FIFO_TAG_INTR1_ENABLE__LEN (1)
+#define SMI130_USER_FIFO_TAG_INTR1_ENABLE__MSK (0x08)
+#define SMI130_USER_FIFO_TAG_INTR1_ENABLE__REG (SMI130_USER_FIFO_CONFIG_1_ADDR)
+/**************************************************************/
+/**\name FIFO HEADER LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Config_1 Description - Reg Addr --> 0x47, Bit --> 4 */
+#define SMI130_USER_FIFO_HEADER_ENABLE__POS (4)
+#define SMI130_USER_FIFO_HEADER_ENABLE__LEN (1)
+#define SMI130_USER_FIFO_HEADER_ENABLE__MSK (0x10)
+#define SMI130_USER_FIFO_HEADER_ENABLE__REG \
+(SMI130_USER_FIFO_CONFIG_1_ADDR)
+/**************************************************************/
+/**\name FIFO MAG ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Config_1 Description - Reg Addr --> 0x47, Bit --> 5 */
+#define SMI130_USER_FIFO_MAG_ENABLE__POS (5)
+#define SMI130_USER_FIFO_MAG_ENABLE__LEN (1)
+#define SMI130_USER_FIFO_MAG_ENABLE__MSK (0x20)
+#define SMI130_USER_FIFO_MAG_ENABLE__REG \
+(SMI130_USER_FIFO_CONFIG_1_ADDR)
+/**************************************************************/
+/**\name FIFO ACCEL ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Config_1 Description - Reg Addr --> 0x47, Bit --> 6 */
+#define SMI130_USER_FIFO_ACCEL_ENABLE__POS (6)
+#define SMI130_USER_FIFO_ACCEL_ENABLE__LEN (1)
+#define SMI130_USER_FIFO_ACCEL_ENABLE__MSK (0x40)
+#define SMI130_USER_FIFO_ACCEL_ENABLE__REG \
+(SMI130_USER_FIFO_CONFIG_1_ADDR)
+/**************************************************************/
+/**\name FIFO GYRO ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Config_1 Description - Reg Addr --> 0x47, Bit --> 7 */
+#define SMI130_USER_FIFO_GYRO_ENABLE__POS (7)
+#define SMI130_USER_FIFO_GYRO_ENABLE__LEN (1)
+#define SMI130_USER_FIFO_GYRO_ENABLE__MSK (0x80)
+#define SMI130_USER_FIFO_GYRO_ENABLE__REG \
+(SMI130_USER_FIFO_CONFIG_1_ADDR)
+
+/**************************************************************/
+/**\name MAG I2C ADDRESS SELECTION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+
+/* Mag_IF_0 Description - Reg Addr --> 0x4b, Bit --> 1...7 */
+#define SMI130_USER_I2C_DEVICE_ADDR__POS (1)
+#define SMI130_USER_I2C_DEVICE_ADDR__LEN (7)
+#define SMI130_USER_I2C_DEVICE_ADDR__MSK (0xFE)
+#define SMI130_USER_I2C_DEVICE_ADDR__REG (SMI130_USER_MAG_IF_0_ADDR)
+/**************************************************************/
+/**\name MAG CONFIGURATION FOR SECONDARY
+ INTERFACE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Mag_IF_1 Description - Reg Addr --> 0x4c, Bit --> 0...1 */
+#define SMI130_USER_MAG_BURST__POS (0)
+#define SMI130_USER_MAG_BURST__LEN (2)
+#define SMI130_USER_MAG_BURST__MSK (0x03)
+#define SMI130_USER_MAG_BURST__REG (SMI130_USER_MAG_IF_1_ADDR)
+
+/* Mag_IF_1 Description - Reg Addr --> 0x4c, Bit --> 2...5 */
+#define SMI130_USER_MAG_OFFSET__POS (2)
+#define SMI130_USER_MAG_OFFSET__LEN (4)
+#define SMI130_USER_MAG_OFFSET__MSK (0x3C)
+#define SMI130_USER_MAG_OFFSET__REG (SMI130_USER_MAG_IF_1_ADDR)
+
+/* Mag_IF_1 Description - Reg Addr --> 0x4c, Bit --> 7 */
+#define SMI130_USER_MAG_MANUAL_ENABLE__POS (7)
+#define SMI130_USER_MAG_MANUAL_ENABLE__LEN (1)
+#define SMI130_USER_MAG_MANUAL_ENABLE__MSK (0x80)
+#define SMI130_USER_MAG_MANUAL_ENABLE__REG \
+(SMI130_USER_MAG_IF_1_ADDR)
+
+/* Mag_IF_2 Description - Reg Addr --> 0x4d, Bit -->0... 7 */
+#define SMI130_USER_READ_ADDR__POS (0)
+#define SMI130_USER_READ_ADDR__LEN (8)
+#define SMI130_USER_READ_ADDR__MSK (0xFF)
+#define SMI130_USER_READ_ADDR__REG (SMI130_USER_MAG_IF_2_ADDR)
+
+/* Mag_IF_3 Description - Reg Addr --> 0x4e, Bit -->0... 7 */
+#define SMI130_USER_WRITE_ADDR__POS (0)
+#define SMI130_USER_WRITE_ADDR__LEN (8)
+#define SMI130_USER_WRITE_ADDR__MSK (0xFF)
+#define SMI130_USER_WRITE_ADDR__REG (SMI130_USER_MAG_IF_3_ADDR)
+
+/* Mag_IF_4 Description - Reg Addr --> 0x4f, Bit -->0... 7 */
+#define SMI130_USER_WRITE_DATA__POS (0)
+#define SMI130_USER_WRITE_DATA__LEN (8)
+#define SMI130_USER_WRITE_DATA__MSK (0xFF)
+#define SMI130_USER_WRITE_DATA__REG (SMI130_USER_MAG_IF_4_ADDR)
+/**************************************************************/
+/**\name ANY MOTION XYZ AXIS ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_0 Description - Reg Addr --> 0x50, Bit -->0 */
+#define SMI130_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE__POS (0)
+#define SMI130_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE__MSK (0x01)
+#define SMI130_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_0_ADDR)
+
+/* Int_En_0 Description - Reg Addr --> 0x50, Bit -->1 */
+#define SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE__POS (1)
+#define SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE__MSK (0x02)
+#define SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_0_ADDR)
+
+/* Int_En_0 Description - Reg Addr --> 0x50, Bit -->2 */
+#define SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE__POS (2)
+#define SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE__MSK (0x04)
+#define SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_0_ADDR)
+/**************************************************************/
+/**\name DOUBLE TAP ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_0 Description - Reg Addr --> 0x50, Bit -->4 */
+#define SMI130_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE__POS (4)
+#define SMI130_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE__MSK (0x10)
+#define SMI130_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_0_ADDR)
+/**************************************************************/
+/**\name SINGLE TAP ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_0 Description - Reg Addr --> 0x50, Bit -->5 */
+#define SMI130_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE__POS (5)
+#define SMI130_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE__MSK (0x20)
+#define SMI130_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_0_ADDR)
+/**************************************************************/
+/**\name ORIENT ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_0 Description - Reg Addr --> 0x50, Bit -->6 */
+#define SMI130_USER_INTR_ENABLE_0_ORIENT_ENABLE__POS (6)
+#define SMI130_USER_INTR_ENABLE_0_ORIENT_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_0_ORIENT_ENABLE__MSK (0x40)
+#define SMI130_USER_INTR_ENABLE_0_ORIENT_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_0_ADDR)
+/**************************************************************/
+/**\name FLAT ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_0 Description - Reg Addr --> 0x50, Bit -->7 */
+#define SMI130_USER_INTR_ENABLE_0_FLAT_ENABLE__POS (7)
+#define SMI130_USER_INTR_ENABLE_0_FLAT_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_0_FLAT_ENABLE__MSK (0x80)
+#define SMI130_USER_INTR_ENABLE_0_FLAT_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_0_ADDR)
+/**************************************************************/
+/**\name HIGH_G XYZ ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_1 Description - Reg Addr --> (0x51), Bit -->0 */
+#define SMI130_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE__POS (0)
+#define SMI130_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE__MSK (0x01)
+#define SMI130_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_1_ADDR)
+
+/* Int_En_1 Description - Reg Addr --> (0x51), Bit -->1 */
+#define SMI130_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE__POS (1)
+#define SMI130_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE__MSK (0x02)
+#define SMI130_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_1_ADDR)
+
+/* Int_En_1 Description - Reg Addr --> (0x51), Bit -->2 */
+#define SMI130_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE__POS (2)
+#define SMI130_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE__MSK (0x04)
+#define SMI130_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_1_ADDR)
+/**************************************************************/
+/**\name LOW_G ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_1 Description - Reg Addr --> (0x51), Bit -->3 */
+#define SMI130_USER_INTR_ENABLE_1_LOW_G_ENABLE__POS (3)
+#define SMI130_USER_INTR_ENABLE_1_LOW_G_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_1_LOW_G_ENABLE__MSK (0x08)
+#define SMI130_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_1_ADDR)
+/**************************************************************/
+/**\name DATA READY ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_1 Description - Reg Addr --> (0x51), Bit -->4 */
+#define SMI130_USER_INTR_ENABLE_1_DATA_RDY_ENABLE__POS (4)
+#define SMI130_USER_INTR_ENABLE_1_DATA_RDY_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_1_DATA_RDY_ENABLE__MSK (0x10)
+#define SMI130_USER_INTR_ENABLE_1_DATA_RDY_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_1_ADDR)
+/**************************************************************/
+/**\name FIFO FULL AND WATER MARK ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_1 Description - Reg Addr --> (0x51), Bit -->5 */
+#define SMI130_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE__POS (5)
+#define SMI130_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE__MSK (0x20)
+#define SMI130_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_1_ADDR)
+
+/* Int_En_1 Description - Reg Addr --> (0x51), Bit -->6 */
+#define SMI130_USER_INTR_ENABLE_1_FIFO_WM_ENABLE__POS (6)
+#define SMI130_USER_INTR_ENABLE_1_FIFO_WM_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_1_FIFO_WM_ENABLE__MSK (0x40)
+#define SMI130_USER_INTR_ENABLE_1_FIFO_WM_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_1_ADDR)
+/**************************************************************/
+/**\name NO MOTION XYZ ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_2 Description - Reg Addr --> (0x52), Bit -->0 */
+#define SMI130_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE__POS (0)
+#define SMI130_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE__MSK (0x01)
+#define SMI130_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_2_ADDR)
+
+/* Int_En_2 Description - Reg Addr --> (0x52), Bit -->1 */
+#define SMI130_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE__POS (1)
+#define SMI130_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE__MSK (0x02)
+#define SMI130_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_2_ADDR)
+
+/* Int_En_2 Description - Reg Addr --> (0x52), Bit -->2 */
+#define SMI130_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE__POS (2)
+#define SMI130_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE__MSK (0x04)
+#define SMI130_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_2_ADDR)
+/**************************************************************/
+/**\name STEP DETECTOR ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_2 Description - Reg Addr --> (0x52), Bit -->3 */
+#define SMI130_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE__POS (3)
+#define SMI130_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE__MSK (0x08)
+#define SMI130_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_2_ADDR)
+/**************************************************************/
+/**\name EDGE CONTROL ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->0 */
+#define SMI130_USER_INTR1_EDGE_CTRL__POS (0)
+#define SMI130_USER_INTR1_EDGE_CTRL__LEN (1)
+#define SMI130_USER_INTR1_EDGE_CTRL__MSK (0x01)
+#define SMI130_USER_INTR1_EDGE_CTRL__REG \
+(SMI130_USER_INTR_OUT_CTRL_ADDR)
+/**************************************************************/
+/**\name LEVEL CONTROL ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->1 */
+#define SMI130_USER_INTR1_LEVEL__POS (1)
+#define SMI130_USER_INTR1_LEVEL__LEN (1)
+#define SMI130_USER_INTR1_LEVEL__MSK (0x02)
+#define SMI130_USER_INTR1_LEVEL__REG \
+(SMI130_USER_INTR_OUT_CTRL_ADDR)
+/**************************************************************/
+/**\name OUTPUT TYPE ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->2 */
+#define SMI130_USER_INTR1_OUTPUT_TYPE__POS (2)
+#define SMI130_USER_INTR1_OUTPUT_TYPE__LEN (1)
+#define SMI130_USER_INTR1_OUTPUT_TYPE__MSK (0x04)
+#define SMI130_USER_INTR1_OUTPUT_TYPE__REG \
+(SMI130_USER_INTR_OUT_CTRL_ADDR)
+/**************************************************************/
+/**\name OUTPUT TYPE ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->3 */
+#define SMI130_USER_INTR1_OUTPUT_ENABLE__POS (3)
+#define SMI130_USER_INTR1_OUTPUT_ENABLE__LEN (1)
+#define SMI130_USER_INTR1_OUTPUT_ENABLE__MSK (0x08)
+#define SMI130_USER_INTR1_OUTPUT_ENABLE__REG \
+(SMI130_USER_INTR_OUT_CTRL_ADDR)
+/**************************************************************/
+/**\name EDGE CONTROL ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->4 */
+#define SMI130_USER_INTR2_EDGE_CTRL__POS (4)
+#define SMI130_USER_INTR2_EDGE_CTRL__LEN (1)
+#define SMI130_USER_INTR2_EDGE_CTRL__MSK (0x10)
+#define SMI130_USER_INTR2_EDGE_CTRL__REG \
+(SMI130_USER_INTR_OUT_CTRL_ADDR)
+/**************************************************************/
+/**\name LEVEL CONTROL ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->5 */
+#define SMI130_USER_INTR2_LEVEL__POS (5)
+#define SMI130_USER_INTR2_LEVEL__LEN (1)
+#define SMI130_USER_INTR2_LEVEL__MSK (0x20)
+#define SMI130_USER_INTR2_LEVEL__REG \
+(SMI130_USER_INTR_OUT_CTRL_ADDR)
+/**************************************************************/
+/**\name OUTPUT TYPE ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->6 */
+#define SMI130_USER_INTR2_OUTPUT_TYPE__POS (6)
+#define SMI130_USER_INTR2_OUTPUT_TYPE__LEN (1)
+#define SMI130_USER_INTR2_OUTPUT_TYPE__MSK (0x40)
+#define SMI130_USER_INTR2_OUTPUT_TYPE__REG \
+(SMI130_USER_INTR_OUT_CTRL_ADDR)
+
+/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->7 */
+#define SMI130_USER_INTR2_OUTPUT_EN__POS (7)
+#define SMI130_USER_INTR2_OUTPUT_EN__LEN (1)
+#define SMI130_USER_INTR2_OUTPUT_EN__MSK (0x80)
+#define SMI130_USER_INTR2_OUTPUT_EN__REG \
+(SMI130_USER_INTR_OUT_CTRL_ADDR)
+/**************************************************************/
+/**\name LATCH INTERRUPT LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Latch Description - Reg Addr --> 0x54, Bit -->0...3 */
+#define SMI130_USER_INTR_LATCH__POS (0)
+#define SMI130_USER_INTR_LATCH__LEN (4)
+#define SMI130_USER_INTR_LATCH__MSK (0x0F)
+#define SMI130_USER_INTR_LATCH__REG (SMI130_USER_INTR_LATCH_ADDR)
+/**************************************************************/
+/**\name INPUT ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Latch Description - Reg Addr --> 0x54, Bit -->4 */
+#define SMI130_USER_INTR1_INPUT_ENABLE__POS (4)
+#define SMI130_USER_INTR1_INPUT_ENABLE__LEN (1)
+#define SMI130_USER_INTR1_INPUT_ENABLE__MSK (0x10)
+#define SMI130_USER_INTR1_INPUT_ENABLE__REG \
+(SMI130_USER_INTR_LATCH_ADDR)
+
+/* Int_Latch Description - Reg Addr --> 0x54, Bit -->5*/
+#define SMI130_USER_INTR2_INPUT_ENABLE__POS (5)
+#define SMI130_USER_INTR2_INPUT_ENABLE__LEN (1)
+#define SMI130_USER_INTR2_INPUT_ENABLE__MSK (0x20)
+#define SMI130_USER_INTR2_INPUT_ENABLE__REG \
+(SMI130_USER_INTR_LATCH_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF LOW_G LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_0 Description - Reg Addr --> 0x55, Bit -->0 */
+#define SMI130_USER_INTR_MAP_0_INTR1_LOW_G__POS (0)
+#define SMI130_USER_INTR_MAP_0_INTR1_LOW_G__LEN (1)
+#define SMI130_USER_INTR_MAP_0_INTR1_LOW_G__MSK (0x01)
+#define SMI130_USER_INTR_MAP_0_INTR1_LOW_G__REG (SMI130_USER_INTR_MAP_0_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF HIGH_G LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_0 Description - Reg Addr --> 0x55, Bit -->1 */
+#define SMI130_USER_INTR_MAP_0_INTR1_HIGH_G__POS (1)
+#define SMI130_USER_INTR_MAP_0_INTR1_HIGH_G__LEN (1)
+#define SMI130_USER_INTR_MAP_0_INTR1_HIGH_G__MSK (0x02)
+#define SMI130_USER_INTR_MAP_0_INTR1_HIGH_G__REG \
+(SMI130_USER_INTR_MAP_0_ADDR)
+/**************************************************************/
+/**\name INTERRUPT MAPPIONG OF ANY MOTION_G LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_0 Description - Reg Addr --> 0x55, Bit -->2 */
+#define SMI130_USER_INTR_MAP_0_INTR1_ANY_MOTION__POS (2)
+#define SMI130_USER_INTR_MAP_0_INTR1_ANY_MOTION__LEN (1)
+#define SMI130_USER_INTR_MAP_0_INTR1_ANY_MOTION__MSK (0x04)
+#define SMI130_USER_INTR_MAP_0_INTR1_ANY_MOTION__REG \
+(SMI130_USER_INTR_MAP_0_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF NO MOTION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_0 Description - Reg Addr --> 0x55, Bit -->3 */
+#define SMI130_USER_INTR_MAP_0_INTR1_NOMOTION__POS (3)
+#define SMI130_USER_INTR_MAP_0_INTR1_NOMOTION__LEN (1)
+#define SMI130_USER_INTR_MAP_0_INTR1_NOMOTION__MSK (0x08)
+#define SMI130_USER_INTR_MAP_0_INTR1_NOMOTION__REG (SMI130_USER_INTR_MAP_0_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF DOUBLE TAP LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_0 Description - Reg Addr --> 0x55, Bit -->4 */
+#define SMI130_USER_INTR_MAP_0_INTR1_DOUBLE_TAP__POS (4)
+#define SMI130_USER_INTR_MAP_0_INTR1_DOUBLE_TAP__LEN (1)
+#define SMI130_USER_INTR_MAP_0_INTR1_DOUBLE_TAP__MSK (0x10)
+#define SMI130_USER_INTR_MAP_0_INTR1_DOUBLE_TAP__REG \
+(SMI130_USER_INTR_MAP_0_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF SINGLE TAP LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_0 Description - Reg Addr --> 0x55, Bit -->5 */
+#define SMI130_USER_INTR_MAP_0_INTR1_SINGLE_TAP__POS (5)
+#define SMI130_USER_INTR_MAP_0_INTR1_SINGLE_TAP__LEN (1)
+#define SMI130_USER_INTR_MAP_0_INTR1_SINGLE_TAP__MSK (0x20)
+#define SMI130_USER_INTR_MAP_0_INTR1_SINGLE_TAP__REG \
+(SMI130_USER_INTR_MAP_0_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF ORIENT LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_0 Description - Reg Addr --> 0x55, Bit -->6 */
+#define SMI130_USER_INTR_MAP_0_INTR1_ORIENT__POS (6)
+#define SMI130_USER_INTR_MAP_0_INTR1_ORIENT__LEN (1)
+#define SMI130_USER_INTR_MAP_0_INTR1_ORIENT__MSK (0x40)
+#define SMI130_USER_INTR_MAP_0_INTR1_ORIENT__REG \
+(SMI130_USER_INTR_MAP_0_ADDR)
+/**************************************************************/
+/**\name INTERRUPT MAPPIONG OF FLAT LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_0 Description - Reg Addr --> 0x56, Bit -->7 */
+#define SMI130_USER_INTR_MAP_0_INTR1_FLAT__POS (7)
+#define SMI130_USER_INTR_MAP_0_INTR1_FLAT__LEN (1)
+#define SMI130_USER_INTR_MAP_0_INTR1_FLAT__MSK (0x80)
+#define SMI130_USER_INTR_MAP_0_INTR1_FLAT__REG (SMI130_USER_INTR_MAP_0_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF PMU TRIGGER LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->0 */
+#define SMI130_USER_INTR_MAP_1_INTR2_PMU_TRIG__POS (0)
+#define SMI130_USER_INTR_MAP_1_INTR2_PMU_TRIG__LEN (1)
+#define SMI130_USER_INTR_MAP_1_INTR2_PMU_TRIG__MSK (0x01)
+#define SMI130_USER_INTR_MAP_1_INTR2_PMU_TRIG__REG (SMI130_USER_INTR_MAP_1_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF FIFO FULL AND
+ WATER MARK LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->1 */
+#define SMI130_USER_INTR_MAP_1_INTR2_FIFO_FULL__POS (1)
+#define SMI130_USER_INTR_MAP_1_INTR2_FIFO_FULL__LEN (1)
+#define SMI130_USER_INTR_MAP_1_INTR2_FIFO_FULL__MSK (0x02)
+#define SMI130_USER_INTR_MAP_1_INTR2_FIFO_FULL__REG \
+(SMI130_USER_INTR_MAP_1_ADDR)
+
+/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->2 */
+#define SMI130_USER_INTR_MAP_1_INTR2_FIFO_WM__POS (2)
+#define SMI130_USER_INTR_MAP_1_INTR2_FIFO_WM__LEN (1)
+#define SMI130_USER_INTR_MAP_1_INTR2_FIFO_WM__MSK (0x04)
+#define SMI130_USER_INTR_MAP_1_INTR2_FIFO_WM__REG \
+(SMI130_USER_INTR_MAP_1_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF DATA READY LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->3 */
+#define SMI130_USER_INTR_MAP_1_INTR2_DATA_RDY__POS (3)
+#define SMI130_USER_INTR_MAP_1_INTR2_DATA_RDY__LEN (1)
+#define SMI130_USER_INTR_MAP_1_INTR2_DATA_RDY__MSK (0x08)
+#define SMI130_USER_INTR_MAP_1_INTR2_DATA_RDY__REG \
+(SMI130_USER_INTR_MAP_1_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF PMU TRIGGER LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->4 */
+#define SMI130_USER_INTR_MAP_1_INTR1_PMU_TRIG__POS (4)
+#define SMI130_USER_INTR_MAP_1_INTR1_PMU_TRIG__LEN (1)
+#define SMI130_USER_INTR_MAP_1_INTR1_PMU_TRIG__MSK (0x10)
+#define SMI130_USER_INTR_MAP_1_INTR1_PMU_TRIG__REG (SMI130_USER_INTR_MAP_1_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF FIFO FULL AND
+ WATER MARK LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->5 */
+#define SMI130_USER_INTR_MAP_1_INTR1_FIFO_FULL__POS (5)
+#define SMI130_USER_INTR_MAP_1_INTR1_FIFO_FULL__LEN (1)
+#define SMI130_USER_INTR_MAP_1_INTR1_FIFO_FULL__MSK (0x20)
+#define SMI130_USER_INTR_MAP_1_INTR1_FIFO_FULL__REG \
+(SMI130_USER_INTR_MAP_1_ADDR)
+
+/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->6 */
+#define SMI130_USER_INTR_MAP_1_INTR1_FIFO_WM__POS (6)
+#define SMI130_USER_INTR_MAP_1_INTR1_FIFO_WM__LEN (1)
+#define SMI130_USER_INTR_MAP_1_INTR1_FIFO_WM__MSK (0x40)
+#define SMI130_USER_INTR_MAP_1_INTR1_FIFO_WM__REG \
+(SMI130_USER_INTR_MAP_1_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF DATA READY LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->7 */
+#define SMI130_USER_INTR_MAP_1_INTR1_DATA_RDY__POS (7)
+#define SMI130_USER_INTR_MAP_1_INTR1_DATA_RDY__LEN (1)
+#define SMI130_USER_INTR_MAP_1_INTR1_DATA_RDY__MSK (0x80)
+#define SMI130_USER_INTR_MAP_1_INTR1_DATA_RDY__REG \
+(SMI130_USER_INTR_MAP_1_ADDR)
+/**************************************************************/
+/**\name INTERRUPT2 MAPPIONG OF LOW_G LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->0 */
+#define SMI130_USER_INTR_MAP_2_INTR2_LOW_G__POS (0)
+#define SMI130_USER_INTR_MAP_2_INTR2_LOW_G__LEN (1)
+#define SMI130_USER_INTR_MAP_2_INTR2_LOW_G__MSK (0x01)
+#define SMI130_USER_INTR_MAP_2_INTR2_LOW_G__REG (SMI130_USER_INTR_MAP_2_ADDR)
+/**************************************************************/
+/**\name INTERRUPT2 MAPPIONG OF HIGH_G LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->1 */
+#define SMI130_USER_INTR_MAP_2_INTR2_HIGH_G__POS (1)
+#define SMI130_USER_INTR_MAP_2_INTR2_HIGH_G__LEN (1)
+#define SMI130_USER_INTR_MAP_2_INTR2_HIGH_G__MSK (0x02)
+#define SMI130_USER_INTR_MAP_2_INTR2_HIGH_G__REG \
+(SMI130_USER_INTR_MAP_2_ADDR)
+/**************************************************************/
+/**\name INTERRUPT2 MAPPIONG OF ANY MOTION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->2 */
+#define SMI130_USER_INTR_MAP_2_INTR2_ANY_MOTION__POS (2)
+#define SMI130_USER_INTR_MAP_2_INTR2_ANY_MOTION__LEN (1)
+#define SMI130_USER_INTR_MAP_2_INTR2_ANY_MOTION__MSK (0x04)
+#define SMI130_USER_INTR_MAP_2_INTR2_ANY_MOTION__REG \
+(SMI130_USER_INTR_MAP_2_ADDR)
+/**************************************************************/
+/**\name INTERRUPT2 MAPPIONG OF NO MOTION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->3 */
+#define SMI130_USER_INTR_MAP_2_INTR2_NOMOTION__POS (3)
+#define SMI130_USER_INTR_MAP_2_INTR2_NOMOTION__LEN (1)
+#define SMI130_USER_INTR_MAP_2_INTR2_NOMOTION__MSK (0x08)
+#define SMI130_USER_INTR_MAP_2_INTR2_NOMOTION__REG (SMI130_USER_INTR_MAP_2_ADDR)
+/**************************************************************/
+/**\name INTERRUPT2 MAPPIONG OF DOUBLE TAP LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->4 */
+#define SMI130_USER_INTR_MAP_2_INTR2_DOUBLE_TAP__POS (4)
+#define SMI130_USER_INTR_MAP_2_INTR2_DOUBLE_TAP__LEN (1)
+#define SMI130_USER_INTR_MAP_2_INTR2_DOUBLE_TAP__MSK (0x10)
+#define SMI130_USER_INTR_MAP_2_INTR2_DOUBLE_TAP__REG \
+(SMI130_USER_INTR_MAP_2_ADDR)
+/**************************************************************/
+/**\name INTERRUPT2 MAPPIONG OF SINGLE TAP LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->5 */
+#define SMI130_USER_INTR_MAP_2_INTR2_SINGLE_TAP__POS (5)
+#define SMI130_USER_INTR_MAP_2_INTR2_SINGLE_TAP__LEN (1)
+#define SMI130_USER_INTR_MAP_2_INTR2_SINGLE_TAP__MSK (0x20)
+#define SMI130_USER_INTR_MAP_2_INTR2_SINGLE_TAP__REG \
+(SMI130_USER_INTR_MAP_2_ADDR)
+/**************************************************************/
+/**\name INTERRUPT2 MAPPIONG OF ORIENT LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->6 */
+#define SMI130_USER_INTR_MAP_2_INTR2_ORIENT__POS (6)
+#define SMI130_USER_INTR_MAP_2_INTR2_ORIENT__LEN (1)
+#define SMI130_USER_INTR_MAP_2_INTR2_ORIENT__MSK (0x40)
+#define SMI130_USER_INTR_MAP_2_INTR2_ORIENT__REG \
+(SMI130_USER_INTR_MAP_2_ADDR)
+/**************************************************************/
+/**\name INTERRUPT2 MAPPIONG OF FLAT LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->7 */
+#define SMI130_USER_INTR_MAP_2_INTR2_FLAT__POS (7)
+#define SMI130_USER_INTR_MAP_2_INTR2_FLAT__LEN (1)
+#define SMI130_USER_INTR_MAP_2_INTR2_FLAT__MSK (0x80)
+#define SMI130_USER_INTR_MAP_2_INTR2_FLAT__REG (SMI130_USER_INTR_MAP_2_ADDR)
+
+/**************************************************************/
+/**\name TAP SOURCE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Data_0 Description - Reg Addr --> 0x58, Bit --> 3 */
+#define SMI130_USER_INTR_DATA_0_INTR_TAP_SOURCE__POS (3)
+#define SMI130_USER_INTR_DATA_0_INTR_TAP_SOURCE__LEN (1)
+#define SMI130_USER_INTR_DATA_0_INTR_TAP_SOURCE__MSK (0x08)
+#define SMI130_USER_INTR_DATA_0_INTR_TAP_SOURCE__REG \
+(SMI130_USER_INTR_DATA_0_ADDR)
+
+/**************************************************************/
+/**\name HIGH SOURCE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Data_0 Description - Reg Addr --> 0x58, Bit --> 7 */
+#define SMI130_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE__POS (7)
+#define SMI130_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE__LEN (1)
+#define SMI130_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE__MSK (0x80)
+#define SMI130_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE__REG \
+(SMI130_USER_INTR_DATA_0_ADDR)
+
+/**************************************************************/
+/**\name MOTION SOURCE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Data_1 Description - Reg Addr --> 0x59, Bit --> 7 */
+#define SMI130_USER_INTR_DATA_1_INTR_MOTION_SOURCE__POS (7)
+#define SMI130_USER_INTR_DATA_1_INTR_MOTION_SOURCE__LEN (1)
+#define SMI130_USER_INTR_DATA_1_INTR_MOTION_SOURCE__MSK (0x80)
+#define SMI130_USER_INTR_DATA_1_INTR_MOTION_SOURCE__REG \
+ (SMI130_USER_INTR_DATA_1_ADDR)
+/**************************************************************/
+/**\name LOW HIGH DURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_LowHigh_0 Description - Reg Addr --> 0x5a, Bit --> 0...7 */
+#define SMI130_USER_INTR_LOWHIGH_0_INTR_LOW_DURN__POS (0)
+#define SMI130_USER_INTR_LOWHIGH_0_INTR_LOW_DURN__LEN (8)
+#define SMI130_USER_INTR_LOWHIGH_0_INTR_LOW_DURN__MSK (0xFF)
+#define SMI130_USER_INTR_LOWHIGH_0_INTR_LOW_DURN__REG \
+ (SMI130_USER_INTR_LOWHIGH_0_ADDR)
+/**************************************************************/
+/**\name LOW THRESHOLD LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_LowHigh_1 Description - Reg Addr --> 0x5b, Bit --> 0...7 */
+#define SMI130_USER_INTR_LOWHIGH_1_INTR_LOW_THRES__POS (0)
+#define SMI130_USER_INTR_LOWHIGH_1_INTR_LOW_THRES__LEN (8)
+#define SMI130_USER_INTR_LOWHIGH_1_INTR_LOW_THRES__MSK (0xFF)
+#define SMI130_USER_INTR_LOWHIGH_1_INTR_LOW_THRES__REG \
+ (SMI130_USER_INTR_LOWHIGH_1_ADDR)
+/**************************************************************/
+/**\name LOW HYSTERESIS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_LowHigh_2 Description - Reg Addr --> 0x5c, Bit --> 0...1 */
+#define SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST__POS (0)
+#define SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST__LEN (2)
+#define SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST__MSK (0x03)
+#define SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST__REG \
+ (SMI130_USER_INTR_LOWHIGH_2_ADDR)
+/**************************************************************/
+/**\name LOW MODE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_LowHigh_2 Description - Reg Addr --> 0x5c, Bit --> 2 */
+#define SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE__POS (2)
+#define SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE__LEN (1)
+#define SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE__MSK (0x04)
+#define SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE__REG \
+ (SMI130_USER_INTR_LOWHIGH_2_ADDR)
+/**************************************************************/
+/**\name HIGH_G HYSTERESIS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_LowHigh_2 Description - Reg Addr --> 0x5c, Bit --> 6...7 */
+#define SMI130_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST__POS (6)
+#define SMI130_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST__LEN (2)
+#define SMI130_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST__MSK (0xC0)
+#define SMI130_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST__REG \
+ (SMI130_USER_INTR_LOWHIGH_2_ADDR)
+/**************************************************************/
+/**\name HIGH_G DURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_LowHigh_3 Description - Reg Addr --> 0x5d, Bit --> 0...7 */
+#define SMI130_USER_INTR_LOWHIGH_3_INTR_HIGH_G_DURN__POS (0)
+#define SMI130_USER_INTR_LOWHIGH_3_INTR_HIGH_G_DURN__LEN (8)
+#define SMI130_USER_INTR_LOWHIGH_3_INTR_HIGH_G_DURN__MSK (0xFF)
+#define SMI130_USER_INTR_LOWHIGH_3_INTR_HIGH_G_DURN__REG \
+ (SMI130_USER_INTR_LOWHIGH_3_ADDR)
+/**************************************************************/
+/**\name HIGH_G THRESHOLD LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_LowHigh_4 Description - Reg Addr --> 0x5e, Bit --> 0...7 */
+#define SMI130_USER_INTR_LOWHIGH_4_INTR_HIGH_THRES__POS (0)
+#define SMI130_USER_INTR_LOWHIGH_4_INTR_HIGH_THRES__LEN (8)
+#define SMI130_USER_INTR_LOWHIGH_4_INTR_HIGH_THRES__MSK (0xFF)
+#define SMI130_USER_INTR_LOWHIGH_4_INTR_HIGH_THRES__REG \
+ (SMI130_USER_INTR_LOWHIGH_4_ADDR)
+/**************************************************************/
+/**\name ANY MOTION DURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Motion_0 Description - Reg Addr --> 0x5f, Bit --> 0...1 */
+#define SMI130_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN__POS (0)
+#define SMI130_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN__LEN (2)
+#define SMI130_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN__MSK (0x03)
+#define SMI130_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN__REG \
+ (SMI130_USER_INTR_MOTION_0_ADDR)
+/**************************************************************/
+/**\name SLOW/NO MOTION DURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+ /* Int_Motion_0 Description - Reg Addr --> 0x5f, Bit --> 2...7 */
+#define SMI130_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN__POS (2)
+#define SMI130_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN__LEN (6)
+#define SMI130_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN__MSK (0xFC)
+#define SMI130_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN__REG \
+ (SMI130_USER_INTR_MOTION_0_ADDR)
+/**************************************************************/
+/**\name ANY MOTION THRESHOLD LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Motion_1 Description - Reg Addr --> (0x60), Bit --> 0...7 */
+#define SMI130_USER_INTR_MOTION_1_INTR_ANY_MOTION_THRES__POS (0)
+#define SMI130_USER_INTR_MOTION_1_INTR_ANY_MOTION_THRES__LEN (8)
+#define SMI130_USER_INTR_MOTION_1_INTR_ANY_MOTION_THRES__MSK (0xFF)
+#define SMI130_USER_INTR_MOTION_1_INTR_ANY_MOTION_THRES__REG \
+ (SMI130_USER_INTR_MOTION_1_ADDR)
+/**************************************************************/
+/**\name SLOW/NO MOTION THRESHOLD LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Motion_2 Description - Reg Addr --> 0x61, Bit --> 0...7 */
+#define SMI130_USER_INTR_MOTION_2_INTR_SLOW_NO_MOTION_THRES__POS (0)
+#define SMI130_USER_INTR_MOTION_2_INTR_SLOW_NO_MOTION_THRES__LEN (8)
+#define SMI130_USER_INTR_MOTION_2_INTR_SLOW_NO_MOTION_THRES__MSK (0xFF)
+#define SMI130_USER_INTR_MOTION_2_INTR_SLOW_NO_MOTION_THRES__REG \
+ (SMI130_USER_INTR_MOTION_2_ADDR)
+/**************************************************************/
+/**\name SLOW/NO MOTION SELECT LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Motion_3 Description - Reg Addr --> (0x62), Bit --> 0 */
+#define SMI130_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT__POS (0)
+#define SMI130_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT__LEN (1)
+#define SMI130_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT__MSK (0x01)
+#define SMI130_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT__REG \
+(SMI130_USER_INTR_MOTION_3_ADDR)
+/**************************************************************/
+/**\name SIGNIFICANT MOTION SELECT LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Motion_3 Description - Reg Addr --> (0x62), Bit --> 1 */
+#define SMI130_USER_INTR_SIGNIFICATION_MOTION_SELECT__POS (1)
+#define SMI130_USER_INTR_SIGNIFICATION_MOTION_SELECT__LEN (1)
+#define SMI130_USER_INTR_SIGNIFICATION_MOTION_SELECT__MSK (0x02)
+#define SMI130_USER_INTR_SIGNIFICATION_MOTION_SELECT__REG \
+ (SMI130_USER_INTR_MOTION_3_ADDR)
+
+/* Int_Motion_3 Description - Reg Addr --> (0x62), Bit --> 3..2 */
+#define SMI130_USER_INTR_SIGNIFICANT_MOTION_SKIP__POS (2)
+#define SMI130_USER_INTR_SIGNIFICANT_MOTION_SKIP__LEN (2)
+#define SMI130_USER_INTR_SIGNIFICANT_MOTION_SKIP__MSK (0x0C)
+#define SMI130_USER_INTR_SIGNIFICANT_MOTION_SKIP__REG \
+ (SMI130_USER_INTR_MOTION_3_ADDR)
+
+/* Int_Motion_3 Description - Reg Addr --> (0x62), Bit --> 5..4 */
+#define SMI130_USER_INTR_SIGNIFICANT_MOTION_PROOF__POS (4)
+#define SMI130_USER_INTR_SIGNIFICANT_MOTION_PROOF__LEN (2)
+#define SMI130_USER_INTR_SIGNIFICANT_MOTION_PROOF__MSK (0x30)
+#define SMI130_USER_INTR_SIGNIFICANT_MOTION_PROOF__REG \
+ (SMI130_USER_INTR_MOTION_3_ADDR)
+/**************************************************************/
+/**\name TAP DURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* INT_TAP_0 Description - Reg Addr --> (0x63), Bit --> 0..2*/
+#define SMI130_USER_INTR_TAP_0_INTR_TAP_DURN__POS (0)
+#define SMI130_USER_INTR_TAP_0_INTR_TAP_DURN__LEN (3)
+#define SMI130_USER_INTR_TAP_0_INTR_TAP_DURN__MSK (0x07)
+#define SMI130_USER_INTR_TAP_0_INTR_TAP_DURN__REG \
+(SMI130_USER_INTR_TAP_0_ADDR)
+/**************************************************************/
+/**\name TAP SHOCK LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Tap_0 Description - Reg Addr --> (0x63), Bit --> 6 */
+#define SMI130_USER_INTR_TAP_0_INTR_TAP_SHOCK__POS (6)
+#define SMI130_USER_INTR_TAP_0_INTR_TAP_SHOCK__LEN (1)
+#define SMI130_USER_INTR_TAP_0_INTR_TAP_SHOCK__MSK (0x40)
+#define SMI130_USER_INTR_TAP_0_INTR_TAP_SHOCK__REG (SMI130_USER_INTR_TAP_0_ADDR)
+/**************************************************************/
+/**\name TAP QUIET LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Tap_0 Description - Reg Addr --> (0x63), Bit --> 7 */
+#define SMI130_USER_INTR_TAP_0_INTR_TAP_QUIET__POS (7)
+#define SMI130_USER_INTR_TAP_0_INTR_TAP_QUIET__LEN (1)
+#define SMI130_USER_INTR_TAP_0_INTR_TAP_QUIET__MSK (0x80)
+#define SMI130_USER_INTR_TAP_0_INTR_TAP_QUIET__REG (SMI130_USER_INTR_TAP_0_ADDR)
+/**************************************************************/
+/**\name TAP THRESHOLD LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Tap_1 Description - Reg Addr --> (0x64), Bit --> 0...4 */
+#define SMI130_USER_INTR_TAP_1_INTR_TAP_THRES__POS (0)
+#define SMI130_USER_INTR_TAP_1_INTR_TAP_THRES__LEN (5)
+#define SMI130_USER_INTR_TAP_1_INTR_TAP_THRES__MSK (0x1F)
+#define SMI130_USER_INTR_TAP_1_INTR_TAP_THRES__REG (SMI130_USER_INTR_TAP_1_ADDR)
+/**************************************************************/
+/**\name ORIENT MODE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Orient_0 Description - Reg Addr --> (0x65), Bit --> 0...1 */
+#define SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_MODE__POS (0)
+#define SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_MODE__LEN (2)
+#define SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_MODE__MSK (0x03)
+#define SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_MODE__REG \
+ (SMI130_USER_INTR_ORIENT_0_ADDR)
+/**************************************************************/
+/**\name ORIENT BLOCKING LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Orient_0 Description - Reg Addr --> (0x65), Bit --> 2...3 */
+#define SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING__POS (2)
+#define SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING__LEN (2)
+#define SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING__MSK (0x0C)
+#define SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING__REG \
+ (SMI130_USER_INTR_ORIENT_0_ADDR)
+/**************************************************************/
+/**\name ORIENT HYSTERESIS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Orient_0 Description - Reg Addr --> (0x65), Bit --> 4...7 */
+#define SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_HYST__POS (4)
+#define SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_HYST__LEN (4)
+#define SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_HYST__MSK (0xF0)
+#define SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_HYST__REG \
+ (SMI130_USER_INTR_ORIENT_0_ADDR)
+/**************************************************************/
+/**\name ORIENT THETA LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Orient_1 Description - Reg Addr --> 0x66, Bit --> 0...5 */
+#define SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_THETA__POS (0)
+#define SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_THETA__LEN (6)
+#define SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_THETA__MSK (0x3F)
+#define SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_THETA__REG \
+ (SMI130_USER_INTR_ORIENT_1_ADDR)
+/**************************************************************/
+/**\name ORIENT UD LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Orient_1 Description - Reg Addr --> 0x66, Bit --> 6 */
+#define SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE__POS (6)
+#define SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE__MSK (0x40)
+#define SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE__REG \
+ (SMI130_USER_INTR_ORIENT_1_ADDR)
+/**************************************************************/
+/**\name ORIENT AXIS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Orient_1 Description - Reg Addr --> 0x66, Bit --> 7 */
+#define SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX__POS (7)
+#define SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX__LEN (1)
+#define SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX__MSK (0x80)
+#define SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX__REG \
+ (SMI130_USER_INTR_ORIENT_1_ADDR)
+/**************************************************************/
+/**\name FLAT THETA LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Flat_0 Description - Reg Addr --> 0x67, Bit --> 0...5 */
+#define SMI130_USER_INTR_FLAT_0_INTR_FLAT_THETA__POS (0)
+#define SMI130_USER_INTR_FLAT_0_INTR_FLAT_THETA__LEN (6)
+#define SMI130_USER_INTR_FLAT_0_INTR_FLAT_THETA__MSK (0x3F)
+#define SMI130_USER_INTR_FLAT_0_INTR_FLAT_THETA__REG \
+ (SMI130_USER_INTR_FLAT_0_ADDR)
+/**************************************************************/
+/**\name FLAT HYSTERESIS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Flat_1 Description - Reg Addr --> (0x68), Bit --> 0...3 */
+#define SMI130_USER_INTR_FLAT_1_INTR_FLAT_HYST__POS (0)
+#define SMI130_USER_INTR_FLAT_1_INTR_FLAT_HYST__LEN (4)
+#define SMI130_USER_INTR_FLAT_1_INTR_FLAT_HYST__MSK (0x0F)
+#define SMI130_USER_INTR_FLAT_1_INTR_FLAT_HYST__REG \
+(SMI130_USER_INTR_FLAT_1_ADDR)
+/**************************************************************/
+/**\name FLAT HOLD LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Flat_1 Description - Reg Addr --> (0x68), Bit --> 4...5 */
+#define SMI130_USER_INTR_FLAT_1_INTR_FLAT_HOLD__POS (4)
+#define SMI130_USER_INTR_FLAT_1_INTR_FLAT_HOLD__LEN (2)
+#define SMI130_USER_INTR_FLAT_1_INTR_FLAT_HOLD__MSK (0x30)
+#define SMI130_USER_INTR_FLAT_1_INTR_FLAT_HOLD__REG \
+(SMI130_USER_INTR_FLAT_1_ADDR)
+/**************************************************************/
+/**\name FOC ACCEL XYZ LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Foc_Conf Description - Reg Addr --> (0x69), Bit --> 0...1 */
+#define SMI130_USER_FOC_ACCEL_Z__POS (0)
+#define SMI130_USER_FOC_ACCEL_Z__LEN (2)
+#define SMI130_USER_FOC_ACCEL_Z__MSK (0x03)
+#define SMI130_USER_FOC_ACCEL_Z__REG (SMI130_USER_FOC_CONFIG_ADDR)
+
+/* Foc_Conf Description - Reg Addr --> (0x69), Bit --> 2...3 */
+#define SMI130_USER_FOC_ACCEL_Y__POS (2)
+#define SMI130_USER_FOC_ACCEL_Y__LEN (2)
+#define SMI130_USER_FOC_ACCEL_Y__MSK (0x0C)
+#define SMI130_USER_FOC_ACCEL_Y__REG (SMI130_USER_FOC_CONFIG_ADDR)
+
+/* Foc_Conf Description - Reg Addr --> (0x69), Bit --> 4...5 */
+#define SMI130_USER_FOC_ACCEL_X__POS (4)
+#define SMI130_USER_FOC_ACCEL_X__LEN (2)
+#define SMI130_USER_FOC_ACCEL_X__MSK (0x30)
+#define SMI130_USER_FOC_ACCEL_X__REG (SMI130_USER_FOC_CONFIG_ADDR)
+/**************************************************************/
+/**\name FOC GYRO LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Foc_Conf Description - Reg Addr --> (0x69), Bit --> 6 */
+#define SMI130_USER_FOC_GYRO_ENABLE__POS (6)
+#define SMI130_USER_FOC_GYRO_ENABLE__LEN (1)
+#define SMI130_USER_FOC_GYRO_ENABLE__MSK (0x40)
+#define SMI130_USER_FOC_GYRO_ENABLE__REG \
+(SMI130_USER_FOC_CONFIG_ADDR)
+/**************************************************************/
+/**\name NVM PROGRAM LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* CONF Description - Reg Addr --> (0x6A), Bit --> 1 */
+#define SMI130_USER_CONFIG_NVM_PROG_ENABLE__POS (1)
+#define SMI130_USER_CONFIG_NVM_PROG_ENABLE__LEN (1)
+#define SMI130_USER_CONFIG_NVM_PROG_ENABLE__MSK (0x02)
+#define SMI130_USER_CONFIG_NVM_PROG_ENABLE__REG \
+(SMI130_USER_CONFIG_ADDR)
+
+/*IF_CONF Description - Reg Addr --> (0x6B), Bit --> 0 */
+
+#define SMI130_USER_IF_CONFIG_SPI3__POS (0)
+#define SMI130_USER_IF_CONFIG_SPI3__LEN (1)
+#define SMI130_USER_IF_CONFIG_SPI3__MSK (0x01)
+#define SMI130_USER_IF_CONFIG_SPI3__REG \
+(SMI130_USER_IF_CONFIG_ADDR)
+
+/*IF_CONF Description - Reg Addr --> (0x6B), Bit --> 5..4 */
+#define SMI130_USER_IF_CONFIG_IF_MODE__POS (4)
+#define SMI130_USER_IF_CONFIG_IF_MODE__LEN (2)
+#define SMI130_USER_IF_CONFIG_IF_MODE__MSK (0x30)
+#define SMI130_USER_IF_CONFIG_IF_MODE__REG \
+(SMI130_USER_IF_CONFIG_ADDR)
+/**************************************************************/
+/**\name GYRO SLEEP CONFIGURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Pmu_Trigger Description - Reg Addr --> 0x6c, Bit --> 0...2 */
+#define SMI130_USER_GYRO_SLEEP_TRIGGER__POS (0)
+#define SMI130_USER_GYRO_SLEEP_TRIGGER__LEN (3)
+#define SMI130_USER_GYRO_SLEEP_TRIGGER__MSK (0x07)
+#define SMI130_USER_GYRO_SLEEP_TRIGGER__REG (SMI130_USER_PMU_TRIGGER_ADDR)
+
+/* Pmu_Trigger Description - Reg Addr --> 0x6c, Bit --> 3...4 */
+#define SMI130_USER_GYRO_WAKEUP_TRIGGER__POS (3)
+#define SMI130_USER_GYRO_WAKEUP_TRIGGER__LEN (2)
+#define SMI130_USER_GYRO_WAKEUP_TRIGGER__MSK (0x18)
+#define SMI130_USER_GYRO_WAKEUP_TRIGGER__REG (SMI130_USER_PMU_TRIGGER_ADDR)
+
+/* Pmu_Trigger Description - Reg Addr --> 0x6c, Bit --> 5 */
+#define SMI130_USER_GYRO_SLEEP_STATE__POS (5)
+#define SMI130_USER_GYRO_SLEEP_STATE__LEN (1)
+#define SMI130_USER_GYRO_SLEEP_STATE__MSK (0x20)
+#define SMI130_USER_GYRO_SLEEP_STATE__REG (SMI130_USER_PMU_TRIGGER_ADDR)
+
+/* Pmu_Trigger Description - Reg Addr --> 0x6c, Bit --> 6 */
+#define SMI130_USER_GYRO_WAKEUP_INTR__POS (6)
+#define SMI130_USER_GYRO_WAKEUP_INTR__LEN (1)
+#define SMI130_USER_GYRO_WAKEUP_INTR__MSK (0x40)
+#define SMI130_USER_GYRO_WAKEUP_INTR__REG (SMI130_USER_PMU_TRIGGER_ADDR)
+/**************************************************************/
+/**\name ACCEL SELF TEST LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Self_Test Description - Reg Addr --> 0x6d, Bit --> 0...1 */
+#define SMI130_USER_ACCEL_SELFTEST_AXIS__POS (0)
+#define SMI130_USER_ACCEL_SELFTEST_AXIS__LEN (2)
+#define SMI130_USER_ACCEL_SELFTEST_AXIS__MSK (0x03)
+#define SMI130_USER_ACCEL_SELFTEST_AXIS__REG (SMI130_USER_SELF_TEST_ADDR)
+
+/* Self_Test Description - Reg Addr --> 0x6d, Bit --> 2 */
+#define SMI130_USER_ACCEL_SELFTEST_SIGN__POS (2)
+#define SMI130_USER_ACCEL_SELFTEST_SIGN__LEN (1)
+#define SMI130_USER_ACCEL_SELFTEST_SIGN__MSK (0x04)
+#define SMI130_USER_ACCEL_SELFTEST_SIGN__REG (SMI130_USER_SELF_TEST_ADDR)
+
+/* Self_Test Description - Reg Addr --> 0x6d, Bit --> 3 */
+#define SMI130_USER_SELFTEST_AMP__POS (3)
+#define SMI130_USER_SELFTEST_AMP__LEN (1)
+#define SMI130_USER_SELFTEST_AMP__MSK (0x08)
+#define SMI130_USER_SELFTEST_AMP__REG (SMI130_USER_SELF_TEST_ADDR)
+/**************************************************************/
+/**\name GYRO SELF TEST LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Self_Test Description - Reg Addr --> 0x6d, Bit --> 4 */
+#define SMI130_USER_GYRO_SELFTEST_START__POS (4)
+#define SMI130_USER_GYRO_SELFTEST_START__LEN (1)
+#define SMI130_USER_GYRO_SELFTEST_START__MSK (0x10)
+#define SMI130_USER_GYRO_SELFTEST_START__REG \
+(SMI130_USER_SELF_TEST_ADDR)
+/**************************************************************/
+/**\name NV_CONFIG LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* NV_CONF Description - Reg Addr --> (0x70), Bit --> 0 */
+#define SMI130_USER_NV_CONFIG_SPI_ENABLE__POS (0)
+#define SMI130_USER_NV_CONFIG_SPI_ENABLE__LEN (1)
+#define SMI130_USER_NV_CONFIG_SPI_ENABLE__MSK (0x01)
+#define SMI130_USER_NV_CONFIG_SPI_ENABLE__REG (SMI130_USER_NV_CONFIG_ADDR)
+
+/*IF_CONF Description - Reg Addr --> (0x70), Bit --> 1 */
+#define SMI130_USER_IF_CONFIG_I2C_WDT_SELECT__POS (1)
+#define SMI130_USER_IF_CONFIG_I2C_WDT_SELECT__LEN (1)
+#define SMI130_USER_IF_CONFIG_I2C_WDT_SELECT__MSK (0x02)
+#define SMI130_USER_IF_CONFIG_I2C_WDT_SELECT__REG \
+(SMI130_USER_NV_CONFIG_ADDR)
+
+/*IF_CONF Description - Reg Addr --> (0x70), Bit --> 2 */
+#define SMI130_USER_IF_CONFIG_I2C_WDT_ENABLE__POS (2)
+#define SMI130_USER_IF_CONFIG_I2C_WDT_ENABLE__LEN (1)
+#define SMI130_USER_IF_CONFIG_I2C_WDT_ENABLE__MSK (0x04)
+#define SMI130_USER_IF_CONFIG_I2C_WDT_ENABLE__REG \
+(SMI130_USER_NV_CONFIG_ADDR)
+
+/* NV_CONF Description - Reg Addr --> (0x70), Bit --> 3 */
+#define SMI130_USER_NV_CONFIG_SPARE0__POS (3)
+#define SMI130_USER_NV_CONFIG_SPARE0__LEN (1)
+#define SMI130_USER_NV_CONFIG_SPARE0__MSK (0x08)
+#define SMI130_USER_NV_CONFIG_SPARE0__REG (SMI130_USER_NV_CONFIG_ADDR)
+
+/* NV_CONF Description - Reg Addr --> (0x70), Bit --> 4...7 */
+#define SMI130_USER_NV_CONFIG_NVM_COUNTER__POS (4)
+#define SMI130_USER_NV_CONFIG_NVM_COUNTER__LEN (4)
+#define SMI130_USER_NV_CONFIG_NVM_COUNTER__MSK (0xF0)
+#define SMI130_USER_NV_CONFIG_NVM_COUNTER__REG (SMI130_USER_NV_CONFIG_ADDR)
+/**************************************************************/
+/**\name ACCEL MANUAL OFFSET LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Offset_0 Description - Reg Addr --> (0x71), Bit --> 0...7 */
+#define SMI130_USER_OFFSET_0_ACCEL_OFF_X__POS (0)
+#define SMI130_USER_OFFSET_0_ACCEL_OFF_X__LEN (8)
+#define SMI130_USER_OFFSET_0_ACCEL_OFF_X__MSK (0xFF)
+#define SMI130_USER_OFFSET_0_ACCEL_OFF_X__REG (SMI130_USER_OFFSET_0_ADDR)
+
+/* Offset_1 Description - Reg Addr --> 0x72, Bit --> 0...7 */
+#define SMI130_USER_OFFSET_1_ACCEL_OFF_Y__POS (0)
+#define SMI130_USER_OFFSET_1_ACCEL_OFF_Y__LEN (8)
+#define SMI130_USER_OFFSET_1_ACCEL_OFF_Y__MSK (0xFF)
+#define SMI130_USER_OFFSET_1_ACCEL_OFF_Y__REG (SMI130_USER_OFFSET_1_ADDR)
+
+/* Offset_2 Description - Reg Addr --> 0x73, Bit --> 0...7 */
+#define SMI130_USER_OFFSET_2_ACCEL_OFF_Z__POS (0)
+#define SMI130_USER_OFFSET_2_ACCEL_OFF_Z__LEN (8)
+#define SMI130_USER_OFFSET_2_ACCEL_OFF_Z__MSK (0xFF)
+#define SMI130_USER_OFFSET_2_ACCEL_OFF_Z__REG (SMI130_USER_OFFSET_2_ADDR)
+/**************************************************************/
+/**\name GYRO MANUAL OFFSET LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Offset_3 Description - Reg Addr --> 0x74, Bit --> 0...7 */
+#define SMI130_USER_OFFSET_3_GYRO_OFF_X__POS (0)
+#define SMI130_USER_OFFSET_3_GYRO_OFF_X__LEN (8)
+#define SMI130_USER_OFFSET_3_GYRO_OFF_X__MSK (0xFF)
+#define SMI130_USER_OFFSET_3_GYRO_OFF_X__REG (SMI130_USER_OFFSET_3_ADDR)
+
+/* Offset_4 Description - Reg Addr --> 0x75, Bit --> 0...7 */
+#define SMI130_USER_OFFSET_4_GYRO_OFF_Y__POS (0)
+#define SMI130_USER_OFFSET_4_GYRO_OFF_Y__LEN (8)
+#define SMI130_USER_OFFSET_4_GYRO_OFF_Y__MSK (0xFF)
+#define SMI130_USER_OFFSET_4_GYRO_OFF_Y__REG (SMI130_USER_OFFSET_4_ADDR)
+
+/* Offset_5 Description - Reg Addr --> 0x76, Bit --> 0...7 */
+#define SMI130_USER_OFFSET_5_GYRO_OFF_Z__POS (0)
+#define SMI130_USER_OFFSET_5_GYRO_OFF_Z__LEN (8)
+#define SMI130_USER_OFFSET_5_GYRO_OFF_Z__MSK (0xFF)
+#define SMI130_USER_OFFSET_5_GYRO_OFF_Z__REG (SMI130_USER_OFFSET_5_ADDR)
+
+
+/* Offset_6 Description - Reg Addr --> 0x77, Bit --> 0..1 */
+#define SMI130_USER_OFFSET_6_GYRO_OFF_X__POS (0)
+#define SMI130_USER_OFFSET_6_GYRO_OFF_X__LEN (2)
+#define SMI130_USER_OFFSET_6_GYRO_OFF_X__MSK (0x03)
+#define SMI130_USER_OFFSET_6_GYRO_OFF_X__REG (SMI130_USER_OFFSET_6_ADDR)
+
+/* Offset_6 Description - Reg Addr --> 0x77, Bit --> 2...3 */
+#define SMI130_USER_OFFSET_6_GYRO_OFF_Y__POS (2)
+#define SMI130_USER_OFFSET_6_GYRO_OFF_Y__LEN (2)
+#define SMI130_USER_OFFSET_6_GYRO_OFF_Y__MSK (0x0C)
+#define SMI130_USER_OFFSET_6_GYRO_OFF_Y__REG (SMI130_USER_OFFSET_6_ADDR)
+
+/* Offset_6 Description - Reg Addr --> 0x77, Bit --> 4...5 */
+#define SMI130_USER_OFFSET_6_GYRO_OFF_Z__POS (4)
+#define SMI130_USER_OFFSET_6_GYRO_OFF_Z__LEN (2)
+#define SMI130_USER_OFFSET_6_GYRO_OFF_Z__MSK (0x30)
+#define SMI130_USER_OFFSET_6_GYRO_OFF_Z__REG (SMI130_USER_OFFSET_6_ADDR)
+/**************************************************************/
+/**\name ACCEL OFFSET ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Offset_6 Description - Reg Addr --> 0x77, Bit --> 6 */
+#define SMI130_USER_OFFSET_6_ACCEL_OFF_ENABLE__POS (6)
+#define SMI130_USER_OFFSET_6_ACCEL_OFF_ENABLE__LEN (1)
+#define SMI130_USER_OFFSET_6_ACCEL_OFF_ENABLE__MSK (0x40)
+#define SMI130_USER_OFFSET_6_ACCEL_OFF_ENABLE__REG \
+(SMI130_USER_OFFSET_6_ADDR)
+/**************************************************************/
+/**\name GYRO OFFSET ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Offset_6 Description - Reg Addr --> 0x77, Bit --> 7 */
+#define SMI130_USER_OFFSET_6_GYRO_OFF_EN__POS (7)
+#define SMI130_USER_OFFSET_6_GYRO_OFF_EN__LEN (1)
+#define SMI130_USER_OFFSET_6_GYRO_OFF_EN__MSK (0x80)
+#define SMI130_USER_OFFSET_6_GYRO_OFF_EN__REG (SMI130_USER_OFFSET_6_ADDR)
+/**************************************************************/
+/**\name STEP COUNTER LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* STEP_CNT_0 Description - Reg Addr --> 0x78, Bit --> 0 to 7 */
+#define SMI130_USER_STEP_COUNT_LSB__POS (0)
+#define SMI130_USER_STEP_COUNT_LSB__LEN (7)
+#define SMI130_USER_STEP_COUNT_LSB__MSK (0xFF)
+#define SMI130_USER_STEP_COUNT_LSB__REG (SMI130_USER_STEP_COUNT_0_ADDR)
+
+/* STEP_CNT_1 Description - Reg Addr --> 0x79, Bit --> 0 to 7 */
+#define SMI130_USER_STEP_COUNT_MSB__POS (0)
+#define SMI130_USER_STEP_COUNT_MSB__LEN (7)
+#define SMI130_USER_STEP_COUNT_MSB__MSK (0xFF)
+#define SMI130_USER_STEP_COUNT_MSB__REG (SMI130_USER_STEP_COUNT_1_ADDR)
+/**************************************************************/
+/**\name STEP COUNTER CONFIGURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* STEP_CONFIG_0 Description - Reg Addr --> 0x7A, Bit --> 0 to 7 */
+#define SMI130_USER_STEP_CONFIG_ZERO__POS (0)
+#define SMI130_USER_STEP_CONFIG_ZERO__LEN (7)
+#define SMI130_USER_STEP_CONFIG_ZERO__MSK (0xFF)
+#define SMI130_USER_STEP_CONFIG_ZERO__REG \
+(SMI130_USER_STEP_CONFIG_0_ADDR)
+
+
+/* STEP_CONFIG_1 Description - Reg Addr --> 0x7B, Bit --> 0 to 2 and
+4 to 7 */
+#define SMI130_USER_STEP_CONFIG_ONE_CNF1__POS (0)
+#define SMI130_USER_STEP_CONFIG_ONE_CNF1__LEN (3)
+#define SMI130_USER_STEP_CONFIG_ONE_CNF1__MSK (0x07)
+#define SMI130_USER_STEP_CONFIG_ONE_CNF1__REG \
+(SMI130_USER_STEP_CONFIG_1_ADDR)
+
+#define SMI130_USER_STEP_CONFIG_ONE_CNF2__POS (4)
+#define SMI130_USER_STEP_CONFIG_ONE_CNF2__LEN (4)
+#define SMI130_USER_STEP_CONFIG_ONE_CNF2__MSK (0xF0)
+#define SMI130_USER_STEP_CONFIG_ONE_CNF2__REG \
+(SMI130_USER_STEP_CONFIG_1_ADDR)
+/**************************************************************/
+/**\name STEP COUNTER ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* STEP_CONFIG_1 Description - Reg Addr --> 0x7B, Bit --> 0 to 2 */
+#define SMI130_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE__POS (3)
+#define SMI130_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE__LEN (1)
+#define SMI130_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE__MSK (0x08)
+#define SMI130_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE__REG \
+(SMI130_USER_STEP_CONFIG_1_ADDR)
+
+/* USER REGISTERS DEFINITION END */
+/**************************************************************************/
+/* CMD REGISTERS DEFINITION START */
+/**************************************************************/
+/**\name COMMAND REGISTER LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Command description address - Reg Addr --> 0x7E, Bit --> 0....7 */
+#define SMI130_CMD_COMMANDS__POS (0)
+#define SMI130_CMD_COMMANDS__LEN (8)
+#define SMI130_CMD_COMMANDS__MSK (0xFF)
+#define SMI130_CMD_COMMANDS__REG (SMI130_CMD_COMMANDS_ADDR)
+/**************************************************************/
+/**\name PAGE ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Target page address - Reg Addr --> 0x7F, Bit --> 4....5 */
+#define SMI130_CMD_TARGET_PAGE__POS (4)
+#define SMI130_CMD_TARGET_PAGE__LEN (2)
+#define SMI130_CMD_TARGET_PAGE__MSK (0x30)
+#define SMI130_CMD_TARGET_PAGE__REG (SMI130_CMD_EXT_MODE_ADDR)
+
+/* Target page address - Reg Addr --> 0x7F, Bit --> 4....5 */
+#define SMI130_CMD_PAGING_EN__POS (7)
+#define SMI130_CMD_PAGING_EN__LEN (1)
+#define SMI130_CMD_PAGING_EN__MSK (0x80)
+#define SMI130_CMD_PAGING_EN__REG (SMI130_CMD_EXT_MODE_ADDR)
+
+/* Target page address - Reg Addr --> 0x7F, Bit --> 4....5 */
+#define SMI130_COM_C_TRIM_FIVE__POS (0)
+#define SMI130_COM_C_TRIM_FIVE__LEN (8)
+#define SMI130_COM_C_TRIM_FIVE__MSK (0xFF)
+#define SMI130_COM_C_TRIM_FIVE__REG (SMI130_COM_C_TRIM_FIVE_ADDR)
+
+/**************************************************************************/
+/* CMD REGISTERS DEFINITION END */
+
+/**************************************************/
+/**\name FIFO FRAME COUNT DEFINITION */
+/*************************************************/
+#define FIFO_FRAME (1024)
+#define FIFO_CONFIG_CHECK1 (0x00)
+#define FIFO_CONFIG_CHECK2 (0x80)
+/**************************************************/
+/**\name MAG SENSOR SELECT */
+/*************************************************/
+#define BST_BMM (0)
+#define BST_AKM (1)
+#define SMI130_YAS537_I2C_ADDRESS (0x2E)
+/**************************************************/
+/**\name ACCEL RANGE */
+/*************************************************/
+#define SMI130_ACCEL_RANGE_2G (0X03)
+#define SMI130_ACCEL_RANGE_4G (0X05)
+#define SMI130_ACCEL_RANGE_8G (0X08)
+#define SMI130_ACCEL_RANGE_16G (0X0C)
+/**************************************************/
+/**\name ACCEL ODR */
+/*************************************************/
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_RESERVED (0x00)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_0_78HZ (0x01)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_1_56HZ (0x02)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_3_12HZ (0x03)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_6_25HZ (0x04)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_12_5HZ (0x05)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_25HZ (0x06)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_50HZ (0x07)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_100HZ (0x08)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_200HZ (0x09)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_400HZ (0x0A)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_800HZ (0x0B)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_1600HZ (0x0C)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_RESERVED0 (0x0D)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_RESERVED1 (0x0E)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_RESERVED2 (0x0F)
+/**************************************************/
+/**\name ACCEL BANDWIDTH PARAMETER */
+/*************************************************/
+#define SMI130_ACCEL_OSR4_AVG1 (0x00)
+#define SMI130_ACCEL_OSR2_AVG2 (0x01)
+#define SMI130_ACCEL_NORMAL_AVG4 (0x02)
+#define SMI130_ACCEL_CIC_AVG8 (0x03)
+#define SMI130_ACCEL_RES_AVG16 (0x04)
+#define SMI130_ACCEL_RES_AVG32 (0x05)
+#define SMI130_ACCEL_RES_AVG64 (0x06)
+#define SMI130_ACCEL_RES_AVG128 (0x07)
+/**************************************************/
+/**\name GYRO ODR */
+/*************************************************/
+#define SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED (0x00)
+#define SMI130_GYRO_OUTPUT_DATA_RATE_25HZ (0x06)
+#define SMI130_GYRO_OUTPUT_DATA_RATE_50HZ (0x07)
+#define SMI130_GYRO_OUTPUT_DATA_RATE_100HZ (0x08)
+#define SMI130_GYRO_OUTPUT_DATA_RATE_200HZ (0x09)
+#define SMI130_GYRO_OUTPUT_DATA_RATE_400HZ (0x0A)
+#define SMI130_GYRO_OUTPUT_DATA_RATE_800HZ (0x0B)
+#define SMI130_GYRO_OUTPUT_DATA_RATE_1600HZ (0x0C)
+#define SMI130_GYRO_OUTPUT_DATA_RATE_3200HZ (0x0D)
+/**************************************************/
+/**\name GYRO BANDWIDTH PARAMETER */
+/*************************************************/
+#define SMI130_GYRO_OSR4_MODE (0x00)
+#define SMI130_GYRO_OSR2_MODE (0x01)
+#define SMI130_GYRO_NORMAL_MODE (0x02)
+#define SMI130_GYRO_CIC_MODE (0x03)
+/**************************************************/
+/**\name GYROSCOPE RANGE PARAMETER */
+/*************************************************/
+#define SMI130_GYRO_RANGE_2000_DEG_SEC (0x00)
+#define SMI130_GYRO_RANGE_1000_DEG_SEC (0x01)
+#define SMI130_GYRO_RANGE_500_DEG_SEC (0x02)
+#define SMI130_GYRO_RANGE_250_DEG_SEC (0x03)
+#define SMI130_GYRO_RANGE_125_DEG_SEC (0x04)
+/**************************************************/
+/**\name MAG ODR */
+/*************************************************/
+#define SMI130_MAG_OUTPUT_DATA_RATE_RESERVED (0x00)
+#define SMI130_MAG_OUTPUT_DATA_RATE_0_78HZ (0x01)
+#define SMI130_MAG_OUTPUT_DATA_RATE_1_56HZ (0x02)
+#define SMI130_MAG_OUTPUT_DATA_RATE_3_12HZ (0x03)
+#define SMI130_MAG_OUTPUT_DATA_RATE_6_25HZ (0x04)
+#define SMI130_MAG_OUTPUT_DATA_RATE_12_5HZ (0x05)
+#define SMI130_MAG_OUTPUT_DATA_RATE_25HZ (0x06)
+#define SMI130_MAG_OUTPUT_DATA_RATE_50HZ (0x07)
+#define SMI130_MAG_OUTPUT_DATA_RATE_100HZ (0x08)
+#define SMI130_MAG_OUTPUT_DATA_RATE_200HZ (0x09)
+#define SMI130_MAG_OUTPUT_DATA_RATE_400HZ (0x0A)
+#define SMI130_MAG_OUTPUT_DATA_RATE_800HZ (0x0B)
+#define SMI130_MAG_OUTPUT_DATA_RATE_1600HZ (0x0C)
+#define SMI130_MAG_OUTPUT_DATA_RATE_RESERVED0 (0x0D)
+#define SMI130_MAG_OUTPUT_DATA_RATE_RESERVED1 (0x0E)
+#define SMI130_MAG_OUTPUT_DATA_RATE_RESERVED2 (0x0F)
+
+/**************************************************/
+/**\name ENABLE/DISABLE SELECTIONS */
+/*************************************************/
+
+/* Enable accel and gyro offset */
+#define ACCEL_OFFSET_ENABLE (0x01)
+#define GYRO_OFFSET_ENABLE (0x01)
+
+/* command register definition */
+#define START_FOC_ACCEL_GYRO (0X03)
+
+ /* INT ENABLE 1 */
+#define SMI130_ANY_MOTION_X_ENABLE (0)
+#define SMI130_ANY_MOTION_Y_ENABLE (1)
+#define SMI130_ANY_MOTION_Z_ENABLE (2)
+#define SMI130_DOUBLE_TAP_ENABLE (4)
+#define SMI130_SINGLE_TAP_ENABLE (5)
+#define SMI130_ORIENT_ENABLE (6)
+#define SMI130_FLAT_ENABLE (7)
+
+/* INT ENABLE 1 */
+#define SMI130_HIGH_G_X_ENABLE (0)
+#define SMI130_HIGH_G_Y_ENABLE (1)
+#define SMI130_HIGH_G_Z_ENABLE (2)
+#define SMI130_LOW_G_ENABLE (3)
+#define SMI130_DATA_RDY_ENABLE (4)
+#define SMI130_FIFO_FULL_ENABLE (5)
+#define SMI130_FIFO_WM_ENABLE (6)
+
+/* INT ENABLE 2 */
+#define SMI130_NOMOTION_X_ENABLE (0)
+#define SMI130_NOMOTION_Y_ENABLE (1)
+#define SMI130_NOMOTION_Z_ENABLE (2)
+#define SMI130_STEP_DETECTOR_EN (3)
+
+/* FOC axis selection for accel*/
+#define FOC_X_AXIS (0)
+#define FOC_Y_AXIS (1)
+#define FOC_Z_AXIS (2)
+
+/* IN OUT CONTROL */
+#define SMI130_INTR1_EDGE_CTRL (0)
+#define SMI130_INTR2_EDGE_CTRL (1)
+#define SMI130_INTR1_LEVEL (0)
+#define SMI130_INTR2_LEVEL (1)
+#define SMI130_INTR1_OUTPUT_TYPE (0)
+#define SMI130_INTR2_OUTPUT_TYPE (1)
+#define SMI130_INTR1_OUTPUT_ENABLE (0)
+#define SMI130_INTR2_OUTPUT_ENABLE (1)
+
+#define SMI130_INTR1_INPUT_ENABLE (0)
+#define SMI130_INTR2_INPUT_ENABLE (1)
+
+/* INTERRUPT MAPS */
+#define SMI130_INTR1_MAP_LOW_G (0)
+#define SMI130_INTR2_MAP_LOW_G (1)
+#define SMI130_INTR1_MAP_HIGH_G (0)
+#define SMI130_INTR2_MAP_HIGH_G (1)
+#define SMI130_INTR1_MAP_ANY_MOTION (0)
+#define SMI130_INTR2_MAP_ANY_MOTION (1)
+#define SMI130_INTR1_MAP_NOMO (0)
+#define SMI130_INTR2_MAP_NOMO (1)
+#define SMI130_INTR1_MAP_DOUBLE_TAP (0)
+#define SMI130_INTR2_MAP_DOUBLE_TAP (1)
+#define SMI130_INTR1_MAP_SINGLE_TAP (0)
+#define SMI130_INTR2_MAP_SINGLE_TAP (1)
+#define SMI130_INTR1_MAP_ORIENT (0)
+#define SMI130_INTR2_MAP_ORIENT (1)
+#define SMI130_INTR1_MAP_FLAT (0)
+#define SMI130_INTR2_MAP_FLAT (1)
+#define SMI130_INTR1_MAP_DATA_RDY (0)
+#define SMI130_INTR2_MAP_DATA_RDY (1)
+#define SMI130_INTR1_MAP_FIFO_WM (0)
+#define SMI130_INTR2_MAP_FIFO_WM (1)
+#define SMI130_INTR1_MAP_FIFO_FULL (0)
+#define SMI130_INTR2_MAP_FIFO_FULL (1)
+#define SMI130_INTR1_MAP_PMUTRIG (0)
+#define SMI130_INTR2_MAP_PMUTRIG (1)
+
+/* Interrupt mapping*/
+#define SMI130_MAP_INTR1 (0)
+#define SMI130_MAP_INTR2 (1)
+/**************************************************/
+/**\name TAP DURATION */
+/*************************************************/
+#define SMI130_TAP_DURN_50MS (0x00)
+#define SMI130_TAP_DURN_100MS (0x01)
+#define SMI130_TAP_DURN_150MS (0x02)
+#define SMI130_TAP_DURN_200MS (0x03)
+#define SMI130_TAP_DURN_250MS (0x04)
+#define SMI130_TAP_DURN_375MS (0x05)
+#define SMI130_TAP_DURN_500MS (0x06)
+#define SMI130_TAP_DURN_700MS (0x07)
+/**************************************************/
+/**\name TAP SHOCK */
+/*************************************************/
+#define SMI130_TAP_SHOCK_50MS (0x00)
+#define SMI130_TAP_SHOCK_75MS (0x01)
+/**************************************************/
+/**\name TAP QUIET */
+/*************************************************/
+#define SMI130_TAP_QUIET_30MS (0x00)
+#define SMI130_TAP_QUIET_20MS (0x01)
+/**************************************************/
+/**\name STEP DETECTION SELECTION MODES */
+/*************************************************/
+#define SMI130_STEP_NORMAL_MODE (0)
+#define SMI130_STEP_SENSITIVE_MODE (1)
+#define SMI130_STEP_ROBUST_MODE (2)
+/**************************************************/
+/**\name STEP CONFIGURATION SELECT MODE */
+/*************************************************/
+#define STEP_CONFIG_NORMAL (0X315)
+#define STEP_CONFIG_SENSITIVE (0X2D)
+#define STEP_CONFIG_ROBUST (0X71D)
+/**************************************************/
+/**\name BMM150 TRIM DATA DEFINITIONS */
+/*************************************************/
+#define SMI130_MAG_DIG_X1 (0x5D)
+#define SMI130_MAG_DIG_Y1 (0x5E)
+#define SMI130_MAG_DIG_Z4_LSB (0x62)
+#define SMI130_MAG_DIG_Z4_MSB (0x63)
+#define SMI130_MAG_DIG_X2 (0x64)
+#define SMI130_MAG_DIG_Y2 (0x65)
+#define SMI130_MAG_DIG_Z2_LSB (0x68)
+#define SMI130_MAG_DIG_Z2_MSB (0x69)
+#define SMI130_MAG_DIG_Z1_LSB (0x6A)
+#define SMI130_MAG_DIG_Z1_MSB (0x6B)
+#define SMI130_MAG_DIG_XYZ1_LSB (0x6C)
+#define SMI130_MAG_DIG_XYZ1_MSB (0x6D)
+#define SMI130_MAG_DIG_Z3_LSB (0x6E)
+#define SMI130_MAG_DIG_Z3_MSB (0x6F)
+#define SMI130_MAG_DIG_XY2 (0x70)
+#define SMI130_MAG_DIG_XY1 (0x71)
+/**************************************************/
+/**\name BMM150 PRE-SET MODE DEFINITIONS */
+/*************************************************/
+#define SMI130_MAG_PRESETMODE_LOWPOWER (1)
+#define SMI130_MAG_PRESETMODE_REGULAR (2)
+#define SMI130_MAG_PRESETMODE_HIGHACCURACY (3)
+#define SMI130_MAG_PRESETMODE_ENHANCED (4)
+/**************************************************/
+/**\name BMM150 PRESET MODES - DATA RATES */
+/*************************************************/
+#define SMI130_MAG_LOWPOWER_DR (0x02)
+#define SMI130_MAG_REGULAR_DR (0x02)
+#define SMI130_MAG_HIGHACCURACY_DR (0x2A)
+#define SMI130_MAG_ENHANCED_DR (0x02)
+/**************************************************/
+/**\name BMM150 PRESET MODES - REPETITIONS-XY RATES */
+/*************************************************/
+#define SMI130_MAG_LOWPOWER_REPXY (1)
+#define SMI130_MAG_REGULAR_REPXY (4)
+#define SMI130_MAG_HIGHACCURACY_REPXY (23)
+#define SMI130_MAG_ENHANCED_REPXY (7)
+/**************************************************/
+/**\name BMM150 PRESET MODES - REPETITIONS-Z RATES */
+/*************************************************/
+#define SMI130_MAG_LOWPOWER_REPZ (2)
+#define SMI130_MAG_REGULAR_REPZ (14)
+#define SMI130_MAG_HIGHACCURACY_REPZ (82)
+#define SMI130_MAG_ENHANCED_REPZ (26)
+#define SMI130_MAG_NOAMRL_SWITCH_TIMES (5)
+#define MAG_INTERFACE_PMU_ENABLE (1)
+#define MAG_INTERFACE_PMU_DISABLE (0)
+/**************************************************/
+/**\name USED FOR MAG OVERFLOW CHECK FOR BMM150 */
+/*************************************************/
+#define SMI130_MAG_OVERFLOW_OUTPUT ((s16)-32768)
+#define SMI130_MAG_OVERFLOW_OUTPUT_S32 ((s32)(-2147483647-1))
+#define SMI130_MAG_NEGATIVE_SATURATION_Z ((s16)-32767)
+#define SMI130_MAG_POSITIVE_SATURATION_Z ((u16)32767)
+#define SMI130_MAG_FLIP_OVERFLOW_ADCVAL ((s16)-4096)
+#define SMI130_MAG_HALL_OVERFLOW_ADCVAL ((s16)-16384)
+/**************************************************/
+/**\name BMM150 REGISTER DEFINITION */
+/*************************************************/
+#define SMI130_BMM150_CHIP_ID (0x40)
+#define SMI130_BMM150_POWE_CONTROL_REG (0x4B)
+#define SMI130_BMM150_POWE_MODE_REG (0x4C)
+#define SMI130_BMM150_DATA_REG (0x42)
+#define SMI130_BMM150_XY_REP (0x51)
+#define SMI130_BMM150_Z_REP (0x52)
+/**************************************************/
+/**\name AKM COMPENSATING DATA REGISTERS */
+/*************************************************/
+#define SMI130_BST_AKM_ASAX (0x60)
+#define SMI130_BST_AKM_ASAY (0x61)
+#define SMI130_BST_AKM_ASAZ (0x62)
+/**************************************************/
+/**\name AKM POWER MODE SELECTION */
+/*************************************************/
+#define AKM_POWER_DOWN_MODE (0)
+#define AKM_SINGLE_MEAS_MODE (1)
+#define FUSE_ROM_MODE (2)
+/**************************************************/
+/**\name SECONDARY_MAG POWER MODE SELECTION */
+/*************************************************/
+#define SMI130_MAG_FORCE_MODE (0)
+#define SMI130_MAG_SUSPEND_MODE (1)
+/**************************************************/
+/**\name MAG POWER MODE SELECTION */
+/*************************************************/
+#define FORCE_MODE (0)
+#define SUSPEND_MODE (1)
+#define NORMAL_MODE (2)
+#define MAG_SUSPEND_MODE (1)
+/**************************************************/
+/**\name FIFO CONFIGURATIONS */
+/*************************************************/
+#define FIFO_HEADER_ENABLE (0x01)
+#define FIFO_MAG_ENABLE (0x01)
+#define FIFO_ACCEL_ENABLE (0x01)
+#define FIFO_GYRO_ENABLE (0x01)
+#define FIFO_TIME_ENABLE (0x01)
+#define FIFO_STOPONFULL_ENABLE (0x01)
+#define FIFO_WM_INTERRUPT_ENABLE (0x01)
+#define SMI130_FIFO_INDEX_LENGTH (1)
+#define SMI130_FIFO_TAG_INTR_MASK (0xFC)
+
+/**************************************************/
+/**\name ACCEL POWER MODE */
+/*************************************************/
+#define ACCEL_MODE_NORMAL (0x11)
+#define ACCEL_LOWPOWER (0X12)
+#define ACCEL_SUSPEND (0X10)
+/**************************************************/
+/**\name GYRO POWER MODE */
+/*************************************************/
+#define GYRO_MODE_SUSPEND (0x14)
+#define GYRO_MODE_NORMAL (0x15)
+#define GYRO_MODE_FASTSTARTUP (0x17)
+/**************************************************/
+/**\name MAG POWER MODE */
+/*************************************************/
+#define MAG_MODE_SUSPEND (0x18)
+#define MAG_MODE_NORMAL (0x19)
+#define MAG_MODE_LOWPOWER (0x1A)
+/**************************************************/
+/**\name ENABLE/DISABLE BIT VALUES */
+/*************************************************/
+#define SMI130_ENABLE (0x01)
+#define SMI130_DISABLE (0x00)
+/**************************************************/
+/**\name INTERRUPT EDGE TRIGGER ENABLE */
+/*************************************************/
+#define SMI130_EDGE (0x01)
+#define SMI130_LEVEL (0x00)
+/**************************************************/
+/**\name INTERRUPT LEVEL ENABLE */
+/*************************************************/
+#define SMI130_LEVEL_LOW (0x00)
+#define SMI130_LEVEL_HIGH (0x01)
+/**************************************************/
+/**\name INTERRUPT OUTPUT ENABLE */
+/*************************************************/
+#define SMI130_OPEN_DRAIN (0x01)
+#define SMI130_PUSH_PULL (0x00)
+
+/* interrupt output enable*/
+#define SMI130_INPUT (0x01)
+#define SMI130_OUTPUT (0x00)
+
+/**************************************************/
+/**\name INTERRUPT TAP SOURCE ENABLE */
+/*************************************************/
+#define FILTER_DATA (0x00)
+#define UNFILTER_DATA (0x01)
+/**************************************************/
+/**\name SLOW MOTION/ NO MOTION SELECT */
+/*************************************************/
+#define SLOW_MOTION (0x00)
+#define NO_MOTION (0x01)
+/**************************************************/
+/**\name SIGNIFICANT MOTION SELECTION */
+/*************************************************/
+#define ANY_MOTION (0x00)
+#define SIGNIFICANT_MOTION (0x01)
+/**************************************************/
+/**\name LATCH DURATION */
+/*************************************************/
+#define SMI130_LATCH_DUR_NONE (0x00)
+#define SMI130_LATCH_DUR_312_5_MICRO_SEC (0x01)
+#define SMI130_LATCH_DUR_625_MICRO_SEC (0x02)
+#define SMI130_LATCH_DUR_1_25_MILLI_SEC (0x03)
+#define SMI130_LATCH_DUR_2_5_MILLI_SEC (0x04)
+#define SMI130_LATCH_DUR_5_MILLI_SEC (0x05)
+#define SMI130_LATCH_DUR_10_MILLI_SEC (0x06)
+#define SMI130_LATCH_DUR_20_MILLI_SEC (0x07)
+#define SMI130_LATCH_DUR_40_MILLI_SEC (0x08)
+#define SMI130_LATCH_DUR_80_MILLI_SEC (0x09)
+#define SMI130_LATCH_DUR_160_MILLI_SEC (0x0A)
+#define SMI130_LATCH_DUR_320_MILLI_SEC (0x0B)
+#define SMI130_LATCH_DUR_640_MILLI_SEC (0x0C)
+#define SMI130_LATCH_DUR_1_28_SEC (0x0D)
+#define SMI130_LATCH_DUR_2_56_SEC (0x0E)
+#define SMI130_LATCHED (0x0F)
+/**************************************************/
+/**\name GYRO OFFSET MASK DEFINITION */
+/*************************************************/
+#define SMI130_GYRO_MANUAL_OFFSET_0_7 (0x00FF)
+#define SMI130_GYRO_MANUAL_OFFSET_8_9 (0x0300)
+/**************************************************/
+/**\name STEP CONFIGURATION MASK DEFINITION */
+/*************************************************/
+#define SMI130_STEP_CONFIG_0_7 (0x00FF)
+#define SMI130_STEP_CONFIG_8_10 (0x0700)
+#define SMI130_STEP_CONFIG_11_14 (0xF000)
+/**************************************************/
+/**\name DEFINITION USED FOR DIFFERENT WRITE */
+/*************************************************/
+#define SMI130_WRITE_TARGET_PAGE0 (0x00)
+#define SMI130_WRITE_TARGET_PAGE1 (0x01)
+#define SMI130_WRITE_ENABLE_PAGE1 (0x01)
+#define SMI130_MANUAL_DISABLE (0x00)
+#define SMI130_MANUAL_ENABLE (0x01)
+#define SMI130_YAS_DISABLE_RCOIL (0x00)
+#define SMI130_ENABLE_MAG_IF_MODE (0x02)
+#define SMI130_ENABLE_ANY_MOTION_INTR1 (0x04)
+#define SMI130_ENABLE_ANY_MOTION_INTR2 (0x04)
+#define SMI130_MAG_DATA_READ_REG (0x04)
+#define SMI130_BMM_POWER_MODE_REG (0x06)
+#define SMI130_ENABLE_ANY_MOTION_AXIS (0x07)
+#define SMI130_ENABLE_LOW_G (0x08)
+#define SMI130_YAS532_ACQ_START (0x11)
+#define SMI130_YAS_DEVICE_ID_REG (0x80)
+#define SMI130_FIFO_GYRO_ENABLE (0x80)
+#define SMI130_SIG_MOTION_INTR_ENABLE (0x01)
+#define SMI130_STEP_DETECT_INTR_ENABLE (0x01)
+#define SMI130_LOW_G_INTR_STAT (0x01)
+#define SMI130_PULL_UP_DATA (0x30)
+#define SMI130_FIFO_M_G_A_ENABLE (0xE0)
+#define SMI130_FIFO_M_G_ENABLE (0xA0)
+#define SMI130_FIFO_M_A_ENABLE (0x60)
+#define SMI130_FIFO_G_A_ENABLE (0xC0)
+#define SMI130_FIFO_A_ENABLE (0x40)
+#define SMI130_FIFO_M_ENABLE (0x20)
+/**************************************************/
+/**\name MAG INIT DEFINITION */
+/*************************************************/
+#define SMI130_COMMAND_REG_ONE (0x37)
+#define SMI130_COMMAND_REG_TWO (0x9A)
+#define SMI130_COMMAND_REG_THREE (0xC0)
+#define RESET_STEP_COUNTER (0xB2)
+/**************************************************/
+/**\name BIT SLICE GET AND SET FUNCTIONS */
+/*************************************************/
+#define SMI130_GET_BITSLICE(regvar, bitname)\
+ ((regvar & bitname##__MSK) >> bitname##__POS)
+
+
+#define SMI130_SET_BITSLICE(regvar, bitname, val)\
+ ((regvar & ~bitname##__MSK) | \
+ ((val<<bitname##__POS)&bitname##__MSK))
+
+/**************************************************/
+/**\name FUNCTION DECLARATIONS */
+/*************************************************/
+/**************************************************/
+/**\name FUNCTION FOR SMI130 INITIALIZE */
+/*************************************************/
+/*!
+ * @brief
+ * This function is used for initialize
+ * bus read and bus write functions
+ * assign the chip id and device address
+ * chip id is read in the register 0x00 bit from 0 to 7
+ *
+ * @param smi130 : structure pointer
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ * @note
+ * While changing the parameter of the smi130_t
+ * consider the following point:
+ * Changing the reference value of the parameter
+ * will changes the local copy or local reference
+ * make sure your changes will not
+ * affect the reference value of the parameter
+ * (Better case don't change the reference value of the parameter)
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_init(struct smi130_t *smi130);
+/**************************************************/
+/**\name FUNCTION FOR READ AND WRITE REGISTERS */
+/*************************************************/
+/*!
+ * @brief
+ * This API write the data to
+ * the given register
+ *
+ *
+ * @param v_addr_u8 -> Address of the register
+ * @param v_data_u8 -> The data from the register
+ * @param v_len_u8 -> no of bytes to read
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_write_reg(u8 v_addr_u8,
+u8 *v_data_u8, u8 v_len_u8);
+/*!
+ * @brief
+ * This API reads the data from
+ * the given register
+ *
+ *
+ * @param v_addr_u8 -> Address of the register
+ * @param v_data_u8 -> The data from the register
+ * @param v_len_u8 -> no of bytes to read
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_read_reg(u8 v_addr_u8,
+u8 *v_data_u8, u8 v_len_u8);
+/**************************************************/
+/**\name FUNCTION FOR ERROR CODES */
+/*************************************************/
+/*!
+ * @brief This API used to reads the fatal error
+ * from the Register 0x02 bit 0
+ * This flag will be reset only by power-on-reset and soft reset
+ *
+ *
+ * @param v_fatal_err_u8 : The status of fatal error
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fatal_err(u8
+*v_fatal_err_u8);
+/*!
+ * @brief This API used to read the error code
+ * from register 0x02 bit 1 to 4
+ *
+ *
+ * @param v_err_code_u8 : The status of error codes
+ * error_code | description
+ * ------------|---------------
+ * 0x00 |no error
+ * 0x01 |ACC_CONF error (accel ODR and bandwidth not compatible)
+ * 0x02 |GYR_CONF error (Gyroscope ODR and bandwidth not compatible)
+ * 0x03 |Under sampling mode and interrupt uses pre filtered data
+ * 0x04 |reserved
+ * 0x05 |Selected trigger-readout offset in
+ * - |MAG_IF greater than selected ODR
+ * 0x06 |FIFO configuration error for header less mode
+ * 0x07 |Under sampling mode and pre filtered data as FIFO source
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_err_code(u8
+*v_error_code_u8);
+/*!
+ * @brief This API Reads the i2c error code from the
+ * Register 0x02 bit 5.
+ * This error occurred in I2C master detected
+ *
+ * @param v_i2c_err_code_u8 : The status of i2c fail error
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_i2c_fail_err(u8
+*v_i2c_error_code_u8);
+ /*!
+ * @brief This API Reads the dropped command error
+ * from the register 0x02 bit 6
+ *
+ *
+ * @param v_drop_cmd_err_u8 : The status of drop command error
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_drop_cmd_err(u8
+*v_drop_cmd_err_u8);
+/*!
+ * @brief This API reads the magnetometer data ready
+ * interrupt not active.
+ * It reads from the error register 0x0x2 bit 7
+ *
+ *
+ *
+ *
+ * @param v_mag_data_rdy_err_u8 : The status of mag data ready interrupt
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_dada_rdy_err(u8
+*v_mag_data_rdy_err_u8);
+/*!
+ * @brief This API reads the error status
+ * from the error register 0x02 bit 0 to 7
+ *
+ * @param v_mag_data_rdy_err_u8 : The status of mag data ready interrupt
+ * @param v_fatal_er_u8r : The status of fatal error
+ * @param v_err_code_u8 : The status of error code
+ * @param v_i2c_fail_err_u8 : The status of I2C fail error
+ * @param v_drop_cmd_err_u8 : The status of drop command error
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_error_status(u8 *v_fatal_er_u8r,
+u8 *v_err_code_u8, u8 *v_i2c_fail_err_u8,
+u8 *v_drop_cmd_err_u8, u8 *v_mag_data_rdy_err_u8);
+/******************************************************************/
+/**\name FUNCTIONS FOR MAG,ACCEL AND GYRO POWER MODE STATUS */
+/*****************************************************************/
+/*!
+ * @brief This API reads the magnetometer power mode from
+ * PMU status register 0x03 bit 0 and 1
+ *
+ * @param v_mag_power_mode_stat_u8 : The value of mag power mode
+ * mag_powermode | value
+ * ------------------|----------
+ * SUSPEND | 0x00
+ * NORMAL | 0x01
+ * LOW POWER | 0x02
+ *
+ *
+ * @note The power mode of mag set by the 0x7E command register
+ * @note using the function "smi130_set_command_register()"
+ * value | mode
+ * ---------|----------------
+ * 0x18 | MAG_MODE_SUSPEND
+ * 0x19 | MAG_MODE_NORMAL
+ * 0x1A | MAG_MODE_LOWPOWER
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_power_mode_stat(u8
+*v_mag_power_mode_stat_u8);
+/*!
+ * @brief This API reads the gyroscope power mode from
+ * PMU status register 0x03 bit 2 and 3
+ *
+ * @param v_gyro_power_mode_stat_u8 : The value of gyro power mode
+ * gyro_powermode | value
+ * ------------------|----------
+ * SUSPEND | 0x00
+ * NORMAL | 0x01
+ * FAST POWER UP | 0x03
+ *
+ * @note The power mode of gyro set by the 0x7E command register
+ * @note using the function "smi130_set_command_register()"
+ * value | mode
+ * ---------|----------------
+ * 0x14 | GYRO_MODE_SUSPEND
+ * 0x15 | GYRO_MODE_NORMAL
+ * 0x17 | GYRO_MODE_FASTSTARTUP
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_power_mode_stat(u8
+*v_gyro_power_mode_stat_u8);
+/*!
+ * @brief This API reads the accelerometer power mode from
+ * PMU status register 0x03 bit 4 and 5
+ *
+ *
+ * @param v_accel_power_mode_stat_u8 : The value of accel power mode
+ * accel_powermode | value
+ * ------------------|----------
+ * SUSPEND | 0x00
+ * NORMAL | 0x01
+ * LOW POWER | 0x03
+ *
+ * @note The power mode of accel set by the 0x7E command register
+ * @note using the function "smi130_set_command_register()"
+ * value | mode
+ * ---------|----------------
+ * 0x11 | ACCEL_MODE_NORMAL
+ * 0x12 | ACCEL_LOWPOWER
+ * 0x10 | ACCEL_SUSPEND
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_power_mode_stat(u8
+*v_accel_power_mode_stat_u8);
+/*!
+ * @brief This API switch mag interface to normal mode
+ * and confirm whether the mode switching done successfully or not
+*
+ * @return results of bus communication function and current MAG_PMU result
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_interface_normal(void);
+/**************************************************/
+/**\name FUNCTION FOR Mag XYZ data read */
+/*************************************************/
+/*!
+ * @brief This API reads magnetometer data X values
+ * from the register 0x04 and 0x05
+ * @brief The mag sensor data read form auxiliary mag
+ *
+ * @param v_mag_x_s16 : The value of mag x
+ * @param v_sensor_select_u8 : Mag selection value
+ * value | sensor
+ * ---------|----------------
+ * 0 | BMM150
+ * 1 | AKM09911 or AKM09912
+ *
+ * @note For mag data output rate configuration use the following function
+ * @note smi130_set_mag_output_data_rate()
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_mag_x(s16 *v_mag_x_s16,
+u8 v_sensor_select_u8);
+/*!
+ * @brief This API reads magnetometer data Y values
+ * from the register 0x06 and 0x07
+ * @brief The mag sensor data read form auxiliary mag
+ *
+ * @param v_mag_y_s16 : The value of mag y
+ * @param v_sensor_select_u8 : Mag selection value
+ * value | sensor
+ * ---------|----------------
+ * 0 | BMM150
+ * 1 | AKM09911 or AKM09912
+ *
+ * @note For mag data output rate configuration use the following function
+ * @note smi130_set_mag_output_data_rate()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_mag_y(s16 *v_mag_y_s16,
+u8 v_sensor_select_u8);
+/*!
+ * @brief This API reads magnetometer data Z values
+ * from the register 0x08 and 0x09
+ * @brief The mag sensor data read form auxiliary mag
+ *
+ * @param v_mag_z_s16 : The value of mag z
+ * @param v_sensor_select_u8 : Mag selection value
+ * value | sensor
+ * ---------|----------------
+ * 0 | BMM150
+ * 1 | AKM09911 or AKM09912
+ *
+ * @note For mag data output rate configuration use the following function
+ * @note smi130_set_mag_output_data_rate()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_mag_z(s16 *v_mag_z_s16,
+u8 v_sensor_select_u8);
+/*!
+ * @brief This API reads magnetometer data RHALL values
+ * from the register 0x0A and 0x0B
+ *
+ *
+ * @param v_mag_r_s16 : The value of BMM150 r data
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_mag_r(
+s16 *v_mag_r_s16);
+/*!
+ * @brief This API reads magnetometer data X,Y,Z values
+ * from the register 0x04 to 0x09
+ *
+ * @brief The mag sensor data read form auxiliary mag
+ *
+ * @param mag : The value of mag xyz data
+ * @param v_sensor_select_u8 : Mag selection value
+ * value | sensor
+ * ---------|----------------
+ * 0 | BMM150
+ * 1 | AKM09911 or AKM09912
+ *
+ * @note For mag data output rate configuration use the following function
+ * @note smi130_set_mag_output_data_rate()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_mag_xyz(
+struct smi130_mag_t *mag, u8 v_sensor_select_u8);
+ /*!*
+ * @brief This API reads magnetometer data X,Y,Z,r
+ * values from the register 0x04 to 0x0B
+ *
+ * @brief The mag sensor data read form auxiliary mag
+ *
+ * @param mag : The value of mag-BMM150 xyzr data
+ *
+ * @note For mag data output rate configuration use the following function
+ * @note smi130_set_mag_output_data_rate()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_mag_xyzr(
+struct smi130_mag_xyzr_t *mag);
+/**************************************************/
+/**\name FUNCTION FOR GYRO XYZ DATA READ */
+/*************************************************/
+/*!
+ * @brief This API reads gyro data X values
+ * form the register 0x0C and 0x0D
+ *
+ *
+ *
+ *
+ * @param v_gyro_x_s16 : The value of gyro x data
+ *
+ * @note Gyro Configuration use the following function
+ * @note smi130_set_gyro_output_data_rate()
+ * @note smi130_set_gyro_bw()
+ * @note smi130_set_gyro_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_gyro_x(
+s16 *v_gyro_x_s16);
+/*!
+ * @brief This API reads gyro data Y values
+ * form the register 0x0E and 0x0F
+ *
+ *
+ *
+ *
+ * @param v_gyro_y_s16 : The value of gyro y data
+ *
+ * @note Gyro Configuration use the following function
+ * @note smi130_set_gyro_output_data_rate()
+ * @note smi130_set_gyro_bw()
+ * @note smi130_set_gyro_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error result of communication routines
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_gyro_y(
+s16 *v_gyro_y_s16);
+/*!
+ * @brief This API reads gyro data Z values
+ * form the register 0x10 and 0x11
+ *
+ *
+ *
+ *
+ * @param v_gyro_z_s16 : The value of gyro z data
+ *
+ * @note Gyro Configuration use the following function
+ * @note smi130_set_gyro_output_data_rate()
+ * @note smi130_set_gyro_bw()
+ * @note smi130_set_gyro_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_gyro_z(
+s16 *v_gyro_z_s16);
+/*!
+ * @brief This API reads gyro data X,Y,Z values
+ * from the register 0x0C to 0x11
+ *
+ *
+ *
+ *
+ * @param gyro : The value of gyro xyz
+ *
+ * @note Gyro Configuration use the following function
+ * @note smi130_set_gyro_output_data_rate()
+ * @note smi130_set_gyro_bw()
+ * @note smi130_set_gyro_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_gyro_xyz(
+struct smi130_gyro_t *gyro);
+/**************************************************/
+/**\name FUNCTION FOR ACCEL XYZ DATA READ */
+/*************************************************/
+/*!
+ * @brief This API reads accelerometer data X values
+ * form the register 0x12 and 0x13
+ *
+ *
+ *
+ *
+ * @param v_accel_x_s16 : The value of accel x
+ *
+ * @note For accel configuration use the following functions
+ * @note smi130_set_accel_output_data_rate()
+ * @note smi130_set_accel_bw()
+ * @note smi130_set_accel_under_sampling_parameter()
+ * @note smi130_set_accel_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_accel_x(
+s16 *v_accel_x_s16);
+/*!
+ * @brief This API reads accelerometer data Y values
+ * form the register 0x14 and 0x15
+ *
+ *
+ *
+ *
+ * @param v_accel_y_s16 : The value of accel y
+ *
+ * @note For accel configuration use the following functions
+ * @note smi130_set_accel_output_data_rate()
+ * @note smi130_set_accel_bw()
+ * @note smi130_set_accel_under_sampling_parameter()
+ * @note smi130_set_accel_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_accel_y(
+s16 *v_accel_y_s16);
+/*!
+ * @brief This API reads accelerometer data Z values
+ * form the register 0x16 and 0x17
+ *
+ *
+ *
+ *
+ * @param v_accel_z_s16 : The value of accel z
+ *
+ * @note For accel configuration use the following functions
+ * @note smi130_set_accel_output_data_rate()
+ * @note smi130_set_accel_bw()
+ * @note smi130_set_accel_under_sampling_parameter()
+ * @note smi130_set_accel_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_accel_z(
+s16 *v_accel_z_s16);
+/*!
+ * @brief This API reads accelerometer data X,Y,Z values
+ * from the register 0x12 to 0x17
+ *
+ *
+ *
+ *
+ * @param accel :The value of accel xyz
+ *
+ * @note For accel configuration use the following functions
+ * @note smi130_set_accel_output_data_rate()
+ * @note smi130_set_accel_bw()
+ * @note smi130_set_accel_under_sampling_parameter()
+ * @note smi130_set_accel_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_accel_xyz(
+struct smi130_accel_t *accel);
+/**************************************************/
+/**\name FUNCTION FOR SENSOR TIME */
+/*************************************************/
+/*!
+ * @brief This API reads sensor_time from the register
+ * 0x18 to 0x1A
+ *
+ *
+ * @param v_sensor_time_u32 : The value of sensor time
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_sensor_time(
+u32 *v_sensor_time_u32);
+/**************************************************/
+/**\name FUNCTION FOR GYRO SLEF TEST */
+/*************************************************/
+/*!
+ * @brief This API reads the Gyroscope self test
+ * status from the register 0x1B bit 1
+ *
+ *
+ * @param v_gyro_selftest_u8 : The value of gyro self test status
+ * value | status
+ * ---------|----------------
+ * 0 | Gyroscope self test is running or failed
+ * 1 | Gyroscope self test completed successfully
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_selftest(u8
+*v_gyro_selftest_u8);
+/**************************************************/
+/**\name FUNCTION FOR MANUAL INTERFACE */
+/*************************************************/
+/*!
+ * @brief This API reads the status of
+ * mag manual interface operation form the register 0x1B bit 2
+ *
+ *
+ *
+ * @param v_mag_manual_stat_u8 : The value of mag manual operation status
+ * value | status
+ * ---------|----------------
+ * 0 | Indicates no manual magnetometer
+ * - | interface operation is ongoing
+ * 1 | Indicates manual magnetometer
+ * - | interface operation is ongoing
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_manual_operation_stat(u8
+*v_mag_manual_stat_u8);
+/**************************************************/
+/**\name FUNCTION FOR FAST OFFSET READY */
+/*************************************************/
+/*!
+ * @brief This API reads the fast offset compensation
+ * status form the register 0x1B bit 3
+ *
+ *
+ * @param v_foc_rdy_u8 : The status of fast compensation
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_foc_rdy(u8
+*v_foc_rdy_u8);
+/**************************************************/
+/**\name FUNCTION FOR NVM READY */
+/*************************************************/
+/*!
+ * @brief This API Reads the nvm_rdy status from the
+ * resister 0x1B bit 4
+ *
+ *
+ * @param v_nvm_rdy_u8 : The value of NVM ready status
+ * value | status
+ * ---------|----------------
+ * 0 | NVM write operation in progress
+ * 1 | NVM is ready to accept a new write trigger
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_nvm_rdy(u8
+*v_nvm_rdy_u8);
+/**************************************************/
+/**\name FUNCTION FOR DATA READY FOR MAG, GYRO, AND ACCEL */
+/*************************************************/
+/*!
+ * @brief This API reads the status of mag data ready
+ * from the register 0x1B bit 5
+ * The status get reset when one mag data register is read out
+ *
+ * @param v_data_rdy_u8 : The value of mag data ready status
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_data_rdy_mag(u8
+*v_data_rdy_u8);
+/*!
+ * @brief This API reads the status of gyro data ready form the
+ * register 0x1B bit 6
+ * The status get reset when gyro data register read out
+ *
+ *
+ * @param v_data_rdy_u8 : The value of gyro data ready
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_data_rdy(u8
+*v_data_rdy_u8);
+/*!
+ * @brief This API reads the status of accel data ready form the
+ * register 0x1B bit 7
+ * The status get reset when accel data register read out
+ *
+ *
+ * @param v_data_rdy_u8 : The value of accel data ready status
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_data_rdy(u8
+*drdy_acc);
+/**************************************************/
+/**\name FUNCTION FOR STEP INTERRUPT STATUS */
+/*************************************************/
+/*!
+ * @brief This API reads the step detector interrupt status
+ * from the register 0x1C bit 0
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_step_intr_u8 : The status of step detector interrupt
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_step_intr(u8
+*v_step_intr_u8);
+/**************************************************/
+/**\name FUNCTION FOR SIGNIFICANT INTERRUPT STATUS */
+/*************************************************/
+/*!
+ * @brief This API reads the
+ * significant motion interrupt status
+ * from the register 0x1C bit 1
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ *
+ * @param v_significant_intr_u8 : The status of step
+ * motion interrupt
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_significant_intr(u8
+*sigmot_intr);
+/**************************************************/
+/**\name FUNCTION FOR ANY MOTION INTERRUPT STATUS */
+/*************************************************/
+ /*!
+ * @brief This API reads the any motion interrupt status
+ * from the register 0x1C bit 2
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ * @param v_any_motion_intr_u8 : The status of any-motion interrupt
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_any_motion_intr(u8
+*v_any_motion_intr_u8);
+/**************************************************/
+/**\name FUNCTION FOR PMU TRIGGER INTERRUPT STATUS */
+/*************************************************/
+/*!
+ * @brief This API reads the power mode trigger interrupt status
+ * from the register 0x1C bit 3
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ *
+ * @param v_pmu_trigger_intr_u8 : The status of power mode trigger interrupt
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_pmu_trigger_intr(u8
+*v_pmu_trigger_intr_u8);
+/**************************************************/
+/**\name FUNCTION FOR DOUBLE TAB STATUS */
+/*************************************************/
+/*!
+ * @brief This API reads the double tab status
+ * from the register 0x1C bit 4
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_double_tap_intr_u8 :The status of double tab interrupt
+ *
+ * @note Double tap interrupt can be configured by the following functions
+ * @note INTERRUPT MAPPING
+ * @note smi130_set_intr_double_tap()
+ * @note AXIS MAPPING
+ * @note smi130_get_stat2_tap_first_x()
+ * @note smi130_get_stat2_tap_first_y()
+ * @note smi130_get_stat2_tap_first_z()
+ * @note DURATION
+ * @note smi130_set_intr_tap_durn()
+ * @note THRESHOLD
+ * @note smi130_set_intr_tap_thres()
+ * @note TAP QUIET
+ * @note smi130_set_intr_tap_quiet()
+ * @note TAP SHOCK
+ * @note smi130_set_intr_tap_shock()
+ * @note TAP SOURCE
+ * @note smi130_set_intr_tap_source()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_double_tap_intr(u8
+*v_double_tap_intr_u8);
+/**************************************************/
+/**\name FUNCTION FOR SINGLE TAB STATUS */
+/*************************************************/
+/*!
+ * @brief This API reads the single tab status
+ * from the register 0x1C bit 5
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_single_tap_intr_u8 :The status of single tap interrupt
+ *
+ * @note Single tap interrupt can be configured by the following functions
+ * @note INTERRUPT MAPPING
+ * @note smi130_set_intr_single_tap()
+ * @note AXIS MAPPING
+ * @note smi130_get_stat2_tap_first_x()
+ * @note smi130_get_stat2_tap_first_y()
+ * @note smi130_get_stat2_tap_first_z()
+ * @note DURATION
+ * @note smi130_set_intr_tap_durn()
+ * @note THRESHOLD
+ * @note smi130_set_intr_tap_thres()
+ * @note TAP QUIET
+ * @note smi130_set_intr_tap_quiet()
+ * @note TAP SHOCK
+ * @note smi130_set_intr_tap_shock()
+ * @note TAP SOURCE
+ * @note smi130_set_intr_tap_source()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_single_tap_intr(u8
+*v_single_tap_intr_u8);
+/**************************************************/
+/**\name FUNCTION FOR ORIENT INTERRUPT STATUS */
+/*************************************************/
+/*!
+ * @brief This API reads the orient_mbl status
+ * from the register 0x1C bit 6
+ * flag is associated with a specific interrupt function.
+ * It is set when the orient_mbl interrupt triggers. The
+ * setting of INT_LATCH controls if the
+ * interrupt signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_orient_mbl_intr_u8 : The status of orient_mbl interrupt
+ *
+ * @note For orient_mbl interrupt configuration use the following functions
+ * @note STATUS
+ * @note smi130_get_stat0_orient_mbl_intr()
+ * @note AXIS MAPPING
+ * @note smi130_get_stat3_orient_mbl_xy()
+ * @note smi130_get_stat3_orient_mbl_z()
+ * @note smi130_set_intr_orient_mbl_axes_enable()
+ * @note INTERRUPT MAPPING
+ * @note smi130_set_intr_orient_mbl()
+ * @note INTERRUPT OUTPUT
+ * @note smi130_set_intr_orient_mbl_ud_enable()
+ * @note THETA
+ * @note smi130_set_intr_orient_mbl_theta()
+ * @note HYSTERESIS
+ * @note smi130_set_intr_orient_mbl_hyst()
+ * @note BLOCKING
+ * @note smi130_set_intr_orient_mbl_blocking()
+ * @note MODE
+ * @note smi130_set_intr_orient_mbl_mode()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_orient_mbl_intr(u8
+*v_orient_mbl_intr_u8);
+/**************************************************/
+/**\name FUNCTION FOR FLAT INTERRUPT STATUS */
+/*************************************************/
+/*!
+ * @brief This API reads the flat interrupt status
+ * from the register 0x1C bit 7
+ * flag is associated with a specific interrupt function.
+ * It is set when the flat interrupt triggers. The
+ * setting of INT_LATCH controls if the
+ * interrupt signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_flat_intr_u8 : The status of flat interrupt
+ *
+ * @note For flat configuration use the following functions
+ * @note STATS
+ * @note smi130_get_stat0_flat_intr()
+ * @note smi130_get_stat3_flat()
+ * @note INTERRUPT MAPPING
+ * @note smi130_set_intr_flat()
+ * @note THETA
+ * @note smi130_set_intr_flat_theta()
+ * @note HOLD TIME
+ * @note smi130_set_intr_flat_hold()
+ * @note HYSTERESIS
+ * @note smi130_set_intr_flat_hyst()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_flat_intr(u8
+*v_flat_intr_u8);
+/**************************************************/
+/**\name FUNCTION FOR HIGH_G INTERRUPT STATUS */
+/*************************************************/
+/*!
+ * @brief This API reads the high_g interrupt status
+ * from the register 0x1D bit 2
+ * flag is associated with a specific interrupt function.
+ * It is set when the high g interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt signal and hence the
+ * respective interrupt flag will be permanently
+ * latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_high_g_intr_u8 : The status of high_g interrupt
+ *
+ * @note High_g interrupt configured by following functions
+ * @note STATUS
+ * @note smi130_get_stat1_high_g_intr()
+ * @note AXIS MAPPING
+ * @note smi130_get_stat3_high_g_first_x()
+ * @note smi130_get_stat3_high_g_first_y()
+ * @note smi130_get_stat3_high_g_first_z()
+ * @note SIGN MAPPING
+ * @note smi130_get_stat3_high_g_first_sign()
+ * @note INTERRUPT MAPPING
+ * @note smi130_set_intr_high_g()
+ * @note HYSTERESIS
+ * @note smi130_set_intr_high_g_hyst()
+ * @note DURATION
+ * @note smi130_set_intr_high_g_durn()
+ * @note THRESHOLD
+ * @note smi130_set_intr_high_g_thres()
+ * @note SOURCE
+ * @note smi130_set_intr_low_high_source()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat1_high_g_intr(u8
+*v_high_g_intr_u8);
+/**************************************************/
+/**\name FUNCTION FOR LOW_G INTERRUPT STATUS */
+/*************************************************/
+/*!
+ * @brief This API reads the low g interrupt status
+ * from the register 0x1D bit 3
+ * flag is associated with a specific interrupt function.
+ * It is set when the low g interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_low_g_intr_u8 : The status of low_g interrupt
+ *
+ * @note Low_g interrupt configured by following functions
+ * @note STATUS
+ * @note smi130_get_stat1_low_g_intr()
+ * @note INTERRUPT MAPPING
+ * @note smi130_set_intr_low_g()
+ * @note SOURCE
+ * @note smi130_set_intr_low_high_source()
+ * @note DURATION
+ * @note smi130_set_intr_low_g_durn()
+ * @note THRESHOLD
+ * @note smi130_set_intr_low_g_thres()
+ * @note HYSTERESIS
+ * @note smi130_set_intr_low_g_hyst()
+ * @note MODE
+ * @note smi130_set_intr_low_g_mode()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat1_low_g_intr(u8
+*v_low_g_intr_u8);
+/**************************************************/
+/**\name FUNCTION FOR DATA READY INTERRUPT STATUS */
+/*************************************************/
+/*!
+ * @brief This API reads data ready interrupt status
+ * from the register 0x1D bit 4
+ * flag is associated with a specific interrupt function.
+ * It is set when the data ready interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_data_rdy_intr_u8 : The status of data ready interrupt
+ *
+ * @note Data ready interrupt configured by following functions
+ * @note STATUS
+ * @note smi130_get_stat1_data_rdy_intr()
+ * @note INTERRUPT MAPPING
+ * @note smi130_set_intr_data_rdy()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat1_data_rdy_intr(u8
+*v_data_rdy_intr_u8);
+/**************************************************/
+/**\name FUNCTIONS FOR FIFO FULL AND WATER MARK INTERRUPT STATUS*/
+/*************************************************/
+/*!
+ * @brief This API reads data ready FIFO full interrupt status
+ * from the register 0x1D bit 5
+ * flag is associated with a specific interrupt function.
+ * It is set when the FIFO full interrupt triggers. The
+ * setting of INT_LATCH controls if the
+ * interrupt signal and hence the
+ * respective interrupt flag will
+ * be permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_fifo_full_intr_u8 : The status of fifo full interrupt
+ *
+ * @note FIFO full interrupt can be configured by following functions
+ * @note smi130_set_intr_fifo_full()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat1_fifo_full_intr(u8
+*v_fifo_full_intr_u8);
+/*!
+ * @brief This API reads data
+ * ready FIFO watermark interrupt status
+ * from the register 0x1D bit 6
+ * flag is associated with a specific interrupt function.
+ * It is set when the FIFO watermark interrupt triggers. The
+ * setting of INT_LATCH controls if the
+ * interrupt signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_fifo_wm_intr_u8 : The status of fifo water mark interrupt
+ *
+ * @note FIFO full interrupt can be configured by following functions
+ * @note smi130_set_intr_fifo_wm()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat1_fifo_wm_intr(u8
+*v_fifo_wm_intr_u8);
+/**************************************************/
+/**\name FUNCTIONS FOR NO MOTION INTERRUPT STATUS*/
+/*************************************************/
+/*!
+ * @brief This API reads data ready no motion interrupt status
+ * from the register 0x1D bit 7
+ * flag is associated with a specific interrupt function.
+ * It is set when the no motion interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt signal and hence the
+ * respective interrupt flag will be permanently
+ * latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_nomotion_intr_u8 : The status of no motion interrupt
+ *
+ * @note No motion interrupt can be configured by following function
+ * @note STATUS
+ * @note smi130_get_stat1_nomotion_intr()
+ * @note INTERRUPT MAPPING
+ * @note smi130_set_intr_nomotion()
+ * @note DURATION
+ * @note smi130_set_intr_slow_no_motion_durn()
+ * @note THRESHOLD
+ * @note smi130_set_intr_slow_no_motion_thres()
+ * @note SLOW/NO MOTION SELECT
+ * @note smi130_set_intr_slow_no_motion_select()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat1_nomotion_intr(u8
+*nomo_intr);
+/**************************************************/
+/**\name FUNCTIONS FOR ANY MOTION FIRST XYZ AND SIGN INTERRUPT STATUS*/
+/*************************************************/
+/*!
+ * @brief This API reads the status of any motion first x
+ * from the register 0x1E bit 0
+ *
+ *
+ * @param v_anymotion_first_x_u8 : The status of any motion first x interrupt
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by x axis
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_any_motion_first_x(u8
+*v_anymotion_first_x_u8);
+/*!
+ * @brief This API reads the status of any motion first y interrupt
+ * from the register 0x1E bit 1
+ *
+ *
+ *
+ *@param v_any_motion_first_y_u8 : The status of any motion first y interrupt
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_any_motion_first_y(u8
+*v_any_motion_first_y_u8);
+/*!
+ * @brief This API reads the status of any motion first z interrupt
+ * from the register 0x1E bit 2
+ *
+ *
+ *
+ *
+ *@param v_any_motion_first_z_u8 : The status of any motion first z interrupt
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_any_motion_first_z(u8
+*v_any_motion_first_z_u8);
+/*!
+ * @brief This API reads the any motion sign status from the
+ * register 0x1E bit 3
+ *
+ *
+ *
+ *
+ * @param v_anymotion_sign_u8 : The status of any motion sign
+ * value | sign
+ * -----------|-------------
+ * 0 | positive
+ * 1 | negative
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_any_motion_sign(u8
+*v_anymotion_sign_u8);
+/**************************************************/
+/**\name FUNCTIONS FOR TAP FIRST XYZ AND SIGN INTERRUPT STATUS*/
+/*************************************************/
+/*!
+ * @brief This API reads the any motion tap first x status from the
+ * register 0x1E bit 4
+ *
+ *
+ *
+ *
+ * @param v_tap_first_x_u8 :The status of any motion tap first x
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by x axis
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_tap_first_x(u8
+*v_tap_first_x_u8);
+/*!
+ * @brief This API reads the tap first y interrupt status from the
+ * register 0x1E bit 5
+ *
+ *
+ *
+ *
+ * @param v_tap_first_y_u8 :The status of tap first y interrupt
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_tap_first_y(u8
+*v_tap_first_y_u8);
+/*!
+ * @brief This API reads the tap first z interrupt status from the
+ * register 0x1E bit 6
+ *
+ *
+ *
+ *
+ * @param v_tap_first_z_u8 :The status of tap first z interrupt
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_tap_first_z(u8
+*v_tap_first_z_u8);
+/*!
+ * @brief This API reads the tap sign status from the
+ * register 0x1E bit 7
+ *
+ *
+ *
+ *
+ * @param v_tap_sign_u8 : The status of tap sign
+ * value | sign
+ * -----------|-------------
+ * 0 | positive
+ * 1 | negative
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_tap_sign(u8
+*tap_sign);
+/**************************************************/
+/**\name FUNCTIONS FOR HIGH_G FIRST XYZ AND SIGN INTERRUPT STATUS*/
+/*************************************************/
+/*!
+ * @brief This API reads the high_g first x status from the
+ * register 0x1F bit 0
+ *
+ *
+ *
+ *
+ * @param v_high_g_first_x_u8 :The status of high_g first x
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by x axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat3_high_g_first_x(u8
+*v_high_g_first_x_u8);
+/*!
+ * @brief This API reads the high_g first y status from the
+ * register 0x1F bit 1
+ *
+ *
+ *
+ *
+ * @param v_high_g_first_y_u8 : The status of high_g first y
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat3_high_g_first_y(u8
+*v_high_g_first_y_u8);
+/*!
+ * @brief This API reads the high_g first z status from the
+ * register 0x1F bit 3
+ *
+ *
+ *
+ *
+ * @param v_high_g_first_z_u8 : The status of high_g first z
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat3_high_g_first_z(u8
+*v_high_g_first_z_u8);
+/*!
+ * @brief This API reads the high sign status from the
+ * register 0x1F bit 3
+ *
+ *
+ *
+ *
+ * @param v_high_g_sign_u8 :The status of high sign
+ * value | sign
+ * -----------|-------------
+ * 0 | positive
+ * 1 | negative
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat3_high_g_sign(u8
+*v_high_g_sign_u8);
+/**************************************************/
+/**\name FUNCTIONS FOR ORIENT XY AND Z INTERRUPT STATUS*/
+/*************************************************/
+/*!
+ * @brief This API reads the status of orient_mbl_xy plane
+ * from the register 0x1F bit 4 and 5
+ *
+ *
+ * @param v_orient_mbl_xy_u8 :The status of orient_mbl_xy plane
+ * value | status
+ * -----------|-------------
+ * 0x00 | portrait upright
+ * 0x01 | portrait upside down
+ * 0x02 | landscape left
+ * 0x03 | landscape right
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat3_orient_mbl_xy(u8
+*v_orient_mbl_xy_u8);
+/*!
+ * @brief This API reads the status of orient_mbl z plane
+ * from the register 0x1F bit 6
+ *
+ *
+ * @param v_orient_mbl_z_u8 :The status of orient_mbl z
+ * value | status
+ * -----------|-------------
+ * 0x00 | upward looking
+ * 0x01 | downward looking
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat3_orient_mbl_z(u8
+*v_orient_mbl_z_u8);
+/**************************************************/
+/**\name FUNCTIONS FOR FLAT INTERRUPT STATUS*/
+/*************************************************/
+/*!
+ * @brief This API reads the flat status from the register
+ * 0x1F bit 7
+ *
+ *
+ * @param v_flat_u8 : The status of flat interrupt
+ * value | status
+ * -----------|-------------
+ * 0x00 | non flat
+ * 0x01 | flat position
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat3_flat(u8
+*flat);
+/**************************************************/
+/**\name FUNCTION FOR TEMPERATUE READ */
+/*************************************************/
+/*!
+ * @brief This API reads the temperature of the sensor
+ * from the register 0x21 bit 0 to 7
+ *
+ *
+ *
+ * @param v_temp_s16 : The value of temperature
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_temp(s16
+*v_temp_s16);
+/**************************************************/
+/**\name FUNCTION FOR FIFO LENGTH AND FIFO DATA READ */
+/*************************************************/
+/*!
+ * @brief This API reads the of the sensor
+ * form the register 0x23 and 0x24 bit 0 to 7 and 0 to 2
+ * @brief this byte counter is updated each time a complete frame
+ * was read or writtern
+ *
+ *
+ * @param v_fifo_length_u32 : The value of fifo byte counter
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_fifo_length(
+u32 *v_fifo_length_u32);
+/*!
+ * @brief This API reads the fifo data of the sensor
+ * from the register 0x24
+ * @brief Data format depends on the setting of register FIFO_CONFIG
+ *
+ *
+ *
+ * @param v_fifodata_u8 : Pointer holding the fifo data
+ *
+ * @note For reading FIFO data use the following functions
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_fifo_data(
+u8 *v_fifodata_u8, u16 v_fifo_length_u16);
+/**************************************************/
+/**\name FUNCTION FOR ACCEL CONFIGURATIONS */
+/*************************************************/
+/*!
+ * @brief This API is used to get the
+ * accel output date rate form the register 0x40 bit 0 to 3
+ *
+ *
+ * @param v_output_data_rate_u8 :The value of accel output date rate
+ * value | output data rate
+ * -------|--------------------------
+ * 0 | SMI130_ACCEL_OUTPUT_DATA_RATE_RESERVED
+ * 1 | SMI130_ACCEL_OUTPUT_DATA_RATE_0_78HZ
+ * 2 | SMI130_ACCEL_OUTPUT_DATA_RATE_1_56HZ
+ * 3 | SMI130_ACCEL_OUTPUT_DATA_RATE_3_12HZ
+ * 4 | SMI130_ACCEL_OUTPUT_DATA_RATE_6_25HZ
+ * 5 | SMI130_ACCEL_OUTPUT_DATA_RATE_12_5HZ
+ * 6 | SMI130_ACCEL_OUTPUT_DATA_RATE_25HZ
+ * 7 | SMI130_ACCEL_OUTPUT_DATA_RATE_50HZ
+ * 8 | SMI130_ACCEL_OUTPUT_DATA_RATE_100HZ
+ * 9 | SMI130_ACCEL_OUTPUT_DATA_RATE_200HZ
+ * 10 | SMI130_ACCEL_OUTPUT_DATA_RATE_400HZ
+ * 11 | SMI130_ACCEL_OUTPUT_DATA_RATE_800HZ
+ * 12 | SMI130_ACCEL_OUTPUT_DATA_RATE_1600HZ
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_output_data_rate(
+u8 *v_output_data_rate_u8);
+/*!
+ * @brief This API is used to set the
+ * accel output date rate form the register 0x40 bit 0 to 3
+ *
+ *
+ * @param v_output_data_rate_u8 :The value of accel output date rate
+ * value | output data rate
+ * -------|--------------------------
+ * 0 | SMI130_ACCEL_OUTPUT_DATA_RATE_RESERVED
+ * 1 | SMI130_ACCEL_OUTPUT_DATA_RATE_0_78HZ
+ * 2 | SMI130_ACCEL_OUTPUT_DATA_RATE_1_56HZ
+ * 3 | SMI130_ACCEL_OUTPUT_DATA_RATE_3_12HZ
+ * 4 | SMI130_ACCEL_OUTPUT_DATA_RATE_6_25HZ
+ * 5 | SMI130_ACCEL_OUTPUT_DATA_RATE_12_5HZ
+ * 6 | SMI130_ACCEL_OUTPUT_DATA_RATE_25HZ
+ * 7 | SMI130_ACCEL_OUTPUT_DATA_RATE_50HZ
+ * 8 | SMI130_ACCEL_OUTPUT_DATA_RATE_100HZ
+ * 9 | SMI130_ACCEL_OUTPUT_DATA_RATE_200HZ
+ * 10 | SMI130_ACCEL_OUTPUT_DATA_RATE_400HZ
+ * 11 | SMI130_ACCEL_OUTPUT_DATA_RATE_800HZ
+ * 12 | SMI130_ACCEL_OUTPUT_DATA_RATE_1600HZ
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_output_data_rate(u8 odr);
+/*!
+ * @brief This API is used to get the
+ * accel bandwidth from the register 0x40 bit 4 to 6
+ * @brief bandwidth parameter determines filter configuration(acc_us=0)
+ * and averaging for under sampling mode(acc_us=1)
+ *
+ *
+ * @param v_bw_u8 : The value of accel bandwidth
+ *
+ * @note accel bandwidth depends on under sampling parameter
+ * @note under sampling parameter cab be set by the function
+ * "SMI130_SET_ACCEL_UNDER_SAMPLING_PARAMETER"
+ *
+ * @note Filter configuration
+ * accel_us | Filter configuration
+ * -----------|---------------------
+ * 0x00 | OSR4 mode
+ * 0x01 | OSR2 mode
+ * 0x02 | normal mode
+ * 0x03 | CIC mode
+ * 0x04 | Reserved
+ * 0x05 | Reserved
+ * 0x06 | Reserved
+ * 0x07 | Reserved
+ *
+ * @note accel under sampling mode
+ * accel_us | Under sampling mode
+ * -----------|---------------------
+ * 0x00 | no averaging
+ * 0x01 | average 2 samples
+ * 0x02 | average 4 samples
+ * 0x03 | average 8 samples
+ * 0x04 | average 16 samples
+ * 0x05 | average 32 samples
+ * 0x06 | average 64 samples
+ * 0x07 | average 128 samples
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_bw(u8 *v_bw_u8);
+/*!
+ * @brief This API is used to set the
+ * accel bandwidth from the register 0x40 bit 4 to 6
+ * @brief bandwidth parameter determines filter configuration(acc_us=0)
+ * and averaging for under sampling mode(acc_us=1)
+ *
+ *
+ * @param v_bw_u8 : The value of accel bandwidth
+ *
+ * @note accel bandwidth depends on under sampling parameter
+ * @note under sampling parameter cab be set by the function
+ * "SMI130_SET_ACCEL_UNDER_SAMPLING_PARAMETER"
+ *
+ * @note Filter configuration
+ * accel_us | Filter configuration
+ * -----------|---------------------
+ * 0x00 | OSR4 mode
+ * 0x01 | OSR2 mode
+ * 0x02 | normal mode
+ * 0x03 | CIC mode
+ * 0x04 | Reserved
+ * 0x05 | Reserved
+ * 0x06 | Reserved
+ * 0x07 | Reserved
+ *
+ * @note accel under sampling mode
+ * accel_us | Under sampling mode
+ * -----------|---------------------
+ * 0x00 | no averaging
+ * 0x01 | average 2 samples
+ * 0x02 | average 4 samples
+ * 0x03 | average 8 samples
+ * 0x04 | average 16 samples
+ * 0x05 | average 32 samples
+ * 0x06 | average 64 samples
+ * 0x07 | average 128 samples
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_bw(u8 v_bw_u8);
+/*!
+ * @brief This API is used to get the accel
+ * under sampling parameter form the register 0x40 bit 7
+ *
+ *
+ *
+ *
+ * @param v_accel_under_sampling_u8 : The value of accel under sampling
+ * value | under_sampling
+ * ----------|---------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_under_sampling_parameter(
+u8 *v_accel_under_sampling_u8);
+/*!
+ * @brief This API is used to set the accel
+ * under sampling parameter form the register 0x40 bit 7
+ *
+ *
+ *
+ *
+ * @param v_accel_under_sampling_u8 : The value of accel under sampling
+ * value | under_sampling
+ * ----------|---------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_under_sampling_parameter(
+u8 v_accel_under_sampling_u8);
+/*!
+ * @brief This API is used to get the ranges
+ * (g values) of the accel from the register 0x41 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_range_u8 : The value of accel g range
+ * value | g_range
+ * ----------|-----------
+ * 0x03 | SMI130_ACCEL_RANGE_2G
+ * 0x05 | SMI130_ACCEL_RANGE_4G
+ * 0x08 | SMI130_ACCEL_RANGE_8G
+ * 0x0C | SMI130_ACCEL_RANGE_16G
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_range(
+u8 *v_range_u8);
+/*!
+ * @brief This API is used to set the ranges
+ * (g values) of the accel from the register 0x41 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_range_u8 : The value of accel g range
+ * value | g_range
+ * ----------|-----------
+ * 0x03 | SMI130_ACCEL_RANGE_2G
+ * 0x05 | SMI130_ACCEL_RANGE_4G
+ * 0x08 | SMI130_ACCEL_RANGE_8G
+ * 0x0C | SMI130_ACCEL_RANGE_16G
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_range(
+u8 v_range_u8);
+/**************************************************/
+/**\name FUNCTION FOR GYRO CONFIGURATIONS */
+/*************************************************/
+/*!
+ * @brief This API is used to get the
+ * gyroscope output data rate from the register 0x42 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_output_data_rate_u8 :The value of gyro output data rate
+ * value | gyro output data rate
+ * -----------|-----------------------------
+ * 0x00 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x01 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x02 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x03 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x04 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x05 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x06 | SMI130_GYRO_OUTPUT_DATA_RATE_25HZ
+ * 0x07 | SMI130_GYRO_OUTPUT_DATA_RATE_50HZ
+ * 0x08 | SMI130_GYRO_OUTPUT_DATA_RATE_100HZ
+ * 0x09 | SMI130_GYRO_OUTPUT_DATA_RATE_200HZ
+ * 0x0A | SMI130_GYRO_OUTPUT_DATA_RATE_400HZ
+ * 0x0B | SMI130_GYRO_OUTPUT_DATA_RATE_800HZ
+ * 0x0C | SMI130_GYRO_OUTPUT_DATA_RATE_1600HZ
+ * 0x0D | SMI130_GYRO_OUTPUT_DATA_RATE_3200HZ
+ * 0x0E | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x0F | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_output_data_rate(
+u8 *gyro_output_typer);
+/*!
+ * @brief This API is used to set the
+ * gyroscope output data rate from the register 0x42 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_output_data_rate_u8 :The value of gyro output data rate
+ * value | gyro output data rate
+ * -----------|-----------------------------
+ * 0x00 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x01 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x02 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x03 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x04 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x05 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x06 | SMI130_GYRO_OUTPUT_DATA_RATE_25HZ
+ * 0x07 | SMI130_GYRO_OUTPUT_DATA_RATE_50HZ
+ * 0x08 | SMI130_GYRO_OUTPUT_DATA_RATE_100HZ
+ * 0x09 | SMI130_GYRO_OUTPUT_DATA_RATE_200HZ
+ * 0x0A | SMI130_GYRO_OUTPUT_DATA_RATE_400HZ
+ * 0x0B | SMI130_GYRO_OUTPUT_DATA_RATE_800HZ
+ * 0x0C | SMI130_GYRO_OUTPUT_DATA_RATE_1600HZ
+ * 0x0D | SMI130_GYRO_OUTPUT_DATA_RATE_3200HZ
+ * 0x0E | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x0F | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_output_data_rate(
+u8 gyro_output_typer);
+/*!
+ * @brief This API is used to get the
+ * data of gyro from the register 0x42 bit 4 to 5
+ *
+ *
+ *
+ *
+ * @param v_bw_u8 : The value of gyro bandwidth
+ * value | gyro bandwidth
+ * ----------|----------------
+ * 0x00 | SMI130_GYRO_OSR4_MODE
+ * 0x01 | SMI130_GYRO_OSR2_MODE
+ * 0x02 | SMI130_GYRO_NORMAL_MODE
+ * 0x03 | SMI130_GYRO_CIC_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_bw(u8 *v_bw_u8);
+/*!
+ * @brief This API is used to set the
+ * data of gyro from the register 0x42 bit 4 to 5
+ *
+ *
+ *
+ *
+ * @param v_bw_u8 : The value of gyro bandwidth
+ * value | gyro bandwidth
+ * ----------|----------------
+ * 0x00 | SMI130_GYRO_OSR4_MODE
+ * 0x01 | SMI130_GYRO_OSR2_MODE
+ * 0x02 | SMI130_GYRO_NORMAL_MODE
+ * 0x03 | SMI130_GYRO_CIC_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_bw(u8 v_bw_u8);
+/*!
+ * @brief This API reads the range
+ * of gyro from the register 0x43 bit 0 to 2
+ *
+ * @param v_range_u8 : The value of gyro range
+ * value | range
+ * ----------|-------------------------------
+ * 0x00 | SMI130_GYRO_RANGE_2000_DEG_SEC
+ * 0x01 | SMI130_GYRO_RANGE_1000_DEG_SEC
+ * 0x02 | SMI130_GYRO_RANGE_500_DEG_SEC
+ * 0x03 | SMI130_GYRO_RANGE_250_DEG_SEC
+ * 0x04 | SMI130_GYRO_RANGE_125_DEG_SEC
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_range(
+u8 *v_range_u8);
+/*!
+ * @brief This API set the range
+ * of gyro from the register 0x43 bit 0 to 2
+ *
+ * @param v_range_u8 : The value of gyro range
+ * value | range
+ * ----------|-------------------------------
+ * 0x00 | SMI130_GYRO_RANGE_2000_DEG_SEC
+ * 0x01 | SMI130_GYRO_RANGE_1000_DEG_SEC
+ * 0x02 | SMI130_GYRO_RANGE_500_DEG_SEC
+ * 0x03 | SMI130_GYRO_RANGE_250_DEG_SEC
+ * 0x04 | SMI130_GYRO_RANGE_125_DEG_SEC
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_range(
+u8 v_range_u8);
+/**************************************************/
+/**\name FUNCTION FOR MAG CONFIGURATIONS */
+/*************************************************/
+/*!
+ * @brief This API is used to get the
+ * output data rate of magnetometer from the register 0x44 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_output_data_rat_u8e : The value of mag output data rate
+ * value | mag output data rate
+ * ---------|---------------------------
+ * 0x00 |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED
+ * 0x01 |SMI130_MAG_OUTPUT_DATA_RATE_0_78HZ
+ * 0x02 |SMI130_MAG_OUTPUT_DATA_RATE_1_56HZ
+ * 0x03 |SMI130_MAG_OUTPUT_DATA_RATE_3_12HZ
+ * 0x04 |SMI130_MAG_OUTPUT_DATA_RATE_6_25HZ
+ * 0x05 |SMI130_MAG_OUTPUT_DATA_RATE_12_5HZ
+ * 0x06 |SMI130_MAG_OUTPUT_DATA_RATE_25HZ
+ * 0x07 |SMI130_MAG_OUTPUT_DATA_RATE_50HZ
+ * 0x08 |SMI130_MAG_OUTPUT_DATA_RATE_100HZ
+ * 0x09 |SMI130_MAG_OUTPUT_DATA_RATE_200HZ
+ * 0x0A |SMI130_MAG_OUTPUT_DATA_RATE_400HZ
+ * 0x0B |SMI130_MAG_OUTPUT_DATA_RATE_800HZ
+ * 0x0C |SMI130_MAG_OUTPUT_DATA_RATE_1600HZ
+ * 0x0D |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED0
+ * 0x0E |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED1
+ * 0x0F |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED2
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_output_data_rate(u8 *odr);
+/*!
+ * @brief This API is used to set the
+ * output data rate of magnetometer from the register 0x44 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_output_data_rat_u8e : The value of mag output data rate
+ * value | mag output data rate
+ * ---------|---------------------------
+ * 0x00 |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED
+ * 0x01 |SMI130_MAG_OUTPUT_DATA_RATE_0_78HZ
+ * 0x02 |SMI130_MAG_OUTPUT_DATA_RATE_1_56HZ
+ * 0x03 |SMI130_MAG_OUTPUT_DATA_RATE_3_12HZ
+ * 0x04 |SMI130_MAG_OUTPUT_DATA_RATE_6_25HZ
+ * 0x05 |SMI130_MAG_OUTPUT_DATA_RATE_12_5HZ
+ * 0x06 |SMI130_MAG_OUTPUT_DATA_RATE_25HZ
+ * 0x07 |SMI130_MAG_OUTPUT_DATA_RATE_50HZ
+ * 0x08 |SMI130_MAG_OUTPUT_DATA_RATE_100HZ
+ * 0x09 |SMI130_MAG_OUTPUT_DATA_RATE_200HZ
+ * 0x0A |SMI130_MAG_OUTPUT_DATA_RATE_400HZ
+ * 0x0B |SMI130_MAG_OUTPUT_DATA_RATE_800HZ
+ * 0x0C |SMI130_MAG_OUTPUT_DATA_RATE_1600HZ
+ * 0x0D |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED0
+ * 0x0E |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED1
+ * 0x0F |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED2
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_output_data_rate(u8 odr);
+/**************************************************/
+/**\name FUNCTION FOR FIFO CONFIGURATIONS */
+/*************************************************/
+ /*!
+ * @brief This API is used to read Down sampling
+ * for gyro (2**downs_gyro) in the register 0x45 bit 0 to 2
+ *
+ *
+ *
+ *
+ * @param v_fifo_down_gyro_u8 :The value of gyro fifo down
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_down_gyro(
+u8 *v_fifo_down_gyro_u8);
+ /*!
+ * @brief This API is used to set Down sampling
+ * for gyro (2**downs_gyro) in the register 0x45 bit 0 to 2
+ *
+ *
+ *
+ *
+ * @param v_fifo_down_gyro_u8 :The value of gyro fifo down
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_down_gyro(
+u8 v_fifo_down_gyro_u8);
+/*!
+ * @brief This API is used to read gyro fifo filter data
+ * from the register 0x45 bit 3
+ *
+ *
+ *
+ * @param v_gyro_fifo_filter_data_u8 :The value of gyro filter data
+ * value | gyro_fifo_filter_data
+ * ------------|-------------------------
+ * 0x00 | Unfiltered data
+ * 0x01 | Filtered data
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_fifo_filter_data(
+u8 *v_gyro_fifo_filter_data_u8);
+/*!
+ * @brief This API is used to set gyro fifo filter data
+ * from the register 0x45 bit 3
+ *
+ *
+ *
+ * @param v_gyro_fifo_filter_data_u8 :The value of gyro filter data
+ * value | gyro_fifo_filter_data
+ * ------------|-------------------------
+ * 0x00 | Unfiltered data
+ * 0x01 | Filtered data
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_fifo_filter_data(
+u8 v_gyro_fifo_filter_data_u8);
+/*!
+ * @brief This API is used to read Down sampling
+ * for accel (2*downs_accel) from the register 0x45 bit 4 to 6
+ *
+ *
+ *
+ *
+ * @param v_fifo_down_u8 :The value of accel fifo down
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_down_accel(
+u8 *v_fifo_down_u8);
+ /*!
+ * @brief This API is used to set Down sampling
+ * for accel (2*downs_accel) from the register 0x45 bit 4 to 6
+ *
+ *
+ *
+ *
+ * @param v_fifo_down_u8 :The value of accel fifo down
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_down_accel(
+u8 v_fifo_down_u8);
+/*!
+ * @brief This API is used to read accel fifo filter data
+ * from the register 0x45 bit 7
+ *
+ *
+ *
+ * @param v_accel_fifo_filter_u8 :The value of accel filter data
+ * value | accel_fifo_filter_data
+ * ------------|-------------------------
+ * 0x00 | Unfiltered data
+ * 0x01 | Filtered data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_fifo_filter_data(
+u8 *v_accel_fifo_filter_u8);
+/*!
+ * @brief This API is used to set accel fifo filter data
+ * from the register 0x45 bit 7
+ *
+ *
+ *
+ * @param v_accel_fifo_filter_u8 :The value of accel filter data
+ * value | accel_fifo_filter_data
+ * ------------|-------------------------
+ * 0x00 | Unfiltered data
+ * 0x01 | Filtered data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_fifo_filter_data(
+u8 v_accel_fifo_filter_u8);
+/**************************************************/
+/**\name FUNCTION FOR FIFO WATER MARK ENABLE */
+/*************************************************/
+/*!
+ * @brief This API is used to Trigger an interrupt
+ * when FIFO contains water mark level from the register 0x46 bit 0 to 7
+ *
+ *
+ *
+ * @param v_fifo_wm_u8 : The value of fifo water mark level
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_wm(
+u8 *v_fifo_wm_u8);
+/*!
+ * @brief This API is used to Trigger an interrupt
+ * when FIFO contains water mark level from the register 0x46 bit 0 to 7
+ *
+ *
+ *
+ * @param v_fifo_wm_u8 : The value of fifo water mark level
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_wm(
+u8 v_fifo_wm_u8);
+/**************************************************/
+/**\name FUNCTION FOR FIFO CONFIGURATIONS */
+/*************************************************/
+/*!
+ * @brief This API reads fifo sensor time
+ * frame after the last valid data frame form the register 0x47 bit 1
+ *
+ *
+ *
+ *
+ * @param v_fifo_time_enable_u8 : The value of sensor time
+ * value | fifo sensor time
+ * ------------|-------------------------
+ * 0x00 | do not return sensortime frame
+ * 0x01 | return sensortime frame
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_time_enable(
+u8 *v_fifo_time_enable_u8);
+/*!
+ * @brief This API set fifo sensor time
+ * frame after the last valid data frame form the register 0x47 bit 1
+ *
+ *
+ *
+ *
+ * @param v_fifo_time_enable_u8 : The value of sensor time
+ * value | fifo sensor time
+ * ------------|-------------------------
+ * 0x00 | do not return sensortime frame
+ * 0x01 | return sensortime frame
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_time_enable(
+u8 v_fifo_time_enable_u8);
+/*!
+ * @brief This API reads FIFO tag interrupt2 enable status
+ * from the resister 0x47 bit 2
+ *
+ * @param v_fifo_tag_intr2_u8 : The value of fifo tag interrupt
+ * value | fifo tag interrupt
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_tag_intr2_enable(
+u8 *v_fifo_tag_intr2_u8);
+/*!
+ * @brief This API set FIFO tag interrupt2 enable status
+ * from the resister 0x47 bit 2
+ *
+ * @param v_fifo_tag_intr2_u8 : The value of fifo tag interrupt
+ * value | fifo tag interrupt
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_tag_intr2_enable(
+u8 v_fifo_tag_intr2_u8);
+/*!
+ * @brief This API get FIFO tag interrupt1 enable status
+ * from the resister 0x47 bit 3
+ *
+ * @param v_fifo_tag_intr1_u8 :The value of fifo tag interrupt1
+ * value | fifo tag interrupt
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_tag_intr1_enable(
+u8 *v_fifo_tag_intr1_u8);
+/*!
+ * @brief This API set FIFO tag interrupt1 enable status
+ * from the resister 0x47 bit 3
+ *
+ * @param v_fifo_tag_intr1_u8 :The value of fifo tag interrupt1
+ * value | fifo tag interrupt
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_tag_intr1_enable(
+u8 v_fifo_tag_intr1_u8);
+/*!
+ * @brief This API reads FIFO frame
+ * header enable from the register 0x47 bit 4
+ *
+ * @param v_fifo_header_u8 :The value of fifo header
+ * value | fifo header
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_header_enable(
+u8 *v_fifo_header_u8);
+/*!
+ * @brief This API set FIFO frame
+ * header enable from the register 0x47 bit 4
+ *
+ * @param v_fifo_header_u8 :The value of fifo header
+ * value | fifo header
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_header_enable(
+u8 v_fifo_header_u8);
+/*!
+ * @brief This API is used to read stored
+ * magnetometer data in FIFO (all 3 axes) from the register 0x47 bit 5
+ *
+ * @param v_fifo_mag_u8 : The value of fifo mag enble
+ * value | fifo mag
+ * ----------|-------------------
+ * 0x00 | no magnetometer data is stored
+ * 0x01 | magnetometer data is stored
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_mag_enable(
+u8 *v_fifo_mag_u8);
+/*!
+ * @brief This API is used to set stored
+ * magnetometer data in FIFO (all 3 axes) from the register 0x47 bit 5
+ *
+ * @param v_fifo_mag_u8 : The value of fifo mag enble
+ * value | fifo mag
+ * ----------|-------------------
+ * 0x00 | no magnetometer data is stored
+ * 0x01 | magnetometer data is stored
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_mag_enable(
+u8 v_fifo_mag_u8);
+/*!
+ * @brief This API is used to read stored
+ * accel data in FIFO (all 3 axes) from the register 0x47 bit 6
+ *
+ * @param v_fifo_accel_u8 : The value of fifo accel enble
+ * value | fifo accel
+ * ----------|-------------------
+ * 0x00 | no accel data is stored
+ * 0x01 | accel data is stored
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_accel_enable(
+u8 *v_fifo_accel_u8);
+/*!
+ * @brief This API is used to set stored
+ * accel data in FIFO (all 3 axes) from the register 0x47 bit 6
+ *
+ * @param v_fifo_accel_u8 : The value of fifo accel enble
+ * value | fifo accel
+ * ----------|-------------------
+ * 0x00 | no accel data is stored
+ * 0x01 | accel data is stored
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_accel_enable(
+u8 v_fifo_accel_u8);
+/*!
+ * @brief This API is used to read stored
+ * gyro data in FIFO (all 3 axes) from the resister 0x47 bit 7
+ *
+ *
+ * @param v_fifo_gyro_u8 : The value of fifo gyro enble
+ * value | fifo gyro
+ * ----------|-------------------
+ * 0x00 | no gyro data is stored
+ * 0x01 | gyro data is stored
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_gyro_enable(
+u8 *v_fifo_gyro_u8);
+/*!
+ * @brief This API is used to set stored
+ * gyro data in FIFO (all 3 axes) from the resister 0x47 bit 7
+ *
+ *
+ * @param v_fifo_gyro_u8 : The value of fifo gyro enble
+ * value | fifo gyro
+ * ----------|-------------------
+ * 0x00 | no gyro data is stored
+ * 0x01 | gyro data is stored
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_gyro_enable(
+u8 v_fifo_gyro_u8);
+/***************************************************************/
+/**\name FUNCTION FOR MAG I2C ADDRESS SELECTION */
+/***************************************************************/
+/*!
+ * @brief This API is used to read
+ * I2C device address of auxiliary mag from the register 0x4B bit 1 to 7
+ *
+ *
+ *
+ *
+ * @param v_i2c_device_addr_u8 : The value of mag I2C device address
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_i2c_device_addr(
+u8 *v_i2c_device_addr_u8);
+/*!
+ * @brief This API is used to set
+ * I2C device address of auxiliary mag from the register 0x4B bit 1 to 7
+ *
+ *
+ *
+ *
+ * @param v_i2c_device_addr_u8 : The value of mag I2C device address
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_i2c_device_addr(
+u8 v_i2c_device_addr_u8);
+/*!
+ * @brief This API is used to read
+ * Burst data length (1,2,6,8 byte) from the register 0x4C bit 0 to 1
+ *
+ *
+ *
+ *
+ * @param v_mag_burst_u8 : The data of mag burst read lenth
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_burst(
+u8 *v_mag_burst_u8);
+/*!
+ * @brief This API is used to set
+ * Burst data length (1,2,6,8 byte) from the register 0x4C bit 0 to 1
+ *
+ *
+ *
+ *
+ * @param v_mag_burst_u8 : The data of mag burst read lenth
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_burst(
+u8 v_mag_burst_u8);
+/***************************************************************/
+/**\name FUNCTION FOR MAG OFFSET */
+/***************************************************************/
+/*!
+ * @brief This API is used to read
+ * trigger-readout offset in units of 2.5 ms. If set to zero,
+ * the offset is maximum, i.e. after readout a trigger
+ * is issued immediately. from the register 0x4C bit 2 to 5
+ *
+ *
+ *
+ *
+ * @param v_mag_offset_u8 : The value of mag offset
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_offset(
+u8 *v_mag_offset_u8);
+/*!
+ * @brief This API is used to set
+ * trigger-readout offset in units of 2.5 ms. If set to zero,
+ * the offset is maximum, i.e. after readout a trigger
+ * is issued immediately. from the register 0x4C bit 2 to 5
+ *
+ *
+ *
+ *
+ * @param v_mag_offset_u8 : The value of mag offset
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_offset(
+u8 v_mag_offset_u8);
+/***************************************************************/
+/**\name FUNCTION FOR MAG MANUAL/AUTO MODE SELECTION */
+/***************************************************************/
+/*!
+ * @brief This API is used to read
+ * Enable register access on MAG_IF[2] or MAG_IF[3] writes.
+ * This implies that the DATA registers are not updated with
+ * magnetometer values. Accessing magnetometer requires
+ * the magnetometer in normal mode in PMU_STATUS.
+ * from the register 0x4C bit 7
+ *
+ *
+ *
+ * @param v_mag_manual_u8 : The value of mag manual enable
+ * value | mag manual
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_manual_enable(
+u8 *v_mag_manual_u8);
+/*!
+ * @brief This API is used to set
+ * Enable register access on MAG_IF[2] or MAG_IF[3] writes.
+ * This implies that the DATA registers are not updated with
+ * magnetometer values. Accessing magnetometer requires
+ * the magnetometer in normal mode in PMU_STATUS.
+ * from the register 0x4C bit 7
+ *
+ *
+ *
+ * @param v_mag_manual_u8 : The value of mag manual enable
+ * value | mag manual
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_manual_enable(
+u8 v_mag_manual_u8);
+/***************************************************************/
+/**\name FUNCTIONS FOR MAG READ, WRITE AND WRITE DATA ADDRESS */
+/***************************************************************/
+/*!
+ * @brief This API is used to read data
+ * magnetometer address to read from the register 0x4D bit 0 to 7
+ * @brief It used to provide mag read address of auxiliary mag
+ *
+ *
+ *
+ *
+ * @param v_mag_read_addr_u8 : The value of address need to be read
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_read_addr(
+u8 *v_mag_read_addr_u8);
+/*!
+ * @brief This API is used to set
+ * magnetometer write address from the register 0x4D bit 0 to 7
+ * @brief mag write address writes the address of auxiliary mag to write
+ *
+ *
+ *
+ * @param v_mag_read_addr_u8:
+ * The data of auxiliary mag address to write data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_read_addr(
+u8 v_mag_read_addr_u8);
+/*!
+ * @brief This API is used to read
+ * magnetometer write address from the register 0x4E bit 0 to 7
+ * @brief mag write address writes the address of auxiliary mag to write
+ *
+ *
+ *
+ * @param v_mag_write_addr_u8:
+ * The data of auxiliary mag address to write data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_write_addr(
+u8 *v_mag_write_addr_u8);
+/*!
+ * @brief This API is used to set
+ * magnetometer write address from the register 0x4E bit 0 to 7
+ * @brief mag write address writes the address of auxiliary mag to write
+ *
+ *
+ *
+ * @param v_mag_write_addr_u8:
+ * The data of auxiliary mag address to write data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_write_addr(
+u8 v_mag_write_addr_u8);
+/*!
+ * @brief This API is used to read magnetometer write data
+ * form the resister 0x4F bit 0 to 7
+ * @brief This writes the data will be wrote to mag
+ *
+ *
+ *
+ * @param v_mag_write_data_u8: The value of mag data
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_write_data(
+u8 *v_mag_write_data_u8);
+/*!
+ * @brief This API is used to set magnetometer write data
+ * form the resister 0x4F bit 0 to 7
+ * @brief This writes the data will be wrote to mag
+ *
+ *
+ *
+ * @param v_mag_write_data_u8: The value of mag data
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_write_data(
+u8 v_mag_write_data_u8);
+/***************************************************************/
+/**\name FUNCTION FOR INTERRUPT ENABLE OF
+ANY-MOTION XYZ, DOUBLE AND SINGLE TAP, ORIENT AND FLAT */
+/***************************************************************/
+/*!
+ * @brief This API is used to read
+ * interrupt enable from the register 0x50 bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_enable_u8 : Value to decided to select interrupt
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_ANY_MOTION_X_ENABLE
+ * 1 | SMI130_ANY_MOTION_Y_ENABLE
+ * 2 | SMI130_ANY_MOTION_Z_ENABLE
+ * 3 | SMI130_DOUBLE_TAP_ENABLE
+ * 4 | SMI130_SINGLE_TAP_ENABLE
+ * 5 | SMI130_ORIENT_ENABLE
+ * 6 | SMI130_FLAT_ENABLE
+ *
+ * @param v_intr_enable_zero_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_enable_0(
+u8 enable, u8 *v_intr_enable_zero_u8);
+/*!
+ * @brief This API is used to set
+ * interrupt enable from the register 0x50 bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_enable_u8 : Value to decided to select interrupt
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_ANY_MOTION_X_ENABLE
+ * 1 | SMI130_ANY_MOTION_Y_ENABLE
+ * 2 | SMI130_ANY_MOTION_Z_ENABLE
+ * 3 | SMI130_DOUBLE_TAP_ENABLE
+ * 4 | SMI130_SINGLE_TAP_ENABLE
+ * 5 | SMI130_ORIENT_ENABLE
+ * 6 | SMI130_FLAT_ENABLE
+ *
+ * @param v_intr_enable_zero_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_enable_0(
+u8 enable, u8 v_intr_enable_zero_u8);
+/***************************************************************/
+/**\name FUNCTION FOR INTERRUPT ENABLE OF
+HIGH_G XYZ, LOW_G, DATA READY, FIFO FULL AND FIFO WATER MARK */
+/***************************************************************/
+/*!
+ * @brief This API is used to read
+ * interrupt enable byte1 from the register 0x51 bit 0 to 6
+ * @brief It read the high_g_x,high_g_y,high_g_z,low_g_enable
+ * data ready, fifo full and fifo water mark.
+ *
+ *
+ *
+ * @param v_enable_u8 : The value of interrupt enable
+ * @param v_enable_u8 : Value to decided to select interrupt
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_HIGH_G_X_ENABLE
+ * 1 | SMI130_HIGH_G_Y_ENABLE
+ * 2 | SMI130_HIGH_G_Z_ENABLE
+ * 3 | SMI130_LOW_G_ENABLE
+ * 4 | SMI130_DATA_RDY_ENABLE
+ * 5 | SMI130_FIFO_FULL_ENABLE
+ * 6 | SMI130_FIFO_WM_ENABLE
+ *
+ * @param v_intr_enable_1_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_enable_1(
+u8 enable, u8 *v_intr_enable_1_u8);
+/*!
+ * @brief This API is used to set
+ * interrupt enable byte1 from the register 0x51 bit 0 to 6
+ * @brief It read the high_g_x,high_g_y,high_g_z,low_g_enable
+ * data ready, fifo full and fifo water mark.
+ *
+ *
+ *
+ * @param v_enable_u8 : The value of interrupt enable
+ * @param v_enable_u8 : Value to decided to select interrupt
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_HIGH_G_X_ENABLE
+ * 1 | SMI130_HIGH_G_Y_ENABLE
+ * 2 | SMI130_HIGH_G_Z_ENABLE
+ * 3 | SMI130_LOW_G_ENABLE
+ * 4 | SMI130_DATA_RDY_ENABLE
+ * 5 | SMI130_FIFO_FULL_ENABLE
+ * 6 | SMI130_FIFO_WM_ENABLE
+ *
+ * @param v_intr_enable_1_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_enable_1(
+u8 enable, u8 v_intr_enable_1_u8);
+/***************************************************************/
+/**\name FUNCTION FOR INTERRUPT ENABLE OF
+NO MOTION XYZ */
+/***************************************************************/
+/*!
+ * @brief This API is used to read
+ * interrupt enable byte2 from the register bit 0x52 bit 0 to 3
+ * @brief It reads no motion x,y and z
+ *
+ *
+ *
+ * @param v_enable_u8: The value of interrupt enable
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_NOMOTION_X_ENABLE
+ * 1 | SMI130_NOMOTION_Y_ENABLE
+ * 2 | SMI130_NOMOTION_Z_ENABLE
+ *
+ * @param v_intr_enable_2_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_enable_2(
+u8 enable, u8 *v_intr_enable_2_u8);
+/*!
+ * @brief This API is used to set
+ * interrupt enable byte2 from the register bit 0x52 bit 0 to 3
+ * @brief It reads no motion x,y and z
+ *
+ *
+ *
+ * @param v_enable_u8: The value of interrupt enable
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_NOMOTION_X_ENABLE
+ * 1 | SMI130_NOMOTION_Y_ENABLE
+ * 2 | SMI130_NOMOTION_Z_ENABLE
+ *
+ * @param v_intr_enable_2_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_enable_2(
+u8 enable, u8 v_intr_enable_2_u8);
+/***************************************************************/
+/**\name FUNCTION FOR INTERRUPT ENABLE OF
+ STEP DETECTOR */
+/***************************************************************/
+ /*!
+ * @brief This API is used to read
+ * interrupt enable step detector interrupt from
+ * the register bit 0x52 bit 3
+ *
+ *
+ *
+ *
+ * @param v_step_intr_u8 : The value of step detector interrupt enable
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_get_step_detector_enable(
+u8 *v_step_intr_u8);
+ /*!
+ * @brief This API is used to set
+ * interrupt enable step detector interrupt from
+ * the register bit 0x52 bit 3
+ *
+ *
+ *
+ *
+ * @param v_step_intr_u8 : The value of step detector interrupt enable
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_step_detector_enable(
+u8 v_step_intr_u8);
+/***************************************************************/
+/**\name FUNCTION FOR INTERRUPT CONTROL */
+/***************************************************************/
+/*!
+ * @brief Configure trigger condition of interrupt1
+ * and interrupt2 pin from the register 0x53
+ * @brief interrupt1 - bit 0
+ * @brief interrupt2 - bit 4
+ *
+ * @param v_channel_u8: The value of edge trigger selection
+ * v_channel_u8 | Edge trigger
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_EDGE_CTRL
+ * 1 | SMI130_INTR2_EDGE_CTRL
+ *
+ * @param v_intr_edge_ctrl_u8 : The value of edge trigger enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_EDGE
+ * 0x00 | SMI130_LEVEL
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_edge_ctrl(
+u8 v_channel_u8, u8 *v_intr_edge_ctrl_u8);
+/*!
+ * @brief Configure trigger condition of interrupt1
+ * and interrupt2 pin from the register 0x53
+ * @brief interrupt1 - bit 0
+ * @brief interrupt2 - bit 4
+ *
+ * @param v_channel_u8: The value of edge trigger selection
+ * v_channel_u8 | Edge trigger
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_EDGE_CTRL
+ * 1 | SMI130_INTR2_EDGE_CTRL
+ *
+ * @param v_intr_edge_ctrl_u8 : The value of edge trigger enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_EDGE
+ * 0x00 | SMI130_LEVEL
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_edge_ctrl(
+u8 v_channel_u8, u8 v_intr_edge_ctrl_u8);
+/*!
+ * @brief API used for get the Configure level condition of interrupt1
+ * and interrupt2 pin form the register 0x53
+ * @brief interrupt1 - bit 1
+ * @brief interrupt2 - bit 5
+ *
+ * @param v_channel_u8: The value of level condition selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_LEVEL
+ * 1 | SMI130_INTR2_LEVEL
+ *
+ * @param v_intr_level_u8 : The value of level of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | SMI130_LEVEL_HIGH
+ * 0x00 | SMI130_LEVEL_LOW
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_level(
+u8 v_channel_u8, u8 *v_intr_level_u8);
+/*!
+ * @brief API used for set the Configure level condition of interrupt1
+ * and interrupt2 pin form the register 0x53
+ * @brief interrupt1 - bit 1
+ * @brief interrupt2 - bit 5
+ *
+ * @param v_channel_u8: The value of level condition selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_LEVEL
+ * 1 | SMI130_INTR2_LEVEL
+ *
+ * @param v_intr_level_u8 : The value of level of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | SMI130_LEVEL_HIGH
+ * 0x00 | SMI130_LEVEL_LOW
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_level(
+u8 v_channel_u8, u8 v_intr_level_u8);
+/*!
+ * @brief API used to get configured output enable of interrupt1
+ * and interrupt2 from the register 0x53
+ * @brief interrupt1 - bit 2
+ * @brief interrupt2 - bit 6
+ *
+ *
+ * @param v_channel_u8: The value of output type enable selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_OUTPUT_TYPE
+ * 1 | SMI130_INTR2_OUTPUT_TYPE
+ *
+ * @param v_intr_output_type_u8 :
+ * The value of output type of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | SMI130_OPEN_DRAIN
+ * 0x00 | SMI130_PUSH_PULL
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_output_type(
+u8 v_channel_u8, u8 *v_intr_output_type_u8);
+/*!
+ * @brief API used to set output enable of interrupt1
+ * and interrupt2 from the register 0x53
+ * @brief interrupt1 - bit 2
+ * @brief interrupt2 - bit 6
+ *
+ *
+ * @param v_channel_u8: The value of output type enable selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_OUTPUT_TYPE
+ * 1 | SMI130_INTR2_OUTPUT_TYPE
+ *
+ * @param v_intr_output_type_u8 :
+ * The value of output type of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | SMI130_OPEN_DRAIN
+ * 0x00 | SMI130_PUSH_PULL
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_output_type(
+u8 v_channel_u8, u8 v_intr_output_type_u8);
+ /*!
+ * @brief API used to get the Output enable for interrupt1
+ * and interrupt1 pin from the register 0x53
+ * @brief interrupt1 - bit 3
+ * @brief interrupt2 - bit 7
+ *
+ * @param v_channel_u8: The value of output enable selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_OUTPUT_TYPE
+ * 1 | SMI130_INTR2_OUTPUT_TYPE
+ *
+ * @param v_output_enable_u8 :
+ * The value of output enable of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | SMI130_INPUT
+ * 0x00 | SMI130_OUTPUT
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_output_enable(
+u8 v_channel_u8, u8 *v_output_enable_u8);
+ /*!
+ * @brief API used to set the Output enable for interrupt1
+ * and interrupt1 pin from the register 0x53
+ * @brief interrupt1 - bit 3
+ * @brief interrupt2 - bit 7
+ *
+ * @param v_channel_u8: The value of output enable selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_OUTPUT_TYPE
+ * 1 | SMI130_INTR2_OUTPUT_TYPE
+ *
+ * @param v_output_enable_u8 :
+ * The value of output enable of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | SMI130_INPUT
+ * 0x00 | SMI130_OUTPUT
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_output_enable(
+u8 v_channel_u8, u8 v_output_enable_u8);
+/***************************************************************/
+/**\name FUNCTION FOR INTERRUPT LATCH INTERRUPT */
+/***************************************************************/
+/*!
+* @brief This API is used to get the latch duration
+* from the register 0x54 bit 0 to 3
+* @brief This latch selection is not applicable for data ready,
+* orient_mblation and flat interrupts.
+*
+*
+*
+* @param v_latch_intr_u8 : The value of latch duration
+* Latch Duration | value
+* --------------------------------------|------------------
+* SMI130_LATCH_DUR_NONE | 0x00
+* SMI130_LATCH_DUR_312_5_MICRO_SEC | 0x01
+* SMI130_LATCH_DUR_625_MICRO_SEC | 0x02
+* SMI130_LATCH_DUR_1_25_MILLI_SEC | 0x03
+* SMI130_LATCH_DUR_2_5_MILLI_SEC | 0x04
+* SMI130_LATCH_DUR_5_MILLI_SEC | 0x05
+* SMI130_LATCH_DUR_10_MILLI_SEC | 0x06
+* SMI130_LATCH_DUR_20_MILLI_SEC | 0x07
+* SMI130_LATCH_DUR_40_MILLI_SEC | 0x08
+* SMI130_LATCH_DUR_80_MILLI_SEC | 0x09
+* SMI130_LATCH_DUR_160_MILLI_SEC | 0x0A
+* SMI130_LATCH_DUR_320_MILLI_SEC | 0x0B
+* SMI130_LATCH_DUR_640_MILLI_SEC | 0x0C
+* SMI130_LATCH_DUR_1_28_SEC | 0x0D
+* SMI130_LATCH_DUR_2_56_SEC | 0x0E
+* SMI130_LATCHED | 0x0F
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_latch_intr(
+u8 *v_latch_intr_u8);
+/*!
+* @brief This API is used to set the latch duration
+* from the register 0x54 bit 0 to 3
+* @brief This latch selection is not applicable for data ready,
+* orient_mblation and flat interrupts.
+*
+*
+*
+* @param v_latch_intr_u8 : The value of latch duration
+* Latch Duration | value
+* --------------------------------------|------------------
+* SMI130_LATCH_DUR_NONE | 0x00
+* SMI130_LATCH_DUR_312_5_MICRO_SEC | 0x01
+* SMI130_LATCH_DUR_625_MICRO_SEC | 0x02
+* SMI130_LATCH_DUR_1_25_MILLI_SEC | 0x03
+* SMI130_LATCH_DUR_2_5_MILLI_SEC | 0x04
+* SMI130_LATCH_DUR_5_MILLI_SEC | 0x05
+* SMI130_LATCH_DUR_10_MILLI_SEC | 0x06
+* SMI130_LATCH_DUR_20_MILLI_SEC | 0x07
+* SMI130_LATCH_DUR_40_MILLI_SEC | 0x08
+* SMI130_LATCH_DUR_80_MILLI_SEC | 0x09
+* SMI130_LATCH_DUR_160_MILLI_SEC | 0x0A
+* SMI130_LATCH_DUR_320_MILLI_SEC | 0x0B
+* SMI130_LATCH_DUR_640_MILLI_SEC | 0x0C
+* SMI130_LATCH_DUR_1_28_SEC | 0x0D
+* SMI130_LATCH_DUR_2_56_SEC | 0x0E
+* SMI130_LATCHED | 0x0F
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_latch_intr(
+u8 v_latch_intr_u8);
+/*!
+ * @brief API used to get input enable for interrupt1
+ * and interrupt2 pin from the register 0x54
+ * @brief interrupt1 - bit 4
+ * @brief interrupt2 - bit 5
+ *
+ * @param v_channel_u8: The value of input enable selection
+ * v_channel_u8 | input selection
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_INPUT_ENABLE
+ * 1 | SMI130_INTR2_INPUT_ENABLE
+ *
+ * @param v_input_en_u8 :
+ * The value of input enable of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | SMI130_INPUT
+ * 0x00 | SMI130_OUTPUT
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_input_enable(
+u8 v_channel_u8, u8 *v_input_en_u8);
+/*!
+ * @brief API used to set input enable for interrupt1
+ * and interrupt2 pin from the register 0x54
+ * @brief interrupt1 - bit 4
+ * @brief interrupt2 - bit 5
+ *
+ * @param v_channel_u8: The value of input enable selection
+ * v_channel_u8 | input selection
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_INPUT_ENABLE
+ * 1 | SMI130_INTR2_INPUT_ENABLE
+ *
+ * @param v_input_en_u8 :
+ * The value of input enable of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | SMI130_INPUT
+ * 0x00 | SMI130_OUTPUT
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_input_enable(
+u8 v_channel_u8, u8 v_input_en_u8);
+/***************************************************************/
+/**\name FUNCTION FOR INTERRUPT1 AND INTERRUPT2 MAPPING */
+/***************************************************************/
+ /*!
+ * @brief reads the Low g interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 0 in the register 0x55
+ * @brief interrupt2 bit 0 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of low_g selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_LOW_G
+ * 1 | SMI130_INTR2_MAP_LOW_G
+ *
+ * @param v_intr_low_g_u8 : The value of low_g enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_low_g(
+u8 v_channel_u8, u8 *v_intr_low_g_u8);
+ /*!
+ * @brief set the Low g interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 0 in the register 0x55
+ * @brief interrupt2 bit 0 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of low_g selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_LOW_G
+ * 1 | SMI130_INTR2_MAP_LOW_G
+ *
+ * @param v_intr_low_g_u8 : The value of low_g enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_low_g(
+u8 v_channel_u8, u8 v_intr_low_g_u8);
+/*!
+ * @brief Reads the HIGH g interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 1 in the register 0x55
+ * @brief interrupt2 bit 1 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of high_g selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_HIGH_G
+ * 1 | SMI130_INTR2_MAP_HIGH_G
+ *
+ * @param v_intr_high_g_u8 : The value of high_g enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_high_g(
+u8 v_channel_u8, u8 *v_intr_high_g_u8);
+/*!
+ * @brief Write the HIGH g interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 1 in the register 0x55
+ * @brief interrupt2 bit 1 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of high_g selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_HIGH_G
+ * 1 | SMI130_INTR2_MAP_HIGH_G
+ *
+ * @param v_intr_high_g_u8 : The value of high_g enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_high_g(
+u8 v_channel_u8, u8 v_intr_high_g_u8);
+/*!
+ * @brief Reads the Any motion interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 2 in the register 0x55
+ * @brief interrupt2 bit 2 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of any motion selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_ANY_MOTION
+ * 1 | SMI130_INTR2_MAP_ANY_MOTION
+ *
+ * @param v_intr_any_motion_u8 : The value of any motion enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_any_motion(
+u8 v_channel_u8, u8 *v_intr_any_motion_u8);
+/*!
+ * @brief Write the Any motion interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 2 in the register 0x55
+ * @brief interrupt2 bit 2 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of any motion selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_ANY_MOTION
+ * 1 | SMI130_INTR2_MAP_ANY_MOTION
+ *
+ * @param v_intr_any_motion_u8 : The value of any motion enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_any_motion(
+u8 v_channel_u8, u8 v_intr_any_motion_u8);
+/*!
+ * @brief Reads the No motion interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 3 in the register 0x55
+ * @brief interrupt2 bit 3 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of no motion selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_NOMO
+ * 1 | SMI130_INTR2_MAP_NOMO
+ *
+ * @param v_intr_nomotion_u8 : The value of no motion enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_nomotion(
+u8 v_channel_u8, u8 *v_intr_nomotion_u8);
+/*!
+ * @brief Write the No motion interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 3 in the register 0x55
+ * @brief interrupt2 bit 3 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of no motion selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_NOMO
+ * 1 | SMI130_INTR2_MAP_NOMO
+ *
+ * @param v_intr_nomotion_u8 : The value of no motion enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_nomotion(
+u8 v_channel_u8, u8 v_intr_nomotion_u8);
+/*!
+ * @brief Reads the Double Tap interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 4 in the register 0x55
+ * @brief interrupt2 bit 4 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of double tap interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_DOUBLE_TAP
+ * 1 | SMI130_INTR2_MAP_DOUBLE_TAP
+ *
+ * @param v_intr_double_tap_u8 : The value of double tap enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_double_tap(
+u8 v_channel_u8, u8 *v_intr_double_tap_u8);
+/*!
+ * @brief Write the Double Tap interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 4 in the register 0x55
+ * @brief interrupt2 bit 4 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of double tap interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_DOUBLE_TAP
+ * 1 | SMI130_INTR2_MAP_DOUBLE_TAP
+ *
+ * @param v_intr_double_tap_u8 : The value of double tap enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_double_tap(
+u8 v_channel_u8, u8 v_intr_double_tap_u8);
+/*!
+ * @brief Reads the Single Tap interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 5 in the register 0x55
+ * @brief interrupt2 bit 5 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of single tap interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_SINGLE_TAP
+ * 1 | SMI130_INTR2_MAP_SINGLE_TAP
+ *
+ * @param v_intr_single_tap_u8 : The value of single tap enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_single_tap(
+u8 v_channel_u8, u8 *v_intr_single_tap_u8);
+/*!
+ * @brief Write the Single Tap interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 5 in the register 0x55
+ * @brief interrupt2 bit 5 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of single tap interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_SINGLE_TAP
+ * 1 | SMI130_INTR2_MAP_SINGLE_TAP
+ *
+ * @param v_intr_single_tap_u8 : The value of single tap enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_single_tap(
+u8 v_channel_u8, u8 v_intr_single_tap_u8);
+/*!
+ * @brief Reads the Orient interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 6 in the register 0x55
+ * @brief interrupt2 bit 6 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of orient_mbl interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_ORIENT
+ * 1 | SMI130_INTR2_MAP_ORIENT
+ *
+ * @param v_intr_orient_mbl_u8 : The value of orient_mbl enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_orient_mbl(
+u8 v_channel_u8, u8 *v_intr_orient_mbl_u8);
+/*!
+ * @brief Write the Orient interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 6 in the register 0x55
+ * @brief interrupt2 bit 6 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of orient_mbl interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_ORIENT
+ * 1 | SMI130_INTR2_MAP_ORIENT
+ *
+ * @param v_intr_orient_mbl_u8 : The value of orient_mbl enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_orient_mbl(
+u8 v_channel_u8, u8 v_intr_orient_mbl_u8);
+ /*!
+ * @brief Reads the Flat interrupt
+ * mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 7 in the register 0x55
+ * @brief interrupt2 bit 7 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of flat interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_FLAT
+ * 1 | SMI130_INTR2_MAP_FLAT
+ *
+ * @param v_intr_flat_u8 : The value of flat enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_flat(
+u8 v_channel_u8, u8 *v_intr_flat_u8);
+ /*!
+ * @brief Write the Flat interrupt
+ * mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 7 in the register 0x55
+ * @brief interrupt2 bit 7 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of flat interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_FLAT
+ * 1 | SMI130_INTR2_MAP_FLAT
+ *
+ * @param v_intr_flat_u8 : The value of flat enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_flat(
+u8 v_channel_u8, u8 v_intr_flat_u8);
+/*!
+ * @brief Reads PMU trigger interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 0 and 4
+ * @brief interrupt1 bit 0 in the register 0x56
+ * @brief interrupt2 bit 4 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of pmu trigger selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_PMUTRIG
+ * 1 | SMI130_INTR2_MAP_PMUTRIG
+ *
+ * @param v_intr_pmu_trig_u8 : The value of pmu trigger enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_pmu_trig(
+u8 v_channel_u8, u8 *v_intr_pmu_trig_u8);
+/*!
+ * @brief Write PMU trigger interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 0 and 4
+ * @brief interrupt1 bit 0 in the register 0x56
+ * @brief interrupt2 bit 4 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of pmu trigger selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_PMUTRIG
+ * 1 | SMI130_INTR2_MAP_PMUTRIG
+ *
+ * @param v_intr_pmu_trig_u8 : The value of pmu trigger enable
+ * value | trigger enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_pmu_trig(
+u8 v_channel_u8, u8 v_intr_pmu_trig_u8);
+/*!
+ * @brief Reads FIFO Full interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 5 and 1
+ * @brief interrupt1 bit 5 in the register 0x56
+ * @brief interrupt2 bit 1 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of fifo full interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_FIFO_FULL
+ * 1 | SMI130_INTR2_MAP_FIFO_FULL
+ *
+ * @param v_intr_fifo_full_u8 : The value of fifo full interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_fifo_full(
+u8 v_channel_u8, u8 *v_intr_fifo_full_u8);
+/*!
+ * @brief Write FIFO Full interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 5 and 1
+ * @brief interrupt1 bit 5 in the register 0x56
+ * @brief interrupt2 bit 1 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of fifo full interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_FIFO_FULL
+ * 1 | SMI130_INTR2_MAP_FIFO_FULL
+ *
+ * @param v_intr_fifo_full_u8 : The value of fifo full interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_fifo_full(
+u8 v_channel_u8, u8 v_intr_fifo_full_u8);
+/*!
+ * @brief Reads FIFO Watermark interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 6 and 2
+ * @brief interrupt1 bit 6 in the register 0x56
+ * @brief interrupt2 bit 2 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of fifo Watermark interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_FIFO_WM
+ * 1 | SMI130_INTR2_MAP_FIFO_WM
+ *
+ * @param v_intr_fifo_wm_u8 : The value of fifo Watermark interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_fifo_wm(
+u8 v_channel_u8, u8 *v_intr_fifo_wm_u8);
+/*!
+ * @brief Write FIFO Watermark interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 6 and 2
+ * @brief interrupt1 bit 6 in the register 0x56
+ * @brief interrupt2 bit 2 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of fifo Watermark interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_FIFO_WM
+ * 1 | SMI130_INTR2_MAP_FIFO_WM
+ *
+ * @param v_intr_fifo_wm_u8 : The value of fifo Watermark interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_fifo_wm(
+u8 v_channel_u8, u8 v_intr_fifo_wm_u8);
+/*!
+ * @brief Reads Data Ready interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56
+ * @brief interrupt1 bit 7 in the register 0x56
+ * @brief interrupt2 bit 3 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of data ready interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_DATA_RDY
+ * 1 | SMI130_INTR2_MAP_DATA_RDY
+ *
+ * @param v_intr_data_rdy_u8 : The value of data ready interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_data_rdy(
+u8 v_channel_u8, u8 *v_intr_data_rdy_u8);
+/*!
+ * @brief Write Data Ready interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56
+ * @brief interrupt1 bit 7 in the register 0x56
+ * @brief interrupt2 bit 3 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of data ready interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_DATA_RDY
+ * 1 | SMI130_INTR2_MAP_DATA_RDY
+ *
+ * @param v_intr_data_rdy_u8 : The value of data ready interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_data_rdy(
+u8 v_channel_u8, u8 v_intr_data_rdy_u8);
+/***************************************************************/
+/**\name FUNCTION FOR TAP SOURCE CONFIGURATION */
+/***************************************************************/
+ /*!
+ * @brief This API reads data source for the interrupt
+ * engine for the single and double tap interrupts from the register
+ * 0x58 bit 3
+ *
+ *
+ * @param v_tap_source_u8 : The value of the tap source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_tap_source(
+u8 *v_tap_source_u8);
+ /*!
+ * @brief This API write data source for the interrupt
+ * engine for the single and double tap interrupts from the register
+ * 0x58 bit 3
+ *
+ *
+ * @param v_tap_source_u8 : The value of the tap source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_tap_source(
+u8 v_tap_source_u8);
+/***************************************************************/
+/**\name FUNCTION FOR LOW_G AND HIGH_G SOURCE CONFIGURATION */
+/***************************************************************/
+ /*!
+ * @brief This API Reads Data source for the
+ * interrupt engine for the low and high g interrupts
+ * from the register 0x58 bit 7
+ *
+ * @param v_low_high_source_u8 : The value of the tap source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_low_high_source(
+u8 *v_low_high_source_u8);
+ /*!
+ * @brief This API write Data source for the
+ * interrupt engine for the low and high g interrupts
+ * from the register 0x58 bit 7
+ *
+ * @param v_low_high_source_u8 : The value of the tap source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_low_high_source(
+u8 v_low_high_source_u8);
+/***************************************************************/
+/**\name FUNCTION FOR MOTION SOURCE CONFIGURATION */
+/***************************************************************/
+ /*!
+ * @brief This API reads Data source for the
+ * interrupt engine for the nomotion and anymotion interrupts
+ * from the register 0x59 bit 7
+ *
+ * @param v_motion_source_u8 :
+ * The value of the any/no motion interrupt source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_motion_source(
+u8 *v_motion_source_u8);
+ /*!
+ * @brief This API write Data source for the
+ * interrupt engine for the nomotion and anymotion interrupts
+ * from the register 0x59 bit 7
+ *
+ * @param v_motion_source_u8 :
+ * The value of the any/no motion interrupt source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_motion_source(
+u8 v_motion_source_u8);
+/***************************************************************/
+/**\name FUNCTION FOR LOW_G DURATION CONFIGURATION */
+/***************************************************************/
+/*!
+ * @brief This API is used to read the low_g duration from register
+ * 0x5A bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_low_g_durn_u8 : The value of low_g duration
+ *
+ * @note Low_g duration trigger trigger delay according to
+ * "(v_low_g_durn_u8 * 2.5)ms" in a range from 2.5ms to 640ms.
+ * the default corresponds delay is 20ms
+ * @note When low_g data source of interrupt is unfiltered
+ * the sensor must not be in low power mode
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_low_g_durn(
+u8 *v_low_durn_u8);
+ /*!
+ * @brief This API is used to write the low_g duration from register
+ * 0x5A bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_low_g_durn_u8 : The value of low_g duration
+ *
+ * @note Low_g duration trigger trigger delay according to
+ * "(v_low_g_durn_u8 * 2.5)ms" in a range from 2.5ms to 640ms.
+ * the default corresponds delay is 20ms
+ * @note When low_g data source of interrupt is unfiltered
+ * the sensor must not be in low power mode
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_low_g_durn(
+u8 v_low_durn_u8);
+/***************************************************************/
+/**\name FUNCTION FOR LOW_G THRESH CONFIGURATION */
+/***************************************************************/
+/*!
+ * @brief This API is used to read Threshold
+ * definition for the low-g interrupt from the register 0x5B bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_low_g_thres_u8 : The value of low_g threshold
+ *
+ * @note Low_g interrupt trigger threshold according to
+ * (v_low_g_thres_u8 * 7.81)mg for v_low_g_thres_u8 > 0
+ * 3.91 mg for v_low_g_thres_u8 = 0
+ * The threshold range is form 3.91mg to 2.000mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_low_g_thres(
+u8 *v_low_g_thres_u8);
+/*!
+ * @brief This API is used to write Threshold
+ * definition for the low-g interrupt from the register 0x5B bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_low_g_thres_u8 : The value of low_g threshold
+ *
+ * @note Low_g interrupt trigger threshold according to
+ * (v_low_g_thres_u8 * 7.81)mg for v_low_g_thres_u8 > 0
+ * 3.91 mg for v_low_g_thres_u8 = 0
+ * The threshold range is form 3.91mg to 2.000mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_low_g_thres(
+u8 v_low_g_thres_u8);
+/***************************************************************/
+/**\name FUNCTION FOR LOW_G HYSTERESIS CONFIGURATION */
+/***************************************************************/
+ /*!
+ * @brief This API Reads Low-g interrupt hysteresis
+ * from the register 0x5C bit 0 to 1
+ *
+ * @param v_low_hyst_u8 :The value of low_g hysteresis
+ *
+ * @note Low_g hysteresis calculated by v_low_hyst_u8*125 mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_low_g_hyst(
+u8 *v_low_hyst_u8);
+ /*!
+ * @brief This API write Low-g interrupt hysteresis
+ * from the register 0x5C bit 0 to 1
+ *
+ * @param v_low_hyst_u8 :The value of low_g hysteresis
+ *
+ * @note Low_g hysteresis calculated by v_low_hyst_u8*125 mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_low_g_hyst(
+u8 v_low_hyst_u8);
+/***************************************************************/
+/**\name FUNCTION FOR LOW_G MODE CONFIGURATION */
+/***************************************************************/
+/*!
+ * @brief This API reads Low-g interrupt mode
+ * from the register 0x5C bit 2
+ *
+ * @param v_low_g_mode_u8 : The value of low_g mode
+ * Value | Description
+ * ----------|-----------------
+ * 0 | single-axis
+ * 1 | axis-summing
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_low_g_mode(
+u8 *v_low_g_mode_u8);
+/*!
+ * @brief This API write Low-g interrupt mode
+ * from the register 0x5C bit 2
+ *
+ * @param v_low_g_mode_u8 : The value of low_g mode
+ * Value | Description
+ * ----------|-----------------
+ * 0 | single-axis
+ * 1 | axis-summing
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_low_g_mode(
+u8 v_low_g_mode_u8);
+/***************************************************************/
+/**\name FUNCTION FOR HIGH_G HYST CONFIGURATION */
+/***************************************************************/
+/*!
+ * @brief This API reads High-g interrupt hysteresis
+ * from the register 0x5C bit 6 and 7
+ *
+ * @param v_high_g_hyst_u8 : The value of high hysteresis
+ *
+ * @note High_g hysteresis changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | high_g hysteresis
+ * ----------------|---------------------
+ * 2g | high_hy*125 mg
+ * 4g | high_hy*250 mg
+ * 8g | high_hy*500 mg
+ * 16g | high_hy*1000 mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_high_g_hyst(
+u8 *v_high_g_hyst_u8);
+/*!
+ * @brief This API write High-g interrupt hysteresis
+ * from the register 0x5C bit 6 and 7
+ *
+ * @param v_high_g_hyst_u8 : The value of high hysteresis
+ *
+ * @note High_g hysteresis changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | high_g hysteresis
+ * ----------------|---------------------
+ * 2g | high_hy*125 mg
+ * 4g | high_hy*250 mg
+ * 8g | high_hy*500 mg
+ * 16g | high_hy*1000 mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_high_g_hyst(
+u8 v_high_g_hyst_u8);
+/***************************************************************/
+/**\name FUNCTION FOR HIGH_G DURATION CONFIGURATION */
+/***************************************************************/
+/*!
+ * @brief This API is used to read Delay
+ * time definition for the high-g interrupt from the register
+ * 0x5D bit 0 to 7
+ *
+ *
+ *
+ * @param v_high_g_durn_u8 : The value of high duration
+ *
+ * @note High_g interrupt delay triggered according to
+ * v_high_g_durn_u8 * 2.5ms in a range from 2.5ms to 640ms
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_high_g_durn(
+u8 *v_high_g_durn_u8);
+/*!
+ * @brief This API is used to write Delay
+ * time definition for the high-g interrupt from the register
+ * 0x5D bit 0 to 7
+ *
+ *
+ *
+ * @param v_high_g_durn_u8 : The value of high duration
+ *
+ * @note High_g interrupt delay triggered according to
+ * v_high_g_durn_u8 * 2.5ms in a range from 2.5ms to 640ms
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_high_g_durn(
+u8 v_high_g_durn_u8);
+/***************************************************************/
+/**\name FUNCTION FOR HIGH_G THRESHOLD CONFIGURATION */
+/***************************************************************/
+/*!
+ * @brief This API is used to read Threshold
+ * definition for the high-g interrupt from the register 0x5E 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_high_g_thres_u8 : Pointer holding the value of Threshold
+ * @note High_g threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | high_g threshold
+ * ----------------|---------------------
+ * 2g | v_high_g_thres_u8*7.81 mg
+ * 4g | v_high_g_thres_u8*15.63 mg
+ * 8g | v_high_g_thres_u8*31.25 mg
+ * 16g | v_high_g_thres_u8*62.5 mg
+ * @note when v_high_g_thres_u8 = 0
+ * accel_range | high_g threshold
+ * ----------------|---------------------
+ * 2g | 3.91 mg
+ * 4g | 7.81 mg
+ * 8g | 15.63 mg
+ * 16g | 31.25 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_high_g_thres(
+u8 *v_high_g_thres_u8);
+/*!
+ * @brief This API is used to write Threshold
+ * definition for the high-g interrupt from the register 0x5E 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_high_g_thres_u8 : Pointer holding the value of Threshold
+ * @note High_g threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | high_g threshold
+ * ----------------|---------------------
+ * 2g | v_high_g_thres_u8*7.81 mg
+ * 4g | v_high_g_thres_u8*15.63 mg
+ * 8g | v_high_g_thres_u8*31.25 mg
+ * 16g | v_high_g_thres_u8*62.5 mg
+ * @note when v_high_g_thres_u8 = 0
+ * accel_range | high_g threshold
+ * ----------------|---------------------
+ * 2g | 3.91 mg
+ * 4g | 7.81 mg
+ * 8g | 15.63 mg
+ * 16g | 31.25 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_high_g_thres(
+u8 v_high_g_thres_u8);
+/***************************************************************/
+/**\name FUNCTION FOR ANY MOTION DURATION CONFIGURATION */
+/***************************************************************/
+/*!
+ * @brief This API reads any motion duration
+ * from the register 0x5F bit 0 and 1
+ *
+ * @param v_any_motion_durn_u8 : The value of any motion duration
+ *
+ * @note Any motion duration can be calculated by "v_any_motion_durn_u8 + 1"
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_any_motion_durn(
+u8 *v_any_motion_durn_u8);
+/*!
+ * @brief This API write any motion duration
+ * from the register 0x5F bit 0 and 1
+ *
+ * @param v_any_motion_durn_u8 : The value of any motion duration
+ *
+ * @note Any motion duration can be calculated by "v_any_motion_durn_u8 + 1"
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_any_motion_durn(
+u8 nomotion);
+/***************************************************************/
+/**\name FUNCTION FOR SLOW NO MOTION DURATION CONFIGURATION */
+/***************************************************************/
+ /*!
+ * @brief This API read Slow/no-motion
+ * interrupt trigger delay duration from the register 0x5F bit 2 to 7
+ *
+ * @param v_slow_no_motion_u8 :The value of slow no motion duration
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ * @note
+ * @note v_slow_no_motion_u8(5:4)=0b00 ->
+ * [v_slow_no_motion_u8(3:0) + 1] * 1.28s (1.28s-20.48s)
+ * @note v_slow_no_motion_u8(5:4)=1 ->
+ * [v_slow_no_motion_u8(3:0)+5] * 5.12s (25.6s-102.4s)
+ * @note v_slow_no_motion_u8(5)='1' ->
+ * [(v_slow_no_motion_u8:0)+11] * 10.24s (112.64s-430.08s);
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_slow_no_motion_durn(
+u8 *v_slow_no_motion_u8);
+ /*!
+ * @brief This API write Slow/no-motion
+ * interrupt trigger delay duration from the register 0x5F bit 2 to 7
+ *
+ * @param v_slow_no_motion_u8 :The value of slow no motion duration
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ * @note
+ * @note v_slow_no_motion_u8(5:4)=0b00 ->
+ * [v_slow_no_motion_u8(3:0) + 1] * 1.28s (1.28s-20.48s)
+ * @note v_slow_no_motion_u8(5:4)=1 ->
+ * [v_slow_no_motion_u8(3:0)+5] * 5.12s (25.6s-102.4s)
+ * @note v_slow_no_motion_u8(5)='1' ->
+ * [(v_slow_no_motion_u8:0)+11] * 10.24s (112.64s-430.08s);
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_slow_no_motion_durn(
+u8 v_slow_no_motion_u8);
+/***************************************************************/
+/**\name FUNCTION FOR ANY MOTION THRESHOLD CONFIGURATION */
+/***************************************************************/
+/*!
+ * @brief This API is used to read threshold
+ * definition for the any-motion interrupt
+ * from the register 0x60 bit 0 to 7
+ *
+ *
+ * @param v_any_motion_thres_u8 : The value of any motion threshold
+ *
+ * @note any motion threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | any motion threshold
+ * ----------------|---------------------
+ * 2g | v_any_motion_thres_u8*3.91 mg
+ * 4g | v_any_motion_thres_u8*7.81 mg
+ * 8g | v_any_motion_thres_u8*15.63 mg
+ * 16g | v_any_motion_thres_u8*31.25 mg
+ * @note when v_any_motion_thres_u8 = 0
+ * accel_range | any motion threshold
+ * ----------------|---------------------
+ * 2g | 1.95 mg
+ * 4g | 3.91 mg
+ * 8g | 7.81 mg
+ * 16g | 15.63 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_any_motion_thres(
+u8 *v_any_motion_thres_u8);
+/*!
+ * @brief This API is used to write threshold
+ * definition for the any-motion interrupt
+ * from the register 0x60 bit 0 to 7
+ *
+ *
+ * @param v_any_motion_thres_u8 : The value of any motion threshold
+ *
+ * @note any motion threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | any motion threshold
+ * ----------------|---------------------
+ * 2g | v_any_motion_thres_u8*3.91 mg
+ * 4g | v_any_motion_thres_u8*7.81 mg
+ * 8g | v_any_motion_thres_u8*15.63 mg
+ * 16g | v_any_motion_thres_u8*31.25 mg
+ * @note when v_any_motion_thres_u8 = 0
+ * accel_range | any motion threshold
+ * ----------------|---------------------
+ * 2g | 1.95 mg
+ * 4g | 3.91 mg
+ * 8g | 7.81 mg
+ * 16g | 15.63 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_any_motion_thres(
+u8 v_any_motion_thres_u8);
+/***************************************************************/
+/**\name FUNCTION FOR SLO/NO MOTION THRESHOLD CONFIGURATION */
+/***************************************************************/
+ /*!
+ * @brief This API is used to read threshold
+ * for the slow/no-motion interrupt
+ * from the register 0x61 bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_slow_no_motion_thres_u8 : The value of slow no motion threshold
+ * @note slow no motion threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | slow no motion threshold
+ * ----------------|---------------------
+ * 2g | v_slow_no_motion_thres_u8*3.91 mg
+ * 4g | v_slow_no_motion_thres_u8*7.81 mg
+ * 8g | v_slow_no_motion_thres_u8*15.63 mg
+ * 16g | v_slow_no_motion_thres_u8*31.25 mg
+ * @note when v_slow_no_motion_thres_u8 = 0
+ * accel_range | slow no motion threshold
+ * ----------------|---------------------
+ * 2g | 1.95 mg
+ * 4g | 3.91 mg
+ * 8g | 7.81 mg
+ * 16g | 15.63 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_slow_no_motion_thres(
+u8 *v_slow_no_motion_thres_u8);
+ /*!
+ * @brief This API is used to write threshold
+ * for the slow/no-motion interrupt
+ * from the register 0x61 bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_slow_no_motion_thres_u8 : The value of slow no motion threshold
+ * @note slow no motion threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | slow no motion threshold
+ * ----------------|---------------------
+ * 2g | v_slow_no_motion_thres_u8*3.91 mg
+ * 4g | v_slow_no_motion_thres_u8*7.81 mg
+ * 8g | v_slow_no_motion_thres_u8*15.63 mg
+ * 16g | v_slow_no_motion_thres_u8*31.25 mg
+ * @note when v_slow_no_motion_thres_u8 = 0
+ * accel_range | slow no motion threshold
+ * ----------------|---------------------
+ * 2g | 1.95 mg
+ * 4g | 3.91 mg
+ * 8g | 7.81 mg
+ * 16g | 15.63 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_slow_no_motion_thres(
+u8 v_slow_no_motion_thres_u8);
+/***************************************************************/
+/**\name FUNCTION FOR SLO/NO MOTION SELECT CONFIGURATION */
+/***************************************************************/
+ /*!
+ * @brief This API is used to read
+ * the slow/no-motion selection from the register 0x62 bit 0
+ *
+ *
+ *
+ *
+ * @param v_intr_slow_no_motion_select_u8 :
+ * The value of slow/no-motion select
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | SLOW_MOTION
+ * 0x01 | NO_MOTION
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_slow_no_motion_select(
+u8 *v_intr_slow_no_motion_select_u8);
+ /*!
+ * @brief This API is used to write
+ * the slow/no-motion selection from the register 0x62 bit 0
+ *
+ *
+ *
+ *
+ * @param v_intr_slow_no_motion_select_u8 :
+ * The value of slow/no-motion select
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | SLOW_MOTION
+ * 0x01 | NO_MOTION
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_slow_no_motion_select(
+u8 v_intr_slow_no_motion_select_u8);
+/***************************************************************/
+/**\name FUNCTION FOR SIGNIFICANT MOTION SELECT CONFIGURATION*/
+/***************************************************************/
+ /*!
+ * @brief This API is used to select
+ * the significant or any motion interrupt from the register 0x62 bit 1
+ *
+ *
+ *
+ *
+ * @param v_intr_significant_motion_select_u8 :
+ * the value of significant or any motion interrupt selection
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | ANY_MOTION
+ * 0x01 | SIGNIFICANT_MOTION
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_significant_motion_select(
+u8 *int_sig_mot_sel);
+ /*!
+ * @brief This API is used to write, select
+ * the significant or any motion interrupt from the register 0x62 bit 1
+ *
+ *
+ *
+ *
+ * @param v_intr_significant_motion_select_u8 :
+ * the value of significant or any motion interrupt selection
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | ANY_MOTION
+ * 0x01 | SIGNIFICANT_MOTION
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_significant_motion_select(
+u8 int_sig_mot_sel);
+ /*!
+ * @brief This API is used to read
+ * the significant skip time from the register 0x62 bit 2 and 3
+ *
+ *
+ *
+ *
+ * @param v_int_sig_mot_skip_u8 : the value of significant skip time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | skip time 1.5 seconds
+ * 0x01 | skip time 3 seconds
+ * 0x02 | skip time 6 seconds
+ * 0x03 | skip time 12 seconds
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_significant_motion_skip(
+u8 *v_int_sig_mot_skip_u8);
+ /*!
+ * @brief This API is used to write
+ * the significant skip time from the register 0x62 bit 2 and 3
+ *
+ *
+ *
+ *
+ * @param v_int_sig_mot_skip_u8 : the value of significant skip time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | skip time 1.5 seconds
+ * 0x01 | skip time 3 seconds
+ * 0x02 | skip time 6 seconds
+ * 0x03 | skip time 12 seconds
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_significant_motion_skip(
+u8 v_int_sig_mot_skip_u8);
+ /*!
+ * @brief This API is used to read
+ * the significant proof time from the register 0x62 bit 4 and 5
+ *
+ *
+ *
+ *
+ * @param v_significant_motion_proof_u8 :
+ * the value of significant proof time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | proof time 0.25 seconds
+ * 0x01 | proof time 0.5 seconds
+ * 0x02 | proof time 1 seconds
+ * 0x03 | proof time 2 seconds
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_significant_motion_proof(
+u8 *int_sig_mot_proof);
+ /*!
+ * @brief This API is used to write
+ * the significant proof time from the register 0x62 bit 4 and 5
+ *
+ *
+ *
+ *
+ * @param v_significant_motion_proof_u8 :
+ * the value of significant proof time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | proof time 0.25 seconds
+ * 0x01 | proof time 0.5 seconds
+ * 0x02 | proof time 1 seconds
+ * 0x03 | proof time 2 seconds
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_significant_motion_proof(
+u8 int_sig_mot_proof);
+/***************************************************************/
+/**\name FUNCTION FOR TAP DURATION CONFIGURATION*/
+/***************************************************************/
+/*!
+ * @brief This API is used to get the tap duration
+ * from the register 0x63 bit 0 to 2
+ *
+ *
+ *
+ * @param v_tap_durn_u8 : The value of tap duration
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | SMI130_TAP_DURN_50MS
+ * 0x01 | SMI130_TAP_DURN_100MS
+ * 0x03 | SMI130_TAP_DURN_150MS
+ * 0x04 | SMI130_TAP_DURN_200MS
+ * 0x05 | SMI130_TAP_DURN_250MS
+ * 0x06 | SMI130_TAP_DURN_375MS
+ * 0x07 | SMI130_TAP_DURN_700MS
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_tap_durn(
+u8 *v_tap_durn_u8);
+/*!
+ * @brief This API is used to write the tap duration
+ * from the register 0x63 bit 0 to 2
+ *
+ *
+ *
+ * @param v_tap_durn_u8 : The value of tap duration
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | SMI130_TAP_DURN_50MS
+ * 0x01 | SMI130_TAP_DURN_100MS
+ * 0x03 | SMI130_TAP_DURN_150MS
+ * 0x04 | SMI130_TAP_DURN_200MS
+ * 0x05 | SMI130_TAP_DURN_250MS
+ * 0x06 | SMI130_TAP_DURN_375MS
+ * 0x07 | SMI130_TAP_DURN_700MS
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_tap_durn(
+u8 v_tap_durn_u8);
+/***************************************************************/
+/**\name FUNCTION FOR TAP SHOCK CONFIGURATION*/
+/***************************************************************/
+ /*!
+ * @brief This API read the
+ * tap shock duration from the register 0x63 bit 2
+ *
+ * @param v_tap_shock_u8 :The value of tap shock
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | SMI130_TAP_SHOCK_50MS
+ * 0x01 | SMI130_TAP_SHOCK_75MS
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_tap_shock(
+u8 *v_tap_shock_u8);
+ /*!
+ * @brief This API write the
+ * tap shock duration from the register 0x63 bit 2
+ *
+ * @param v_tap_shock_u8 :The value of tap shock
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | SMI130_TAP_SHOCK_50MS
+ * 0x01 | SMI130_TAP_SHOCK_75MS
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_tap_shock(
+u8 v_tap_shock_u8);
+/***************************************************************/
+/**\name FUNCTION FOR TAP QUIET CONFIGURATION*/
+/***************************************************************/
+/*!
+ * @brief This API read
+ * tap quiet duration from the register 0x63 bit 7
+ *
+ *
+ * @param v_tap_quiet_u8 : The value of tap quiet
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | SMI130_TAP_QUIET_30MS
+ * 0x01 | SMI130_TAP_QUIET_20MS
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_tap_quiet(
+u8 *v_tap_quiet_u8);
+/*!
+ * @brief This API write
+ * tap quiet duration from the register 0x63 bit 7
+ *
+ *
+ * @param v_tap_quiet_u8 : The value of tap quiet
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | SMI130_TAP_QUIET_30MS
+ * 0x01 | SMI130_TAP_QUIET_20MS
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_tap_quiet(
+u8 v_tap_quiet_u8);
+/***************************************************************/
+/**\name FUNCTION FOR TAP THRESHOLD CONFIGURATION*/
+/***************************************************************/
+ /*!
+ * @brief This API read Threshold of the
+ * single/double tap interrupt from the register 0x64 bit 0 to 4
+ *
+ *
+ * @param v_tap_thres_u8 : The value of single/double tap threshold
+ *
+ * @note single/double tap threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | single/double tap threshold
+ * ----------------|---------------------
+ * 2g | ((v_tap_thres_u8 + 1) * 62.5)mg
+ * 4g | ((v_tap_thres_u8 + 1) * 125)mg
+ * 8g | ((v_tap_thres_u8 + 1) * 250)mg
+ * 16g | ((v_tap_thres_u8 + 1) * 500)mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_tap_thres(
+u8 *v_tap_thres_u8);
+ /*!
+ * @brief This API write Threshold of the
+ * single/double tap interrupt from the register 0x64 bit 0 to 4
+ *
+ *
+ * @param v_tap_thres_u8 : The value of single/double tap threshold
+ *
+ * @note single/double tap threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | single/double tap threshold
+ * ----------------|---------------------
+ * 2g | ((v_tap_thres_u8 + 1) * 62.5)mg
+ * 4g | ((v_tap_thres_u8 + 1) * 125)mg
+ * 8g | ((v_tap_thres_u8 + 1) * 250)mg
+ * 16g | ((v_tap_thres_u8 + 1) * 500)mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_tap_thres(
+u8 v_tap_thres_u8);
+/***************************************************************/
+/**\name FUNCTION FOR ORIENT MODE CONFIGURATION*/
+/***************************************************************/
+ /*!
+ * @brief This API read the threshold for orient_mblation interrupt
+ * from the register 0x65 bit 0 and 1
+ *
+ * @param v_orient_mbl_mode_u8 : The value of threshold for orient_mblation
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | symmetrical
+ * 0x01 | high-asymmetrical
+ * 0x02 | low-asymmetrical
+ * 0x03 | symmetrical
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_orient_mbl_mode(
+u8 *v_orient_mbl_mode_u8);
+ /*!
+ * @brief This API write the threshold for orient_mblation interrupt
+ * from the register 0x65 bit 0 and 1
+ *
+ * @param v_orient_mbl_mode_u8 : The value of threshold for orient_mblation
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | symmetrical
+ * 0x01 | high-asymmetrical
+ * 0x02 | low-asymmetrical
+ * 0x03 | symmetrical
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_orient_mbl_mode(
+u8 v_orient_mbl_mode_u8);
+/***************************************************************/
+/**\name FUNCTION FOR ORIENT BLOCKING CONFIGURATION*/
+/***************************************************************/
+/*!
+ * @brief This API read the orient_mbl blocking mode
+ * that is used for the generation of the orient_mblation interrupt.
+ * from the register 0x65 bit 2 and 3
+ *
+ * @param v_orient_mbl_blocking_u8 : The value of orient_mbl blocking mode
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | No blocking
+ * 0x01 | Theta blocking or acceleration in any axis > 1.5g
+ * 0x02 | Theta blocking or acceleration slope in any axis >
+ * - | 0.2g or acceleration in any axis > 1.5g
+ * 0x03 | Theta blocking or acceleration slope in any axis >
+ * - | 0.4g or acceleration in any axis >
+ * - | 1.5g and value of orient_mbl is not stable
+ * - | for at least 100 ms
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_orient_mbl_blocking(
+u8 *v_orient_mbl_blocking_u8);
+/*!
+ * @brief This API write the orient_mbl blocking mode
+ * that is used for the generation of the orient_mblation interrupt.
+ * from the register 0x65 bit 2 and 3
+ *
+ * @param v_orient_mbl_blocking_u8 : The value of orient_mbl blocking mode
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | No blocking
+ * 0x01 | Theta blocking or acceleration in any axis > 1.5g
+ * 0x02 | Theta blocking or acceleration slope in any axis >
+ * - | 0.2g or acceleration in any axis > 1.5g
+ * 0x03 | Theta blocking or acceleration slope in any axis >
+ * - | 0.4g or acceleration in any axis >
+ * - | 1.5g and value of orient_mbl is not stable
+ * - | for at least 100 ms
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_orient_mbl_blocking(
+u8 v_orient_mbl_blocking_u8);
+/***************************************************************/
+/**\name FUNCTION FOR ORIENT HYSTERESIS CONFIGURATION*/
+/***************************************************************/
+/*!
+ * @brief This API read Orient interrupt
+ * hysteresis, from the register 0x64 bit 4 to 7
+ *
+ *
+ *
+ * @param v_orient_mbl_hyst_u8 : The value of orient_mbl hysteresis
+ *
+ * @note 1 LSB corresponds to 62.5 mg,
+ * irrespective of the selected accel range
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_orient_mbl_hyst(
+u8 *v_orient_mbl_hyst_u8);
+/*!
+ * @brief This API write Orient interrupt
+ * hysteresis, from the register 0x64 bit 4 to 7
+ *
+ *
+ *
+ * @param v_orient_mbl_hyst_u8 : The value of orient_mbl hysteresis
+ *
+ * @note 1 LSB corresponds to 62.5 mg,
+ * irrespective of the selected accel range
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_orient_mbl_hyst(
+u8 v_orient_mbl_hyst_u8);
+/***************************************************************/
+/**\name FUNCTION FOR ORIENT THETA CONFIGURATION*/
+/***************************************************************/
+ /*!
+ * @brief This API read Orient
+ * blocking angle (0 to 44.8) from the register 0x66 bit 0 to 5
+ *
+ * @param v_orient_mbl_theta_u8 : The value of Orient blocking angle
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_orient_mbl_theta(
+u8 *v_orient_mbl_theta_u8);
+ /*!
+ * @brief This API write Orient
+ * blocking angle (0 to 44.8) from the register 0x66 bit 0 to 5
+ *
+ * @param v_orient_mbl_theta_u8 : The value of Orient blocking angle
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_orient_mbl_theta(
+u8 v_orient_mbl_theta_u8);
+/***************************************************************/
+/**\name FUNCTION FOR ORIENT OUTPUT ENABLE CONFIGURATION*/
+/***************************************************************/
+/*!
+ * @brief This API read orient_mbl change
+ * of up/down bit from the register 0x66 bit 6
+ *
+ * @param v_orient_mbl_ud_u8 : The value of orient_mbl change of up/down
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | Is ignored
+ * 0x01 | Generates orient_mblation interrupt
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_orient_mbl_ud_enable(
+u8 *v_orient_mbl_ud_u8);
+/*!
+ * @brief This API write orient_mbl change
+ * of up/down bit from the register 0x66 bit 6
+ *
+ * @param v_orient_mbl_ud_u8 : The value of orient_mbl change of up/down
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | Is ignored
+ * 0x01 | Generates orient_mblation interrupt
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_orient_mbl_ud_enable(
+u8 v_orient_mbl_ud_u8);
+/***************************************************************/
+/**\name FUNCTION FOR ORIENT AXIS ENABLE CONFIGURATION*/
+/***************************************************************/
+ /*!
+ * @brief This API read orient_mblation axes changes
+ * from the register 0x66 bit 7
+ *
+ * @param v_orient_mbl_axes_u8 : The value of orient_mbl axes assignment
+ * value | Behaviour | Name
+ * ----------|--------------------|------
+ * 0x00 | x = x, y = y, z = z|orient_mbl_ax_noex
+ * 0x01 | x = y, y = z, z = x|orient_mbl_ax_ex
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_orient_mbl_axes_enable(
+u8 *v_orient_mbl_axes_u8);
+ /*!
+ * @brief This API write orient_mblation axes changes
+ * from the register 0x66 bit 7
+ *
+ * @param v_orient_mbl_axes_u8 : The value of orient_mbl axes assignment
+ * value | Behaviour | Name
+ * ----------|--------------------|------
+ * 0x00 | x = x, y = y, z = z|orient_mbl_ax_noex
+ * 0x01 | x = y, y = z, z = x|orient_mbl_ax_ex
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_orient_mbl_axes_enable(
+u8 v_orient_mbl_axes_u8);
+/***************************************************************/
+/**\name FUNCTION FOR FLAT THETA CONFIGURATION*/
+/***************************************************************/
+ /*!
+ * @brief This API read Flat angle (0 to 44.8) for flat interrupt
+ * from the register 0x67 bit 0 to 5
+ *
+ * @param v_flat_theta_u8 : The value of flat angle
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_flat_theta(
+u8 *v_flat_theta_u8);
+ /*!
+ * @brief This API write Flat angle (0 to 44.8) for flat interrupt
+ * from the register 0x67 bit 0 to 5
+ *
+ * @param v_flat_theta_u8 : The value of flat angle
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_flat_theta(
+u8 v_flat_theta_u8);
+/***************************************************************/
+/**\name FUNCTION FOR FLAT HOLD CONFIGURATION*/
+/***************************************************************/
+/*!
+ * @brief This API read Flat interrupt hold time;
+ * from the register 0x68 bit 4 and 5
+ *
+ * @param v_flat_hold_u8 : The value of flat hold time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | 0ms
+ * 0x01 | 512ms
+ * 0x01 | 1024ms
+ * 0x01 | 2048ms
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_flat_hold(
+u8 *v_flat_hold_u8);
+/*!
+ * @brief This API write Flat interrupt hold time;
+ * from the register 0x68 bit 4 and 5
+ *
+ * @param v_flat_hold_u8 : The value of flat hold time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | 0ms
+ * 0x01 | 512ms
+ * 0x01 | 1024ms
+ * 0x01 | 2048ms
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_flat_hold(
+u8 v_flat_hold_u8);
+/***************************************************************/
+/**\name FUNCTION FOR FLAT HYSTERESIS CONFIGURATION*/
+/***************************************************************/
+/*!
+ * @brief This API read flat interrupt hysteresis
+ * from the register 0x68 bit 0 to 3
+ *
+ * @param v_flat_hyst_u8 : The value of flat hysteresis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_flat_hyst(
+u8 *v_flat_hyst_u8);
+/*!
+ * @brief This API write flat interrupt hysteresis
+ * from the register 0x68 bit 0 to 3
+ *
+ * @param v_flat_hyst_u8 : The value of flat hysteresis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_flat_hyst(
+u8 v_flat_hyst_u8);
+/***************************************************************/
+/**\name FUNCTION FAST OFFSET COMPENSATION FOR ACCEL */
+/***************************************************************/
+ /*!
+ * @brief This API read accel offset compensation
+ * target value for z-axis from the register 0x69 bit 0 and 1
+ *
+ * @param v_foc_accel_z_u8 : the value of accel offset compensation z axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_foc_accel_z(
+u8 *v_foc_accel_z_u8);
+ /*!
+ * @brief This API write accel offset compensation
+ * target value for z-axis from the register 0x69 bit 0 and 1
+ *
+ * @param v_foc_accel_z_u8 : the value of accel offset compensation z axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_foc_accel_z(
+u8 v_foc_accel_z_u8);
+/*!
+ * @brief This API read accel offset compensation
+ * target value for y-axis
+ * from the register 0x69 bit 2 and 3
+ *
+ * @param v_foc_accel_y_u8 : the value of accel offset compensation y axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_foc_accel_y(
+u8 *v_foc_accel_y_u8);
+/*!
+ * @brief This API write accel offset compensation
+ * target value for y-axis
+ * from the register 0x69 bit 2 and 3
+ *
+ * @param v_foc_accel_y_u8 : the value of accel offset compensation y axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_foc_accel_y(
+u8 v_foc_accel_y_u8);
+/*!
+ * @brief This API read accel offset compensation
+ * target value for x-axis is
+ * from the register 0x69 bit 4 and 5
+ *
+ * @param v_foc_accel_x_u8 : the value of accel offset compensation x axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_foc_accel_x(
+u8 *v_foc_accel_x_u8);
+/*!
+ * @brief This API write accel offset compensation
+ * target value for x-axis is
+ * from the register 0x69 bit 4 and 5
+ *
+ * @param v_foc_accel_x_u8 : the value of accel offset compensation x axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_foc_accel_x(
+u8 v_foc_accel_x_u8);
+/***************************************************************/
+/**\name FUNCTION FAST OFFSET COMPENSATION FOR GYRO */
+/***************************************************************/
+/*!
+ * @brief This API write gyro fast offset enable
+ * from the register 0x69 bit 6
+ *
+ * @param v_foc_gyro_u8 : The value of gyro fast offset enable
+ * value | Description
+ * ----------|-------------
+ * 0 | fast offset compensation disabled
+ * 1 | fast offset compensation enabled
+ *
+ * @param v_gyro_off_x_s16 : The value of gyro fast offset x axis data
+ * @param v_gyro_off_y_s16 : The value of gyro fast offset y axis data
+ * @param v_gyro_off_z_s16 : The value of gyro fast offset z axis data
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_foc_gyro_enable(
+u8 v_foc_gyro_u8, s16 *v_gyro_off_x_s16,
+s16 *v_gyro_off_y_s16, s16 *v_gyro_off_z_s16);
+/***************************************************/
+/**\name FUNCTION FOR NVM*/
+/***************************************************/
+ /*!
+ * @brief This API read NVM program enable
+ * from the register 0x6A bit 1
+ *
+ * @param v_nvm_prog_u8 : The value of NVM program enable
+ * Value | Description
+ * --------|-------------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_nvm_prog_enable(
+u8 *v_nvm_prog_u8);
+ /*!
+ * @brief This API write NVM program enable
+ * from the register 0x6A bit 1
+ *
+ * @param v_nvm_prog_u8 : The value of NVM program enable
+ * Value | Description
+ * --------|-------------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_nvm_prog_enable(
+u8 v_nvm_prog_u8);
+/***************************************************/
+/**\name FUNCTION FOR SPI MODE*/
+/***************************************************/
+/*!
+ * @brief This API read to configure SPI
+ * Interface Mode for primary and OIS interface
+ * from the register 0x6B bit 0
+ *
+ * @param v_spi3_u8 : The value of SPI mode selection
+ * Value | Description
+ * --------|-------------
+ * 0 | SPI 4-wire mode
+ * 1 | SPI 3-wire mode
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_get_spi3(
+u8 *v_spi3_u8);
+/*!
+ * @brief This API write to configure SPI
+ * Interface Mode for primary and OIS interface
+ * from the register 0x6B bit 0
+ *
+ * @param v_spi3_u8 : The value of SPI mode selection
+ * Value | Description
+ * --------|-------------
+ * 0 | SPI 4-wire mode
+ * 1 | SPI 3-wire mode
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_spi3(
+u8 v_spi3_u8);
+/***************************************************/
+/**\name FUNCTION FOR FOC GYRO */
+/***************************************************/
+/*!
+ * @brief This API read gyro fast offset enable
+ * from the register 0x69 bit 6
+ *
+ * @param v_foc_gyro_u8 : The value of gyro fast offset enable
+ * value | Description
+ * ----------|-------------
+ * 0 | fast offset compensation disabled
+ * 1 | fast offset compensation enabled
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_foc_gyro_enable(
+u8 *v_foc_gyro_u8);
+/***************************************************/
+/**\name FUNCTION FOR I2C WATCHDOG TIMBER */
+/***************************************************/
+/*!
+ * @brief This API read I2C Watchdog timer
+ * from the register 0x70 bit 1
+ *
+ * @param v_i2c_wdt_u8 : The value of I2C watch dog timer
+ * Value | Description
+ * --------|-------------
+ * 0 | I2C watchdog v_timeout_u8 after 1 ms
+ * 1 | I2C watchdog v_timeout_u8 after 50 ms
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_i2c_wdt_select(
+u8 *v_i2c_wdt_u8);
+/*!
+ * @brief This API write I2C Watchdog timer
+ * from the register 0x70 bit 1
+ *
+ * @param v_i2c_wdt_u8 : The value of I2C watch dog timer
+ * Value | Description
+ * --------|-------------
+ * 0 | I2C watchdog v_timeout_u8 after 1 ms
+ * 1 | I2C watchdog v_timeout_u8 after 50 ms
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE
+smi130_set_i2c_wdt_select(u8 v_i2c_wdt_u8);
+/*!
+ * @brief This API read I2C watchdog enable
+ * from the register 0x70 bit 2
+ *
+ * @param v_i2c_wdt_u8 : The value of I2C watchdog enable
+ * Value | Description
+ * --------|-------------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_i2c_wdt_enable(
+u8 *v_i2c_wdt_u8);
+/*!
+ * @brief This API write I2C watchdog enable
+ * from the register 0x70 bit 2
+ *
+ * @param v_i2c_wdt_u8 : The value of I2C watchdog enable
+ * Value | Description
+ * --------|-------------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_i2c_wdt_enable(
+u8 v_i2c_wdt_u8);
+/***************************************************/
+/**\name FUNCTION FOR IF MODE*/
+/***************************************************/
+/*!
+ * @brief This API read I2C interface configuration(if) moe
+ * from the register 0x6B bit 4 and 5
+ *
+ * @param v_if_mode_u8 : The value of interface configuration mode
+ * Value | Description
+ * --------|-------------
+ * 0x00 | Primary interface:autoconfig / secondary interface:off
+ * 0x01 | Primary interface:I2C / secondary interface:OIS
+ * 0x02 | Primary interface:autoconfig/secondary interface:Magnetometer
+ * 0x03 | Reserved
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_if_mode(
+u8 *v_if_mode_u8);
+/*!
+ * @brief This API write I2C interface configuration(if) moe
+ * from the register 0x6B bit 4 and 5
+ *
+ * @param v_if_mode_u8 : The value of interface configuration mode
+ * Value | Description
+ * --------|-------------
+ * 0x00 | Primary interface:autoconfig / secondary interface:off
+ * 0x01 | Primary interface:I2C / secondary interface:OIS
+ * 0x02 | Primary interface:autoconfig/secondary interface:Magnetometer
+ * 0x03 | Reserved
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_if_mode(
+u8 v_if_mode_u8);
+/***************************************************/
+/**\name FUNCTION FOR GYRO SLEEP TRIGGER INTERRUPT CONFIGURATION*/
+/***************************************************/
+/*!
+ * @brief This API read gyro sleep trigger
+ * from the register 0x6C bit 0 to 2
+ *
+ * @param v_gyro_sleep_trigger_u8 : The value of gyro sleep trigger
+ * Value | Description
+ * --------|-------------
+ * 0x00 | nomotion: no / Not INT1 pin: no / INT2 pin: no
+ * 0x01 | nomotion: no / Not INT1 pin: no / INT2 pin: yes
+ * 0x02 | nomotion: no / Not INT1 pin: yes / INT2 pin: no
+ * 0x03 | nomotion: no / Not INT1 pin: yes / INT2 pin: yes
+ * 0x04 | nomotion: yes / Not INT1 pin: no / INT2 pin: no
+ * 0x05 | anymotion: yes / Not INT1 pin: no / INT2 pin: yes
+ * 0x06 | anymotion: yes / Not INT1 pin: yes / INT2 pin: no
+ * 0x07 | anymotion: yes / Not INT1 pin: yes / INT2 pin: yes
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_sleep_trigger(
+u8 *v_gyro_sleep_trigger_u8);
+/*!
+ * @brief This API write gyro sleep trigger
+ * from the register 0x6C bit 0 to 2
+ *
+ * @param v_gyro_sleep_trigger_u8 : The value of gyro sleep trigger
+ * Value | Description
+ * --------|-------------
+ * 0x00 | nomotion: no / Not INT1 pin: no / INT2 pin: no
+ * 0x01 | nomotion: no / Not INT1 pin: no / INT2 pin: yes
+ * 0x02 | nomotion: no / Not INT1 pin: yes / INT2 pin: no
+ * 0x03 | nomotion: no / Not INT1 pin: yes / INT2 pin: yes
+ * 0x04 | nomotion: yes / Not INT1 pin: no / INT2 pin: no
+ * 0x05 | anymotion: yes / Not INT1 pin: no / INT2 pin: yes
+ * 0x06 | anymotion: yes / Not INT1 pin: yes / INT2 pin: no
+ * 0x07 | anymotion: yes / Not INT1 pin: yes / INT2 pin: yes
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_sleep_trigger(
+u8 v_gyro_sleep_trigger_u8);
+/*!
+ * @brief This API read gyro wakeup trigger
+ * from the register 0x6C bit 3 and 4
+ *
+ * @param v_gyro_wakeup_trigger_u8 : The value of gyro wakeup trigger
+ * Value | Description
+ * --------|-------------
+ * 0x00 | anymotion: no / INT1 pin: no
+ * 0x01 | anymotion: no / INT1 pin: yes
+ * 0x02 | anymotion: yes / INT1 pin: no
+ * 0x03 | anymotion: yes / INT1 pin: yes
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_wakeup_trigger(
+u8 *v_gyro_wakeup_trigger_u8);
+/*!
+ * @brief This API write gyro wakeup trigger
+ * from the register 0x6C bit 3 and 4
+ *
+ * @param v_gyro_wakeup_trigger_u8 : The value of gyro wakeup trigger
+ * Value | Description
+ * --------|-------------
+ * 0x00 | anymotion: no / INT1 pin: no
+ * 0x01 | anymotion: no / INT1 pin: yes
+ * 0x02 | anymotion: yes / INT1 pin: no
+ * 0x03 | anymotion: yes / INT1 pin: yes
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_wakeup_trigger(
+u8 v_gyro_wakeup_trigger_u8);
+/*!
+ * @brief This API read Target state for gyro sleep mode
+ * from the register 0x6C bit 5
+ *
+ * @param v_gyro_sleep_state_u8 : The value of gyro sleep mode
+ * Value | Description
+ * --------|-------------
+ * 0x00 | Sleep transition to fast wake up state
+ * 0x01 | Sleep transition to suspend state
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_sleep_state(
+u8 *v_gyro_sleep_state_u8);
+/*!
+ * @brief This API write Target state for gyro sleep mode
+ * from the register 0x6C bit 5
+ *
+ * @param v_gyro_sleep_state_u8 : The value of gyro sleep mode
+ * Value | Description
+ * --------|-------------
+ * 0x00 | Sleep transition to fast wake up state
+ * 0x01 | Sleep transition to suspend state
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_sleep_state(
+u8 v_gyro_sleep_state_u8);
+/*!
+ * @brief This API read gyro wakeup interrupt
+ * from the register 0x6C bit 6
+ *
+ * @param v_gyro_wakeup_intr_u8 : The valeu of gyro wakeup interrupt
+ * Value | Description
+ * --------|-------------
+ * 0x00 | DISABLE
+ * 0x01 | ENABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_wakeup_intr(
+u8 *v_gyro_wakeup_intr_u8);
+/*!
+ * @brief This API write gyro wakeup interrupt
+ * from the register 0x6C bit 6
+ *
+ * @param v_gyro_wakeup_intr_u8 : The valeu of gyro wakeup interrupt
+ * Value | Description
+ * --------|-------------
+ * 0x00 | DISABLE
+ * 0x01 | ENABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_wakeup_intr(
+u8 v_gyro_wakeup_intr_u8);
+/***************************************************/
+/**\name FUNCTION FOR ACCEL SELF TEST */
+/***************************************************/
+/*!
+ * @brief This API read accel select axis to be self-test
+ *
+ * @param v_accel_selftest_axis_u8 :
+ * The value of accel self test axis selection
+ * Value | Description
+ * --------|-------------
+ * 0x00 | disabled
+ * 0x01 | x-axis
+ * 0x02 | y-axis
+ * 0x03 | z-axis
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_selftest_axis(
+u8 *acc_selftest_axis);
+/*!
+ * @brief This API write accel select axis to be self-test
+ *
+ * @param v_accel_selftest_axis_u8 :
+ * The value of accel self test axis selection
+ * Value | Description
+ * --------|-------------
+ * 0x00 | disabled
+ * 0x01 | x-axis
+ * 0x02 | y-axis
+ * 0x03 | z-axis
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_selftest_axis(
+u8 acc_selftest_axis);
+/*!
+ * @brief This API read accel self test axis sign
+ * from the register 0x6D bit 2
+ *
+ * @param v_accel_selftest_sign_u8: The value of accel self test axis sign
+ * Value | Description
+ * --------|-------------
+ * 0x00 | negative
+ * 0x01 | positive
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_selftest_sign(
+u8 *acc_selftest_sign);
+/*!
+ * @brief This API write accel self test axis sign
+ * from the register 0x6D bit 2
+ *
+ * @param v_accel_selftest_sign_u8: The value of accel self test axis sign
+ * Value | Description
+ * --------|-------------
+ * 0x00 | negative
+ * 0x01 | positive
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_selftest_sign(
+u8 acc_selftest_sign);
+/*!
+ * @brief This API read accel self test amplitude
+ * from the register 0x6D bit 3
+ * select amplitude of the selftest deflection:
+ *
+ * @param v_accel_selftest_amp_u8 : The value of accel self test amplitude
+ * Value | Description
+ * --------|-------------
+ * 0x00 | LOW
+ * 0x01 | HIGH
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_selftest_amp(
+u8 *acc_selftest_amp);
+/*!
+ * @brief This API write accel self test amplitude
+ * from the register 0x6D bit 3
+ * select amplitude of the selftest deflection:
+ *
+ * @param v_accel_selftest_amp_u8 : The value of accel self test amplitude
+ * Value | Description
+ * --------|-------------
+ * 0x00 | LOW
+ * 0x01 | HIGH
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_selftest_amp(
+u8 acc_selftest_amp);
+/***************************************************/
+/**\name FUNCTION FOR GYRO SELF TEST */
+/***************************************************/
+/*!
+ * @brief This API read gyro self test trigger
+ *
+ * @param v_gyro_selftest_start_u8: The value of gyro self test start
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_selftest_start(
+u8 *v_gyro_selftest_start_u8);
+/*!
+ * @brief This API write gyro self test trigger
+ *
+ * @param v_gyro_selftest_start_u8: The value of gyro self test start
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_selftest_start(
+u8 v_gyro_selftest_start_u8);
+/***************************************************/
+/**\name FUNCTION FOR SPI/I2C ENABLE */
+/***************************************************/
+ /*!
+ * @brief This API read primary interface selection I2C or SPI
+ * from the register 0x70 bit 0
+ *
+ * @param v_spi_enable_u8: The value of Interface selection
+ * Value | Description
+ * --------|-------------
+ * 0x00 | I2C Enable
+ * 0x01 | I2C DISBALE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_spi_enable(
+u8 *v_spi_enable_u8);
+ /*!
+ * @brief This API write primary interface selection I2C or SPI
+ * from the register 0x70 bit 0
+ *
+ * @param v_spi_enable_u8: The value of Interface selection
+ * Value | Description
+ * --------|-------------
+ * 0x00 | I2C Enable
+ * 0x01 | I2C DISBALE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_spi_enable(
+u8 v_spi_enable_u8);
+ /*!
+ * @brief This API read the spare zero
+ * form register 0x70 bit 3
+ *
+ *
+ * @param v_spare0_trim_u8: The value of spare zero
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_spare0_trim
+(u8 *v_spare0_trim_u8);
+ /*!
+ * @brief This API write the spare zero
+ * form register 0x70 bit 3
+ *
+ *
+ * @param v_spare0_trim_u8: The value of spare zero
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_spare0_trim
+(u8 v_spare0_trim_u8);
+/***************************************************/
+/**\name FUNCTION FOR NVM COUNTER */
+/***************************************************/
+ /*!
+ * @brief This API read the NVM counter
+ * form register 0x70 bit 4 to 7
+ *
+ *
+ * @param v_nvm_counter_u8: The value of NVM counter
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_nvm_counter(
+u8 *v_nvm_counter_u8);
+ /*!
+ * @brief This API write the NVM counter
+ * form register 0x70 bit 4 to 7
+ *
+ *
+ * @param v_nvm_counter_u8: The value of NVM counter
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_nvm_counter(
+u8 v_nvm_counter_u8);
+/***************************************************/
+/**\name FUNCTION FOR ACCEL MANUAL OFFSET COMPENSATION */
+/***************************************************/
+/*!
+ * @brief This API read accel manual offset compensation of x axis
+ * from the register 0x71 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_x_s8:
+ * The value of accel manual offset compensation of x axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_offset_compensation_xaxis(
+s8 *v_accel_off_x_s8);
+/*!
+ * @brief This API write accel manual offset compensation of x axis
+ * from the register 0x71 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_x_s8:
+ * The value of accel manual offset compensation of x axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_offset_compensation_xaxis(
+s8 v_accel_off_x_s8);
+/*!
+ * @brief This API read accel manual offset compensation of y axis
+ * from the register 0x72 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_y_s8:
+ * The value of accel manual offset compensation of y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_offset_compensation_yaxis(
+s8 *v_accel_off_y_s8);
+/*!
+ * @brief This API write accel manual offset compensation of y axis
+ * from the register 0x72 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_y_s8:
+ * The value of accel manual offset compensation of y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_offset_compensation_yaxis(
+s8 v_accel_off_y_s8);
+/*!
+ * @brief This API read accel manual offset compensation of z axis
+ * from the register 0x73 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_z_s8:
+ * The value of accel manual offset compensation of z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_offset_compensation_zaxis(
+s8 *v_accel_off_z_s8);
+/*!
+ * @brief This API write accel manual offset compensation of z axis
+ * from the register 0x73 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_z_s8:
+ * The value of accel manual offset compensation of z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_offset_compensation_zaxis(
+s8 v_accel_off_z_s8);
+/***************************************************/
+/**\name FUNCTION FOR GYRO MANUAL OFFSET COMPENSATION */
+/***************************************************/
+/*!
+ * @brief This API read gyro manual offset compensation of x axis
+ * from the register 0x74 bit 0 to 7 and 0x77 bit 0 and 1
+ *
+ *
+ *
+ * @param v_gyro_off_x_s16:
+ * The value of gyro manual offset compensation of x axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_offset_compensation_xaxis(
+s16 *v_gyro_off_x_s16);
+/*!
+ * @brief This API write gyro manual offset compensation of x axis
+ * from the register 0x74 bit 0 to 7 and 0x77 bit 0 and 1
+ *
+ *
+ *
+ * @param v_gyro_off_x_s16:
+ * The value of gyro manual offset compensation of x axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_offset_compensation_xaxis(
+s16 v_gyro_off_x_s16);
+/*!
+ * @brief This API read gyro manual offset compensation of y axis
+ * from the register 0x75 bit 0 to 7 and 0x77 bit 2 and 3
+ *
+ *
+ *
+ * @param v_gyro_off_y_s16:
+ * The value of gyro manual offset compensation of y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_offset_compensation_yaxis(
+s16 *v_gyro_off_y_s16);
+/*!
+ * @brief This API write gyro manual offset compensation of y axis
+ * from the register 0x75 bit 0 to 7 and 0x77 bit 2 and 3
+ *
+ *
+ *
+ * @param v_gyro_off_y_s16:
+ * The value of gyro manual offset compensation of y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_offset_compensation_yaxis(
+s16 v_gyro_off_y_s16);
+/*!
+ * @brief This API read gyro manual offset compensation of z axis
+ * from the register 0x76 bit 0 to 7 and 0x77 bit 4 and 5
+ *
+ *
+ *
+ * @param v_gyro_off_z_s16:
+ * The value of gyro manual offset compensation of z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_offset_compensation_zaxis(
+s16 *v_gyro_off_z_s16);
+/*!
+ * @brief This API write gyro manual offset compensation of z axis
+ * from the register 0x76 bit 0 to 7 and 0x77 bit 4 and 5
+ *
+ *
+ *
+ * @param v_gyro_off_z_s16:
+ * The value of gyro manual offset compensation of z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_offset_compensation_zaxis(
+s16 v_gyro_off_z_s16);
+/*!
+ * @brief This API writes accel fast offset compensation
+ * from the register 0x69 bit 0 to 5
+ * @brief This API writes each axis individually
+ * FOC_X_AXIS - bit 4 and 5
+ * FOC_Y_AXIS - bit 2 and 3
+ * FOC_Z_AXIS - bit 0 and 1
+ *
+ * @param v_foc_accel_u8: The value of accel offset compensation
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @param v_axis_u8: The value of accel offset axis selection
+ * value | axis
+ * ----------|-------------------
+ * 0 | FOC_X_AXIS
+ * 1 | FOC_Y_AXIS
+ * 2 | FOC_Z_AXIS
+ *
+ * @param v_accel_offset_s8: The accel offset value
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_foc_trigger(u8 axis,
+u8 foc_acc, s8 *accel_offset);
+/*!
+ * @brief This API write fast accel offset compensation
+ * it writes all axis together.To the register 0x69 bit 0 to 5
+ * FOC_X_AXIS - bit 4 and 5
+ * FOC_Y_AXIS - bit 2 and 3
+ * FOC_Z_AXIS - bit 0 and 1
+ *
+ * @param v_foc_accel_x_u8: The value of accel offset x compensation
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @param v_foc_accel_y_u8: The value of accel offset y compensation
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @param v_foc_accel_z_u8: The value of accel offset z compensation
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @param v_accel_off_x_s8: The value of accel offset x axis
+ * @param v_accel_off_y_s8: The value of accel offset y axis
+ * @param v_accel_off_z_s8: The value of accel offset z axis
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_accel_foc_trigger_xyz(u8 v_foc_accel_x_u8,
+u8 v_foc_accel_y_u8, u8 v_foc_accel_z_u8,
+s8 *acc_off_x, s8 *acc_off_y, s8 *acc_off_z);
+/***************************************************/
+/**\name FUNCTION FOR ACEL AND GYRO OFFSET ENABLE */
+/***************************************************/
+/*!
+ * @brief This API read the accel offset enable bit
+ * from the register 0x77 bit 6
+ *
+ *
+ *
+ * @param v_accel_off_enable_u8: The value of accel offset enable
+ * value | Description
+ * ----------|--------------
+ * 0x01 | ENABLE
+ * 0x00 | DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_offset_enable(
+u8 *acc_off_en);
+/*!
+ * @brief This API write the accel offset enable bit
+ * from the register 0x77 bit 6
+ *
+ *
+ *
+ * @param v_accel_off_enable_u8: The value of accel offset enable
+ * value | Description
+ * ----------|--------------
+ * 0x01 | ENABLE
+ * 0x00 | DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_offset_enable(
+u8 acc_off_en);
+/*!
+ * @brief This API read the accel offset enable bit
+ * from the register 0x77 bit 7
+ *
+ *
+ *
+ * @param v_gyro_off_enable_u8: The value of gyro offset enable
+ * value | Description
+ * ----------|--------------
+ * 0x01 | ENABLE
+ * 0x00 | DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_offset_enable(
+u8 *v_gyro_off_enable_u8);
+/*!
+ * @brief This API write the accel offset enable bit
+ * from the register 0x77 bit 7
+ *
+ *
+ *
+ * @param v_gyro_off_enable_u8: The value of gyro offset enable
+ * value | Description
+ * ----------|--------------
+ * 0x01 | ENABLE
+ * 0x00 | DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_offset_enable(
+u8 v_gyro_off_enable_u8);
+/***************************************************/
+/**\name FUNCTION FOR STEP COUNTER INTERRUPT */
+/***************************************************/
+/*!
+ * @brief This API reads step counter value
+ * form the register 0x78 and 0x79
+ *
+ *
+ *
+ *
+ * @param v_step_cnt_s16 : The value of step counter
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_read_step_count(u16 *v_step_cnt_s16);
+ /*!
+ * @brief This API Reads
+ * step counter configuration
+ * from the register 0x7A bit 0 to 7
+ * and from the register 0x7B bit 0 to 2 and 4 to 7
+ *
+ *
+ * @param v_step_config_u16 : The value of step configuration
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_step_config(
+u16 *v_step_config_u16);
+ /*!
+ * @brief This API write
+ * step counter configuration
+ * from the register 0x7A bit 0 to 7
+ * and from the register 0x7B bit 0 to 2 and 4 to 7
+ *
+ *
+ * @param v_step_config_u16 :
+ * the value of Enable step configuration
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_step_config(
+u16 v_step_config_u16);
+ /*!
+ * @brief This API read enable step counter
+ * from the register 0x7B bit 3
+ *
+ *
+ * @param v_step_counter_u8 : The value of step counter enable
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_step_counter_enable(
+u8 *v_step_counter_u8);
+ /*!
+ * @brief This API write enable step counter
+ * from the register 0x7B bit 3
+ *
+ *
+ * @param v_step_counter_u8 : The value of step counter enable
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_step_counter_enable(
+u8 v_step_counter_u8);
+ /*!
+ * @brief This API set Step counter modes
+ *
+ *
+ * @param v_step_mode_u8 : The value of step counter mode
+ * value | mode
+ * ----------|-----------
+ * 0 | SMI130_STEP_NORMAL_MODE
+ * 1 | SMI130_STEP_SENSITIVE_MODE
+ * 2 | SMI130_STEP_ROBUST_MODE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_step_mode(u8 v_step_mode_u8);
+/*!
+ * @brief This API used to trigger the signification motion
+ * interrupt
+ *
+ *
+ * @param v_significant_u8 : The value of interrupt selection
+ * value | interrupt
+ * ----------|-----------
+ * 0 | SMI130_MAP_INTR1
+ * 1 | SMI130_MAP_INTR2
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_map_significant_motion_intr(
+u8 v_significant_u8);
+/*!
+ * @brief This API used to trigger the step detector
+ * interrupt
+ *
+ *
+ * @param v_step_detector_u8 : The value of interrupt selection
+ * value | interrupt
+ * ----------|-----------
+ * 0 | SMI130_MAP_INTR1
+ * 1 | SMI130_MAP_INTR2
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_map_step_detector_intr(
+u8 v_step_detector_u8);
+ /*!
+ * @brief This API used to clear the step counter interrupt
+ * interrupt
+ *
+ *
+ * @param : None
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_clear_step_counter(void);
+/***************************************************/
+/**\name FUNCTION FOR STEP COMMAND REGISTER WRITE */
+/***************************************************/
+ /*!
+ * @brief This API writes value to the register 0x7E bit 0 to 7
+ *
+ *
+ * @param v_command_reg_u8 : The value to write command register
+ * value | Description
+ * ---------|--------------------------------------------------------
+ * 0x00 | Reserved
+ * 0x03 | Starts fast offset calibration for the accel and gyro
+ * 0x10 | Sets the PMU mode for the Accelerometer to suspend
+ * 0x11 | Sets the PMU mode for the Accelerometer to normal
+ * 0x12 | Sets the PMU mode for the Accelerometer Lowpower
+ * 0x14 | Sets the PMU mode for the Gyroscope to suspend
+ * 0x15 | Sets the PMU mode for the Gyroscope to normal
+ * 0x16 | Reserved
+ * 0x17 | Sets the PMU mode for the Gyroscope to fast start-up
+ * 0x18 | Sets the PMU mode for the Magnetometer to suspend
+ * 0x19 | Sets the PMU mode for the Magnetometer to normal
+ * 0x1A | Sets the PMU mode for the Magnetometer to Lowpower
+ * 0xB0 | Clears all data in the FIFO
+ * 0xB1 | Resets the interrupt engine
+ * 0xB2 | step_cnt_clr Clears the step counter
+ * 0xB6 | Triggers a reset
+ * 0x37 | See extmode_en_last
+ * 0x9A | See extmode_en_last
+ * 0xC0 | Enable the extended mode
+ * 0xC4 | Erase NVM cell
+ * 0xC8 | Load NVM cell
+ * 0xF0 | Reset acceleration data path
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_command_register(
+u8 v_command_reg_u8);
+/***************************************************/
+/**\name FUNCTION FOR PAGE ENABLE */
+/***************************************************/
+ /*!
+ * @brief This API read target page from the register 0x7F bit 4 and 5
+ *
+ * @param v_target_page_u8: The value of target page
+ * value | page
+ * ---------|-----------
+ * 0 | User data/configure page
+ * 1 | Chip level trim/test page
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_target_page(
+u8 *v_target_page_u8);
+ /*!
+ * @brief This API write target page from the register 0x7F bit 4 and 5
+ *
+ * @param v_target_page_u8: The value of target page
+ * value | page
+ * ---------|-----------
+ * 0 | User data/configure page
+ * 1 | Chip level trim/test page
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_target_page(
+u8 v_target_page_u8);
+ /*!
+ * @brief This API read page enable from the register 0x7F bit 7
+ *
+ *
+ *
+ * @param v_page_enable_u8: The value of page enable
+ * value | page
+ * ---------|-----------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_paging_enable(
+u8 *v_page_enable_u8);
+ /*!
+ * @brief This API write page enable from the register 0x7F bit 7
+ *
+ *
+ *
+ * @param v_page_enable_u8: The value of page enable
+ * value | page
+ * ---------|-----------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_paging_enable(
+u8 v_page_enable_u8);
+ /*!
+ * @brief This API read
+ * pull up configuration from the register 0X85 bit 4 an 5
+ *
+ *
+ *
+ * @param v_control_pullup_u8: The value of pull up register
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_pullup_configuration(
+u8 *v_control_pullup_u8);
+ /*!
+ * @brief This API write
+ * pull up configuration from the register 0X85 bit 4 an 5
+ *
+ *
+ *
+ * @param v_control_pullup_u8: The value of pull up register
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_pullup_configuration(
+u8 v_control_pullup_u8);
+/***************************************************/
+/**\name FUNCTION FOR BMM150 */
+/***************************************************/
+ /*!
+ * @brief This function used for initialize the bmm150 sensor
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bmm150_mag_interface_init(void);
+ /*!
+ * @brief This function used for set the mag power control
+ * bit enable
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bmm150_mag_wakeup(void);
+ /*!
+ * @brief This function used for read the trim values of magnetometer
+ *
+ * @note
+ * Before reading the mag trimming values
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_bmm150_mag_trim_mbl(void);
+ /*!
+ * @brief This function used for read the compensated value of mag
+ * Before start reading the mag compensated data's
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bmm150_mag_compensate_xyz(
+struct smi130_mag_xyz_s32_t *mag_comp_xyz);
+SMI130_RETURN_FUNCTION_TYPE smi130_bmm150_mag_compensate_xyz_raw(
+struct smi130_mag_xyz_s32_t *mag_comp_xyz, struct smi130_mag_xyzr_t mag_xyzr);
+
+/*!
+ * @brief This API used to get the compensated BMM150-X data
+ * the out put of X as s32
+ * Before start reading the mag compensated X data
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ *
+ * @param v_mag_data_x_s16 : The value of mag raw X data
+ * @param v_data_r_u16 : The value of mag R data
+ *
+ * @return results of compensated X data value output as s32
+ *
+ */
+s32 smi130_bmm150_mag_compensate_X(s16 v_mag_data_x_s16, u16 v_data_r_u16);
+/*!
+ * @brief This API used to get the compensated BMM150-Y data
+ * the out put of Y as s32
+ * Before start reading the mag compensated Y data
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ *
+ * @param v_mag_data_y_s16 : The value of mag raw Y data
+ * @param v_data_r_u16 : The value of mag R data
+ *
+ * @return results of compensated Y data value output as s32
+ */
+s32 smi130_bmm150_mag_compensate_Y(s16 v_mag_data_y_s16, u16 v_data_r_u16);
+/*!
+ * @brief This API used to get the compensated BMM150-Z data
+ * the out put of Z as s32
+ * Before start reading the mag compensated Z data
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ *
+ * @param v_mag_data_z_s16 : The value of mag raw Z data
+ * @param v_data_r_u16 : The value of mag R data
+ *
+ * @return results of compensated Z data value output as s32
+ */
+s32 smi130_bmm150_mag_compensate_Z(s16 v_mag_data_z_s16, u16 v_data_r_u16);
+/*!
+ * @brief This API used to set the pre-set modes of bmm150
+ * The pre-set mode setting is depend on data rate and xy and z repetitions
+ *
+ * @note
+ * Before set the mag preset mode
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ * @param v_mode_u8: The value of pre-set mode selection value
+ * value | pre_set mode
+ * ----------|------------
+ * 1 | SMI130_MAG_PRESETMODE_LOWPOWER
+ * 2 | SMI130_MAG_PRESETMODE_REGULAR
+ * 3 | SMI130_MAG_PRESETMODE_HIGHACCURACY
+ * 4 | SMI130_MAG_PRESETMODE_ENHANCED
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_bmm150_mag_presetmode(u8 mode);
+/*!
+ * @brief This function used for set the magnetometer
+ * power mode.
+ * @note
+ * Before set the mag power mode
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ * @param v_mag_pow_mode_u8 : The value of mag power mode
+ * value | mode
+ * ----------|------------
+ * 0 | FORCE_MODE
+ * 1 | SUSPEND_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bmm150_mag_set_power_mode(u8 mag_pow_mode);
+ /*!
+ * @brief This function used for set the magnetometer
+ * power mode.
+ * @note
+ * Before set the mag power mode
+ * make sure the following two point is addressed
+ * Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ *
+ * @param v_mag_sec_if_pow_mode_u8 : The value of mag power mode
+ * value | mode
+ * ----------|------------
+ * 0 | SMI130_MAG_FORCE_MODE
+ * 1 | SMI130_MAG_SUSPEND_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_bmm150_mag_and_secondary_if_power_mode(
+u8 v_mag_sec_if_pow_mode_u8);
+/***************************************************/
+/**\name FUNCTIONS FOR AKM09911 AND AKM09912*/
+/***************************************************/
+ /*!
+ * @brief This function used for initialize
+ * the AKM09911 and AKM09912 sensor
+ *
+ *
+ * @param v_akm_i2c_address_u8: The value of device address
+ * AKM sensor | Slave address
+ * --------------|---------------------
+ * AKM09911 | AKM09911_I2C_ADDR_1
+ * - | and AKM09911_I2C_ADDR_2
+ * AKM09912 | AKM09912_I2C_ADDR_1
+ * - | AKM09912_I2C_ADDR_2
+ * - | AKM09912_I2C_ADDR_3
+ * - | AKM09912_I2C_ADDR_4
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_akm_mag_interface_init(
+u8 v_akm_i2c_address_u8);
+ /*!
+ * @brief This function used for read the sensitivity data of
+ * AKM09911 and AKM09912
+ *
+ * @note Before reading the mag sensitivity values
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_bosch_akm_sensitivity_data(void);
+/*!
+ * @brief This API used to get the compensated X data
+ * of AKM09911 the out put of X as s32
+ * @note Before start reading the mag compensated X data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bosch_akm_x_s16 : The value of X data
+ *
+ * @return results of compensated X data value output as s32
+ *
+ */
+s32 smi130_bosch_akm09911_compensate_X(s16 v_bosch_akm_x_s16);
+/*!
+ * @brief This API used to get the compensated Y data
+ * of AKM09911 the out put of Y as s32
+ * @note Before start reading the mag compensated Y data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bosch_akm_y_s16 : The value of Y data
+ *
+ * @return results of compensated Y data value output as s32
+ *
+ */
+s32 smi130_bosch_akm09911_compensate_Y(s16 v_bosch_akm_y_s16);
+/*!
+ * @brief This API used to get the compensated Z data
+ * of AKM09911 the out put of Z as s32
+ * @note Before start reading the mag compensated Z data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bosch_akm_z_s16 : The value of Z data
+ *
+ * @return results of compensated Z data value output as s32
+ *
+ */
+s32 smi130_bosch_akm09911_compensate_Z(s16 v_bosch_akm_z_s16);
+/*!
+ * @brief This API used to get the compensated X data
+ * of AKM09912 the out put of X as s32
+ * @note Before start reading the mag compensated X data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bosch_akm_x_s16 : The value of X data
+ *
+ * @return results of compensated X data value output as s32
+ *
+ */
+s32 smi130_bosch_akm09912_compensate_X(s16 v_bosch_akm_x_s16);
+/*!
+ * @brief This API used to get the compensated Y data
+ * of AKM09912 the out put of Y as s32
+ * @note Before start reading the mag compensated Y data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bosch_akm_y_s16 : The value of Y data
+ *
+ * @return results of compensated Y data value output as s32
+ *
+ */
+s32 smi130_bosch_akm09912_compensate_Y(s16 v_bosch_akm_y_s16);
+/*!
+ * @brief This API used to get the compensated Z data
+ * of AKM09912 the out put of Z as s32
+ * @note Before start reading the mag compensated Z data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bosch_akm_z_s16 : The value of Z data
+ *
+ * @return results of compensated Z data value output as s32
+ *
+ */
+s32 smi130_bosch_akm09912_compensate_Z(s16 v_bosch_akm_z_s16);
+ /*!
+ * @brief This function used for read the compensated value of
+ * AKM09911
+ * @note Before start reading the mag compensated data's
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_akm09911_compensate_xyz(
+struct smi130_mag_xyz_s32_t *bosch_akm_xyz);
+ /*!
+ * @brief This function used for read the compensated value of
+ * AKM09912
+ * @note Before start reading the mag compensated data's
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_akm09912_compensate_xyz(
+struct smi130_mag_xyz_s32_t *bosch_akm_xyz);
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_akm09912_compensate_xyz_raw(
+struct smi130_mag_xyz_s32_t *bosch_akm_xyz);
+/*!
+ * @brief This function used for set the AKM09911 and AKM09912
+ * power mode.
+ * @note Before set the AKM power mode
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ * @param v_akm_pow_mode_u8 : The value of akm power mode
+ * value | Description
+ * ---------|--------------------
+ * 0 | AKM_POWER_DOWN_MODE
+ * 1 | AKM_SINGLE_MEAS_MODE
+ * 2 | FUSE_ROM_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_akm_set_powermode(u8 v_akm_pow_mode_u8);
+ /*!
+ * @brief This function used for set the magnetometer
+ * power mode of AKM09911 and AKM09912
+ * @note Before set the mag power mode
+ * make sure the following two point is addressed
+ * Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ *
+ * @param v_mag_sec_if_pow_mode_u8 : The value of secondary if power mode
+ * value | Description
+ * ---------|--------------------
+ * 0 | SMI130_MAG_FORCE_MODE
+ * 1 | SMI130_MAG_SUSPEND_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_bosch_akm_and_secondary_if_powermode(
+u8 v_mag_sec_if_pow_mode_u8);
+/***************************************************/
+/**\name FUNCTIONS FOR YAMAH-YAS532 */
+/***************************************************/
+/*!
+ * @brief This function used for read the YAMAH-YAS532 init
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yamaha_yas532_mag_interface_init(
+void);
+/*!
+ * @brief This function used to set the YAS532 initial values
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas532_set_initial_values(void);
+/*!
+ * @brief This function used for YAS532 offset correction
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas532_magnetic_measure_set_offset(
+void);
+/*!
+ * @brief This function used for read the
+ * YAMAHA YAS532 calibration data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yamaha_yas532_calib_values(void);
+/*!
+ * @brief This function used for calculate the
+ * YAS532 read the linear data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas532_xy1y2_to_linear(
+u16 *v_xy1y2_u16, s32 *xy1y2_linear);
+/*!
+ * @brief This function used for read the YAS532 sensor data
+ * @param v_acquisition_command_u8: used to set the data acquisition
+ * acquisition_command | operation
+ * ---------------------|-------------------------
+ * 0x17 | turn on the acquisition coil
+ * - | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Deferred acquisition mode
+ * 0x07 | turn on the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Normal acquisition mode
+ * 0x11 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Deferred acquisition mode
+ * 0x01 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Normal acquisition mode
+ *
+ * @param v_busy_u8 : used to get the busy flay for sensor data read
+ * @param v_temp_u16 : used to get the temperature data
+ * @param v_xy1y2_u16 : used to get the sensor xy1y2 data
+ * @param v_overflow_u8 : used to get the overflow data
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas532_normal_measurement_data(
+u8 v_acquisition_command_u8, u8 *v_busy_u8,
+u16 *v_temp_u16, u16 *v_xy1y2_u16, u8 *v_overflow_u8);
+/*!
+ * @brief This function used for YAS532 sensor data
+ * @param v_acquisition_command_u8 : the value of CMDR
+ * acquisition_command | operation
+ * ---------------------|-------------------------
+ * 0x17 | turn on the acquisition coil
+ * - | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Deferred acquisition mode
+ * 0x07 | turn on the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Normal acquisition mode
+ * 0x11 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Deferred acquisition mode
+ * 0x01 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Normal acquisition mode
+ *
+ * @param xyz_data : the vector xyz output
+ * @param v_overflow_s8 : the value of overflow
+ * @param v_temp_correction_u8 : the value of temperate correction enable
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas532_measurement_xyz_data(
+struct yas532_vector *xyz_data, u8 *v_overflow_s8, u8 v_temp_correction_u8,
+u8 v_acquisition_command_u8);
+/*!
+ * @brief This function used for YAS532 write data acquisition
+ * command register write
+ * @param v_command_reg_data_u8 : the value of data acquisition
+ * acquisition_command | operation
+ * ---------------------|-------------------------
+ * 0x17 | turn on the acquisition coil
+ * - | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Deferred acquisition mode
+ * 0x07 | turn on the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Normal acquisition mode
+ * 0x11 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Deferred acquisition mode
+ * 0x01 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Normal acquisition mode
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas532_acquisition_command_register(
+u8 v_command_reg_data_u8);
+/*!
+ * @brief This function used write offset of YAS532
+ *
+ * @param p_offset_s8 : The value of offset to write
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas532_set_offset(
+const s8 *p_offset_s8);
+/*!
+ * @brief This function used to init the YAMAH-YAS537
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yamaha_yas537_mag_interface_init(
+void);
+/*!
+ * @brief This function used for read the
+ * YAMAHA YAS537 calibration data
+ *
+ *
+ * @param v_rcoil_u8 : The value of r coil
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yamaha_yas537_calib_values(
+u8 v_rcoil_u8);
+/*!
+ * @brief This function used for YAS537 write data acquisition
+ * command register write
+ * @param v_command_reg_data_u8 : the value of data acquisition
+ * acquisition_command | operation
+ * ---------------------|-------------------------
+ * 0x17 | turn on the acquisition coil
+ * - | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Deferred acquisition mode
+ * 0x07 | turn on the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Normal acquisition mode
+ * 0x11 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Deferred acquisition mode
+ * 0x01 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Normal acquisition mode
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas537_acquisition_command_register(
+u8 v_command_reg_data_u8);
+
+/*!
+ * @brief This function used for read the
+ * YAMAHA YAS537 xy1y2 data
+ *
+ * @param v_coil_stat_u8: The value of R coil status
+ * @param v_busy_u8: The value of busy status
+ * @param v_temperature_u16: The value of temperature
+ * @param xy1y2: The value of raw xy1y2 data
+ * @param v_ouflow_u8: The value of overflow
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yamaha_yas537_read_xy1y2_data(
+u8 *v_coil_stat_u8, u8 *v_busy_u8,
+u16 *v_temperature_u16, u16 *xy1y2, u8 *v_ouflow_u8);
+/*!
+ * @brief This function used for read the
+ * YAMAHA YAS537 xy1y2 data
+ *
+ * @param v_ouflow_u8: The value of overflow
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yamaha_yas537_measure_xyz_data(
+u8 *v_ouflow_u8, struct yas_vector *vector_xyz);
+
+/***************************************************/
+/**\name FUNCTIONS FOR FIFO DATA READ */
+/***************************************************/
+/*!
+ * @brief This function used for reading the
+ * fifo data of header less mode
+ *
+ *
+ *
+ * @note Configure the below functions for FIFO header less mode
+ * @note 1. smi130_set_fifo_down_gyro
+ * @note 2. smi130_set_gyro_fifo_filter_data
+ * @note 3. smi130_set_fifo_down_accel
+ * @note 4. smi130_set_accel_fifo_filter_dat
+ * @note 5. smi130_set_fifo_mag_enable
+ * @note 6. smi130_set_fifo_accel_enable
+ * @note 7. smi130_set_fifo_gyro_enable
+ * @note For interrupt configuration
+ * @note 1. smi130_set_intr_fifo_full
+ * @note 2. smi130_set_intr_fifo_wm
+ * @note 3. smi130_set_fifo_tag_intr2_enable
+ * @note 4. smi130_set_fifo_tag_intr1_enable
+ *
+ * @note The fifo reads the whole 1024 bytes
+ * and processing the data
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_read_fifo_headerless_mode(
+void);
+/*!
+ * @brief This function used for reading the
+ * fifo data of header less mode for using user defined length
+ *
+ *
+ * @param v_fifo_user_length_u16: The value of length of fifo read data
+ *
+ * @note Configure the below functions for FIFO header less mode
+ * @note 1. smi130_set_fifo_down_gyro
+ * @note 2. smi130_set_gyro_fifo_filter_data
+ * @note 3. smi130_set_fifo_down_accel
+ * @note 4. smi130_set_accel_fifo_filter_dat
+ * @note 5. smi130_set_fifo_mag_enable
+ * @note 6. smi130_set_fifo_accel_enable
+ * @note 7. smi130_set_fifo_gyro_enable
+ * @note For interrupt configuration
+ * @note 1. smi130_set_intr_fifo_full
+ * @note 2. smi130_set_intr_fifo_wm
+ * @note 3. smi130_set_fifo_tag_intr2_enable
+ * @note 4. smi130_set_fifo_tag_intr1_enable
+ *
+ * @note The fifo reads the whole 1024 bytes
+ * and processing the data
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE
+smi130_read_fifo_headerless_mode_user_defined_length(
+u16 v_fifo_user_length_u16);
+/*!
+ * @brief This function used for reading the
+ * fifo data of header mode
+ *
+ *
+ * @note Configure the below functions for FIFO header mode
+ * @note 1. smi130_set_fifo_down_gyro()
+ * @note 2. smi130_set_gyro_fifo_filter_data()
+ * @note 3. smi130_set_fifo_down_accel()
+ * @note 4. smi130_set_accel_fifo_filter_dat()
+ * @note 5. smi130_set_fifo_mag_enable()
+ * @note 6. smi130_set_fifo_accel_enable()
+ * @note 7. smi130_set_fifo_gyro_enable()
+ * @note 8. smi130_set_fifo_header_enable()
+ * @note For interrupt configuration
+ * @note 1. smi130_set_intr_fifo_full()
+ * @note 2. smi130_set_intr_fifo_wm()
+ * @note 3. smi130_set_fifo_tag_intr2_enable()
+ * @note 4. smi130_set_fifo_tag_intr1_enable()
+ *
+ * @note The fifo reads the whole 1024 bytes
+ * and processing the data
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_read_fifo_header_data(
+void);
+/*!
+ * @brief This function used for reading the
+ * fifo data of header mode for using user defined length
+ *
+ *
+ * @note Configure the below functions for FIFO header mode
+ * @note 1. smi130_set_fifo_down_gyro()
+ * @note 2. smi130_set_gyro_fifo_filter_data()
+ * @note 3. smi130_set_fifo_down_accel()
+ * @note 4. smi130_set_accel_fifo_filter_dat()
+ * @note 5. smi130_set_fifo_mag_enable()
+ * @note 6. smi130_set_fifo_accel_enable()
+ * @note 7. smi130_set_fifo_gyro_enable()
+ * @note 8. smi130_set_fifo_header_enable()
+ * @note For interrupt configuration
+ * @note 1. smi130_set_intr_fifo_full()
+ * @note 2. smi130_set_intr_fifo_wm()
+ * @note 3. smi130_set_fifo_tag_intr2_enable()
+ * @note 4. smi130_set_fifo_tag_intr1_enable()
+ *
+ * @note The fifo reads the whole 1024 bytes
+ * and processing the data
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_read_fifo_header_data_user_defined_length(
+u16 v_fifo_user_length_u16);
+/*!
+ * @brief This function used for reading
+ * smi130_t structure
+ *
+ * @return the reference and values of smi130_t
+ *
+ *
+*/
+struct smi130_t *smi130_get_ptr(void);
+
+#endif
+
diff --git a/drivers/input/sensors/smi130/smi130_acc.c b/drivers/input/sensors/smi130/smi130_acc.c
new file mode 100644
index 0000000..4828b39
--- /dev/null
+++ b/drivers/input/sensors/smi130/smi130_acc.c
@@ -0,0 +1,7507 @@
+/*!
+ * @section LICENSE
+ * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved
+ *
+ * (C) Modification Copyright 2018 Robert Bosch Kft All Rights Reserved
+ *
+ * This software program is licensed subject to the GNU General
+ * Public License (GPL).Version 2,June 1991,
+ * available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * Special: Description of the Software:
+ *
+ * This software module (hereinafter called "Software") and any
+ * information on application-sheets (hereinafter called "Information") is
+ * provided free of charge for the sole purpose to support your application
+ * work.
+ *
+ * As such, the Software is merely an experimental software, not tested for
+ * safety in the field and only intended for inspiration for further development
+ * and testing. Any usage in a safety-relevant field of use (like automotive,
+ * seafaring, spacefaring, industrial plants etc.) was not intended, so there are
+ * no precautions for such usage incorporated in the Software.
+ *
+ * The Software is specifically designed for the exclusive use for Bosch
+ * Sensortec products by personnel who have special experience and training. Do
+ * not use this Software if you do not have the proper experience or training.
+ *
+ * This Software package is provided as is and without any expressed or
+ * implied warranties, including without limitation, the implied warranties of
+ * merchantability and fitness for a particular purpose.
+ *
+ * Bosch Sensortec and their representatives and agents deny any liability for
+ * the functional impairment of this Software in terms of fitness, performance
+ * and safety. Bosch Sensortec and their representatives and agents shall not be
+ * liable for any direct or indirect damages or injury, except as otherwise
+ * stipulated in mandatory applicable law.
+ * The Information provided is believed to be accurate and reliable. Bosch
+ * Sensortec assumes no responsibility for the consequences of use of such
+ * Information nor for any infringement of patents or other rights of third
+ * parties which may result from its use.
+ *
+ *------------------------------------------------------------------------------
+ * The following Product Disclaimer does not apply to the BSX4-HAL-4.1NoFusion Software
+ * which is licensed under the Apache License, Version 2.0 as stated above.
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Product Disclaimer
+ *
+ * Common:
+ *
+ * Assessment of Products Returned from Field
+ *
+ * Returned products are considered good if they fulfill the specifications /
+ * test data for 0-mileage and field listed in this document.
+ *
+ * Engineering Samples
+ *
+ * Engineering samples are marked with (e) or (E). Samples may vary from the
+ * valid technical specifications of the series product contained in this
+ * data sheet. Therefore, they are not intended or fit for resale to
+ * third parties or for use in end products. Their sole purpose is internal
+ * client testing. The testing of an engineering sample may in no way replace
+ * the testing of a series product. Bosch assumes no liability for the use
+ * of engineering samples. The purchaser shall indemnify Bosch from all claims
+ * arising from the use of engineering samples.
+ *
+ * Intended use
+ *
+ * Provided that SMI130 is used within the conditions (environment, application,
+ * installation, loads) as described in this TCD and the corresponding
+ * agreed upon documents, Bosch ensures that the product complies with
+ * the agreed properties. Agreements beyond this require
+ * the written approval by Bosch. The product is considered fit for the intended
+ * use when the product successfully has passed the tests
+ * in accordance with the TCD and agreed upon documents.
+ *
+ * It is the responsibility of the customer to ensure the proper application
+ * of the product in the overall system/vehicle.
+ *
+ * Bosch does not assume any responsibility for changes to the environment
+ * of the product that deviate from the TCD and the agreed upon documents
+ * as well as all applications not released by Bosch
+ *
+ * The resale and/or use of products are at the purchaser’s own risk and
+ * responsibility. The examination and testing of the SMI130
+ * is the sole responsibility of the purchaser.
+ *
+ * The purchaser shall indemnify Bosch from all third party claims
+ * arising from any product use not covered by the parameters of
+ * this product data sheet or not approved by Bosch and reimburse Bosch
+ * for all costs and damages in connection with such claims.
+ *
+ * The purchaser must monitor the market for the purchased products,
+ * particularly with regard to product safety, and inform Bosch without delay
+ * of all security relevant incidents.
+ *
+ * Application Examples and Hints
+ *
+ * With respect to any application examples, advice, normal values
+ * and/or any information regarding the application of the device,
+ * Bosch hereby disclaims any and all warranties and liabilities of any kind,
+ * including without limitation warranties of
+ * non-infringement of intellectual property rights or copyrights
+ * of any third party.
+ * The information given in this document shall in no event be regarded
+ * as a guarantee of conditions or characteristics. They are provided
+ * for illustrative purposes only and no evaluation regarding infringement
+ * of intellectual property rights or copyrights or regarding functionality,
+ * performance or error has been made.
+ *
+ * @filename smi130_acc.c
+ * @date 2015/11/17 10:32
+ * @Modification Date 2018/08/28 18:20
+ * @id "836294d"
+ * @version 2.1.2
+ *
+ * @brief
+ * This file contains all function implementations for the SMI_ACC2X2 in linux
+*/
+
+#ifdef CONFIG_SIG_MOTION
+#undef CONFIG_HAS_EARLYSUSPEND
+#endif
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <asm/irq.h>
+#include <linux/math64.h>
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+
+#ifdef __KERNEL__
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/unistd.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#else
+#include <unistd.h>
+#include <sys/types.h>
+#include <string.h>
+#endif
+
+#include "boschclass.h"
+#include "bs_log.h"
+#define DRIVER_VERSION "0.0.53.0"
+#define ACC_NAME "ACC"
+#define SMI_ACC2X2_ENABLE_INT1 1
+#define CONFIG_SMI_ACC_ENABLE_NEWDATA_INT 1
+
+#define SENSOR_NAME "smi130_acc"
+#define SMI130_ACC_USE_BASIC_I2C_FUNC 1
+
+#define MSC_TIME 6
+#define ABSMIN -512
+#define ABSMAX 512
+#define SLOPE_THRESHOLD_VALUE 32
+#define SLOPE_DURATION_VALUE 1
+#define INTERRUPT_LATCH_MODE 13
+#define INTERRUPT_ENABLE 1
+#define INTERRUPT_DISABLE 0
+#define MAP_SLOPE_INTERRUPT 2
+#define SLOPE_X_INDEX 5
+#define SLOPE_Y_INDEX 6
+#define SLOPE_Z_INDEX 7
+#define SMI_ACC2X2_MAX_DELAY 200
+#define SMI_ACC2X2_RANGE_SET 3 /* +/- 2G */
+#define SMI_ACC2X2_BW_SET 12 /* 125HZ */
+
+#define LOW_G_INTERRUPT REL_Z
+#define HIGH_G_INTERRUPT REL_HWHEEL
+#define SLOP_INTERRUPT REL_DIAL
+#define DOUBLE_TAP_INTERRUPT REL_WHEEL
+#define SINGLE_TAP_INTERRUPT REL_MISC
+#define ORIENT_INTERRUPT ABS_PRESSURE
+#define FLAT_INTERRUPT ABS_DISTANCE
+#define SLOW_NO_MOTION_INTERRUPT REL_Y
+
+#define HIGH_G_INTERRUPT_X_HAPPENED 1
+#define HIGH_G_INTERRUPT_Y_HAPPENED 2
+#define HIGH_G_INTERRUPT_Z_HAPPENED 3
+#define HIGH_G_INTERRUPT_X_NEGATIVE_HAPPENED 4
+#define HIGH_G_INTERRUPT_Y_NEGATIVE_HAPPENED 5
+#define HIGH_G_INTERRUPT_Z_NEGATIVE_HAPPENED 6
+#define SLOPE_INTERRUPT_X_HAPPENED 7
+#define SLOPE_INTERRUPT_Y_HAPPENED 8
+#define SLOPE_INTERRUPT_Z_HAPPENED 9
+#define SLOPE_INTERRUPT_X_NEGATIVE_HAPPENED 10
+#define SLOPE_INTERRUPT_Y_NEGATIVE_HAPPENED 11
+#define SLOPE_INTERRUPT_Z_NEGATIVE_HAPPENED 12
+#define DOUBLE_TAP_INTERRUPT_HAPPENED 13
+#define SINGLE_TAP_INTERRUPT_HAPPENED 14
+#define UPWARD_PORTRAIT_UP_INTERRUPT_HAPPENED 15
+#define UPWARD_PORTRAIT_DOWN_INTERRUPT_HAPPENED 16
+#define UPWARD_LANDSCAPE_LEFT_INTERRUPT_HAPPENED 17
+#define UPWARD_LANDSCAPE_RIGHT_INTERRUPT_HAPPENED 18
+#define DOWNWARD_PORTRAIT_UP_INTERRUPT_HAPPENED 19
+#define DOWNWARD_PORTRAIT_DOWN_INTERRUPT_HAPPENED 20
+#define DOWNWARD_LANDSCAPE_LEFT_INTERRUPT_HAPPENED 21
+#define DOWNWARD_LANDSCAPE_RIGHT_INTERRUPT_HAPPENED 22
+#define FLAT_INTERRUPT_TURE_HAPPENED 23
+#define FLAT_INTERRUPT_FALSE_HAPPENED 24
+#define LOW_G_INTERRUPT_HAPPENED 25
+#define SLOW_NO_MOTION_INTERRUPT_HAPPENED 26
+
+#define PAD_LOWG 0
+#define PAD_HIGHG 1
+#define PAD_SLOP 2
+#define PAD_DOUBLE_TAP 3
+#define PAD_SINGLE_TAP 4
+#define PAD_ORIENT 5
+#define PAD_FLAT 6
+#define PAD_SLOW_NO_MOTION 7
+
+#define SMI_ACC2X2_EEP_OFFSET 0x16
+#define SMI_ACC2X2_IMAGE_BASE 0x38
+#define SMI_ACC2X2_IMAGE_LEN 22
+
+#define SMI_ACC2X2_CHIP_ID_REG 0x00
+#define SMI_ACC2X2_VERSION_REG 0x01
+#define SMI_ACC2X2_X_AXIS_LSB_REG 0x02
+#define SMI_ACC2X2_X_AXIS_MSB_REG 0x03
+#define SMI_ACC2X2_Y_AXIS_LSB_REG 0x04
+#define SMI_ACC2X2_Y_AXIS_MSB_REG 0x05
+#define SMI_ACC2X2_Z_AXIS_LSB_REG 0x06
+#define SMI_ACC2X2_Z_AXIS_MSB_REG 0x07
+#define SMI_ACC2X2_TEMPERATURE_REG 0x08
+#define SMI_ACC2X2_STATUS1_REG 0x09
+#define SMI_ACC2X2_STATUS2_REG 0x0A
+#define SMI_ACC2X2_STATUS_TAP_SLOPE_REG 0x0B
+#define SMI_ACC2X2_STATUS_ORIENT_HIGH_REG 0x0C
+#define SMI_ACC2X2_STATUS_FIFO_REG 0x0E
+#define SMI_ACC2X2_RANGE_SEL_REG 0x0F
+#define SMI_ACC2X2_BW_SEL_REG 0x10
+#define SMI_ACC2X2_MODE_CTRL_REG 0x11
+#define SMI_ACC2X2_LOW_NOISE_CTRL_REG 0x12
+#define SMI_ACC2X2_DATA_CTRL_REG 0x13
+#define SMI_ACC2X2_RESET_REG 0x14
+#define SMI_ACC2X2_INT_ENABLE1_REG 0x16
+#define SMI_ACC2X2_INT_ENABLE2_REG 0x17
+#define SMI_ACC2X2_INT_SLO_NO_MOT_REG 0x18
+#define SMI_ACC2X2_INT1_PAD_SEL_REG 0x19
+#define SMI_ACC2X2_INT_DATA_SEL_REG 0x1A
+#define SMI_ACC2X2_INT2_PAD_SEL_REG 0x1B
+#define SMI_ACC2X2_INT_SRC_REG 0x1E
+#define SMI_ACC2X2_INT_SET_REG 0x20
+#define SMI_ACC2X2_INT_CTRL_REG 0x21
+#define SMI_ACC2X2_LOW_DURN_REG 0x22
+#define SMI_ACC2X2_LOW_THRES_REG 0x23
+#define SMI_ACC2X2_LOW_HIGH_HYST_REG 0x24
+#define SMI_ACC2X2_HIGH_DURN_REG 0x25
+#define SMI_ACC2X2_HIGH_THRES_REG 0x26
+#define SMI_ACC2X2_SLOPE_DURN_REG 0x27
+#define SMI_ACC2X2_SLOPE_THRES_REG 0x28
+#define SMI_ACC2X2_SLO_NO_MOT_THRES_REG 0x29
+#define SMI_ACC2X2_TAP_PARAM_REG 0x2A
+#define SMI_ACC2X2_TAP_THRES_REG 0x2B
+#define SMI_ACC2X2_ORIENT_PARAM_REG 0x2C
+#define SMI_ACC2X2_THETA_BLOCK_REG 0x2D
+#define SMI_ACC2X2_THETA_FLAT_REG 0x2E
+#define SMI_ACC2X2_FLAT_HOLD_TIME_REG 0x2F
+#define SMI_ACC2X2_FIFO_WML_TRIG 0x30
+#define SMI_ACC2X2_SELF_TEST_REG 0x32
+#define SMI_ACC2X2_EEPROM_CTRL_REG 0x33
+#define SMI_ACC2X2_SERIAL_CTRL_REG 0x34
+#define SMI_ACC2X2_EXTMODE_CTRL_REG 0x35
+#define SMI_ACC2X2_OFFSET_CTRL_REG 0x36
+#define SMI_ACC2X2_OFFSET_PARAMS_REG 0x37
+#define SMI_ACC2X2_OFFSET_X_AXIS_REG 0x38
+#define SMI_ACC2X2_OFFSET_Y_AXIS_REG 0x39
+#define SMI_ACC2X2_OFFSET_Z_AXIS_REG 0x3A
+#define SMI_ACC2X2_GP0_REG 0x3B
+#define SMI_ACC2X2_GP1_REG 0x3C
+#define SMI_ACC2X2_FIFO_MODE_REG 0x3E
+#define SMI_ACC2X2_FIFO_DATA_OUTPUT_REG 0x3F
+
+#define SMI_ACC2X2_CHIP_ID__POS 0
+#define SMI_ACC2X2_CHIP_ID__MSK 0xFF
+#define SMI_ACC2X2_CHIP_ID__LEN 8
+#define SMI_ACC2X2_CHIP_ID__REG SMI_ACC2X2_CHIP_ID_REG
+
+#define SMI_ACC2X2_VERSION__POS 0
+#define SMI_ACC2X2_VERSION__LEN 8
+#define SMI_ACC2X2_VERSION__MSK 0xFF
+#define SMI_ACC2X2_VERSION__REG SMI_ACC2X2_VERSION_REG
+
+#define SMI130_ACC_SLO_NO_MOT_DUR__POS 2
+#define SMI130_ACC_SLO_NO_MOT_DUR__LEN 6
+#define SMI130_ACC_SLO_NO_MOT_DUR__MSK 0xFC
+#define SMI130_ACC_SLO_NO_MOT_DUR__REG SMI_ACC2X2_SLOPE_DURN_REG
+
+#define SMI_ACC2X2_NEW_DATA_X__POS 0
+#define SMI_ACC2X2_NEW_DATA_X__LEN 1
+#define SMI_ACC2X2_NEW_DATA_X__MSK 0x01
+#define SMI_ACC2X2_NEW_DATA_X__REG SMI_ACC2X2_X_AXIS_LSB_REG
+
+#define SMI_ACC2X2_ACC_X14_LSB__POS 2
+#define SMI_ACC2X2_ACC_X14_LSB__LEN 6
+#define SMI_ACC2X2_ACC_X14_LSB__MSK 0xFC
+#define SMI_ACC2X2_ACC_X14_LSB__REG SMI_ACC2X2_X_AXIS_LSB_REG
+
+#define SMI_ACC2X2_ACC_X12_LSB__POS 4
+#define SMI_ACC2X2_ACC_X12_LSB__LEN 4
+#define SMI_ACC2X2_ACC_X12_LSB__MSK 0xF0
+#define SMI_ACC2X2_ACC_X12_LSB__REG SMI_ACC2X2_X_AXIS_LSB_REG
+
+#define SMI_ACC2X2_ACC_X10_LSB__POS 6
+#define SMI_ACC2X2_ACC_X10_LSB__LEN 2
+#define SMI_ACC2X2_ACC_X10_LSB__MSK 0xC0
+#define SMI_ACC2X2_ACC_X10_LSB__REG SMI_ACC2X2_X_AXIS_LSB_REG
+
+#define SMI_ACC2X2_ACC_X8_LSB__POS 0
+#define SMI_ACC2X2_ACC_X8_LSB__LEN 0
+#define SMI_ACC2X2_ACC_X8_LSB__MSK 0x00
+#define SMI_ACC2X2_ACC_X8_LSB__REG SMI_ACC2X2_X_AXIS_LSB_REG
+
+#define SMI_ACC2X2_ACC_X_MSB__POS 0
+#define SMI_ACC2X2_ACC_X_MSB__LEN 8
+#define SMI_ACC2X2_ACC_X_MSB__MSK 0xFF
+#define SMI_ACC2X2_ACC_X_MSB__REG SMI_ACC2X2_X_AXIS_MSB_REG
+
+#define SMI_ACC2X2_NEW_DATA_Y__POS 0
+#define SMI_ACC2X2_NEW_DATA_Y__LEN 1
+#define SMI_ACC2X2_NEW_DATA_Y__MSK 0x01
+#define SMI_ACC2X2_NEW_DATA_Y__REG SMI_ACC2X2_Y_AXIS_LSB_REG
+
+#define SMI_ACC2X2_ACC_Y14_LSB__POS 2
+#define SMI_ACC2X2_ACC_Y14_LSB__LEN 6
+#define SMI_ACC2X2_ACC_Y14_LSB__MSK 0xFC
+#define SMI_ACC2X2_ACC_Y14_LSB__REG SMI_ACC2X2_Y_AXIS_LSB_REG
+
+#define SMI_ACC2X2_ACC_Y12_LSB__POS 4
+#define SMI_ACC2X2_ACC_Y12_LSB__LEN 4
+#define SMI_ACC2X2_ACC_Y12_LSB__MSK 0xF0
+#define SMI_ACC2X2_ACC_Y12_LSB__REG SMI_ACC2X2_Y_AXIS_LSB_REG
+
+#define SMI_ACC2X2_ACC_Y10_LSB__POS 6
+#define SMI_ACC2X2_ACC_Y10_LSB__LEN 2
+#define SMI_ACC2X2_ACC_Y10_LSB__MSK 0xC0
+#define SMI_ACC2X2_ACC_Y10_LSB__REG SMI_ACC2X2_Y_AXIS_LSB_REG
+
+#define SMI_ACC2X2_ACC_Y8_LSB__POS 0
+#define SMI_ACC2X2_ACC_Y8_LSB__LEN 0
+#define SMI_ACC2X2_ACC_Y8_LSB__MSK 0x00
+#define SMI_ACC2X2_ACC_Y8_LSB__REG SMI_ACC2X2_Y_AXIS_LSB_REG
+
+#define SMI_ACC2X2_ACC_Y_MSB__POS 0
+#define SMI_ACC2X2_ACC_Y_MSB__LEN 8
+#define SMI_ACC2X2_ACC_Y_MSB__MSK 0xFF
+#define SMI_ACC2X2_ACC_Y_MSB__REG SMI_ACC2X2_Y_AXIS_MSB_REG
+
+#define SMI_ACC2X2_NEW_DATA_Z__POS 0
+#define SMI_ACC2X2_NEW_DATA_Z__LEN 1
+#define SMI_ACC2X2_NEW_DATA_Z__MSK 0x01
+#define SMI_ACC2X2_NEW_DATA_Z__REG SMI_ACC2X2_Z_AXIS_LSB_REG
+
+#define SMI_ACC2X2_ACC_Z14_LSB__POS 2
+#define SMI_ACC2X2_ACC_Z14_LSB__LEN 6
+#define SMI_ACC2X2_ACC_Z14_LSB__MSK 0xFC
+#define SMI_ACC2X2_ACC_Z14_LSB__REG SMI_ACC2X2_Z_AXIS_LSB_REG
+
+#define SMI_ACC2X2_ACC_Z12_LSB__POS 4
+#define SMI_ACC2X2_ACC_Z12_LSB__LEN 4
+#define SMI_ACC2X2_ACC_Z12_LSB__MSK 0xF0
+#define SMI_ACC2X2_ACC_Z12_LSB__REG SMI_ACC2X2_Z_AXIS_LSB_REG
+
+#define SMI_ACC2X2_ACC_Z10_LSB__POS 6
+#define SMI_ACC2X2_ACC_Z10_LSB__LEN 2
+#define SMI_ACC2X2_ACC_Z10_LSB__MSK 0xC0
+#define SMI_ACC2X2_ACC_Z10_LSB__REG SMI_ACC2X2_Z_AXIS_LSB_REG
+
+#define SMI_ACC2X2_ACC_Z8_LSB__POS 0
+#define SMI_ACC2X2_ACC_Z8_LSB__LEN 0
+#define SMI_ACC2X2_ACC_Z8_LSB__MSK 0x00
+#define SMI_ACC2X2_ACC_Z8_LSB__REG SMI_ACC2X2_Z_AXIS_LSB_REG
+
+#define SMI_ACC2X2_ACC_Z_MSB__POS 0
+#define SMI_ACC2X2_ACC_Z_MSB__LEN 8
+#define SMI_ACC2X2_ACC_Z_MSB__MSK 0xFF
+#define SMI_ACC2X2_ACC_Z_MSB__REG SMI_ACC2X2_Z_AXIS_MSB_REG
+
+#define SMI_ACC2X2_TEMPERATURE__POS 0
+#define SMI_ACC2X2_TEMPERATURE__LEN 8
+#define SMI_ACC2X2_TEMPERATURE__MSK 0xFF
+#define SMI_ACC2X2_TEMPERATURE__REG SMI_ACC2X2_TEMP_RD_REG
+
+#define SMI_ACC2X2_LOWG_INT_S__POS 0
+#define SMI_ACC2X2_LOWG_INT_S__LEN 1
+#define SMI_ACC2X2_LOWG_INT_S__MSK 0x01
+#define SMI_ACC2X2_LOWG_INT_S__REG SMI_ACC2X2_STATUS1_REG
+
+#define SMI_ACC2X2_HIGHG_INT_S__POS 1
+#define SMI_ACC2X2_HIGHG_INT_S__LEN 1
+#define SMI_ACC2X2_HIGHG_INT_S__MSK 0x02
+#define SMI_ACC2X2_HIGHG_INT_S__REG SMI_ACC2X2_STATUS1_REG
+
+#define SMI_ACC2X2_SLOPE_INT_S__POS 2
+#define SMI_ACC2X2_SLOPE_INT_S__LEN 1
+#define SMI_ACC2X2_SLOPE_INT_S__MSK 0x04
+#define SMI_ACC2X2_SLOPE_INT_S__REG SMI_ACC2X2_STATUS1_REG
+
+
+#define SMI_ACC2X2_SLO_NO_MOT_INT_S__POS 3
+#define SMI_ACC2X2_SLO_NO_MOT_INT_S__LEN 1
+#define SMI_ACC2X2_SLO_NO_MOT_INT_S__MSK 0x08
+#define SMI_ACC2X2_SLO_NO_MOT_INT_S__REG SMI_ACC2X2_STATUS1_REG
+
+#define SMI_ACC2X2_DOUBLE_TAP_INT_S__POS 4
+#define SMI_ACC2X2_DOUBLE_TAP_INT_S__LEN 1
+#define SMI_ACC2X2_DOUBLE_TAP_INT_S__MSK 0x10
+#define SMI_ACC2X2_DOUBLE_TAP_INT_S__REG SMI_ACC2X2_STATUS1_REG
+
+#define SMI_ACC2X2_SINGLE_TAP_INT_S__POS 5
+#define SMI_ACC2X2_SINGLE_TAP_INT_S__LEN 1
+#define SMI_ACC2X2_SINGLE_TAP_INT_S__MSK 0x20
+#define SMI_ACC2X2_SINGLE_TAP_INT_S__REG SMI_ACC2X2_STATUS1_REG
+
+#define SMI_ACC2X2_ORIENT_INT_S__POS 6
+#define SMI_ACC2X2_ORIENT_INT_S__LEN 1
+#define SMI_ACC2X2_ORIENT_INT_S__MSK 0x40
+#define SMI_ACC2X2_ORIENT_INT_S__REG SMI_ACC2X2_STATUS1_REG
+
+#define SMI_ACC2X2_FLAT_INT_S__POS 7
+#define SMI_ACC2X2_FLAT_INT_S__LEN 1
+#define SMI_ACC2X2_FLAT_INT_S__MSK 0x80
+#define SMI_ACC2X2_FLAT_INT_S__REG SMI_ACC2X2_STATUS1_REG
+
+#define SMI_ACC2X2_FIFO_FULL_INT_S__POS 5
+#define SMI_ACC2X2_FIFO_FULL_INT_S__LEN 1
+#define SMI_ACC2X2_FIFO_FULL_INT_S__MSK 0x20
+#define SMI_ACC2X2_FIFO_FULL_INT_S__REG SMI_ACC2X2_STATUS2_REG
+
+#define SMI_ACC2X2_FIFO_WM_INT_S__POS 6
+#define SMI_ACC2X2_FIFO_WM_INT_S__LEN 1
+#define SMI_ACC2X2_FIFO_WM_INT_S__MSK 0x40
+#define SMI_ACC2X2_FIFO_WM_INT_S__REG SMI_ACC2X2_STATUS2_REG
+
+#define SMI_ACC2X2_DATA_INT_S__POS 7
+#define SMI_ACC2X2_DATA_INT_S__LEN 1
+#define SMI_ACC2X2_DATA_INT_S__MSK 0x80
+#define SMI_ACC2X2_DATA_INT_S__REG SMI_ACC2X2_STATUS2_REG
+
+#define SMI_ACC2X2_SLOPE_FIRST_X__POS 0
+#define SMI_ACC2X2_SLOPE_FIRST_X__LEN 1
+#define SMI_ACC2X2_SLOPE_FIRST_X__MSK 0x01
+#define SMI_ACC2X2_SLOPE_FIRST_X__REG SMI_ACC2X2_STATUS_TAP_SLOPE_REG
+
+#define SMI_ACC2X2_SLOPE_FIRST_Y__POS 1
+#define SMI_ACC2X2_SLOPE_FIRST_Y__LEN 1
+#define SMI_ACC2X2_SLOPE_FIRST_Y__MSK 0x02
+#define SMI_ACC2X2_SLOPE_FIRST_Y__REG SMI_ACC2X2_STATUS_TAP_SLOPE_REG
+
+#define SMI_ACC2X2_SLOPE_FIRST_Z__POS 2
+#define SMI_ACC2X2_SLOPE_FIRST_Z__LEN 1
+#define SMI_ACC2X2_SLOPE_FIRST_Z__MSK 0x04
+#define SMI_ACC2X2_SLOPE_FIRST_Z__REG SMI_ACC2X2_STATUS_TAP_SLOPE_REG
+
+#define SMI_ACC2X2_SLOPE_SIGN_S__POS 3
+#define SMI_ACC2X2_SLOPE_SIGN_S__LEN 1
+#define SMI_ACC2X2_SLOPE_SIGN_S__MSK 0x08
+#define SMI_ACC2X2_SLOPE_SIGN_S__REG SMI_ACC2X2_STATUS_TAP_SLOPE_REG
+
+#define SMI_ACC2X2_TAP_FIRST_X__POS 4
+#define SMI_ACC2X2_TAP_FIRST_X__LEN 1
+#define SMI_ACC2X2_TAP_FIRST_X__MSK 0x10
+#define SMI_ACC2X2_TAP_FIRST_X__REG SMI_ACC2X2_STATUS_TAP_SLOPE_REG
+
+#define SMI_ACC2X2_TAP_FIRST_Y__POS 5
+#define SMI_ACC2X2_TAP_FIRST_Y__LEN 1
+#define SMI_ACC2X2_TAP_FIRST_Y__MSK 0x20
+#define SMI_ACC2X2_TAP_FIRST_Y__REG SMI_ACC2X2_STATUS_TAP_SLOPE_REG
+
+#define SMI_ACC2X2_TAP_FIRST_Z__POS 6
+#define SMI_ACC2X2_TAP_FIRST_Z__LEN 1
+#define SMI_ACC2X2_TAP_FIRST_Z__MSK 0x40
+#define SMI_ACC2X2_TAP_FIRST_Z__REG SMI_ACC2X2_STATUS_TAP_SLOPE_REG
+
+#define SMI_ACC2X2_TAP_SIGN_S__POS 7
+#define SMI_ACC2X2_TAP_SIGN_S__LEN 1
+#define SMI_ACC2X2_TAP_SIGN_S__MSK 0x80
+#define SMI_ACC2X2_TAP_SIGN_S__REG SMI_ACC2X2_STATUS_TAP_SLOPE_REG
+
+#define SMI_ACC2X2_HIGHG_FIRST_X__POS 0
+#define SMI_ACC2X2_HIGHG_FIRST_X__LEN 1
+#define SMI_ACC2X2_HIGHG_FIRST_X__MSK 0x01
+#define SMI_ACC2X2_HIGHG_FIRST_X__REG SMI_ACC2X2_STATUS_ORIENT_HIGH_REG
+
+#define SMI_ACC2X2_HIGHG_FIRST_Y__POS 1
+#define SMI_ACC2X2_HIGHG_FIRST_Y__LEN 1
+#define SMI_ACC2X2_HIGHG_FIRST_Y__MSK 0x02
+#define SMI_ACC2X2_HIGHG_FIRST_Y__REG SMI_ACC2X2_STATUS_ORIENT_HIGH_REG
+
+#define SMI_ACC2X2_HIGHG_FIRST_Z__POS 2
+#define SMI_ACC2X2_HIGHG_FIRST_Z__LEN 1
+#define SMI_ACC2X2_HIGHG_FIRST_Z__MSK 0x04
+#define SMI_ACC2X2_HIGHG_FIRST_Z__REG SMI_ACC2X2_STATUS_ORIENT_HIGH_REG
+
+#define SMI_ACC2X2_HIGHG_SIGN_S__POS 3
+#define SMI_ACC2X2_HIGHG_SIGN_S__LEN 1
+#define SMI_ACC2X2_HIGHG_SIGN_S__MSK 0x08
+#define SMI_ACC2X2_HIGHG_SIGN_S__REG SMI_ACC2X2_STATUS_ORIENT_HIGH_REG
+
+#define SMI_ACC2X2_ORIENT_S__POS 4
+#define SMI_ACC2X2_ORIENT_S__LEN 3
+#define SMI_ACC2X2_ORIENT_S__MSK 0x70
+#define SMI_ACC2X2_ORIENT_S__REG SMI_ACC2X2_STATUS_ORIENT_HIGH_REG
+
+#define SMI_ACC2X2_FLAT_S__POS 7
+#define SMI_ACC2X2_FLAT_S__LEN 1
+#define SMI_ACC2X2_FLAT_S__MSK 0x80
+#define SMI_ACC2X2_FLAT_S__REG SMI_ACC2X2_STATUS_ORIENT_HIGH_REG
+
+#define SMI_ACC2X2_FIFO_FRAME_COUNTER_S__POS 0
+#define SMI_ACC2X2_FIFO_FRAME_COUNTER_S__LEN 7
+#define SMI_ACC2X2_FIFO_FRAME_COUNTER_S__MSK 0x7F
+#define SMI_ACC2X2_FIFO_FRAME_COUNTER_S__REG SMI_ACC2X2_STATUS_FIFO_REG
+
+#define SMI_ACC2X2_FIFO_OVERRUN_S__POS 7
+#define SMI_ACC2X2_FIFO_OVERRUN_S__LEN 1
+#define SMI_ACC2X2_FIFO_OVERRUN_S__MSK 0x80
+#define SMI_ACC2X2_FIFO_OVERRUN_S__REG SMI_ACC2X2_STATUS_FIFO_REG
+
+#define SMI_ACC2X2_RANGE_SEL__POS 0
+#define SMI_ACC2X2_RANGE_SEL__LEN 4
+#define SMI_ACC2X2_RANGE_SEL__MSK 0x0F
+#define SMI_ACC2X2_RANGE_SEL__REG SMI_ACC2X2_RANGE_SEL_REG
+
+#define SMI_ACC2X2_BANDWIDTH__POS 0
+#define SMI_ACC2X2_BANDWIDTH__LEN 5
+#define SMI_ACC2X2_BANDWIDTH__MSK 0x1F
+#define SMI_ACC2X2_BANDWIDTH__REG SMI_ACC2X2_BW_SEL_REG
+
+#define SMI_ACC2X2_SLEEP_DUR__POS 1
+#define SMI_ACC2X2_SLEEP_DUR__LEN 4
+#define SMI_ACC2X2_SLEEP_DUR__MSK 0x1E
+#define SMI_ACC2X2_SLEEP_DUR__REG SMI_ACC2X2_MODE_CTRL_REG
+
+#define SMI_ACC2X2_MODE_CTRL__POS 5
+#define SMI_ACC2X2_MODE_CTRL__LEN 3
+#define SMI_ACC2X2_MODE_CTRL__MSK 0xE0
+#define SMI_ACC2X2_MODE_CTRL__REG SMI_ACC2X2_MODE_CTRL_REG
+
+#define SMI_ACC2X2_DEEP_SUSPEND__POS 5
+#define SMI_ACC2X2_DEEP_SUSPEND__LEN 1
+#define SMI_ACC2X2_DEEP_SUSPEND__MSK 0x20
+#define SMI_ACC2X2_DEEP_SUSPEND__REG SMI_ACC2X2_MODE_CTRL_REG
+
+#define SMI_ACC2X2_EN_LOW_POWER__POS 6
+#define SMI_ACC2X2_EN_LOW_POWER__LEN 1
+#define SMI_ACC2X2_EN_LOW_POWER__MSK 0x40
+#define SMI_ACC2X2_EN_LOW_POWER__REG SMI_ACC2X2_MODE_CTRL_REG
+
+#define SMI_ACC2X2_EN_SUSPEND__POS 7
+#define SMI_ACC2X2_EN_SUSPEND__LEN 1
+#define SMI_ACC2X2_EN_SUSPEND__MSK 0x80
+#define SMI_ACC2X2_EN_SUSPEND__REG SMI_ACC2X2_MODE_CTRL_REG
+
+#define SMI_ACC2X2_SLEEP_TIMER__POS 5
+#define SMI_ACC2X2_SLEEP_TIMER__LEN 1
+#define SMI_ACC2X2_SLEEP_TIMER__MSK 0x20
+#define SMI_ACC2X2_SLEEP_TIMER__REG SMI_ACC2X2_LOW_NOISE_CTRL_REG
+
+#define SMI_ACC2X2_LOW_POWER_MODE__POS 6
+#define SMI_ACC2X2_LOW_POWER_MODE__LEN 1
+#define SMI_ACC2X2_LOW_POWER_MODE__MSK 0x40
+#define SMI_ACC2X2_LOW_POWER_MODE__REG SMI_ACC2X2_LOW_NOISE_CTRL_REG
+
+#define SMI_ACC2X2_EN_LOW_NOISE__POS 7
+#define SMI_ACC2X2_EN_LOW_NOISE__LEN 1
+#define SMI_ACC2X2_EN_LOW_NOISE__MSK 0x80
+#define SMI_ACC2X2_EN_LOW_NOISE__REG SMI_ACC2X2_LOW_NOISE_CTRL_REG
+
+#define SMI_ACC2X2_DIS_SHADOW_PROC__POS 6
+#define SMI_ACC2X2_DIS_SHADOW_PROC__LEN 1
+#define SMI_ACC2X2_DIS_SHADOW_PROC__MSK 0x40
+#define SMI_ACC2X2_DIS_SHADOW_PROC__REG SMI_ACC2X2_DATA_CTRL_REG
+
+#define SMI_ACC2X2_EN_DATA_HIGH_BW__POS 7
+#define SMI_ACC2X2_EN_DATA_HIGH_BW__LEN 1
+#define SMI_ACC2X2_EN_DATA_HIGH_BW__MSK 0x80
+#define SMI_ACC2X2_EN_DATA_HIGH_BW__REG SMI_ACC2X2_DATA_CTRL_REG
+
+#define SMI_ACC2X2_EN_SOFT_RESET__POS 0
+#define SMI_ACC2X2_EN_SOFT_RESET__LEN 8
+#define SMI_ACC2X2_EN_SOFT_RESET__MSK 0xFF
+#define SMI_ACC2X2_EN_SOFT_RESET__REG SMI_ACC2X2_RESET_REG
+
+#define SMI_ACC2X2_EN_SOFT_RESET_VALUE 0xB6
+
+#define SMI_ACC2X2_EN_SLOPE_X_INT__POS 0
+#define SMI_ACC2X2_EN_SLOPE_X_INT__LEN 1
+#define SMI_ACC2X2_EN_SLOPE_X_INT__MSK 0x01
+#define SMI_ACC2X2_EN_SLOPE_X_INT__REG SMI_ACC2X2_INT_ENABLE1_REG
+
+#define SMI_ACC2X2_EN_SLOPE_Y_INT__POS 1
+#define SMI_ACC2X2_EN_SLOPE_Y_INT__LEN 1
+#define SMI_ACC2X2_EN_SLOPE_Y_INT__MSK 0x02
+#define SMI_ACC2X2_EN_SLOPE_Y_INT__REG SMI_ACC2X2_INT_ENABLE1_REG
+
+#define SMI_ACC2X2_EN_SLOPE_Z_INT__POS 2
+#define SMI_ACC2X2_EN_SLOPE_Z_INT__LEN 1
+#define SMI_ACC2X2_EN_SLOPE_Z_INT__MSK 0x04
+#define SMI_ACC2X2_EN_SLOPE_Z_INT__REG SMI_ACC2X2_INT_ENABLE1_REG
+
+#define SMI_ACC2X2_EN_DOUBLE_TAP_INT__POS 4
+#define SMI_ACC2X2_EN_DOUBLE_TAP_INT__LEN 1
+#define SMI_ACC2X2_EN_DOUBLE_TAP_INT__MSK 0x10
+#define SMI_ACC2X2_EN_DOUBLE_TAP_INT__REG SMI_ACC2X2_INT_ENABLE1_REG
+
+#define SMI_ACC2X2_EN_SINGLE_TAP_INT__POS 5
+#define SMI_ACC2X2_EN_SINGLE_TAP_INT__LEN 1
+#define SMI_ACC2X2_EN_SINGLE_TAP_INT__MSK 0x20
+#define SMI_ACC2X2_EN_SINGLE_TAP_INT__REG SMI_ACC2X2_INT_ENABLE1_REG
+
+#define SMI_ACC2X2_EN_ORIENT_INT__POS 6
+#define SMI_ACC2X2_EN_ORIENT_INT__LEN 1
+#define SMI_ACC2X2_EN_ORIENT_INT__MSK 0x40
+#define SMI_ACC2X2_EN_ORIENT_INT__REG SMI_ACC2X2_INT_ENABLE1_REG
+
+#define SMI_ACC2X2_EN_FLAT_INT__POS 7
+#define SMI_ACC2X2_EN_FLAT_INT__LEN 1
+#define SMI_ACC2X2_EN_FLAT_INT__MSK 0x80
+#define SMI_ACC2X2_EN_FLAT_INT__REG SMI_ACC2X2_INT_ENABLE1_REG
+
+#define SMI_ACC2X2_EN_HIGHG_X_INT__POS 0
+#define SMI_ACC2X2_EN_HIGHG_X_INT__LEN 1
+#define SMI_ACC2X2_EN_HIGHG_X_INT__MSK 0x01
+#define SMI_ACC2X2_EN_HIGHG_X_INT__REG SMI_ACC2X2_INT_ENABLE2_REG
+
+#define SMI_ACC2X2_EN_HIGHG_Y_INT__POS 1
+#define SMI_ACC2X2_EN_HIGHG_Y_INT__LEN 1
+#define SMI_ACC2X2_EN_HIGHG_Y_INT__MSK 0x02
+#define SMI_ACC2X2_EN_HIGHG_Y_INT__REG SMI_ACC2X2_INT_ENABLE2_REG
+
+#define SMI_ACC2X2_EN_HIGHG_Z_INT__POS 2
+#define SMI_ACC2X2_EN_HIGHG_Z_INT__LEN 1
+#define SMI_ACC2X2_EN_HIGHG_Z_INT__MSK 0x04
+#define SMI_ACC2X2_EN_HIGHG_Z_INT__REG SMI_ACC2X2_INT_ENABLE2_REG
+
+#define SMI_ACC2X2_EN_LOWG_INT__POS 3
+#define SMI_ACC2X2_EN_LOWG_INT__LEN 1
+#define SMI_ACC2X2_EN_LOWG_INT__MSK 0x08
+#define SMI_ACC2X2_EN_LOWG_INT__REG SMI_ACC2X2_INT_ENABLE2_REG
+
+#define SMI_ACC2X2_EN_NEW_DATA_INT__POS 4
+#define SMI_ACC2X2_EN_NEW_DATA_INT__LEN 1
+#define SMI_ACC2X2_EN_NEW_DATA_INT__MSK 0x10
+#define SMI_ACC2X2_EN_NEW_DATA_INT__REG SMI_ACC2X2_INT_ENABLE2_REG
+
+#define SMI_ACC2X2_INT_FFULL_EN_INT__POS 5
+#define SMI_ACC2X2_INT_FFULL_EN_INT__LEN 1
+#define SMI_ACC2X2_INT_FFULL_EN_INT__MSK 0x20
+#define SMI_ACC2X2_INT_FFULL_EN_INT__REG SMI_ACC2X2_INT_ENABLE2_REG
+
+#define SMI_ACC2X2_INT_FWM_EN_INT__POS 6
+#define SMI_ACC2X2_INT_FWM_EN_INT__LEN 1
+#define SMI_ACC2X2_INT_FWM_EN_INT__MSK 0x40
+#define SMI_ACC2X2_INT_FWM_EN_INT__REG SMI_ACC2X2_INT_ENABLE2_REG
+
+#define SMI_ACC2X2_INT_SLO_NO_MOT_EN_X_INT__POS 0
+#define SMI_ACC2X2_INT_SLO_NO_MOT_EN_X_INT__LEN 1
+#define SMI_ACC2X2_INT_SLO_NO_MOT_EN_X_INT__MSK 0x01
+#define SMI_ACC2X2_INT_SLO_NO_MOT_EN_X_INT__REG SMI_ACC2X2_INT_SLO_NO_MOT_REG
+
+#define SMI_ACC2X2_INT_SLO_NO_MOT_EN_Y_INT__POS 1
+#define SMI_ACC2X2_INT_SLO_NO_MOT_EN_Y_INT__LEN 1
+#define SMI_ACC2X2_INT_SLO_NO_MOT_EN_Y_INT__MSK 0x02
+#define SMI_ACC2X2_INT_SLO_NO_MOT_EN_Y_INT__REG SMI_ACC2X2_INT_SLO_NO_MOT_REG
+
+#define SMI_ACC2X2_INT_SLO_NO_MOT_EN_Z_INT__POS 2
+#define SMI_ACC2X2_INT_SLO_NO_MOT_EN_Z_INT__LEN 1
+#define SMI_ACC2X2_INT_SLO_NO_MOT_EN_Z_INT__MSK 0x04
+#define SMI_ACC2X2_INT_SLO_NO_MOT_EN_Z_INT__REG SMI_ACC2X2_INT_SLO_NO_MOT_REG
+
+#define SMI_ACC2X2_INT_SLO_NO_MOT_EN_SEL_INT__POS 3
+#define SMI_ACC2X2_INT_SLO_NO_MOT_EN_SEL_INT__LEN 1
+#define SMI_ACC2X2_INT_SLO_NO_MOT_EN_SEL_INT__MSK 0x08
+#define SMI_ACC2X2_INT_SLO_NO_MOT_EN_SEL_INT__REG SMI_ACC2X2_INT_SLO_NO_MOT_REG
+
+#define SMI_ACC2X2_EN_INT1_PAD_LOWG__POS 0
+#define SMI_ACC2X2_EN_INT1_PAD_LOWG__LEN 1
+#define SMI_ACC2X2_EN_INT1_PAD_LOWG__MSK 0x01
+#define SMI_ACC2X2_EN_INT1_PAD_LOWG__REG SMI_ACC2X2_INT1_PAD_SEL_REG
+
+#define SMI_ACC2X2_EN_INT1_PAD_HIGHG__POS 1
+#define SMI_ACC2X2_EN_INT1_PAD_HIGHG__LEN 1
+#define SMI_ACC2X2_EN_INT1_PAD_HIGHG__MSK 0x02
+#define SMI_ACC2X2_EN_INT1_PAD_HIGHG__REG SMI_ACC2X2_INT1_PAD_SEL_REG
+
+#define SMI_ACC2X2_EN_INT1_PAD_SLOPE__POS 2
+#define SMI_ACC2X2_EN_INT1_PAD_SLOPE__LEN 1
+#define SMI_ACC2X2_EN_INT1_PAD_SLOPE__MSK 0x04
+#define SMI_ACC2X2_EN_INT1_PAD_SLOPE__REG SMI_ACC2X2_INT1_PAD_SEL_REG
+
+#define SMI_ACC2X2_EN_INT1_PAD_SLO_NO_MOT__POS 3
+#define SMI_ACC2X2_EN_INT1_PAD_SLO_NO_MOT__LEN 1
+#define SMI_ACC2X2_EN_INT1_PAD_SLO_NO_MOT__MSK 0x08
+#define SMI_ACC2X2_EN_INT1_PAD_SLO_NO_MOT__REG SMI_ACC2X2_INT1_PAD_SEL_REG
+
+#define SMI_ACC2X2_EN_INT1_PAD_DB_TAP__POS 4
+#define SMI_ACC2X2_EN_INT1_PAD_DB_TAP__LEN 1
+#define SMI_ACC2X2_EN_INT1_PAD_DB_TAP__MSK 0x10
+#define SMI_ACC2X2_EN_INT1_PAD_DB_TAP__REG SMI_ACC2X2_INT1_PAD_SEL_REG
+
+#define SMI_ACC2X2_EN_INT1_PAD_SNG_TAP__POS 5
+#define SMI_ACC2X2_EN_INT1_PAD_SNG_TAP__LEN 1
+#define SMI_ACC2X2_EN_INT1_PAD_SNG_TAP__MSK 0x20
+#define SMI_ACC2X2_EN_INT1_PAD_SNG_TAP__REG SMI_ACC2X2_INT1_PAD_SEL_REG
+
+#define SMI_ACC2X2_EN_INT1_PAD_ORIENT__POS 6
+#define SMI_ACC2X2_EN_INT1_PAD_ORIENT__LEN 1
+#define SMI_ACC2X2_EN_INT1_PAD_ORIENT__MSK 0x40
+#define SMI_ACC2X2_EN_INT1_PAD_ORIENT__REG SMI_ACC2X2_INT1_PAD_SEL_REG
+
+#define SMI_ACC2X2_EN_INT1_PAD_FLAT__POS 7
+#define SMI_ACC2X2_EN_INT1_PAD_FLAT__LEN 1
+#define SMI_ACC2X2_EN_INT1_PAD_FLAT__MSK 0x80
+#define SMI_ACC2X2_EN_INT1_PAD_FLAT__REG SMI_ACC2X2_INT1_PAD_SEL_REG
+
+#define SMI_ACC2X2_EN_INT2_PAD_LOWG__POS 0
+#define SMI_ACC2X2_EN_INT2_PAD_LOWG__LEN 1
+#define SMI_ACC2X2_EN_INT2_PAD_LOWG__MSK 0x01
+#define SMI_ACC2X2_EN_INT2_PAD_LOWG__REG SMI_ACC2X2_INT2_PAD_SEL_REG
+
+#define SMI_ACC2X2_EN_INT2_PAD_HIGHG__POS 1
+#define SMI_ACC2X2_EN_INT2_PAD_HIGHG__LEN 1
+#define SMI_ACC2X2_EN_INT2_PAD_HIGHG__MSK 0x02
+#define SMI_ACC2X2_EN_INT2_PAD_HIGHG__REG SMI_ACC2X2_INT2_PAD_SEL_REG
+
+#define SMI_ACC2X2_EN_INT2_PAD_SLOPE__POS 2
+#define SMI_ACC2X2_EN_INT2_PAD_SLOPE__LEN 1
+#define SMI_ACC2X2_EN_INT2_PAD_SLOPE__MSK 0x04
+#define SMI_ACC2X2_EN_INT2_PAD_SLOPE__REG SMI_ACC2X2_INT2_PAD_SEL_REG
+
+#define SMI_ACC2X2_EN_INT2_PAD_SLO_NO_MOT__POS 3
+#define SMI_ACC2X2_EN_INT2_PAD_SLO_NO_MOT__LEN 1
+#define SMI_ACC2X2_EN_INT2_PAD_SLO_NO_MOT__MSK 0x08
+#define SMI_ACC2X2_EN_INT2_PAD_SLO_NO_MOT__REG SMI_ACC2X2_INT2_PAD_SEL_REG
+
+#define SMI_ACC2X2_EN_INT2_PAD_DB_TAP__POS 4
+#define SMI_ACC2X2_EN_INT2_PAD_DB_TAP__LEN 1
+#define SMI_ACC2X2_EN_INT2_PAD_DB_TAP__MSK 0x10
+#define SMI_ACC2X2_EN_INT2_PAD_DB_TAP__REG SMI_ACC2X2_INT2_PAD_SEL_REG
+
+#define SMI_ACC2X2_EN_INT2_PAD_SNG_TAP__POS 5
+#define SMI_ACC2X2_EN_INT2_PAD_SNG_TAP__LEN 1
+#define SMI_ACC2X2_EN_INT2_PAD_SNG_TAP__MSK 0x20
+#define SMI_ACC2X2_EN_INT2_PAD_SNG_TAP__REG SMI_ACC2X2_INT2_PAD_SEL_REG
+
+#define SMI_ACC2X2_EN_INT2_PAD_ORIENT__POS 6
+#define SMI_ACC2X2_EN_INT2_PAD_ORIENT__LEN 1
+#define SMI_ACC2X2_EN_INT2_PAD_ORIENT__MSK 0x40
+#define SMI_ACC2X2_EN_INT2_PAD_ORIENT__REG SMI_ACC2X2_INT2_PAD_SEL_REG
+
+#define SMI_ACC2X2_EN_INT2_PAD_FLAT__POS 7
+#define SMI_ACC2X2_EN_INT2_PAD_FLAT__LEN 1
+#define SMI_ACC2X2_EN_INT2_PAD_FLAT__MSK 0x80
+#define SMI_ACC2X2_EN_INT2_PAD_FLAT__REG SMI_ACC2X2_INT2_PAD_SEL_REG
+
+#define SMI_ACC2X2_EN_INT1_PAD_NEWDATA__POS 0
+#define SMI_ACC2X2_EN_INT1_PAD_NEWDATA__LEN 1
+#define SMI_ACC2X2_EN_INT1_PAD_NEWDATA__MSK 0x01
+#define SMI_ACC2X2_EN_INT1_PAD_NEWDATA__REG SMI_ACC2X2_INT_DATA_SEL_REG
+
+#define SMI_ACC2X2_EN_INT1_PAD_FWM__POS 1
+#define SMI_ACC2X2_EN_INT1_PAD_FWM__LEN 1
+#define SMI_ACC2X2_EN_INT1_PAD_FWM__MSK 0x02
+#define SMI_ACC2X2_EN_INT1_PAD_FWM__REG SMI_ACC2X2_INT_DATA_SEL_REG
+
+#define SMI_ACC2X2_EN_INT1_PAD_FFULL__POS 2
+#define SMI_ACC2X2_EN_INT1_PAD_FFULL__LEN 1
+#define SMI_ACC2X2_EN_INT1_PAD_FFULL__MSK 0x04
+#define SMI_ACC2X2_EN_INT1_PAD_FFULL__REG SMI_ACC2X2_INT_DATA_SEL_REG
+
+#define SMI_ACC2X2_EN_INT2_PAD_FFULL__POS 5
+#define SMI_ACC2X2_EN_INT2_PAD_FFULL__LEN 1
+#define SMI_ACC2X2_EN_INT2_PAD_FFULL__MSK 0x20
+#define SMI_ACC2X2_EN_INT2_PAD_FFULL__REG SMI_ACC2X2_INT_DATA_SEL_REG
+
+#define SMI_ACC2X2_EN_INT2_PAD_FWM__POS 6
+#define SMI_ACC2X2_EN_INT2_PAD_FWM__LEN 1
+#define SMI_ACC2X2_EN_INT2_PAD_FWM__MSK 0x40
+#define SMI_ACC2X2_EN_INT2_PAD_FWM__REG SMI_ACC2X2_INT_DATA_SEL_REG
+
+#define SMI_ACC2X2_EN_INT2_PAD_NEWDATA__POS 7
+#define SMI_ACC2X2_EN_INT2_PAD_NEWDATA__LEN 1
+#define SMI_ACC2X2_EN_INT2_PAD_NEWDATA__MSK 0x80
+#define SMI_ACC2X2_EN_INT2_PAD_NEWDATA__REG SMI_ACC2X2_INT_DATA_SEL_REG
+
+#define SMI_ACC2X2_UNFILT_INT_SRC_LOWG__POS 0
+#define SMI_ACC2X2_UNFILT_INT_SRC_LOWG__LEN 1
+#define SMI_ACC2X2_UNFILT_INT_SRC_LOWG__MSK 0x01
+#define SMI_ACC2X2_UNFILT_INT_SRC_LOWG__REG SMI_ACC2X2_INT_SRC_REG
+
+#define SMI_ACC2X2_UNFILT_INT_SRC_HIGHG__POS 1
+#define SMI_ACC2X2_UNFILT_INT_SRC_HIGHG__LEN 1
+#define SMI_ACC2X2_UNFILT_INT_SRC_HIGHG__MSK 0x02
+#define SMI_ACC2X2_UNFILT_INT_SRC_HIGHG__REG SMI_ACC2X2_INT_SRC_REG
+
+#define SMI_ACC2X2_UNFILT_INT_SRC_SLOPE__POS 2
+#define SMI_ACC2X2_UNFILT_INT_SRC_SLOPE__LEN 1
+#define SMI_ACC2X2_UNFILT_INT_SRC_SLOPE__MSK 0x04
+#define SMI_ACC2X2_UNFILT_INT_SRC_SLOPE__REG SMI_ACC2X2_INT_SRC_REG
+
+#define SMI_ACC2X2_UNFILT_INT_SRC_SLO_NO_MOT__POS 3
+#define SMI_ACC2X2_UNFILT_INT_SRC_SLO_NO_MOT__LEN 1
+#define SMI_ACC2X2_UNFILT_INT_SRC_SLO_NO_MOT__MSK 0x08
+#define SMI_ACC2X2_UNFILT_INT_SRC_SLO_NO_MOT__REG SMI_ACC2X2_INT_SRC_REG
+
+#define SMI_ACC2X2_UNFILT_INT_SRC_TAP__POS 4
+#define SMI_ACC2X2_UNFILT_INT_SRC_TAP__LEN 1
+#define SMI_ACC2X2_UNFILT_INT_SRC_TAP__MSK 0x10
+#define SMI_ACC2X2_UNFILT_INT_SRC_TAP__REG SMI_ACC2X2_INT_SRC_REG
+
+#define SMI_ACC2X2_UNFILT_INT_SRC_DATA__POS 5
+#define SMI_ACC2X2_UNFILT_INT_SRC_DATA__LEN 1
+#define SMI_ACC2X2_UNFILT_INT_SRC_DATA__MSK 0x20
+#define SMI_ACC2X2_UNFILT_INT_SRC_DATA__REG SMI_ACC2X2_INT_SRC_REG
+
+#define SMI_ACC2X2_INT1_PAD_ACTIVE_LEVEL__POS 0
+#define SMI_ACC2X2_INT1_PAD_ACTIVE_LEVEL__LEN 1
+#define SMI_ACC2X2_INT1_PAD_ACTIVE_LEVEL__MSK 0x01
+#define SMI_ACC2X2_INT1_PAD_ACTIVE_LEVEL__REG SMI_ACC2X2_INT_SET_REG
+
+#define SMI_ACC2X2_INT2_PAD_ACTIVE_LEVEL__POS 2
+#define SMI_ACC2X2_INT2_PAD_ACTIVE_LEVEL__LEN 1
+#define SMI_ACC2X2_INT2_PAD_ACTIVE_LEVEL__MSK 0x04
+#define SMI_ACC2X2_INT2_PAD_ACTIVE_LEVEL__REG SMI_ACC2X2_INT_SET_REG
+
+#define SMI_ACC2X2_INT1_PAD_OUTPUT_TYPE__POS 1
+#define SMI_ACC2X2_INT1_PAD_OUTPUT_TYPE__LEN 1
+#define SMI_ACC2X2_INT1_PAD_OUTPUT_TYPE__MSK 0x02
+#define SMI_ACC2X2_INT1_PAD_OUTPUT_TYPE__REG SMI_ACC2X2_INT_SET_REG
+
+#define SMI_ACC2X2_INT2_PAD_OUTPUT_TYPE__POS 3
+#define SMI_ACC2X2_INT2_PAD_OUTPUT_TYPE__LEN 1
+#define SMI_ACC2X2_INT2_PAD_OUTPUT_TYPE__MSK 0x08
+#define SMI_ACC2X2_INT2_PAD_OUTPUT_TYPE__REG SMI_ACC2X2_INT_SET_REG
+
+#define SMI_ACC2X2_INT_MODE_SEL__POS 0
+#define SMI_ACC2X2_INT_MODE_SEL__LEN 4
+#define SMI_ACC2X2_INT_MODE_SEL__MSK 0x0F
+#define SMI_ACC2X2_INT_MODE_SEL__REG SMI_ACC2X2_INT_CTRL_REG
+
+#define SMI_ACC2X2_RESET_INT__POS 7
+#define SMI_ACC2X2_RESET_INT__LEN 1
+#define SMI_ACC2X2_RESET_INT__MSK 0x80
+#define SMI_ACC2X2_RESET_INT__REG SMI_ACC2X2_INT_CTRL_REG
+
+#define SMI_ACC2X2_LOWG_DUR__POS 0
+#define SMI_ACC2X2_LOWG_DUR__LEN 8
+#define SMI_ACC2X2_LOWG_DUR__MSK 0xFF
+#define SMI_ACC2X2_LOWG_DUR__REG SMI_ACC2X2_LOW_DURN_REG
+
+#define SMI_ACC2X2_LOWG_THRES__POS 0
+#define SMI_ACC2X2_LOWG_THRES__LEN 8
+#define SMI_ACC2X2_LOWG_THRES__MSK 0xFF
+#define SMI_ACC2X2_LOWG_THRES__REG SMI_ACC2X2_LOW_THRES_REG
+
+#define SMI_ACC2X2_LOWG_HYST__POS 0
+#define SMI_ACC2X2_LOWG_HYST__LEN 2
+#define SMI_ACC2X2_LOWG_HYST__MSK 0x03
+#define SMI_ACC2X2_LOWG_HYST__REG SMI_ACC2X2_LOW_HIGH_HYST_REG
+
+#define SMI_ACC2X2_LOWG_INT_MODE__POS 2
+#define SMI_ACC2X2_LOWG_INT_MODE__LEN 1
+#define SMI_ACC2X2_LOWG_INT_MODE__MSK 0x04
+#define SMI_ACC2X2_LOWG_INT_MODE__REG SMI_ACC2X2_LOW_HIGH_HYST_REG
+
+#define SMI_ACC2X2_HIGHG_DUR__POS 0
+#define SMI_ACC2X2_HIGHG_DUR__LEN 8
+#define SMI_ACC2X2_HIGHG_DUR__MSK 0xFF
+#define SMI_ACC2X2_HIGHG_DUR__REG SMI_ACC2X2_HIGH_DURN_REG
+
+#define SMI_ACC2X2_HIGHG_THRES__POS 0
+#define SMI_ACC2X2_HIGHG_THRES__LEN 8
+#define SMI_ACC2X2_HIGHG_THRES__MSK 0xFF
+#define SMI_ACC2X2_HIGHG_THRES__REG SMI_ACC2X2_HIGH_THRES_REG
+
+#define SMI_ACC2X2_HIGHG_HYST__POS 6
+#define SMI_ACC2X2_HIGHG_HYST__LEN 2
+#define SMI_ACC2X2_HIGHG_HYST__MSK 0xC0
+#define SMI_ACC2X2_HIGHG_HYST__REG SMI_ACC2X2_LOW_HIGH_HYST_REG
+
+#define SMI_ACC2X2_SLOPE_DUR__POS 0
+#define SMI_ACC2X2_SLOPE_DUR__LEN 2
+#define SMI_ACC2X2_SLOPE_DUR__MSK 0x03
+#define SMI_ACC2X2_SLOPE_DUR__REG SMI_ACC2X2_SLOPE_DURN_REG
+
+#define SMI_ACC2X2_SLO_NO_MOT_DUR__POS 2
+#define SMI_ACC2X2_SLO_NO_MOT_DUR__LEN 6
+#define SMI_ACC2X2_SLO_NO_MOT_DUR__MSK 0xFC
+#define SMI_ACC2X2_SLO_NO_MOT_DUR__REG SMI_ACC2X2_SLOPE_DURN_REG
+
+#define SMI_ACC2X2_SLOPE_THRES__POS 0
+#define SMI_ACC2X2_SLOPE_THRES__LEN 8
+#define SMI_ACC2X2_SLOPE_THRES__MSK 0xFF
+#define SMI_ACC2X2_SLOPE_THRES__REG SMI_ACC2X2_SLOPE_THRES_REG
+
+#define SMI_ACC2X2_SLO_NO_MOT_THRES__POS 0
+#define SMI_ACC2X2_SLO_NO_MOT_THRES__LEN 8
+#define SMI_ACC2X2_SLO_NO_MOT_THRES__MSK 0xFF
+#define SMI_ACC2X2_SLO_NO_MOT_THRES__REG SMI_ACC2X2_SLO_NO_MOT_THRES_REG
+
+#define SMI_ACC2X2_TAP_DUR__POS 0
+#define SMI_ACC2X2_TAP_DUR__LEN 3
+#define SMI_ACC2X2_TAP_DUR__MSK 0x07
+#define SMI_ACC2X2_TAP_DUR__REG SMI_ACC2X2_TAP_PARAM_REG
+
+#define SMI_ACC2X2_TAP_SHOCK_DURN__POS 6
+#define SMI_ACC2X2_TAP_SHOCK_DURN__LEN 1
+#define SMI_ACC2X2_TAP_SHOCK_DURN__MSK 0x40
+#define SMI_ACC2X2_TAP_SHOCK_DURN__REG SMI_ACC2X2_TAP_PARAM_REG
+
+#define SMI_ACC2X2_ADV_TAP_INT__POS 5
+#define SMI_ACC2X2_ADV_TAP_INT__LEN 1
+#define SMI_ACC2X2_ADV_TAP_INT__MSK 0x20
+#define SMI_ACC2X2_ADV_TAP_INT__REG SMI_ACC2X2_TAP_PARAM_REG
+
+#define SMI_ACC2X2_TAP_QUIET_DURN__POS 7
+#define SMI_ACC2X2_TAP_QUIET_DURN__LEN 1
+#define SMI_ACC2X2_TAP_QUIET_DURN__MSK 0x80
+#define SMI_ACC2X2_TAP_QUIET_DURN__REG SMI_ACC2X2_TAP_PARAM_REG
+
+#define SMI_ACC2X2_TAP_THRES__POS 0
+#define SMI_ACC2X2_TAP_THRES__LEN 5
+#define SMI_ACC2X2_TAP_THRES__MSK 0x1F
+#define SMI_ACC2X2_TAP_THRES__REG SMI_ACC2X2_TAP_THRES_REG
+
+#define SMI_ACC2X2_TAP_SAMPLES__POS 6
+#define SMI_ACC2X2_TAP_SAMPLES__LEN 2
+#define SMI_ACC2X2_TAP_SAMPLES__MSK 0xC0
+#define SMI_ACC2X2_TAP_SAMPLES__REG SMI_ACC2X2_TAP_THRES_REG
+
+#define SMI_ACC2X2_ORIENT_MODE__POS 0
+#define SMI_ACC2X2_ORIENT_MODE__LEN 2
+#define SMI_ACC2X2_ORIENT_MODE__MSK 0x03
+#define SMI_ACC2X2_ORIENT_MODE__REG SMI_ACC2X2_ORIENT_PARAM_REG
+
+#define SMI_ACC2X2_ORIENT_BLOCK__POS 2
+#define SMI_ACC2X2_ORIENT_BLOCK__LEN 2
+#define SMI_ACC2X2_ORIENT_BLOCK__MSK 0x0C
+#define SMI_ACC2X2_ORIENT_BLOCK__REG SMI_ACC2X2_ORIENT_PARAM_REG
+
+#define SMI_ACC2X2_ORIENT_HYST__POS 4
+#define SMI_ACC2X2_ORIENT_HYST__LEN 3
+#define SMI_ACC2X2_ORIENT_HYST__MSK 0x70
+#define SMI_ACC2X2_ORIENT_HYST__REG SMI_ACC2X2_ORIENT_PARAM_REG
+
+#define SMI_ACC2X2_ORIENT_AXIS__POS 7
+#define SMI_ACC2X2_ORIENT_AXIS__LEN 1
+#define SMI_ACC2X2_ORIENT_AXIS__MSK 0x80
+#define SMI_ACC2X2_ORIENT_AXIS__REG SMI_ACC2X2_THETA_BLOCK_REG
+
+#define SMI_ACC2X2_ORIENT_UD_EN__POS 6
+#define SMI_ACC2X2_ORIENT_UD_EN__LEN 1
+#define SMI_ACC2X2_ORIENT_UD_EN__MSK 0x40
+#define SMI_ACC2X2_ORIENT_UD_EN__REG SMI_ACC2X2_THETA_BLOCK_REG
+
+#define SMI_ACC2X2_THETA_BLOCK__POS 0
+#define SMI_ACC2X2_THETA_BLOCK__LEN 6
+#define SMI_ACC2X2_THETA_BLOCK__MSK 0x3F
+#define SMI_ACC2X2_THETA_BLOCK__REG SMI_ACC2X2_THETA_BLOCK_REG
+
+#define SMI_ACC2X2_THETA_FLAT__POS 0
+#define SMI_ACC2X2_THETA_FLAT__LEN 6
+#define SMI_ACC2X2_THETA_FLAT__MSK 0x3F
+#define SMI_ACC2X2_THETA_FLAT__REG SMI_ACC2X2_THETA_FLAT_REG
+
+#define SMI_ACC2X2_FLAT_HOLD_TIME__POS 4
+#define SMI_ACC2X2_FLAT_HOLD_TIME__LEN 2
+#define SMI_ACC2X2_FLAT_HOLD_TIME__MSK 0x30
+#define SMI_ACC2X2_FLAT_HOLD_TIME__REG SMI_ACC2X2_FLAT_HOLD_TIME_REG
+
+#define SMI_ACC2X2_FLAT_HYS__POS 0
+#define SMI_ACC2X2_FLAT_HYS__LEN 3
+#define SMI_ACC2X2_FLAT_HYS__MSK 0x07
+#define SMI_ACC2X2_FLAT_HYS__REG SMI_ACC2X2_FLAT_HOLD_TIME_REG
+
+#define SMI_ACC2X2_FIFO_WML_TRIG_RETAIN__POS 0
+#define SMI_ACC2X2_FIFO_WML_TRIG_RETAIN__LEN 6
+#define SMI_ACC2X2_FIFO_WML_TRIG_RETAIN__MSK 0x3F
+#define SMI_ACC2X2_FIFO_WML_TRIG_RETAIN__REG SMI_ACC2X2_FIFO_WML_TRIG
+
+#define SMI_ACC2X2_EN_SELF_TEST__POS 0
+#define SMI_ACC2X2_EN_SELF_TEST__LEN 2
+#define SMI_ACC2X2_EN_SELF_TEST__MSK 0x03
+#define SMI_ACC2X2_EN_SELF_TEST__REG SMI_ACC2X2_SELF_TEST_REG
+
+#define SMI_ACC2X2_NEG_SELF_TEST__POS 2
+#define SMI_ACC2X2_NEG_SELF_TEST__LEN 1
+#define SMI_ACC2X2_NEG_SELF_TEST__MSK 0x04
+#define SMI_ACC2X2_NEG_SELF_TEST__REG SMI_ACC2X2_SELF_TEST_REG
+
+#define SMI_ACC2X2_SELF_TEST_AMP__POS 4
+#define SMI_ACC2X2_SELF_TEST_AMP__LEN 1
+#define SMI_ACC2X2_SELF_TEST_AMP__MSK 0x10
+#define SMI_ACC2X2_SELF_TEST_AMP__REG SMI_ACC2X2_SELF_TEST_REG
+
+
+#define SMI_ACC2X2_UNLOCK_EE_PROG_MODE__POS 0
+#define SMI_ACC2X2_UNLOCK_EE_PROG_MODE__LEN 1
+#define SMI_ACC2X2_UNLOCK_EE_PROG_MODE__MSK 0x01
+#define SMI_ACC2X2_UNLOCK_EE_PROG_MODE__REG SMI_ACC2X2_EEPROM_CTRL_REG
+
+#define SMI_ACC2X2_START_EE_PROG_TRIG__POS 1
+#define SMI_ACC2X2_START_EE_PROG_TRIG__LEN 1
+#define SMI_ACC2X2_START_EE_PROG_TRIG__MSK 0x02
+#define SMI_ACC2X2_START_EE_PROG_TRIG__REG SMI_ACC2X2_EEPROM_CTRL_REG
+
+#define SMI_ACC2X2_EE_PROG_READY__POS 2
+#define SMI_ACC2X2_EE_PROG_READY__LEN 1
+#define SMI_ACC2X2_EE_PROG_READY__MSK 0x04
+#define SMI_ACC2X2_EE_PROG_READY__REG SMI_ACC2X2_EEPROM_CTRL_REG
+
+#define SMI_ACC2X2_UPDATE_IMAGE__POS 3
+#define SMI_ACC2X2_UPDATE_IMAGE__LEN 1
+#define SMI_ACC2X2_UPDATE_IMAGE__MSK 0x08
+#define SMI_ACC2X2_UPDATE_IMAGE__REG SMI_ACC2X2_EEPROM_CTRL_REG
+
+#define SMI_ACC2X2_EE_REMAIN__POS 4
+#define SMI_ACC2X2_EE_REMAIN__LEN 4
+#define SMI_ACC2X2_EE_REMAIN__MSK 0xF0
+#define SMI_ACC2X2_EE_REMAIN__REG SMI_ACC2X2_EEPROM_CTRL_REG
+
+#define SMI_ACC2X2_EN_SPI_MODE_3__POS 0
+#define SMI_ACC2X2_EN_SPI_MODE_3__LEN 1
+#define SMI_ACC2X2_EN_SPI_MODE_3__MSK 0x01
+#define SMI_ACC2X2_EN_SPI_MODE_3__REG SMI_ACC2X2_SERIAL_CTRL_REG
+
+#define SMI_ACC2X2_I2C_WATCHDOG_PERIOD__POS 1
+#define SMI_ACC2X2_I2C_WATCHDOG_PERIOD__LEN 1
+#define SMI_ACC2X2_I2C_WATCHDOG_PERIOD__MSK 0x02
+#define SMI_ACC2X2_I2C_WATCHDOG_PERIOD__REG SMI_ACC2X2_SERIAL_CTRL_REG
+
+#define SMI_ACC2X2_EN_I2C_WATCHDOG__POS 2
+#define SMI_ACC2X2_EN_I2C_WATCHDOG__LEN 1
+#define SMI_ACC2X2_EN_I2C_WATCHDOG__MSK 0x04
+#define SMI_ACC2X2_EN_I2C_WATCHDOG__REG SMI_ACC2X2_SERIAL_CTRL_REG
+
+#define SMI_ACC2X2_EXT_MODE__POS 7
+#define SMI_ACC2X2_EXT_MODE__LEN 1
+#define SMI_ACC2X2_EXT_MODE__MSK 0x80
+#define SMI_ACC2X2_EXT_MODE__REG SMI_ACC2X2_EXTMODE_CTRL_REG
+
+#define SMI_ACC2X2_ALLOW_UPPER__POS 6
+#define SMI_ACC2X2_ALLOW_UPPER__LEN 1
+#define SMI_ACC2X2_ALLOW_UPPER__MSK 0x40
+#define SMI_ACC2X2_ALLOW_UPPER__REG SMI_ACC2X2_EXTMODE_CTRL_REG
+
+#define SMI_ACC2X2_MAP_2_LOWER__POS 5
+#define SMI_ACC2X2_MAP_2_LOWER__LEN 1
+#define SMI_ACC2X2_MAP_2_LOWER__MSK 0x20
+#define SMI_ACC2X2_MAP_2_LOWER__REG SMI_ACC2X2_EXTMODE_CTRL_REG
+
+#define SMI_ACC2X2_MAGIC_NUMBER__POS 0
+#define SMI_ACC2X2_MAGIC_NUMBER__LEN 5
+#define SMI_ACC2X2_MAGIC_NUMBER__MSK 0x1F
+#define SMI_ACC2X2_MAGIC_NUMBER__REG SMI_ACC2X2_EXTMODE_CTRL_REG
+
+#define SMI_ACC2X2_UNLOCK_EE_WRITE_TRIM__POS 4
+#define SMI_ACC2X2_UNLOCK_EE_WRITE_TRIM__LEN 4
+#define SMI_ACC2X2_UNLOCK_EE_WRITE_TRIM__MSK 0xF0
+#define SMI_ACC2X2_UNLOCK_EE_WRITE_TRIM__REG SMI_ACC2X2_CTRL_UNLOCK_REG
+
+#define SMI_ACC2X2_EN_SLOW_COMP_X__POS 0
+#define SMI_ACC2X2_EN_SLOW_COMP_X__LEN 1
+#define SMI_ACC2X2_EN_SLOW_COMP_X__MSK 0x01
+#define SMI_ACC2X2_EN_SLOW_COMP_X__REG SMI_ACC2X2_OFFSET_CTRL_REG
+
+#define SMI_ACC2X2_EN_SLOW_COMP_Y__POS 1
+#define SMI_ACC2X2_EN_SLOW_COMP_Y__LEN 1
+#define SMI_ACC2X2_EN_SLOW_COMP_Y__MSK 0x02
+#define SMI_ACC2X2_EN_SLOW_COMP_Y__REG SMI_ACC2X2_OFFSET_CTRL_REG
+
+#define SMI_ACC2X2_EN_SLOW_COMP_Z__POS 2
+#define SMI_ACC2X2_EN_SLOW_COMP_Z__LEN 1
+#define SMI_ACC2X2_EN_SLOW_COMP_Z__MSK 0x04
+#define SMI_ACC2X2_EN_SLOW_COMP_Z__REG SMI_ACC2X2_OFFSET_CTRL_REG
+
+#define SMI_ACC2X2_FAST_CAL_RDY_S__POS 4
+#define SMI_ACC2X2_FAST_CAL_RDY_S__LEN 1
+#define SMI_ACC2X2_FAST_CAL_RDY_S__MSK 0x10
+#define SMI_ACC2X2_FAST_CAL_RDY_S__REG SMI_ACC2X2_OFFSET_CTRL_REG
+
+#define SMI_ACC2X2_CAL_TRIGGER__POS 5
+#define SMI_ACC2X2_CAL_TRIGGER__LEN 2
+#define SMI_ACC2X2_CAL_TRIGGER__MSK 0x60
+#define SMI_ACC2X2_CAL_TRIGGER__REG SMI_ACC2X2_OFFSET_CTRL_REG
+
+#define SMI_ACC2X2_RESET_OFFSET_REGS__POS 7
+#define SMI_ACC2X2_RESET_OFFSET_REGS__LEN 1
+#define SMI_ACC2X2_RESET_OFFSET_REGS__MSK 0x80
+#define SMI_ACC2X2_RESET_OFFSET_REGS__REG SMI_ACC2X2_OFFSET_CTRL_REG
+
+#define SMI_ACC2X2_COMP_CUTOFF__POS 0
+#define SMI_ACC2X2_COMP_CUTOFF__LEN 1
+#define SMI_ACC2X2_COMP_CUTOFF__MSK 0x01
+#define SMI_ACC2X2_COMP_CUTOFF__REG SMI_ACC2X2_OFFSET_PARAMS_REG
+
+#define SMI_ACC2X2_COMP_TARGET_OFFSET_X__POS 1
+#define SMI_ACC2X2_COMP_TARGET_OFFSET_X__LEN 2
+#define SMI_ACC2X2_COMP_TARGET_OFFSET_X__MSK 0x06
+#define SMI_ACC2X2_COMP_TARGET_OFFSET_X__REG SMI_ACC2X2_OFFSET_PARAMS_REG
+
+#define SMI_ACC2X2_COMP_TARGET_OFFSET_Y__POS 3
+#define SMI_ACC2X2_COMP_TARGET_OFFSET_Y__LEN 2
+#define SMI_ACC2X2_COMP_TARGET_OFFSET_Y__MSK 0x18
+#define SMI_ACC2X2_COMP_TARGET_OFFSET_Y__REG SMI_ACC2X2_OFFSET_PARAMS_REG
+
+#define SMI_ACC2X2_COMP_TARGET_OFFSET_Z__POS 5
+#define SMI_ACC2X2_COMP_TARGET_OFFSET_Z__LEN 2
+#define SMI_ACC2X2_COMP_TARGET_OFFSET_Z__MSK 0x60
+#define SMI_ACC2X2_COMP_TARGET_OFFSET_Z__REG SMI_ACC2X2_OFFSET_PARAMS_REG
+
+#define SMI_ACC2X2_FIFO_DATA_SELECT__POS 0
+#define SMI_ACC2X2_FIFO_DATA_SELECT__LEN 2
+#define SMI_ACC2X2_FIFO_DATA_SELECT__MSK 0x03
+#define SMI_ACC2X2_FIFO_DATA_SELECT__REG SMI_ACC2X2_FIFO_MODE_REG
+
+#define SMI_ACC2X2_FIFO_TRIGGER_SOURCE__POS 2
+#define SMI_ACC2X2_FIFO_TRIGGER_SOURCE__LEN 2
+#define SMI_ACC2X2_FIFO_TRIGGER_SOURCE__MSK 0x0C
+#define SMI_ACC2X2_FIFO_TRIGGER_SOURCE__REG SMI_ACC2X2_FIFO_MODE_REG
+
+#define SMI_ACC2X2_FIFO_TRIGGER_ACTION__POS 4
+#define SMI_ACC2X2_FIFO_TRIGGER_ACTION__LEN 2
+#define SMI_ACC2X2_FIFO_TRIGGER_ACTION__MSK 0x30
+#define SMI_ACC2X2_FIFO_TRIGGER_ACTION__REG SMI_ACC2X2_FIFO_MODE_REG
+
+#define SMI_ACC2X2_FIFO_MODE__POS 6
+#define SMI_ACC2X2_FIFO_MODE__LEN 2
+#define SMI_ACC2X2_FIFO_MODE__MSK 0xC0
+#define SMI_ACC2X2_FIFO_MODE__REG SMI_ACC2X2_FIFO_MODE_REG
+
+
+#define SMI_ACC2X2_STATUS1 0
+#define SMI_ACC2X2_STATUS2 1
+#define SMI_ACC2X2_STATUS3 2
+#define SMI_ACC2X2_STATUS4 3
+#define SMI_ACC2X2_STATUS5 4
+
+
+#define SMI_ACC2X2_RANGE_2G 3
+#define SMI_ACC2X2_RANGE_4G 5
+#define SMI_ACC2X2_RANGE_8G 8
+#define SMI_ACC2X2_RANGE_16G 12
+
+
+#define SMI_ACC2X2_BW_7_81HZ 0x08
+#define SMI_ACC2X2_BW_15_63HZ 0x09
+#define SMI_ACC2X2_BW_31_25HZ 0x0A
+#define SMI_ACC2X2_BW_62_50HZ 0x0B
+#define SMI_ACC2X2_BW_125HZ 0x0C
+#define SMI_ACC2X2_BW_250HZ 0x0D
+#define SMI_ACC2X2_BW_500HZ 0x0E
+#define SMI_ACC2X2_BW_1000HZ 0x0F
+
+#define SMI_ACC2X2_SLEEP_DUR_0_5MS 0x05
+#define SMI_ACC2X2_SLEEP_DUR_1MS 0x06
+#define SMI_ACC2X2_SLEEP_DUR_2MS 0x07
+#define SMI_ACC2X2_SLEEP_DUR_4MS 0x08
+#define SMI_ACC2X2_SLEEP_DUR_6MS 0x09
+#define SMI_ACC2X2_SLEEP_DUR_10MS 0x0A
+#define SMI_ACC2X2_SLEEP_DUR_25MS 0x0B
+#define SMI_ACC2X2_SLEEP_DUR_50MS 0x0C
+#define SMI_ACC2X2_SLEEP_DUR_100MS 0x0D
+#define SMI_ACC2X2_SLEEP_DUR_500MS 0x0E
+#define SMI_ACC2X2_SLEEP_DUR_1S 0x0F
+
+#define SMI_ACC2X2_LATCH_DUR_NON_LATCH 0x00
+#define SMI_ACC2X2_LATCH_DUR_250MS 0x01
+#define SMI_ACC2X2_LATCH_DUR_500MS 0x02
+#define SMI_ACC2X2_LATCH_DUR_1S 0x03
+#define SMI_ACC2X2_LATCH_DUR_2S 0x04
+#define SMI_ACC2X2_LATCH_DUR_4S 0x05
+#define SMI_ACC2X2_LATCH_DUR_8S 0x06
+#define SMI_ACC2X2_LATCH_DUR_LATCH 0x07
+#define SMI_ACC2X2_LATCH_DUR_NON_LATCH1 0x08
+#define SMI_ACC2X2_LATCH_DUR_250US 0x09
+#define SMI_ACC2X2_LATCH_DUR_500US 0x0A
+#define SMI_ACC2X2_LATCH_DUR_1MS 0x0B
+#define SMI_ACC2X2_LATCH_DUR_12_5MS 0x0C
+#define SMI_ACC2X2_LATCH_DUR_25MS 0x0D
+#define SMI_ACC2X2_LATCH_DUR_50MS 0x0E
+#define SMI_ACC2X2_LATCH_DUR_LATCH1 0x0F
+
+#define SMI_ACC2X2_MODE_NORMAL 0
+#define SMI_ACC2X2_MODE_LOWPOWER1 1
+#define SMI_ACC2X2_MODE_SUSPEND 2
+#define SMI_ACC2X2_MODE_DEEP_SUSPEND 3
+#define SMI_ACC2X2_MODE_LOWPOWER2 4
+#define SMI_ACC2X2_MODE_STANDBY 5
+
+#define SMI_ACC2X2_X_AXIS 0
+#define SMI_ACC2X2_Y_AXIS 1
+#define SMI_ACC2X2_Z_AXIS 2
+
+#define SMI_ACC2X2_Low_G_Interrupt 0
+#define SMI_ACC2X2_High_G_X_Interrupt 1
+#define SMI_ACC2X2_High_G_Y_Interrupt 2
+#define SMI_ACC2X2_High_G_Z_Interrupt 3
+#define SMI_ACC2X2_DATA_EN 4
+#define SMI_ACC2X2_Slope_X_Interrupt 5
+#define SMI_ACC2X2_Slope_Y_Interrupt 6
+#define SMI_ACC2X2_Slope_Z_Interrupt 7
+#define SMI_ACC2X2_Single_Tap_Interrupt 8
+#define SMI_ACC2X2_Double_Tap_Interrupt 9
+#define SMI_ACC2X2_Orient_Interrupt 10
+#define SMI_ACC2X2_Flat_Interrupt 11
+#define SMI_ACC2X2_FFULL_INTERRUPT 12
+#define SMI_ACC2X2_FWM_INTERRUPT 13
+
+#define SMI_ACC2X2_INT1_LOWG 0
+#define SMI_ACC2X2_INT2_LOWG 1
+#define SMI_ACC2X2_INT1_HIGHG 0
+#define SMI_ACC2X2_INT2_HIGHG 1
+#define SMI_ACC2X2_INT1_SLOPE 0
+#define SMI_ACC2X2_INT2_SLOPE 1
+#define SMI_ACC2X2_INT1_SLO_NO_MOT 0
+#define SMI_ACC2X2_INT2_SLO_NO_MOT 1
+#define SMI_ACC2X2_INT1_DTAP 0
+#define SMI_ACC2X2_INT2_DTAP 1
+#define SMI_ACC2X2_INT1_STAP 0
+#define SMI_ACC2X2_INT2_STAP 1
+#define SMI_ACC2X2_INT1_ORIENT 0
+#define SMI_ACC2X2_INT2_ORIENT 1
+#define SMI_ACC2X2_INT1_FLAT 0
+#define SMI_ACC2X2_INT2_FLAT 1
+#define SMI_ACC2X2_INT1_NDATA 0
+#define SMI_ACC2X2_INT2_NDATA 1
+#define SMI_ACC2X2_INT1_FWM 0
+#define SMI_ACC2X2_INT2_FWM 1
+#define SMI_ACC2X2_INT1_FFULL 0
+#define SMI_ACC2X2_INT2_FFULL 1
+
+#define SMI_ACC2X2_SRC_LOWG 0
+#define SMI_ACC2X2_SRC_HIGHG 1
+#define SMI_ACC2X2_SRC_SLOPE 2
+#define SMI_ACC2X2_SRC_SLO_NO_MOT 3
+#define SMI_ACC2X2_SRC_TAP 4
+#define SMI_ACC2X2_SRC_DATA 5
+
+#define SMI_ACC2X2_INT1_OUTPUT 0
+#define SMI_ACC2X2_INT2_OUTPUT 1
+#define SMI_ACC2X2_INT1_LEVEL 0
+#define SMI_ACC2X2_INT2_LEVEL 1
+
+#define SMI_ACC2X2_LOW_DURATION 0
+#define SMI_ACC2X2_HIGH_DURATION 1
+#define SMI_ACC2X2_SLOPE_DURATION 2
+#define SMI_ACC2X2_SLO_NO_MOT_DURATION 3
+
+#define SMI_ACC2X2_LOW_THRESHOLD 0
+#define SMI_ACC2X2_HIGH_THRESHOLD 1
+#define SMI_ACC2X2_SLOPE_THRESHOLD 2
+#define SMI_ACC2X2_SLO_NO_MOT_THRESHOLD 3
+
+
+#define SMI_ACC2X2_LOWG_HYST 0
+#define SMI_ACC2X2_HIGHG_HYST 1
+
+#define SMI_ACC2X2_ORIENT_THETA 0
+#define SMI_ACC2X2_FLAT_THETA 1
+
+#define SMI_ACC2X2_I2C_SELECT 0
+#define SMI_ACC2X2_I2C_EN 1
+
+#define SMI_ACC2X2_SLOW_COMP_X 0
+#define SMI_ACC2X2_SLOW_COMP_Y 1
+#define SMI_ACC2X2_SLOW_COMP_Z 2
+
+#define SMI_ACC2X2_CUT_OFF 0
+#define SMI_ACC2X2_OFFSET_TRIGGER_X 1
+#define SMI_ACC2X2_OFFSET_TRIGGER_Y 2
+#define SMI_ACC2X2_OFFSET_TRIGGER_Z 3
+
+#define SMI_ACC2X2_GP0 0
+#define SMI_ACC2X2_GP1 1
+
+#define SMI_ACC2X2_SLO_NO_MOT_EN_X 0
+#define SMI_ACC2X2_SLO_NO_MOT_EN_Y 1
+#define SMI_ACC2X2_SLO_NO_MOT_EN_Z 2
+#define SMI_ACC2X2_SLO_NO_MOT_EN_SEL 3
+
+#define SMI_ACC2X2_WAKE_UP_DUR_20MS 0
+#define SMI_ACC2X2_WAKE_UP_DUR_80MS 1
+#define SMI_ACC2X2_WAKE_UP_DUR_320MS 2
+#define SMI_ACC2X2_WAKE_UP_DUR_2560MS 3
+
+#define SMI_ACC2X2_SELF_TEST0_ON 1
+#define SMI_ACC2X2_SELF_TEST1_ON 2
+
+#define SMI_ACC2X2_EE_W_OFF 0
+#define SMI_ACC2X2_EE_W_ON 1
+
+#define SMI_ACC2X2_LOW_TH_IN_G(gthres, range) ((256 * gthres) / range)
+
+
+#define SMI_ACC2X2_HIGH_TH_IN_G(gthres, range) ((256 * gthres) / range)
+
+
+#define SMI_ACC2X2_LOW_HY_IN_G(ghyst, range) ((32 * ghyst) / range)
+
+
+#define SMI_ACC2X2_HIGH_HY_IN_G(ghyst, range) ((32 * ghyst) / range)
+
+
+#define SMI_ACC2X2_SLOPE_TH_IN_G(gthres, range) ((128 * gthres) / range)
+
+
+#define SMI_ACC2X2_GET_BITSLICE(regvar, bitname)\
+ ((regvar & bitname##__MSK) >> bitname##__POS)
+
+
+#define SMI_ACC2X2_SET_BITSLICE(regvar, bitname, val)\
+ ((regvar & ~bitname##__MSK) | ((val<<bitname##__POS)&bitname##__MSK))
+
+#define CHECK_CHIP_ID_TIME_MAX 5
+#define SMI_ACC255_CHIP_ID 0XFA
+#define SMI_ACC250E_CHIP_ID 0XF9
+#define SMI_ACC222E_CHIP_ID 0XF8
+#define SMI_ACC280_CHIP_ID 0XFB
+#define SMI_ACC355_CHIP_ID 0XEA
+
+#define SMI_ACC255_TYPE 0
+#define SMI_ACC250E_TYPE 1
+#define SMI_ACC222E_TYPE 2
+#define SMI_ACC280_TYPE 3
+
+#define MAX_FIFO_F_LEVEL 32
+#define MAX_FIFO_F_BYTES 6
+#define SMI_ACC_MAX_RETRY_I2C_XFER (100)
+
+#ifdef CONFIG_DOUBLE_TAP
+#define DEFAULT_TAP_JUDGE_PERIOD 1000 /* default judge in 1 second */
+#endif
+
+/*! Bosch sensor unknown place*/
+#define BOSCH_SENSOR_PLACE_UNKNOWN (-1)
+/*! Bosch sensor remapping table size P0~P7*/
+#define MAX_AXIS_REMAP_TAB_SZ 8
+
+/* How was SMI_ACC enabled(set to operation mode) */
+#define SMI_ACC_ENABLED_ALL 0
+#define SMI_ACC_ENABLED_SGM 1
+#define SMI_ACC_ENABLED_DTAP 2
+#define SMI_ACC_ENABLED_INPUT 3
+#define SMI_ACC_ENABLED_BSX 4
+
+
+/*!
+ * @brief:BMI058 feature
+ * macro definition
+*/
+
+#define SMI_ACC2X2_FIFO_DAT_SEL_X 1
+#define SMI_ACC2X2_FIFO_DAT_SEL_Y 2
+#define SMI_ACC2X2_FIFO_DAT_SEL_Z 3
+
+#ifdef CONFIG_SENSORS_BMI058
+#define C_BMI058_One_U8X 1
+#define C_BMI058_Two_U8X 2
+#define BMI058_OFFSET_TRIGGER_X SMI_ACC2X2_OFFSET_TRIGGER_Y
+#define BMI058_OFFSET_TRIGGER_Y SMI_ACC2X2_OFFSET_TRIGGER_X
+
+/*! BMI058 X AXIS OFFSET REG definition*/
+#define BMI058_OFFSET_X_AXIS_REG SMI_ACC2X2_OFFSET_Y_AXIS_REG
+/*! BMI058 Y AXIS OFFSET REG definition*/
+#define BMI058_OFFSET_Y_AXIS_REG SMI_ACC2X2_OFFSET_X_AXIS_REG
+
+#define BMI058_FIFO_DAT_SEL_X SMI_ACC2X2_FIFO_DAT_SEL_Y
+#define BMI058_FIFO_DAT_SEL_Y SMI_ACC2X2_FIFO_DAT_SEL_X
+
+/*! SMI130_ACC common slow no motion X interrupt type definition*/
+#define SMI_ACC2X2_SLOW_NO_MOT_X_INT 12
+/*! SMI130_ACC common slow no motion Y interrupt type definition*/
+#define SMI_ACC2X2_SLOW_NO_MOT_Y_INT 13
+/*! SMI130_ACC common High G X interrupt type definition*/
+#define SMI_ACC2X2_HIGHG_X_INT 1
+/*! SMI130_ACC common High G Y interrupt type definition*/
+#define SMI_ACC2X2_HIGHG_Y_INT 2
+/*! SMI130_ACC common slope X interrupt type definition*/
+#define SMI_ACC2X2_SLOPE_X_INT 5
+/*! SMI130_ACC common slope Y interrupt type definition*/
+#define SMI_ACC2X2_SLOPE_Y_INT 6
+
+/*! this structure holds some interrupt types difference
+**between SMI130_ACC and BMI058.
+*/
+struct interrupt_map_t {
+ int x;
+ int y;
+};
+/*!*Need to use SMI130_ACC Common interrupt type definition to
+* instead of Some of BMI058 reversed Interrupt type
+* because of HW Register.
+* The reversed Interrupt types contain:
+* slow_no_mot_x_int && slow_not_mot_y_int
+* highg_x_int && highg_y_int
+* slope_x_int && slope_y_int
+**/
+static const struct interrupt_map_t int_map[] = {
+ {SMI_ACC2X2_SLOW_NO_MOT_X_INT, SMI_ACC2X2_SLOW_NO_MOT_Y_INT},
+ {SMI_ACC2X2_HIGHG_X_INT, SMI_ACC2X2_HIGHG_Y_INT},
+ {SMI_ACC2X2_SLOPE_X_INT, SMI_ACC2X2_SLOPE_Y_INT}
+};
+
+/*! high g or slope interrupt type definition for BMI058*/
+/*! High G interrupt of x, y, z axis happened */
+#define HIGH_G_INTERRUPT_X HIGH_G_INTERRUPT_Y_HAPPENED
+#define HIGH_G_INTERRUPT_Y HIGH_G_INTERRUPT_X_HAPPENED
+#define HIGH_G_INTERRUPT_Z HIGH_G_INTERRUPT_Z_HAPPENED
+/*! High G interrupt of x, y, z negative axis happened */
+#define HIGH_G_INTERRUPT_X_N HIGH_G_INTERRUPT_Y_NEGATIVE_HAPPENED
+#define HIGH_G_INTERRUPT_Y_N HIGH_G_INTERRUPT_X_NEGATIVE_HAPPENED
+#define HIGH_G_INTERRUPT_Z_N HIGH_G_INTERRUPT_Z_NEGATIVE_HAPPENED
+/*! Slope interrupt of x, y, z axis happened */
+#define SLOPE_INTERRUPT_X SLOPE_INTERRUPT_Y_HAPPENED
+#define SLOPE_INTERRUPT_Y SLOPE_INTERRUPT_X_HAPPENED
+#define SLOPE_INTERRUPT_Z SLOPE_INTERRUPT_Z_HAPPENED
+/*! Slope interrupt of x, y, z negative axis happened */
+#define SLOPE_INTERRUPT_X_N SLOPE_INTERRUPT_Y_NEGATIVE_HAPPENED
+#define SLOPE_INTERRUPT_Y_N SLOPE_INTERRUPT_X_NEGATIVE_HAPPENED
+#define SLOPE_INTERRUPT_Z_N SLOPE_INTERRUPT_Z_NEGATIVE_HAPPENED
+
+
+#else
+
+/*! high g or slope interrupt type definition*/
+/*! High G interrupt of x, y, z axis happened */
+#define HIGH_G_INTERRUPT_X HIGH_G_INTERRUPT_X_HAPPENED
+#define HIGH_G_INTERRUPT_Y HIGH_G_INTERRUPT_Y_HAPPENED
+#define HIGH_G_INTERRUPT_Z HIGH_G_INTERRUPT_Z_HAPPENED
+/*! High G interrupt of x, y, z negative axis happened */
+#define HIGH_G_INTERRUPT_X_N HIGH_G_INTERRUPT_X_NEGATIVE_HAPPENED
+#define HIGH_G_INTERRUPT_Y_N HIGH_G_INTERRUPT_Y_NEGATIVE_HAPPENED
+#define HIGH_G_INTERRUPT_Z_N HIGH_G_INTERRUPT_Z_NEGATIVE_HAPPENED
+/*! Slope interrupt of x, y, z axis happened */
+#define SLOPE_INTERRUPT_X SLOPE_INTERRUPT_X_HAPPENED
+#define SLOPE_INTERRUPT_Y SLOPE_INTERRUPT_Y_HAPPENED
+#define SLOPE_INTERRUPT_Z SLOPE_INTERRUPT_Z_HAPPENED
+/*! Slope interrupt of x, y, z negative axis happened */
+#define SLOPE_INTERRUPT_X_N SLOPE_INTERRUPT_X_NEGATIVE_HAPPENED
+#define SLOPE_INTERRUPT_Y_N SLOPE_INTERRUPT_Y_NEGATIVE_HAPPENED
+#define SLOPE_INTERRUPT_Z_N SLOPE_INTERRUPT_Z_NEGATIVE_HAPPENED
+
+
+#endif/*End of CONFIG_SENSORS_BMI058*/
+
+/*! A workaroud mask definition with complete resolution exists
+* aim at writing operation FIFO_CONFIG_1, 0x3E register */
+#define FIFO_WORKAROUNDS_MSK SMI_ACC2X2_FIFO_TRIGGER_SOURCE__MSK
+
+struct smi130_acc_type_map_t {
+
+ /*! smi130_acc sensor chip id */
+ uint16_t chip_id;
+
+ /*! smi130_acc sensor type */
+ uint16_t sensor_type;
+
+ /*! smi130_acc sensor name */
+ const char *sensor_name;
+};
+
+static const struct smi130_acc_type_map_t sensor_type_map[] = {
+
+ {SMI_ACC255_CHIP_ID, SMI_ACC255_TYPE, "SMI_ACC255/254"},
+ {SMI_ACC355_CHIP_ID, SMI_ACC255_TYPE, "SMI_ACC355"},
+ {SMI_ACC250E_CHIP_ID, SMI_ACC250E_TYPE, "SMI_ACC250E"},
+ {SMI_ACC222E_CHIP_ID, SMI_ACC222E_TYPE, "SMI_ACC222E"},
+ {SMI_ACC280_CHIP_ID, SMI_ACC280_TYPE, "SMI_ACC280"},
+
+};
+
+/*!
+* Bst sensor common definition,
+* please give parameters in BSP file.
+*/
+struct bosch_sensor_specific {
+ char *name;
+ /* 0 to 7 */
+ int place;
+ int irq;
+ int (*irq_gpio_cfg)(void);
+};
+
+
+/*!
+ * we use a typedef to hide the detail,
+ * because this type might be changed
+ */
+struct bosch_sensor_axis_remap {
+ /* src means which source will be mapped to target x, y, z axis */
+ /* if an target OS axis is remapped from (-)x,
+ * src is 0, sign_* is (-)1 */
+ /* if an target OS axis is remapped from (-)y,
+ * src is 1, sign_* is (-)1 */
+ /* if an target OS axis is remapped from (-)z,
+ * src is 2, sign_* is (-)1 */
+ int src_x:3;
+ int src_y:3;
+ int src_z:3;
+
+ int sign_x:2;
+ int sign_y:2;
+ int sign_z:2;
+};
+
+struct bosch_sensor_data {
+ union {
+ int16_t v[3];
+ struct {
+ int16_t x;
+ int16_t y;
+ int16_t z;
+ };
+ };
+};
+
+struct smi130_accacc {
+ s16 x;
+ s16 y;
+ s16 z;
+};
+
+struct smi130_acc_data {
+ struct i2c_client *smi130_acc_client;
+ atomic_t delay;
+ atomic_t enable;
+ atomic_t selftest_result;
+ unsigned int chip_id;
+ unsigned int fifo_count;
+ unsigned char fifo_datasel;
+ unsigned char mode;
+ signed char sensor_type;
+ uint64_t timestamp;
+ uint64_t fifo_time;
+ uint64_t base_time;
+ uint64_t acc_count;
+ uint64_t time_odr;
+ uint8_t debug_level;
+ struct work_struct report_data_work;
+ int is_timer_running;
+ struct hrtimer timer;
+ ktime_t work_delay_kt;
+ struct input_dev *input;
+
+ struct bosch_dev *bosch_acc;
+
+ struct smi130_accacc value;
+ struct mutex value_mutex;
+ struct mutex enable_mutex;
+ struct mutex mode_mutex;
+ struct delayed_work work;
+ struct work_struct irq_work;
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ struct early_suspend early_suspend;
+#endif
+ int16_t IRQ;
+ struct bosch_sensor_specific *bosch_pd;
+
+ int smi_acc_mode_enabled;
+ struct input_dev *dev_interrupt;
+
+#ifdef CONFIG_SIG_MOTION
+ struct class *g_sensor_class;
+ struct device *g_sensor_dev;
+
+ /*struct smi_acc250_platform_data *pdata;*/
+ atomic_t en_sig_motion;
+#endif
+
+#ifdef CONFIG_DOUBLE_TAP
+ struct class *g_sensor_class_doubletap;
+ struct device *g_sensor_dev_doubletap;
+ atomic_t en_double_tap;
+ unsigned char tap_times;
+ struct mutex tap_mutex;
+ struct timer_list tap_timer;
+ int tap_time_period;
+#endif
+};
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void smi130_acc_early_suspend(struct early_suspend *h);
+static void smi130_acc_late_resume(struct early_suspend *h);
+#endif
+
+static int smi130_acc_set_mode(struct i2c_client *client,
+ u8 mode, u8 enabled_mode);
+static int smi130_acc_get_mode(struct i2c_client *client, u8 *mode);
+static int smi130_acc_get_fifo_mode(struct i2c_client *client, u8 *fifo_mode);
+static int smi130_acc_set_fifo_mode(struct i2c_client *client, u8 fifo_mode);
+static int smi130_acc_normal_to_suspend(struct smi130_acc_data *smi130_acc,
+ unsigned char data1, unsigned char data2);
+
+static void smi130_acc_delay(u32 msec)
+{
+ if (msec <= 20)
+ usleep_range(msec * 1000, msec * 1000);
+ else
+ msleep(msec);
+}
+/*Remapping for SMI_ACC2X2*/
+static const struct bosch_sensor_axis_remap
+bosch_axis_remap_tab_dft[MAX_AXIS_REMAP_TAB_SZ] = {
+ /* src_x src_y src_z sign_x sign_y sign_z */
+ { 0, 1, 2, 1, 1, 1 }, /* P0 */
+ { 1, 0, 2, 1, -1, 1 }, /* P1 */
+ { 0, 1, 2, -1, -1, 1 }, /* P2 */
+ { 1, 0, 2, -1, 1, 1 }, /* P3 */
+
+ { 0, 1, 2, -1, 1, -1 }, /* P4 */
+ { 1, 0, 2, -1, -1, -1 }, /* P5 */
+ { 0, 1, 2, 1, -1, -1 }, /* P6 */
+ { 1, 0, 2, 1, 1, -1 }, /* P7 */
+};
+
+
+static void bosch_remap_sensor_data(struct bosch_sensor_data *data,
+ const struct bosch_sensor_axis_remap *remap)
+{
+ struct bosch_sensor_data tmp;
+
+ tmp.x = data->v[remap->src_x] * remap->sign_x;
+ tmp.y = data->v[remap->src_y] * remap->sign_y;
+ tmp.z = data->v[remap->src_z] * remap->sign_z;
+
+ memcpy(data, &tmp, sizeof(*data));
+}
+
+
+static void bosch_remap_sensor_data_dft_tab(struct bosch_sensor_data *data,
+ int place)
+{
+ /* sensor with place 0 needs not to be remapped */
+ if ((place <= 0) || (place >= MAX_AXIS_REMAP_TAB_SZ))
+ return;
+
+ bosch_remap_sensor_data(data, &bosch_axis_remap_tab_dft[place]);
+}
+
+static void smi130_acc_remap_sensor_data(struct smi130_accacc *val,
+ struct smi130_acc_data *client_data)
+{
+ struct bosch_sensor_data bsd;
+ int place;
+
+ if ((NULL == client_data->bosch_pd) || (BOSCH_SENSOR_PLACE_UNKNOWN
+ == client_data->bosch_pd->place))
+ place = BOSCH_SENSOR_PLACE_UNKNOWN;
+ else
+ place = client_data->bosch_pd->place;
+
+#ifdef CONFIG_SENSORS_BMI058
+/*x,y need to be invesed becase of HW Register for BMI058*/
+ bsd.y = val->x;
+ bsd.x = val->y;
+ bsd.z = val->z;
+#else
+ bsd.x = val->x;
+ bsd.y = val->y;
+ bsd.z = val->z;
+#endif
+
+ bosch_remap_sensor_data_dft_tab(&bsd, place);
+
+ val->x = bsd.x;
+ val->y = bsd.y;
+ val->z = bsd.z;
+
+}
+
+
+static int smi130_acc_smbus_read_byte(struct i2c_client *client,
+ unsigned char reg_addr, unsigned char *data)
+{
+#if !defined SMI130_ACC_USE_BASIC_I2C_FUNC
+ s32 dummy;
+ int len = 1;
+ if (NULL == client)
+ return -ENODEV;
+
+ while (0 != len--) {
+#ifdef SMI130_ACC_SMBUS
+ dummy = i2c_smbus_read_byte_data(client, reg_addr);
+ if (dummy < 0) {
+ PERR("i2c bus read error");
+ return -EIO;
+ }
+ *data = (u8)(dummy & 0xff);
+#else
+ dummy = i2c_master_send(client, (char *)®_addr, 1);
+ if (dummy < 0)
+ return -EIO;
+
+ dummy = i2c_master_recv(client, (char *)data, 1);
+ if (dummy < 0)
+ return -EIO;
+#endif
+ reg_addr++;
+ data++;
+ }
+ return 0;
+#else
+ int retry;
+ int len = 1;
+ struct i2c_msg msg[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 1,
+ .buf = ®_addr,
+ },
+
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = len,
+ .buf = data,
+ },
+ };
+
+ for (retry = 0; retry < SMI_ACC_MAX_RETRY_I2C_XFER; retry++) {
+ if (i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)) > 0)
+ break;
+ else
+ smi130_acc_delay(1);
+ }
+
+ if (SMI_ACC_MAX_RETRY_I2C_XFER <= retry) {
+ PERR("I2C xfer error");
+ return -EIO;
+ }
+
+ return 0;
+#endif
+}
+
+static int smi130_acc_smbus_write_byte(struct i2c_client *client,
+ unsigned char reg_addr, unsigned char *data)
+{
+#if !defined SMI130_ACC_USE_BASIC_I2C_FUNC
+ s32 dummy;
+ int len = 1;
+#ifndef SMI130_ACC_SMBUS
+ u8 buffer[2];
+#endif
+ if (NULL == client)
+ return -ENODEV;
+
+ while (0 != len--) {
+#ifdef SMI130_ACC_SMBUS
+ dummy = i2c_smbus_write_byte_data(client, reg_addr, *data);
+#else
+ buffer[0] = reg_addr;
+ buffer[1] = *data;
+ dummy = i2c_master_send(client, (char *)buffer, 2);
+#endif
+ reg_addr++;
+ data++;
+ if (dummy < 0) {
+ PERR("error writing i2c bus");
+ return -EIO;
+ }
+
+ }
+ return 0;
+#else
+ u8 buffer[2];
+ int retry;
+ int len = 1;
+ struct i2c_msg msg[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 2,
+ .buf = buffer,
+ },
+ };
+ while (0 != len--) {
+ buffer[0] = reg_addr;
+ buffer[1] = *data;
+ for (retry = 0; retry < SMI_ACC_MAX_RETRY_I2C_XFER; retry++) {
+ if (i2c_transfer(client->adapter, msg,
+ ARRAY_SIZE(msg)) > 0) {
+ break;
+ } else {
+ smi130_acc_delay(1);
+ }
+ }
+ if (SMI_ACC_MAX_RETRY_I2C_XFER <= retry) {
+ PERR("I2C xfer error");
+ return -EIO;
+ }
+ reg_addr++;
+ data++;
+ }
+
+ return 0;
+#endif
+}
+
+static int smi130_acc_smbus_read_byte_block(struct i2c_client *client,
+ unsigned char reg_addr, unsigned char *data, unsigned char len)
+{
+ int retry;
+
+ struct i2c_msg msg[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 1,
+ .buf = ®_addr,
+ },
+
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = len,
+ .buf = data,
+ },
+ };
+
+ for (retry = 0; retry < SMI_ACC_MAX_RETRY_I2C_XFER; retry++) {
+ if (i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)) > 0)
+ break;
+ else
+ smi130_acc_delay(1);
+ }
+
+ if (SMI_ACC_MAX_RETRY_I2C_XFER <= retry) {
+ PERR("I2C xfer error");
+ return -EIO;
+ }
+ return 0;
+}
+
+static int smi_acc_i2c_burst_read(struct i2c_client *client, u8 reg_addr,
+ u8 *data, u16 len)
+{
+ int retry;
+
+ struct i2c_msg msg[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 1,
+ .buf = ®_addr,
+ },
+
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = len,
+ .buf = data,
+ },
+ };
+
+ for (retry = 0; retry < SMI_ACC_MAX_RETRY_I2C_XFER; retry++) {
+ if (i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)) > 0)
+ break;
+ else
+ smi130_acc_delay(1);
+ }
+
+ if (SMI_ACC_MAX_RETRY_I2C_XFER <= retry) {
+ PINFO("I2C xfer error");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int smi130_acc_check_chip_id(struct i2c_client *client,
+ struct smi130_acc_data *data)
+{
+ int i = 0;
+ int err = 0;
+ unsigned char chip_id = 0;
+ unsigned char read_count = 0;
+ unsigned char smi130_acc_sensor_type_count = 0;
+
+ smi130_acc_sensor_type_count =
+ sizeof(sensor_type_map) / sizeof(struct smi130_acc_type_map_t);
+
+ while (read_count++ < CHECK_CHIP_ID_TIME_MAX) {
+ if (smi130_acc_smbus_read_byte(client, SMI_ACC2X2_CHIP_ID_REG,
+ &chip_id) < 0) {
+ PERR("Bosch Sensortec Device not found\n\n"
+ "i2c bus read error, read chip_id:%d\n", chip_id);
+ continue;
+ } else {
+ for (i = 0; i < smi130_acc_sensor_type_count; i++) {
+ if (sensor_type_map[i].chip_id == chip_id) {
+ data->sensor_type =
+ sensor_type_map[i].sensor_type;
+ data->chip_id = chip_id;
+ PINFO("Bosch Sensortec Device detected,\n\n"
+ " HW IC name: %s\n",
+ sensor_type_map[i].sensor_name);
+ return err;
+ }
+ }
+ if (i < smi130_acc_sensor_type_count)
+ return err;
+ else {
+ if (read_count == CHECK_CHIP_ID_TIME_MAX) {
+ PERR("Failed! Bosch Sensortec Device\n\n"
+ " not found, mismatch chip_id:%d\n",
+ chip_id);
+ err = -ENODEV;
+ return err;
+ }
+ }
+ smi130_acc_delay(1);
+ }
+ }
+ return err;
+}
+
+#ifdef CONFIG_SMI_ACC_ENABLE_NEWDATA_INT
+static int smi130_acc_set_newdata(struct i2c_client *client,
+ unsigned char channel, unsigned char int_newdata)
+{
+
+ unsigned char data = 0;
+ int comres = 0;
+
+ switch (channel) {
+ case SMI_ACC2X2_INT1_NDATA:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_EN_INT1_PAD_NEWDATA__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data,
+ SMI_ACC2X2_EN_INT1_PAD_NEWDATA, int_newdata);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_EN_INT1_PAD_NEWDATA__REG, &data);
+ break;
+ case SMI_ACC2X2_INT2_NDATA:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_EN_INT2_PAD_NEWDATA__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data,
+ SMI_ACC2X2_EN_INT2_PAD_NEWDATA, int_newdata);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_EN_INT2_PAD_NEWDATA__REG, &data);
+ break;
+ default:
+ comres = -1;
+ break;
+ }
+
+ return comres;
+
+}
+#endif /* CONFIG_SMI_ACC_ENABLE_NEWDATA_INT */
+
+#ifdef SMI_ACC2X2_ENABLE_INT1
+static int smi130_acc_set_int1_pad_sel(struct i2c_client *client, unsigned char
+ int1sel)
+{
+ int comres = 0;
+ unsigned char data = 0;
+ unsigned char state;
+ state = 0x01;
+
+
+ switch (int1sel) {
+ case 0:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_EN_INT1_PAD_LOWG__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_EN_INT1_PAD_LOWG,
+ state);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_EN_INT1_PAD_LOWG__REG, &data);
+ break;
+ case 1:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_EN_INT1_PAD_HIGHG__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_EN_INT1_PAD_HIGHG,
+ state);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_EN_INT1_PAD_HIGHG__REG, &data);
+ break;
+ case 2:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_EN_INT1_PAD_SLOPE__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_EN_INT1_PAD_SLOPE,
+ state);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_EN_INT1_PAD_SLOPE__REG, &data);
+ break;
+ case 3:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_EN_INT1_PAD_DB_TAP__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_EN_INT1_PAD_DB_TAP,
+ state);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_EN_INT1_PAD_DB_TAP__REG, &data);
+ break;
+ case 4:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_EN_INT1_PAD_SNG_TAP__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_EN_INT1_PAD_SNG_TAP,
+ state);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_EN_INT1_PAD_SNG_TAP__REG, &data);
+ break;
+ case 5:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_EN_INT1_PAD_ORIENT__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_EN_INT1_PAD_ORIENT,
+ state);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_EN_INT1_PAD_ORIENT__REG, &data);
+ break;
+ case 6:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_EN_INT1_PAD_FLAT__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_EN_INT1_PAD_FLAT,
+ state);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_EN_INT1_PAD_FLAT__REG, &data);
+ break;
+ case 7:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_EN_INT1_PAD_SLO_NO_MOT__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_EN_INT1_PAD_SLO_NO_MOT,
+ state);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_EN_INT1_PAD_SLO_NO_MOT__REG, &data);
+ break;
+
+ default:
+ break;
+ }
+
+ return comres;
+}
+#endif /* SMI_ACC2X2_ENABLE_INT1 */
+
+#ifdef SMI_ACC2X2_ENABLE_INT2
+static int smi130_acc_set_int2_pad_sel(struct i2c_client *client, unsigned char
+ int2sel)
+{
+ int comres = 0;
+ unsigned char data = 0;
+ unsigned char state;
+ state = 0x01;
+
+
+ switch (int2sel) {
+ case 0:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_EN_INT2_PAD_LOWG__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_EN_INT2_PAD_LOWG,
+ state);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_EN_INT2_PAD_LOWG__REG, &data);
+ break;
+ case 1:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_EN_INT2_PAD_HIGHG__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_EN_INT2_PAD_HIGHG,
+ state);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_EN_INT2_PAD_HIGHG__REG, &data);
+ break;
+ case 2:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_EN_INT2_PAD_SLOPE__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_EN_INT2_PAD_SLOPE,
+ state);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_EN_INT2_PAD_SLOPE__REG, &data);
+ break;
+ case 3:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_EN_INT2_PAD_DB_TAP__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_EN_INT2_PAD_DB_TAP,
+ state);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_EN_INT2_PAD_DB_TAP__REG, &data);
+ break;
+ case 4:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_EN_INT2_PAD_SNG_TAP__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_EN_INT2_PAD_SNG_TAP,
+ state);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_EN_INT2_PAD_SNG_TAP__REG, &data);
+ break;
+ case 5:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_EN_INT2_PAD_ORIENT__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_EN_INT2_PAD_ORIENT,
+ state);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_EN_INT2_PAD_ORIENT__REG, &data);
+ break;
+ case 6:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_EN_INT2_PAD_FLAT__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_EN_INT2_PAD_FLAT,
+ state);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_EN_INT2_PAD_FLAT__REG, &data);
+ break;
+ case 7:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_EN_INT2_PAD_SLO_NO_MOT__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_EN_INT2_PAD_SLO_NO_MOT,
+ state);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_EN_INT2_PAD_SLO_NO_MOT__REG, &data);
+ break;
+ default:
+ break;
+ }
+
+ return comres;
+}
+#endif /* SMI_ACC2X2_ENABLE_INT2 */
+
+static int smi130_acc_set_Int_Enable(struct i2c_client *client, unsigned char
+ InterruptType , unsigned char value)
+{
+ int comres = 0;
+ unsigned char data1 = 0;
+ unsigned char data2 = 0;
+
+ if ((11 < InterruptType) && (InterruptType < 16)) {
+ switch (InterruptType) {
+ case 12:
+ /* slow/no motion X Interrupt */
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_INT_SLO_NO_MOT_EN_X_INT__REG, &data1);
+ data1 = SMI_ACC2X2_SET_BITSLICE(data1,
+ SMI_ACC2X2_INT_SLO_NO_MOT_EN_X_INT, value);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_INT_SLO_NO_MOT_EN_X_INT__REG, &data1);
+ break;
+ case 13:
+ /* slow/no motion Y Interrupt */
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_INT_SLO_NO_MOT_EN_Y_INT__REG, &data1);
+ data1 = SMI_ACC2X2_SET_BITSLICE(data1,
+ SMI_ACC2X2_INT_SLO_NO_MOT_EN_Y_INT, value);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_INT_SLO_NO_MOT_EN_Y_INT__REG, &data1);
+ break;
+ case 14:
+ /* slow/no motion Z Interrupt */
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_INT_SLO_NO_MOT_EN_Z_INT__REG, &data1);
+ data1 = SMI_ACC2X2_SET_BITSLICE(data1,
+ SMI_ACC2X2_INT_SLO_NO_MOT_EN_Z_INT, value);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_INT_SLO_NO_MOT_EN_Z_INT__REG, &data1);
+ break;
+ case 15:
+ /* slow / no motion Interrupt select */
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_INT_SLO_NO_MOT_EN_SEL_INT__REG, &data1);
+ data1 = SMI_ACC2X2_SET_BITSLICE(data1,
+ SMI_ACC2X2_INT_SLO_NO_MOT_EN_SEL_INT, value);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_INT_SLO_NO_MOT_EN_SEL_INT__REG, &data1);
+ }
+
+ return comres;
+ }
+
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_INT_ENABLE1_REG, &data1);
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_INT_ENABLE2_REG, &data2);
+
+ value = value & 1;
+ switch (InterruptType) {
+ case 0:
+ /* Low G Interrupt */
+ data2 = SMI_ACC2X2_SET_BITSLICE(data2, SMI_ACC2X2_EN_LOWG_INT, value);
+ break;
+
+ case 1:
+ /* High G X Interrupt */
+ data2 = SMI_ACC2X2_SET_BITSLICE(data2, SMI_ACC2X2_EN_HIGHG_X_INT,
+ value);
+ break;
+
+ case 2:
+ /* High G Y Interrupt */
+ data2 = SMI_ACC2X2_SET_BITSLICE(data2, SMI_ACC2X2_EN_HIGHG_Y_INT,
+ value);
+ break;
+
+ case 3:
+ /* High G Z Interrupt */
+ data2 = SMI_ACC2X2_SET_BITSLICE(data2, SMI_ACC2X2_EN_HIGHG_Z_INT,
+ value);
+ break;
+
+ case 4:
+ /* New Data Interrupt */
+ data2 = SMI_ACC2X2_SET_BITSLICE(data2, SMI_ACC2X2_EN_NEW_DATA_INT,
+ value);
+ break;
+
+ case 5:
+ /* Slope X Interrupt */
+ data1 = SMI_ACC2X2_SET_BITSLICE(data1, SMI_ACC2X2_EN_SLOPE_X_INT,
+ value);
+ break;
+
+ case 6:
+ /* Slope Y Interrupt */
+ data1 = SMI_ACC2X2_SET_BITSLICE(data1, SMI_ACC2X2_EN_SLOPE_Y_INT,
+ value);
+ break;
+
+ case 7:
+ /* Slope Z Interrupt */
+ data1 = SMI_ACC2X2_SET_BITSLICE(data1, SMI_ACC2X2_EN_SLOPE_Z_INT,
+ value);
+ break;
+
+ case 8:
+ /* Single Tap Interrupt */
+ data1 = SMI_ACC2X2_SET_BITSLICE(data1, SMI_ACC2X2_EN_SINGLE_TAP_INT,
+ value);
+ break;
+
+ case 9:
+ /* Double Tap Interrupt */
+ data1 = SMI_ACC2X2_SET_BITSLICE(data1, SMI_ACC2X2_EN_DOUBLE_TAP_INT,
+ value);
+ break;
+
+ case 10:
+ /* Orient Interrupt */
+ data1 = SMI_ACC2X2_SET_BITSLICE(data1, SMI_ACC2X2_EN_ORIENT_INT, value);
+ break;
+
+ case 11:
+ /* Flat Interrupt */
+ data1 = SMI_ACC2X2_SET_BITSLICE(data1, SMI_ACC2X2_EN_FLAT_INT, value);
+ break;
+
+ default:
+ break;
+ }
+ comres = smi130_acc_smbus_write_byte(client, SMI_ACC2X2_INT_ENABLE1_REG,
+ &data1);
+ comres = smi130_acc_smbus_write_byte(client, SMI_ACC2X2_INT_ENABLE2_REG,
+ &data2);
+
+ return comres;
+}
+
+
+#if defined(SMI_ACC2X2_ENABLE_INT1) || defined(SMI_ACC2X2_ENABLE_INT2)
+static int smi130_acc_get_interruptstatus1(struct i2c_client *client, unsigned char
+ *intstatus)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_STATUS1_REG, &data);
+ *intstatus = data;
+
+ return comres;
+}
+
+#ifdef CONFIG_SMI_ACC_ENABLE_NEWDATA_INT
+/*
+static int smi130_acc_get_interruptstatus2(struct i2c_client *client, unsigned char
+ *intstatus)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_STATUS2_REG, &data);
+ *intstatus = data;
+
+ return comres;
+}
+*/
+#endif
+
+static int smi130_acc_get_HIGH_first(struct i2c_client *client, unsigned char
+ param, unsigned char *intstatus)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ switch (param) {
+ case 0:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_STATUS_ORIENT_HIGH_REG, &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_HIGHG_FIRST_X);
+ *intstatus = data;
+ break;
+ case 1:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_STATUS_ORIENT_HIGH_REG, &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_HIGHG_FIRST_Y);
+ *intstatus = data;
+ break;
+ case 2:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_STATUS_ORIENT_HIGH_REG, &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_HIGHG_FIRST_Z);
+ *intstatus = data;
+ break;
+ default:
+ break;
+ }
+
+ return comres;
+}
+
+static int smi130_acc_get_HIGH_sign(struct i2c_client *client, unsigned char
+ *intstatus)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_STATUS_ORIENT_HIGH_REG,
+ &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_HIGHG_SIGN_S);
+ *intstatus = data;
+
+ return comres;
+}
+
+#ifndef CONFIG_SIG_MOTION
+static int smi130_acc_get_slope_first(struct i2c_client *client, unsigned char
+ param, unsigned char *intstatus)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ switch (param) {
+ case 0:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_STATUS_TAP_SLOPE_REG, &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_SLOPE_FIRST_X);
+ *intstatus = data;
+ break;
+ case 1:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_STATUS_TAP_SLOPE_REG, &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_SLOPE_FIRST_Y);
+ *intstatus = data;
+ break;
+ case 2:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_STATUS_TAP_SLOPE_REG, &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_SLOPE_FIRST_Z);
+ *intstatus = data;
+ break;
+ default:
+ break;
+ }
+
+ return comres;
+}
+
+static int smi130_acc_get_slope_sign(struct i2c_client *client, unsigned char
+ *intstatus)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_STATUS_TAP_SLOPE_REG,
+ &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_SLOPE_SIGN_S);
+ *intstatus = data;
+
+ return comres;
+}
+#endif
+
+static int smi130_acc_get_orient_mbl_status(struct i2c_client *client, unsigned char
+ *intstatus)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_STATUS_ORIENT_HIGH_REG,
+ &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_ORIENT_S);
+ *intstatus = data;
+
+ return comres;
+}
+
+static int smi130_acc_get_orient_mbl_flat_status(struct i2c_client *client, unsigned
+ char *intstatus)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_STATUS_ORIENT_HIGH_REG,
+ &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_FLAT_S);
+ *intstatus = data;
+
+ return comres;
+}
+#endif /* defined(SMI_ACC2X2_ENABLE_INT1)||defined(SMI_ACC2X2_ENABLE_INT2) */
+
+static int smi130_acc_set_Int_Mode(struct i2c_client *client, unsigned char Mode)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_INT_MODE_SEL__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_INT_MODE_SEL, Mode);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_INT_MODE_SEL__REG, &data);
+
+
+ return comres;
+}
+
+static int smi130_acc_get_Int_Mode(struct i2c_client *client, unsigned char *Mode)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_INT_MODE_SEL__REG, &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_INT_MODE_SEL);
+ *Mode = data;
+
+
+ return comres;
+}
+static int smi130_acc_set_slope_duration(struct i2c_client *client, unsigned char
+ duration)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_SLOPE_DUR__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_SLOPE_DUR, duration);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_SLOPE_DUR__REG, &data);
+
+ return comres;
+}
+
+static int smi130_acc_get_slope_duration(struct i2c_client *client, unsigned char
+ *status)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_SLOPE_DURN_REG, &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_SLOPE_DUR);
+ *status = data;
+
+
+ return comres;
+}
+
+static int smi130_acc_set_slope_no_mot_duration(struct i2c_client *client,
+ unsigned char duration)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI130_ACC_SLO_NO_MOT_DUR__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI130_ACC_SLO_NO_MOT_DUR, duration);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI130_ACC_SLO_NO_MOT_DUR__REG, &data);
+
+
+ return comres;
+}
+
+static int smi130_acc_get_slope_no_mot_duration(struct i2c_client *client,
+ unsigned char *status)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI130_ACC_SLO_NO_MOT_DUR__REG, &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI130_ACC_SLO_NO_MOT_DUR);
+ *status = data;
+
+
+ return comres;
+}
+
+static int smi130_acc_set_slope_threshold(struct i2c_client *client,
+ unsigned char threshold)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ data = threshold;
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_SLOPE_THRES__REG, &data);
+
+ return comres;
+}
+
+static int smi130_acc_get_slope_threshold(struct i2c_client *client,
+ unsigned char *status)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_SLOPE_THRES_REG, &data);
+ *status = data;
+
+ return comres;
+}
+
+static int smi130_acc_set_slope_no_mot_threshold(struct i2c_client *client,
+ unsigned char threshold)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ data = threshold;
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_SLO_NO_MOT_THRES_REG, &data);
+
+ return comres;
+}
+
+static int smi130_acc_get_slope_no_mot_threshold(struct i2c_client *client,
+ unsigned char *status)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_SLO_NO_MOT_THRES_REG, &data);
+ *status = data;
+
+ return comres;
+}
+
+
+static int smi130_acc_set_low_g_duration(struct i2c_client *client, unsigned char
+ duration)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_LOWG_DUR__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_LOWG_DUR, duration);
+ comres = smi130_acc_smbus_write_byte(client, SMI_ACC2X2_LOWG_DUR__REG, &data);
+
+ return comres;
+}
+
+static int smi130_acc_get_low_g_duration(struct i2c_client *client, unsigned char
+ *status)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_LOW_DURN_REG, &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_LOWG_DUR);
+ *status = data;
+
+ return comres;
+}
+
+static int smi130_acc_set_low_g_threshold(struct i2c_client *client, unsigned char
+ threshold)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_LOWG_THRES__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_LOWG_THRES, threshold);
+ comres = smi130_acc_smbus_write_byte(client, SMI_ACC2X2_LOWG_THRES__REG, &data);
+
+ return comres;
+}
+
+static int smi130_acc_get_low_g_threshold(struct i2c_client *client, unsigned char
+ *status)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_LOW_THRES_REG, &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_LOWG_THRES);
+ *status = data;
+
+ return comres;
+}
+
+static int smi130_acc_set_high_g_duration(struct i2c_client *client, unsigned char
+ duration)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_HIGHG_DUR__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_HIGHG_DUR, duration);
+ comres = smi130_acc_smbus_write_byte(client, SMI_ACC2X2_HIGHG_DUR__REG, &data);
+
+ return comres;
+}
+
+static int smi130_acc_get_high_g_duration(struct i2c_client *client, unsigned char
+ *status)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_HIGH_DURN_REG, &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_HIGHG_DUR);
+ *status = data;
+
+ return comres;
+}
+
+static int smi130_acc_set_high_g_threshold(struct i2c_client *client, unsigned char
+ threshold)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_HIGHG_THRES__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_HIGHG_THRES, threshold);
+ comres = smi130_acc_smbus_write_byte(client, SMI_ACC2X2_HIGHG_THRES__REG,
+ &data);
+
+ return comres;
+}
+
+static int smi130_acc_get_high_g_threshold(struct i2c_client *client, unsigned char
+ *status)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_HIGH_THRES_REG, &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_HIGHG_THRES);
+ *status = data;
+
+ return comres;
+}
+
+
+static int smi130_acc_set_tap_duration(struct i2c_client *client, unsigned char
+ duration)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_TAP_DUR__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_TAP_DUR, duration);
+ comres = smi130_acc_smbus_write_byte(client, SMI_ACC2X2_TAP_DUR__REG, &data);
+
+ return comres;
+}
+
+static int smi130_acc_get_tap_duration(struct i2c_client *client, unsigned char
+ *status)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_TAP_PARAM_REG, &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_TAP_DUR);
+ *status = data;
+
+ return comres;
+}
+
+static int smi130_acc_set_tap_shock(struct i2c_client *client, unsigned char setval)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_TAP_SHOCK_DURN__REG,
+ &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_TAP_SHOCK_DURN, setval);
+ comres = smi130_acc_smbus_write_byte(client, SMI_ACC2X2_TAP_SHOCK_DURN__REG,
+ &data);
+
+ return comres;
+}
+
+static int smi130_acc_get_tap_shock(struct i2c_client *client, unsigned char
+ *status)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_TAP_PARAM_REG, &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_TAP_SHOCK_DURN);
+ *status = data;
+
+ return comres;
+}
+
+static int smi130_acc_set_tap_quiet(struct i2c_client *client, unsigned char
+ duration)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_TAP_QUIET_DURN__REG,
+ &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_TAP_QUIET_DURN, duration);
+ comres = smi130_acc_smbus_write_byte(client, SMI_ACC2X2_TAP_QUIET_DURN__REG,
+ &data);
+
+ return comres;
+}
+
+static int smi130_acc_get_tap_quiet(struct i2c_client *client, unsigned char
+ *status)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_TAP_PARAM_REG, &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_TAP_QUIET_DURN);
+ *status = data;
+
+ return comres;
+}
+
+static int smi130_acc_set_tap_threshold(struct i2c_client *client, unsigned char
+ threshold)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_TAP_THRES__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_TAP_THRES, threshold);
+ comres = smi130_acc_smbus_write_byte(client, SMI_ACC2X2_TAP_THRES__REG, &data);
+
+ return comres;
+}
+
+static int smi130_acc_get_tap_threshold(struct i2c_client *client, unsigned char
+ *status)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_TAP_THRES_REG, &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_TAP_THRES);
+ *status = data;
+
+ return comres;
+}
+
+static int smi130_acc_set_tap_samp(struct i2c_client *client, unsigned char samp)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_TAP_SAMPLES__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_TAP_SAMPLES, samp);
+ comres = smi130_acc_smbus_write_byte(client, SMI_ACC2X2_TAP_SAMPLES__REG,
+ &data);
+
+ return comres;
+}
+
+static int smi130_acc_get_tap_samp(struct i2c_client *client, unsigned char *status)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_TAP_THRES_REG, &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_TAP_SAMPLES);
+ *status = data;
+
+ return comres;
+}
+
+static int smi130_acc_set_orient_mbl_mode(struct i2c_client *client, unsigned char mode)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_ORIENT_MODE__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_ORIENT_MODE, mode);
+ comres = smi130_acc_smbus_write_byte(client, SMI_ACC2X2_ORIENT_MODE__REG,
+ &data);
+
+ return comres;
+}
+
+static int smi130_acc_get_orient_mbl_mode(struct i2c_client *client, unsigned char
+ *status)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_ORIENT_PARAM_REG, &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_ORIENT_MODE);
+ *status = data;
+
+ return comres;
+}
+
+static int smi130_acc_set_orient_mbl_blocking(struct i2c_client *client, unsigned char
+ samp)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_ORIENT_BLOCK__REG,
+ &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_ORIENT_BLOCK, samp);
+ comres = smi130_acc_smbus_write_byte(client, SMI_ACC2X2_ORIENT_BLOCK__REG,
+ &data);
+
+ return comres;
+}
+
+static int smi130_acc_get_orient_mbl_blocking(struct i2c_client *client, unsigned char
+ *status)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_ORIENT_PARAM_REG, &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_ORIENT_BLOCK);
+ *status = data;
+
+ return comres;
+}
+
+static int smi130_acc_set_orient_mbl_hyst(struct i2c_client *client, unsigned char
+ orient_mblhyst)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_ORIENT_HYST__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_ORIENT_HYST, orient_mblhyst);
+ comres = smi130_acc_smbus_write_byte(client, SMI_ACC2X2_ORIENT_HYST__REG,
+ &data);
+
+ return comres;
+}
+
+static int smi130_acc_get_orient_mbl_hyst(struct i2c_client *client, unsigned char
+ *status)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_ORIENT_PARAM_REG, &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_ORIENT_HYST);
+ *status = data;
+
+ return comres;
+}
+static int smi130_acc_set_theta_blocking(struct i2c_client *client, unsigned char
+ thetablk)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_THETA_BLOCK__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_THETA_BLOCK, thetablk);
+ comres = smi130_acc_smbus_write_byte(client, SMI_ACC2X2_THETA_BLOCK__REG,
+ &data);
+
+ return comres;
+}
+
+static int smi130_acc_get_theta_blocking(struct i2c_client *client, unsigned char
+ *status)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_THETA_BLOCK_REG, &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_THETA_BLOCK);
+ *status = data;
+
+ return comres;
+}
+
+static int smi130_acc_set_theta_flat(struct i2c_client *client, unsigned char
+ thetaflat)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_THETA_FLAT__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_THETA_FLAT, thetaflat);
+ comres = smi130_acc_smbus_write_byte(client, SMI_ACC2X2_THETA_FLAT__REG, &data);
+
+ return comres;
+}
+
+static int smi130_acc_get_theta_flat(struct i2c_client *client, unsigned char
+ *status)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_THETA_FLAT_REG, &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_THETA_FLAT);
+ *status = data;
+
+ return comres;
+}
+
+static int smi130_acc_set_flat_hold_time(struct i2c_client *client, unsigned char
+ holdtime)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_FLAT_HOLD_TIME__REG,
+ &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_FLAT_HOLD_TIME, holdtime);
+ comres = smi130_acc_smbus_write_byte(client, SMI_ACC2X2_FLAT_HOLD_TIME__REG,
+ &data);
+
+ return comres;
+}
+
+static int smi130_acc_get_flat_hold_time(struct i2c_client *client, unsigned char
+ *holdtime)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_FLAT_HOLD_TIME_REG,
+ &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_FLAT_HOLD_TIME);
+ *holdtime = data;
+
+ return comres;
+}
+
+/*!
+ * brief: smi130_acc switch from normal to suspend mode
+ * @param[i] smi130_acc
+ * @param[i] data1, write to PMU_LPW
+ * @param[i] data2, write to PMU_LOW_NOSIE
+ *
+ * @return zero success, none-zero failed
+ */
+static int smi130_acc_normal_to_suspend(struct smi130_acc_data *smi130_acc,
+ unsigned char data1, unsigned char data2)
+{
+ unsigned char current_fifo_mode;
+ unsigned char current_op_mode;
+ if (smi130_acc == NULL)
+ return -ENODEV;
+ /* get current op mode from mode register */
+ if (smi130_acc_get_mode(smi130_acc->smi130_acc_client, ¤t_op_mode) < 0)
+ return -EIO;
+ /* only aimed at operatiom mode chang from normal/lpw1 mode
+ * to suspend state.
+ */
+ if (current_op_mode == SMI_ACC2X2_MODE_NORMAL ||
+ current_op_mode == SMI_ACC2X2_MODE_LOWPOWER1) {
+ /* get current fifo mode from fifo config register */
+ if (smi130_acc_get_fifo_mode(smi130_acc->smi130_acc_client,
+ ¤t_fifo_mode) < 0)
+ return -EIO;
+ else {
+ smi130_acc_smbus_write_byte(smi130_acc->smi130_acc_client,
+ SMI_ACC2X2_LOW_NOISE_CTRL_REG, &data2);
+ smi130_acc_smbus_write_byte(smi130_acc->smi130_acc_client,
+ SMI_ACC2X2_MODE_CTRL_REG, &data1);
+ /*! Aim at fifo workarounds with FIFO_CONFIG_1 */
+ current_fifo_mode |= FIFO_WORKAROUNDS_MSK;
+ smi130_acc_smbus_write_byte(smi130_acc->smi130_acc_client,
+ SMI_ACC2X2_FIFO_MODE__REG, ¤t_fifo_mode);
+ smi130_acc_delay(3);
+ return 0;
+ }
+ } else {
+ smi130_acc_smbus_write_byte(smi130_acc->smi130_acc_client,
+ SMI_ACC2X2_LOW_NOISE_CTRL_REG, &data2);
+ smi130_acc_smbus_write_byte(smi130_acc->smi130_acc_client,
+ SMI_ACC2X2_MODE_CTRL_REG, &data1);
+ smi130_acc_delay(3);
+ return 0;
+ }
+
+}
+
+static int smi130_acc_set_mode(struct i2c_client *client, unsigned char mode,
+ unsigned char enabled_mode)
+{
+ int comres = 0;
+ unsigned char data1 = 0;
+ unsigned char data2 = 0;
+ int ret = 0;
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ mutex_lock(&smi130_acc->mode_mutex);
+ if (SMI_ACC2X2_MODE_SUSPEND == mode) {
+ if (enabled_mode != SMI_ACC_ENABLED_ALL) {
+ if ((smi130_acc->smi_acc_mode_enabled &
+ (1<<enabled_mode)) == 0) {
+ /* sensor is already closed in this mode */
+ mutex_unlock(&smi130_acc->mode_mutex);
+ return 0;
+ } else {
+ smi130_acc->smi_acc_mode_enabled &= ~(1<<enabled_mode);
+ }
+ } else {
+ /* shut down, close all and force do it*/
+ smi130_acc->smi_acc_mode_enabled = 0;
+ }
+ } else if (SMI_ACC2X2_MODE_NORMAL == mode) {
+ if ((smi130_acc->smi_acc_mode_enabled & (1<<enabled_mode)) != 0) {
+ /* sensor is already enabled in this mode */
+ mutex_unlock(&smi130_acc->mode_mutex);
+ return 0;
+ } else {
+ smi130_acc->smi_acc_mode_enabled |= (1<<enabled_mode);
+ }
+ } else {
+ /* other mode, close all and force do it*/
+ smi130_acc->smi_acc_mode_enabled = 0;
+ }
+ mutex_unlock(&smi130_acc->mode_mutex);
+
+ if (mode < 6) {
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_MODE_CTRL_REG,
+ &data1);
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_LOW_NOISE_CTRL_REG,
+ &data2);
+ switch (mode) {
+ case SMI_ACC2X2_MODE_NORMAL:
+ data1 = SMI_ACC2X2_SET_BITSLICE(data1,
+ SMI_ACC2X2_MODE_CTRL, 0);
+ data2 = SMI_ACC2X2_SET_BITSLICE(data2,
+ SMI_ACC2X2_LOW_POWER_MODE, 0);
+ smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_MODE_CTRL_REG, &data1);
+ smi130_acc_delay(3);
+ smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_LOW_NOISE_CTRL_REG, &data2);
+ break;
+ case SMI_ACC2X2_MODE_LOWPOWER1:
+ data1 = SMI_ACC2X2_SET_BITSLICE(data1,
+ SMI_ACC2X2_MODE_CTRL, 2);
+ data2 = SMI_ACC2X2_SET_BITSLICE(data2,
+ SMI_ACC2X2_LOW_POWER_MODE, 0);
+ smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_MODE_CTRL_REG, &data1);
+ smi130_acc_delay(3);
+ smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_LOW_NOISE_CTRL_REG, &data2);
+ break;
+ case SMI_ACC2X2_MODE_SUSPEND:
+ if (smi130_acc->smi_acc_mode_enabled != 0) {
+ PERR("smi_acc still working");
+ return 0;
+ }
+ data1 = SMI_ACC2X2_SET_BITSLICE(data1,
+ SMI_ACC2X2_MODE_CTRL, 4);
+ data2 = SMI_ACC2X2_SET_BITSLICE(data2,
+ SMI_ACC2X2_LOW_POWER_MODE, 0);
+ /*aimed at anomaly resolution when switch to suspend*/
+ ret = smi130_acc_normal_to_suspend(smi130_acc, data1, data2);
+ if (ret < 0)
+ PERR("Error switching to suspend");
+ break;
+ case SMI_ACC2X2_MODE_DEEP_SUSPEND:
+ if (smi130_acc->smi_acc_mode_enabled != 0) {
+ PERR("smi_acc still working");
+ return 0;
+ }
+ data1 = SMI_ACC2X2_SET_BITSLICE(data1,
+ SMI_ACC2X2_MODE_CTRL, 1);
+ data2 = SMI_ACC2X2_SET_BITSLICE(data2,
+ SMI_ACC2X2_LOW_POWER_MODE, 1);
+ smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_MODE_CTRL_REG, &data1);
+ smi130_acc_delay(3);
+ smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_LOW_NOISE_CTRL_REG, &data2);
+ break;
+ case SMI_ACC2X2_MODE_LOWPOWER2:
+ data1 = SMI_ACC2X2_SET_BITSLICE(data1,
+ SMI_ACC2X2_MODE_CTRL, 2);
+ data2 = SMI_ACC2X2_SET_BITSLICE(data2,
+ SMI_ACC2X2_LOW_POWER_MODE, 1);
+ smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_MODE_CTRL_REG, &data1);
+ smi130_acc_delay(3);
+ smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_LOW_NOISE_CTRL_REG, &data2);
+ break;
+ case SMI_ACC2X2_MODE_STANDBY:
+ data1 = SMI_ACC2X2_SET_BITSLICE(data1,
+ SMI_ACC2X2_MODE_CTRL, 4);
+ data2 = SMI_ACC2X2_SET_BITSLICE(data2,
+ SMI_ACC2X2_LOW_POWER_MODE, 1);
+ smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_LOW_NOISE_CTRL_REG, &data2);
+ smi130_acc_delay(3);
+ smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_MODE_CTRL_REG, &data1);
+ break;
+ }
+ } else {
+ comres = -1;
+ }
+
+ return comres;
+}
+
+
+static int smi130_acc_get_mode(struct i2c_client *client, unsigned char *mode)
+{
+ int comres = 0;
+ unsigned char data1 = 0;
+ unsigned char data2 = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_MODE_CTRL_REG, &data1);
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_LOW_NOISE_CTRL_REG,
+ &data2);
+
+ data1 = (data1 & 0xE0) >> 5;
+ data2 = (data2 & 0x40) >> 6;
+
+
+ if ((data1 == 0x00) && (data2 == 0x00)) {
+ *mode = SMI_ACC2X2_MODE_NORMAL;
+ } else {
+ if ((data1 == 0x02) && (data2 == 0x00)) {
+ *mode = SMI_ACC2X2_MODE_LOWPOWER1;
+ } else {
+ if ((data1 == 0x04 || data1 == 0x06) &&
+ (data2 == 0x00)) {
+ *mode = SMI_ACC2X2_MODE_SUSPEND;
+ } else {
+ if (((data1 & 0x01) == 0x01)) {
+ *mode = SMI_ACC2X2_MODE_DEEP_SUSPEND;
+ } else {
+ if ((data1 == 0x02) &&
+ (data2 == 0x01)) {
+ *mode = SMI_ACC2X2_MODE_LOWPOWER2;
+ } else {
+ if ((data1 == 0x04) && (data2 ==
+ 0x01)) {
+ *mode =
+ SMI_ACC2X2_MODE_STANDBY;
+ } else {
+ *mode =
+ SMI_ACC2X2_MODE_DEEP_SUSPEND;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return comres;
+}
+
+static int smi130_acc_set_range(struct i2c_client *client, unsigned char Range)
+{
+ int comres = 0;
+ unsigned char data1 = 0;
+
+ if ((Range == 3) || (Range == 5) || (Range == 8) || (Range == 12)) {
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_RANGE_SEL_REG,
+ &data1);
+ switch (Range) {
+ case SMI_ACC2X2_RANGE_2G:
+ data1 = SMI_ACC2X2_SET_BITSLICE(data1,
+ SMI_ACC2X2_RANGE_SEL, 3);
+ break;
+ case SMI_ACC2X2_RANGE_4G:
+ data1 = SMI_ACC2X2_SET_BITSLICE(data1,
+ SMI_ACC2X2_RANGE_SEL, 5);
+ break;
+ case SMI_ACC2X2_RANGE_8G:
+ data1 = SMI_ACC2X2_SET_BITSLICE(data1,
+ SMI_ACC2X2_RANGE_SEL, 8);
+ break;
+ case SMI_ACC2X2_RANGE_16G:
+ data1 = SMI_ACC2X2_SET_BITSLICE(data1,
+ SMI_ACC2X2_RANGE_SEL, 12);
+ break;
+ default:
+ break;
+ }
+ comres += smi130_acc_smbus_write_byte(client, SMI_ACC2X2_RANGE_SEL_REG,
+ &data1);
+ } else {
+ comres = -1;
+ }
+
+ return comres;
+}
+
+static int smi130_acc_get_range(struct i2c_client *client, unsigned char *Range)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_RANGE_SEL__REG, &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_RANGE_SEL);
+ *Range = data;
+
+ return comres;
+}
+
+
+static int smi130_acc_set_bandwidth(struct i2c_client *client, unsigned char BW)
+{
+ int comres = 0;
+ unsigned char data = 0;
+ int Bandwidth = 0;
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (BW > 7 && BW < 16) {
+ switch (BW) {
+ case SMI_ACC2X2_BW_7_81HZ:
+ Bandwidth = SMI_ACC2X2_BW_7_81HZ;
+ smi130_acc->time_odr = 64000000;
+
+ /* 7.81 Hz 64000 uS */
+ break;
+ case SMI_ACC2X2_BW_15_63HZ:
+ Bandwidth = SMI_ACC2X2_BW_15_63HZ;
+ smi130_acc->time_odr = 32000000;
+ /* 15.63 Hz 32000 uS */
+ break;
+ case SMI_ACC2X2_BW_31_25HZ:
+ Bandwidth = SMI_ACC2X2_BW_31_25HZ;
+ smi130_acc->time_odr = 16000000;
+ /* 31.25 Hz 16000 uS */
+ break;
+ case SMI_ACC2X2_BW_62_50HZ:
+ Bandwidth = SMI_ACC2X2_BW_62_50HZ;
+ smi130_acc->time_odr = 8000000;
+ /* 62.50 Hz 8000 uS */
+ break;
+ case SMI_ACC2X2_BW_125HZ:
+ Bandwidth = SMI_ACC2X2_BW_125HZ;
+ smi130_acc->time_odr = 4000000;
+ /* 125 Hz 4000 uS */
+ break;
+ case SMI_ACC2X2_BW_250HZ:
+ Bandwidth = SMI_ACC2X2_BW_250HZ;
+ smi130_acc->time_odr = 2000000;
+ /* 250 Hz 2000 uS */
+ break;
+ case SMI_ACC2X2_BW_500HZ:
+ Bandwidth = SMI_ACC2X2_BW_500HZ;
+ smi130_acc->time_odr = 1000000;
+ /* 500 Hz 1000 uS */
+ break;
+ case SMI_ACC2X2_BW_1000HZ:
+ Bandwidth = SMI_ACC2X2_BW_1000HZ;
+ smi130_acc->time_odr = 500000;
+ /* 1000 Hz 500 uS */
+ break;
+ default:
+ break;
+ }
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_BANDWIDTH__REG,
+ &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_BANDWIDTH, Bandwidth);
+ comres += smi130_acc_smbus_write_byte(client, SMI_ACC2X2_BANDWIDTH__REG,
+ &data);
+ } else {
+ comres = -1;
+ }
+
+ return comres;
+}
+
+static int smi130_acc_get_bandwidth(struct i2c_client *client, unsigned char *BW)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_BANDWIDTH__REG, &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_BANDWIDTH);
+ *BW = data;
+
+ return comres;
+}
+
+int smi130_acc_get_sleep_duration(struct i2c_client *client, unsigned char
+ *sleep_dur)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_SLEEP_DUR__REG, &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_SLEEP_DUR);
+ *sleep_dur = data;
+
+ return comres;
+}
+
+int smi130_acc_set_sleep_duration(struct i2c_client *client, unsigned char
+ sleep_dur)
+{
+ int comres = 0;
+ unsigned char data = 0;
+ int sleep_duration = 0;
+
+ if (sleep_dur > 4 && sleep_dur < 16) {
+ switch (sleep_dur) {
+ case SMI_ACC2X2_SLEEP_DUR_0_5MS:
+ sleep_duration = SMI_ACC2X2_SLEEP_DUR_0_5MS;
+
+ /* 0.5 MS */
+ break;
+ case SMI_ACC2X2_SLEEP_DUR_1MS:
+ sleep_duration = SMI_ACC2X2_SLEEP_DUR_1MS;
+
+ /* 1 MS */
+ break;
+ case SMI_ACC2X2_SLEEP_DUR_2MS:
+ sleep_duration = SMI_ACC2X2_SLEEP_DUR_2MS;
+
+ /* 2 MS */
+ break;
+ case SMI_ACC2X2_SLEEP_DUR_4MS:
+ sleep_duration = SMI_ACC2X2_SLEEP_DUR_4MS;
+
+ /* 4 MS */
+ break;
+ case SMI_ACC2X2_SLEEP_DUR_6MS:
+ sleep_duration = SMI_ACC2X2_SLEEP_DUR_6MS;
+
+ /* 6 MS */
+ break;
+ case SMI_ACC2X2_SLEEP_DUR_10MS:
+ sleep_duration = SMI_ACC2X2_SLEEP_DUR_10MS;
+
+ /* 10 MS */
+ break;
+ case SMI_ACC2X2_SLEEP_DUR_25MS:
+ sleep_duration = SMI_ACC2X2_SLEEP_DUR_25MS;
+
+ /* 25 MS */
+ break;
+ case SMI_ACC2X2_SLEEP_DUR_50MS:
+ sleep_duration = SMI_ACC2X2_SLEEP_DUR_50MS;
+
+ /* 50 MS */
+ break;
+ case SMI_ACC2X2_SLEEP_DUR_100MS:
+ sleep_duration = SMI_ACC2X2_SLEEP_DUR_100MS;
+
+ /* 100 MS */
+ break;
+ case SMI_ACC2X2_SLEEP_DUR_500MS:
+ sleep_duration = SMI_ACC2X2_SLEEP_DUR_500MS;
+
+ /* 500 MS */
+ break;
+ case SMI_ACC2X2_SLEEP_DUR_1S:
+ sleep_duration = SMI_ACC2X2_SLEEP_DUR_1S;
+
+ /* 1 SECS */
+ break;
+ default:
+ break;
+ }
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_SLEEP_DUR__REG,
+ &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_SLEEP_DUR,
+ sleep_duration);
+ comres = smi130_acc_smbus_write_byte(client, SMI_ACC2X2_SLEEP_DUR__REG,
+ &data);
+ } else {
+ comres = -1;
+ }
+
+
+ return comres;
+}
+
+static int smi130_acc_get_fifo_mode(struct i2c_client *client, unsigned char
+ *fifo_mode)
+{
+ int comres;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_FIFO_MODE__REG, &data);
+ *fifo_mode = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_FIFO_MODE);
+
+ return comres;
+}
+
+static int smi130_acc_set_fifo_mode(struct i2c_client *client, unsigned char
+ fifo_mode)
+{
+ unsigned char data = 0;
+ int comres = 0;
+
+ if (fifo_mode < 4) {
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_FIFO_MODE__REG,
+ &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_FIFO_MODE, fifo_mode);
+ /*! Aim at fifo workarounds with FIFO_CONFIG_1 */
+ data |= FIFO_WORKAROUNDS_MSK;
+ comres = smi130_acc_smbus_write_byte(client, SMI_ACC2X2_FIFO_MODE__REG,
+ &data);
+ } else {
+ comres = -1;
+ }
+
+ return comres;
+}
+
+static int smi130_acc_get_fifo_trig(struct i2c_client *client, unsigned char
+ *fifo_trig)
+{
+ int comres;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_FIFO_TRIGGER_ACTION__REG, &data);
+ *fifo_trig = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_FIFO_TRIGGER_ACTION);
+
+ return comres;
+}
+
+static int smi130_acc_set_fifo_trig(struct i2c_client *client, unsigned char
+ fifo_trig)
+{
+ unsigned char data = 0;
+ int comres = 0;
+
+ if (fifo_trig < 4) {
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_FIFO_TRIGGER_ACTION__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_FIFO_TRIGGER_ACTION,
+ fifo_trig);
+ /*! Aim at fifo workarounds with FIFO_CONFIG_1 */
+ data |= FIFO_WORKAROUNDS_MSK;
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_FIFO_TRIGGER_ACTION__REG, &data);
+ } else {
+ comres = -1;
+ }
+
+ return comres;
+}
+
+static int smi130_acc_get_fifo_trig_src(struct i2c_client *client, unsigned char
+ *trig_src)
+{
+ int comres;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_FIFO_TRIGGER_SOURCE__REG, &data);
+ *trig_src = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_FIFO_TRIGGER_SOURCE);
+
+ return comres;
+}
+
+static int smi130_acc_set_fifo_trig_src(struct i2c_client *client, unsigned char
+ trig_src)
+{
+ unsigned char data = 0;
+ int comres = 0;
+
+ if (trig_src < 4) {
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_FIFO_TRIGGER_SOURCE__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_FIFO_TRIGGER_SOURCE,
+ trig_src);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_FIFO_TRIGGER_SOURCE__REG, &data);
+ } else {
+ comres = -1;
+ }
+
+ return comres;
+}
+
+static int smi130_acc_get_fifo_framecount(struct i2c_client *client, unsigned char
+ *framecount)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_FIFO_FRAME_COUNTER_S__REG, &data);
+ *framecount = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_FIFO_FRAME_COUNTER_S);
+
+ return comres;
+}
+
+static int smi130_acc_get_fifo_data_sel(struct i2c_client *client, unsigned char
+ *data_sel)
+{
+ int comres;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_FIFO_DATA_SELECT__REG, &data);
+ *data_sel = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_FIFO_DATA_SELECT);
+
+ return comres;
+}
+
+static int smi130_acc_set_fifo_data_sel(struct i2c_client *client, unsigned char
+ data_sel)
+{
+ unsigned char data = 0;
+ int comres = 0;
+
+ if (data_sel < 4) {
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_FIFO_DATA_SELECT__REG,
+ &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_FIFO_DATA_SELECT,
+ data_sel);
+ /*! Aim at fifo workarounds with FIFO_CONFIG_1 */
+ data |= FIFO_WORKAROUNDS_MSK;
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_FIFO_DATA_SELECT__REG,
+ &data);
+ } else {
+ comres = -1;
+ }
+
+ return comres;
+}
+
+
+static int smi130_acc_get_offset_target(struct i2c_client *client, unsigned char
+ channel, unsigned char *offset)
+{
+ unsigned char data = 0;
+ int comres = 0;
+
+ switch (channel) {
+ case SMI_ACC2X2_CUT_OFF:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_COMP_CUTOFF__REG, &data);
+ *offset = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_COMP_CUTOFF);
+ break;
+ case SMI_ACC2X2_OFFSET_TRIGGER_X:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_COMP_TARGET_OFFSET_X__REG, &data);
+ *offset = SMI_ACC2X2_GET_BITSLICE(data,
+ SMI_ACC2X2_COMP_TARGET_OFFSET_X);
+ break;
+ case SMI_ACC2X2_OFFSET_TRIGGER_Y:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_COMP_TARGET_OFFSET_Y__REG, &data);
+ *offset = SMI_ACC2X2_GET_BITSLICE(data,
+ SMI_ACC2X2_COMP_TARGET_OFFSET_Y);
+ break;
+ case SMI_ACC2X2_OFFSET_TRIGGER_Z:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_COMP_TARGET_OFFSET_Z__REG, &data);
+ *offset = SMI_ACC2X2_GET_BITSLICE(data,
+ SMI_ACC2X2_COMP_TARGET_OFFSET_Z);
+ break;
+ default:
+ comres = -1;
+ break;
+ }
+
+ return comres;
+}
+
+static int smi130_acc_set_offset_target(struct i2c_client *client, unsigned char
+ channel, unsigned char offset)
+{
+ unsigned char data = 0;
+ int comres = 0;
+
+ switch (channel) {
+ case SMI_ACC2X2_CUT_OFF:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_COMP_CUTOFF__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_COMP_CUTOFF,
+ offset);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_COMP_CUTOFF__REG, &data);
+ break;
+ case SMI_ACC2X2_OFFSET_TRIGGER_X:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_COMP_TARGET_OFFSET_X__REG,
+ &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data,
+ SMI_ACC2X2_COMP_TARGET_OFFSET_X,
+ offset);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_COMP_TARGET_OFFSET_X__REG,
+ &data);
+ break;
+ case SMI_ACC2X2_OFFSET_TRIGGER_Y:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_COMP_TARGET_OFFSET_Y__REG,
+ &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data,
+ SMI_ACC2X2_COMP_TARGET_OFFSET_Y,
+ offset);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_COMP_TARGET_OFFSET_Y__REG,
+ &data);
+ break;
+ case SMI_ACC2X2_OFFSET_TRIGGER_Z:
+ comres = smi130_acc_smbus_read_byte(client,
+ SMI_ACC2X2_COMP_TARGET_OFFSET_Z__REG,
+ &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data,
+ SMI_ACC2X2_COMP_TARGET_OFFSET_Z,
+ offset);
+ comres = smi130_acc_smbus_write_byte(client,
+ SMI_ACC2X2_COMP_TARGET_OFFSET_Z__REG,
+ &data);
+ break;
+ default:
+ comres = -1;
+ break;
+ }
+
+ return comres;
+}
+
+static int smi130_acc_get_cal_ready(struct i2c_client *client,
+ unsigned char *calrdy)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_FAST_CAL_RDY_S__REG,
+ &data);
+ data = SMI_ACC2X2_GET_BITSLICE(data, SMI_ACC2X2_FAST_CAL_RDY_S);
+ *calrdy = data;
+
+ return comres;
+}
+
+static int smi130_acc_set_cal_trigger(struct i2c_client *client, unsigned char
+ caltrigger)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_CAL_TRIGGER__REG, &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_CAL_TRIGGER, caltrigger);
+ comres = smi130_acc_smbus_write_byte(client, SMI_ACC2X2_CAL_TRIGGER__REG,
+ &data);
+
+ return comres;
+}
+
+static int smi130_acc_write_reg(struct i2c_client *client, unsigned char addr,
+ unsigned char *data)
+{
+ int comres = 0;
+ comres = smi130_acc_smbus_write_byte(client, addr, data);
+
+ return comres;
+}
+
+
+static int smi130_acc_set_offset_x(struct i2c_client *client, unsigned char
+ offsetfilt)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ data = offsetfilt;
+
+#ifdef CONFIG_SENSORS_BMI058
+ comres = smi130_acc_smbus_write_byte(client, BMI058_OFFSET_X_AXIS_REG,
+ &data);
+#else
+ comres = smi130_acc_smbus_write_byte(client, SMI_ACC2X2_OFFSET_X_AXIS_REG,
+ &data);
+#endif
+
+ return comres;
+}
+
+
+static int smi130_acc_get_offset_x(struct i2c_client *client, unsigned char
+ *offsetfilt)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+#ifdef CONFIG_SENSORS_BMI058
+ comres = smi130_acc_smbus_read_byte(client, BMI058_OFFSET_X_AXIS_REG,
+ &data);
+#else
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_OFFSET_X_AXIS_REG,
+ &data);
+#endif
+ *offsetfilt = data;
+
+ return comres;
+}
+
+static int smi130_acc_set_offset_y(struct i2c_client *client, unsigned char
+ offsetfilt)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ data = offsetfilt;
+
+#ifdef CONFIG_SENSORS_BMI058
+ comres = smi130_acc_smbus_write_byte(client, BMI058_OFFSET_Y_AXIS_REG,
+ &data);
+#else
+ comres = smi130_acc_smbus_write_byte(client, SMI_ACC2X2_OFFSET_Y_AXIS_REG,
+ &data);
+#endif
+ return comres;
+}
+
+static int smi130_acc_get_offset_y(struct i2c_client *client, unsigned char
+ *offsetfilt)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+#ifdef CONFIG_SENSORS_BMI058
+ comres = smi130_acc_smbus_read_byte(client, BMI058_OFFSET_Y_AXIS_REG,
+ &data);
+#else
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_OFFSET_Y_AXIS_REG,
+ &data);
+#endif
+ *offsetfilt = data;
+
+ return comres;
+}
+
+static int smi130_acc_set_offset_z(struct i2c_client *client, unsigned char
+ offsetfilt)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ data = offsetfilt;
+ comres = smi130_acc_smbus_write_byte(client, SMI_ACC2X2_OFFSET_Z_AXIS_REG,
+ &data);
+
+ return comres;
+}
+
+static int smi130_acc_get_offset_z(struct i2c_client *client, unsigned char
+ *offsetfilt)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_OFFSET_Z_AXIS_REG,
+ &data);
+ *offsetfilt = data;
+
+ return comres;
+}
+
+
+static int smi130_acc_set_selftest_st(struct i2c_client *client, unsigned char
+ selftest)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_EN_SELF_TEST__REG,
+ &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_EN_SELF_TEST, selftest);
+ comres = smi130_acc_smbus_write_byte(client, SMI_ACC2X2_EN_SELF_TEST__REG,
+ &data);
+
+ return comres;
+}
+
+static int smi130_acc_set_selftest_stn(struct i2c_client *client, unsigned char stn)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_NEG_SELF_TEST__REG,
+ &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_NEG_SELF_TEST, stn);
+ comres = smi130_acc_smbus_write_byte(client, SMI_ACC2X2_NEG_SELF_TEST__REG,
+ &data);
+
+ return comres;
+}
+
+static int smi130_acc_set_selftest_amp(struct i2c_client *client, unsigned char amp)
+{
+ int comres = 0;
+ unsigned char data = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_SELF_TEST_AMP__REG,
+ &data);
+ data = SMI_ACC2X2_SET_BITSLICE(data, SMI_ACC2X2_SELF_TEST_AMP, amp);
+ comres = smi130_acc_smbus_write_byte(client, SMI_ACC2X2_SELF_TEST_AMP__REG,
+ &data);
+
+ return comres;
+}
+
+static int smi130_acc_read_accel_x(struct i2c_client *client,
+ signed char sensor_type, short *a_x)
+{
+ int comres = 0;
+ unsigned char data[2];
+
+ switch (sensor_type) {
+ case 0:
+ comres = smi130_acc_smbus_read_byte_block(client,
+ SMI_ACC2X2_ACC_X12_LSB__REG, data, 2);
+ *a_x = SMI_ACC2X2_GET_BITSLICE(data[0], SMI_ACC2X2_ACC_X12_LSB)|
+ (SMI_ACC2X2_GET_BITSLICE(data[1],
+ SMI_ACC2X2_ACC_X_MSB)<<(SMI_ACC2X2_ACC_X12_LSB__LEN));
+ *a_x = *a_x << (sizeof(short)*8-(SMI_ACC2X2_ACC_X12_LSB__LEN
+ + SMI_ACC2X2_ACC_X_MSB__LEN));
+ *a_x = *a_x >> (sizeof(short)*8-(SMI_ACC2X2_ACC_X12_LSB__LEN
+ + SMI_ACC2X2_ACC_X_MSB__LEN));
+ break;
+ case 1:
+ comres = smi130_acc_smbus_read_byte_block(client,
+ SMI_ACC2X2_ACC_X10_LSB__REG, data, 2);
+ *a_x = SMI_ACC2X2_GET_BITSLICE(data[0], SMI_ACC2X2_ACC_X10_LSB)|
+ (SMI_ACC2X2_GET_BITSLICE(data[1],
+ SMI_ACC2X2_ACC_X_MSB)<<(SMI_ACC2X2_ACC_X10_LSB__LEN));
+ *a_x = *a_x << (sizeof(short)*8-(SMI_ACC2X2_ACC_X10_LSB__LEN
+ + SMI_ACC2X2_ACC_X_MSB__LEN));
+ *a_x = *a_x >> (sizeof(short)*8-(SMI_ACC2X2_ACC_X10_LSB__LEN
+ + SMI_ACC2X2_ACC_X_MSB__LEN));
+ break;
+ case 2:
+ comres = smi130_acc_smbus_read_byte_block(client,
+ SMI_ACC2X2_ACC_X8_LSB__REG, data, 2);
+ *a_x = SMI_ACC2X2_GET_BITSLICE(data[0], SMI_ACC2X2_ACC_X8_LSB)|
+ (SMI_ACC2X2_GET_BITSLICE(data[1],
+ SMI_ACC2X2_ACC_X_MSB)<<(SMI_ACC2X2_ACC_X8_LSB__LEN));
+ *a_x = *a_x << (sizeof(short)*8-(SMI_ACC2X2_ACC_X8_LSB__LEN
+ + SMI_ACC2X2_ACC_X_MSB__LEN));
+ *a_x = *a_x >> (sizeof(short)*8-(SMI_ACC2X2_ACC_X8_LSB__LEN
+ + SMI_ACC2X2_ACC_X_MSB__LEN));
+ break;
+ case 3:
+ comres = smi130_acc_smbus_read_byte_block(client,
+ SMI_ACC2X2_ACC_X14_LSB__REG, data, 2);
+ *a_x = SMI_ACC2X2_GET_BITSLICE(data[0], SMI_ACC2X2_ACC_X14_LSB)|
+ (SMI_ACC2X2_GET_BITSLICE(data[1],
+ SMI_ACC2X2_ACC_X_MSB)<<(SMI_ACC2X2_ACC_X14_LSB__LEN));
+ *a_x = *a_x << (sizeof(short)*8-(SMI_ACC2X2_ACC_X14_LSB__LEN
+ + SMI_ACC2X2_ACC_X_MSB__LEN));
+ *a_x = *a_x >> (sizeof(short)*8-(SMI_ACC2X2_ACC_X14_LSB__LEN
+ + SMI_ACC2X2_ACC_X_MSB__LEN));
+ break;
+ default:
+ break;
+ }
+
+ return comres;
+}
+
+static int smi130_acc_soft_reset(struct i2c_client *client)
+{
+ int comres = 0;
+ unsigned char data = SMI_ACC2X2_EN_SOFT_RESET_VALUE;
+
+ comres = smi130_acc_smbus_write_byte(client, SMI_ACC2X2_EN_SOFT_RESET__REG,
+ &data);
+
+ return comres;
+}
+
+static int smi130_acc_read_accel_y(struct i2c_client *client,
+ signed char sensor_type, short *a_y)
+{
+ int comres = 0;
+ unsigned char data[2];
+
+ switch (sensor_type) {
+ case 0:
+ comres = smi130_acc_smbus_read_byte_block(client,
+ SMI_ACC2X2_ACC_Y12_LSB__REG, data, 2);
+ *a_y = SMI_ACC2X2_GET_BITSLICE(data[0], SMI_ACC2X2_ACC_Y12_LSB)|
+ (SMI_ACC2X2_GET_BITSLICE(data[1],
+ SMI_ACC2X2_ACC_Y_MSB)<<(SMI_ACC2X2_ACC_Y12_LSB__LEN));
+ *a_y = *a_y << (sizeof(short)*8-(SMI_ACC2X2_ACC_Y12_LSB__LEN
+ + SMI_ACC2X2_ACC_Y_MSB__LEN));
+ *a_y = *a_y >> (sizeof(short)*8-(SMI_ACC2X2_ACC_Y12_LSB__LEN
+ + SMI_ACC2X2_ACC_Y_MSB__LEN));
+ break;
+ case 1:
+ comres = smi130_acc_smbus_read_byte_block(client,
+ SMI_ACC2X2_ACC_Y10_LSB__REG, data, 2);
+ *a_y = SMI_ACC2X2_GET_BITSLICE(data[0], SMI_ACC2X2_ACC_Y10_LSB)|
+ (SMI_ACC2X2_GET_BITSLICE(data[1],
+ SMI_ACC2X2_ACC_Y_MSB)<<(SMI_ACC2X2_ACC_Y10_LSB__LEN));
+ *a_y = *a_y << (sizeof(short)*8-(SMI_ACC2X2_ACC_Y10_LSB__LEN
+ + SMI_ACC2X2_ACC_Y_MSB__LEN));
+ *a_y = *a_y >> (sizeof(short)*8-(SMI_ACC2X2_ACC_Y10_LSB__LEN
+ + SMI_ACC2X2_ACC_Y_MSB__LEN));
+ break;
+ case 2:
+ comres = smi130_acc_smbus_read_byte_block(client,
+ SMI_ACC2X2_ACC_Y8_LSB__REG, data, 2);
+ *a_y = SMI_ACC2X2_GET_BITSLICE(data[0], SMI_ACC2X2_ACC_Y8_LSB)|
+ (SMI_ACC2X2_GET_BITSLICE(data[1],
+ SMI_ACC2X2_ACC_Y_MSB)<<(SMI_ACC2X2_ACC_Y8_LSB__LEN));
+ *a_y = *a_y << (sizeof(short)*8-(SMI_ACC2X2_ACC_Y8_LSB__LEN
+ + SMI_ACC2X2_ACC_Y_MSB__LEN));
+ *a_y = *a_y >> (sizeof(short)*8-(SMI_ACC2X2_ACC_Y8_LSB__LEN
+ + SMI_ACC2X2_ACC_Y_MSB__LEN));
+ break;
+ case 3:
+ comres = smi130_acc_smbus_read_byte_block(client,
+ SMI_ACC2X2_ACC_Y14_LSB__REG, data, 2);
+ *a_y = SMI_ACC2X2_GET_BITSLICE(data[0], SMI_ACC2X2_ACC_Y14_LSB)|
+ (SMI_ACC2X2_GET_BITSLICE(data[1],
+ SMI_ACC2X2_ACC_Y_MSB)<<(SMI_ACC2X2_ACC_Y14_LSB__LEN));
+ *a_y = *a_y << (sizeof(short)*8-(SMI_ACC2X2_ACC_Y14_LSB__LEN
+ + SMI_ACC2X2_ACC_Y_MSB__LEN));
+ *a_y = *a_y >> (sizeof(short)*8-(SMI_ACC2X2_ACC_Y14_LSB__LEN
+ + SMI_ACC2X2_ACC_Y_MSB__LEN));
+ break;
+ default:
+ break;
+ }
+
+ return comres;
+}
+
+static int smi130_acc_read_accel_z(struct i2c_client *client,
+ signed char sensor_type, short *a_z)
+{
+ int comres = 0;
+ unsigned char data[2];
+
+ switch (sensor_type) {
+ case 0:
+ comres = smi130_acc_smbus_read_byte_block(client,
+ SMI_ACC2X2_ACC_Z12_LSB__REG, data, 2);
+ *a_z = SMI_ACC2X2_GET_BITSLICE(data[0], SMI_ACC2X2_ACC_Z12_LSB)|
+ (SMI_ACC2X2_GET_BITSLICE(data[1],
+ SMI_ACC2X2_ACC_Z_MSB)<<(SMI_ACC2X2_ACC_Z12_LSB__LEN));
+ *a_z = *a_z << (sizeof(short)*8-(SMI_ACC2X2_ACC_Z12_LSB__LEN
+ + SMI_ACC2X2_ACC_Z_MSB__LEN));
+ *a_z = *a_z >> (sizeof(short)*8-(SMI_ACC2X2_ACC_Z12_LSB__LEN
+ + SMI_ACC2X2_ACC_Z_MSB__LEN));
+ break;
+ case 1:
+ comres = smi130_acc_smbus_read_byte_block(client,
+ SMI_ACC2X2_ACC_Z10_LSB__REG, data, 2);
+ *a_z = SMI_ACC2X2_GET_BITSLICE(data[0], SMI_ACC2X2_ACC_Z10_LSB)|
+ (SMI_ACC2X2_GET_BITSLICE(data[1],
+ SMI_ACC2X2_ACC_Z_MSB)<<(SMI_ACC2X2_ACC_Z10_LSB__LEN));
+ *a_z = *a_z << (sizeof(short)*8-(SMI_ACC2X2_ACC_Z10_LSB__LEN
+ + SMI_ACC2X2_ACC_Z_MSB__LEN));
+ *a_z = *a_z >> (sizeof(short)*8-(SMI_ACC2X2_ACC_Z10_LSB__LEN
+ + SMI_ACC2X2_ACC_Z_MSB__LEN));
+ break;
+ case 2:
+ comres = smi130_acc_smbus_read_byte_block(client,
+ SMI_ACC2X2_ACC_Z8_LSB__REG, data, 2);
+ *a_z = SMI_ACC2X2_GET_BITSLICE(data[0], SMI_ACC2X2_ACC_Z8_LSB)|
+ (SMI_ACC2X2_GET_BITSLICE(data[1],
+ SMI_ACC2X2_ACC_Z_MSB)<<(SMI_ACC2X2_ACC_Z8_LSB__LEN));
+ *a_z = *a_z << (sizeof(short)*8-(SMI_ACC2X2_ACC_Z8_LSB__LEN
+ + SMI_ACC2X2_ACC_Z_MSB__LEN));
+ *a_z = *a_z >> (sizeof(short)*8-(SMI_ACC2X2_ACC_Z8_LSB__LEN
+ + SMI_ACC2X2_ACC_Z_MSB__LEN));
+ break;
+ case 3:
+ comres = smi130_acc_smbus_read_byte_block(client,
+ SMI_ACC2X2_ACC_Z14_LSB__REG, data, 2);
+ *a_z = SMI_ACC2X2_GET_BITSLICE(data[0], SMI_ACC2X2_ACC_Z14_LSB)|
+ (SMI_ACC2X2_GET_BITSLICE(data[1],
+ SMI_ACC2X2_ACC_Z_MSB)<<(SMI_ACC2X2_ACC_Z14_LSB__LEN));
+ *a_z = *a_z << (sizeof(short)*8-(SMI_ACC2X2_ACC_Z14_LSB__LEN
+ + SMI_ACC2X2_ACC_Z_MSB__LEN));
+ *a_z = *a_z >> (sizeof(short)*8-(SMI_ACC2X2_ACC_Z14_LSB__LEN
+ + SMI_ACC2X2_ACC_Z_MSB__LEN));
+ break;
+ default:
+ break;
+ }
+
+ return comres;
+}
+
+
+static int smi130_acc_read_temperature(struct i2c_client *client,
+ signed char *temperature)
+{
+ unsigned char data = 0;
+ int comres = 0;
+
+ comres = smi130_acc_smbus_read_byte(client, SMI_ACC2X2_TEMPERATURE_REG, &data);
+ *temperature = (signed char)data;
+
+ return comres;
+}
+
+static ssize_t smi130_acc_enable_int_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int type, value;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+#ifdef CONFIG_SENSORS_BMI058
+ int i;
+#endif
+
+ sscanf(buf, "%3d %3d", &type, &value);
+
+#ifdef CONFIG_SENSORS_BMI058
+ for (i = 0; i < sizeof(int_map) / sizeof(struct interrupt_map_t); i++) {
+ if (int_map[i].x == type) {
+ type = int_map[i].y;
+ break;
+ }
+ if (int_map[i].y == type) {
+ type = int_map[i].x;
+ break;
+ }
+ }
+#endif
+
+ if (smi130_acc_set_Int_Enable(smi130_acc->smi130_acc_client, type, value) < 0)
+ return -EINVAL;
+
+ return count;
+}
+
+
+static ssize_t smi130_acc_int_mode_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_Int_Mode(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_acc_int_mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if (smi130_acc_set_Int_Mode(smi130_acc->smi130_acc_client, (unsigned char)data) < 0)
+ return -EINVAL;
+
+ return count;
+}
+static ssize_t smi130_acc_slope_duration_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_slope_duration(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_slope_duration_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if (smi130_acc_set_slope_duration(smi130_acc->smi130_acc_client, (unsigned
+ char)data) < 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static ssize_t smi130_acc_slope_no_mot_duration_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_slope_no_mot_duration(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_slope_no_mot_duration_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if (smi130_acc_set_slope_no_mot_duration(smi130_acc->smi130_acc_client, (unsigned
+ char)data) < 0)
+ return -EINVAL;
+
+ return count;
+}
+
+
+static ssize_t smi130_acc_slope_threshold_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_slope_threshold(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_slope_threshold_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+ if (smi130_acc_set_slope_threshold(smi130_acc->smi130_acc_client, (unsigned
+ char)data) < 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static ssize_t smi130_acc_slope_no_mot_threshold_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_slope_no_mot_threshold(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_slope_no_mot_threshold_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+ if (smi130_acc_set_slope_no_mot_threshold(smi130_acc->smi130_acc_client, (unsigned
+ char)data) < 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static ssize_t smi130_acc_high_g_duration_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_high_g_duration(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_high_g_duration_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if (smi130_acc_set_high_g_duration(smi130_acc->smi130_acc_client, (unsigned
+ char)data) < 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static ssize_t smi130_acc_high_g_threshold_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_high_g_threshold(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_high_g_threshold_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+ if (smi130_acc_set_high_g_threshold(smi130_acc->smi130_acc_client, (unsigned
+ char)data) < 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static ssize_t smi130_acc_low_g_duration_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_low_g_duration(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_low_g_duration_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if (smi130_acc_set_low_g_duration(smi130_acc->smi130_acc_client, (unsigned
+ char)data) < 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static ssize_t smi130_acc_low_g_threshold_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_low_g_threshold(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_low_g_threshold_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+ if (smi130_acc_set_low_g_threshold(smi130_acc->smi130_acc_client, (unsigned
+ char)data) < 0)
+ return -EINVAL;
+
+ return count;
+}
+static ssize_t smi130_acc_tap_threshold_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_tap_threshold(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_tap_threshold_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+ if (smi130_acc_set_tap_threshold(smi130_acc->smi130_acc_client, (unsigned char)data)
+ < 0)
+ return -EINVAL;
+
+ return count;
+}
+static ssize_t smi130_acc_tap_duration_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_tap_duration(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_tap_duration_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if (smi130_acc_set_tap_duration(smi130_acc->smi130_acc_client, (unsigned char)data)
+ < 0)
+ return -EINVAL;
+
+ return count;
+}
+static ssize_t smi130_acc_tap_quiet_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_tap_quiet(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_tap_quiet_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if (smi130_acc_set_tap_quiet(smi130_acc->smi130_acc_client, (unsigned char)data) <
+ 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static ssize_t smi130_acc_tap_shock_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_tap_shock(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_tap_shock_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if (smi130_acc_set_tap_shock(smi130_acc->smi130_acc_client, (unsigned char)data) <
+ 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static ssize_t smi130_acc_tap_samp_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_tap_samp(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_tap_samp_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if (smi130_acc_set_tap_samp(smi130_acc->smi130_acc_client, (unsigned char)data) < 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static ssize_t smi130_acc_orient_mbl_mode_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_orient_mbl_mode(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_orient_mbl_mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if (smi130_acc_set_orient_mbl_mode(smi130_acc->smi130_acc_client, (unsigned char)data) <
+ 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static ssize_t smi130_acc_orient_mbl_blocking_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_orient_mbl_blocking(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_orient_mbl_blocking_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if (smi130_acc_set_orient_mbl_blocking(smi130_acc->smi130_acc_client, (unsigned
+ char)data) < 0)
+ return -EINVAL;
+
+ return count;
+}
+static ssize_t smi130_acc_orient_mbl_hyst_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_orient_mbl_hyst(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_orient_mbl_hyst_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if (smi130_acc_set_orient_mbl_hyst(smi130_acc->smi130_acc_client, (unsigned char)data) <
+ 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static ssize_t smi130_acc_orient_mbl_theta_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_theta_blocking(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_orient_mbl_theta_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if (smi130_acc_set_theta_blocking(smi130_acc->smi130_acc_client, (unsigned
+ char)data) < 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static ssize_t smi130_acc_flat_theta_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_theta_flat(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_flat_theta_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if (smi130_acc_set_theta_flat(smi130_acc->smi130_acc_client, (unsigned char)data) <
+ 0)
+ return -EINVAL;
+
+ return count;
+}
+static ssize_t smi130_acc_flat_hold_time_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_flat_hold_time(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+static ssize_t smi130_acc_selftest_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+
+
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ return snprintf(buf, 16, "%d\n", atomic_read(&smi130_acc->selftest_result));
+
+}
+
+static ssize_t smi130_acc_softreset_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_soft_reset(smi130_acc->smi130_acc_client) < 0)
+ return -EINVAL;
+
+ return count;
+}
+static ssize_t smi130_acc_selftest_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+
+ unsigned long data;
+ unsigned char clear_value = 0;
+ int error;
+ short value1 = 0;
+ short value2 = 0;
+ short diff = 0;
+ unsigned long result = 0;
+ unsigned char test_result_branch = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ smi130_acc_soft_reset(smi130_acc->smi130_acc_client);
+ smi130_acc_delay(5);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if (data != 1)
+ return -EINVAL;
+
+ smi130_acc_write_reg(smi130_acc->smi130_acc_client, 0x32, &clear_value);
+
+ if ((smi130_acc->sensor_type == SMI_ACC280_TYPE) ||
+ (smi130_acc->sensor_type == SMI_ACC255_TYPE)) {
+#ifdef CONFIG_SENSORS_BMI058
+ /*set self test amp */
+ if (smi130_acc_set_selftest_amp(smi130_acc->smi130_acc_client, 1) < 0)
+ return -EINVAL;
+ /* set to 8 G range */
+ if (smi130_acc_set_range(smi130_acc->smi130_acc_client,
+ SMI_ACC2X2_RANGE_8G) < 0)
+ return -EINVAL;
+#else
+ /* set to 4 G range */
+ if (smi130_acc_set_range(smi130_acc->smi130_acc_client,
+ SMI_ACC2X2_RANGE_4G) < 0)
+ return -EINVAL;
+#endif
+ }
+
+ if ((smi130_acc->sensor_type == SMI_ACC250E_TYPE) ||
+ (smi130_acc->sensor_type == SMI_ACC222E_TYPE)) {
+ /* set to 8 G range */
+ if (smi130_acc_set_range(smi130_acc->smi130_acc_client, 8) < 0)
+ return -EINVAL;
+ if (smi130_acc_set_selftest_amp(smi130_acc->smi130_acc_client, 1) < 0)
+ return -EINVAL;
+ }
+
+ /* 1 for x-axis(but BMI058 is 1 for y-axis )*/
+ smi130_acc_set_selftest_st(smi130_acc->smi130_acc_client, 1);
+ smi130_acc_set_selftest_stn(smi130_acc->smi130_acc_client, 0);
+ smi130_acc_delay(10);
+ smi130_acc_read_accel_x(smi130_acc->smi130_acc_client,
+ smi130_acc->sensor_type, &value1);
+ smi130_acc_set_selftest_stn(smi130_acc->smi130_acc_client, 1);
+ smi130_acc_delay(10);
+ smi130_acc_read_accel_x(smi130_acc->smi130_acc_client,
+ smi130_acc->sensor_type, &value2);
+ diff = value1-value2;
+
+#ifdef CONFIG_SENSORS_BMI058
+ PINFO("diff y is %d,value1 is %d, value2 is %d\n", diff,
+ value1, value2);
+ test_result_branch = 2;
+#else
+ PINFO("diff x is %d,value1 is %d, value2 is %d\n", diff,
+ value1, value2);
+ test_result_branch = 1;
+#endif
+
+ if (smi130_acc->sensor_type == SMI_ACC280_TYPE) {
+#ifdef CONFIG_SENSORS_BMI058
+ if (abs(diff) < 819)
+ result |= test_result_branch;
+#else
+ if (abs(diff) < 1638)
+ result |= test_result_branch;
+#endif
+ }
+ if (smi130_acc->sensor_type == SMI_ACC255_TYPE) {
+ if (abs(diff) < 409)
+ result |= 1;
+ }
+ if (smi130_acc->sensor_type == SMI_ACC250E_TYPE) {
+ if (abs(diff) < 51)
+ result |= 1;
+ }
+ if (smi130_acc->sensor_type == SMI_ACC222E_TYPE) {
+ if (abs(diff) < 12)
+ result |= 1;
+ }
+
+ /* 2 for y-axis but BMI058 is 1*/
+ smi130_acc_set_selftest_st(smi130_acc->smi130_acc_client, 2);
+ smi130_acc_set_selftest_stn(smi130_acc->smi130_acc_client, 0);
+ smi130_acc_delay(10);
+ smi130_acc_read_accel_y(smi130_acc->smi130_acc_client,
+ smi130_acc->sensor_type, &value1);
+ smi130_acc_set_selftest_stn(smi130_acc->smi130_acc_client, 1);
+ smi130_acc_delay(10);
+ smi130_acc_read_accel_y(smi130_acc->smi130_acc_client,
+ smi130_acc->sensor_type, &value2);
+ diff = value1-value2;
+
+#ifdef CONFIG_SENSORS_BMI058
+ PINFO("diff x is %d,value1 is %d, value2 is %d\n", diff,
+ value1, value2);
+ test_result_branch = 1;
+#else
+ PINFO("diff y is %d,value1 is %d, value2 is %d\n", diff,
+ value1, value2);
+ test_result_branch = 2;
+#endif
+
+ if (smi130_acc->sensor_type == SMI_ACC280_TYPE) {
+#ifdef CONFIG_SENSORS_BMI058
+ if (abs(diff) < 819)
+ result |= test_result_branch;
+#else
+ if (abs(diff) < 1638)
+ result |= test_result_branch;
+#endif
+ }
+ if (smi130_acc->sensor_type == SMI_ACC255_TYPE) {
+ if (abs(diff) < 409)
+ result |= test_result_branch;
+ }
+ if (smi130_acc->sensor_type == SMI_ACC250E_TYPE) {
+ if (abs(diff) < 51)
+ result |= test_result_branch;
+ }
+ if (smi130_acc->sensor_type == SMI_ACC222E_TYPE) {
+ if (abs(diff) < 12)
+ result |= test_result_branch;
+ }
+
+
+ smi130_acc_set_selftest_st(smi130_acc->smi130_acc_client, 3); /* 3 for z-axis*/
+ smi130_acc_set_selftest_stn(smi130_acc->smi130_acc_client, 0);
+ smi130_acc_delay(10);
+ smi130_acc_read_accel_z(smi130_acc->smi130_acc_client,
+ smi130_acc->sensor_type, &value1);
+ smi130_acc_set_selftest_stn(smi130_acc->smi130_acc_client, 1);
+ smi130_acc_delay(10);
+ smi130_acc_read_accel_z(smi130_acc->smi130_acc_client,
+ smi130_acc->sensor_type, &value2);
+ diff = value1-value2;
+
+ PINFO("diff z is %d,value1 is %d, value2 is %d\n", diff,
+ value1, value2);
+
+ if (smi130_acc->sensor_type == SMI_ACC280_TYPE) {
+#ifdef CONFIG_SENSORS_BMI058
+ if (abs(diff) < 409)
+ result |= 4;
+#else
+ if (abs(diff) < 819)
+ result |= 4;
+#endif
+ }
+ if (smi130_acc->sensor_type == SMI_ACC255_TYPE) {
+ if (abs(diff) < 204)
+ result |= 4;
+ }
+ if (smi130_acc->sensor_type == SMI_ACC250E_TYPE) {
+ if (abs(diff) < 25)
+ result |= 4;
+ }
+ if (smi130_acc->sensor_type == SMI_ACC222E_TYPE) {
+ if (abs(diff) < 6)
+ result |= 4;
+ }
+
+ /* self test for smi_acc254 */
+ if ((smi130_acc->sensor_type == SMI_ACC255_TYPE) && (result > 0)) {
+ result = 0;
+ smi130_acc_soft_reset(smi130_acc->smi130_acc_client);
+ smi130_acc_delay(5);
+ smi130_acc_write_reg(smi130_acc->smi130_acc_client, 0x32, &clear_value);
+ /* set to 8 G range */
+ if (smi130_acc_set_range(smi130_acc->smi130_acc_client, 8) < 0)
+ return -EINVAL;
+ if (smi130_acc_set_selftest_amp(smi130_acc->smi130_acc_client, 1) < 0)
+ return -EINVAL;
+
+ smi130_acc_set_selftest_st(smi130_acc->smi130_acc_client, 1); /* 1
+ for x-axis*/
+ smi130_acc_set_selftest_stn(smi130_acc->smi130_acc_client, 0); /*
+ positive direction*/
+ smi130_acc_delay(10);
+ smi130_acc_read_accel_x(smi130_acc->smi130_acc_client,
+ smi130_acc->sensor_type, &value1);
+ smi130_acc_set_selftest_stn(smi130_acc->smi130_acc_client, 1); /*
+ negative direction*/
+ smi130_acc_delay(10);
+ smi130_acc_read_accel_x(smi130_acc->smi130_acc_client,
+ smi130_acc->sensor_type, &value2);
+ diff = value1-value2;
+
+ PINFO("diff x is %d,value1 is %d, value2 is %d\n",
+ diff, value1, value2);
+ if (abs(diff) < 204)
+ result |= 1;
+
+ smi130_acc_set_selftest_st(smi130_acc->smi130_acc_client, 2); /* 2
+ for y-axis*/
+ smi130_acc_set_selftest_stn(smi130_acc->smi130_acc_client, 0); /*
+ positive direction*/
+ smi130_acc_delay(10);
+ smi130_acc_read_accel_y(smi130_acc->smi130_acc_client,
+ smi130_acc->sensor_type, &value1);
+ smi130_acc_set_selftest_stn(smi130_acc->smi130_acc_client, 1); /*
+ negative direction*/
+ smi130_acc_delay(10);
+ smi130_acc_read_accel_y(smi130_acc->smi130_acc_client,
+ smi130_acc->sensor_type, &value2);
+ diff = value1-value2;
+ PINFO("diff y is %d,value1 is %d, value2 is %d\n",
+ diff, value1, value2);
+
+ if (abs(diff) < 204)
+ result |= 2;
+
+ smi130_acc_set_selftest_st(smi130_acc->smi130_acc_client, 3); /* 3
+ for z-axis*/
+ smi130_acc_set_selftest_stn(smi130_acc->smi130_acc_client, 0); /*
+ positive direction*/
+ smi130_acc_delay(10);
+ smi130_acc_read_accel_z(smi130_acc->smi130_acc_client,
+ smi130_acc->sensor_type, &value1);
+ smi130_acc_set_selftest_stn(smi130_acc->smi130_acc_client, 1); /*
+ negative direction*/
+ smi130_acc_delay(10);
+ smi130_acc_read_accel_z(smi130_acc->smi130_acc_client,
+ smi130_acc->sensor_type, &value2);
+ diff = value1-value2;
+
+ PINFO("diff z is %d,value1 is %d, value2 is %d\n",
+ diff, value1, value2);
+ if (abs(diff) < 102)
+ result |= 4;
+ }
+
+ atomic_set(&smi130_acc->selftest_result, (unsigned int)result);
+
+ smi130_acc_soft_reset(smi130_acc->smi130_acc_client);
+ smi130_acc_delay(5);
+ PINFO("self test finished\n");
+
+ return count;
+}
+
+
+
+static ssize_t smi130_acc_flat_hold_time_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if (smi130_acc_set_flat_hold_time(smi130_acc->smi130_acc_client, (unsigned
+ char)data) < 0)
+ return -EINVAL;
+
+ return count;
+}
+
+const int smi130_acc_sensor_bitwidth[] = {
+ 12, 10, 8, 14
+};
+
+static int smi130_acc_read_accel_xyz(struct i2c_client *client,
+ signed char sensor_type, struct smi130_accacc *acc)
+{
+ int comres = 0;
+ unsigned char data[6];
+ struct smi130_acc_data *client_data = i2c_get_clientdata(client);
+#ifndef SMI_ACC2X2_SENSOR_IDENTIFICATION_ENABLE
+ int bitwidth;
+#endif
+ comres = smi130_acc_smbus_read_byte_block(client,
+ SMI_ACC2X2_ACC_X12_LSB__REG, data, 6);
+ if (sensor_type >= 4)
+ return -EINVAL;
+
+ acc->x = (data[1]<<8)|data[0];
+ acc->y = (data[3]<<8)|data[2];
+ acc->z = (data[5]<<8)|data[4];
+
+#ifndef SMI_ACC2X2_SENSOR_IDENTIFICATION_ENABLE
+ bitwidth = smi130_acc_sensor_bitwidth[sensor_type];
+
+ acc->x = (acc->x >> (16 - bitwidth));
+ acc->y = (acc->y >> (16 - bitwidth));
+ acc->z = (acc->z >> (16 - bitwidth));
+#endif
+
+ smi130_acc_remap_sensor_data(acc, client_data);
+ return comres;
+}
+
+#ifndef CONFIG_SMI_ACC_ENABLE_NEWDATA_INT
+static void smi130_acc_work_func(struct work_struct *work)
+{
+ struct smi130_acc_data *smi130_acc = container_of((struct delayed_work *)work,
+ struct smi130_acc_data, work);
+ static struct smi130_accacc acc;
+ unsigned long delay = msecs_to_jiffies(atomic_read(&smi130_acc->delay));
+
+ smi130_acc_read_accel_xyz(smi130_acc->smi130_acc_client, smi130_acc->sensor_type, &acc);
+ input_report_abs(smi130_acc->input, ABS_X, acc.x);
+ input_report_abs(smi130_acc->input, ABS_Y, acc.y);
+ input_report_abs(smi130_acc->input, ABS_Z, acc.z);
+ input_sync(smi130_acc->input);
+ mutex_lock(&smi130_acc->value_mutex);
+ smi130_acc->value = acc;
+ mutex_unlock(&smi130_acc->value_mutex);
+ schedule_delayed_work(&smi130_acc->work, delay);
+}
+#endif
+static struct workqueue_struct *reportdata_wq;
+
+uint64_t smi130_acc_get_alarm_timestamp(void)
+{
+ uint64_t ts_ap;
+ struct timespec tmp_time;
+ get_monotonic_boottime(&tmp_time);
+ ts_ap = (uint64_t)tmp_time.tv_sec * 1000000000 + tmp_time.tv_nsec;
+ return ts_ap;
+}
+
+#define ABS(x) ((x) > 0 ? (x) : -(x))
+
+static void smi130_acc_timer_work_fun(struct work_struct *work)
+{
+ struct smi130_acc_data *smi130_acc =
+ container_of(work,
+ struct smi130_acc_data, report_data_work);
+ int i;
+ unsigned char count = 0;
+ unsigned char mode = 0;
+ signed char fifo_data_out[MAX_FIFO_F_LEVEL * MAX_FIFO_F_BYTES] = {0};
+ unsigned char f_len = 0;
+ uint64_t del = 0;
+ uint64_t time_internal = 0;
+ int64_t drift_time = 0;
+ static uint64_t time_odr;
+ struct smi130_accacc acc_lsb;
+ struct timespec ts;
+ static uint32_t data_cnt;
+ static uint32_t pre_data_cnt;
+ static int64_t sample_drift_offset;
+
+ if (smi130_acc->fifo_datasel) {
+ /*Select one axis data output for every fifo frame*/
+ f_len = 2;
+ } else {
+ /*Select X Y Z axis data output for every fifo frame*/
+ f_len = 6;
+ }
+ if (smi130_acc_get_fifo_framecount(smi130_acc->smi130_acc_client, &count) < 0) {
+ PERR("smi130_acc_get_fifo_framecount err\n");
+ return;
+ }
+ if (count == 0) {
+ PERR("smi130_acc_get_fifo_framecount zero\n");
+ return;
+ }
+ if (count > MAX_FIFO_F_LEVEL) {
+ if (smi130_acc_get_mode(smi130_acc->smi130_acc_client, &mode) < 0) {
+ PERR("smi130_acc_get_mode err\n");
+ return;
+ }
+ if (SMI_ACC2X2_MODE_NORMAL == mode) {
+ PERR("smi130_acc fifo_count: %d abnormal, op_mode: %d\n",
+ count, mode);
+ count = MAX_FIFO_F_LEVEL;
+ } else {
+ /*chip already suspend or shutdown*/
+ count = 0;
+ return;
+ }
+ }
+ if (smi_acc_i2c_burst_read(smi130_acc->smi130_acc_client,
+ SMI_ACC2X2_FIFO_DATA_OUTPUT_REG, fifo_data_out,
+ count * f_len) < 0) {
+ PERR("smi130_acc read fifo err\n");
+ return;
+ }
+ smi130_acc->fifo_time = smi130_acc_get_alarm_timestamp();
+ if (smi130_acc->acc_count == 0)
+ smi130_acc->base_time = smi130_acc->timestamp =
+ smi130_acc->fifo_time - (count-1) * smi130_acc->time_odr;
+
+ smi130_acc->acc_count += count;
+ del = smi130_acc->fifo_time - smi130_acc->base_time;
+ time_internal = div64_u64(del, smi130_acc->acc_count);
+
+ data_cnt++;
+ if (data_cnt == 1)
+ time_odr = smi130_acc->time_odr;
+
+ if (time_internal > time_odr) {
+ if (time_internal - time_odr > div64_u64 (time_odr, 200))
+ time_internal = time_odr + div64_u64(time_odr, 200);
+ } else {
+ if (time_odr - time_internal > div64_u64(time_odr, 200))
+ time_internal = time_odr - div64_u64(time_odr, 200);
+ }
+/* please give attation for the fifo output data format*/
+ if (f_len == 6) {
+ /* Select X Y Z axis data output for every frame */
+ for (i = 0; i < count; i++) {
+ if (smi130_acc->debug_level & 0x01)
+ printk(KERN_INFO "smi_acc time =%llu fifo_time =%llu smi_acc->count=%llu time_internal =%lld time_odr = %lld ",
+ smi130_acc->timestamp, smi130_acc->fifo_time,
+ smi130_acc->acc_count, time_internal, time_odr);
+
+ ts = ns_to_timespec(smi130_acc->timestamp);
+ acc_lsb.x =
+ ((unsigned char)fifo_data_out[i * f_len + 1] << 8 |
+ (unsigned char)fifo_data_out[i * f_len + 0]);
+ acc_lsb.y =
+ ((unsigned char)fifo_data_out[i * f_len + 3] << 8 |
+ (unsigned char)fifo_data_out[i * f_len + 2]);
+ acc_lsb.z =
+ ((unsigned char)fifo_data_out[i * f_len + 5] << 8 |
+ (unsigned char)fifo_data_out[i * f_len + 4]);
+#ifndef SMI_ACC2X2_SENSOR_IDENTIFICATION_ENABLE
+ acc_lsb.x >>=
+ (16 - smi130_acc_sensor_bitwidth[smi130_acc->sensor_type]);
+ acc_lsb.y >>=
+ (16 - smi130_acc_sensor_bitwidth[smi130_acc->sensor_type]);
+ acc_lsb.z >>=
+ (16 - smi130_acc_sensor_bitwidth[smi130_acc->sensor_type]);
+#endif
+ smi130_acc_remap_sensor_data(&acc_lsb, smi130_acc);
+ input_event(smi130_acc->input, EV_MSC, MSC_TIME,
+ ts.tv_sec);
+ input_event(smi130_acc->input, EV_MSC, MSC_TIME,
+ ts.tv_nsec);
+ input_event(smi130_acc->input, EV_MSC,
+ MSC_GESTURE, acc_lsb.x);
+ input_event(smi130_acc->input, EV_MSC,
+ MSC_RAW, acc_lsb.y);
+ input_event(smi130_acc->input, EV_MSC,
+ MSC_SCAN, acc_lsb.z);
+ input_sync(smi130_acc->input);
+ smi130_acc->timestamp +=
+ time_internal - sample_drift_offset;
+ }
+ }
+ drift_time = smi130_acc->timestamp - smi130_acc->fifo_time;
+ if (data_cnt % 20 == 0) {
+ if (ABS(drift_time) > div64_u64(time_odr, 5)) {
+ sample_drift_offset =
+ div64_s64(drift_time, smi130_acc->acc_count - pre_data_cnt);
+ pre_data_cnt = smi130_acc->acc_count;
+ time_odr = time_internal;
+ }
+ }
+
+}
+
+static enum hrtimer_restart reportdata_timer_fun(
+ struct hrtimer *hrtimer)
+{
+ struct smi130_acc_data *client_data =
+ container_of(hrtimer, struct smi130_acc_data, timer);
+ int32_t delay = 0;
+ delay = 8;
+ queue_work(reportdata_wq, &(client_data->report_data_work));
+ /*set delay 8ms*/
+ client_data->work_delay_kt = ns_to_ktime(delay*1000000);
+ hrtimer_forward(hrtimer, ktime_get(), client_data->work_delay_kt);
+
+ return HRTIMER_RESTART;
+}
+
+static ssize_t smi130_acc_enable_timer_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ return snprintf(buf, 16, "%d\n", smi130_acc->is_timer_running);
+}
+
+static ssize_t smi130_acc_enable_timer_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if (data) {
+ if (0 == smi130_acc->is_timer_running) {
+ hrtimer_start(&smi130_acc->timer,
+ ns_to_ktime(1000000),
+ HRTIMER_MODE_REL);
+ smi130_acc->base_time = 0;
+ smi130_acc->timestamp = 0;
+ smi130_acc->is_timer_running = 1;
+ }
+ } else {
+ if (1 == smi130_acc->is_timer_running) {
+ hrtimer_cancel(&smi130_acc->timer);
+ smi130_acc->is_timer_running = 0;
+ smi130_acc->base_time = 0;
+ smi130_acc->timestamp = 0;
+ smi130_acc->fifo_time = 0;
+ smi130_acc->acc_count = 0;
+ }
+ }
+ return count;
+}
+
+static ssize_t smi130_acc_debug_level_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+ err = snprintf(buf, 8, "%d\n", smi130_acc->debug_level);
+ return err;
+}
+static ssize_t smi130_acc_debug_level_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int32_t ret = 0;
+ unsigned long data;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ ret = kstrtoul(buf, 16, &data);
+ if (ret)
+ return ret;
+ smi130_acc->debug_level = (uint8_t)data;
+ return count;
+}
+
+static ssize_t smi130_acc_register_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int address, value;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ sscanf(buf, "%3d %3d", &address, &value);
+ if (smi130_acc_write_reg(smi130_acc->smi130_acc_client, (unsigned char)address,
+ (unsigned char *)&value) < 0)
+ return -EINVAL;
+ return count;
+}
+static ssize_t smi130_acc_register_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ size_t count = 0;
+ u8 reg[0x40];
+ int i;
+
+ for (i = 0; i < 0x40; i++) {
+ smi130_acc_smbus_read_byte(smi130_acc->smi130_acc_client, i, reg+i);
+
+ count += snprintf(&buf[count], 32, "0x%x: %d\n", i, reg[i]);
+ }
+ return count;
+
+
+}
+
+static ssize_t smi130_acc_range_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_range(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_acc_range_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+ if (smi130_acc_set_range(smi130_acc->smi130_acc_client, (unsigned char) data) < 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static ssize_t smi130_acc_bandwidth_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_bandwidth(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_bandwidth_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if (smi130_acc->sensor_type == SMI_ACC280_TYPE)
+ if ((unsigned char) data > 14)
+ return -EINVAL;
+
+ if (smi130_acc_set_bandwidth(smi130_acc->smi130_acc_client,
+ (unsigned char) data) < 0)
+ return -EINVAL;
+ smi130_acc->base_time = 0;
+ smi130_acc->acc_count = 0;
+
+ return count;
+}
+
+static ssize_t smi130_acc_mode_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_mode(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+ return snprintf(buf, 32, "%d %d\n", data, smi130_acc->smi_acc_mode_enabled);
+}
+
+static ssize_t smi130_acc_mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+ if (smi130_acc_set_mode(smi130_acc->smi130_acc_client,
+ (unsigned char) data, SMI_ACC_ENABLED_BSX) < 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static ssize_t smi130_acc_value_cache_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi130_acc_data *smi130_acc = input_get_drvdata(input);
+ struct smi130_accacc acc_value;
+
+ mutex_lock(&smi130_acc->value_mutex);
+ acc_value = smi130_acc->value;
+ mutex_unlock(&smi130_acc->value_mutex);
+
+ return snprintf(buf, 96, "%d %d %d\n", acc_value.x, acc_value.y,
+ acc_value.z);
+}
+
+static ssize_t smi130_acc_value_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi130_acc_data *smi130_acc = input_get_drvdata(input);
+ struct smi130_accacc acc_value;
+
+ smi130_acc_read_accel_xyz(smi130_acc->smi130_acc_client, smi130_acc->sensor_type,
+ &acc_value);
+
+ return snprintf(buf, 96, "%d %d %d\n", acc_value.x, acc_value.y,
+ acc_value.z);
+}
+
+static ssize_t smi130_acc_delay_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ return snprintf(buf, 16, "%d\n", atomic_read(&smi130_acc->delay));
+
+}
+
+static ssize_t smi130_acc_chip_id_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ return snprintf(buf, 16, "%u\n", smi130_acc->chip_id);
+
+}
+
+
+static ssize_t smi130_acc_place_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+ int place = BOSCH_SENSOR_PLACE_UNKNOWN;
+
+ if (NULL != smi130_acc->bosch_pd)
+ place = smi130_acc->bosch_pd->place;
+
+ return snprintf(buf, 16, "%d\n", place);
+}
+
+
+static ssize_t smi130_acc_delay_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+ if (data > SMI_ACC2X2_MAX_DELAY)
+ data = SMI_ACC2X2_MAX_DELAY;
+ atomic_set(&smi130_acc->delay, (unsigned int) data);
+
+ return count;
+}
+
+
+static ssize_t smi130_acc_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ return snprintf(buf, 16, "%d\n", atomic_read(&smi130_acc->enable));
+
+}
+
+static void smi130_acc_set_enable(struct device *dev, int enable)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+ int pre_enable = atomic_read(&smi130_acc->enable);
+
+ mutex_lock(&smi130_acc->enable_mutex);
+ if (enable) {
+ if (pre_enable == 0) {
+ smi130_acc_set_mode(smi130_acc->smi130_acc_client,
+ SMI_ACC2X2_MODE_NORMAL, SMI_ACC_ENABLED_INPUT);
+
+ #ifndef CONFIG_SMI_ACC_ENABLE_NEWDATA_INT
+ schedule_delayed_work(&smi130_acc->work,
+ msecs_to_jiffies(atomic_read(&smi130_acc->delay)));
+#endif
+ atomic_set(&smi130_acc->enable, 1);
+ }
+
+ } else {
+ if (pre_enable == 1) {
+ smi130_acc_set_mode(smi130_acc->smi130_acc_client,
+ SMI_ACC2X2_MODE_SUSPEND, SMI_ACC_ENABLED_INPUT);
+
+ #ifndef CONFIG_SMI_ACC_ENABLE_NEWDATA_INT
+ cancel_delayed_work_sync(&smi130_acc->work);
+#endif
+ atomic_set(&smi130_acc->enable, 0);
+ }
+ }
+ mutex_unlock(&smi130_acc->enable_mutex);
+
+}
+
+static ssize_t smi130_acc_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+ if ((data == 0) || (data == 1))
+ smi130_acc_set_enable(dev, data);
+
+ return count;
+}
+static ssize_t smi130_acc_fast_calibration_x_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+
+
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+#ifdef CONFIG_SENSORS_BMI058
+ if (smi130_acc_get_offset_target(smi130_acc->smi130_acc_client,
+ BMI058_OFFSET_TRIGGER_X, &data) < 0)
+ return -EINVAL;
+#else
+ if (smi130_acc_get_offset_target(smi130_acc->smi130_acc_client,
+ SMI_ACC2X2_OFFSET_TRIGGER_X, &data) < 0)
+ return -EINVAL;
+#endif
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_fast_calibration_x_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ signed char tmp;
+ unsigned char timeout = 0;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+#ifdef CONFIG_SENSORS_BMI058
+ if (smi130_acc_set_offset_target(smi130_acc->smi130_acc_client,
+ BMI058_OFFSET_TRIGGER_X, (unsigned char)data) < 0)
+ return -EINVAL;
+#else
+ if (smi130_acc_set_offset_target(smi130_acc->smi130_acc_client,
+ SMI_ACC2X2_OFFSET_TRIGGER_X, (unsigned char)data) < 0)
+ return -EINVAL;
+#endif
+
+ if (smi130_acc_set_cal_trigger(smi130_acc->smi130_acc_client, 1) < 0)
+ return -EINVAL;
+
+ do {
+ smi130_acc_delay(2);
+ smi130_acc_get_cal_ready(smi130_acc->smi130_acc_client, &tmp);
+
+ /*PINFO("wait 2ms cal ready flag is %d\n", tmp); */
+ timeout++;
+ if (timeout == 50) {
+ PINFO("get fast calibration ready error\n");
+ return -EINVAL;
+ };
+
+ } while (tmp == 0);
+
+ PINFO("x axis fast calibration finished\n");
+ return count;
+}
+
+static ssize_t smi130_acc_fast_calibration_y_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+
+
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+#ifdef CONFIG_SENSORS_BMI058
+ if (smi130_acc_get_offset_target(smi130_acc->smi130_acc_client,
+ BMI058_OFFSET_TRIGGER_Y, &data) < 0)
+ return -EINVAL;
+#else
+ if (smi130_acc_get_offset_target(smi130_acc->smi130_acc_client,
+ SMI_ACC2X2_OFFSET_TRIGGER_Y, &data) < 0)
+ return -EINVAL;
+#endif
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_fast_calibration_y_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ signed char tmp;
+ unsigned char timeout = 0;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+#ifdef CONFIG_SENSORS_BMI058
+ if (smi130_acc_set_offset_target(smi130_acc->smi130_acc_client,
+ BMI058_OFFSET_TRIGGER_Y, (unsigned char)data) < 0)
+ return -EINVAL;
+#else
+ if (smi130_acc_set_offset_target(smi130_acc->smi130_acc_client,
+ SMI_ACC2X2_OFFSET_TRIGGER_Y, (unsigned char)data) < 0)
+ return -EINVAL;
+#endif
+
+ if (smi130_acc_set_cal_trigger(smi130_acc->smi130_acc_client, 2) < 0)
+ return -EINVAL;
+
+ do {
+ smi130_acc_delay(2);
+ smi130_acc_get_cal_ready(smi130_acc->smi130_acc_client, &tmp);
+
+ /*PINFO("wait 2ms cal ready flag is %d\n", tmp);*/
+ timeout++;
+ if (timeout == 50) {
+ PINFO("get fast calibration ready error\n");
+ return -EINVAL;
+ };
+
+ } while (tmp == 0);
+
+ PINFO("y axis fast calibration finished\n");
+ return count;
+}
+
+static ssize_t smi130_acc_fast_calibration_z_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+
+
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_offset_target(smi130_acc->smi130_acc_client, 3, &data) < 0)
+ return -EINVAL;
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_fast_calibration_z_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ signed char tmp;
+ unsigned char timeout = 0;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if (smi130_acc_set_offset_target(smi130_acc->smi130_acc_client, 3, (unsigned
+ char)data) < 0)
+ return -EINVAL;
+
+ if (smi130_acc_set_cal_trigger(smi130_acc->smi130_acc_client, 3) < 0)
+ return -EINVAL;
+
+ do {
+ smi130_acc_delay(2);
+ smi130_acc_get_cal_ready(smi130_acc->smi130_acc_client, &tmp);
+
+ /*PINFO("wait 2ms cal ready flag is %d\n", tmp);*/
+ timeout++;
+ if (timeout == 50) {
+ PINFO("get fast calibration ready error\n");
+ return -EINVAL;
+ };
+
+ } while (tmp == 0);
+
+ PINFO("z axis fast calibration finished\n");
+ return count;
+}
+
+
+static ssize_t smi130_acc_SleepDur_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_sleep_duration(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_SleepDur_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+ if (smi130_acc_set_sleep_duration(smi130_acc->smi130_acc_client,
+ (unsigned char) data) < 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static ssize_t smi130_acc_fifo_mode_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_fifo_mode(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_fifo_mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+ if (smi130_acc_set_fifo_mode(smi130_acc->smi130_acc_client,
+ (unsigned char) data) < 0)
+ return -EINVAL;
+ return count;
+}
+
+
+
+static ssize_t smi130_acc_fifo_trig_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_fifo_trig(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_fifo_trig_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+ if (smi130_acc_set_fifo_trig(smi130_acc->smi130_acc_client,
+ (unsigned char) data) < 0)
+ return -EINVAL;
+
+ return count;
+}
+
+
+
+static ssize_t smi130_acc_fifo_trig_src_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_fifo_trig_src(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_fifo_trig_src_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+ if (smi130_acc_set_fifo_trig_src(smi130_acc->smi130_acc_client,
+ (unsigned char) data) < 0)
+ return -EINVAL;
+
+ return count;
+}
+
+
+/*!
+ * @brief show fifo_data_sel axis definition(Android definition, not sensor HW reg).
+ * 0--> x, y, z axis fifo data for every frame
+ * 1--> only x axis fifo data for every frame
+ * 2--> only y axis fifo data for every frame
+ * 3--> only z axis fifo data for every frame
+ */
+static ssize_t smi130_acc_fifo_data_sel_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+ signed char place = BOSCH_SENSOR_PLACE_UNKNOWN;
+ if (smi130_acc_get_fifo_data_sel(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+#ifdef CONFIG_SENSORS_BMI058
+/*Update BMI058 fifo_data_sel to the SMI130_ACC common definition*/
+ if (BMI058_FIFO_DAT_SEL_X == data)
+ data = SMI_ACC2X2_FIFO_DAT_SEL_X;
+ else if (BMI058_FIFO_DAT_SEL_Y == data)
+ data = SMI_ACC2X2_FIFO_DAT_SEL_Y;
+#endif
+
+ /*remaping fifo_dat_sel if define virtual place in BSP files*/
+ if ((NULL != smi130_acc->bosch_pd) &&
+ (BOSCH_SENSOR_PLACE_UNKNOWN != smi130_acc->bosch_pd->place)) {
+ place = smi130_acc->bosch_pd->place;
+ /* sensor with place 0 needs not to be remapped */
+ if ((place > 0) && (place < MAX_AXIS_REMAP_TAB_SZ)) {
+ /* SMI_ACC2X2_FIFO_DAT_SEL_X: 1, Y:2, Z:3;
+ * but bosch_axis_remap_tab_dft[i].src_x:0, y:1, z:2
+ * so we need to +1*/
+ if (SMI_ACC2X2_FIFO_DAT_SEL_X == data)
+ data = bosch_axis_remap_tab_dft[place].src_x + 1;
+ else if (SMI_ACC2X2_FIFO_DAT_SEL_Y == data)
+ data = bosch_axis_remap_tab_dft[place].src_y + 1;
+ }
+ }
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_fifo_framecount_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ unsigned char mode;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_fifo_framecount(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+ if (data > MAX_FIFO_F_LEVEL) {
+
+ if (smi130_acc_get_mode(smi130_acc->smi130_acc_client, &mode) < 0)
+ return -EINVAL;
+
+ if (SMI_ACC2X2_MODE_NORMAL == mode) {
+ PERR("smi130_acc fifo_count: %d abnormal, op_mode: %d",
+ data, mode);
+ data = MAX_FIFO_F_LEVEL;
+ } else {
+ /*chip already suspend or shutdown*/
+ data = 0;
+ }
+ }
+
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_acc_fifo_framecount_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+ smi130_acc->fifo_count = (unsigned int) data;
+
+ return count;
+}
+
+static ssize_t smi130_acc_temperature_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_read_temperature(smi130_acc->smi130_acc_client, &data) < 0)
+ return -EINVAL;
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+/*!
+ * @brief store fifo_data_sel axis definition(Android definition, not sensor HW reg).
+ * 0--> x, y, z axis fifo data for every frame
+ * 1--> only x axis fifo data for every frame
+ * 2--> only y axis fifo data for every frame
+ * 3--> only z axis fifo data for every frame
+ */
+static ssize_t smi130_acc_fifo_data_sel_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+ signed char place;
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+ /*save fifo_data_sel(android definition)*/
+ smi130_acc->fifo_datasel = (unsigned char) data;
+
+ /*remaping fifo_dat_sel if define virtual place*/
+ if ((NULL != smi130_acc->bosch_pd) &&
+ (BOSCH_SENSOR_PLACE_UNKNOWN != smi130_acc->bosch_pd->place)) {
+ place = smi130_acc->bosch_pd->place;
+ /* sensor with place 0 needs not to be remapped */
+ if ((place > 0) && (place < MAX_AXIS_REMAP_TAB_SZ)) {
+ /*Need X Y axis revesal sensor place: P1, P3, P5, P7 */
+ /* SMI_ACC2X2_FIFO_DAT_SEL_X: 1, Y:2, Z:3;
+ * but bosch_axis_remap_tab_dft[i].src_x:0, y:1, z:2
+ * so we need to +1*/
+ if (SMI_ACC2X2_FIFO_DAT_SEL_X == data)
+ data = bosch_axis_remap_tab_dft[place].src_x + 1;
+ else if (SMI_ACC2X2_FIFO_DAT_SEL_Y == data)
+ data = bosch_axis_remap_tab_dft[place].src_y + 1;
+ }
+ }
+#ifdef CONFIG_SENSORS_BMI058
+ /*Update BMI058 fifo_data_sel to the SMI130_ACC common definition*/
+ if (SMI_ACC2X2_FIFO_DAT_SEL_X == data)
+ data = BMI058_FIFO_DAT_SEL_X;
+ else if (SMI_ACC2X2_FIFO_DAT_SEL_Y == data)
+ data = BMI058_FIFO_DAT_SEL_Y;
+
+#endif
+ if (smi130_acc_set_fifo_data_sel(smi130_acc->smi130_acc_client,
+ (unsigned char) data) < 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static ssize_t smi130_acc_fifo_data_out_frame_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char f_len = 0;
+ unsigned char count = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+ if (smi130_acc->fifo_datasel) {
+ /*Select one axis data output for every fifo frame*/
+ f_len = 2;
+ } else {
+ /*Select X Y Z axis data output for every fifo frame*/
+ f_len = 6;
+ }
+ if (smi130_acc_get_fifo_framecount(smi130_acc->smi130_acc_client, &count) < 0) {
+ PERR("smi130_acc_get_fifo_framecount err\n");
+ return -EINVAL;
+ }
+ if (count == 0)
+ return 0;
+ if (smi_acc_i2c_burst_read(smi130_acc->smi130_acc_client,
+ SMI_ACC2X2_FIFO_DATA_OUTPUT_REG, buf,
+ count * f_len) < 0)
+ return -EINVAL;
+
+ return count * f_len;
+}
+
+static ssize_t smi130_acc_offset_x_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_offset_x(smi130_acc->smi130_acc_client, &data) < 0)
+ return snprintf(buf, 48, "Read error\n");
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_offset_x_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if (smi130_acc_set_offset_x(smi130_acc->smi130_acc_client, (unsigned
+ char)data) < 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static ssize_t smi130_acc_offset_y_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_offset_y(smi130_acc->smi130_acc_client, &data) < 0)
+ return snprintf(buf, 48, "Read error\n");
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_offset_y_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if (smi130_acc_set_offset_y(smi130_acc->smi130_acc_client, (unsigned
+ char)data) < 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static ssize_t smi130_acc_offset_z_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ if (smi130_acc_get_offset_z(smi130_acc->smi130_acc_client, &data) < 0)
+ return snprintf(buf, 48, "Read error\n");
+
+ return snprintf(buf, 16, "%d\n", data);
+
+}
+
+static ssize_t smi130_acc_offset_z_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if (smi130_acc_set_offset_z(smi130_acc->smi130_acc_client, (unsigned
+ char)data) < 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static ssize_t smi130_acc_driver_version_show(struct device *dev
+ , struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+ int ret;
+
+ if (smi130_acc == NULL) {
+ printk(KERN_ERR "Invalid client_data pointer");
+ return -ENODEV;
+ }
+
+ ret = snprintf(buf, 128, "Driver version: %s\n",
+ DRIVER_VERSION);
+ return ret;
+}
+
+#ifdef CONFIG_SIG_MOTION
+static int smi130_acc_set_en_slope_int(struct smi130_acc_data *smi130_acc,
+ int en)
+{
+ int err;
+ struct i2c_client *client = smi130_acc->smi130_acc_client;
+
+ if (en) {
+ /* Set the related parameters which needs to be fine tuned by
+ * interfaces: slope_threshold and slope_duration
+ */
+ /*dur: 192 samples ~= 3s*/
+ err = smi130_acc_set_slope_duration(client, 0x0);
+ err += smi130_acc_set_slope_threshold(client, 0x16);
+
+ /*Enable the interrupts*/
+ err += smi130_acc_set_Int_Enable(client, 5, 1);/*Slope X*/
+ err += smi130_acc_set_Int_Enable(client, 6, 1);/*Slope Y*/
+ err += smi130_acc_set_Int_Enable(client, 7, 1);/*Slope Z*/
+ #ifdef SMI_ACC2X2_ENABLE_INT1
+ /* TODO: SLOPE can now only be routed to INT1 pin*/
+ err += smi130_acc_set_int1_pad_sel(client, PAD_SLOP);
+ #else
+ /* err += smi130_acc_set_int2_pad_sel(client, PAD_SLOP); */
+ #endif
+ } else {
+ err = smi130_acc_set_Int_Enable(client, 5, 0);/*Slope X*/
+ err += smi130_acc_set_Int_Enable(client, 6, 0);/*Slope Y*/
+ err += smi130_acc_set_Int_Enable(client, 7, 0);/*Slope Z*/
+ }
+ return err;
+}
+
+static ssize_t smi130_acc_en_sig_motion_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ return snprintf(buf, 16, "%d\n", atomic_read(&smi130_acc->en_sig_motion));
+}
+
+static int smi130_acc_set_en_sig_motion(struct smi130_acc_data *smi130_acc,
+ int en)
+{
+ int err = 0;
+
+ en = (en >= 1) ? 1 : 0; /* set sig motion sensor status */
+
+ if (atomic_read(&smi130_acc->en_sig_motion) != en) {
+ if (en) {
+ err = smi130_acc_set_mode(smi130_acc->smi130_acc_client,
+ SMI_ACC2X2_MODE_NORMAL, SMI_ACC_ENABLED_SGM);
+ err = smi130_acc_set_en_slope_int(smi130_acc, en);
+ enable_irq_wake(smi130_acc->IRQ);
+ } else {
+ disable_irq_wake(smi130_acc->IRQ);
+ err = smi130_acc_set_en_slope_int(smi130_acc, en);
+ err = smi130_acc_set_mode(smi130_acc->smi130_acc_client,
+ SMI_ACC2X2_MODE_SUSPEND, SMI_ACC_ENABLED_SGM);
+ }
+ atomic_set(&smi130_acc->en_sig_motion, en);
+ }
+ return err;
+}
+
+static ssize_t smi130_acc_en_sig_motion_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if ((data == 0) || (data == 1))
+ smi130_acc_set_en_sig_motion(smi130_acc, data);
+
+ return count;
+}
+#endif
+
+#ifdef CONFIG_DOUBLE_TAP
+static int smi130_acc_set_en_single_tap_int(struct smi130_acc_data *smi130_acc, int en)
+{
+ int err;
+ struct i2c_client *client = smi130_acc->smi130_acc_client;
+
+ if (en) {
+ /* set tap interruption parameter here if needed.
+ smi130_acc_set_tap_duration(client, 0xc0);
+ smi130_acc_set_tap_threshold(client, 0x16);
+ */
+
+ /*Enable the single tap interrupts*/
+ err = smi130_acc_set_Int_Enable(client, 8, 1);
+ #ifdef SMI_ACC2X2_ENABLE_INT1
+ err += smi130_acc_set_int1_pad_sel(client, PAD_SINGLE_TAP);
+ #else
+ err += smi130_acc_set_int2_pad_sel(client, PAD_SINGLE_TAP);
+ #endif
+ } else {
+ err = smi130_acc_set_Int_Enable(client, 8, 0);
+ }
+ return err;
+}
+
+static ssize_t smi130_acc_tap_time_period_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ return snprintf(buf, 16, "%d\n", smi130_acc->tap_time_period);
+}
+
+static ssize_t smi130_acc_tap_time_period_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ smi130_acc->tap_time_period = data;
+
+ return count;
+}
+
+static ssize_t smi130_acc_en_double_tap_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ return snprintf(buf, 16, "%d\n", atomic_read(&smi130_acc->en_double_tap));
+}
+
+static int smi130_acc_set_en_double_tap(struct smi130_acc_data *smi130_acc,
+ int en)
+{
+ int err = 0;
+
+ en = (en >= 1) ? 1 : 0;
+
+ if (atomic_read(&smi130_acc->en_double_tap) != en) {
+ if (en) {
+ err = smi130_acc_set_mode(smi130_acc->smi130_acc_client,
+ SMI_ACC2X2_MODE_NORMAL, SMI_ACC_ENABLED_DTAP);
+ err = smi130_acc_set_en_single_tap_int(smi130_acc, en);
+ } else {
+ err = smi130_acc_set_en_single_tap_int(smi130_acc, en);
+ err = smi130_acc_set_mode(smi130_acc->smi130_acc_client,
+ SMI_ACC2X2_MODE_SUSPEND, SMI_ACC_ENABLED_DTAP);
+ }
+ atomic_set(&smi130_acc->en_double_tap, en);
+ }
+ return err;
+}
+
+static ssize_t smi130_acc_en_double_tap_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client);
+
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if ((data == 0) || (data == 1))
+ smi130_acc_set_en_double_tap(smi130_acc, data);
+
+ return count;
+}
+
+static void smi130_acc_tap_timeout_handle(unsigned long data)
+{
+ struct smi130_acc_data *smi130_acc = (struct smi130_acc_data *)data;
+
+ PINFO("tap interrupt handle, timeout\n");
+ mutex_lock(&smi130_acc->tap_mutex);
+ smi130_acc->tap_times = 0;
+ mutex_unlock(&smi130_acc->tap_mutex);
+
+ /* if a single tap need to report, open the define */
+#ifdef REPORT_SINGLE_TAP_WHEN_DOUBLE_TAP_SENSOR_ENABLED
+ input_report_rel(smi130_acc->dev_interrupt,
+ SINGLE_TAP_INTERRUPT,
+ SINGLE_TAP_INTERRUPT_HAPPENED);
+ input_sync(smi130_acc->dev_interrupt);
+#endif
+
+}
+#endif
+
+static DEVICE_ATTR(range, S_IRUGO | S_IWUSR,
+ smi130_acc_range_show, smi130_acc_range_store);
+static DEVICE_ATTR(bandwidth, S_IRUGO | S_IWUSR,
+ smi130_acc_bandwidth_show, smi130_acc_bandwidth_store);
+static DEVICE_ATTR(op_mode, S_IRUGO | S_IWUSR,
+ smi130_acc_mode_show, smi130_acc_mode_store);
+static DEVICE_ATTR(value, S_IRUSR,
+ smi130_acc_value_show, NULL);
+static DEVICE_ATTR(value_cache, S_IRUSR,
+ smi130_acc_value_cache_show, NULL);
+static DEVICE_ATTR(delay, S_IRUGO | S_IWUSR,
+ smi130_acc_delay_show, smi130_acc_delay_store);
+static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR,
+ smi130_acc_enable_show, smi130_acc_enable_store);
+static DEVICE_ATTR(SleepDur, S_IRUGO | S_IWUSR,
+ smi130_acc_SleepDur_show, smi130_acc_SleepDur_store);
+static DEVICE_ATTR(fast_calibration_x, S_IRUGO | S_IWUSR,
+ smi130_acc_fast_calibration_x_show,
+ smi130_acc_fast_calibration_x_store);
+static DEVICE_ATTR(fast_calibration_y, S_IRUGO | S_IWUSR,
+ smi130_acc_fast_calibration_y_show,
+ smi130_acc_fast_calibration_y_store);
+static DEVICE_ATTR(fast_calibration_z, S_IRUGO | S_IWUSR,
+ smi130_acc_fast_calibration_z_show,
+ smi130_acc_fast_calibration_z_store);
+static DEVICE_ATTR(fifo_mode, S_IRUGO | S_IWUSR,
+ smi130_acc_fifo_mode_show, smi130_acc_fifo_mode_store);
+static DEVICE_ATTR(fifo_framecount, S_IRUGO | S_IWUSR,
+ smi130_acc_fifo_framecount_show, smi130_acc_fifo_framecount_store);
+static DEVICE_ATTR(fifo_trig, S_IRUGO | S_IWUSR,
+ smi130_acc_fifo_trig_show, smi130_acc_fifo_trig_store);
+static DEVICE_ATTR(fifo_trig_src, S_IRUGO | S_IWUSR,
+ smi130_acc_fifo_trig_src_show, smi130_acc_fifo_trig_src_store);
+static DEVICE_ATTR(fifo_data_sel, S_IRUGO | S_IWUSR,
+ smi130_acc_fifo_data_sel_show, smi130_acc_fifo_data_sel_store);
+static DEVICE_ATTR(fifo_data_frame, S_IRUGO,
+ smi130_acc_fifo_data_out_frame_show, NULL);
+static DEVICE_ATTR(reg, S_IRUGO | S_IWUSR,
+ smi130_acc_register_show, smi130_acc_register_store);
+static DEVICE_ATTR(chip_id, S_IRUSR,
+ smi130_acc_chip_id_show, NULL);
+static DEVICE_ATTR(offset_x, S_IRUGO | S_IWUSR,
+ smi130_acc_offset_x_show,
+ smi130_acc_offset_x_store);
+static DEVICE_ATTR(offset_y, S_IRUGO | S_IWUSR,
+ smi130_acc_offset_y_show,
+ smi130_acc_offset_y_store);
+static DEVICE_ATTR(offset_z, S_IRUGO | S_IWUSR,
+ smi130_acc_offset_z_show,
+ smi130_acc_offset_z_store);
+static DEVICE_ATTR(enable_int, S_IWUSR,
+ NULL, smi130_acc_enable_int_store);
+static DEVICE_ATTR(int_mode, S_IRUGO | S_IWUSR,
+ smi130_acc_int_mode_show, smi130_acc_int_mode_store);
+static DEVICE_ATTR(slope_duration, S_IRUGO | S_IWUSR,
+ smi130_acc_slope_duration_show, smi130_acc_slope_duration_store);
+static DEVICE_ATTR(slope_threshold, S_IRUGO | S_IWUSR,
+ smi130_acc_slope_threshold_show, smi130_acc_slope_threshold_store);
+static DEVICE_ATTR(slope_no_mot_duration, S_IRUGO | S_IWUSR,
+ smi130_acc_slope_no_mot_duration_show,
+ smi130_acc_slope_no_mot_duration_store);
+static DEVICE_ATTR(slope_no_mot_threshold, S_IRUGO | S_IWUSR,
+ smi130_acc_slope_no_mot_threshold_show,
+ smi130_acc_slope_no_mot_threshold_store);
+static DEVICE_ATTR(high_g_duration, S_IRUGO | S_IWUSR,
+ smi130_acc_high_g_duration_show, smi130_acc_high_g_duration_store);
+static DEVICE_ATTR(high_g_threshold, S_IRUGO | S_IWUSR,
+ smi130_acc_high_g_threshold_show, smi130_acc_high_g_threshold_store);
+static DEVICE_ATTR(low_g_duration, S_IRUGO | S_IWUSR,
+ smi130_acc_low_g_duration_show, smi130_acc_low_g_duration_store);
+static DEVICE_ATTR(low_g_threshold, S_IRUGO | S_IWUSR,
+ smi130_acc_low_g_threshold_show, smi130_acc_low_g_threshold_store);
+static DEVICE_ATTR(tap_duration, S_IRUGO | S_IWUSR,
+ smi130_acc_tap_duration_show, smi130_acc_tap_duration_store);
+static DEVICE_ATTR(tap_threshold, S_IRUGO | S_IWUSR,
+ smi130_acc_tap_threshold_show, smi130_acc_tap_threshold_store);
+static DEVICE_ATTR(tap_quiet, S_IRUGO | S_IWUSR,
+ smi130_acc_tap_quiet_show, smi130_acc_tap_quiet_store);
+static DEVICE_ATTR(tap_shock, S_IRUGO | S_IWUSR,
+ smi130_acc_tap_shock_show, smi130_acc_tap_shock_store);
+static DEVICE_ATTR(tap_samp, S_IRUGO | S_IWUSR,
+ smi130_acc_tap_samp_show, smi130_acc_tap_samp_store);
+static DEVICE_ATTR(orient_mbl_mode, S_IRUGO | S_IWUSR,
+ smi130_acc_orient_mbl_mode_show, smi130_acc_orient_mbl_mode_store);
+static DEVICE_ATTR(orient_mbl_blocking, S_IRUGO | S_IWUSR,
+ smi130_acc_orient_mbl_blocking_show, smi130_acc_orient_mbl_blocking_store);
+static DEVICE_ATTR(orient_mbl_hyst, S_IRUGO | S_IWUSR,
+ smi130_acc_orient_mbl_hyst_show, smi130_acc_orient_mbl_hyst_store);
+static DEVICE_ATTR(orient_mbl_theta, S_IRUGO | S_IWUSR,
+ smi130_acc_orient_mbl_theta_show, smi130_acc_orient_mbl_theta_store);
+static DEVICE_ATTR(flat_theta, S_IRUGO | S_IWUSR,
+ smi130_acc_flat_theta_show, smi130_acc_flat_theta_store);
+static DEVICE_ATTR(flat_hold_time, S_IRUGO | S_IWUSR,
+ smi130_acc_flat_hold_time_show, smi130_acc_flat_hold_time_store);
+static DEVICE_ATTR(selftest, S_IRUGO | S_IWUSR,
+ smi130_acc_selftest_show, smi130_acc_selftest_store);
+static DEVICE_ATTR(softreset, S_IWUSR,
+ NULL, smi130_acc_softreset_store);
+static DEVICE_ATTR(enable_timer, S_IRUGO | S_IWUSR,
+ smi130_acc_enable_timer_show, smi130_acc_enable_timer_store);
+static DEVICE_ATTR(debug_level, S_IRUGO | S_IWUSR,
+ smi130_acc_debug_level_show, smi130_acc_debug_level_store);
+static DEVICE_ATTR(temperature, S_IRUSR,
+ smi130_acc_temperature_show, NULL);
+static DEVICE_ATTR(place, S_IRUSR,
+ smi130_acc_place_show, NULL);
+static DEVICE_ATTR(driver_version, S_IRUSR,
+ smi130_acc_driver_version_show, NULL);
+
+#ifdef CONFIG_SIG_MOTION
+static DEVICE_ATTR(en_sig_motion, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH,
+ smi130_acc_en_sig_motion_show, smi130_acc_en_sig_motion_store);
+#endif
+#ifdef CONFIG_DOUBLE_TAP
+static DEVICE_ATTR(tap_time_period, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH,
+ smi130_acc_tap_time_period_show, smi130_acc_tap_time_period_store);
+static DEVICE_ATTR(en_double_tap, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH,
+ smi130_acc_en_double_tap_show, smi130_acc_en_double_tap_store);
+#endif
+
+static struct attribute *smi130_acc_attributes[] = {
+ &dev_attr_range.attr,
+ &dev_attr_bandwidth.attr,
+ &dev_attr_op_mode.attr,
+ &dev_attr_value.attr,
+ &dev_attr_value_cache.attr,
+ &dev_attr_delay.attr,
+ &dev_attr_enable.attr,
+ &dev_attr_SleepDur.attr,
+ &dev_attr_reg.attr,
+ &dev_attr_fast_calibration_x.attr,
+ &dev_attr_fast_calibration_y.attr,
+ &dev_attr_fast_calibration_z.attr,
+ &dev_attr_fifo_mode.attr,
+ &dev_attr_fifo_framecount.attr,
+ &dev_attr_fifo_trig.attr,
+ &dev_attr_fifo_trig_src.attr,
+ &dev_attr_fifo_data_sel.attr,
+ &dev_attr_fifo_data_frame.attr,
+ &dev_attr_chip_id.attr,
+ &dev_attr_offset_x.attr,
+ &dev_attr_offset_y.attr,
+ &dev_attr_offset_z.attr,
+ &dev_attr_enable_int.attr,
+ &dev_attr_enable_timer.attr,
+ &dev_attr_debug_level.attr,
+ &dev_attr_int_mode.attr,
+ &dev_attr_slope_duration.attr,
+ &dev_attr_slope_threshold.attr,
+ &dev_attr_slope_no_mot_duration.attr,
+ &dev_attr_slope_no_mot_threshold.attr,
+ &dev_attr_high_g_duration.attr,
+ &dev_attr_high_g_threshold.attr,
+ &dev_attr_low_g_duration.attr,
+ &dev_attr_low_g_threshold.attr,
+ &dev_attr_tap_threshold.attr,
+ &dev_attr_tap_duration.attr,
+ &dev_attr_tap_quiet.attr,
+ &dev_attr_tap_shock.attr,
+ &dev_attr_tap_samp.attr,
+ &dev_attr_orient_mbl_mode.attr,
+ &dev_attr_orient_mbl_blocking.attr,
+ &dev_attr_orient_mbl_hyst.attr,
+ &dev_attr_orient_mbl_theta.attr,
+ &dev_attr_flat_theta.attr,
+ &dev_attr_flat_hold_time.attr,
+ &dev_attr_selftest.attr,
+ &dev_attr_softreset.attr,
+ &dev_attr_temperature.attr,
+ &dev_attr_place.attr,
+ &dev_attr_driver_version.attr,
+#ifdef CONFIG_SIG_MOTION
+ &dev_attr_en_sig_motion.attr,
+#endif
+#ifdef CONFIG_DOUBLE_TAP
+ &dev_attr_en_double_tap.attr,
+#endif
+
+ NULL
+};
+
+static struct attribute_group smi130_acc_attribute_group = {
+ .attrs = smi130_acc_attributes
+};
+
+#ifdef CONFIG_SIG_MOTION
+static struct attribute *smi130_acc_sig_motion_attributes[] = {
+ &dev_attr_slope_duration.attr,
+ &dev_attr_slope_threshold.attr,
+ &dev_attr_en_sig_motion.attr,
+ NULL
+};
+static struct attribute_group smi130_acc_sig_motion_attribute_group = {
+ .attrs = smi130_acc_sig_motion_attributes
+};
+#endif
+
+#ifdef CONFIG_DOUBLE_TAP
+static struct attribute *smi130_acc_double_tap_attributes[] = {
+ &dev_attr_tap_threshold.attr,
+ &dev_attr_tap_duration.attr,
+ &dev_attr_tap_quiet.attr,
+ &dev_attr_tap_shock.attr,
+ &dev_attr_tap_samp.attr,
+ &dev_attr_tap_time_period.attr,
+ &dev_attr_en_double_tap.attr,
+ NULL
+};
+static struct attribute_group smi130_acc_double_tap_attribute_group = {
+ .attrs = smi130_acc_double_tap_attributes
+};
+#endif
+
+
+#if defined(SMI_ACC2X2_ENABLE_INT1) || defined(SMI_ACC2X2_ENABLE_INT2)
+unsigned char *orient_mbl[] = {"upward looking portrait upright",
+ "upward looking portrait upside-down",
+ "upward looking landscape left",
+ "upward looking landscape right",
+ "downward looking portrait upright",
+ "downward looking portrait upside-down",
+ "downward looking landscape left",
+ "downward looking landscape right"};
+
+
+static void smi130_acc_high_g_interrupt_handle(struct smi130_acc_data *smi130_acc)
+{
+ unsigned char first_value = 0;
+ unsigned char sign_value = 0;
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ smi130_acc_get_HIGH_first(smi130_acc->smi130_acc_client, i, &first_value);
+ if (first_value == 1) {
+ smi130_acc_get_HIGH_sign(smi130_acc->smi130_acc_client,
+ &sign_value);
+ if (sign_value == 1) {
+ if (i == 0)
+ input_report_rel(smi130_acc->dev_interrupt,
+ HIGH_G_INTERRUPT,
+ HIGH_G_INTERRUPT_X_N);
+ if (i == 1)
+ input_report_rel(smi130_acc->dev_interrupt,
+ HIGH_G_INTERRUPT,
+ HIGH_G_INTERRUPT_Y_N);
+ if (i == 2)
+ input_report_rel(smi130_acc->dev_interrupt,
+ HIGH_G_INTERRUPT,
+ HIGH_G_INTERRUPT_Z_N);
+ } else {
+ if (i == 0)
+ input_report_rel(smi130_acc->dev_interrupt,
+ HIGH_G_INTERRUPT,
+ HIGH_G_INTERRUPT_X);
+ if (i == 1)
+ input_report_rel(smi130_acc->dev_interrupt,
+ HIGH_G_INTERRUPT,
+ HIGH_G_INTERRUPT_Y);
+ if (i == 2)
+ input_report_rel(smi130_acc->dev_interrupt,
+ HIGH_G_INTERRUPT,
+ HIGH_G_INTERRUPT_Z);
+ }
+ }
+
+ PINFO("High G interrupt happened,exis is %d,\n\n"
+ "first is %d,sign is %d\n", i,
+ first_value, sign_value);
+ }
+
+
+}
+
+#ifndef CONFIG_SIG_MOTION
+static void smi130_acc_slope_interrupt_handle(struct smi130_acc_data *smi130_acc)
+{
+ unsigned char first_value = 0;
+ unsigned char sign_value = 0;
+ int i;
+ for (i = 0; i < 3; i++) {
+ smi130_acc_get_slope_first(smi130_acc->smi130_acc_client, i, &first_value);
+ if (first_value == 1) {
+ smi130_acc_get_slope_sign(smi130_acc->smi130_acc_client,
+ &sign_value);
+ if (sign_value == 1) {
+ if (i == 0)
+ input_report_rel(smi130_acc->dev_interrupt,
+ SLOP_INTERRUPT,
+ SLOPE_INTERRUPT_X_N);
+ if (i == 1)
+ input_report_rel(smi130_acc->dev_interrupt,
+ SLOP_INTERRUPT,
+ SLOPE_INTERRUPT_Y_N);
+ if (i == 2)
+ input_report_rel(smi130_acc->dev_interrupt,
+ SLOP_INTERRUPT,
+ SLOPE_INTERRUPT_Z_N);
+ } else {
+ if (i == 0)
+ input_report_rel(smi130_acc->dev_interrupt,
+ SLOP_INTERRUPT,
+ SLOPE_INTERRUPT_X);
+ if (i == 1)
+ input_report_rel(smi130_acc->dev_interrupt,
+ SLOP_INTERRUPT,
+ SLOPE_INTERRUPT_Y);
+ if (i == 2)
+ input_report_rel(smi130_acc->dev_interrupt,
+ SLOP_INTERRUPT,
+ SLOPE_INTERRUPT_Z);
+
+ }
+ }
+
+ PINFO("Slop interrupt happened,exis is %d,\n\n"
+ "first is %d,sign is %d\n", i,
+ first_value, sign_value);
+ }
+}
+#endif
+
+static void smi130_acc_irq_work_func(struct work_struct *work)
+{
+ struct smi130_acc_data *smi130_acc = container_of((struct work_struct *)work,
+ struct smi130_acc_data, irq_work);
+#ifdef CONFIG_DOUBLE_TAP
+ struct i2c_client *client = smi130_acc->smi130_acc_client;
+#endif
+
+ unsigned char status = 0;
+ unsigned char first_value = 0;
+ unsigned char sign_value = 0;
+
+#ifdef CONFIG_SMI_ACC_ENABLE_NEWDATA_INT
+ static struct smi130_accacc acc;
+ struct timespec ts;
+ /*
+ do not use this function judge new data interrupt
+ smi130_acc_get_interruptstatus2(smi130_acc->smi130_acc_client, &status);
+ use the
+ x-axis value bit new_data_x
+ y-axis value bit new_data_y
+ z-axis value bit new_data_z
+ judge if this is the new data
+ */
+ /* PINFO("New data interrupt happened\n");*/
+ smi130_acc_read_accel_xyz(smi130_acc->smi130_acc_client,
+ smi130_acc->sensor_type, &acc);
+ ts = ns_to_timespec(smi130_acc->timestamp);
+ //if ((acc.x & SMI_ACC2X2_NEW_DATA_X__MSK) &&
+ // (acc.y & SMI_ACC2X2_NEW_DATA_Y__MSK) &&
+ // (acc.x & SMI_ACC2X2_NEW_DATA_Z__MSK))
+ {
+ input_event(smi130_acc->input, EV_MSC, MSC_TIME,
+ ts.tv_sec);
+ input_event(smi130_acc->input, EV_MSC, MSC_TIME,
+ ts.tv_nsec);
+ input_event(smi130_acc->input, EV_MSC,
+ MSC_GESTURE, acc.x);
+ input_event(smi130_acc->input, EV_MSC,
+ MSC_RAW, acc.y);
+ input_event(smi130_acc->input, EV_MSC,
+ MSC_SCAN, acc.z);
+ input_sync(smi130_acc->input);
+ mutex_lock(&smi130_acc->value_mutex);
+ smi130_acc->value = acc;
+ mutex_unlock(&smi130_acc->value_mutex);
+ }
+#endif
+
+ smi130_acc_get_interruptstatus1(smi130_acc->smi130_acc_client, &status);
+ PINFO("smi130_acc_irq_work_func, status = 0x%x\n", status);
+
+#ifdef CONFIG_SIG_MOTION
+ if (status & 0x04) {
+ if (atomic_read(&smi130_acc->en_sig_motion) == 1) {
+ PINFO("Significant motion interrupt happened\n");
+ /* close sig sensor,
+ it will be open again if APP wants */
+ smi130_acc_set_en_sig_motion(smi130_acc, 0);
+
+ input_report_rel(smi130_acc->dev_interrupt,
+ SLOP_INTERRUPT, 1);
+ input_sync(smi130_acc->dev_interrupt);
+ }
+ }
+#endif
+
+#ifdef CONFIG_DOUBLE_TAP
+ if (status & 0x20) {
+ if (atomic_read(&smi130_acc->en_double_tap) == 1) {
+ PINFO("single tap interrupt happened\n");
+ smi130_acc_set_Int_Enable(client, 8, 0);
+ if (smi130_acc->tap_times == 0) {
+ mod_timer(&smi130_acc->tap_timer, jiffies +
+ msecs_to_jiffies(smi130_acc->tap_time_period));
+ smi130_acc->tap_times = 1;
+ } else {
+ /* only double tap is judged */
+ PINFO("double tap\n");
+ mutex_lock(&smi130_acc->tap_mutex);
+ smi130_acc->tap_times = 0;
+ del_timer(&smi130_acc->tap_timer);
+ mutex_unlock(&smi130_acc->tap_mutex);
+ input_report_rel(smi130_acc->dev_interrupt,
+ DOUBLE_TAP_INTERRUPT,
+ DOUBLE_TAP_INTERRUPT_HAPPENED);
+ input_sync(smi130_acc->dev_interrupt);
+ }
+ smi130_acc_set_Int_Enable(client, 8, 1);
+ }
+ }
+#endif
+
+ switch (status) {
+
+ case 0x01:
+ PINFO("Low G interrupt happened\n");
+ input_report_rel(smi130_acc->dev_interrupt, LOW_G_INTERRUPT,
+ LOW_G_INTERRUPT_HAPPENED);
+ break;
+
+ case 0x02:
+ smi130_acc_high_g_interrupt_handle(smi130_acc);
+ break;
+
+#ifndef CONFIG_SIG_MOTION
+ case 0x04:
+ smi130_acc_slope_interrupt_handle(smi130_acc);
+ break;
+#endif
+
+ case 0x08:
+ PINFO("slow/ no motion interrupt happened\n");
+ input_report_rel(smi130_acc->dev_interrupt,
+ SLOW_NO_MOTION_INTERRUPT,
+ SLOW_NO_MOTION_INTERRUPT_HAPPENED);
+ break;
+
+#ifndef CONFIG_DOUBLE_TAP
+ case 0x10:
+ PINFO("double tap interrupt happened\n");
+ input_report_rel(smi130_acc->dev_interrupt,
+ DOUBLE_TAP_INTERRUPT,
+ DOUBLE_TAP_INTERRUPT_HAPPENED);
+ break;
+ case 0x20:
+ PINFO("single tap interrupt happened\n");
+ input_report_rel(smi130_acc->dev_interrupt,
+ SINGLE_TAP_INTERRUPT,
+ SINGLE_TAP_INTERRUPT_HAPPENED);
+ break;
+#endif
+
+ case 0x40:
+ smi130_acc_get_orient_mbl_status(smi130_acc->smi130_acc_client,
+ &first_value);
+ PINFO("orient_mbl interrupt happened,%s\n",
+ orient_mbl[first_value]);
+ if (first_value == 0)
+ input_report_abs(smi130_acc->dev_interrupt,
+ ORIENT_INTERRUPT,
+ UPWARD_PORTRAIT_UP_INTERRUPT_HAPPENED);
+ else if (first_value == 1)
+ input_report_abs(smi130_acc->dev_interrupt,
+ ORIENT_INTERRUPT,
+ UPWARD_PORTRAIT_DOWN_INTERRUPT_HAPPENED);
+ else if (first_value == 2)
+ input_report_abs(smi130_acc->dev_interrupt,
+ ORIENT_INTERRUPT,
+ UPWARD_LANDSCAPE_LEFT_INTERRUPT_HAPPENED);
+ else if (first_value == 3)
+ input_report_abs(smi130_acc->dev_interrupt,
+ ORIENT_INTERRUPT,
+ UPWARD_LANDSCAPE_RIGHT_INTERRUPT_HAPPENED);
+ else if (first_value == 4)
+ input_report_abs(smi130_acc->dev_interrupt,
+ ORIENT_INTERRUPT,
+ DOWNWARD_PORTRAIT_UP_INTERRUPT_HAPPENED);
+ else if (first_value == 5)
+ input_report_abs(smi130_acc->dev_interrupt,
+ ORIENT_INTERRUPT,
+ DOWNWARD_PORTRAIT_DOWN_INTERRUPT_HAPPENED);
+ else if (first_value == 6)
+ input_report_abs(smi130_acc->dev_interrupt,
+ ORIENT_INTERRUPT,
+ DOWNWARD_LANDSCAPE_LEFT_INTERRUPT_HAPPENED);
+ else if (first_value == 7)
+ input_report_abs(smi130_acc->dev_interrupt,
+ ORIENT_INTERRUPT,
+ DOWNWARD_LANDSCAPE_RIGHT_INTERRUPT_HAPPENED);
+ break;
+ case 0x80:
+ smi130_acc_get_orient_mbl_flat_status(smi130_acc->smi130_acc_client,
+ &sign_value);
+ PINFO("flat interrupt happened,flat status is %d\n",
+ sign_value);
+ if (sign_value == 1) {
+ input_report_abs(smi130_acc->dev_interrupt,
+ FLAT_INTERRUPT,
+ FLAT_INTERRUPT_TURE_HAPPENED);
+ } else {
+ input_report_abs(smi130_acc->dev_interrupt,
+ FLAT_INTERRUPT,
+ FLAT_INTERRUPT_FALSE_HAPPENED);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+static irqreturn_t smi130_acc_irq_handler(int irq, void *handle)
+{
+ struct smi130_acc_data *data = handle;
+
+ if (data == NULL)
+ return IRQ_HANDLED;
+ if (data->smi130_acc_client == NULL)
+ return IRQ_HANDLED;
+ data->timestamp = smi130_acc_get_alarm_timestamp();
+
+ schedule_work(&data->irq_work);
+
+ return IRQ_HANDLED;
+}
+#endif /* defined(SMI_ACC2X2_ENABLE_INT1)||defined(SMI_ACC2X2_ENABLE_INT2) */
+
+
+static int smi130_acc_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int err = 0;
+ struct smi130_acc_data *data;
+ struct input_dev *dev;
+ struct bosch_dev *dev_acc;
+#if defined(SMI_ACC2X2_ENABLE_INT1) || defined(SMI_ACC2X2_ENABLE_INT2)
+ struct bosch_sensor_specific *pdata;
+#endif
+ struct input_dev *dev_interrupt;
+
+ PINFO("smi130_acc_probe start\n");
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ PERR("i2c_check_functionality error\n");
+ err = -EIO;
+ goto exit;
+ }
+ data = kzalloc(sizeof(struct smi130_acc_data), GFP_KERNEL);
+ if (!data) {
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ /* read and check chip id */
+ if (smi130_acc_check_chip_id(client, data) < 0) {
+ err = -EINVAL;
+ goto kfree_exit;
+ }
+
+ /* do soft reset */
+ smi130_acc_delay(5);
+ if (smi130_acc_soft_reset(client) < 0) {
+ PERR("i2c bus write error, pls check HW connection\n");
+ err = -EINVAL;
+ goto kfree_exit;
+ }
+ smi130_acc_delay(20);
+
+ i2c_set_clientdata(client, data);
+ data->smi130_acc_client = client;
+ mutex_init(&data->value_mutex);
+ mutex_init(&data->mode_mutex);
+ mutex_init(&data->enable_mutex);
+ smi130_acc_set_bandwidth(client, SMI_ACC2X2_BW_SET);
+ smi130_acc_set_range(client, SMI_ACC2X2_RANGE_SET);
+
+#if defined(SMI_ACC2X2_ENABLE_INT1) || defined(SMI_ACC2X2_ENABLE_INT2)
+
+ pdata = client->dev.platform_data;
+ if (pdata) {
+ if (pdata->irq_gpio_cfg && (pdata->irq_gpio_cfg() < 0)) {
+ PERR("IRQ GPIO conf. error %d\n",
+ client->irq);
+ }
+ }
+
+#ifdef SMI_ACC2X2_ENABLE_INT1
+ /* maps interrupt to INT1 pin */
+ smi130_acc_set_int1_pad_sel(client, PAD_LOWG);
+ smi130_acc_set_int1_pad_sel(client, PAD_HIGHG);
+ smi130_acc_set_int1_pad_sel(client, PAD_SLOP);
+ smi130_acc_set_int1_pad_sel(client, PAD_DOUBLE_TAP);
+ smi130_acc_set_int1_pad_sel(client, PAD_SINGLE_TAP);
+ smi130_acc_set_int1_pad_sel(client, PAD_ORIENT);
+ smi130_acc_set_int1_pad_sel(client, PAD_FLAT);
+ smi130_acc_set_int1_pad_sel(client, PAD_SLOW_NO_MOTION);
+#ifdef CONFIG_SMI_ACC_ENABLE_NEWDATA_INT
+ smi130_acc_set_newdata(client, SMI_ACC2X2_INT1_NDATA, 1);
+ smi130_acc_set_newdata(client, SMI_ACC2X2_INT2_NDATA, 0);
+#endif
+#endif
+
+#ifdef SMI_ACC2X2_ENABLE_INT2
+ /* maps interrupt to INT2 pin */
+ smi130_acc_set_int2_pad_sel(client, PAD_LOWG);
+ smi130_acc_set_int2_pad_sel(client, PAD_HIGHG);
+ smi130_acc_set_int2_pad_sel(client, PAD_SLOP);
+ smi130_acc_set_int2_pad_sel(client, PAD_DOUBLE_TAP);
+ smi130_acc_set_int2_pad_sel(client, PAD_SINGLE_TAP);
+ smi130_acc_set_int2_pad_sel(client, PAD_ORIENT);
+ smi130_acc_set_int2_pad_sel(client, PAD_FLAT);
+ smi130_acc_set_int2_pad_sel(client, PAD_SLOW_NO_MOTION);
+#ifdef CONFIG_SMI_ACC_ENABLE_NEWDATA_INT
+ smi130_acc_set_newdata(client, SMI_ACC2X2_INT1_NDATA, 0);
+ smi130_acc_set_newdata(client, SMI_ACC2X2_INT2_NDATA, 1);
+#endif
+#endif
+
+ smi130_acc_set_Int_Mode(client, 1);/*latch interrupt 250ms*/
+
+ /* do not open any interrupt here */
+ /*10,orient_mbl
+ 11,flat*/
+ /* smi130_acc_set_Int_Enable(client, 10, 1); */
+ /* smi130_acc_set_Int_Enable(client, 11, 1); */
+
+#ifdef CONFIG_SMI_ACC_ENABLE_NEWDATA_INT
+ /* enable new data interrupt */
+ smi130_acc_set_Int_Enable(client, 4, 1);
+#endif
+
+#ifdef CONFIG_SIG_MOTION
+ enable_irq_wake(data->IRQ);
+#endif
+ if (err)
+ PERR("could not request irq\n");
+
+ INIT_WORK(&data->irq_work, smi130_acc_irq_work_func);
+#endif
+
+#ifndef CONFIG_SMI_ACC_ENABLE_NEWDATA_INT
+ INIT_DELAYED_WORK(&data->work, smi130_acc_work_func);
+#endif
+ atomic_set(&data->delay, SMI_ACC2X2_MAX_DELAY);
+ atomic_set(&data->enable, 0);
+
+ dev = input_allocate_device();
+ if (!dev)
+ return -ENOMEM;
+
+ dev_interrupt = input_allocate_device();
+ if (!dev_interrupt) {
+ kfree(data);
+ input_free_device(dev); /*free the successful dev and return*/
+ return -ENOMEM;
+ }
+
+ /* only value events reported */
+ dev->name = SENSOR_NAME;
+ dev->id.bustype = BUS_I2C;
+ input_set_capability(dev, EV_ABS, ABS_MISC);
+ input_set_abs_params(dev, ABS_X, ABSMIN, ABSMAX, 0, 0);
+ input_set_abs_params(dev, ABS_Y, ABSMIN, ABSMAX, 0, 0);
+ input_set_abs_params(dev, ABS_Z, ABSMIN, ABSMAX, 0, 0);
+ input_set_capability(dev, EV_MSC, MSC_GESTURE);
+ input_set_capability(dev, EV_MSC, MSC_RAW);
+ input_set_capability(dev, EV_MSC, MSC_SCAN);
+ input_set_capability(dev, EV_MSC, MSC_TIME);
+ input_set_drvdata(dev, data);
+ err = input_register_device(dev);
+ if (err < 0)
+ goto err_register_input_device;
+
+ /* all interrupt generated events are moved to interrupt input devices*/
+ dev_interrupt->name = "smi_acc_interrupt";
+ dev_interrupt->id.bustype = BUS_I2C;
+ input_set_capability(dev_interrupt, EV_REL,
+ SLOW_NO_MOTION_INTERRUPT);
+ input_set_capability(dev_interrupt, EV_REL,
+ LOW_G_INTERRUPT);
+ input_set_capability(dev_interrupt, EV_REL,
+ HIGH_G_INTERRUPT);
+ input_set_capability(dev_interrupt, EV_REL,
+ SLOP_INTERRUPT);
+ input_set_capability(dev_interrupt, EV_REL,
+ DOUBLE_TAP_INTERRUPT);
+ input_set_capability(dev_interrupt, EV_REL,
+ SINGLE_TAP_INTERRUPT);
+ input_set_capability(dev_interrupt, EV_ABS,
+ ORIENT_INTERRUPT);
+ input_set_capability(dev_interrupt, EV_ABS,
+ FLAT_INTERRUPT);
+ input_set_drvdata(dev_interrupt, data);
+
+ err = input_register_device(dev_interrupt);
+ if (err < 0)
+ goto err_register_input_device_interrupt;
+
+ data->dev_interrupt = dev_interrupt;
+ data->input = dev;
+
+#ifdef CONFIG_SIG_MOTION
+ data->g_sensor_class = class_create(THIS_MODULE, "sig_sensor");
+ if (IS_ERR(data->g_sensor_class)) {
+ err = PTR_ERR(data->g_sensor_class);
+ data->g_sensor_class = NULL;
+ PERR("could not allocate g_sensor_class\n");
+ goto err_create_class;
+ }
+
+ data->g_sensor_dev = device_create(data->g_sensor_class,
+ NULL, 0, "%s", "g_sensor");
+ if (unlikely(IS_ERR(data->g_sensor_dev))) {
+ err = PTR_ERR(data->g_sensor_dev);
+ data->g_sensor_dev = NULL;
+
+ PERR("could not allocate g_sensor_dev\n");
+ goto err_create_g_sensor_device;
+ }
+
+ dev_set_drvdata(data->g_sensor_dev, data);
+
+ err = sysfs_create_group(&data->g_sensor_dev->kobj,
+ &smi130_acc_sig_motion_attribute_group);
+ if (err < 0)
+ goto error_sysfs;
+#endif
+
+#ifdef CONFIG_DOUBLE_TAP
+ data->g_sensor_class_doubletap =
+ class_create(THIS_MODULE, "dtap_sensor");
+ if (IS_ERR(data->g_sensor_class_doubletap)) {
+ err = PTR_ERR(data->g_sensor_class_doubletap);
+ data->g_sensor_class_doubletap = NULL;
+ PERR("could not allocate g_sensor_class_doubletap\n");
+ goto err_create_class;
+ }
+
+ data->g_sensor_dev_doubletap = device_create(
+ data->g_sensor_class_doubletap,
+ NULL, 0, "%s", "g_sensor");
+ if (unlikely(IS_ERR(data->g_sensor_dev_doubletap))) {
+ err = PTR_ERR(data->g_sensor_dev_doubletap);
+ data->g_sensor_dev_doubletap = NULL;
+
+ PERR("could not allocate g_sensor_dev_doubletap\n");
+ goto err_create_g_sensor_device_double_tap;
+ }
+
+ dev_set_drvdata(data->g_sensor_dev_doubletap, data);
+
+ err = sysfs_create_group(&data->g_sensor_dev_doubletap->kobj,
+ &smi130_acc_double_tap_attribute_group);
+ if (err < 0)
+ goto error_sysfs;
+#endif
+
+ err = sysfs_create_group(&data->input->dev.kobj,
+ &smi130_acc_attribute_group);
+ if (err < 0)
+ goto error_sysfs;
+
+ dev_acc = bosch_allocate_device();
+ if (!dev_acc) {
+ err = -ENOMEM;
+ goto error_sysfs;
+ }
+ dev_acc->name = ACC_NAME;
+
+ bosch_set_drvdata(dev_acc, data);
+
+ err = bosch_register_device(dev_acc);
+ if (err < 0)
+ goto bosch_free_acc_exit;
+
+ data->bosch_acc = dev_acc;
+ err = sysfs_create_group(&data->bosch_acc->dev.kobj,
+ &smi130_acc_attribute_group);
+
+ if (err < 0)
+ goto bosch_free_exit;
+
+ if (NULL != client->dev.platform_data) {
+ data->bosch_pd = kzalloc(sizeof(*data->bosch_pd),
+ GFP_KERNEL);
+
+ if (NULL != data->bosch_pd) {
+ memcpy(data->bosch_pd, client->dev.platform_data,
+ sizeof(*data->bosch_pd));
+ PINFO("%s sensor driver set place: p%d",
+ data->bosch_pd->name, data->bosch_pd->place);
+ }
+ }
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
+ data->early_suspend.suspend = smi130_acc_early_suspend;
+ data->early_suspend.resume = smi130_acc_late_resume;
+ register_early_suspend(&data->early_suspend);
+#endif
+ INIT_WORK(&data->report_data_work,
+ smi130_acc_timer_work_fun);
+ reportdata_wq = create_singlethread_workqueue("smi130_acc_wq");
+ if (NULL == reportdata_wq)
+ PERR("fail to create the reportdta_wq");
+ hrtimer_init(&data->timer, CLOCK_MONOTONIC,
+ HRTIMER_MODE_REL);
+ data->timer.function = reportdata_timer_fun;
+ data->work_delay_kt = ns_to_ktime(4000000);
+ data->is_timer_running = 0;
+ data->timestamp = 0;
+ data->time_odr = 4000000;/*default bandwidth 125HZ*/
+ data->smi_acc_mode_enabled = 0;
+ data->fifo_datasel = 0;
+ data->fifo_count = 0;
+ data->acc_count = 0;
+
+#ifdef CONFIG_SIG_MOTION
+ atomic_set(&data->en_sig_motion, 0);
+#endif
+#ifdef CONFIG_DOUBLE_TAP
+ atomic_set(&data->en_double_tap, 0);
+ data->tap_times = 0;
+ data->tap_time_period = DEFAULT_TAP_JUDGE_PERIOD;
+ mutex_init(&data->tap_mutex);
+ setup_timer(&data->tap_timer, smi130_acc_tap_timeout_handle,
+ (unsigned long)data);
+#endif
+ if (smi130_acc_set_mode(client, SMI_ACC2X2_MODE_SUSPEND, SMI_ACC_ENABLED_ALL) < 0)
+ return -EINVAL;
+ data->IRQ = client->irq;
+ PDEBUG("data->IRQ = %d", data->IRQ);
+ err = request_irq(data->IRQ, smi130_acc_irq_handler, IRQF_TRIGGER_RISING,
+ "smi130_acc", data);
+ PINFO("SMI130_ACC driver probe successfully");
+
+ return 0;
+
+bosch_free_exit:
+ bosch_unregister_device(dev_acc);
+
+bosch_free_acc_exit:
+ bosch_free_device(dev_acc);
+
+error_sysfs:
+ input_unregister_device(data->input);
+
+#ifdef CONFIG_DOUBLE_TAP
+err_create_g_sensor_device_double_tap:
+ class_destroy(data->g_sensor_class_doubletap);
+#endif
+
+#ifdef CONFIG_SIG_MOTION
+err_create_g_sensor_device:
+ class_destroy(data->g_sensor_class);
+#endif
+
+#if defined(CONFIG_SIG_MOTION) || defined(CONFIG_DOUBLE_TAP)
+err_create_class:
+ input_unregister_device(data->dev_interrupt);
+#endif
+
+err_register_input_device_interrupt:
+ input_free_device(dev_interrupt);
+ input_unregister_device(data->input);
+
+err_register_input_device:
+ input_free_device(dev);
+
+kfree_exit:
+ if ((NULL != data) && (NULL != data->bosch_pd)) {
+ kfree(data->bosch_pd);
+ data->bosch_pd = NULL;
+ }
+ kfree(data);
+exit:
+ return err;
+}
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void smi130_acc_early_suspend(struct early_suspend *h)
+{
+ struct smi130_acc_data *data =
+ container_of(h, struct smi130_acc_data, early_suspend);
+
+ mutex_lock(&data->enable_mutex);
+ if (atomic_read(&data->enable) == 1) {
+ smi130_acc_set_mode(data->smi130_acc_client,
+ SMI_ACC2X2_MODE_SUSPEND, SMI_ACC_ENABLED_INPUT);
+#ifndef CONFIG_SMI_ACC_ENABLE_NEWDATA_INT
+ cancel_delayed_work_sync(&data->work);
+#endif
+ }
+ if (data->is_timer_running) {
+ /*diable fifo_mode when close timer*/
+ if (smi130_acc_set_fifo_mode(data->smi130_acc_client, 0) < 0)
+ PERR("set fifo_mode falied");
+ hrtimer_cancel(&data->timer);
+ data->base_time = 0;
+ data->timestamp = 0;
+ data->fifo_time = 0;
+ data->acc_count = 0;
+ }
+ mutex_unlock(&data->enable_mutex);
+}
+
+static void smi130_acc_late_resume(struct early_suspend *h)
+{
+ struct smi130_acc_data *data =
+ container_of(h, struct smi130_acc_data, early_suspend);
+ if (NULL == data)
+ return;
+
+ mutex_lock(&data->enable_mutex);
+ if (atomic_read(&data->enable) == 1) {
+ smi130_acc_set_mode(data->smi130_acc_client,
+ SMI_ACC2X2_MODE_NORMAL, SMI_ACC_ENABLED_INPUT);
+#ifndef CONFIG_SMI_ACC_ENABLE_NEWDATA_INT
+ schedule_delayed_work(&data->work,
+ msecs_to_jiffies(atomic_read(&data->delay)));
+#endif
+ }
+ if (data->is_timer_running) {
+ hrtimer_start(&data->timer,
+ ns_to_ktime(data->time_odr),
+ HRTIMER_MODE_REL);
+ /*enable fifo_mode when init*/
+ if (smi130_acc_set_fifo_mode(data->smi130_acc_client, 2) < 0)
+ PERR("set fifo_mode falied");
+ data->base_time = 0;
+ data->timestamp = 0;
+ data->is_timer_running = 1;
+ data->acc_count = 0;
+ }
+ mutex_unlock(&data->enable_mutex);
+}
+#endif
+
+static int smi130_acc_remove(struct i2c_client *client)
+{
+ struct smi130_acc_data *data = i2c_get_clientdata(client);
+
+ if (NULL == data)
+ return 0;
+
+ smi130_acc_set_enable(&client->dev, 0);
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ unregister_early_suspend(&data->early_suspend);
+#endif
+ sysfs_remove_group(&data->input->dev.kobj, &smi130_acc_attribute_group);
+ input_unregister_device(data->input);
+
+ if (NULL != data->bosch_pd) {
+ kfree(data->bosch_pd);
+ data->bosch_pd = NULL;
+ }
+
+ kfree(data);
+ return 0;
+}
+
+void smi130_acc_shutdown(struct i2c_client *client)
+{
+ struct smi130_acc_data *data = i2c_get_clientdata(client);
+
+ mutex_lock(&data->enable_mutex);
+ smi130_acc_set_mode(data->smi130_acc_client,
+ SMI_ACC2X2_MODE_DEEP_SUSPEND, SMI_ACC_ENABLED_ALL);
+ mutex_unlock(&data->enable_mutex);
+}
+
+#ifdef CONFIG_PM
+static int smi130_acc_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+ struct smi130_acc_data *data = i2c_get_clientdata(client);
+
+ mutex_lock(&data->enable_mutex);
+ if (atomic_read(&data->enable) == 1) {
+ smi130_acc_set_mode(data->smi130_acc_client,
+ SMI_ACC2X2_MODE_SUSPEND, SMI_ACC_ENABLED_INPUT);
+#ifndef CONFIG_SMI_ACC_ENABLE_NEWDATA_INT
+ cancel_delayed_work_sync(&data->work);
+#endif
+ }
+ if (data->is_timer_running) {
+ hrtimer_cancel(&data->timer);
+ data->base_time = 0;
+ data->timestamp = 0;
+ data->fifo_time = 0;
+ data->acc_count = 0;
+ }
+ mutex_unlock(&data->enable_mutex);
+
+ return 0;
+}
+
+static int smi130_acc_resume(struct i2c_client *client)
+{
+ struct smi130_acc_data *data = i2c_get_clientdata(client);
+
+ mutex_lock(&data->enable_mutex);
+ if (atomic_read(&data->enable) == 1) {
+ smi130_acc_set_mode(data->smi130_acc_client,
+ SMI_ACC2X2_MODE_NORMAL, SMI_ACC_ENABLED_INPUT);
+#ifndef CONFIG_SMI_ACC_ENABLE_NEWDATA_INT
+ schedule_delayed_work(&data->work,
+ msecs_to_jiffies(atomic_read(&data->delay)));
+#endif
+ }
+ if (data->is_timer_running) {
+ hrtimer_start(&data->timer,
+ ns_to_ktime(data->time_odr),
+ HRTIMER_MODE_REL);
+ data->base_time = 0;
+ data->timestamp = 0;
+ data->is_timer_running = 1;
+ }
+ mutex_unlock(&data->enable_mutex);
+
+ return 0;
+}
+
+#else
+
+#define smi130_acc_suspend NULL
+#define smi130_acc_resume NULL
+
+#endif /* CONFIG_PM */
+
+static const struct i2c_device_id smi130_acc_id[] = {
+ { SENSOR_NAME, 0 },
+ { }
+};
+
+MODULE_DEVICE_TABLE(i2c, smi130_acc_id);
+static const struct of_device_id smi130_acc_of_match[] = {
+ { .compatible = "smi130_acc", },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, smi130_acc_of_match);
+
+static struct i2c_driver smi130_acc_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = SENSOR_NAME,
+ .of_match_table = smi130_acc_of_match,
+ },
+ //.suspend = smi130_acc_suspend,
+ //.resume = smi130_acc_resume,
+ .id_table = smi130_acc_id,
+ .probe = smi130_acc_probe,
+ .remove = smi130_acc_remove,
+ .shutdown = smi130_acc_shutdown,
+};
+
+static int __init SMI_ACC2X2_init(void)
+{
+ return i2c_add_driver(&smi130_acc_driver);
+}
+
+static void __exit SMI_ACC2X2_exit(void)
+{
+ i2c_del_driver(&smi130_acc_driver);
+}
+
+MODULE_AUTHOR("contact@bosch-sensortec.com");
+MODULE_DESCRIPTION("SMI_ACC2X2 ACCELEROMETER SENSOR DRIVER");
+MODULE_LICENSE("GPL v2");
+
+module_init(SMI_ACC2X2_init);
+module_exit(SMI_ACC2X2_exit);
+
diff --git a/drivers/input/sensors/smi130/smi130_driver.c b/drivers/input/sensors/smi130/smi130_driver.c
new file mode 100644
index 0000000..42a0a57
--- /dev/null
+++ b/drivers/input/sensors/smi130/smi130_driver.c
@@ -0,0 +1,4121 @@
+/*!
+ * @section LICENSE
+ * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved
+ *
+ * (C) Modification Copyright 2018 Robert Bosch Kft All Rights Reserved
+ *
+ * This software program is licensed subject to the GNU General
+ * Public License (GPL).Version 2,June 1991,
+ * available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * Special: Description of the Software:
+ *
+ * This software module (hereinafter called "Software") and any
+ * information on application-sheets (hereinafter called "Information") is
+ * provided free of charge for the sole purpose to support your application
+ * work.
+ *
+ * As such, the Software is merely an experimental software, not tested for
+ * safety in the field and only intended for inspiration for further development
+ * and testing. Any usage in a safety-relevant field of use (like automotive,
+ * seafaring, spacefaring, industrial plants etc.) was not intended, so there are
+ * no precautions for such usage incorporated in the Software.
+ *
+ * The Software is specifically designed for the exclusive use for Bosch
+ * Sensortec products by personnel who have special experience and training. Do
+ * not use this Software if you do not have the proper experience or training.
+ *
+ * This Software package is provided as is and without any expressed or
+ * implied warranties, including without limitation, the implied warranties of
+ * merchantability and fitness for a particular purpose.
+ *
+ * Bosch Sensortec and their representatives and agents deny any liability for
+ * the functional impairment of this Software in terms of fitness, performance
+ * and safety. Bosch Sensortec and their representatives and agents shall not be
+ * liable for any direct or indirect damages or injury, except as otherwise
+ * stipulated in mandatory applicable law.
+ * The Information provided is believed to be accurate and reliable. Bosch
+ * Sensortec assumes no responsibility for the consequences of use of such
+ * Information nor for any infringement of patents or other rights of third
+ * parties which may result from its use.
+ *
+ *------------------------------------------------------------------------------
+ * The following Product Disclaimer does not apply to the BSX4-HAL-4.1NoFusion Software
+ * which is licensed under the Apache License, Version 2.0 as stated above.
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Product Disclaimer
+ *
+ * Common:
+ *
+ * Assessment of Products Returned from Field
+ *
+ * Returned products are considered good if they fulfill the specifications /
+ * test data for 0-mileage and field listed in this document.
+ *
+ * Engineering Samples
+ *
+ * Engineering samples are marked with (e) or (E). Samples may vary from the
+ * valid technical specifications of the series product contained in this
+ * data sheet. Therefore, they are not intended or fit for resale to
+ * third parties or for use in end products. Their sole purpose is internal
+ * client testing. The testing of an engineering sample may in no way replace
+ * the testing of a series product. Bosch assumes no liability for the use
+ * of engineering samples. The purchaser shall indemnify Bosch from all claims
+ * arising from the use of engineering samples.
+ *
+ * Intended use
+ *
+ * Provided that SMI130 is used within the conditions (environment, application,
+ * installation, loads) as described in this TCD and the corresponding
+ * agreed upon documents, Bosch ensures that the product complies with
+ * the agreed properties. Agreements beyond this require
+ * the written approval by Bosch. The product is considered fit for the intended
+ * use when the product successfully has passed the tests
+ * in accordance with the TCD and agreed upon documents.
+ *
+ * It is the responsibility of the customer to ensure the proper application
+ * of the product in the overall system/vehicle.
+ *
+ * Bosch does not assume any responsibility for changes to the environment
+ * of the product that deviate from the TCD and the agreed upon documents
+ * as well as all applications not released by Bosch
+ *
+ * The resale and/or use of products are at the purchaser’s own risk and
+ * responsibility. The examination and testing of the SMI130
+ * is the sole responsibility of the purchaser.
+ *
+ * The purchaser shall indemnify Bosch from all third party claims
+ * arising from any product use not covered by the parameters of
+ * this product data sheet or not approved by Bosch and reimburse Bosch
+ * for all costs and damages in connection with such claims.
+ *
+ * The purchaser must monitor the market for the purchased products,
+ * particularly with regard to product safety, and inform Bosch without delay
+ * of all security relevant incidents.
+ *
+ * Application Examples and Hints
+ *
+ * With respect to any application examples, advice, normal values
+ * and/or any information regarding the application of the device,
+ * Bosch hereby disclaims any and all warranties and liabilities of any kind,
+ * including without limitation warranties of
+ * non-infringement of intellectual property rights or copyrights
+ * of any third party.
+ * The information given in this document shall in no event be regarded
+ * as a guarantee of conditions or characteristics. They are provided
+ * for illustrative purposes only and no evaluation regarding infringement
+ * of intellectual property rights or copyrights or regarding functionality,
+ * performance or error has been made.
+ *
+ * @filename smi130_driver.c
+ * @date 2016/08/01 14:40
+ * @Modification Date 2018/08/28 18:20
+ * @id "b5ff23a"
+ * @version 1.3
+ *
+ * @brief
+ * The core code of SMI130 device driver
+ *
+ * @detail
+ * This file implements the core code of SMI130 device driver,
+ * which includes hardware related functions, input device register,
+ * device attribute files, etc.
+*/
+
+#include "smi130.h"
+#include "smi130_driver.h"
+#include <linux/device.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/of_irq.h>
+
+
+#define DRIVER_VERSION "0.0.53.0"
+#define I2C_BURST_READ_MAX_LEN (256)
+#define SMI130_STORE_COUNT (6000)
+#define LMADA (1)
+uint64_t g_current_apts_us_mbl;
+
+
+enum SMI_SENSOR_INT_T {
+ /* Interrupt enable0*/
+ SMI_ANYMO_X_INT = 0,
+ SMI_ANYMO_Y_INT,
+ SMI_ANYMO_Z_INT,
+ SMI_D_TAP_INT,
+ SMI_S_TAP_INT,
+ SMI_ORIENT_INT,
+ SMI_FLAT_INT,
+ /* Interrupt enable1*/
+ SMI_HIGH_X_INT,
+ SMI_HIGH_Y_INT,
+ SMI_HIGH_Z_INT,
+ SMI_LOW_INT,
+ SMI_DRDY_INT,
+ SMI_FFULL_INT,
+ SMI_FWM_INT,
+ /* Interrupt enable2 */
+ SMI_NOMOTION_X_INT,
+ SMI_NOMOTION_Y_INT,
+ SMI_NOMOTION_Z_INT,
+ SMI_STEP_DETECTOR_INT,
+ INT_TYPE_MAX
+};
+
+/*smi fifo sensor type combination*/
+enum SMI_SENSOR_FIFO_COMBINATION {
+ SMI_FIFO_A = 0,
+ SMI_FIFO_G,
+ SMI_FIFO_M,
+ SMI_FIFO_G_A,
+ SMI_FIFO_M_A,
+ SMI_FIFO_M_G,
+ SMI_FIFO_M_G_A,
+ SMI_FIFO_COM_MAX
+};
+
+/*smi fifo analyse return err status*/
+enum SMI_FIFO_ANALYSE_RETURN_T {
+ FIFO_OVER_READ_RETURN = -10,
+ FIFO_SENSORTIME_RETURN = -9,
+ FIFO_SKIP_OVER_LEN = -8,
+ FIFO_M_G_A_OVER_LEN = -7,
+ FIFO_M_G_OVER_LEN = -6,
+ FIFO_M_A_OVER_LEN = -5,
+ FIFO_G_A_OVER_LEN = -4,
+ FIFO_M_OVER_LEN = -3,
+ FIFO_G_OVER_LEN = -2,
+ FIFO_A_OVER_LEN = -1
+};
+
+/*!smi sensor generic power mode enum */
+enum SMI_DEV_OP_MODE {
+ SENSOR_PM_NORMAL = 0,
+ SENSOR_PM_LP1,
+ SENSOR_PM_SUSPEND,
+ SENSOR_PM_LP2
+};
+
+/*! smi acc sensor power mode enum */
+enum SMI_ACC_PM_TYPE {
+ SMI_ACC_PM_NORMAL = 0,
+ SMI_ACC_PM_LP1,
+ SMI_ACC_PM_SUSPEND,
+ SMI_ACC_PM_LP2,
+ SMI_ACC_PM_MAX
+};
+
+/*! smi gyro sensor power mode enum */
+enum SMI_GYRO_PM_TYPE {
+ SMI_GYRO_PM_NORMAL = 0,
+ SMI_GYRO_PM_FAST_START,
+ SMI_GYRO_PM_SUSPEND,
+ SMI_GYRO_PM_MAX
+};
+
+/*! smi mag sensor power mode enum */
+enum SMI_MAG_PM_TYPE {
+ SMI_MAG_PM_NORMAL = 0,
+ SMI_MAG_PM_LP1,
+ SMI_MAG_PM_SUSPEND,
+ SMI_MAG_PM_LP2,
+ SMI_MAG_PM_MAX
+};
+
+
+/*! smi sensor support type*/
+enum SMI_SENSOR_TYPE {
+ SMI_ACC_SENSOR,
+ SMI_GYRO_SENSOR,
+ SMI_MAG_SENSOR,
+ SMI_SENSOR_TYPE_MAX
+};
+
+/*!smi sensor generic power mode enum */
+enum SMI_AXIS_TYPE {
+ X_AXIS = 0,
+ Y_AXIS,
+ Z_AXIS,
+ AXIS_MAX
+};
+
+/*!smi sensor generic intterrupt enum */
+enum SMI_INT_TYPE {
+ SMI130_INT0 = 0,
+ SMI130_INT1,
+ SMI130_INT_MAX
+};
+
+/*! smi sensor time resolution definition*/
+enum SMI_SENSOR_TIME_RS_TYPE {
+ TS_0_78_HZ = 1,/*0.78HZ*/
+ TS_1_56_HZ,/*1.56HZ*/
+ TS_3_125_HZ,/*3.125HZ*/
+ TS_6_25_HZ,/*6.25HZ*/
+ TS_12_5_HZ,/*12.5HZ*/
+ TS_25_HZ,/*25HZ, odr=6*/
+ TS_50_HZ,/*50HZ*/
+ TS_100_HZ,/*100HZ*/
+ TS_200_HZ,/*200HZ*/
+ TS_400_HZ,/*400HZ*/
+ TS_800_HZ,/*800HZ*/
+ TS_1600_HZ,/*1600HZ*/
+ TS_MAX_HZ
+};
+
+/*! smi sensor interface mode */
+enum SMI_SENSOR_IF_MODE_TYPE {
+ /*primary interface:autoconfig/secondary interface off*/
+ P_AUTO_S_OFF = 0,
+ /*primary interface:I2C/secondary interface:OIS*/
+ P_I2C_S_OIS,
+ /*primary interface:autoconfig/secondary interface:Magnetometer*/
+ P_AUTO_S_MAG,
+ /*interface mode reseved*/
+ IF_MODE_RESEVED
+
+};
+
+/*! smi130 acc/gyro calibration status in H/W layer */
+enum SMI_CALIBRATION_STATUS_TYPE {
+ /*SMI FAST Calibration ready x/y/z status*/
+ SMI_ACC_X_FAST_CALI_RDY = 0,
+ SMI_ACC_Y_FAST_CALI_RDY,
+ SMI_ACC_Z_FAST_CALI_RDY
+};
+
+unsigned int reg_op_addr_mbl;
+
+static const int smi_pmu_cmd_acc_arr[SMI_ACC_PM_MAX] = {
+ /*!smi pmu for acc normal, low power1,
+ * suspend, low power2 mode command */
+ CMD_PMU_ACC_NORMAL,
+ CMD_PMU_ACC_LP1,
+ CMD_PMU_ACC_SUSPEND,
+ CMD_PMU_ACC_LP2
+};
+
+static const int smi_pmu_cmd_gyro_arr[SMI_GYRO_PM_MAX] = {
+ /*!smi pmu for gyro normal, fast startup,
+ * suspend mode command */
+ CMD_PMU_GYRO_NORMAL,
+ CMD_PMU_GYRO_FASTSTART,
+ CMD_PMU_GYRO_SUSPEND
+};
+
+static const int smi_pmu_cmd_mag_arr[SMI_MAG_PM_MAX] = {
+ /*!smi pmu for mag normal, low power1,
+ * suspend, low power2 mode command */
+ CMD_PMU_MAG_NORMAL,
+ CMD_PMU_MAG_LP1,
+ CMD_PMU_MAG_SUSPEND,
+ CMD_PMU_MAG_LP2
+};
+
+static const char *smi_axis_name[AXIS_MAX] = {"x", "y", "z"};
+
+static const int smi_interrupt_type[] = {
+ /*!smi interrupt type */
+ /* Interrupt enable0 , index=0~6*/
+ SMI130_ANY_MOTION_X_ENABLE,
+ SMI130_ANY_MOTION_Y_ENABLE,
+ SMI130_ANY_MOTION_Z_ENABLE,
+ SMI130_DOUBLE_TAP_ENABLE,
+ SMI130_SINGLE_TAP_ENABLE,
+ SMI130_ORIENT_ENABLE,
+ SMI130_FLAT_ENABLE,
+ /* Interrupt enable1, index=7~13*/
+ SMI130_HIGH_G_X_ENABLE,
+ SMI130_HIGH_G_Y_ENABLE,
+ SMI130_HIGH_G_Z_ENABLE,
+ SMI130_LOW_G_ENABLE,
+ SMI130_DATA_RDY_ENABLE,
+ SMI130_FIFO_FULL_ENABLE,
+ SMI130_FIFO_WM_ENABLE,
+ /* Interrupt enable2, index = 14~17*/
+ SMI130_NOMOTION_X_ENABLE,
+ SMI130_NOMOTION_Y_ENABLE,
+ SMI130_NOMOTION_Z_ENABLE,
+ SMI130_STEP_DETECTOR_EN
+};
+
+/*! smi sensor time depend on ODR*/
+struct smi_sensor_time_odr_tbl {
+ u32 ts_duration_lsb;
+ u32 ts_duration_us;
+ u32 ts_delat;/*sub current delat fifo_time*/
+};
+
+struct smi130_axis_data_t {
+ s16 x;
+ s16 y;
+ s16 z;
+};
+
+struct smi130_type_mapping_type {
+
+ /*! smi16x sensor chip id */
+ uint16_t chip_id;
+
+ /*! smi16x chip revision code */
+ uint16_t revision_id;
+
+ /*! smi130_acc sensor name */
+ const char *sensor_name;
+};
+
+struct smi130_store_info_t {
+ uint8_t current_frm_cnt;
+ uint64_t current_apts_us[2];
+ uint8_t fifo_ts_total_frmcnt;
+ uint64_t fifo_time;
+};
+
+uint64_t get_current_timestamp_mbl(void)
+{
+ uint64_t ts_ap;
+ struct timespec tmp_time;
+ get_monotonic_boottime(&tmp_time);
+ ts_ap = (uint64_t)tmp_time.tv_sec * 1000000000 + tmp_time.tv_nsec;
+ return ts_ap;
+
+}
+
+/*! sensor support type map */
+static const struct smi130_type_mapping_type sensor_type_map[] = {
+
+ {SENSOR_CHIP_ID_SMI, SENSOR_CHIP_REV_ID_SMI, "SMI130/162AB"},
+ {SENSOR_CHIP_ID_SMI_C2, SENSOR_CHIP_REV_ID_SMI, "SMI130C2"},
+ {SENSOR_CHIP_ID_SMI_C3, SENSOR_CHIP_REV_ID_SMI, "SMI130C3"},
+
+};
+
+/*!smi130 sensor time depends on ODR */
+static const struct smi_sensor_time_odr_tbl
+ sensortime_duration_tbl[TS_MAX_HZ] = {
+ {0x010000, 2560000, 0x00ffff},/*2560ms, 0.39hz, odr=resver*/
+ {0x008000, 1280000, 0x007fff},/*1280ms, 0.78hz, odr_acc=1*/
+ {0x004000, 640000, 0x003fff},/*640ms, 1.56hz, odr_acc=2*/
+ {0x002000, 320000, 0x001fff},/*320ms, 3.125hz, odr_acc=3*/
+ {0x001000, 160000, 0x000fff},/*160ms, 6.25hz, odr_acc=4*/
+ {0x000800, 80000, 0x0007ff},/*80ms, 12.5hz*/
+ {0x000400, 40000, 0x0003ff},/*40ms, 25hz, odr_acc = odr_gyro =6*/
+ {0x000200, 20000, 0x0001ff},/*20ms, 50hz, odr = 7*/
+ {0x000100, 10000, 0x0000ff},/*10ms, 100hz, odr=8*/
+ {0x000080, 5000, 0x00007f},/*5ms, 200hz, odr=9*/
+ {0x000040, 2500, 0x00003f},/*2.5ms, 400hz, odr=10*/
+ {0x000020, 1250, 0x00001f},/*1.25ms, 800hz, odr=11*/
+ {0x000010, 625, 0x00000f},/*0.625ms, 1600hz, odr=12*/
+
+};
+
+#if defined(CONFIG_USE_QUALCOMM_HAL)
+#define POLL_INTERVAL_MIN_MS 10
+#define POLL_INTERVAL_MAX_MS 4000
+#define POLL_DEFAULT_INTERVAL_MS 200
+#define SMI130_ACCEL_MIN_VALUE -32768
+#define SMI130_ACCEL_MAX_VALUE 32767
+#define SMI130_GYRO_MIN_VALUE -32768
+#define SMI130_GYRO_MAX_VALUE 32767
+#define SMI130_ACCEL_DEFAULT_POLL_INTERVAL_MS 200
+#define SMI130_GYRO_DEFAULT_POLL_INTERVAL_MS 200
+#define SMI130_ACCEL_MIN_POLL_INTERVAL_MS 10
+#define SMI130_ACCEL_MAX_POLL_INTERVAL_MS 5000
+#define SMI130_GYRO_MIN_POLL_INTERVAL_MS 10
+#define SMI130_GYRO_MAX_POLL_INTERVAL_MS 5000
+static struct sensors_classdev smi130_accel_cdev = {
+ .name = "smi130-accel",
+ .vendor = "bosch",
+ .version = 1,
+ .handle = SENSORS_ACCELERATION_HANDLE,
+ .type = SENSOR_TYPE_ACCELEROMETER,
+ .max_range = "156.8", /* 16g */
+ .resolution = "0.153125", /* 15.6mg */
+ .sensor_power = "0.13", /* typical value */
+ .min_delay = POLL_INTERVAL_MIN_MS * 1000, /* in microseconds */
+ .max_delay = POLL_INTERVAL_MAX_MS,
+ .delay_msec = POLL_DEFAULT_INTERVAL_MS, /* in millisecond */
+ .fifo_reserved_event_count = 0,
+ .fifo_max_event_count = 0,
+ .enabled = 0,
+ .max_latency = 0,
+ .flags = 0,
+ .sensors_enable = NULL,
+ .sensors_poll_delay = NULL,
+ .sensors_set_latency = NULL,
+ .sensors_flush = NULL,
+ .sensors_self_test = NULL,
+};
+static struct sensors_classdev smi130_gyro_cdev = {
+ .name = "smi130-gyro",
+ .vendor = "bosch",
+ .version = 1,
+ .handle = SENSORS_GYROSCOPE_HANDLE,
+ .type = SENSOR_TYPE_GYROSCOPE,
+ .max_range = "34.906586", /* rad/s */
+ .resolution = "0.0010681152", /* rad/s */
+ .sensor_power = "3.6", /* 3.6 mA */
+ .min_delay = SMI130_GYRO_MIN_POLL_INTERVAL_MS * 1000,
+ .max_delay = SMI130_GYRO_MAX_POLL_INTERVAL_MS,
+ .delay_msec = SMI130_GYRO_DEFAULT_POLL_INTERVAL_MS,
+ .fifo_reserved_event_count = 0,
+ .fifo_max_event_count = 0,
+ .enabled = 0,
+ .max_latency = 0,
+ .flags = 0, /* SENSOR_FLAG_CONTINUOUS_MODE */
+ .sensors_enable = NULL,
+ .sensors_poll_delay = NULL,
+ .sensors_enable_wakeup = NULL,
+ .sensors_set_latency = NULL,
+ .sensors_flush = NULL,
+};
+#endif
+static void smi_delay(u32 msec)
+{
+ if (msec <= 20)
+ usleep_range(msec * 1000, msec * 1000);
+ else
+ msleep(msec);
+}
+
+static void smi_dump_reg(struct smi_client_data *client_data)
+{
+ #define REG_MAX0 0x24
+ #define REG_MAX1 0x56
+ int i;
+ u8 dbg_buf0[REG_MAX0];
+ u8 dbg_buf1[REG_MAX1];
+ u8 dbg_buf_str0[REG_MAX0 * 3 + 1] = "";
+ u8 dbg_buf_str1[REG_MAX1 * 3 + 1] = "";
+
+ dev_notice(client_data->dev, "\nFrom 0x00:\n");
+
+ client_data->device.bus_read(client_data->device.dev_addr,
+ SMI_REG_NAME(USER_CHIP_ID), dbg_buf0, REG_MAX0);
+ for (i = 0; i < REG_MAX0; i++) {
+ snprintf(dbg_buf_str0 + i * 3, 16, "%02x%c", dbg_buf0[i],
+ (((i + 1) % BYTES_PER_LINE == 0) ? '\n' : ' '));
+ }
+ dev_notice(client_data->dev, "%s\n", dbg_buf_str0);
+
+ client_data->device.bus_read(client_data->device.dev_addr,
+ SMI130_USER_ACCEL_CONFIG_ADDR, dbg_buf1, REG_MAX1);
+ dev_notice(client_data->dev, "\nFrom 0x40:\n");
+ for (i = 0; i < REG_MAX1; i++) {
+ snprintf(dbg_buf_str1 + i * 3, 16, "%02x%c", dbg_buf1[i],
+ (((i + 1) % BYTES_PER_LINE == 0) ? '\n' : ' '));
+ }
+ dev_notice(client_data->dev, "\n%s\n", dbg_buf_str1);
+ }
+
+
+void smi_fifo_frame_bytes_extend_calc(
+ struct smi_client_data *client_data,
+ unsigned int *fifo_frmbytes_extend)
+{
+
+ switch (client_data->fifo_data_sel) {
+ case SMI_FIFO_A_SEL:
+ case SMI_FIFO_G_SEL:
+ *fifo_frmbytes_extend = 7;
+ break;
+ case SMI_FIFO_G_A_SEL:
+ *fifo_frmbytes_extend = 13;
+ break;
+ case SMI_FIFO_M_SEL:
+ *fifo_frmbytes_extend = 9;
+ break;
+ case SMI_FIFO_M_A_SEL:
+ case SMI_FIFO_M_G_SEL:
+ /*8(mag) + 6(gyro or acc) +1(head) = 15*/
+ *fifo_frmbytes_extend = 15;
+ break;
+ case SMI_FIFO_M_G_A_SEL:
+ /*8(mag) + 6(gyro or acc) + 6 + 1 = 21*/
+ *fifo_frmbytes_extend = 21;
+ break;
+ default:
+ *fifo_frmbytes_extend = 0;
+ break;
+
+ };
+
+}
+
+static int smi_input_init(struct smi_client_data *client_data)
+{
+ struct input_dev *dev;
+ int err = 0;
+
+ dev = input_allocate_device();
+ if (NULL == dev)
+ return -ENOMEM;
+#if defined(CONFIG_USE_QUALCOMM_HAL)
+ dev->name = "smi130-accel";
+#else
+ dev->name = SENSOR_NAME;
+#endif
+ dev->id.bustype = BUS_I2C;
+
+ input_set_capability(dev, EV_MSC, MSC_GESTURE);
+ input_set_capability(dev, EV_MSC, INPUT_EVENT_SGM);
+
+ input_set_capability(dev, EV_MSC, INPUT_EVENT_FAST_GYRO_CALIB_DONE);
+ input_set_capability(dev, EV_MSC, INPUT_EVENT_STEP_DETECTOR);
+ input_set_capability(dev, EV_MSC, INPUT_EVENT_FAST_ACC_CALIB_DONE);
+
+
+ input_set_capability(dev, EV_REL, REL_X);
+ input_set_capability(dev, EV_REL, REL_Y);
+ input_set_capability(dev, EV_REL, REL_Z);
+ #if defined(CONFIG_USE_QUALCOMM_HAL)
+ input_set_capability(dev, EV_ABS, ABS_MISC);
+ input_set_abs_params(dev, ABS_X,
+ SMI130_ACCEL_MIN_VALUE, SMI130_ACCEL_MAX_VALUE,
+ 0, 0);
+ input_set_abs_params(dev, ABS_Y,
+ SMI130_ACCEL_MIN_VALUE, SMI130_ACCEL_MAX_VALUE,
+ 0, 0);
+ input_set_abs_params(dev, ABS_Z,
+ SMI130_ACCEL_MIN_VALUE, SMI130_ACCEL_MAX_VALUE,
+ 0, 0);
+ #endif
+ input_set_drvdata(dev, client_data);
+
+ err = input_register_device(dev);
+ if (err < 0) {
+ input_free_device(dev);
+ dev_notice(client_data->dev, "smi130 input free!\n");
+ return err;
+ }
+ client_data->input = dev;
+ dev_notice(client_data->dev,
+ "smi130 input register successfully, %s!\n",
+ client_data->input->name);
+ return err;
+}
+
+//#if defined(CONFIG_USE_QUALCOMM_HAL)
+static int smi_gyro_input_init(struct smi_client_data *client_data)
+{
+ struct input_dev *dev;
+ int err = 0;
+
+ dev = input_allocate_device();
+ if (NULL == dev)
+ return -ENOMEM;
+ dev->name = "smi130-gyro";
+ dev->id.bustype = BUS_I2C;
+ input_set_capability(dev, EV_ABS, ABS_MISC);
+ input_set_capability(dev, EV_MSC, MSC_GESTURE);
+ input_set_capability(dev, EV_MSC, INPUT_EVENT_SGM);
+
+ input_set_capability(dev, EV_MSC, INPUT_EVENT_FAST_GYRO_CALIB_DONE);
+ input_set_capability(dev, EV_MSC, INPUT_EVENT_STEP_DETECTOR);
+ input_set_capability(dev, EV_MSC, INPUT_EVENT_FAST_ACC_CALIB_DONE);
+ #if defined(CONFIG_USE_QUALCOMM_HAL)
+ input_set_abs_params(dev, ABS_RX,
+ SMI130_ACCEL_MIN_VALUE, SMI130_ACCEL_MAX_VALUE,
+ 0, 0);
+ input_set_abs_params(dev, ABS_RY,
+ SMI130_ACCEL_MIN_VALUE, SMI130_ACCEL_MAX_VALUE,
+ 0, 0);
+ input_set_abs_params(dev, ABS_RZ,
+ SMI130_ACCEL_MIN_VALUE, SMI130_ACCEL_MAX_VALUE,
+ 0, 0);
+ #endif
+ input_set_drvdata(dev, client_data);
+ err = input_register_device(dev);
+ if (err < 0) {
+ input_free_device(dev);
+ dev_notice(client_data->dev, "smi130 input free!\n");
+ return err;
+ }
+ client_data->gyro_input = dev;
+ dev_notice(client_data->dev,
+ "smi130 input register successfully, %s!\n",
+ client_data->gyro_input->name);
+ return err;
+}
+//#endif
+static void smi_input_destroy(struct smi_client_data *client_data)
+{
+ struct input_dev *dev = client_data->input;
+
+ input_unregister_device(dev);
+ input_free_device(dev);
+}
+
+static int smi_check_chip_id(struct smi_client_data *client_data)
+{
+ int8_t err = 0;
+ int8_t i = 0;
+ uint8_t chip_id = 0;
+ uint8_t read_count = 0;
+ u8 smi_sensor_cnt = sizeof(sensor_type_map)
+ / sizeof(struct smi130_type_mapping_type);
+ /* read and check chip id */
+ while (read_count++ < CHECK_CHIP_ID_TIME_MAX) {
+ if (client_data->device.bus_read(client_data->device.dev_addr,
+ SMI_REG_NAME(USER_CHIP_ID), &chip_id, 1) < 0) {
+
+ dev_err(client_data->dev,
+ "Bosch Sensortec Device not found"
+ "read chip_id:%d\n", chip_id);
+ continue;
+ } else {
+ for (i = 0; i < smi_sensor_cnt; i++) {
+ if (sensor_type_map[i].chip_id == chip_id) {
+ client_data->chip_id = chip_id;
+ dev_notice(client_data->dev,
+ "Bosch Sensortec Device detected, "
+ "HW IC name: %s\n", sensor_type_map[i].sensor_name);
+ break;
+ }
+ }
+ if (i < smi_sensor_cnt)
+ break;
+ else {
+ if (read_count == CHECK_CHIP_ID_TIME_MAX) {
+ dev_err(client_data->dev,
+ "Failed!Bosch Sensortec Device not found"
+ " mismatch chip_id:%d\n", chip_id);
+ err = -ENODEV;
+ return err;
+ }
+ }
+ smi_delay(1);
+ }
+ }
+ return err;
+
+}
+
+static int smi_pmu_set_suspend(struct smi_client_data *client_data)
+{
+ int err = 0;
+ if (client_data == NULL)
+ return -EINVAL;
+ else {
+ err += SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_acc_arr[SENSOR_PM_SUSPEND]);
+ err += SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_gyro_arr[SENSOR_PM_SUSPEND]);
+ err += SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_mag_arr[SENSOR_PM_SUSPEND]);
+ client_data->pw.acc_pm = SMI_ACC_PM_SUSPEND;
+ client_data->pw.gyro_pm = SMI_GYRO_PM_SUSPEND;
+ client_data->pw.mag_pm = SMI_MAG_PM_SUSPEND;
+ }
+
+ return err;
+}
+
+static int smi_get_err_status(struct smi_client_data *client_data)
+{
+ int err = 0;
+
+ err = SMI_CALL_API(get_error_status)(&client_data->err_st.fatal_err,
+ &client_data->err_st.err_code, &client_data->err_st.i2c_fail,
+ &client_data->err_st.drop_cmd, &client_data->err_st.mag_drdy_err);
+ return err;
+}
+
+static void smi_work_func(struct work_struct *work)
+{
+ struct smi_client_data *client_data =
+ container_of((struct delayed_work *)work,
+ struct smi_client_data, work);
+ unsigned long delay =
+ msecs_to_jiffies(atomic_read(&client_data->delay));
+ struct smi130_accel_t data;
+ int err;
+
+ err = SMI_CALL_API(read_accel_xyz)(&data);
+ if (err < 0)
+ return;
+
+ /*report current frame via input event*/
+ input_event(client_data->input, EV_REL, REL_X, data.x);
+ input_event(client_data->input, EV_REL, REL_Y, data.y);
+ input_event(client_data->input, EV_REL, REL_Z, data.z);
+ input_sync(client_data->input);
+
+ schedule_delayed_work(&client_data->work, delay);
+}
+
+static ssize_t smi130_chip_id_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ return snprintf(buf, 16, "0x%x\n", client_data->chip_id);
+}
+
+static ssize_t smi130_err_st_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ int err = 0;
+ err = smi_get_err_status(client_data);
+ if (err)
+ return err;
+ else {
+ return snprintf(buf, 128, "fatal_err:0x%x, err_code:%d,\n\n"
+ "i2c_fail_err:%d, drop_cmd_err:%d, mag_drdy_err:%d\n",
+ client_data->err_st.fatal_err,
+ client_data->err_st.err_code,
+ client_data->err_st.i2c_fail,
+ client_data->err_st.drop_cmd,
+ client_data->err_st.mag_drdy_err);
+
+ }
+}
+
+static ssize_t smi130_sensor_time_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err = 0;
+ u32 sensor_time;
+ err = SMI_CALL_API(get_sensor_time)(&sensor_time);
+ if (err)
+ return err;
+ else
+ return snprintf(buf, 16, "0x%x\n", (unsigned int)sensor_time);
+}
+
+static ssize_t smi130_fifo_flush_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long enable;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &enable);
+ if (err)
+ return err;
+ if (enable)
+ err = SMI_CALL_API(set_command_register)(CMD_CLR_FIFO_DATA);
+
+ if (err)
+ dev_err(client_data->dev, "fifo flush failed!\n");
+
+ return count;
+
+}
+
+
+static ssize_t smi130_fifo_bytecount_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned int fifo_bytecount = 0;
+
+ SMI_CALL_API(fifo_length)(&fifo_bytecount);
+ err = snprintf(buf, 16, "%u\n", fifo_bytecount);
+ return err;
+}
+
+static ssize_t smi130_fifo_bytecount_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ int err;
+ unsigned long data;
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+ client_data->fifo_bytecount = (unsigned int) data;
+
+ return count;
+}
+
+int smi130_fifo_data_sel_get(struct smi_client_data *client_data)
+{
+ int err = 0;
+ unsigned char fifo_acc_en, fifo_gyro_en, fifo_mag_en;
+ unsigned char fifo_datasel;
+
+ err += SMI_CALL_API(get_fifo_accel_enable)(&fifo_acc_en);
+ err += SMI_CALL_API(get_fifo_gyro_enable)(&fifo_gyro_en);
+ err += SMI_CALL_API(get_fifo_mag_enable)(&fifo_mag_en);
+
+ if (err)
+ return err;
+
+ fifo_datasel = (fifo_acc_en << SMI_ACC_SENSOR) |
+ (fifo_gyro_en << SMI_GYRO_SENSOR) |
+ (fifo_mag_en << SMI_MAG_SENSOR);
+
+ client_data->fifo_data_sel = fifo_datasel;
+
+ return err;
+
+
+}
+
+static ssize_t smi130_fifo_data_sel_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err = 0;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ err = smi130_fifo_data_sel_get(client_data);
+ if (err) {
+ dev_err(client_data->dev, "get fifo_sel failed!\n");
+ return -EINVAL;
+ }
+ return snprintf(buf, 16, "%d\n", client_data->fifo_data_sel);
+}
+
+/* write any value to clear all the fifo data. */
+static ssize_t smi130_fifo_data_sel_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ int err;
+ unsigned long data;
+ unsigned char fifo_datasel;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+ /* data format: aimed 0b0000 0x(m)x(g)x(a), x:1 enable, 0:disable*/
+ if (data > 7)
+ return -EINVAL;
+
+
+ fifo_datasel = (unsigned char)data;
+
+
+ err += SMI_CALL_API(set_fifo_accel_enable)
+ ((fifo_datasel & (1 << SMI_ACC_SENSOR)) ? 1 : 0);
+ err += SMI_CALL_API(set_fifo_gyro_enable)
+ (fifo_datasel & (1 << SMI_GYRO_SENSOR) ? 1 : 0);
+ err += SMI_CALL_API(set_fifo_mag_enable)
+ ((fifo_datasel & (1 << SMI_MAG_SENSOR)) ? 1 : 0);
+
+ err += SMI_CALL_API(set_command_register)(CMD_CLR_FIFO_DATA);
+ if (err)
+ return -EIO;
+ else {
+ dev_notice(client_data->dev, "FIFO A_en:%d, G_en:%d, M_en:%d\n",
+ (fifo_datasel & (1 << SMI_ACC_SENSOR)) ? 1 : 0,
+ (fifo_datasel & (1 << SMI_GYRO_SENSOR) ? 1 : 0),
+ ((fifo_datasel & (1 << SMI_MAG_SENSOR)) ? 1 : 0));
+ client_data->fifo_data_sel = fifo_datasel;
+ }
+ return count;
+}
+
+static ssize_t smi130_fifo_data_out_frame_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ int err = 0;
+ uint32_t fifo_bytecount = 0;
+
+ err = SMI_CALL_API(fifo_length)(&fifo_bytecount);
+ if (err < 0) {
+ dev_err(client_data->dev, "read fifo_length err");
+ return -EINVAL;
+ }
+ if (fifo_bytecount == 0)
+ return 0;
+ err = smi_burst_read_wrapper(client_data->device.dev_addr,
+ SMI130_USER_FIFO_DATA__REG, buf,
+ fifo_bytecount);
+ if (err) {
+ dev_err(client_data->dev, "read fifo err");
+ SMI_CALL_API(set_command_register)(CMD_CLR_FIFO_DATA);
+ return -EINVAL;
+ }
+ return fifo_bytecount;
+
+}
+
+static ssize_t smi130_fifo_watermark_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char data = 0xff;
+
+ err = SMI_CALL_API(get_fifo_wm)(&data);
+
+ if (err)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_fifo_watermark_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long data;
+ unsigned char fifo_watermark;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ fifo_watermark = (unsigned char)data;
+ err = SMI_CALL_API(set_fifo_wm)(fifo_watermark);
+ if (err)
+ return -EIO;
+
+ return count;
+}
+
+
+static ssize_t smi130_fifo_header_en_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char data = 0xff;
+
+ err = SMI_CALL_API(get_fifo_header_enable)(&data);
+
+ if (err)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_fifo_header_en_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ int err;
+ unsigned long data;
+ unsigned char fifo_header_en;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+ if (data > 1)
+ return -ENOENT;
+
+ fifo_header_en = (unsigned char)data;
+ err = SMI_CALL_API(set_fifo_header_enable)(fifo_header_en);
+ if (err)
+ return -EIO;
+
+ client_data->fifo_head_en = fifo_header_en;
+
+ return count;
+}
+
+static ssize_t smi130_fifo_time_en_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char data = 0;
+
+ err = SMI_CALL_API(get_fifo_time_enable)(&data);
+
+ if (!err)
+ err = snprintf(buf, 16, "%d\n", data);
+
+ return err;
+}
+
+static ssize_t smi130_fifo_time_en_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long data;
+ unsigned char fifo_ts_en;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ fifo_ts_en = (unsigned char)data;
+
+ err = SMI_CALL_API(set_fifo_time_enable)(fifo_ts_en);
+ if (err)
+ return -EIO;
+
+ return count;
+}
+
+static ssize_t smi130_fifo_int_tag_en_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err = 0;
+ unsigned char fifo_tag_int1 = 0;
+ unsigned char fifo_tag_int2 = 0;
+ unsigned char fifo_tag_int;
+
+ err += SMI_CALL_API(get_fifo_tag_intr1_enable)(&fifo_tag_int1);
+ err += SMI_CALL_API(get_fifo_tag_intr2_enable)(&fifo_tag_int2);
+
+ fifo_tag_int = (fifo_tag_int1 << SMI130_INT0) |
+ (fifo_tag_int2 << SMI130_INT1);
+
+ if (!err)
+ err = snprintf(buf, 16, "%d\n", fifo_tag_int);
+
+ return err;
+}
+
+static ssize_t smi130_fifo_int_tag_en_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ int err;
+ unsigned long data;
+ unsigned char fifo_tag_int_en;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+ if (data > 3)
+ return -EINVAL;
+
+ fifo_tag_int_en = (unsigned char)data;
+
+ err += SMI_CALL_API(set_fifo_tag_intr1_enable)
+ ((fifo_tag_int_en & (1 << SMI130_INT0)) ? 1 : 0);
+ err += SMI_CALL_API(set_fifo_tag_intr2_enable)
+ ((fifo_tag_int_en & (1 << SMI130_INT1)) ? 1 : 0);
+
+ if (err) {
+ dev_err(client_data->dev, "fifo int tag en err:%d\n", err);
+ return -EIO;
+ }
+ client_data->fifo_int_tag_en = fifo_tag_int_en;
+
+ return count;
+}
+
+static int smi130_set_acc_op_mode(struct smi_client_data *client_data,
+ unsigned long op_mode)
+{
+ int err = 0;
+ unsigned char stc_enable;
+ unsigned char std_enable;
+ mutex_lock(&client_data->mutex_op_mode);
+
+ if (op_mode < SMI_ACC_PM_MAX) {
+ switch (op_mode) {
+ case SMI_ACC_PM_NORMAL:
+ err = SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_acc_arr[SMI_ACC_PM_NORMAL]);
+ client_data->pw.acc_pm = SMI_ACC_PM_NORMAL;
+ smi_delay(10);
+ break;
+ case SMI_ACC_PM_LP1:
+ err = SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_acc_arr[SMI_ACC_PM_LP1]);
+ client_data->pw.acc_pm = SMI_ACC_PM_LP1;
+ smi_delay(3);
+ break;
+ case SMI_ACC_PM_SUSPEND:
+ SMI_CALL_API(get_step_counter_enable)(&stc_enable);
+ SMI_CALL_API(get_step_detector_enable)(&std_enable);
+ if ((stc_enable == 0) && (std_enable == 0) &&
+ (client_data->sig_flag == 0)) {
+ err = SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_acc_arr[SMI_ACC_PM_SUSPEND]);
+ client_data->pw.acc_pm = SMI_ACC_PM_SUSPEND;
+ smi_delay(10);
+ }
+ break;
+ case SMI_ACC_PM_LP2:
+ err = SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_acc_arr[SMI_ACC_PM_LP2]);
+ client_data->pw.acc_pm = SMI_ACC_PM_LP2;
+ smi_delay(3);
+ break;
+ default:
+ mutex_unlock(&client_data->mutex_op_mode);
+ return -EINVAL;
+ }
+ } else {
+ mutex_unlock(&client_data->mutex_op_mode);
+ return -EINVAL;
+ }
+
+ mutex_unlock(&client_data->mutex_op_mode);
+
+ return err;
+
+
+}
+
+static ssize_t smi130_temperature_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ s16 temp = 0xff;
+
+ err = SMI_CALL_API(get_temp)(&temp);
+
+ if (!err)
+ err = snprintf(buf, 16, "0x%x\n", temp);
+
+ return err;
+}
+
+static ssize_t smi130_place_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ int place = BOSCH_SENSOR_PLACE_UNKNOWN;
+
+ if (NULL != client_data->bosch_pd)
+ place = client_data->bosch_pd->place;
+
+ return snprintf(buf, 16, "%d\n", place);
+}
+
+static ssize_t smi130_delay_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ return snprintf(buf, 16, "%d\n", atomic_read(&client_data->delay));
+
+}
+
+static ssize_t smi130_delay_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ int err;
+ unsigned long data;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ if (data == 0) {
+ err = -EINVAL;
+ return err;
+ }
+
+ if (data < SMI_DELAY_MIN)
+ data = SMI_DELAY_MIN;
+
+ atomic_set(&client_data->delay, (unsigned int)data);
+
+ return count;
+}
+
+static ssize_t smi130_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ return snprintf(buf, 16, "%d\n", atomic_read(&client_data->wkqueue_en));
+
+}
+
+static ssize_t smi130_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ int err;
+ unsigned long enable;
+ int pre_enable = atomic_read(&client_data->wkqueue_en);
+
+ err = kstrtoul(buf, 10, &enable);
+ if (err)
+ return err;
+
+ enable = enable ? 1 : 0;
+ mutex_lock(&client_data->mutex_enable);
+ if (enable) {
+ if (pre_enable == 0) {
+ smi130_set_acc_op_mode(client_data,
+ SMI_ACC_PM_NORMAL);
+ schedule_delayed_work(&client_data->work,
+ msecs_to_jiffies(atomic_read(&client_data->delay)));
+ atomic_set(&client_data->wkqueue_en, 1);
+ }
+
+ } else {
+ if (pre_enable == 1) {
+ smi130_set_acc_op_mode(client_data,
+ SMI_ACC_PM_SUSPEND);
+
+ cancel_delayed_work_sync(&client_data->work);
+ atomic_set(&client_data->wkqueue_en, 0);
+ }
+ }
+
+ mutex_unlock(&client_data->mutex_enable);
+
+ return count;
+}
+
+#if defined(SMI130_ENABLE_INT1) || defined(SMI130_ENABLE_INT2)
+/* accel sensor part */
+static ssize_t smi130_anymot_duration_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char data;
+
+ err = SMI_CALL_API(get_intr_any_motion_durn)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_anymot_duration_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_intr_any_motion_durn)((unsigned char)data);
+ if (err < 0)
+ return -EIO;
+
+ return count;
+}
+
+static ssize_t smi130_anymot_threshold_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+
+ err = SMI_CALL_API(get_intr_any_motion_thres)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_anymot_threshold_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_intr_any_motion_thres)((unsigned char)data);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t smi130_step_detector_status_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ u8 data = 0;
+ u8 step_det;
+ int err;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ err = SMI_CALL_API(get_step_detector_enable)(&step_det);
+ /*smi130_get_status0_step_int*/
+ if (err < 0)
+ return err;
+/*client_data->std will be updated in smi_stepdetector_interrupt_handle */
+ if ((step_det == 1) && (client_data->std == 1)) {
+ data = 1;
+ client_data->std = 0;
+ }
+ else {
+ data = 0;
+ }
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_step_detector_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+
+ err = SMI_CALL_API(get_step_detector_enable)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_step_detector_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_step_detector_enable)((unsigned char)data);
+ if (err < 0)
+ return -EIO;
+ if (data == 0)
+ client_data->pedo_data.wkar_step_detector_status = 0;
+ return count;
+}
+
+static ssize_t smi130_signification_motion_enable_store(
+ struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+ /*0x62 (bit 1) INT_MOTION_3 int_sig_mot_sel*/
+ err = SMI_CALL_API(set_intr_significant_motion_select)(
+ (unsigned char)data);
+ if (err < 0)
+ return -EIO;
+ if (data == 1) {
+ err = SMI_CALL_API(set_intr_enable_0)
+ (SMI130_ANY_MOTION_X_ENABLE, 1);
+ err += SMI_CALL_API(set_intr_enable_0)
+ (SMI130_ANY_MOTION_Y_ENABLE, 1);
+ err += SMI_CALL_API(set_intr_enable_0)
+ (SMI130_ANY_MOTION_Z_ENABLE, 1);
+ if (err < 0)
+ return -EIO;
+ enable_irq_wake(client_data->IRQ);
+ client_data->sig_flag = 1;
+ } else {
+ err = SMI_CALL_API(set_intr_enable_0)
+ (SMI130_ANY_MOTION_X_ENABLE, 0);
+ err += SMI_CALL_API(set_intr_enable_0)
+ (SMI130_ANY_MOTION_Y_ENABLE, 0);
+ err += SMI_CALL_API(set_intr_enable_0)
+ (SMI130_ANY_MOTION_Z_ENABLE, 0);
+ if (err < 0)
+ return -EIO;
+ disable_irq_wake(client_data->IRQ);
+ client_data->sig_flag = 0;
+ }
+ return count;
+}
+
+static ssize_t smi130_signification_motion_enable_show(
+ struct device *dev, struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+ /*0x62 (bit 1) INT_MOTION_3 int_sig_mot_sel*/
+ err = SMI_CALL_API(get_intr_significant_motion_select)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static int sigmotion_init_interrupts(u8 sig_map_int_pin)
+{
+ int ret = 0;
+/*0x60 */
+ ret += smi130_set_intr_any_motion_thres(0x1e);
+/* 0x62(bit 3~2) 0=1.5s */
+ ret += smi130_set_intr_significant_motion_skip(0);
+/*0x62(bit 5~4) 1=0.5s*/
+ ret += smi130_set_intr_significant_motion_proof(1);
+/*0x50 (bit 0, 1, 2) INT_EN_0 anymo x y z*/
+ ret += smi130_map_significant_motion_intr(sig_map_int_pin);
+/*0x62 (bit 1) INT_MOTION_3 int_sig_mot_sel
+close the signification_motion*/
+ ret += smi130_set_intr_significant_motion_select(0);
+/*close the anymotion interrupt*/
+ ret += SMI_CALL_API(set_intr_enable_0)
+ (SMI130_ANY_MOTION_X_ENABLE, 0);
+ ret += SMI_CALL_API(set_intr_enable_0)
+ (SMI130_ANY_MOTION_Y_ENABLE, 0);
+ ret += SMI_CALL_API(set_intr_enable_0)
+ (SMI130_ANY_MOTION_Z_ENABLE, 0);
+ if (ret)
+ printk(KERN_ERR "smi130 sig motion failed setting,%d!\n", ret);
+ return ret;
+
+}
+#endif
+
+static ssize_t smi130_acc_range_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char range;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = SMI_CALL_API(get_accel_range)(&range);
+ if (err)
+ return err;
+
+ client_data->range.acc_range = range;
+ return snprintf(buf, 16, "%d\n", range);
+}
+
+static ssize_t smi130_acc_range_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long range;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+
+ err = kstrtoul(buf, 10, &range);
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_accel_range)(range);
+ if (err)
+ return -EIO;
+
+ client_data->range.acc_range = range;
+ return count;
+}
+
+static ssize_t smi130_acc_odr_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char acc_odr;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = SMI_CALL_API(get_accel_output_data_rate)(&acc_odr);
+ if (err)
+ return err;
+
+ client_data->odr.acc_odr = acc_odr;
+ return snprintf(buf, 16, "%d\n", acc_odr);
+}
+
+static ssize_t smi130_acc_odr_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long acc_odr;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &acc_odr);
+ if (err)
+ return err;
+
+ if (acc_odr < 1 || acc_odr > 12)
+ return -EIO;
+
+ if (acc_odr < 5)
+ err = SMI_CALL_API(set_accel_under_sampling_parameter)(1);
+ else
+ err = SMI_CALL_API(set_accel_under_sampling_parameter)(0);
+
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_accel_output_data_rate)(acc_odr);
+ if (err)
+ return -EIO;
+ client_data->odr.acc_odr = acc_odr;
+ return count;
+}
+
+static ssize_t smi130_acc_op_mode_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ int err = 0;
+ u8 accel_pmu_status = 0;
+ err = SMI_CALL_API(get_accel_power_mode_stat)(
+ &accel_pmu_status);
+
+ if (err)
+ return err;
+ else
+ return snprintf(buf, 32, "reg:%d, val:%d\n", accel_pmu_status,
+ client_data->pw.acc_pm);
+}
+
+static ssize_t smi130_acc_op_mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ int err;
+ unsigned long op_mode;
+ err = kstrtoul(buf, 10, &op_mode);
+ if (err)
+ return err;
+
+ err = smi130_set_acc_op_mode(client_data, op_mode);
+ if (err)
+ return err;
+ else
+ return count;
+
+}
+
+static ssize_t smi130_acc_value_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct smi130_accel_t data;
+
+ int err;
+
+ err = SMI_CALL_API(read_accel_xyz)(&data);
+ if (err < 0)
+ return err;
+
+ return snprintf(buf, 48, "%hd %hd %hd\n",
+ data.x, data.y, data.z);
+}
+
+static ssize_t smi130_acc_fast_calibration_x_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+
+ err = SMI_CALL_API(get_foc_accel_x)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_acc_fast_calibration_x_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+ s8 accel_offset_x = 0;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+ /* 0: disable, 1: +1g, 2: -1g, 3: 0g */
+ if (data > 3)
+ return -EINVAL;
+
+ err = SMI_CALL_API(set_accel_foc_trigger)(X_AXIS,
+ data, &accel_offset_x);
+ if (err)
+ return -EIO;
+ else
+ client_data->calib_status |=
+ SMI_FAST_CALI_TRUE << SMI_ACC_X_FAST_CALI_RDY;
+ return count;
+}
+
+static ssize_t smi130_acc_fast_calibration_y_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+
+ err = SMI_CALL_API(get_foc_accel_y)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_acc_fast_calibration_y_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+ s8 accel_offset_y = 0;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+ /* 0: disable, 1: +1g, 2: -1g, 3: 0g */
+ if (data > 3)
+ return -EINVAL;
+
+ err = SMI_CALL_API(set_accel_foc_trigger)(Y_AXIS,
+ data, &accel_offset_y);
+ if (err)
+ return -EIO;
+ else
+ client_data->calib_status |=
+ SMI_FAST_CALI_TRUE << SMI_ACC_Y_FAST_CALI_RDY;
+ return count;
+}
+
+static ssize_t smi130_acc_fast_calibration_z_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+
+ err = SMI_CALL_API(get_foc_accel_z)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_acc_fast_calibration_z_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+ s8 accel_offset_z = 0;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ unsigned char data1[3] = {0};
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+ /* 0: disable, 1: +1g, 2: -1g, 3: 0g */
+ if (data > 3)
+ return -EINVAL;
+
+ err = SMI_CALL_API(set_accel_foc_trigger)(Z_AXIS,
+ data, &accel_offset_z);
+ if (err)
+ return -EIO;
+ else
+ client_data->calib_status |=
+ SMI_FAST_CALI_TRUE << SMI_ACC_Z_FAST_CALI_RDY;
+
+ if (client_data->calib_status == SMI_FAST_CALI_ALL_RDY) {
+ err = SMI_CALL_API(get_accel_offset_compensation_xaxis)(
+ &data1[0]);
+ err += SMI_CALL_API(get_accel_offset_compensation_yaxis)(
+ &data1[1]);
+ err += SMI_CALL_API(get_accel_offset_compensation_zaxis)(
+ &data1[2]);
+ dev_info(client_data->dev, "accx %d, accy %d, accz %d\n",
+ data1[0], data1[1], data1[2]);
+ if (err)
+ return -EIO;
+ input_event(client_data->input, EV_MSC,
+ INPUT_EVENT_FAST_ACC_CALIB_DONE,
+ (data1[0] | (data1[1] << 8) | (data1[2] << 16)));
+ input_sync(client_data->input);
+ client_data->calib_status = 0;
+ }
+
+ return count;
+}
+
+static ssize_t smi130_acc_offset_x_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+
+ err = SMI_CALL_API(get_accel_offset_compensation_xaxis)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+
+static ssize_t smi130_acc_offset_x_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_accel_offset_compensation_xaxis)
+ ((unsigned char)data);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t smi130_acc_offset_y_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+
+ err = SMI_CALL_API(get_accel_offset_compensation_yaxis)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_acc_offset_y_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_accel_offset_compensation_yaxis)
+ ((unsigned char)data);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t smi130_acc_offset_z_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+
+ err = SMI_CALL_API(get_accel_offset_compensation_zaxis)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_acc_offset_z_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_accel_offset_compensation_zaxis)
+ ((unsigned char)data);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t smi130_test_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ u8 raw_data[15] = {0};
+ unsigned int sensor_time = 0;
+
+ int err;
+ memset(raw_data, 0, sizeof(raw_data));
+
+ err = client_data->device.bus_read(client_data->device.dev_addr,
+ SMI130_USER_DATA_8_GYRO_X_LSB__REG, raw_data, 15);
+ if (err)
+ return err;
+
+ udelay(10);
+ sensor_time = (u32)(raw_data[14] << 16 | raw_data[13] << 8
+ | raw_data[12]);
+
+ return snprintf(buf, 128, "%d %d %d %d %d %d %u",
+ (s16)(raw_data[1] << 8 | raw_data[0]),
+ (s16)(raw_data[3] << 8 | raw_data[2]),
+ (s16)(raw_data[5] << 8 | raw_data[4]),
+ (s16)(raw_data[7] << 8 | raw_data[6]),
+ (s16)(raw_data[9] << 8 | raw_data[8]),
+ (s16)(raw_data[11] << 8 | raw_data[10]),
+ sensor_time);
+
+}
+
+static ssize_t smi130_step_counter_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = SMI_CALL_API(get_step_counter_enable)(&data);
+
+ client_data->stc_enable = data;
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_step_counter_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_step_counter_enable)((unsigned char)data);
+
+ client_data->stc_enable = data;
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+
+static ssize_t smi130_step_counter_mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_step_mode)((unsigned char)data);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t smi130_step_counter_clc_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = smi130_clear_step_counter();
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t smi130_step_counter_value_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ u16 data;
+ int err;
+ static u16 last_stc_value;
+
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = SMI_CALL_API(read_step_count)(&data);
+
+ if (err < 0)
+ return err;
+ if (data >= last_stc_value) {
+ client_data->pedo_data.last_step_counter_value += (
+ data - last_stc_value);
+ last_stc_value = data;
+ } else
+ last_stc_value = data;
+ return snprintf(buf, 16, "%d\n",
+ client_data->pedo_data.last_step_counter_value);
+}
+
+static ssize_t smi130_smi_value_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ u8 raw_data[12] = {0};
+
+ int err;
+ memset(raw_data, 0, sizeof(raw_data));
+
+ err = client_data->device.bus_read(client_data->device.dev_addr,
+ SMI130_USER_DATA_8_GYRO_X_LSB__REG, raw_data, 12);
+ if (err)
+ return err;
+ /*output:gyro x y z acc x y z*/
+ return snprintf(buf, 96, "%hd %d %hd %hd %hd %hd\n",
+ (s16)(raw_data[1] << 8 | raw_data[0]),
+ (s16)(raw_data[3] << 8 | raw_data[2]),
+ (s16)(raw_data[5] << 8 | raw_data[4]),
+ (s16)(raw_data[7] << 8 | raw_data[6]),
+ (s16)(raw_data[9] << 8 | raw_data[8]),
+ (s16)(raw_data[11] << 8 | raw_data[10]));
+
+}
+
+
+static ssize_t smi130_selftest_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ return snprintf(buf, 16, "0x%x\n",
+ atomic_read(&client_data->selftest_result));
+}
+
+static int smi_restore_hw_cfg(struct smi_client_data *client);
+
+/*!
+ * @brief store selftest result which make up of acc and gyro
+ * format: 0b 0000 xxxx x:1 failed, 0 success
+ * bit3: gyro_self
+ * bit2..0: acc_self z y x
+ */
+static ssize_t smi130_selftest_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ int err = 0;
+ int i = 0;
+
+ u8 acc_selftest = 0;
+ u8 gyro_selftest = 0;
+ u8 smi_selftest = 0;
+ s16 axis_p_value, axis_n_value;
+ u16 diff_axis[3] = {0xff, 0xff, 0xff};
+ u8 acc_odr, range, acc_selftest_amp, acc_selftest_sign;
+
+ dev_notice(client_data->dev, "Selftest for SMI16x starting.\n");
+
+ client_data->selftest = 1;
+
+ /*soft reset*/
+ err = SMI_CALL_API(set_command_register)(CMD_RESET_USER_REG);
+ msleep(70);
+ err += SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_acc_arr[SMI_ACC_PM_NORMAL]);
+ err += SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_gyro_arr[SMI_GYRO_PM_NORMAL]);
+ err += SMI_CALL_API(set_accel_under_sampling_parameter)(0);
+ err += SMI_CALL_API(set_accel_output_data_rate)(
+ SMI130_ACCEL_OUTPUT_DATA_RATE_1600HZ);
+
+ /* set to 8G range*/
+ err += SMI_CALL_API(set_accel_range)(SMI130_ACCEL_RANGE_8G);
+ /* set to self amp high */
+ err += SMI_CALL_API(set_accel_selftest_amp)(SMI_SELFTEST_AMP_HIGH);
+
+
+ err += SMI_CALL_API(get_accel_output_data_rate)(&acc_odr);
+ err += SMI_CALL_API(get_accel_range)(&range);
+ err += SMI_CALL_API(get_accel_selftest_amp)(&acc_selftest_amp);
+ err += SMI_CALL_API(read_accel_x)(&axis_n_value);
+
+ dev_info(client_data->dev,
+ "acc_odr:%d, acc_range:%d, acc_selftest_amp:%d, acc_x:%d\n",
+ acc_odr, range, acc_selftest_amp, axis_n_value);
+
+ for (i = X_AXIS; i < AXIS_MAX; i++) {
+ axis_n_value = 0;
+ axis_p_value = 0;
+ /* set every selftest axis */
+ /*set_acc_selftest_axis(param),param x:1, y:2, z:3
+ * but X_AXIS:0, Y_AXIS:1, Z_AXIS:2
+ * so we need to +1*/
+ err += SMI_CALL_API(set_accel_selftest_axis)(i + 1);
+ msleep(50);
+ switch (i) {
+ case X_AXIS:
+ /* set negative sign */
+ err += SMI_CALL_API(set_accel_selftest_sign)(0);
+ err += SMI_CALL_API(get_accel_selftest_sign)(
+ &acc_selftest_sign);
+
+ msleep(60);
+ err += SMI_CALL_API(read_accel_x)(&axis_n_value);
+ dev_info(client_data->dev,
+ "acc_x_selftest_sign:%d, axis_n_value:%d\n",
+ acc_selftest_sign, axis_n_value);
+
+ /* set postive sign */
+ err += SMI_CALL_API(set_accel_selftest_sign)(1);
+ err += SMI_CALL_API(get_accel_selftest_sign)(
+ &acc_selftest_sign);
+
+ msleep(60);
+ err += SMI_CALL_API(read_accel_x)(&axis_p_value);
+ dev_info(client_data->dev,
+ "acc_x_selftest_sign:%d, axis_p_value:%d\n",
+ acc_selftest_sign, axis_p_value);
+ diff_axis[i] = abs(axis_p_value - axis_n_value);
+ break;
+
+ case Y_AXIS:
+ /* set negative sign */
+ err += SMI_CALL_API(set_accel_selftest_sign)(0);
+ msleep(60);
+ err += SMI_CALL_API(read_accel_y)(&axis_n_value);
+ /* set postive sign */
+ err += SMI_CALL_API(set_accel_selftest_sign)(1);
+ msleep(60);
+ err += SMI_CALL_API(read_accel_y)(&axis_p_value);
+ diff_axis[i] = abs(axis_p_value - axis_n_value);
+ break;
+
+ case Z_AXIS:
+ /* set negative sign */
+ err += SMI_CALL_API(set_accel_selftest_sign)(0);
+ msleep(60);
+ err += SMI_CALL_API(read_accel_z)(&axis_n_value);
+ /* set postive sign */
+ err += SMI_CALL_API(set_accel_selftest_sign)(1);
+ msleep(60);
+ err += SMI_CALL_API(read_accel_z)(&axis_p_value);
+ /* also start gyro self test */
+ err += SMI_CALL_API(set_gyro_selftest_start)(1);
+ msleep(60);
+ err += SMI_CALL_API(get_gyro_selftest)(&gyro_selftest);
+
+ diff_axis[i] = abs(axis_p_value - axis_n_value);
+ break;
+ default:
+ err += -EINVAL;
+ break;
+ }
+ if (err) {
+ dev_err(client_data->dev,
+ "Failed selftest axis:%s, p_val=%d, n_val=%d\n",
+ smi_axis_name[i], axis_p_value, axis_n_value);
+ client_data->selftest = 0;
+ return -EINVAL;
+ }
+
+ /*400mg for acc z axis*/
+ if (Z_AXIS == i) {
+ if (diff_axis[i] < 1639) {
+ acc_selftest |= 1 << i;
+ dev_err(client_data->dev,
+ "Over selftest minimum for "
+ "axis:%s,diff=%d,p_val=%d, n_val=%d\n",
+ smi_axis_name[i], diff_axis[i],
+ axis_p_value, axis_n_value);
+ }
+ } else {
+ /*800mg for x or y axis*/
+ if (diff_axis[i] < 3277) {
+ acc_selftest |= 1 << i;
+
+ if (smi_get_err_status(client_data) < 0)
+ return err;
+ dev_err(client_data->dev,
+ "Over selftest minimum for "
+ "axis:%s,diff=%d, p_val=%d, n_val=%d\n",
+ smi_axis_name[i], diff_axis[i],
+ axis_p_value, axis_n_value);
+ dev_err(client_data->dev, "err_st:0x%x\n",
+ client_data->err_st.err_st_all);
+
+ }
+ }
+
+ }
+ /* gyro_selftest==1,gyro selftest successfully,
+ * but smi_result bit4 0 is successful, 1 is failed*/
+ smi_selftest = (acc_selftest & 0x0f) | ((!gyro_selftest) << AXIS_MAX);
+ atomic_set(&client_data->selftest_result, smi_selftest);
+ /*soft reset*/
+ err = SMI_CALL_API(set_command_register)(CMD_RESET_USER_REG);
+ if (err) {
+ client_data->selftest = 0;
+ return err;
+ }
+ msleep(50);
+
+ smi_restore_hw_cfg(client_data);
+
+ client_data->selftest = 0;
+ dev_notice(client_data->dev, "Selftest for SMI16x finished\n");
+
+ return count;
+}
+
+/* gyro sensor part */
+static ssize_t smi130_gyro_op_mode_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ int err = 0;
+ u8 gyro_pmu_status = 0;
+
+ err = SMI_CALL_API(get_gyro_power_mode_stat)(
+ &gyro_pmu_status);
+
+ if (err)
+ return err;
+ else
+ return snprintf(buf, 32, "reg:%d, val:%d\n", gyro_pmu_status,
+ client_data->pw.gyro_pm);
+}
+
+static ssize_t smi130_gyro_op_mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ unsigned long op_mode;
+ int err;
+
+ err = kstrtoul(buf, 10, &op_mode);
+ if (err)
+ return err;
+
+ mutex_lock(&client_data->mutex_op_mode);
+
+ if (op_mode < SMI_GYRO_PM_MAX) {
+ switch (op_mode) {
+ case SMI_GYRO_PM_NORMAL:
+ err = SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_gyro_arr[SMI_GYRO_PM_NORMAL]);
+ client_data->pw.gyro_pm = SMI_GYRO_PM_NORMAL;
+ smi_delay(60);
+ break;
+ case SMI_GYRO_PM_FAST_START:
+ err = SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_gyro_arr[SMI_GYRO_PM_FAST_START]);
+ client_data->pw.gyro_pm = SMI_GYRO_PM_FAST_START;
+ smi_delay(60);
+ break;
+ case SMI_GYRO_PM_SUSPEND:
+ err = SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_gyro_arr[SMI_GYRO_PM_SUSPEND]);
+ client_data->pw.gyro_pm = SMI_GYRO_PM_SUSPEND;
+ smi_delay(60);
+ break;
+ default:
+ mutex_unlock(&client_data->mutex_op_mode);
+ return -EINVAL;
+ }
+ } else {
+ mutex_unlock(&client_data->mutex_op_mode);
+ return -EINVAL;
+ }
+
+ mutex_unlock(&client_data->mutex_op_mode);
+
+ if (err)
+ return err;
+ else
+ return count;
+
+}
+
+static ssize_t smi130_gyro_value_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct smi130_gyro_t data;
+ int err;
+
+ err = SMI_CALL_API(read_gyro_xyz)(&data);
+ if (err < 0)
+ return err;
+
+
+ return snprintf(buf, 48, "%hd %hd %hd\n", data.x,
+ data.y, data.z);
+}
+
+static ssize_t smi130_gyro_range_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char range;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = SMI_CALL_API(get_gyro_range)(&range);
+ if (err)
+ return err;
+
+ client_data->range.gyro_range = range;
+ return snprintf(buf, 16, "%d\n", range);
+}
+
+static ssize_t smi130_gyro_range_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long range;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &range);
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_gyro_range)(range);
+ if (err)
+ return -EIO;
+
+ client_data->range.gyro_range = range;
+ return count;
+}
+
+static ssize_t smi130_gyro_odr_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char gyro_odr;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = SMI_CALL_API(get_gyro_output_data_rate)(&gyro_odr);
+ if (err)
+ return err;
+
+ client_data->odr.gyro_odr = gyro_odr;
+ return snprintf(buf, 16, "%d\n", gyro_odr);
+}
+
+static ssize_t smi130_gyro_odr_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long gyro_odr;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &gyro_odr);
+ if (err)
+ return err;
+
+ if (gyro_odr < 6 || gyro_odr > 13)
+ return -EIO;
+
+ err = SMI_CALL_API(set_gyro_output_data_rate)(gyro_odr);
+ if (err)
+ return -EIO;
+
+ client_data->odr.gyro_odr = gyro_odr;
+ return count;
+}
+
+static ssize_t smi130_gyro_fast_calibration_en_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+
+ err = SMI_CALL_API(get_foc_gyro_enable)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_gyro_fast_calibration_en_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long enable;
+ s8 err;
+ s16 gyr_off_x;
+ s16 gyr_off_y;
+ s16 gyr_off_z;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &enable);
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_foc_gyro_enable)((u8)enable,
+ &gyr_off_x, &gyr_off_y, &gyr_off_z);
+
+ if (err < 0)
+ return -EIO;
+ else {
+ input_event(client_data->input, EV_MSC,
+ INPUT_EVENT_FAST_GYRO_CALIB_DONE, 1);
+ input_sync(client_data->input);
+ }
+ return count;
+}
+
+static ssize_t smi130_gyro_offset_x_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ s16 data = 0;
+ s8 err = 0;
+
+ err = SMI_CALL_API(get_gyro_offset_compensation_xaxis)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_gyro_offset_x_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ s8 err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_gyro_offset_compensation_xaxis)((s16)data);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t smi130_gyro_offset_y_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ s16 data = 0;
+ s8 err = 0;
+
+ err = SMI_CALL_API(get_gyro_offset_compensation_yaxis)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_gyro_offset_y_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ s8 err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_gyro_offset_compensation_yaxis)((s16)data);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t smi130_gyro_offset_z_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ s16 data = 0;
+ int err = 0;
+
+ err = SMI_CALL_API(get_gyro_offset_compensation_zaxis)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_gyro_offset_z_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_gyro_offset_compensation_zaxis)((s16)data);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+
+/* mag sensor part */
+#ifdef SMI130_MAG_INTERFACE_SUPPORT
+static ssize_t smi130_mag_op_mode_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ u8 mag_op_mode;
+ s8 err;
+ err = smi130_get_mag_power_mode_stat(&mag_op_mode);
+ if (err) {
+ dev_err(client_data->dev,
+ "Failed to get SMI130 mag power mode:%d\n", err);
+ return err;
+ } else
+ return snprintf(buf, 32, "%d, reg:%d\n",
+ client_data->pw.mag_pm, mag_op_mode);
+}
+
+static ssize_t smi130_mag_op_mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ unsigned long op_mode;
+ int err;
+
+ err = kstrtoul(buf, 10, &op_mode);
+ if (err)
+ return err;
+
+ if (op_mode == client_data->pw.mag_pm)
+ return count;
+
+ mutex_lock(&client_data->mutex_op_mode);
+
+
+ if (op_mode < SMI_MAG_PM_MAX) {
+ switch (op_mode) {
+ case SMI_MAG_PM_NORMAL:
+ /* need to modify as mag sensor connected,
+ * set write address to 0x4c and triggers
+ * write operation
+ * 0x4c(op mode control reg)
+ * enables normal mode in magnetometer */
+#if defined(SMI130_AKM09912_SUPPORT)
+ err = smi130_set_bosch_akm_and_secondary_if_powermode(
+ SMI130_MAG_FORCE_MODE);
+#else
+ err = smi130_set_bmm150_mag_and_secondary_if_power_mode(
+ SMI130_MAG_FORCE_MODE);
+#endif
+ client_data->pw.mag_pm = SMI_MAG_PM_NORMAL;
+ smi_delay(5);
+ break;
+ case SMI_MAG_PM_LP1:
+ /* need to modify as mag sensor connected,
+ * set write address to 0x4 band triggers
+ * write operation
+ * 0x4b(bmm150, power control reg, bit0)
+ * enables power in magnetometer*/
+#if defined(SMI130_AKM09912_SUPPORT)
+ err = smi130_set_bosch_akm_and_secondary_if_powermode(
+ SMI130_MAG_FORCE_MODE);
+#else
+ err = smi130_set_bmm150_mag_and_secondary_if_power_mode(
+ SMI130_MAG_FORCE_MODE);
+#endif
+ client_data->pw.mag_pm = SMI_MAG_PM_LP1;
+ smi_delay(5);
+ break;
+ case SMI_MAG_PM_SUSPEND:
+ case SMI_MAG_PM_LP2:
+#if defined(SMI130_AKM09912_SUPPORT)
+ err = smi130_set_bosch_akm_and_secondary_if_powermode(
+ SMI130_MAG_SUSPEND_MODE);
+#else
+ err = smi130_set_bmm150_mag_and_secondary_if_power_mode(
+ SMI130_MAG_SUSPEND_MODE);
+#endif
+ client_data->pw.mag_pm = op_mode;
+ smi_delay(5);
+ break;
+ default:
+ mutex_unlock(&client_data->mutex_op_mode);
+ return -EINVAL;
+ }
+ } else {
+ mutex_unlock(&client_data->mutex_op_mode);
+ return -EINVAL;
+ }
+
+ mutex_unlock(&client_data->mutex_op_mode);
+
+ if (err) {
+ dev_err(client_data->dev,
+ "Failed to switch SMI130 mag power mode:%d\n",
+ client_data->pw.mag_pm);
+ return err;
+ } else
+ return count;
+
+}
+
+static ssize_t smi130_mag_odr_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err = 0;
+ unsigned char mag_odr = 0;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = SMI_CALL_API(get_mag_output_data_rate)(&mag_odr);
+ if (err)
+ return err;
+
+ client_data->odr.mag_odr = mag_odr;
+ return snprintf(buf, 16, "%d\n", mag_odr);
+}
+
+static ssize_t smi130_mag_odr_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long mag_odr;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &mag_odr);
+ if (err)
+ return err;
+ /*1~25/32hz,..6(25hz),7(50hz),... */
+ err = SMI_CALL_API(set_mag_output_data_rate)(mag_odr);
+ if (err)
+ return -EIO;
+
+ client_data->odr.mag_odr = mag_odr;
+ return count;
+}
+
+static ssize_t smi130_mag_i2c_address_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ u8 data;
+ s8 err;
+
+ err = SMI_CALL_API(set_mag_manual_enable)(1);
+ err += SMI_CALL_API(get_i2c_device_addr)(&data);
+ err += SMI_CALL_API(set_mag_manual_enable)(0);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "0x%x\n", data);
+}
+
+static ssize_t smi130_mag_i2c_address_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err += SMI_CALL_API(set_mag_manual_enable)(1);
+ if (!err)
+ err += SMI_CALL_API(set_i2c_device_addr)((unsigned char)data);
+ err += SMI_CALL_API(set_mag_manual_enable)(0);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t smi130_mag_value_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ struct smi130_mag_xyz_s32_t data;
+ int err;
+ /* raw data with compensation */
+#if defined(SMI130_AKM09912_SUPPORT)
+ err = smi130_bosch_akm09912_compensate_xyz(&data);
+#else
+ err = smi130_bmm150_mag_compensate_xyz(&data);
+#endif
+
+ if (err < 0) {
+ memset(&data, 0, sizeof(data));
+ dev_err(client_data->dev, "mag not ready!\n");
+ }
+ return snprintf(buf, 48, "%hd %hd %hd\n", data.x,
+ data.y, data.z);
+}
+static ssize_t smi130_mag_offset_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err = 0;
+ unsigned char mag_offset;
+ err = SMI_CALL_API(get_mag_offset)(&mag_offset);
+ if (err)
+ return err;
+
+ return snprintf(buf, 16, "%d\n", mag_offset);
+
+}
+
+static ssize_t smi130_mag_offset_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err += SMI_CALL_API(set_mag_manual_enable)(1);
+ if (err == 0)
+ err += SMI_CALL_API(set_mag_offset)((unsigned char)data);
+ err += SMI_CALL_API(set_mag_manual_enable)(0);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t smi130_mag_chip_id_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ s8 err = 0;
+ u8 mag_chipid;
+
+ err = smi130_set_mag_manual_enable(0x01);
+ /* read mag chip_id value */
+#if defined(SMI130_AKM09912_SUPPORT)
+ err += smi130_set_mag_read_addr(AKM09912_CHIP_ID_REG);
+ /* 0x04 is mag_x lsb register */
+ err += smi130_read_reg(SMI130_USER_DATA_0_MAG_X_LSB__REG,
+ &mag_chipid, 1);
+
+ /* Must add this commands to re-set data register addr of mag sensor */
+ err += smi130_set_mag_read_addr(AKM_DATA_REGISTER);
+#else
+ err += smi130_set_mag_read_addr(SMI130_BMM150_CHIP_ID);
+ /* 0x04 is mag_x lsb register */
+ err += smi130_read_reg(SMI130_USER_DATA_0_MAG_X_LSB__REG,
+ &mag_chipid, 1);
+
+ /* Must add this commands to re-set data register addr of mag sensor */
+ /* 0x42 is bmm150 data register address */
+ err += smi130_set_mag_read_addr(SMI130_BMM150_DATA_REG);
+#endif
+
+ err += smi130_set_mag_manual_enable(0x00);
+
+ if (err)
+ return err;
+
+ return snprintf(buf, 16, "%x\n", mag_chipid);
+
+}
+
+static ssize_t smi130_mag_chip_name_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ u8 mag_chipid = 0;
+#if defined(SMI130_AKM09912_SUPPORT)
+ mag_chipid = 15;
+#else
+ mag_chipid = 150;
+#endif
+ return snprintf(buf, 16, "%d\n", mag_chipid);
+}
+
+struct smi130_mag_xyz_s32_t mag_compensate;
+static ssize_t smi130_mag_compensate_xyz_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ memcpy(buf, &mag_compensate, sizeof(mag_compensate));
+ return sizeof(mag_compensate);
+}
+static ssize_t smi130_mag_compensate_xyz_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct smi130_mag_xyzr_t mag_raw;
+ memset(&mag_compensate, 0, sizeof(mag_compensate));
+ memset(&mag_raw, 0, sizeof(mag_raw));
+ mag_raw.x = (buf[1] << 8 | buf[0]);
+ mag_raw.y = (buf[3] << 8 | buf[2]);
+ mag_raw.z = (buf[5] << 8 | buf[4]);
+ mag_raw.r = (buf[7] << 8 | buf[6]);
+ mag_raw.x = mag_raw.x >> 3;
+ mag_raw.y = mag_raw.y >> 3;
+ mag_raw.z = mag_raw.z >> 1;
+ mag_raw.r = mag_raw.r >> 2;
+ smi130_bmm150_mag_compensate_xyz_raw(
+ &mag_compensate, mag_raw);
+ return count;
+}
+
+#endif
+
+#if defined(SMI130_ENABLE_INT1) || defined(SMI130_ENABLE_INT2)
+static ssize_t smi_enable_int_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int interrupt_type, value;
+
+ sscanf(buf, "%3d %3d", &interrupt_type, &value);
+
+ if (interrupt_type < 0 || interrupt_type > 16)
+ return -EINVAL;
+
+ if (interrupt_type <= SMI_FLAT_INT) {
+ if (SMI_CALL_API(set_intr_enable_0)
+ (smi_interrupt_type[interrupt_type], value) < 0)
+ return -EINVAL;
+ } else if (interrupt_type <= SMI_FWM_INT) {
+ if (SMI_CALL_API(set_intr_enable_1)
+ (smi_interrupt_type[interrupt_type], value) < 0)
+ return -EINVAL;
+ } else {
+ if (SMI_CALL_API(set_intr_enable_2)
+ (smi_interrupt_type[interrupt_type], value) < 0)
+ return -EINVAL;
+ }
+
+ return count;
+}
+
+#endif
+
+static ssize_t smi130_show_reg_sel(struct device *dev
+ , struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ if (client_data == NULL) {
+ printk(KERN_ERR "Invalid client_data pointer");
+ return -ENODEV;
+ }
+
+ return snprintf(buf, 64, "reg=0X%02X, len=%d\n",
+ client_data->reg_sel, client_data->reg_len);
+}
+
+static ssize_t smi130_store_reg_sel(struct device *dev
+ , struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ ssize_t ret;
+
+ if (client_data == NULL) {
+ printk(KERN_ERR "Invalid client_data pointer");
+ return -ENODEV;
+ }
+ ret = sscanf(buf, "%11X %11d",
+ &client_data->reg_sel, &client_data->reg_len);
+ if (ret != 2) {
+ dev_err(client_data->dev, "Invalid argument");
+ return -EINVAL;
+ }
+
+ return count;
+}
+
+static ssize_t smi130_show_reg_val(struct device *dev
+ , struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ ssize_t ret;
+ u8 reg_data[128], i;
+ int pos;
+
+ if (client_data == NULL) {
+ printk(KERN_ERR "Invalid client_data pointer");
+ return -ENODEV;
+ }
+
+ ret = smi_burst_read_wrapper(client_data->device.dev_addr,
+ client_data->reg_sel,
+ reg_data, client_data->reg_len);
+ if (ret < 0) {
+ dev_err(client_data->dev, "Reg op failed");
+ return ret;
+ }
+
+ pos = 0;
+ for (i = 0; i < client_data->reg_len; ++i) {
+ pos += snprintf(buf + pos, 16, "%02X", reg_data[i]);
+ buf[pos++] = (i + 1) % 16 == 0 ? '\n' : ' ';
+ }
+ if (buf[pos - 1] == ' ')
+ buf[pos - 1] = '\n';
+
+ return pos;
+}
+
+static ssize_t smi130_store_reg_val(struct device *dev
+ , struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ ssize_t ret;
+ u8 reg_data[32];
+ int i, j, status, digit;
+
+ if (client_data == NULL) {
+ printk(KERN_ERR "Invalid client_data pointer");
+ return -ENODEV;
+ }
+ status = 0;
+ for (i = j = 0; i < count && j < client_data->reg_len; ++i) {
+ if (buf[i] == ' ' || buf[i] == '\n' || buf[i] == '\t' ||
+ buf[i] == '\r') {
+ status = 0;
+ ++j;
+ continue;
+ }
+ digit = buf[i] & 0x10 ? (buf[i] & 0xF) : ((buf[i] & 0xF) + 9);
+ printk(KERN_INFO "digit is %d", digit);
+ switch (status) {
+ case 2:
+ ++j; /* Fall thru */
+ case 0:
+ reg_data[j] = digit;
+ status = 1;
+ break;
+ case 1:
+ reg_data[j] = reg_data[j] * 16 + digit;
+ status = 2;
+ break;
+ }
+ }
+ if (status > 0)
+ ++j;
+ if (j > client_data->reg_len)
+ j = client_data->reg_len;
+ else if (j < client_data->reg_len) {
+ dev_err(client_data->dev, "Invalid argument");
+ return -EINVAL;
+ }
+ printk(KERN_INFO "Reg data read as");
+ for (i = 0; i < j; ++i)
+ printk(KERN_INFO "%d", reg_data[i]);
+
+ ret = SMI_CALL_API(write_reg)(
+ client_data->reg_sel,
+ reg_data, client_data->reg_len);
+ if (ret < 0) {
+ dev_err(client_data->dev, "Reg op failed");
+ return ret;
+ }
+
+ return count;
+}
+
+static ssize_t smi130_driver_version_show(struct device *dev
+ , struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ int ret;
+
+ if (client_data == NULL) {
+ printk(KERN_ERR "Invalid client_data pointer");
+ return -ENODEV;
+ }
+
+ ret = snprintf(buf, 128, "Driver version: %s\n",
+ DRIVER_VERSION);
+
+ return ret;
+}
+static DEVICE_ATTR(chip_id, S_IRUGO,
+ smi130_chip_id_show, NULL);
+static DEVICE_ATTR(err_st, S_IRUGO,
+ smi130_err_st_show, NULL);
+static DEVICE_ATTR(sensor_time, S_IRUGO,
+ smi130_sensor_time_show, NULL);
+
+static DEVICE_ATTR(selftest, S_IRUGO | S_IWUSR,
+ smi130_selftest_show, smi130_selftest_store);
+static DEVICE_ATTR(fifo_flush, S_IRUGO | S_IWUSR,
+ NULL, smi130_fifo_flush_store);
+static DEVICE_ATTR(fifo_bytecount, S_IRUGO | S_IWUSR,
+ smi130_fifo_bytecount_show, smi130_fifo_bytecount_store);
+static DEVICE_ATTR(fifo_data_sel, S_IRUGO | S_IWUSR,
+ smi130_fifo_data_sel_show, smi130_fifo_data_sel_store);
+static DEVICE_ATTR(fifo_data_frame, S_IRUGO,
+ smi130_fifo_data_out_frame_show, NULL);
+
+static DEVICE_ATTR(fifo_watermark, S_IRUGO | S_IWUSR,
+ smi130_fifo_watermark_show, smi130_fifo_watermark_store);
+
+static DEVICE_ATTR(fifo_header_en, S_IRUGO | S_IWUSR,
+ smi130_fifo_header_en_show, smi130_fifo_header_en_store);
+static DEVICE_ATTR(fifo_time_en, S_IRUGO | S_IWUSR,
+ smi130_fifo_time_en_show, smi130_fifo_time_en_store);
+static DEVICE_ATTR(fifo_int_tag_en, S_IRUGO | S_IWUSR,
+ smi130_fifo_int_tag_en_show, smi130_fifo_int_tag_en_store);
+
+static DEVICE_ATTR(temperature, S_IRUGO,
+ smi130_temperature_show, NULL);
+static DEVICE_ATTR(place, S_IRUGO,
+ smi130_place_show, NULL);
+static DEVICE_ATTR(delay, S_IRUGO | S_IWUSR,
+ smi130_delay_show, smi130_delay_store);
+static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR,
+ smi130_enable_show, smi130_enable_store);
+static DEVICE_ATTR(acc_range, S_IRUGO | S_IWUSR,
+ smi130_acc_range_show, smi130_acc_range_store);
+static DEVICE_ATTR(acc_odr, S_IRUGO | S_IWUSR,
+ smi130_acc_odr_show, smi130_acc_odr_store);
+static DEVICE_ATTR(acc_op_mode, S_IRUGO | S_IWUSR,
+ smi130_acc_op_mode_show, smi130_acc_op_mode_store);
+static DEVICE_ATTR(acc_value, S_IRUGO,
+ smi130_acc_value_show, NULL);
+static DEVICE_ATTR(acc_fast_calibration_x, S_IRUGO | S_IWUSR,
+ smi130_acc_fast_calibration_x_show,
+ smi130_acc_fast_calibration_x_store);
+static DEVICE_ATTR(acc_fast_calibration_y, S_IRUGO | S_IWUSR,
+ smi130_acc_fast_calibration_y_show,
+ smi130_acc_fast_calibration_y_store);
+static DEVICE_ATTR(acc_fast_calibration_z, S_IRUGO | S_IWUSR,
+ smi130_acc_fast_calibration_z_show,
+ smi130_acc_fast_calibration_z_store);
+static DEVICE_ATTR(acc_offset_x, S_IRUGO | S_IWUSR,
+ smi130_acc_offset_x_show,
+ smi130_acc_offset_x_store);
+static DEVICE_ATTR(acc_offset_y, S_IRUGO | S_IWUSR,
+ smi130_acc_offset_y_show,
+ smi130_acc_offset_y_store);
+static DEVICE_ATTR(acc_offset_z, S_IRUGO | S_IWUSR,
+ smi130_acc_offset_z_show,
+ smi130_acc_offset_z_store);
+static DEVICE_ATTR(test, S_IRUGO,
+ smi130_test_show, NULL);
+static DEVICE_ATTR(stc_enable, S_IRUGO | S_IWUSR,
+ smi130_step_counter_enable_show,
+ smi130_step_counter_enable_store);
+static DEVICE_ATTR(stc_mode, S_IRUGO | S_IWUSR,
+ NULL, smi130_step_counter_mode_store);
+static DEVICE_ATTR(stc_clc, S_IRUGO | S_IWUSR,
+ NULL, smi130_step_counter_clc_store);
+static DEVICE_ATTR(stc_value, S_IRUGO,
+ smi130_step_counter_value_show, NULL);
+static DEVICE_ATTR(reg_sel, S_IRUGO | S_IWUSR,
+ smi130_show_reg_sel, smi130_store_reg_sel);
+static DEVICE_ATTR(reg_val, S_IRUGO | S_IWUSR,
+ smi130_show_reg_val, smi130_store_reg_val);
+static DEVICE_ATTR(driver_version, S_IRUGO,
+ smi130_driver_version_show, NULL);
+/* gyro part */
+static DEVICE_ATTR(gyro_op_mode, S_IRUGO | S_IWUSR,
+ smi130_gyro_op_mode_show, smi130_gyro_op_mode_store);
+static DEVICE_ATTR(gyro_value, S_IRUGO,
+ smi130_gyro_value_show, NULL);
+static DEVICE_ATTR(gyro_range, S_IRUGO | S_IWUSR,
+ smi130_gyro_range_show, smi130_gyro_range_store);
+static DEVICE_ATTR(gyro_odr, S_IRUGO | S_IWUSR,
+ smi130_gyro_odr_show, smi130_gyro_odr_store);
+static DEVICE_ATTR(gyro_fast_calibration_en, S_IRUGO | S_IWUSR,
+smi130_gyro_fast_calibration_en_show, smi130_gyro_fast_calibration_en_store);
+static DEVICE_ATTR(gyro_offset_x, S_IRUGO | S_IWUSR,
+smi130_gyro_offset_x_show, smi130_gyro_offset_x_store);
+static DEVICE_ATTR(gyro_offset_y, S_IRUGO | S_IWUSR,
+smi130_gyro_offset_y_show, smi130_gyro_offset_y_store);
+static DEVICE_ATTR(gyro_offset_z, S_IRUGO | S_IWUSR,
+smi130_gyro_offset_z_show, smi130_gyro_offset_z_store);
+
+#ifdef SMI130_MAG_INTERFACE_SUPPORT
+static DEVICE_ATTR(mag_op_mode, S_IRUGO | S_IWUSR,
+ smi130_mag_op_mode_show, smi130_mag_op_mode_store);
+static DEVICE_ATTR(mag_odr, S_IRUGO | S_IWUSR,
+ smi130_mag_odr_show, smi130_mag_odr_store);
+static DEVICE_ATTR(mag_i2c_addr, S_IRUGO | S_IWUSR,
+ smi130_mag_i2c_address_show, smi130_mag_i2c_address_store);
+static DEVICE_ATTR(mag_value, S_IRUGO,
+ smi130_mag_value_show, NULL);
+static DEVICE_ATTR(mag_offset, S_IRUGO | S_IWUSR,
+ smi130_mag_offset_show, smi130_mag_offset_store);
+static DEVICE_ATTR(mag_chip_id, S_IRUGO,
+ smi130_mag_chip_id_show, NULL);
+static DEVICE_ATTR(mag_chip_name, S_IRUGO,
+ smi130_mag_chip_name_show, NULL);
+static DEVICE_ATTR(mag_compensate, S_IRUGO | S_IWUSR,
+ smi130_mag_compensate_xyz_show,
+ smi130_mag_compensate_xyz_store);
+#endif
+
+
+#if defined(SMI130_ENABLE_INT1) || defined(SMI130_ENABLE_INT2)
+static DEVICE_ATTR(enable_int, S_IRUGO | S_IWUSR,
+ NULL, smi_enable_int_store);
+static DEVICE_ATTR(anymot_duration, S_IRUGO | S_IWUSR,
+ smi130_anymot_duration_show, smi130_anymot_duration_store);
+static DEVICE_ATTR(anymot_threshold, S_IRUGO | S_IWUSR,
+ smi130_anymot_threshold_show, smi130_anymot_threshold_store);
+static DEVICE_ATTR(std_stu, S_IRUGO,
+ smi130_step_detector_status_show, NULL);
+static DEVICE_ATTR(std_en, S_IRUGO | S_IWUSR,
+ smi130_step_detector_enable_show,
+ smi130_step_detector_enable_store);
+static DEVICE_ATTR(sig_en, S_IRUGO | S_IWUSR,
+ smi130_signification_motion_enable_show,
+ smi130_signification_motion_enable_store);
+
+#endif
+
+
+
+static DEVICE_ATTR(smi_value, S_IRUGO,
+ smi130_smi_value_show, NULL);
+
+
+static struct attribute *smi130_attributes[] = {
+ &dev_attr_chip_id.attr,
+ &dev_attr_err_st.attr,
+ &dev_attr_sensor_time.attr,
+ &dev_attr_selftest.attr,
+ &dev_attr_driver_version.attr,
+ &dev_attr_test.attr,
+ &dev_attr_fifo_flush.attr,
+ &dev_attr_fifo_header_en.attr,
+ &dev_attr_fifo_time_en.attr,
+ &dev_attr_fifo_int_tag_en.attr,
+ &dev_attr_fifo_bytecount.attr,
+ &dev_attr_fifo_data_sel.attr,
+ &dev_attr_fifo_data_frame.attr,
+
+ &dev_attr_fifo_watermark.attr,
+
+ &dev_attr_enable.attr,
+ &dev_attr_delay.attr,
+ &dev_attr_temperature.attr,
+ &dev_attr_place.attr,
+
+ &dev_attr_acc_range.attr,
+ &dev_attr_acc_odr.attr,
+ &dev_attr_acc_op_mode.attr,
+ &dev_attr_acc_value.attr,
+
+ &dev_attr_acc_fast_calibration_x.attr,
+ &dev_attr_acc_fast_calibration_y.attr,
+ &dev_attr_acc_fast_calibration_z.attr,
+ &dev_attr_acc_offset_x.attr,
+ &dev_attr_acc_offset_y.attr,
+ &dev_attr_acc_offset_z.attr,
+
+ &dev_attr_stc_enable.attr,
+ &dev_attr_stc_mode.attr,
+ &dev_attr_stc_clc.attr,
+ &dev_attr_stc_value.attr,
+
+ &dev_attr_gyro_op_mode.attr,
+ &dev_attr_gyro_value.attr,
+ &dev_attr_gyro_range.attr,
+ &dev_attr_gyro_odr.attr,
+ &dev_attr_gyro_fast_calibration_en.attr,
+ &dev_attr_gyro_offset_x.attr,
+ &dev_attr_gyro_offset_y.attr,
+ &dev_attr_gyro_offset_z.attr,
+
+#ifdef SMI130_MAG_INTERFACE_SUPPORT
+ &dev_attr_mag_chip_id.attr,
+ &dev_attr_mag_op_mode.attr,
+ &dev_attr_mag_odr.attr,
+ &dev_attr_mag_i2c_addr.attr,
+ &dev_attr_mag_chip_name.attr,
+ &dev_attr_mag_value.attr,
+ &dev_attr_mag_offset.attr,
+ &dev_attr_mag_compensate.attr,
+#endif
+
+#if defined(SMI130_ENABLE_INT1) || defined(SMI130_ENABLE_INT2)
+ &dev_attr_enable_int.attr,
+
+ &dev_attr_anymot_duration.attr,
+ &dev_attr_anymot_threshold.attr,
+ &dev_attr_std_stu.attr,
+ &dev_attr_std_en.attr,
+ &dev_attr_sig_en.attr,
+
+#endif
+ &dev_attr_reg_sel.attr,
+ &dev_attr_reg_val.attr,
+ &dev_attr_smi_value.attr,
+ NULL
+};
+
+static struct attribute_group smi130_attribute_group = {
+ .attrs = smi130_attributes
+};
+
+#if defined(SMI130_ENABLE_INT1) || defined(SMI130_ENABLE_INT2)
+static void smi_slope_interrupt_handle(struct smi_client_data *client_data)
+{
+ /* anym_first[0..2]: x, y, z */
+ u8 anym_first[3] = {0};
+ u8 status2;
+ u8 anym_sign;
+ u8 i = 0;
+
+ client_data->device.bus_read(client_data->device.dev_addr,
+ SMI130_USER_INTR_STAT_2_ADDR, &status2, 1);
+ anym_first[0] = SMI130_GET_BITSLICE(status2,
+ SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_X);
+ anym_first[1] = SMI130_GET_BITSLICE(status2,
+ SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_Y);
+ anym_first[2] = SMI130_GET_BITSLICE(status2,
+ SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_Z);
+ anym_sign = SMI130_GET_BITSLICE(status2,
+ SMI130_USER_INTR_STAT_2_ANY_MOTION_SIGN);
+
+ for (i = 0; i < 3; i++) {
+ if (anym_first[i]) {
+ /*1: negative*/
+ if (anym_sign)
+ dev_notice(client_data->dev,
+ "Anymotion interrupt happend!"
+ "%s axis, negative sign\n", smi_axis_name[i]);
+ else
+ dev_notice(client_data->dev,
+ "Anymotion interrupt happend!"
+ "%s axis, postive sign\n", smi_axis_name[i]);
+ }
+ }
+
+
+}
+
+static void smi_fifo_watermark_interrupt_handle
+ (struct smi_client_data *client_data)
+{
+ int err = 0;
+ unsigned int fifo_len0 = 0;
+ unsigned int fifo_frmbytes_ext = 0;
+ unsigned char *fifo_data = NULL;
+ fifo_data = kzalloc(FIFO_DATA_BUFSIZE, GFP_KERNEL);
+ /*TO DO*/
+ if (NULL == fifo_data) {
+ dev_err(client_data->dev, "no memory available");
+ err = -ENOMEM;
+ }
+ smi_fifo_frame_bytes_extend_calc(client_data, &fifo_frmbytes_ext);
+
+ if (client_data->pw.acc_pm == 2 && client_data->pw.gyro_pm == 2
+ && client_data->pw.mag_pm == 2)
+ printk(KERN_INFO "pw_acc: %d, pw_gyro: %d\n",
+ client_data->pw.acc_pm, client_data->pw.gyro_pm);
+ if (!client_data->fifo_data_sel)
+ printk(KERN_INFO "no selsect sensor fifo, fifo_data_sel:%d\n",
+ client_data->fifo_data_sel);
+
+ err = SMI_CALL_API(fifo_length)(&fifo_len0);
+ client_data->fifo_bytecount = fifo_len0;
+
+ if (client_data->fifo_bytecount == 0 || err)
+ return;
+
+ if (client_data->fifo_bytecount + fifo_frmbytes_ext > FIFO_DATA_BUFSIZE)
+ client_data->fifo_bytecount = FIFO_DATA_BUFSIZE;
+ /* need give attention for the time of burst read*/
+ if (!err) {
+ err = smi_burst_read_wrapper(client_data->device.dev_addr,
+ SMI130_USER_FIFO_DATA__REG, fifo_data,
+ client_data->fifo_bytecount + fifo_frmbytes_ext);
+ } else
+ dev_err(client_data->dev, "read fifo leght err");
+
+ if (err)
+ dev_err(client_data->dev, "brust read fifo err\n");
+ /*err = smi_fifo_analysis_handle(client_data, fifo_data,
+ client_data->fifo_bytecount + 20, fifo_out_data);*/
+ if (fifo_data != NULL) {
+ kfree(fifo_data);
+ fifo_data = NULL;
+ }
+
+}
+static void smi_data_ready_interrupt_handle(
+ struct smi_client_data *client_data, uint8_t status)
+{
+ uint8_t data12[12] = {0};
+ struct smi130_accel_t accel;
+ struct smi130_gyro_t gyro;
+ struct timespec ts;
+ client_data->device.bus_read(client_data->device.dev_addr,
+ SMI130_USER_DATA_8_ADDR, data12, 12);
+ if (status & 0x80)
+ {
+ /*report acc data*/
+ /* Data X */
+ accel.x = (s16)((((s32)((s8)data12[7])) << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) | (data12[6]));
+ /* Data Y */
+ accel.y = (s16)((((s32)((s8)data12[9])) << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) | (data12[8]));
+ /* Data Z */
+ accel.z = (s16)((((s32)((s8)data12[11]))<< SMI130_SHIFT_BIT_POSITION_BY_08_BITS) | (data12[10]));
+ ts = ns_to_timespec(client_data->timestamp);
+ input_event(client_data->input, EV_MSC, 6, ts.tv_sec);
+ input_event(client_data->input, EV_MSC, 6, ts.tv_nsec);
+ input_event(client_data->input, EV_MSC, MSC_GESTURE, accel.x);
+ input_event(client_data->input, EV_MSC, MSC_RAW, accel.y);
+ input_event(client_data->input, EV_MSC, MSC_SCAN, accel.z);
+ input_sync(client_data->input);
+ }
+ if (status & 0x40)
+ {
+ /*report gyro data*/
+ /* Data X */
+ gyro.x = (s16)((((s32)((s8)data12[1])) << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) | (data12[0]));
+ /* Data Y */
+ gyro.y = (s16)((((s32)((s8)data12[3])) << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) | (data12[2]));
+ /* Data Z */
+ gyro.z = (s16)((((s32)((s8)data12[5]))<< SMI130_SHIFT_BIT_POSITION_BY_08_BITS) | (data12[4]));
+ ts = ns_to_timespec(client_data->timestamp);
+ input_event(client_data->gyro_input, EV_MSC, 6, ts.tv_sec);
+ input_event(client_data->gyro_input, EV_MSC, 6, ts.tv_nsec);
+ input_event(client_data->gyro_input, EV_MSC, MSC_GESTURE, gyro.x);
+ input_event(client_data->gyro_input, EV_MSC, MSC_RAW, gyro.y);
+ input_event(client_data->gyro_input, EV_MSC, MSC_SCAN, gyro.z);
+ input_sync(client_data->gyro_input);
+ }
+}
+
+static void smi_signification_motion_interrupt_handle(
+ struct smi_client_data *client_data)
+{
+ printk(KERN_INFO "smi_signification_motion_interrupt_handle\n");
+ input_event(client_data->input, EV_MSC, INPUT_EVENT_SGM, 1);
+/*input_report_rel(client_data->input,INPUT_EVENT_SGM,1);*/
+ input_sync(client_data->input);
+ smi130_set_command_register(CMD_RESET_INT_ENGINE);
+
+}
+static void smi_stepdetector_interrupt_handle(
+ struct smi_client_data *client_data)
+{
+ u8 current_step_dector_st = 0;
+ client_data->pedo_data.wkar_step_detector_status++;
+ current_step_dector_st =
+ client_data->pedo_data.wkar_step_detector_status;
+ client_data->std = ((current_step_dector_st == 1) ? 0 : 1);
+
+ input_event(client_data->input, EV_MSC, INPUT_EVENT_STEP_DETECTOR, 1);
+ input_sync(client_data->input);
+}
+
+static void smi_irq_work_func(struct work_struct *work)
+{
+ struct smi_client_data *client_data =
+ container_of((struct work_struct *)work,
+ struct smi_client_data, irq_work);
+
+ unsigned char int_status[4] = {0, 0, 0, 0};
+ uint8_t status = 0;
+
+ //client_data->device.bus_read(client_data->device.dev_addr,
+ // SMI130_USER_INTR_STAT_0_ADDR, int_status, 4);
+ client_data->device.bus_read(client_data->device.dev_addr,
+ SMI130_USER_STAT_ADDR, &status, 1);
+ printk("status = 0x%x", status);
+ if (SMI130_GET_BITSLICE(int_status[0],
+ SMI130_USER_INTR_STAT_0_ANY_MOTION))
+ smi_slope_interrupt_handle(client_data);
+
+ if (SMI130_GET_BITSLICE(int_status[0],
+ SMI130_USER_INTR_STAT_0_STEP_INTR))
+ smi_stepdetector_interrupt_handle(client_data);
+ if (SMI130_GET_BITSLICE(int_status[1],
+ SMI130_USER_INTR_STAT_1_FIFO_WM_INTR))
+ smi_fifo_watermark_interrupt_handle(client_data);
+ if ((status & 0x80) || (status & 0x40))
+ smi_data_ready_interrupt_handle(client_data, status);
+ /* Clear ALL inputerrupt status after handler sig mition*/
+ /* Put this commads intot the last one*/
+ if (SMI130_GET_BITSLICE(int_status[0],
+ SMI130_USER_INTR_STAT_0_SIGNIFICANT_INTR))
+ smi_signification_motion_interrupt_handle(client_data);
+
+}
+
+static void smi130_delay_sigmo_work_func(struct work_struct *work)
+{
+ struct smi_client_data *client_data =
+ container_of(work, struct smi_client_data,
+ delay_work_sig.work);
+ unsigned char int_status[4] = {0, 0, 0, 0};
+
+ client_data->device.bus_read(client_data->device.dev_addr,
+ SMI130_USER_INTR_STAT_0_ADDR, int_status, 4);
+ if (SMI130_GET_BITSLICE(int_status[0],
+ SMI130_USER_INTR_STAT_0_SIGNIFICANT_INTR))
+ smi_signification_motion_interrupt_handle(client_data);
+}
+
+static irqreturn_t smi_irq_handler(int irq, void *handle)
+{
+ struct smi_client_data *client_data = handle;
+ int in_suspend_copy;
+ in_suspend_copy = atomic_read(&client_data->in_suspend);
+
+ if (client_data == NULL)
+ return IRQ_HANDLED;
+ if (client_data->dev == NULL)
+ return IRQ_HANDLED;
+ /*this only deal with SIG_motion CTS test*/
+ if ((in_suspend_copy == 1) &&
+ (client_data->sig_flag == 1)) {
+ /*wake_lock_timeout(&client_data->wakelock, HZ);*/
+ schedule_delayed_work(&client_data->delay_work_sig,
+ msecs_to_jiffies(50));
+ }
+ schedule_work(&client_data->irq_work);
+
+ return IRQ_HANDLED;
+}
+#endif /* defined(SMI_ENABLE_INT1)||defined(SMI_ENABLE_INT2) */
+
+static int smi_restore_hw_cfg(struct smi_client_data *client)
+{
+ int err = 0;
+
+ if ((client->fifo_data_sel) & (1 << SMI_ACC_SENSOR)) {
+ err += SMI_CALL_API(set_accel_range)(client->range.acc_range);
+ err += SMI_CALL_API(set_accel_output_data_rate)
+ (client->odr.acc_odr);
+ err += SMI_CALL_API(set_fifo_accel_enable)(1);
+ }
+ if ((client->fifo_data_sel) & (1 << SMI_GYRO_SENSOR)) {
+ err += SMI_CALL_API(set_gyro_range)(client->range.gyro_range);
+ err += SMI_CALL_API(set_gyro_output_data_rate)
+ (client->odr.gyro_odr);
+ err += SMI_CALL_API(set_fifo_gyro_enable)(1);
+ }
+ if ((client->fifo_data_sel) & (1 << SMI_MAG_SENSOR)) {
+ err += SMI_CALL_API(set_mag_output_data_rate)
+ (client->odr.mag_odr);
+ err += SMI_CALL_API(set_fifo_mag_enable)(1);
+ }
+ err += SMI_CALL_API(set_command_register)(CMD_CLR_FIFO_DATA);
+
+ mutex_lock(&client->mutex_op_mode);
+ if (client->pw.acc_pm != SMI_ACC_PM_SUSPEND) {
+ err += SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_acc_arr[SMI_ACC_PM_NORMAL]);
+ smi_delay(3);
+ }
+ mutex_unlock(&client->mutex_op_mode);
+
+ mutex_lock(&client->mutex_op_mode);
+ if (client->pw.gyro_pm != SMI_GYRO_PM_SUSPEND) {
+ err += SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_gyro_arr[SMI_GYRO_PM_NORMAL]);
+ smi_delay(3);
+ }
+ mutex_unlock(&client->mutex_op_mode);
+
+ mutex_lock(&client->mutex_op_mode);
+
+ if (client->pw.mag_pm != SMI_MAG_PM_SUSPEND) {
+#ifdef SMI130_AKM09912_SUPPORT
+ err += smi130_set_bosch_akm_and_secondary_if_powermode
+ (SMI130_MAG_FORCE_MODE);
+#else
+ err += smi130_set_bmm150_mag_and_secondary_if_power_mode
+ (SMI130_MAG_FORCE_MODE);
+#endif
+ smi_delay(3);
+ }
+ mutex_unlock(&client->mutex_op_mode);
+
+ return err;
+}
+
+#if defined(CONFIG_USE_QUALCOMM_HAL)
+static void smi130_accel_work_fn(struct work_struct *work)
+{
+ struct smi_client_data *sensor;
+ ktime_t timestamp;
+ struct smi130_accel_t data;
+ int err;
+ sensor = container_of((struct delayed_work *)work,
+ struct smi_client_data, accel_poll_work);
+ timestamp = ktime_get();
+ err = SMI_CALL_API(read_accel_xyz)(&data);
+ if (err)
+ dev_err(sensor->dev, "read data err");
+ input_report_abs(sensor->input, ABS_X,
+ (data.x));
+ input_report_abs(sensor->input, ABS_Y,
+ (data.y));
+ input_report_abs(sensor->input, ABS_Z,
+ (data.z));
+ input_event(sensor->input,
+ EV_SYN, SYN_TIME_SEC,
+ ktime_to_timespec(timestamp).tv_sec);
+ input_event(sensor->input, EV_SYN,
+ SYN_TIME_NSEC,
+ ktime_to_timespec(timestamp).tv_nsec);
+ input_sync(sensor->input);
+ if (atomic_read(&sensor->accel_en))
+ queue_delayed_work(sensor->data_wq,
+ &sensor->accel_poll_work,
+ msecs_to_jiffies(sensor->accel_poll_ms));
+}
+static void smi130_gyro_work_fn(struct work_struct *work)
+{
+ struct smi_client_data *sensor;
+ ktime_t timestamp;
+ struct smi130_gyro_t data;
+ int err;
+ sensor = container_of((struct delayed_work *)work,
+ struct smi_client_data, gyro_poll_work);
+ timestamp = ktime_get();
+ err = SMI_CALL_API(read_gyro_xyz)(&data);
+ if (err)
+ dev_err(sensor->dev, "read data err");
+ input_report_abs(sensor->gyro_input, ABS_RX,
+ (data.x));
+ input_report_abs(sensor->gyro_input, ABS_RY,
+ (data.y));
+ input_report_abs(sensor->gyro_input, ABS_RZ,
+ (data.z));
+ input_event(sensor->gyro_input,
+ EV_SYN, SYN_TIME_SEC,
+ ktime_to_timespec(timestamp).tv_sec);
+ input_event(sensor->gyro_input, EV_SYN,
+ SYN_TIME_NSEC,
+ ktime_to_timespec(timestamp).tv_nsec);
+ input_sync(sensor->gyro_input);
+ if (atomic_read(&sensor->gyro_en))
+ queue_delayed_work(sensor->data_wq,
+ &sensor->gyro_poll_work,
+ msecs_to_jiffies(sensor->gyro_poll_ms));
+}
+static int smi130_set_gyro_op_mode(struct smi_client_data *client_data,
+ unsigned long op_mode)
+{
+ int err = 0;
+ mutex_lock(&client_data->mutex_op_mode);
+ if (op_mode < SMI_GYRO_PM_MAX) {
+ switch (op_mode) {
+ case SMI_GYRO_PM_NORMAL:
+ err = SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_gyro_arr[SMI_GYRO_PM_NORMAL]);
+ client_data->pw.gyro_pm = SMI_GYRO_PM_NORMAL;
+ smi_delay(60);
+ break;
+ case SMI_GYRO_PM_FAST_START:
+ err = SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_gyro_arr[SMI_GYRO_PM_FAST_START]);
+ client_data->pw.gyro_pm = SMI_GYRO_PM_FAST_START;
+ smi_delay(60);
+ break;
+ case SMI_GYRO_PM_SUSPEND:
+ err = SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_gyro_arr[SMI_GYRO_PM_SUSPEND]);
+ client_data->pw.gyro_pm = SMI_GYRO_PM_SUSPEND;
+ smi_delay(60);
+ break;
+ default:
+ mutex_unlock(&client_data->mutex_op_mode);
+ return -EINVAL;
+ }
+ } else {
+ mutex_unlock(&client_data->mutex_op_mode);
+ return -EINVAL;
+ }
+ mutex_unlock(&client_data->mutex_op_mode);
+ return err;
+}
+static int smi130_accel_set_enable(
+ struct smi_client_data *client_data, bool enable)
+{
+ int ret = 0;
+ dev_notice(client_data->dev,
+ "smi130_accel_set_enable enable=%d\n", enable);
+ if (enable) {
+ ret = smi130_set_acc_op_mode(client_data, 0);
+ if (ret) {
+ dev_err(client_data->dev,
+ "Fail to enable accel engine ret=%d\n", ret);
+ ret = -EBUSY;
+ goto exit;
+ }
+ queue_delayed_work(client_data->data_wq,
+ &client_data->accel_poll_work,
+ msecs_to_jiffies(client_data->accel_poll_ms));
+ atomic_set(&client_data->accel_en, 1);
+ } else {
+ atomic_set(&client_data->accel_en, 0);
+ cancel_delayed_work_sync(&client_data->accel_poll_work);
+ ret = smi130_set_acc_op_mode(client_data, 2);
+ if (ret) {
+ dev_err(client_data->dev,
+ "Fail to disable accel engine ret=%d\n", ret);
+ ret = -EBUSY;
+ goto exit;
+ }
+ }
+exit:
+ return ret;
+}
+static int smi130_accel_set_poll_delay(struct smi_client_data *client_data,
+ unsigned long delay)
+{
+ dev_info(client_data->dev,
+ "smi130_accel_set_poll_delay delay_ms=%ld\n", delay);
+ if (delay < SMI130_ACCEL_MIN_POLL_INTERVAL_MS)
+ delay = SMI130_ACCEL_MIN_POLL_INTERVAL_MS;
+ if (delay > SMI130_ACCEL_MAX_POLL_INTERVAL_MS)
+ delay = SMI130_ACCEL_MAX_POLL_INTERVAL_MS;
+ client_data->accel_poll_ms = delay;
+ if (!atomic_read(&client_data->accel_en))
+ goto exit;
+ cancel_delayed_work_sync(&client_data->accel_poll_work);
+ queue_delayed_work(client_data->data_wq,
+ &client_data->accel_poll_work,
+ msecs_to_jiffies(client_data->accel_poll_ms));
+exit:
+ return 0;
+}
+static int smi130_gyro_set_enable(
+ struct smi_client_data *client_data, bool enable)
+{
+ int ret = 0;
+ dev_notice(client_data->dev,
+ "smi130_gyro_set_enable enable=%d\n", enable);
+ if (enable) {
+ ret = smi130_set_gyro_op_mode(client_data, 0);
+ if (ret) {
+ dev_err(client_data->dev,
+ "Fail to enable gyro engine ret=%d\n", ret);
+ ret = -EBUSY;
+ goto exit;
+ }
+ queue_delayed_work(client_data->data_wq,
+ &client_data->gyro_poll_work,
+ msecs_to_jiffies(client_data->gyro_poll_ms));
+ atomic_set(&client_data->gyro_en, 1);
+ } else {
+ atomic_set(&client_data->gyro_en, 0);
+ cancel_delayed_work_sync(&client_data->gyro_poll_work);
+ ret = smi130_set_gyro_op_mode(client_data, 2);
+ if (ret) {
+ dev_err(client_data->dev,
+ "Fail to disable accel engine ret=%d\n", ret);
+ ret = -EBUSY;
+ goto exit;
+ }
+ }
+exit:
+ return ret;
+}
+static int smi130_gyro_set_poll_delay(struct smi_client_data *client_data,
+ unsigned long delay)
+{
+ dev_info(client_data->dev,
+ "smi130_accel_set_poll_delay delay_ms=%ld\n", delay);
+ if (delay < SMI130_GYRO_MIN_POLL_INTERVAL_MS)
+ delay = SMI130_GYRO_MIN_POLL_INTERVAL_MS;
+ if (delay > SMI130_GYRO_MAX_POLL_INTERVAL_MS)
+ delay = SMI130_GYRO_MAX_POLL_INTERVAL_MS;
+ client_data->gyro_poll_ms = delay;
+ if (!atomic_read(&client_data->gyro_en))
+ goto exit;
+ cancel_delayed_work_sync(&client_data->gyro_poll_work);
+ queue_delayed_work(client_data->data_wq,
+ &client_data->gyro_poll_work,
+ msecs_to_jiffies(client_data->gyro_poll_ms));
+exit:
+ return 0;
+}
+static int smi130_accel_cdev_enable(struct sensors_classdev *sensors_cdev,
+ unsigned int enable)
+{
+ struct smi_client_data *sensor = container_of(sensors_cdev,
+ struct smi_client_data, accel_cdev);
+ return smi130_accel_set_enable(sensor, enable);
+}
+static int smi130_accel_cdev_poll_delay(struct sensors_classdev *sensors_cdev,
+ unsigned int delay_ms)
+{
+ struct smi_client_data *sensor = container_of(sensors_cdev,
+ struct smi_client_data, accel_cdev);
+
+ return smi130_accel_set_poll_delay(sensor, delay_ms);
+}
+
+static int smi130_gyro_cdev_enable(struct sensors_classdev *sensors_cdev,
+ unsigned int enable)
+{
+ struct smi_client_data *sensor = container_of(sensors_cdev,
+ struct smi_client_data, gyro_cdev);
+
+ return smi130_gyro_set_enable(sensor, enable);
+}
+
+static int smi130_gyro_cdev_poll_delay(struct sensors_classdev *sensors_cdev,
+ unsigned int delay_ms)
+{
+ struct smi_client_data *sensor = container_of(sensors_cdev,
+ struct smi_client_data, gyro_cdev);
+
+ return smi130_gyro_set_poll_delay(sensor, delay_ms);
+}
+#endif
+
+int smi_probe(struct smi_client_data *client_data, struct device *dev)
+{
+ int err = 0;
+#ifdef SMI130_MAG_INTERFACE_SUPPORT
+ u8 mag_dev_addr;
+ u8 mag_urst_len;
+ u8 mag_op_mode;
+#endif
+ /* check chip id */
+ err = smi_check_chip_id(client_data);
+ if (err)
+ goto exit_err_clean;
+
+ dev_set_drvdata(dev, client_data);
+ client_data->dev = dev;
+
+ mutex_init(&client_data->mutex_enable);
+ mutex_init(&client_data->mutex_op_mode);
+
+ /* input device init */
+ err = smi_input_init(client_data);
+ if (err < 0)
+ goto exit_err_clean;
+
+ /* sysfs node creation */
+ err = sysfs_create_group(&client_data->input->dev.kobj,
+ &smi130_attribute_group);
+
+ if (err < 0)
+ goto exit_err_sysfs;
+
+ if (NULL != dev->platform_data) {
+ client_data->bosch_pd = kzalloc(sizeof(*client_data->bosch_pd),
+ GFP_KERNEL);
+
+ if (NULL != client_data->bosch_pd) {
+ memcpy(client_data->bosch_pd, dev->platform_data,
+ sizeof(*client_data->bosch_pd));
+ dev_notice(dev, "%s sensor driver set place: p%d\n",
+ client_data->bosch_pd->name,
+ client_data->bosch_pd->place);
+ }
+ }
+
+ if (NULL != client_data->bosch_pd) {
+ memcpy(client_data->bosch_pd, dev->platform_data,
+ sizeof(*client_data->bosch_pd));
+ dev_notice(dev, "%s sensor driver set place: p%d\n",
+ client_data->bosch_pd->name,
+ client_data->bosch_pd->place);
+ }
+
+
+ /* workqueue init */
+ INIT_DELAYED_WORK(&client_data->work, smi_work_func);
+ atomic_set(&client_data->delay, SMI_DELAY_DEFAULT);
+ atomic_set(&client_data->wkqueue_en, 0);
+
+ /* h/w init */
+ client_data->device.delay_msec = smi_delay;
+ err = SMI_CALL_API(init)(&client_data->device);
+
+ smi_dump_reg(client_data);
+
+ /*power on detected*/
+ /*or softrest(cmd 0xB6) */
+ /*fatal err check*/
+ /*soft reset*/
+ err += SMI_CALL_API(set_command_register)(CMD_RESET_USER_REG);
+ smi_delay(3);
+ if (err)
+ dev_err(dev, "Failed soft reset, er=%d", err);
+ /*usr data config page*/
+ err += SMI_CALL_API(set_target_page)(USER_DAT_CFG_PAGE);
+ if (err)
+ dev_err(dev, "Failed cffg page, er=%d", err);
+ err += smi_get_err_status(client_data);
+ if (err) {
+ dev_err(dev, "Failed to smi16x init!err_st=0x%x\n",
+ client_data->err_st.err_st_all);
+ goto exit_err_sysfs;
+ }
+
+#ifdef SMI130_MAG_INTERFACE_SUPPORT
+ err += smi130_set_command_register(MAG_MODE_NORMAL);
+ smi_delay(2);
+ err += smi130_get_mag_power_mode_stat(&mag_op_mode);
+ smi_delay(2);
+ err += SMI_CALL_API(get_i2c_device_addr)(&mag_dev_addr);
+ smi_delay(2);
+#if defined(SMI130_AKM09912_SUPPORT)
+ err += SMI_CALL_API(set_i2c_device_addr)(SMI130_AKM09912_I2C_ADDRESS);
+ smi130_bosch_akm_mag_interface_init(SMI130_AKM09912_I2C_ADDRESS);
+#else
+ err += SMI_CALL_API(set_i2c_device_addr)(
+ SMI130_AUX_BMM150_I2C_ADDRESS);
+ smi130_bmm150_mag_interface_init();
+#endif
+
+ err += smi130_set_mag_burst(3);
+ err += smi130_get_mag_burst(&mag_urst_len);
+ if (err)
+ dev_err(client_data->dev, "Failed cffg mag, er=%d", err);
+ dev_info(client_data->dev,
+ "SMI130 mag_urst_len:%d, mag_add:0x%x, mag_op_mode:%d\n",
+ mag_urst_len, mag_dev_addr, mag_op_mode);
+#endif
+ if (err < 0)
+ goto exit_err_sysfs;
+
+
+#if defined(SMI130_ENABLE_INT1) || defined(SMI130_ENABLE_INT2)
+ /*wake_lock_init(&client_data->wakelock,
+ WAKE_LOCK_SUSPEND, "smi130");*/
+ client_data->gpio_pin = of_get_named_gpio_flags(dev->of_node,
+ "smi,gpio_irq", 0, NULL);
+ dev_info(client_data->dev, "SMI130 qpio number:%d\n",
+ client_data->gpio_pin);
+ err += gpio_request_one(client_data->gpio_pin,
+ GPIOF_IN, "smi130_int");
+ err += gpio_direction_input(client_data->gpio_pin);
+ client_data->IRQ = gpio_to_irq(client_data->gpio_pin);
+ if (err) {
+ dev_err(client_data->dev,
+ "can not request gpio to irq number\n");
+ client_data->gpio_pin = 0;
+ }
+ INIT_DELAYED_WORK(&client_data->delay_work_sig,
+ smi130_delay_sigmo_work_func);
+#ifdef SMI130_ENABLE_INT1
+ /* maps interrupt to INT1/InT2 pin */
+ SMI_CALL_API(set_intr_any_motion)(SMI_INT0, ENABLE);
+ SMI_CALL_API(set_intr_fifo_wm)(SMI_INT0, ENABLE);
+ SMI_CALL_API(set_intr_data_rdy)(SMI_INT0, ENABLE);
+
+ /*Set interrupt trige level way */
+ SMI_CALL_API(set_intr_edge_ctrl)(SMI_INT0, SMI_INT_LEVEL);
+ smi130_set_intr_level(SMI_INT0, 1);
+ /*set interrupt latch temporary, 5 ms*/
+ /*smi130_set_latch_int(5);*/
+
+ SMI_CALL_API(set_output_enable)(
+ SMI130_INTR1_OUTPUT_ENABLE, ENABLE);
+ sigmotion_init_interrupts(SMI130_MAP_INTR1);
+ SMI_CALL_API(map_step_detector_intr)(SMI130_MAP_INTR1);
+ /*close step_detector in init function*/
+ SMI_CALL_API(set_step_detector_enable)(0);
+#endif
+
+#ifdef SMI130_ENABLE_INT2
+ /* maps interrupt to INT1/InT2 pin */
+ SMI_CALL_API(set_intr_any_motion)(SMI_INT1, ENABLE);
+ SMI_CALL_API(set_intr_fifo_wm)(SMI_INT1, ENABLE);
+ SMI_CALL_API(set_intr_data_rdy)(SMI_INT1, ENABLE);
+
+ /*Set interrupt trige level way */
+ SMI_CALL_API(set_intr_edge_ctrl)(SMI_INT1, SMI_INT_LEVEL);
+ smi130_set_intr_level(SMI_INT1, 1);
+ /*set interrupt latch temporary, 5 ms*/
+ /*smi130_set_latch_int(5);*/
+
+ SMI_CALL_API(set_output_enable)(
+ SMI130_INTR2_OUTPUT_ENABLE, ENABLE);
+ sigmotion_init_interrupts(SMI130_MAP_INTR2);
+ SMI_CALL_API(map_step_detector_intr)(SMI130_MAP_INTR2);
+ /*close step_detector in init function*/
+ SMI_CALL_API(set_step_detector_enable)(0);
+#endif
+ err = request_irq(client_data->IRQ, smi_irq_handler,
+ IRQF_TRIGGER_RISING, "smi130", client_data);
+ if (err)
+ dev_err(client_data->dev, "could not request irq\n");
+
+ INIT_WORK(&client_data->irq_work, smi_irq_work_func);
+#endif
+
+ client_data->selftest = 0;
+
+ client_data->fifo_data_sel = 0;
+ #if defined(CONFIG_USE_QUALCOMM_HAL)
+ SMI_CALL_API(set_accel_output_data_rate)(9);/*defalut odr 200HZ*/
+ SMI_CALL_API(set_gyro_output_data_rate)(9);/*defalut odr 200HZ*/
+ #endif
+ SMI_CALL_API(get_accel_output_data_rate)(&client_data->odr.acc_odr);
+ SMI_CALL_API(get_gyro_output_data_rate)(&client_data->odr.gyro_odr);
+ SMI_CALL_API(get_mag_output_data_rate)(&client_data->odr.mag_odr);
+ SMI_CALL_API(set_fifo_time_enable)(1);
+ SMI_CALL_API(get_accel_range)(&client_data->range.acc_range);
+ SMI_CALL_API(get_gyro_range)(&client_data->range.gyro_range);
+ /* now it's power on which is considered as resuming from suspend */
+
+ /* gyro input device init */
+ err = smi_gyro_input_init(client_data);
+ #if defined(CONFIG_USE_QUALCOMM_HAL)
+ /* gyro input device init */
+ err = smi_gyro_input_init(client_data);
+ if (err < 0)
+ goto exit_err_clean;
+ client_data->accel_poll_ms = SMI130_ACCEL_DEFAULT_POLL_INTERVAL_MS;
+ client_data->gyro_poll_ms = SMI130_GYRO_DEFAULT_POLL_INTERVAL_MS;
+ client_data->data_wq = create_freezable_workqueue("smi130_data_work");
+ if (!client_data->data_wq) {
+ dev_err(dev, "Cannot create workqueue!\n");
+ goto exit_err_clean;
+ }
+ INIT_DELAYED_WORK(&client_data->accel_poll_work,
+ smi130_accel_work_fn);
+ client_data->accel_cdev = smi130_accel_cdev;
+ client_data->accel_cdev.delay_msec = client_data->accel_poll_ms;
+ client_data->accel_cdev.sensors_enable = smi130_accel_cdev_enable;
+ client_data->accel_cdev.sensors_poll_delay =
+ smi130_accel_cdev_poll_delay;
+ err = sensors_classdev_register(dev, &client_data->accel_cdev);
+ if (err) {
+ dev_err(dev,
+ "create accel class device file failed!\n");
+ goto exit_err_clean;
+ }
+ INIT_DELAYED_WORK(&client_data->gyro_poll_work, smi130_gyro_work_fn);
+ client_data->gyro_cdev = smi130_gyro_cdev;
+ client_data->gyro_cdev.delay_msec = client_data->gyro_poll_ms;
+ client_data->gyro_cdev.sensors_enable = smi130_gyro_cdev_enable;
+ client_data->gyro_cdev.sensors_poll_delay = smi130_gyro_cdev_poll_delay;
+ err = sensors_classdev_register(dev, &client_data->gyro_cdev);
+ if (err) {
+ dev_err(dev,
+ "create accel class device file failed!\n");
+ goto exit_err_clean;
+ }
+ #endif
+ /* set sensor PMU into suspend power mode for all */
+ if (smi_pmu_set_suspend(client_data) < 0) {
+ dev_err(dev, "Failed to set SMI130 to suspend power mode\n");
+ goto exit_err_sysfs;
+ }
+ /*enable the data ready interrupt*/
+ SMI_CALL_API(set_intr_enable_1)(SMI130_DATA_RDY_ENABLE, 1);
+ dev_notice(dev, "sensor_time:%d, %d, %d",
+ sensortime_duration_tbl[0].ts_delat,
+ sensortime_duration_tbl[0].ts_duration_lsb,
+ sensortime_duration_tbl[0].ts_duration_us);
+ dev_notice(dev, "sensor %s probed successfully", SENSOR_NAME);
+
+ return 0;
+
+exit_err_sysfs:
+ if (err)
+ smi_input_destroy(client_data);
+
+exit_err_clean:
+ if (err) {
+ if (client_data != NULL) {
+ if (NULL != client_data->bosch_pd) {
+ kfree(client_data->bosch_pd);
+ client_data->bosch_pd = NULL;
+ }
+ }
+ }
+ return err;
+}
+EXPORT_SYMBOL(smi_probe);
+
+/*!
+ * @brief remove smi client
+ *
+ * @param dev the pointer of device
+ *
+ * @return zero
+ * @retval zero
+*/
+int smi_remove(struct device *dev)
+{
+ int err = 0;
+ struct smi_client_data *client_data = dev_get_drvdata(dev);
+
+ if (NULL != client_data) {
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ unregister_early_suspend(&client_data->early_suspend_handler);
+#endif
+ mutex_lock(&client_data->mutex_enable);
+ if (SMI_ACC_PM_NORMAL == client_data->pw.acc_pm ||
+ SMI_GYRO_PM_NORMAL == client_data->pw.gyro_pm ||
+ SMI_MAG_PM_NORMAL == client_data->pw.mag_pm) {
+ cancel_delayed_work_sync(&client_data->work);
+ }
+ mutex_unlock(&client_data->mutex_enable);
+
+ err = smi_pmu_set_suspend(client_data);
+
+ smi_delay(5);
+
+ sysfs_remove_group(&client_data->input->dev.kobj,
+ &smi130_attribute_group);
+ smi_input_destroy(client_data);
+
+ if (NULL != client_data->bosch_pd) {
+ kfree(client_data->bosch_pd);
+ client_data->bosch_pd = NULL;
+ }
+ kfree(client_data);
+ }
+
+ return err;
+}
+EXPORT_SYMBOL(smi_remove);
+
+static int smi_post_resume(struct smi_client_data *client_data)
+{
+ int err = 0;
+
+ mutex_lock(&client_data->mutex_enable);
+
+ if (atomic_read(&client_data->wkqueue_en) == 1) {
+ smi130_set_acc_op_mode(client_data, SMI_ACC_PM_NORMAL);
+ schedule_delayed_work(&client_data->work,
+ msecs_to_jiffies(
+ atomic_read(&client_data->delay)));
+ }
+ mutex_unlock(&client_data->mutex_enable);
+
+ return err;
+}
+
+
+int smi_suspend(struct device *dev)
+{
+ int err = 0;
+ struct smi_client_data *client_data = dev_get_drvdata(dev);
+ unsigned char stc_enable;
+ unsigned char std_enable;
+ dev_err(client_data->dev, "smi suspend function entrance");
+
+ atomic_set(&client_data->in_suspend, 1);
+ if (atomic_read(&client_data->wkqueue_en) == 1) {
+ smi130_set_acc_op_mode(client_data, SMI_ACC_PM_SUSPEND);
+ cancel_delayed_work_sync(&client_data->work);
+ }
+ SMI_CALL_API(get_step_counter_enable)(&stc_enable);
+ SMI_CALL_API(get_step_detector_enable)(&std_enable);
+ if (client_data->pw.acc_pm != SMI_ACC_PM_SUSPEND &&
+ (stc_enable != 1) && (std_enable != 1) &&
+ (client_data->sig_flag != 1)) {
+ err += SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_acc_arr[SMI_ACC_PM_SUSPEND]);
+ smi_delay(3);
+ }
+ if (client_data->pw.gyro_pm != SMI_GYRO_PM_SUSPEND) {
+ err += SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_gyro_arr[SMI_GYRO_PM_SUSPEND]);
+ smi_delay(3);
+ }
+
+ if (client_data->pw.mag_pm != SMI_MAG_PM_SUSPEND) {
+#if defined(SMI130_AKM09912_SUPPORT)
+ err += smi130_set_bosch_akm_and_secondary_if_powermode(
+ SMI130_MAG_SUSPEND_MODE);
+#else
+ err += smi130_set_bmm150_mag_and_secondary_if_power_mode(
+ SMI130_MAG_SUSPEND_MODE);
+#endif
+ smi_delay(3);
+ }
+
+ return err;
+}
+EXPORT_SYMBOL(smi_suspend);
+
+int smi_resume(struct device *dev)
+{
+ int err = 0;
+ struct smi_client_data *client_data = dev_get_drvdata(dev);
+ atomic_set(&client_data->in_suspend, 0);
+ if (client_data->pw.acc_pm != SMI_ACC_PM_SUSPEND) {
+ err += SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_acc_arr[SMI_ACC_PM_NORMAL]);
+ smi_delay(3);
+ }
+ if (client_data->pw.gyro_pm != SMI_GYRO_PM_SUSPEND) {
+ err += SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_gyro_arr[SMI_GYRO_PM_NORMAL]);
+ smi_delay(3);
+ }
+
+ if (client_data->pw.mag_pm != SMI_MAG_PM_SUSPEND) {
+#if defined(SMI130_AKM09912_SUPPORT)
+ err += smi130_set_bosch_akm_and_secondary_if_powermode
+ (SMI130_MAG_FORCE_MODE);
+#else
+ err += smi130_set_bmm150_mag_and_secondary_if_power_mode
+ (SMI130_MAG_FORCE_MODE);
+#endif
+ smi_delay(3);
+ }
+ /* post resume operation */
+ err += smi_post_resume(client_data);
+
+ return err;
+}
+EXPORT_SYMBOL(smi_resume);
+
diff --git a/drivers/input/sensors/smi130/smi130_driver.h b/drivers/input/sensors/smi130/smi130_driver.h
new file mode 100644
index 0000000..4307ae5
--- /dev/null
+++ b/drivers/input/sensors/smi130/smi130_driver.h
@@ -0,0 +1,512 @@
+/*!
+ * @section LICENSE
+ * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved
+ *
+ * (C) Modification Copyright 2018 Robert Bosch Kft All Rights Reserved
+ *
+ * This software program is licensed subject to the GNU General
+ * Public License (GPL).Version 2,June 1991,
+ * available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * Special: Description of the Software:
+ *
+ * This software module (hereinafter called "Software") and any
+ * information on application-sheets (hereinafter called "Information") is
+ * provided free of charge for the sole purpose to support your application
+ * work.
+ *
+ * As such, the Software is merely an experimental software, not tested for
+ * safety in the field and only intended for inspiration for further development
+ * and testing. Any usage in a safety-relevant field of use (like automotive,
+ * seafaring, spacefaring, industrial plants etc.) was not intended, so there are
+ * no precautions for such usage incorporated in the Software.
+ *
+ * The Software is specifically designed for the exclusive use for Bosch
+ * Sensortec products by personnel who have special experience and training. Do
+ * not use this Software if you do not have the proper experience or training.
+ *
+ * This Software package is provided as is and without any expressed or
+ * implied warranties, including without limitation, the implied warranties of
+ * merchantability and fitness for a particular purpose.
+ *
+ * Bosch Sensortec and their representatives and agents deny any liability for
+ * the functional impairment of this Software in terms of fitness, performance
+ * and safety. Bosch Sensortec and their representatives and agents shall not be
+ * liable for any direct or indirect damages or injury, except as otherwise
+ * stipulated in mandatory applicable law.
+ * The Information provided is believed to be accurate and reliable. Bosch
+ * Sensortec assumes no responsibility for the consequences of use of such
+ * Information nor for any infringement of patents or other rights of third
+ * parties which may result from its use.
+ *
+ *------------------------------------------------------------------------------
+ * The following Product Disclaimer does not apply to the BSX4-HAL-4.1NoFusion Software
+ * which is licensed under the Apache License, Version 2.0 as stated above.
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Product Disclaimer
+ *
+ * Common:
+ *
+ * Assessment of Products Returned from Field
+ *
+ * Returned products are considered good if they fulfill the specifications /
+ * test data for 0-mileage and field listed in this document.
+ *
+ * Engineering Samples
+ *
+ * Engineering samples are marked with (e) or (E). Samples may vary from the
+ * valid technical specifications of the series product contained in this
+ * data sheet. Therefore, they are not intended or fit for resale to
+ * third parties or for use in end products. Their sole purpose is internal
+ * client testing. The testing of an engineering sample may in no way replace
+ * the testing of a series product. Bosch assumes no liability for the use
+ * of engineering samples. The purchaser shall indemnify Bosch from all claims
+ * arising from the use of engineering samples.
+ *
+ * Intended use
+ *
+ * Provided that SMI130 is used within the conditions (environment, application,
+ * installation, loads) as described in this TCD and the corresponding
+ * agreed upon documents, Bosch ensures that the product complies with
+ * the agreed properties. Agreements beyond this require
+ * the written approval by Bosch. The product is considered fit for the intended
+ * use when the product successfully has passed the tests
+ * in accordance with the TCD and agreed upon documents.
+ *
+ * It is the responsibility of the customer to ensure the proper application
+ * of the product in the overall system/vehicle.
+ *
+ * Bosch does not assume any responsibility for changes to the environment
+ * of the product that deviate from the TCD and the agreed upon documents
+ * as well as all applications not released by Bosch
+ *
+ * The resale and/or use of products are at the purchaser’s own risk and
+ * responsibility. The examination and testing of the SMI130
+ * is the sole responsibility of the purchaser.
+ *
+ * The purchaser shall indemnify Bosch from all third party claims
+ * arising from any product use not covered by the parameters of
+ * this product data sheet or not approved by Bosch and reimburse Bosch
+ * for all costs and damages in connection with such claims.
+ *
+ * The purchaser must monitor the market for the purchased products,
+ * particularly with regard to product safety, and inform Bosch without delay
+ * of all security relevant incidents.
+ *
+ * Application Examples and Hints
+ *
+ * With respect to any application examples, advice, normal values
+ * and/or any information regarding the application of the device,
+ * Bosch hereby disclaims any and all warranties and liabilities of any kind,
+ * including without limitation warranties of
+ * non-infringement of intellectual property rights or copyrights
+ * of any third party.
+ * The information given in this document shall in no event be regarded
+ * as a guarantee of conditions or characteristics. They are provided
+ * for illustrative purposes only and no evaluation regarding infringement
+ * of intellectual property rights or copyrights or regarding functionality,
+ * performance or error has been made.
+ *
+ * @filename smi130_driver.h
+ * @date 2015/08/17 14:40
+ * @Modification Date 2018/08/28 18:20
+ * @id "e90a329"
+ * @version 1.3
+ *
+ * @brief
+ * The head file of SMI130 device driver core code
+*/
+#ifndef _SMI130_DRIVER_H
+#define _SMI130_DRIVER_H
+
+#ifdef __KERNEL__
+#include <linux/kernel.h>
+#include <linux/unistd.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#else
+#include <unistd.h>
+#include <sys/types.h>
+#include <string.h>
+#endif
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/time.h>
+#include <linux/ktime.h>
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+
+#include "smi130.h"
+
+#if defined(CONFIG_USE_QUALCOMM_HAL)
+#include <linux/sensors.h>
+#endif
+/* sensor specific */
+#define SENSOR_NAME "smi130"
+#define SMI130_ENABLE_INT1 1
+#define SMI130_ENABLE_INT2 1
+/*#define SMI130_MAG_INTERFACE_SUPPORT 1*/
+
+/*#define SMI130_AKM09912_SUPPORT 1*/
+#define SMI_USE_BASIC_I2C_FUNC 1
+#define SENSOR_CHIP_ID_SMI (0xD0)
+#define SENSOR_CHIP_ID_SMI_C2 (0xD1)
+#define SENSOR_CHIP_ID_SMI_C3 (0xD3)
+
+#define SENSOR_CHIP_REV_ID_SMI (0x00)
+
+#define CHECK_CHIP_ID_TIME_MAX 5
+
+#define SMI_REG_NAME(name) SMI130_##name##__REG
+#define SMI_VAL_NAME(name) SMI130_##name
+#define SMI_CALL_API(name) smi130_##name
+
+#define SMI_I2C_WRITE_DELAY_TIME (1)
+
+/* generic */
+#define SMI_MAX_RETRY_I2C_XFER (10)
+#define SMI_MAX_RETRY_WAKEUP (5)
+#define SMI_MAX_RETRY_WAIT_DRDY (100)
+
+#define SMI_DELAY_MIN (1)
+#define SMI_DELAY_DEFAULT (200)
+
+#define SMI_VALUE_MAX (32767)
+#define SMI_VALUE_MIN (-32768)
+
+#define BYTES_PER_LINE (16)
+
+#define BUF_SIZE_PRINT (16)
+
+#define SMI_FAST_CALI_TRUE (1)
+#define SMI_FAST_CALI_ALL_RDY (7)
+
+/*! FIFO 1024 byte, max fifo frame count not over 150 */
+#define FIFO_FRAME_CNT 170
+#define FIFO_DATA_BUFSIZE 1024
+
+
+#define FRAME_LEN_ACC 6
+#define FRAME_LEN_GYRO 6
+#define FRAME_LEN_MAG 8
+
+/*! SMI Self test */
+#define SMI_SELFTEST_AMP_HIGH 1
+
+/* CMD */
+#define CMD_FOC_START 0x03
+#define CMD_PMU_ACC_SUSPEND 0x10
+#define CMD_PMU_ACC_NORMAL 0x11
+#define CMD_PMU_ACC_LP1 0x12
+#define CMD_PMU_ACC_LP2 0x13
+#define CMD_PMU_GYRO_SUSPEND 0x14
+#define CMD_PMU_GYRO_NORMAL 0x15
+#define CMD_PMU_GYRO_FASTSTART 0x17
+#define CMD_PMU_MAG_SUSPEND 0x18
+#define CMD_PMU_MAG_NORMAL 0x19
+#define CMD_PMU_MAG_LP1 0x1A
+#define CMD_PMU_MAG_LP2 0x1B
+#define CMD_CLR_FIFO_DATA 0xB0
+#define CMD_RESET_INT_ENGINE 0xB1
+#define CMD_RESET_USER_REG 0xB6
+
+#define USER_DAT_CFG_PAGE 0x00
+
+/*! FIFO Head definition*/
+#define FIFO_HEAD_A 0x84
+#define FIFO_HEAD_G 0x88
+#define FIFO_HEAD_M 0x90
+
+#define FIFO_HEAD_G_A (FIFO_HEAD_G | FIFO_HEAD_A)
+#define FIFO_HEAD_M_A (FIFO_HEAD_M | FIFO_HEAD_A)
+#define FIFO_HEAD_M_G (FIFO_HEAD_M | FIFO_HEAD_G)
+
+#define FIFO_HEAD_M_G_A (FIFO_HEAD_M | FIFO_HEAD_G | FIFO_HEAD_A)
+
+#define FIFO_HEAD_SENSOR_TIME 0x44
+#define FIFO_HEAD_SKIP_FRAME 0x40
+#define FIFO_HEAD_OVER_READ_LSB 0x80
+#define FIFO_HEAD_OVER_READ_MSB 0x00
+
+/*! FIFO head mode Frame bytes number definition */
+#define A_BYTES_FRM 6
+#define G_BYTES_FRM 6
+#define M_BYTES_FRM 8
+#define GA_BYTES_FRM 12
+#define MG_BYTES_FRM 14
+#define MA_BYTES_FRM 14
+#define MGA_BYTES_FRM 20
+
+#define ACC_FIFO_HEAD "acc"
+#define GYRO_FIFO_HEAD "gyro"
+#define MAG_FIFO_HEAD "mag"
+
+/*! Bosch sensor unknown place*/
+#define BOSCH_SENSOR_PLACE_UNKNOWN (-1)
+/*! Bosch sensor remapping table size P0~P7*/
+#define MAX_AXIS_REMAP_TAB_SZ 8
+
+#define ENABLE 1
+#define DISABLE 0
+
+/* smi sensor HW interrupt pin number */
+#define SMI_INT0 0
+#define SMI_INT1 1
+
+#define SMI_INT_LEVEL 0
+#define SMI_INT_EDGE 1
+
+/*! SMI mag interface */
+
+
+/* compensated output value returned if sensor had overflow */
+#define BMM050_OVERFLOW_OUTPUT -32768
+#define BMM050_OVERFLOW_OUTPUT_S32 ((s32)(-2147483647-1))
+
+/* Trim Extended Registers */
+#define BMM050_DIG_X1 0x5D
+#define BMM050_DIG_Y1 0x5E
+#define BMM050_DIG_Z4_LSB 0x62
+#define BMM050_DIG_Z4_MSB 0x63
+#define BMM050_DIG_X2 0x64
+#define BMM050_DIG_Y2 0x65
+#define BMM050_DIG_Z2_LSB 0x68
+#define BMM050_DIG_Z2_MSB 0x69
+#define BMM050_DIG_Z1_LSB 0x6A
+#define BMM050_DIG_Z1_MSB 0x6B
+#define BMM050_DIG_XYZ1_LSB 0x6C
+#define BMM050_DIG_XYZ1_MSB 0x6D
+#define BMM050_DIG_Z3_LSB 0x6E
+#define BMM050_DIG_Z3_MSB 0x6F
+#define BMM050_DIG_XY2 0x70
+#define BMM050_DIG_XY1 0x71
+
+struct smi130mag_compensate_t {
+ signed char dig_x1;
+ signed char dig_y1;
+
+ signed char dig_x2;
+ signed char dig_y2;
+
+ u16 dig_z1;
+ s16 dig_z2;
+ s16 dig_z3;
+ s16 dig_z4;
+
+ unsigned char dig_xy1;
+ signed char dig_xy2;
+
+ u16 dig_xyz1;
+};
+
+/*smi fifo sensor type combination*/
+enum SMI_FIFO_DATA_SELECT_T {
+ SMI_FIFO_A_SEL = 1,
+ SMI_FIFO_G_SEL,
+ SMI_FIFO_G_A_SEL,
+ SMI_FIFO_M_SEL,
+ SMI_FIFO_M_A_SEL,
+ SMI_FIFO_M_G_SEL,
+ SMI_FIFO_M_G_A_SEL,
+ SMI_FIFO_DATA_SEL_MAX
+};
+
+/*smi interrupt about step_detector and sgm*/
+#define INPUT_EVENT_STEP_DETECTOR 5
+#define INPUT_EVENT_SGM 3/*7*/
+#define INPUT_EVENT_FAST_ACC_CALIB_DONE 6
+#define INPUT_EVENT_FAST_GYRO_CALIB_DONE 4
+
+
+/*!
+* Bst sensor common definition,
+* please give parameters in BSP file.
+*/
+struct bosch_sensor_specific {
+ char *name;
+ /* 0 to 7 */
+ unsigned int place:3;
+ int irq;
+ int (*irq_gpio_cfg)(void);
+};
+
+/*! smi130 sensor spec of power mode */
+struct pw_mode {
+ u8 acc_pm;
+ u8 gyro_pm;
+ u8 mag_pm;
+};
+
+/*! smi130 sensor spec of odr */
+struct odr_t {
+ u8 acc_odr;
+ u8 gyro_odr;
+ u8 mag_odr;
+};
+
+/*! smi130 sensor spec of range */
+struct range_t {
+ u8 acc_range;
+ u8 gyro_range;
+};
+
+/*! smi130 sensor error status */
+struct err_status {
+ u8 fatal_err;
+ u8 err_code;
+ u8 i2c_fail;
+ u8 drop_cmd;
+ u8 mag_drdy_err;
+ u8 err_st_all;
+};
+
+/*! smi130 fifo frame for all sensors */
+struct fifo_frame_t {
+ struct smi130_accel_t *acc_farr;
+ struct smi130_gyro_t *gyro_farr;
+ struct smi130_mag_xyz_s32_t *mag_farr;
+
+ unsigned char acc_frame_cnt;
+ unsigned char gyro_frame_cnt;
+ unsigned char mag_frame_cnt;
+
+ u32 acc_lastf_ts;
+ u32 gyro_lastf_ts;
+ u32 mag_lastf_ts;
+};
+
+/*! smi130 fifo sensor time */
+struct fifo_sensor_time_t {
+ u32 acc_ts;
+ u32 gyro_ts;
+ u32 mag_ts;
+};
+
+struct pedometer_data_t {
+ /*! Fix step detector misinformation for the first time*/
+ u8 wkar_step_detector_status;
+ u_int32_t last_step_counter_value;
+};
+
+struct smi_client_data {
+ struct smi130_t device;
+ struct device *dev;
+ struct input_dev *input;/*acc_device*/
+ struct input_dev *gyro_input;
+ #if defined(CONFIG_USE_QUALCOMM_HAL)
+ struct input_dev *gyro_input;
+ struct sensors_classdev accel_cdev;
+ struct sensors_classdev gyro_cdev;
+ struct delayed_work accel_poll_work;
+ struct delayed_work gyro_poll_work;
+ u32 accel_poll_ms;
+ u32 gyro_poll_ms;
+ u32 accel_latency_ms;
+ u32 gyro_latency_ms;
+ atomic_t accel_en;
+ atomic_t gyro_en;
+ struct workqueue_struct *data_wq;
+ #endif
+ struct delayed_work work;
+ struct work_struct irq_work;
+
+ u8 chip_id;
+
+ struct pw_mode pw;
+ struct odr_t odr;
+ struct range_t range; /*TO DO*/
+ struct err_status err_st;
+ struct pedometer_data_t pedo_data;
+ s8 place;
+ u8 selftest;
+ /*struct wake_lock wakelock;*/
+ struct delayed_work delay_work_sig;
+ atomic_t in_suspend;
+
+ atomic_t wkqueue_en; /*TO DO acc gyro mag*/
+ atomic_t delay;
+ atomic_t selftest_result;
+
+ u8 fifo_data_sel;
+ u16 fifo_bytecount;
+ u8 fifo_head_en;
+ unsigned char fifo_int_tag_en;
+ struct fifo_frame_t fifo_frame;
+
+ unsigned char *fifo_data;
+ u64 fifo_time;
+ u8 stc_enable;
+ uint16_t gpio_pin;
+ u8 std;
+ u8 sig_flag;
+ unsigned char calib_status;
+ struct mutex mutex_op_mode;
+ struct mutex mutex_enable;
+ struct bosch_sensor_specific *bosch_pd;
+ int IRQ;
+ int reg_sel;
+ int reg_len;
+ uint64_t timestamp;
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ struct early_suspend early_suspend_handler;
+#endif
+};
+
+
+/*!
+ * we use a typedef to hide the detail,
+ * because this type might be changed
+ */
+struct bosch_sensor_axis_remap {
+ /* src means which source will be mapped to target x, y, z axis */
+ /* if an target OS axis is remapped from (-)x,
+ * src is 0, sign_* is (-)1 */
+ /* if an target OS axis is remapped from (-)y,
+ * src is 1, sign_* is (-)1 */
+ /* if an target OS axis is remapped from (-)z,
+ * src is 2, sign_* is (-)1 */
+ int src_x:3;
+ int src_y:3;
+ int src_z:3;
+
+ int sign_x:2;
+ int sign_y:2;
+ int sign_z:2;
+};
+
+
+struct bosch_sensor_data {
+ union {
+ int16_t v[3];
+ struct {
+ int16_t x;
+ int16_t y;
+ int16_t z;
+ };
+ };
+};
+
+s8 smi_burst_read_wrapper(u8 dev_addr, u8 reg_addr, u8 *data, u16 len);
+int smi_probe(struct smi_client_data *client_data, struct device *dev);
+int smi_remove(struct device *dev);
+int smi_suspend(struct device *dev);
+int smi_resume(struct device *dev);
+
+
+
+
+#endif/*_SMI130_DRIVER_H*/
+/*@}*/
+
diff --git a/drivers/input/sensors/smi130/smi130_gyro.c b/drivers/input/sensors/smi130/smi130_gyro.c
new file mode 100644
index 0000000..ef3fc38f
--- /dev/null
+++ b/drivers/input/sensors/smi130/smi130_gyro.c
@@ -0,0 +1,7422 @@
+/*!
+ * @section LICENSE
+ * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved
+ *
+ * (C) Modification Copyright 2018 Robert Bosch Kft All Rights Reserved
+ *
+ * This software program is licensed subject to the GNU General
+ * Public License (GPL).Version 2,June 1991,
+ * available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * Special: Description of the Software:
+ *
+ * This software module (hereinafter called "Software") and any
+ * information on application-sheets (hereinafter called "Information") is
+ * provided free of charge for the sole purpose to support your application
+ * work.
+ *
+ * As such, the Software is merely an experimental software, not tested for
+ * safety in the field and only intended for inspiration for further development
+ * and testing. Any usage in a safety-relevant field of use (like automotive,
+ * seafaring, spacefaring, industrial plants etc.) was not intended, so there are
+ * no precautions for such usage incorporated in the Software.
+ *
+ * The Software is specifically designed for the exclusive use for Bosch
+ * Sensortec products by personnel who have special experience and training. Do
+ * not use this Software if you do not have the proper experience or training.
+ *
+ * This Software package is provided as is and without any expressed or
+ * implied warranties, including without limitation, the implied warranties of
+ * merchantability and fitness for a particular purpose.
+ *
+ * Bosch Sensortec and their representatives and agents deny any liability for
+ * the functional impairment of this Software in terms of fitness, performance
+ * and safety. Bosch Sensortec and their representatives and agents shall not be
+ * liable for any direct or indirect damages or injury, except as otherwise
+ * stipulated in mandatory applicable law.
+ * The Information provided is believed to be accurate and reliable. Bosch
+ * Sensortec assumes no responsibility for the consequences of use of such
+ * Information nor for any infringement of patents or other rights of third
+ * parties which may result from its use.
+ *
+ *------------------------------------------------------------------------------
+ * The following Product Disclaimer does not apply to the BSX4-HAL-4.1NoFusion Software
+ * which is licensed under the Apache License, Version 2.0 as stated above.
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Product Disclaimer
+ *
+ * Common:
+ *
+ * Assessment of Products Returned from Field
+ *
+ * Returned products are considered good if they fulfill the specifications /
+ * test data for 0-mileage and field listed in this document.
+ *
+ * Engineering Samples
+ *
+ * Engineering samples are marked with (e) or (E). Samples may vary from the
+ * valid technical specifications of the series product contained in this
+ * data sheet. Therefore, they are not intended or fit for resale to
+ * third parties or for use in end products. Their sole purpose is internal
+ * client testing. The testing of an engineering sample may in no way replace
+ * the testing of a series product. Bosch assumes no liability for the use
+ * of engineering samples. The purchaser shall indemnify Bosch from all claims
+ * arising from the use of engineering samples.
+ *
+ * Intended use
+ *
+ * Provided that SMI130 is used within the conditions (environment, application,
+ * installation, loads) as described in this TCD and the corresponding
+ * agreed upon documents, Bosch ensures that the product complies with
+ * the agreed properties. Agreements beyond this require
+ * the written approval by Bosch. The product is considered fit for the intended
+ * use when the product successfully has passed the tests
+ * in accordance with the TCD and agreed upon documents.
+ *
+ * It is the responsibility of the customer to ensure the proper application
+ * of the product in the overall system/vehicle.
+ *
+ * Bosch does not assume any responsibility for changes to the environment
+ * of the product that deviate from the TCD and the agreed upon documents
+ * as well as all applications not released by Bosch
+ *
+ * The resale and/or use of products are at the purchaser’s own risk and
+ * responsibility. The examination and testing of the SMI130
+ * is the sole responsibility of the purchaser.
+ *
+ * The purchaser shall indemnify Bosch from all third party claims
+ * arising from any product use not covered by the parameters of
+ * this product data sheet or not approved by Bosch and reimburse Bosch
+ * for all costs and damages in connection with such claims.
+ *
+ * The purchaser must monitor the market for the purchased products,
+ * particularly with regard to product safety, and inform Bosch without delay
+ * of all security relevant incidents.
+ *
+ * Application Examples and Hints
+ *
+ * With respect to any application examples, advice, normal values
+ * and/or any information regarding the application of the device,
+ * Bosch hereby disclaims any and all warranties and liabilities of any kind,
+ * including without limitation warranties of
+ * non-infringement of intellectual property rights or copyrights
+ * of any third party.
+ * The information given in this document shall in no event be regarded
+ * as a guarantee of conditions or characteristics. They are provided
+ * for illustrative purposes only and no evaluation regarding infringement
+ * of intellectual property rights or copyrights or regarding functionality,
+ * performance or error has been made.
+ * @filename smi130_gyro.c
+ * @date 2013/11/25
+ * @Modification Date 2018/08/28 18:20
+ * @id "8fcde22"
+ * @version 1.5
+ *
+ * @brief SMI130_GYROAPI
+*/
+
+#include "smi130_gyro.h"
+static struct smi130_gyro_t *p_smi130_gyro;
+
+
+/*****************************************************************************
+ * Description: *//**brief API Initialization routine
+ *
+ *
+ *
+ *
+* \param smi130_gyro_t *smi130_gyro
+ * Pointer to a structure.
+ *
+ * structure members are
+ *
+ * unsigned char chip_id;
+ * unsigned char dev_addr;
+ * SMI130_GYRO_BRD_FUNC_PTR;
+ * SMI130_GYRO_WR_FUNC_PTR;
+ * SMI130_GYRO_RD_FUNC_PTR;
+ * void(*delay_msec)( SMI130_GYRO_MDELAY_DATA_TYPE );
+ *
+ *
+ *
+ *
+ *
+ * \return result of communication routines
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_init(struct smi130_gyro_t *smi130_gyro)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char a_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ p_smi130_gyro = smi130_gyro;
+
+ p_smi130_gyro->dev_addr = SMI130_GYRO_I2C_ADDR;
+
+ /*Read CHIP_ID */
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_CHIP_ID_ADDR, &a_data_u8r, 1);
+ p_smi130_gyro->chip_id = a_data_u8r;
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief Reads Rate dataX from location 02h and 03h
+ * registers
+ *
+ *
+ *
+ *
+ * \param
+ * SMI130_GYRO_S16 *data_x : Address of data_x
+ *
+ *
+ * \return
+ * result of communication routines
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_dataX(SMI130_GYRO_S16 *data_x)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char a_data_u8r[2] = {0, 0};
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_RATE_X_LSB_VALUEX__REG, a_data_u8r, 2);
+ a_data_u8r[0] = SMI130_GYRO_GET_BITSLICE(a_data_u8r[0],
+ SMI130_GYRO_RATE_X_LSB_VALUEX);
+ *data_x = (SMI130_GYRO_S16)
+ ((((SMI130_GYRO_S16)((signed char)a_data_u8r[1])) <<
+ SMI130_GYRO_SHIFT_8_POSITION) | (a_data_u8r[0]));
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief Reads rate dataY from location 04h and 05h
+ * registers
+ *
+ *
+ *
+ *
+ * \param
+ * SMI130_GYRO_S16 *data_y : Address of data_y
+ *
+ *
+ * \return
+ * result of communication routines
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_dataY(SMI130_GYRO_S16 *data_y)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char a_data_u8r[2] = {0, 0};
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_RATE_Y_LSB_VALUEY__REG, a_data_u8r, 2);
+ a_data_u8r[0] = SMI130_GYRO_GET_BITSLICE(a_data_u8r[0],
+ SMI130_GYRO_RATE_Y_LSB_VALUEY);
+ *data_y = (SMI130_GYRO_S16)
+ ((((SMI130_GYRO_S16)((signed char)a_data_u8r[1]))
+ << SMI130_GYRO_SHIFT_8_POSITION) | (a_data_u8r[0]));
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief Reads rate dataZ from location 06h and 07h
+ * registers
+ *
+ *
+ *
+ *
+ * \param
+ * SMI130_GYRO_S16 *data_z : Address of data_z
+ *
+ *
+ * \return
+ * result of communication routines
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_dataZ(SMI130_GYRO_S16 *data_z)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char a_data_u8r[2] = {0, 0};
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_RATE_Z_LSB_VALUEZ__REG, a_data_u8r, 2);
+ a_data_u8r[0] = SMI130_GYRO_GET_BITSLICE(a_data_u8r[0],
+ SMI130_GYRO_RATE_Z_LSB_VALUEZ);
+ *data_z = (SMI130_GYRO_S16)
+ ((((SMI130_GYRO_S16)((signed char)a_data_u8r[1]))
+ << SMI130_GYRO_SHIFT_8_POSITION) | (a_data_u8r[0]));
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief Reads data X,Y and Z from location 02h to 07h
+ *
+ *
+ *
+ *
+ * \param
+ * smi130_gyro_data_t *data : Address of smi130_gyro_data_t
+ *
+ *
+ * \return
+ * result of communication routines
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_dataXYZ(struct smi130_gyro_data_t *data)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char a_data_u8r[6] = {0, 0, 0, 0, 0, 0};
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_RATE_X_LSB_VALUEX__REG, a_data_u8r, 6);
+ /* Data X */
+ a_data_u8r[0] =
+ SMI130_GYRO_GET_BITSLICE(a_data_u8r[0], SMI130_GYRO_RATE_X_LSB_VALUEX);
+ data->datax = (SMI130_GYRO_S16)
+ ((((SMI130_GYRO_S16)((signed char)a_data_u8r[1]))
+ << SMI130_GYRO_SHIFT_8_POSITION) | (a_data_u8r[0]));
+ /* Data Y */
+ a_data_u8r[2] = SMI130_GYRO_GET_BITSLICE(a_data_u8r[2],
+ SMI130_GYRO_RATE_Y_LSB_VALUEY);
+ data->datay = (SMI130_GYRO_S16)
+ ((((SMI130_GYRO_S16)((signed char)a_data_u8r[3]))
+ << SMI130_GYRO_SHIFT_8_POSITION) | (a_data_u8r[2]));
+ /* Data Z */
+ a_data_u8r[4] = SMI130_GYRO_GET_BITSLICE(a_data_u8r[4],
+ SMI130_GYRO_RATE_Z_LSB_VALUEZ);
+ data->dataz = (SMI130_GYRO_S16)
+ ((((SMI130_GYRO_S16)((signed char)a_data_u8r[5]))
+ << SMI130_GYRO_SHIFT_8_POSITION) | (a_data_u8r[4]));
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief Reads data X,Y,Z and Interrupts
+ * from location 02h to 07h
+ *
+ *
+ *
+ *
+ * \param
+ * smi130_gyro_data_t *data : Address of smi130_gyro_data_t
+ *
+ *
+ * \return
+ * result of communication routines
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_dataXYZI(struct smi130_gyro_data_t *data)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char a_data_u8r[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_RATE_X_LSB_VALUEX__REG, a_data_u8r, 12);
+ /* Data X */
+ a_data_u8r[0] = SMI130_GYRO_GET_BITSLICE(a_data_u8r[0],
+ SMI130_GYRO_RATE_X_LSB_VALUEX);
+ data->datax = (SMI130_GYRO_S16)
+ ((((SMI130_GYRO_S16)((signed char)a_data_u8r[1]))
+ << SMI130_GYRO_SHIFT_8_POSITION) | (a_data_u8r[0]));
+ /* Data Y */
+ a_data_u8r[2] = SMI130_GYRO_GET_BITSLICE(a_data_u8r[2],
+ SMI130_GYRO_RATE_Y_LSB_VALUEY);
+ data->datay = (SMI130_GYRO_S16)
+ ((((SMI130_GYRO_S16)((signed char)a_data_u8r[3]))
+ << SMI130_GYRO_SHIFT_8_POSITION) | (a_data_u8r[2]));
+ /* Data Z */
+ a_data_u8r[4] = SMI130_GYRO_GET_BITSLICE(a_data_u8r[4],
+ SMI130_GYRO_RATE_Z_LSB_VALUEZ);
+ data->dataz = (SMI130_GYRO_S16)
+ ((((SMI130_GYRO_S16)((signed char)a_data_u8r[5]))
+ << SMI130_GYRO_SHIFT_8_POSITION) | (a_data_u8r[4]));
+ data->intstatus[0] = a_data_u8r[7];
+ data->intstatus[1] = a_data_u8r[8];
+ data->intstatus[2] = a_data_u8r[9];
+ data->intstatus[3] = a_data_u8r[10];
+ data->intstatus[4] = a_data_u8r[11];
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief Reads Temperature from location 08h
+ *
+ *
+ *
+ *
+ * \param
+ * unsigned char *temp : Address of temperature
+ *
+ *
+ * \return
+ * result of communication routines
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_Temperature(unsigned char *temperature)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_TEMP_ADDR, &v_data_u8r, 1);
+ *temperature = v_data_u8r;
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API reads the data from the given register
+ *
+ *
+ *
+ *
+ *\param unsigned char addr, unsigned char *data unsigned char len
+ * addr -> Address of the register
+ * data -> address of the variable, read value will be
+ * kept
+ * len -> No of byte to be read.
+ * \return results of bus communication function
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_read_register(unsigned char addr,
+unsigned char *data, unsigned char len)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr, addr, data, len);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API reads the data from the given register
+ *
+ *
+ *
+ *
+ *\param unsigned char addr, unsigned char *data SMI130_GYRO_S32 len
+ * addr -> Address of the register
+ * data -> address of the variable, read value will be
+ * kept
+ * len -> No of byte to be read.
+ * \return results of bus communication function
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_burst_read(unsigned char addr,
+unsigned char *data, SMI130_GYRO_S32 len)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BURST_READ_FUNC(p_smi130_gyro->dev_addr,
+ addr, data, len);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API given data to the given register
+ *
+ *
+ *
+ *
+ *\param unsigned char addr, unsigned char data,unsigned char len
+ * addr -> Address of the register
+ * data -> Data to be written to the register
+ * len -> No of byte to be read.
+ *
+ * \return Results of bus communication function
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_write_register(unsigned char addr,
+unsigned char *data, unsigned char len)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr, addr, data, len);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief Reads interrupt status 0 register byte from 09h
+ *
+ *
+ *
+ *
+ * \param
+ * unsigned char *status0_data : Address of status 0 register
+ *
+ *
+ * \return
+ * Result of bus communication function
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_interrupt_status_reg_0(
+unsigned char *status0_data)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_STATUSZERO__REG, &v_data_u8r, 1);
+ *status0_data =
+ SMI130_GYRO_GET_BITSLICE(v_data_u8r, SMI130_GYRO_INT_STATUSZERO);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief Reads interrupt status 1 register byte from 0Ah
+ *
+ *
+ *
+ *
+ * \param
+ * unsigned char *status1_data : Address of status register
+ *
+ *
+ * \return
+ * Result of bus communication function
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_interrupt_status_reg_1(
+unsigned char *status1_data)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr, SMI130_GYRO_INT_STATUSONE__REG,
+ &v_data_u8r, 1);
+ *status1_data =
+ SMI130_GYRO_GET_BITSLICE(v_data_u8r, SMI130_GYRO_INT_STATUSONE);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief Reads interrupt status register byte from 0Bh
+ *
+ *
+ *
+ *
+ * \param
+ * unsigned char *status2_data : Address of status 2 register
+ *
+ *
+ * \return
+ * Result of bus communication function
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_interrupt_status_reg_2(
+unsigned char *status2_data)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_STATUSTWO__REG, &v_data_u8r, 1);
+ *status2_data =
+ SMI130_GYRO_GET_BITSLICE(v_data_u8r, SMI130_GYRO_INT_STATUSTWO);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief Reads interrupt status 3 register byte from 0Ch
+ *
+ *
+ *
+ *
+ * \param
+ * unsigned char *status3_data : Address of status 3 register
+ *
+ *
+ * \return
+ * Result of bus communication function
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_interrupt_status_reg_3(
+unsigned char *status3_data)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_STATUSTHREE__REG, &v_data_u8r, 1);
+ *status3_data =
+ SMI130_GYRO_GET_BITSLICE(v_data_u8r, SMI130_GYRO_INT_STATUSTHREE);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API reads the range from register 0x0Fh of
+ * (0 to 2) bits
+ *
+ *
+ *
+ *
+ *\param unsigned char *range
+ * Range[0....7]
+ * 0 2000/s
+ * 1 1000/s
+ * 2 500/s
+ * 3 250/s
+ * 4 125/s
+ *
+ *
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_range_reg(unsigned char *range)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_RANGE_ADDR_RANGE__REG, &v_data_u8r, 1);
+ *range =
+ SMI130_GYRO_GET_BITSLICE(v_data_u8r, SMI130_GYRO_RANGE_ADDR_RANGE);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API sets the range register 0x0Fh
+ * (0 to 2 bits)
+ *
+ *
+ *
+ *
+ *\param unsigned char range
+ *
+ * Range[0....7]
+ * 0 2000/s
+ * 1 1000/s
+ * 2 500/s
+ * 3 250/s
+ * 4 125/s
+ *
+ *
+ *
+ *
+ * \return Communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_range_reg(unsigned char range)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ if (range < C_SMI130_GYRO_Five_U8X) {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_RANGE_ADDR_RANGE__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_RANGE_ADDR_RANGE,
+ range);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_RANGE_ADDR_RANGE__REG, &v_data_u8r, 1);
+ } else {
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API reads the high resolution bit of 0x10h
+ * Register 7th bit
+ *
+ *
+ *
+ *
+ *\param unsigned char *high_res
+ * Pointer to a variable passed as a parameter
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_high_res(unsigned char *high_res)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_BW_ADDR_HIGH_RES__REG, &v_data_u8r, 1);
+ *high_res =
+ SMI130_GYRO_GET_BITSLICE(v_data_u8r, SMI130_GYRO_BW_ADDR_HIGH_RES);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API reads the bandwidth register of 0x10h 0 to
+ * 3 bits
+ *
+ *
+ *
+ *
+* \param unsigned char *bandwidth
+ * pointer to a variable passed as a parameter
+ *
+ * 0 no filter(523 Hz)
+ * 1 230Hz
+ * 2 116Hz
+ * 3 47Hz
+ * 4 23Hz
+ * 5 12Hz
+ * 6 64Hz
+ * 7 32Hz
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_bw(unsigned char *bandwidth)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr, SMI130_GYRO_BW_ADDR__REG, &v_data_u8r, 1);
+ *bandwidth = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_BW_ADDR);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API writes the Bandwidth register (0x10h of 0
+ * to 3 bits)
+ *
+ *
+ *
+ *
+ *\param unsigned char bandwidth,
+ * The bandwidth to be set passed as a parameter
+ *
+ * 0 no filter(523 Hz)
+ * 1 230Hz
+ * 2 116Hz
+ * 3 47Hz
+ * 4 23Hz
+ * 5 12Hz
+ * 6 64Hz
+ * 7 32Hz
+ *
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_bw(unsigned char bandwidth)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_mode_u8r = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_autosleepduration = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ if (bandwidth < C_SMI130_GYRO_Eight_U8X) {
+ smi130_gyro_get_mode(&v_mode_u8r);
+ if (v_mode_u8r == SMI130_GYRO_MODE_ADVANCEDPOWERSAVING) {
+ smi130_gyro_get_autosleepdur(&v_autosleepduration);
+ smi130_gyro_set_autosleepdur(v_autosleepduration,
+ bandwidth);
+ }
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_BW_ADDR__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_BW_ADDR, bandwidth);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_BW_ADDR__REG, &v_data_u8r, 1);
+ } else {
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API reads the status of External Trigger
+ * selection bits (4 and 5) of 0x12h registers
+ *
+ *
+ *
+ *
+ *\param unsigned char *pwu_ext_tri_sel
+ * Pointer to a variable passed as a parameter
+ *
+ *
+ *
+ * \return Communication Results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_pmu_ext_tri_sel(
+unsigned char *pwu_ext_tri_sel)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MODE_LPM2_ADDR_EXT_TRI_SEL__REG, &v_data_u8r, 1);
+ *pwu_ext_tri_sel = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_MODE_LPM2_ADDR_EXT_TRI_SEL);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API writes the External Trigger selection
+ * bits (4 and 5) of 0x12h registers
+ *
+ *
+ *
+ *
+ *\param unsigned char pwu_ext_tri_sel
+ * Value to be written passed as a parameter
+ *
+ *
+ *
+ * \return Communication Results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_pmu_ext_tri_sel(
+unsigned char pwu_ext_tri_sel)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MODE_LPM2_ADDR_EXT_TRI_SEL__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_MODE_LPM2_ADDR_EXT_TRI_SEL, pwu_ext_tri_sel);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MODE_LPM2_ADDR_EXT_TRI_SEL__REG, &v_data_u8r, 1);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get data high bandwidth
+ *
+ *
+ *
+ *
+ *\param unsigned char *high_bw : Address of high_bw
+ * Pointer to a variable passed as a parameter
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_high_bw(unsigned char *high_bw)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_RATED_HBW_ADDR_DATA_HIGHBW__REG, &v_data_u8r, 1);
+ *high_bw = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_RATED_HBW_ADDR_DATA_HIGHBW);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set data high bandwidth
+ *
+ *
+ *
+ *
+ *\param unsigned char high_bw:
+ * Value to be written passed as a parameter
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_high_bw(unsigned char high_bw)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ if (high_bw < C_SMI130_GYRO_Two_U8X) {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_RATED_HBW_ADDR_DATA_HIGHBW__REG,
+ &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_RATED_HBW_ADDR_DATA_HIGHBW, high_bw);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_RATED_HBW_ADDR_DATA_HIGHBW__REG,
+ &v_data_u8r, 1);
+ } else {
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get shadow dis
+ *
+ *
+ *
+ *
+ *\param unsigned char *shadow_dis : Address of shadow_dis
+ * Pointer to a variable passed as a parameter
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_shadow_dis(unsigned char *shadow_dis)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_RATED_HBW_ADDR_SHADOW_DIS__REG, &v_data_u8r, 1);
+ *shadow_dis = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_RATED_HBW_ADDR_SHADOW_DIS);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set shadow dis
+ *
+ *
+ *
+ *
+ *\param unsigned char shadow_dis
+ * Value to be written passed as a parameter
+ *
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_shadow_dis(unsigned char shadow_dis)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ if (shadow_dis < C_SMI130_GYRO_Two_U8X) {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_RATED_HBW_ADDR_SHADOW_DIS__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_RATED_HBW_ADDR_SHADOW_DIS, shadow_dis);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_RATED_HBW_ADDR_SHADOW_DIS__REG, &v_data_u8r, 1);
+ } else {
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief
+ * This function is used for the soft reset
+ * The soft reset register will be written with 0xB6.
+ *
+ *
+ *
+* \param None
+ *
+ *
+ *
+ * \return Communication results.
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_soft_reset()
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_SoftReset_u8r = C_SMI130_GYRO_Zero_U8X;
+ v_SoftReset_u8r = 0xB6;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_BGW_SOFTRESET_ADDR, &v_SoftReset_u8r, 1);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get data enable data
+ *
+ *
+ *
+ *
+ *\param unsigned char *data_en : Address of data_en
+ * Pointer to a variable passed as a parameter
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_data_enable(unsigned char *data_en)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_ENABLE0_DATAEN__REG, &v_data_u8r, 1);
+ *data_en = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_ENABLE0_DATAEN);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set data enable data
+ *
+ *
+ *
+ *
+ * \param unsigned char data_en:
+ * Value to be written passed as a \parameter
+ * 0 --> Disable
+ * 1 --> Enable
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_data_en(unsigned char data_en)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_ENABLE0_DATAEN__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_ENABLE0_DATAEN, data_en);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_ENABLE0_DATAEN__REG, &v_data_u8r, 1);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get fifo enable bit
+ *
+ *
+ *
+ *
+ * \param unsigned char *fifo_en : Address of fifo_en
+ * Pointer to a variable passed as a parameter
+
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_fifo_enable(unsigned char *fifo_en)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_ENABLE0_FIFOEN__REG, &v_data_u8r, 1);
+ *fifo_en = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_ENABLE0_FIFOEN);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set fifo enable bit
+ *
+ *
+ *
+ *
+ * \param unsigned char fifo_en:
+ * Value to be written passed as a parameter
+ * 0 --> Disable
+ * 1 --> Enable
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_fifo_enable(unsigned char fifo_en)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ if (fifo_en < C_SMI130_GYRO_Two_U8X) {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_ENABLE0_FIFOEN__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_ENABLE0_FIFOEN, fifo_en);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_ENABLE0_FIFOEN__REG, &v_data_u8r, 1);
+ } else {
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API reads the status of the Auto offset
+ * Enable bit
+ * (0x15 Reg 3rd Bit)
+ *
+ *
+ *
+ *
+ * \param unsigned char *offset_en
+ * address of a variable,
+ *
+ *
+ *
+ * \return Communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_auto_offset_en(
+unsigned char *offset_en)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_ENABLE0_AUTO_OFFSETEN__REG, &v_data_u8r, 1);
+ *offset_en = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_ENABLE0_AUTO_OFFSETEN);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API sets the Auto offset enable bit
+ * (Reg 0x15 3rd Bit)
+ *
+ *
+ *
+ *
+ * \param unsigned char offset_en
+ * 0 --> Disable
+ * 1 --> Enable
+ *
+ * \return Communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_auto_offset_en(unsigned char offset_en)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_ENABLE0_AUTO_OFFSETEN__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_ENABLE0_AUTO_OFFSETEN, offset_en);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_ENABLE0_AUTO_OFFSETEN__REG, &v_data_u8r, 1);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get the output type status
+ *
+ *
+ *
+ *
+ * \param unsigned char channel,unsigned char *int_od
+ * SMI130_GYRO_INT1 -> 0
+ * SMI130_GYRO_INT2 -> 1
+ * int_od : open drain -> 1
+ * push pull -> 0
+ *
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_int_od(unsigned char param,
+unsigned char *int_od)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (param) {
+ case SMI130_GYRO_INT1:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_ENABLE1_IT1_OD__REG, &v_data_u8r, 1);
+ *int_od = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_ENABLE1_IT1_OD);
+ break;
+ case SMI130_GYRO_INT2:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_ENABLE1_IT2_OD__REG, &v_data_u8r, 1);
+ *int_od = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_ENABLE1_IT2_OD);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set the output type status
+ *
+ *
+ *
+ *
+ * \param unsigned char channel,unsigned char *int_od
+ * SMI130_GYRO_INT1 -> 0
+ * SMI130_GYRO_INT2 -> 1
+ * int_od : open drain -> 1
+ * push pull -> 0
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_int_od(unsigned char param,
+unsigned char int_od)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (param) {
+ case SMI130_GYRO_INT1:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_ENABLE1_IT1_OD__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_ENABLE1_IT1_OD, int_od);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_ENABLE1_IT1_OD__REG, &v_data_u8r, 1);
+ break;
+ case SMI130_GYRO_INT2:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_ENABLE1_IT2_OD__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_ENABLE1_IT2_OD, int_od);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_ENABLE1_IT2_OD__REG, &v_data_u8r, 1);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get Active Level status
+ *
+ *
+ *
+ *
+ * \param unsigned char channel,unsigned char *int_lvl
+ * SMI130_GYRO_INT1 -> 0
+ * SMI130_GYRO_INT2 -> 1
+ * int_lvl : Active HI -> 1
+ * Active LO -> 0
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_int_lvl(unsigned char param,
+unsigned char *int_lvl)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (param) {
+ case SMI130_GYRO_INT1:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_ENABLE1_IT1_LVL__REG, &v_data_u8r, 1);
+ *int_lvl = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_ENABLE1_IT1_LVL);
+ break;
+ case SMI130_GYRO_INT2:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_ENABLE1_IT2_LVL__REG, &v_data_u8r, 1);
+ *int_lvl = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_ENABLE1_IT2_LVL);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set Active Level status
+ *
+ *
+ *
+ *
+ * \param unsigned char channel,unsigned char *int_lvl
+ * SMI130_GYRO_INT1 -> 0
+ * SMI130_GYRO_INT2 -> 1
+ * int_lvl : Active HI -> 1
+ * Active LO -> 0
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_int_lvl(unsigned char param,
+unsigned char int_lvl)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (param) {
+ case SMI130_GYRO_INT1:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_ENABLE1_IT1_LVL__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_ENABLE1_IT1_LVL, int_lvl);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_ENABLE1_IT1_LVL__REG, &v_data_u8r, 1);
+ break;
+ case SMI130_GYRO_INT2:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_ENABLE1_IT2_LVL__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_ENABLE1_IT2_LVL, int_lvl);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_ENABLE1_IT2_LVL__REG, &v_data_u8r, 1);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get High Interrupt1
+ *
+ *
+ *
+ *
+ * \param unsigned char *int1_high : Address of high_bw
+ * Pointer to a variable passed as a parameter
+
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_int1_high(unsigned char *int1_high)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_MAP_0_INT1_HIGH__REG, &v_data_u8r, 1);
+ *int1_high = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_MAP_0_INT1_HIGH);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set High Interrupt1
+ *
+ *
+ *
+ *
+ * \param unsigned char int1_high
+ * 0 -> Disable
+ * 1 -> Enable
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_int1_high(unsigned char int1_high)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_MAP_0_INT1_HIGH__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_MAP_0_INT1_HIGH, int1_high);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_MAP_0_INT1_HIGH__REG, &v_data_u8r, 1);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get Any Interrupt1
+ *
+ *
+ *
+ *
+ * \param unsigned char *int1_any : Address of high_bw
+ * Pointer to a variable passed as a parameter
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_int1_any(unsigned char *int1_any)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_MAP_0_INT1_ANY__REG, &v_data_u8r, 1);
+ *int1_any = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_MAP_0_INT1_ANY);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set Any Interrupt1
+ *
+ *
+ *
+ *
+ *\param unsigned char int1_any
+ * 0 -> Disable
+ * 1 -> Enable
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_int1_any(unsigned char int1_any)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_MAP_0_INT1_ANY__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_MAP_0_INT1_ANY, int1_any);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_MAP_0_INT1_ANY__REG, &v_data_u8r, 1);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get data Interrupt1 and data
+ * Interrupt2
+ *
+ *
+ *
+ *
+ * \param unsigned char axis,unsigned char *int_data
+ * axis :
+ * SMI130_GYRO_INT1_DATA -> 0
+ * SMI130_GYRO_INT2_DATA -> 1
+ * int_data :
+ * Disable -> 0
+ * Enable -> 1
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_int_data(unsigned char axis,
+unsigned char *int_data)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (axis) {
+ case SMI130_GYRO_INT1_DATA:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MAP_1_INT1_DATA__REG, &v_data_u8r, 1);
+ *int_data = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_MAP_1_INT1_DATA);
+ break;
+ case SMI130_GYRO_INT2_DATA:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MAP_1_INT2_DATA__REG, &v_data_u8r, 1);
+ *int_data = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_MAP_1_INT2_DATA);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set data Interrupt1 and data
+ * Interrupt2
+ *
+ *
+ *
+ *
+ * \param unsigned char axis,unsigned char *int_data
+ * axis :
+ * SMI130_GYRO_INT1_DATA -> 0
+ * SMI130_GYRO_INT2_DATA -> 1
+ * int_data :
+ * Disable -> 0
+ * Enable -> 1
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_int_data(unsigned char axis,
+unsigned char int_data)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (axis) {
+ case SMI130_GYRO_INT1_DATA:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MAP_1_INT1_DATA__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_MAP_1_INT1_DATA, int_data);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MAP_1_INT1_DATA__REG, &v_data_u8r, 1);
+ break;
+ case SMI130_GYRO_INT2_DATA:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MAP_1_INT2_DATA__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_MAP_1_INT2_DATA, int_data);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MAP_1_INT2_DATA__REG, &v_data_u8r, 1);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+ }
+
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get fast offset and auto
+ * offset Interrupt2
+ *
+ *
+ *
+ *
+ *\param unsigned char axis,unsigned char *int2_offset
+ * axis :
+ * SMI130_GYRO_AUTO_OFFSET -> 1
+ * SMI130_GYRO_FAST_OFFSET -> 2
+ * int2_offset :
+ * Disable -> 0
+ * Enable -> 1
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_int2_offset(unsigned char axis,
+unsigned char *int2_offset)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (axis) {
+ case SMI130_GYRO_FAST_OFFSET:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MAP_1_INT2_FAST_OFFSET__REG, &v_data_u8r, 1);
+ *int2_offset = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_MAP_1_INT2_FAST_OFFSET);
+ break;
+ case SMI130_GYRO_AUTO_OFFSET:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MAP_1_INT2_AUTO_OFFSET__REG, &v_data_u8r, 1);
+ *int2_offset = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_MAP_1_INT2_AUTO_OFFSET);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set fast offset and auto
+ * offset Interrupt2
+ *
+ *
+ *
+ *
+ *\param unsigned char axis,unsigned char *int2_offset
+ * axis :
+ * SMI130_GYRO_AUTO_OFFSET -> 1
+ * SMI130_GYRO_FAST_OFFSET -> 2
+ * int2_offset :
+ * Disable -> 0
+ * Enable -> 1
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_int2_offset(unsigned char axis,
+unsigned char int2_offset)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (axis) {
+ case SMI130_GYRO_FAST_OFFSET:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MAP_1_INT2_FAST_OFFSET__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_MAP_1_INT2_FAST_OFFSET, int2_offset);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MAP_1_INT2_FAST_OFFSET__REG, &v_data_u8r, 1);
+ break;
+ case SMI130_GYRO_AUTO_OFFSET:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MAP_1_INT2_AUTO_OFFSET__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_MAP_1_INT2_AUTO_OFFSET, int2_offset);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MAP_1_INT2_AUTO_OFFSET__REG, &v_data_u8r, 1);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get fast offset and auto
+ * offset Interrupt1
+ *
+ *
+ *
+ *
+ *\param unsigned char axis,unsigned char *int1_offset
+ * axis :
+ * SMI130_GYRO_AUTO_OFFSET -> 1
+ * SMI130_GYRO_FAST_OFFSET -> 2
+ * int2_offset :
+ * Disable -> 0
+ * Enable -> 1
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_int1_offset(unsigned char axis,
+unsigned char *int1_offset)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (axis) {
+ case SMI130_GYRO_FAST_OFFSET:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MAP_1_INT1_FAST_OFFSET__REG, &v_data_u8r, 1);
+ *int1_offset = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_MAP_1_INT1_FAST_OFFSET);
+ break;
+ case SMI130_GYRO_AUTO_OFFSET:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MAP_1_INT1_AUTO_OFFSET__REG, &v_data_u8r, 1);
+ *int1_offset = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_MAP_1_INT1_AUTO_OFFSET);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set fast offset and auto
+ * offset Interrupt1
+ *
+ *
+ *
+ *
+ *\param unsigned char axis,unsigned char *int1_offset
+ * axis :
+ * SMI130_GYRO_AUTO_OFFSET -> 1
+ * SMI130_GYRO_FAST_OFFSET -> 2
+ * int2_offset :
+ * Disable -> 0
+ * Enable -> 1
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_int1_offset(unsigned char axis,
+unsigned char int1_offset)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (axis) {
+ case SMI130_GYRO_FAST_OFFSET:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MAP_1_INT1_FAST_OFFSET__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_MAP_1_INT1_FAST_OFFSET, int1_offset);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MAP_1_INT1_FAST_OFFSET__REG, &v_data_u8r, 1);
+ break;
+ case SMI130_GYRO_AUTO_OFFSET:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MAP_1_INT1_AUTO_OFFSET__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_MAP_1_INT1_AUTO_OFFSET, int1_offset);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MAP_1_INT1_AUTO_OFFSET__REG, &v_data_u8r, 1);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get status of FIFO Interrupt
+ *
+ *
+ *
+ *
+ *\param unsigned char *int_fifo : Address of int_fifo
+ * Pointer to a variable passed as a parameter
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_int_fifo(unsigned char *int_fifo)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_STATUS1_FIFO_INT__REG, &v_data_u8r, 1);
+ *int_fifo = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_STATUS1_FIFO_INT);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get FIFO Interrupt2
+ *
+ *
+ *
+ *
+ *\param unsigned char *int_fifo
+ * int_fifo :
+ * Disable -> 0
+ * Enable -> 1
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_int2_fifo(unsigned char *int_fifo)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MAP_1_INT2_FIFO__REG, &v_data_u8r, 1);
+ *int_fifo = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_MAP_1_INT2_FIFO);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get FIFO Interrupt1
+ *
+ *
+ *
+ *
+ *\param unsigned char *int_fifo
+ * int_fifo :
+ * Disable -> 0
+ * Enable -> 1
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_int1_fifo(unsigned char *int_fifo)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MAP_1_INT1_FIFO__REG, &v_data_u8r, 1);
+ *int_fifo = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_MAP_1_INT1_FIFO);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_int_fifo(unsigned char axis,
+unsigned char int_fifo)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (axis) {
+ case SMI130_GYRO_INT1:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MAP_1_INT1_FIFO__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_MAP_1_INT1_FIFO, int_fifo);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MAP_1_INT1_FIFO__REG, &v_data_u8r, 1);
+ break;
+ case SMI130_GYRO_INT2:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MAP_1_INT2_FIFO__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_MAP_1_INT2_FIFO, int_fifo);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MAP_1_INT2_FIFO__REG, &v_data_u8r, 1);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set FIFO Interrupt1
+ *
+ *
+ *
+ *
+ *\param unsigned char *fifo_int1
+ * fifo_int1 :
+ * Disable -> 0
+ * Enable -> 1
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_int1_fifo(unsigned char fifo_int1)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ if (fifo_int1 < C_SMI130_GYRO_Two_U8X) {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MAP_1_INT1_FIFO__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_MAP_1_INT1_FIFO, fifo_int1);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MAP_1_INT1_FIFO__REG, &v_data_u8r, 1);
+ } else {
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set FIFO Interrupt2
+ *
+ *
+ *
+ *
+ *\param unsigned char *fifo_int2
+ * fifo_int2 :
+ * Disable -> 0
+ * Enable -> 1
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_int2_fifo(unsigned char fifo_int2)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ if (fifo_int2 < C_SMI130_GYRO_Two_U8X) {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MAP_1_INT2_FIFO__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_MAP_1_INT2_FIFO, fifo_int2);
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MAP_1_INT2_FIFO__REG, &v_data_u8r, 1);
+ } else {
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get High Interrupt2
+ *
+ *
+ *
+ *
+ *\param unsigned char *int2_high : Address of int2_high
+ * Pointer to a variable passed as a parameter
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_int2_high(unsigned char *int2_high)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_MAP_2_INT2_HIGH__REG, &v_data_u8r, 1);
+ *int2_high = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_MAP_2_INT2_HIGH);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get High Interrupt2
+ *
+ *
+ *
+ *
+ *\param unsigned char int2_high
+ * 0 -> Disable
+ * 1 -> Enable
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_int2_high(unsigned char int2_high)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_MAP_2_INT2_HIGH__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_MAP_2_INT2_HIGH, int2_high);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_MAP_2_INT2_HIGH__REG, &v_data_u8r, 1);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get Any Interrupt2
+ *
+ *
+ *
+ *
+ *\param unsigned char *int2_any : Address of int2_any
+ * Pointer to a variable passed as a parameter
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_int2_any(unsigned char *int2_any)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_MAP_2_INT2_ANY__REG, &v_data_u8r, 1);
+ *int2_any = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_MAP_2_INT2_ANY);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set Any Interrupt2
+ *
+ *
+ *
+ *
+ *\param unsigned char int2_any
+ * 0 -> Disable
+ * 1 -> Enable
+ *
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_int2_any(unsigned char int2_any)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_MAP_2_INT2_ANY__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_MAP_2_INT2_ANY, int2_any);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_MAP_2_INT2_ANY__REG, &v_data_u8r, 1);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get slow offset and fast
+ * offset unfilt data
+ *
+ *
+ *
+ *\param unsigned char param,unsigned char *offset_unfilt
+ * param :
+ * SMI130_GYRO_SLOW_OFFSET -> 0
+ * SMI130_GYRO_FAST_OFFSET -> 2
+ * offset_unfilt: Enable -> 1
+ * Disable -> 0
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_offset_unfilt(unsigned char param,
+unsigned char *offset_unfilt)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (param) {
+ case SMI130_GYRO_SLOW_OFFSET:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_0_ADDR_SLOW_OFFSET_UNFILT__REG,
+ &v_data_u8r, 1);
+ *offset_unfilt = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_0_ADDR_SLOW_OFFSET_UNFILT);
+ break;
+ case SMI130_GYRO_FAST_OFFSET:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_1_ADDR_FAST_OFFSET_UNFILT__REG,
+ &v_data_u8r, 1);
+ *offset_unfilt = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_1_ADDR_FAST_OFFSET_UNFILT);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set slow offset and fast
+ * offset unfilt data
+ *
+ *
+ *
+ *
+ *\param unsigned char param,unsigned char *offset_unfilt
+ * param :
+ * SMI130_GYRO_SLOW_OFFSET -> 0
+ * SMI130_GYRO_FAST_OFFSET -> 2
+ * offset_unfilt: Enable -> 1
+ * Disable -> 0
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_offset_unfilt(unsigned char param,
+unsigned char offset_unfilt)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (param) {
+ case SMI130_GYRO_SLOW_OFFSET:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_0_ADDR_SLOW_OFFSET_UNFILT__REG,
+ &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_0_ADDR_SLOW_OFFSET_UNFILT, offset_unfilt);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_0_ADDR_SLOW_OFFSET_UNFILT__REG,
+ &v_data_u8r, 1);
+ break;
+ case SMI130_GYRO_FAST_OFFSET:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_1_ADDR_FAST_OFFSET_UNFILT__REG,
+ &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_1_ADDR_FAST_OFFSET_UNFILT, offset_unfilt);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_1_ADDR_FAST_OFFSET_UNFILT__REG,
+ &v_data_u8r, 1);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get Tap, High, Constant, Any,
+ * Shake unfilt data
+ *
+ *
+ *
+ *
+ *\param unsigned char param,unsigned char *unfilt_data
+ * param :
+ *
+ * SMI130_GYRO_HIGH_UNFILT_DATA -> 1
+ * SMI130_GYRO_ANY_UNFILT_DATA -> 3
+ *
+ * unfilt_data: Enable -> 1
+ * Disable -> 0
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_unfilt_data(unsigned char param,
+unsigned char *unfilt_data)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (param) {
+ case SMI130_GYRO_HIGH_UNFILT_DATA:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_0_ADDR_HIGH_UNFILT_DATA__REG,
+ &v_data_u8r, 1);
+ *unfilt_data = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_0_ADDR_HIGH_UNFILT_DATA);
+ break;
+ case SMI130_GYRO_ANY_UNFILT_DATA:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_0_ADDR_ANY_UNFILT_DATA__REG, &v_data_u8r, 1);
+ *unfilt_data = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_0_ADDR_ANY_UNFILT_DATA);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set Tap, High, Constant, Any,
+ * Shake unfilt data
+ *
+ *
+ *
+ *
+ *\param unsigned char param,unsigned char *unfilt_data
+ * param :
+ *
+ * SMI130_GYRO_HIGH_UNFILT_DATA -> 1
+ * SMI130_GYRO_ANY_UNFILT_DATA -> 3
+ *
+ * unfilt_data: Enable -> 1
+ * Disable -> 0
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_unfilt_data(unsigned char param,
+unsigned char unfilt_data)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (param) {
+ case SMI130_GYRO_HIGH_UNFILT_DATA:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_0_ADDR_HIGH_UNFILT_DATA__REG,
+ &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_0_ADDR_HIGH_UNFILT_DATA, unfilt_data);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_0_ADDR_HIGH_UNFILT_DATA__REG,
+ &v_data_u8r, 1);
+ break;
+ case SMI130_GYRO_ANY_UNFILT_DATA:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_0_ADDR_ANY_UNFILT_DATA__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_0_ADDR_ANY_UNFILT_DATA, unfilt_data);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_0_ADDR_ANY_UNFILT_DATA__REG, &v_data_u8r, 1);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get Any Threshold
+ *
+ *
+ *
+ *
+ *\param unsigned char *any_th : Address of any_th
+ * Pointer to a variable passed as a parameter
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_any_th(unsigned char *any_th)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_1_ADDR_ANY_TH__REG, &v_data_u8r, 1);
+ *any_th = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_1_ADDR_ANY_TH);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set Any Threshold
+ *
+ *
+ *
+ *
+ *\param unsigned char any_th:
+ * Value to be written passed as a parameter
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_any_th(unsigned char any_th)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_1_ADDR_ANY_TH__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_1_ADDR_ANY_TH, any_th);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_1_ADDR_ANY_TH__REG, &v_data_u8r, 1);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get Awake Duration
+ *
+ *
+ *
+ *
+ *\param unsigned char *awake_dur : Address of awake_dur
+ * Pointer to a variable passed as a parameter
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_awake_dur(unsigned char *awake_dur)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_2_ADDR_AWAKE_DUR__REG, &v_data_u8r, 1);
+ *awake_dur = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_2_ADDR_AWAKE_DUR);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set Awake Duration
+ *
+ *
+ *
+ *
+ *\param unsigned char awake_dur:
+ * Value to be written passed as a parameter
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************
+ * Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_awake_dur(unsigned char awake_dur)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_2_ADDR_AWAKE_DUR__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_2_ADDR_AWAKE_DUR, awake_dur);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_2_ADDR_AWAKE_DUR__REG, &v_data_u8r, 1);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get Any Duration Sample
+ *
+ *
+ *
+ *
+ *\param unsigned char *dursample : Address of dursample
+ * Pointer to a variable passed as a parameter
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_any_dursample(unsigned char *dursample)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_2_ADDR_ANY_DURSAMPLE__REG, &v_data_u8r, 1);
+ *dursample = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_2_ADDR_ANY_DURSAMPLE);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set Any Duration Sample
+ *
+ *
+ *
+ *
+ *\param unsigned char dursample:
+ * Value to be written passed as a parameter
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_any_dursample(unsigned char dursample)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_2_ADDR_ANY_DURSAMPLE__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_2_ADDR_ANY_DURSAMPLE, dursample);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_2_ADDR_ANY_DURSAMPLE__REG, &v_data_u8r, 1);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get the status of Any Enable
+ * Channel X,Y,Z
+ *
+ *
+ *
+ *
+ *\param unsigned char channel,unsigned char *data
+ * channel :
+ * SMI130_GYRO_X_AXIS -> 0
+ * SMI130_GYRO_Y_AXIS -> 1
+ * SMI130_GYRO_Z_AXIS -> 2
+ * data :
+ * Enable -> 1
+ * disable -> 0
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_any_en_ch(unsigned char channel,
+unsigned char *data)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (channel) {
+ case SMI130_GYRO_X_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_2_ADDR_ANY_EN_X__REG, &v_data_u8r, 1);
+ *data = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_2_ADDR_ANY_EN_X);
+ break;
+ case SMI130_GYRO_Y_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_2_ADDR_ANY_EN_Y__REG, &v_data_u8r, 1);
+ *data = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_2_ADDR_ANY_EN_Y);
+ break;
+ case SMI130_GYRO_Z_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_2_ADDR_ANY_EN_Z__REG, &v_data_u8r, 1);
+ *data = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_2_ADDR_ANY_EN_Z);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set the status of Any Enable
+ * Channel X,Y,Z
+ *
+ *
+ *
+ *
+ *\param unsigned char channel,unsigned char *data
+ * channel :
+ * SMI130_GYRO_X_AXIS -> 0
+ * SMI130_GYRO_Y_AXIS -> 1
+ * SMI130_GYRO_Z_AXIS -> 2
+ * data :
+ * Enable -> 1
+ * disable -> 0
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_any_en_ch(unsigned char channel,
+unsigned char data)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (channel) {
+ case SMI130_GYRO_X_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_2_ADDR_ANY_EN_X__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_2_ADDR_ANY_EN_X, data);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_2_ADDR_ANY_EN_X__REG, &v_data_u8r, 1);
+ break;
+ case SMI130_GYRO_Y_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_2_ADDR_ANY_EN_Y__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_2_ADDR_ANY_EN_Y, data);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_2_ADDR_ANY_EN_Y__REG, &v_data_u8r, 1);
+ break;
+ case SMI130_GYRO_Z_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_2_ADDR_ANY_EN_Z__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_2_ADDR_ANY_EN_Z, data);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_2_ADDR_ANY_EN_Z__REG, &v_data_u8r, 1);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get the status of FIFO WM
+ * Enable
+ *
+ *
+ *
+ *
+ *\param unsigned char *fifo_wn_en
+ * Enable -> 1
+ * Disable -> 0
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_fifo_watermark_enable(
+unsigned char *fifo_wn_en)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_4_FIFO_WM_EN__REG, &v_data_u8r, 1);
+ *fifo_wn_en = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_4_FIFO_WM_EN);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set FIFO WM Enable
+ *
+ *
+ *
+ *
+ *\param unsigned char *fifo_wn_en
+ * Enable -> 1
+ * Disable -> 0
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_fifo_watermark_enable(
+unsigned char fifo_wn_en)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ if (fifo_wn_en < C_SMI130_GYRO_Two_U8X) {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_4_FIFO_WM_EN__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_INT_4_FIFO_WM_EN, fifo_wn_en);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_INT_4_FIFO_WM_EN__REG, &v_data_u8r, 1);
+ } else {
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set the Interrupt Reset
+ *
+ *
+ *
+ *
+ *\param unsigned char reset_int
+ * 1 -> Reset All Interrupts
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_reset_int(unsigned char reset_int)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_RST_LATCH_ADDR_RESET_INT__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_RST_LATCH_ADDR_RESET_INT, reset_int);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_RST_LATCH_ADDR_RESET_INT__REG, &v_data_u8r, 1);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set the Offset Reset
+ *
+ *
+ *
+ *
+ *\param unsigned char offset_reset
+ * 1 -> Resets All the Offsets
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_offset_reset(
+unsigned char offset_reset)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_RST_LATCH_ADDR_OFFSET_RESET__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_RST_LATCH_ADDR_OFFSET_RESET, offset_reset);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_RST_LATCH_ADDR_OFFSET_RESET__REG, &v_data_u8r, 1);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get the Latch Status
+ *
+ *
+ *
+ *
+ *\param unsigned char *latch_status : Address of latch_status
+ * Pointer to a variable passed as a parameter
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_latch_status(
+unsigned char *latch_status)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_RST_LATCH_ADDR_LATCH_STATUS__REG, &v_data_u8r, 1);
+ *latch_status = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_RST_LATCH_ADDR_LATCH_STATUS);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set the Latch Status
+ *
+ *
+ *
+ *
+ *\param unsigned char latch_status:
+ * Value to be written passed as a parameter
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_latch_status(
+unsigned char latch_status)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_RST_LATCH_ADDR_LATCH_STATUS__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_RST_LATCH_ADDR_LATCH_STATUS, latch_status);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_RST_LATCH_ADDR_LATCH_STATUS__REG, &v_data_u8r, 1);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get the Latch Interrupt
+ *
+ *
+ *
+ *
+ *\param unsigned char *latch_int : Address of latch_int
+ * Pointer to a variable passed as a parameter
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_latch_int(unsigned char *latch_int)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_RST_LATCH_ADDR_LATCH_INT__REG, &v_data_u8r, 1);
+ *latch_int = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_RST_LATCH_ADDR_LATCH_INT);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set the Latch Interrupt
+ *
+ *
+ *
+ *
+ *\param unsigned char latch_int:
+ * Value to be written passed as a parameter
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_latch_int(unsigned char latch_int)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_RST_LATCH_ADDR_LATCH_INT__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_RST_LATCH_ADDR_LATCH_INT, latch_int);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_RST_LATCH_ADDR_LATCH_INT__REG, &v_data_u8r, 1);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get the status of High
+ * Hysteresis X,Y,Z
+ *
+ *
+ *
+ *
+ *\param unsigned char channel,unsigned char *high_hy
+ * channel :
+ * SMI130_GYRO_X_AXIS -> 0
+ * SMI130_GYRO_Y_AXIS -> 1
+ * SMI130_GYRO_Z_AXIS -> 2
+ * high_hy :
+ * Enable -> 1
+ * disable -> 0
+ *
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_high_hy(unsigned char channel,
+unsigned char *high_hy)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (channel) {
+ case SMI130_GYRO_X_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_HY_X__REG, &v_data_u8r, 1);
+ *high_hy = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_HIGH_HY_X);
+ break;
+ case SMI130_GYRO_Y_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_HY_Y__REG, &v_data_u8r, 1);
+ *high_hy = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_HIGH_HY_Y);
+ break;
+ case SMI130_GYRO_Z_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_HY_Z__REG, &v_data_u8r, 1);
+ *high_hy = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_HIGH_HY_Z);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set the status of High
+ * Hysteresis X,Y,Z
+ *
+ *
+ *
+ *
+ *\param unsigned char channel,unsigned char *high_hy
+ * channel :
+ * SMI130_GYRO_X_AXIS -> 0
+ * SMI130_GYRO_Y_AXIS -> 1
+ * SMI130_GYRO_Z_AXIS -> 2
+ * high_hy :
+ * Enable -> 1
+ * disable -> 0
+ *
+ *
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_high_hy(unsigned char channel,
+unsigned char high_hy)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (channel) {
+ case SMI130_GYRO_X_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_HY_X__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_HIGH_HY_X, high_hy);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_HY_X__REG, &v_data_u8r, 1);
+ break;
+ case SMI130_GYRO_Y_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_HY_Y__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_HIGH_HY_Y, high_hy);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_HY_Y__REG, &v_data_u8r, 1);
+ break;
+ case SMI130_GYRO_Z_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_HY_Z__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_HIGH_HY_Z, high_hy);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_HY_Z__REG, &v_data_u8r, 1);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get the status of High
+ * Threshold X,Y,Z
+ *
+ *
+ *
+ *
+ *\param unsigned char channel,unsigned char *high_th
+ * channel :
+ * SMI130_GYRO_X_AXIS -> 0
+ * SMI130_GYRO_Y_AXIS -> 1
+ * SMI130_GYRO_Z_AXIS -> 2
+ * high_th :
+ * Enable -> 1
+ * disable -> 0
+ *
+ *
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_high_th(unsigned char channel,
+unsigned char *high_th)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (channel) {
+ case SMI130_GYRO_X_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_TH_X__REG, &v_data_u8r, 1);
+ *high_th = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_HIGH_TH_X);
+ break;
+ case SMI130_GYRO_Y_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_TH_Y__REG, &v_data_u8r, 1);
+ *high_th = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_HIGH_TH_Y);
+ break;
+ case SMI130_GYRO_Z_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_TH_Z__REG, &v_data_u8r, 1);
+ *high_th = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_HIGH_TH_Z);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set the status of High
+ * Threshold X,Y,Z
+ *
+ *
+ *
+ *
+ *\param unsigned char channel,unsigned char *high_th
+ * channel :
+ * SMI130_GYRO_X_AXIS -> 0
+ * SMI130_GYRO_Y_AXIS -> 1
+ * SMI130_GYRO_Z_AXIS -> 2
+ * high_th :
+ * Enable -> 1
+ * disable -> 0
+ *
+ *
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_high_th(unsigned char channel,
+unsigned char high_th)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (channel) {
+ case SMI130_GYRO_X_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_TH_X__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_HIGH_TH_X, high_th);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_TH_X__REG, &v_data_u8r, 1);
+ break;
+ case SMI130_GYRO_Y_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_TH_Y__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_HIGH_TH_Y, high_th);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_TH_Y__REG, &v_data_u8r, 1);
+ break;
+ case SMI130_GYRO_Z_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_TH_Z__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_HIGH_TH_Z, high_th);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_TH_Z__REG, &v_data_u8r, 1);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get the status of High Enable
+ * Channel X,Y,Z
+ *
+ *
+ *
+ *
+ *\param unsigned char channel,unsigned char *high_en
+ * channel :
+ * SMI130_GYRO_X_AXIS -> 0
+ * SMI130_GYRO_Y_AXIS -> 1
+ * SMI130_GYRO_Z_AXIS -> 2
+ * high_en :
+ * Enable -> 1
+ * disable -> 0
+ *
+ *
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_high_en_ch(unsigned char channel,
+unsigned char *high_en)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (channel) {
+ case SMI130_GYRO_X_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_EN_X__REG, &v_data_u8r, 1);
+ *high_en = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_HIGH_EN_X);
+ break;
+ case SMI130_GYRO_Y_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_EN_Y__REG, &v_data_u8r, 1);
+ *high_en = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_HIGH_EN_Y);
+ break;
+ case SMI130_GYRO_Z_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_EN_Z__REG, &v_data_u8r, 1);
+ *high_en = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_HIGH_EN_Z);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set the status of High Enable
+ * Channel X,Y,Z
+ *
+ *
+ *
+ *
+ *\param unsigned char channel,unsigned char *high_en
+ * channel :
+ * SMI130_GYRO_X_AXIS -> 0
+ * SMI130_GYRO_Y_AXIS -> 1
+ * SMI130_GYRO_Z_AXIS -> 2
+ * high_en :
+ * Enable -> 1
+ * disable -> 0
+ *
+ *
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_high_en_ch(unsigned char channel,
+unsigned char high_en)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (channel) {
+ case SMI130_GYRO_X_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_EN_X__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_HIGH_EN_X, high_en);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_EN_X__REG, &v_data_u8r, 1);
+ break;
+ case SMI130_GYRO_Y_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_EN_Y__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_HIGH_EN_Y, high_en);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_EN_Y__REG, &v_data_u8r, 1);
+ break;
+ case SMI130_GYRO_Z_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_EN_Z__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_HIGH_EN_Z, high_en);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_EN_Z__REG, &v_data_u8r, 1);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get High Duration
+ *
+ *
+ *
+ *
+ *\param unsigned char channel,unsigned char *high_dur
+ * channel :
+ * SMI130_GYRO_X_AXIS -> 0
+ * SMI130_GYRO_Y_AXIS -> 1
+ * SMI130_GYRO_Z_AXIS -> 2
+ * *high_dur : Address of high_bw
+ * Pointer to a variable passed as a
+ * parameter
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_high_dur_ch(unsigned char channel,
+unsigned char *high_dur)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (channel) {
+ case SMI130_GYRO_X_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_DUR_X_ADDR, &v_data_u8r, 1);
+ *high_dur = v_data_u8r;
+ break;
+ case SMI130_GYRO_Y_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_DUR_Y_ADDR, &v_data_u8r, 1);
+ *high_dur = v_data_u8r;
+ break;
+ case SMI130_GYRO_Z_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_DUR_Z_ADDR, &v_data_u8r, 1);
+ *high_dur = v_data_u8r;
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set High Duration
+ *
+ *
+ *
+ *
+ *\param unsigned char channel,unsigned char *high_dur
+ * channel :
+ * SMI130_GYRO_X_AXIS -> 0
+ * SMI130_GYRO_Y_AXIS -> 1
+ * SMI130_GYRO_Z_AXIS -> 2
+ * high_dur : Value to be written passed as a parameter
+ *
+ *
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_high_dur_ch(unsigned char channel,
+unsigned char high_dur)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (channel) {
+ case SMI130_GYRO_X_AXIS:
+ v_data_u8r = high_dur;
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_DUR_X_ADDR, &v_data_u8r, 1);
+ break;
+ case SMI130_GYRO_Y_AXIS:
+ v_data_u8r = high_dur;
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_DUR_Y_ADDR, &v_data_u8r, 1);
+ break;
+ case SMI130_GYRO_Z_AXIS:
+ v_data_u8r = high_dur;
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_HIGH_DUR_Z_ADDR, &v_data_u8r, 1);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get Slow Offset Threshold
+ *
+ *
+ *
+ *
+ *\param unsigned char *offset_th : Address of offset_th
+ * Pointer to a variable passed as a parameter
+
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_slow_offset_th(
+unsigned char *offset_th)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_SLOW_OFFSET_TH__REG, &v_data_u8r, 1);
+ *offset_th = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_SLOW_OFFSET_TH);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set Slow Offset Threshold
+ *
+ *
+ *
+ *
+ *\param unsigned char offset_th:
+ * Value to be written passed as a parameter
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_slow_offset_th(unsigned char offset_th)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_SLOW_OFFSET_TH__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_SLOW_OFFSET_TH, offset_th);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_SLOW_OFFSET_TH__REG, &v_data_u8r, 1);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get Slow Offset Duration
+ *
+ *
+ *
+ *
+ *\param unsigned char *offset_dur : Address of offset_dur
+ * Pointer to a variable passed as a parameter
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_slow_offset_dur(
+unsigned char *offset_dur)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_SLOW_OFFSET_DUR__REG, &v_data_u8r, 1);
+ *offset_dur = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_SLOW_OFFSET_DUR);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set Slow Offset Duration
+ *
+ *
+ *
+ *
+ *\param unsigned char offset_dur:
+ * Value to be written passed as a parameter
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_slow_offset_dur(
+unsigned char offset_dur)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_SLOW_OFFSET_DUR__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_SLOW_OFFSET_DUR, offset_dur);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_SLOW_OFFSET_DUR__REG, &v_data_u8r, 1);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get Slow Offset Enable channel
+ * X,Y,Z
+ *
+ *
+ *
+ *
+ *\param unsigned char channel,unsigned char *slow_offset
+ * channel :
+ * SMI130_GYRO_X_AXIS -> 0
+ * SMI130_GYRO_Y_AXIS -> 1
+ * SMI130_GYRO_Z_AXIS -> 2
+ * slow_offset :
+ * Enable -> 1
+ * disable -> 0
+ *
+ *
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_slow_offset_en_ch(
+unsigned char channel, unsigned char *slow_offset)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (channel) {
+ case SMI130_GYRO_X_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_SLOW_OFFSET_EN_X__REG, &v_data_u8r, 1);
+ *slow_offset = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_SLOW_OFFSET_EN_X);
+ break;
+ case SMI130_GYRO_Y_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_SLOW_OFFSET_EN_Y__REG, &v_data_u8r, 1);
+ *slow_offset = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_SLOW_OFFSET_EN_Y);
+ break;
+ case SMI130_GYRO_Z_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_SLOW_OFFSET_EN_Z__REG, &v_data_u8r, 1);
+ *slow_offset = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_SLOW_OFFSET_EN_Z);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set Slow Offset Enable channel
+ * X,Y,Z
+ *
+ *
+ *
+ *
+ *\param unsigned char channel,unsigned char *slow_offset
+ * channel :
+ * SMI130_GYRO_X_AXIS -> 0
+ * SMI130_GYRO_Y_AXIS -> 1
+ * SMI130_GYRO_Z_AXIS -> 2
+ * slow_offset :
+ * Enable -> 1
+ * disable -> 0
+ *
+ *
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_slow_offset_en_ch(
+unsigned char channel, unsigned char slow_offset)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (channel) {
+ case SMI130_GYRO_X_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_SLOW_OFFSET_EN_X__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_SLOW_OFFSET_EN_X, slow_offset);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_SLOW_OFFSET_EN_X__REG, &v_data_u8r, 1);
+ break;
+ case SMI130_GYRO_Y_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_SLOW_OFFSET_EN_Y__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_SLOW_OFFSET_EN_Y, slow_offset);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_SLOW_OFFSET_EN_Y__REG, &v_data_u8r, 1);
+ break;
+ case SMI130_GYRO_Z_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_SLOW_OFFSET_EN_Z__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_SLOW_OFFSET_EN_Z,
+ slow_offset);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_SLOW_OFFSET_EN_Z__REG, &v_data_u8r, 1);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get Fast Offset WordLength and
+ * Auto Offset WordLength
+ *
+ *
+ *
+ *
+ *\param unsigned char channel,unsigned char *offset_wl
+ * channel :
+ * SMI130_GYRO_AUTO_OFFSET_WL -> 0
+ * SMI130_GYRO_FAST_OFFSET_WL -> 1
+ * *offset_wl : Address of high_bw
+ * Pointer to a variable passed as a
+ * parameter
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_offset_wl(unsigned char channel,
+unsigned char *offset_wl)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (channel) {
+ case SMI130_GYRO_AUTO_OFFSET_WL:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_AUTO_OFFSET_WL__REG, &v_data_u8r, 1);
+ *offset_wl = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_AUTO_OFFSET_WL);
+ break;
+ case SMI130_GYRO_FAST_OFFSET_WL:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_FAST_OFFSET_WL__REG, &v_data_u8r, 1);
+ *offset_wl = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_FAST_OFFSET_WL);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set Fast Offset WordLength and
+ * Auto Offset WordLength
+ *
+ *
+ *
+ *
+ *\param unsigned char channel,unsigned char *offset_wl
+ * channel :
+ * SMI130_GYRO_AUTO_OFFSET_WL -> 0
+ * SMI130_GYRO_FAST_OFFSET_WL -> 1
+ * offset_wl : Value to be written passed as a parameter
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_offset_wl(
+unsigned char channel, unsigned char offset_wl)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (channel) {
+ case SMI130_GYRO_AUTO_OFFSET_WL:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_AUTO_OFFSET_WL__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_AUTO_OFFSET_WL, offset_wl);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_AUTO_OFFSET_WL__REG, &v_data_u8r, 1);
+ break;
+ case SMI130_GYRO_FAST_OFFSET_WL:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_FAST_OFFSET_WL__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_FAST_OFFSET_WL, offset_wl);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_FAST_OFFSET_WL__REG, &v_data_u8r, 1);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to enable fast offset
+ *
+ *
+ *
+ *
+* \param smi130_gyro_enable_fast_offset
+ * Enable -> 1
+ * Disable -> 0
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_enable_fast_offset()
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_FAST_OFFSET_EN__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_FAST_OFFSET_EN, 1);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_FAST_OFFSET_EN__REG, &v_data_u8r, 1);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API read the Fast offset en status from the
+ * 0x32h of 0 to 2 bits.
+ *
+ *
+ *
+ *
+ *\param unsigned char *fast_offset
+ * Pointer to a variable passed as a parameter
+ *
+ *
+ *
+ * \return Communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_fast_offset_en_ch(
+unsigned char *fast_offset)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_FAST_OFFSET_EN_XYZ__REG, &v_data_u8r, 1);
+ *fast_offset = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_FAST_OFFSET_EN_XYZ);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API writes the Fast offset enable bit based
+ * on the Channel selection 0x32h of (0 to 2 bits)
+ *
+ *
+ *
+ *
+* \param unsigned char channel,unsigned char fast_offset
+ *
+ * channel --> SMI130_GYRO_X_AXIS,SMI130_GYRO_Y_AXIS,SMI130_GYRO_Z_AXIS
+ * fast_offset --> 0 - Disable
+ * 1 - Enable
+ *
+ *
+ *
+ * \return Communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_fast_offset_en_ch(
+unsigned char channel, unsigned char fast_offset)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (channel) {
+ case SMI130_GYRO_X_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_FAST_OFFSET_EN_X__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_FAST_OFFSET_EN_X, fast_offset);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_FAST_OFFSET_EN_X__REG, &v_data_u8r, 1);
+ break;
+ case SMI130_GYRO_Y_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_FAST_OFFSET_EN_Y__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_FAST_OFFSET_EN_Y, fast_offset);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_FAST_OFFSET_EN_Y__REG, &v_data_u8r, 1);
+ break;
+ case SMI130_GYRO_Z_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_FAST_OFFSET_EN_Z__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_FAST_OFFSET_EN_Z, fast_offset);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_FAST_OFFSET_EN_Z__REG, &v_data_u8r, 1);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get the status of nvm program
+ * remain
+ *
+ *
+ *
+ *
+ *\param unsigned char *nvm_remain
+ *
+ *
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_nvm_remain(unsigned char *nvm_remain)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_REMAIN__REG, &v_data_u8r, 1);
+ *nvm_remain = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_REMAIN);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set the status of nvm load
+ *
+ *
+ *
+ *
+ *\param unsigned char nvm_load
+ * 1 -> load offset value from NVM
+ * 0 -> no action
+ *
+ *
+ *
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_nvm_load(unsigned char nvm_load)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_LOAD__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_LOAD, nvm_load);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_LOAD__REG, &v_data_u8r, 1);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get the status of nvmprogram
+ * ready
+ *
+ *
+ *
+ *
+ *\param unsigned char *nvm_rdy
+ * 1 -> program seq finished
+ * 0 -> program seq in progress
+ *
+ *
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_nvm_rdy(unsigned char *nvm_rdy)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_RDY__REG, &v_data_u8r, 1);
+ *nvm_rdy = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_RDY);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set the status of nvm program
+ * trigger
+ *
+ *
+ *
+ *
+ *\param unsigned char trig
+ * 1 -> trig program seq (wo)
+ * 0 -> No Action
+ *
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_nvm_prog_trig(unsigned char prog_trig)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_PROG_TRIG__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_PROG_TRIG, prog_trig);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_PROG_TRIG__REG, &v_data_u8r, 1);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get the status of nvm program
+ * mode
+ *
+ *
+ *
+ *
+* \param unsigned char *prog_mode : Address of *prog_mode
+ * 1 -> Enable program mode
+ * 0 -> Disable program mode
+ *
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_nvm_prog_mode(unsigned char *prog_mode)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_PROG_MODE__REG, &v_data_u8r, 1);
+ *prog_mode = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_PROG_MODE);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/******************************************************************************
+ * Description: *//**brief This API is used to set the status of nvmprogram
+ * mode
+ *
+ *
+ *
+ *
+* \param(unsigned char prog_mode)
+ * 1 -> Enable program mode
+ * 0 -> Disable program mode
+ *
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_nvm_prog_mode(unsigned char prog_mode)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_PROG_MODE__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_PROG_MODE, prog_mode);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_PROG_MODE__REG, &v_data_u8r, 1);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get the status of i2c wdt
+ *
+ *
+ *
+ *
+ *\param unsigned char channel,unsigned char *prog_mode
+ * SMI130_GYRO_I2C_WDT_SEL 1
+ * SMI130_GYRO_I2C_WDT_EN 0
+ * *prog_mode : Address of prog_mode
+ * Pointer to a variable passed as a parameter
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_i2c_wdt(unsigned char i2c_wdt,
+unsigned char *prog_mode)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (i2c_wdt) {
+ case SMI130_GYRO_I2C_WDT_EN:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_BGW_SPI3_WDT_ADDR_I2C_WDT_EN__REG,
+ &v_data_u8r, 1);
+ *prog_mode = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_BGW_SPI3_WDT_ADDR_I2C_WDT_EN);
+ break;
+ case SMI130_GYRO_I2C_WDT_SEL:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_BGW_SPI3_WDT_ADDR_I2C_WDT_SEL__REG,
+ &v_data_u8r, 1);
+ *prog_mode = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_BGW_SPI3_WDT_ADDR_I2C_WDT_SEL);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set the status of i2c wdt
+ *
+ *
+ *
+ *
+ *\param unsigned char channel,unsigned char prog_mode
+ * SMI130_GYRO_I2C_WDT_SEL 1
+ * SMI130_GYRO_I2C_WDT_EN 0
+ * prog_mode : Value to be written passed as a parameter
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_i2c_wdt(unsigned char i2c_wdt,
+unsigned char prog_mode)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (i2c_wdt) {
+ case SMI130_GYRO_I2C_WDT_EN:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_BGW_SPI3_WDT_ADDR_I2C_WDT_EN__REG,
+ &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_BGW_SPI3_WDT_ADDR_I2C_WDT_EN, prog_mode);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_BGW_SPI3_WDT_ADDR_I2C_WDT_EN__REG,
+ &v_data_u8r, 1);
+ break;
+ case SMI130_GYRO_I2C_WDT_SEL:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_BGW_SPI3_WDT_ADDR_I2C_WDT_SEL__REG,
+ &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_BGW_SPI3_WDT_ADDR_I2C_WDT_SEL, prog_mode);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_BGW_SPI3_WDT_ADDR_I2C_WDT_SEL__REG,
+ &v_data_u8r, 1);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get the status of spi3
+ *
+ *
+ *
+ *
+* \param unsigned char *spi3 : Address of spi3
+ * Pointer to a variable passed as a parameter
+ *
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_spi3(unsigned char *spi3)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_BGW_SPI3_WDT_ADDR_SPI3__REG, &v_data_u8r, 1);
+ *spi3 = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_BGW_SPI3_WDT_ADDR_SPI3);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set the status of spi3
+ *
+ *
+ *
+ *
+ *\param unsigned char spi3
+ *
+ *
+ *
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_spi3(unsigned char spi3)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_BGW_SPI3_WDT_ADDR_SPI3__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_BGW_SPI3_WDT_ADDR_SPI3, spi3);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_BGW_SPI3_WDT_ADDR_SPI3__REG, &v_data_u8r, 1);
+ }
+ return comres;
+}
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_fifo_tag(unsigned char *tag)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_FIFO_CGF1_ADDR_TAG__REG, &v_data_u8r, 1);
+ *tag = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_FIFO_CGF1_ADDR_TAG);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set the status of Tag
+ *
+ *
+ *
+ *
+ *\param unsigned char tag
+ * Enable -> 1
+ * Disable -> 0
+ *
+ *
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_fifo_tag(unsigned char tag)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ if (tag < C_SMI130_GYRO_Two_U8X) {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_FIFO_CGF1_ADDR_TAG__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_FIFO_CGF1_ADDR_TAG, tag);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_FIFO_CGF1_ADDR_TAG__REG, &v_data_u8r, 1);
+ } else {
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get Water Mark Level
+ *
+ *
+ *
+ *
+ *\param unsigned char *water_mark_level : Address of water_mark_level
+ * Pointer to a variable passed as a parameter
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_fifo_watermarklevel(
+unsigned char *water_mark_level)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_FIFO_CGF1_ADDR_WML__REG, &v_data_u8r, 1);
+ *water_mark_level = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_FIFO_CGF1_ADDR_WML);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set Water Mark Level
+ *
+ *
+ *
+ *
+ *\param unsigned char water_mark_level:
+ * Value to be written passed as a parameter
+
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_fifo_watermarklevel(
+unsigned char water_mark_level)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ if (water_mark_level < C_SMI130_GYRO_OneTwentyEight_U8X) {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_FIFO_CGF1_ADDR_WML__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_FIFO_CGF1_ADDR_WML, water_mark_level);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_FIFO_CGF1_ADDR_WML__REG, &v_data_u8r, 1);
+ } else {
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get the status of offset
+ *
+ *
+ *
+ *
+ *\param unsigned char axis,unsigned char *offset
+ * axis ->
+ * SMI130_GYRO_X_AXIS -> 0
+ * SMI130_GYRO_Y_AXIS -> 1
+ * SMI130_GYRO_Z_AXIS -> 2
+ * offset -> Any valid value
+ *
+ *
+ *
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_offset(unsigned char axis,
+SMI130_GYRO_S16 *offset)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data1_u8r = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data2_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (axis) {
+ case SMI130_GYRO_X_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_TRIM_GP0_ADDR_OFFSET_X__REG, &v_data1_u8r, 1);
+ v_data1_u8r = SMI130_GYRO_GET_BITSLICE(v_data1_u8r,
+ SMI130_GYRO_TRIM_GP0_ADDR_OFFSET_X);
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_OFC1_ADDR_OFFSET_X__REG, &v_data2_u8r, 1);
+ v_data2_u8r = SMI130_GYRO_GET_BITSLICE(v_data2_u8r,
+ SMI130_GYRO_OFC1_ADDR_OFFSET_X);
+ v_data2_u8r = ((v_data2_u8r <<
+ SMI130_GYRO_SHIFT_2_POSITION) | v_data1_u8r);
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr, SMI130_GYRO_OFC2_ADDR, &v_data1_u8r, 1);
+ *offset = (SMI130_GYRO_S16)((((SMI130_GYRO_S16)
+ ((signed char)v_data1_u8r))
+ << SMI130_GYRO_SHIFT_4_POSITION) | (v_data2_u8r));
+ break;
+ case SMI130_GYRO_Y_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_TRIM_GP0_ADDR_OFFSET_Y__REG, &v_data1_u8r, 1);
+ v_data1_u8r = SMI130_GYRO_GET_BITSLICE(v_data1_u8r,
+ SMI130_GYRO_TRIM_GP0_ADDR_OFFSET_Y);
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_OFC1_ADDR_OFFSET_Y__REG, &v_data2_u8r, 1);
+ v_data2_u8r = SMI130_GYRO_GET_BITSLICE(v_data2_u8r,
+ SMI130_GYRO_OFC1_ADDR_OFFSET_Y);
+ v_data2_u8r = ((v_data2_u8r <<
+ SMI130_GYRO_SHIFT_1_POSITION) | v_data1_u8r);
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_OFC3_ADDR, &v_data1_u8r, 1);
+ *offset = (SMI130_GYRO_S16)((((SMI130_GYRO_S16)
+ ((signed char)v_data1_u8r))
+ << SMI130_GYRO_SHIFT_4_POSITION) | (v_data2_u8r));
+ break;
+ case SMI130_GYRO_Z_AXIS:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_TRIM_GP0_ADDR_OFFSET_Z__REG, &v_data1_u8r, 1);
+ v_data1_u8r = SMI130_GYRO_GET_BITSLICE(v_data1_u8r,
+ SMI130_GYRO_TRIM_GP0_ADDR_OFFSET_Z);
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_OFC1_ADDR_OFFSET_Z__REG, &v_data2_u8r, 1);
+ v_data2_u8r = SMI130_GYRO_GET_BITSLICE(v_data2_u8r,
+ SMI130_GYRO_OFC1_ADDR_OFFSET_Z);
+ v_data2_u8r = ((v_data2_u8r << SMI130_GYRO_SHIFT_1_POSITION)
+ | v_data1_u8r);
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_OFC4_ADDR, &v_data1_u8r, 1);
+ *offset = (SMI130_GYRO_S16)((((SMI130_GYRO_S16)
+ ((signed char)v_data1_u8r))
+ << SMI130_GYRO_SHIFT_4_POSITION) | (v_data2_u8r));
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set the status of offset
+ *
+ *
+ *
+ *
+ *\param unsigned char axis,unsigned char offset
+ * axis ->
+ * SMI130_GYRO_X_AXIS -> 0
+ * SMI130_GYRO_Y_AXIS -> 1
+ * SMI130_GYRO_Z_AXIS -> 2
+ * offset -> Any valid value
+ *
+ *
+ *
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_offset(
+unsigned char axis, SMI130_GYRO_S16 offset)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data1_u8r = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data2_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (axis) {
+ case SMI130_GYRO_X_AXIS:
+ v_data1_u8r = ((signed char) (offset & 0x0FF0))
+ >> SMI130_GYRO_SHIFT_4_POSITION;
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_OFC2_ADDR, &v_data1_u8r, 1);
+
+ v_data1_u8r = (unsigned char) (offset & 0x000C);
+ v_data2_u8r = SMI130_GYRO_SET_BITSLICE(v_data2_u8r,
+ SMI130_GYRO_OFC1_ADDR_OFFSET_X, v_data1_u8r);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_OFC1_ADDR_OFFSET_X__REG, &v_data2_u8r, 1);
+
+ v_data1_u8r = (unsigned char) (offset & 0x0003);
+ v_data2_u8r = SMI130_GYRO_SET_BITSLICE(v_data2_u8r,
+ SMI130_GYRO_TRIM_GP0_ADDR_OFFSET_X, v_data1_u8r);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_TRIM_GP0_ADDR_OFFSET_X__REG, &v_data2_u8r, 1);
+ break;
+ case SMI130_GYRO_Y_AXIS:
+ v_data1_u8r = ((signed char) (offset & 0x0FF0)) >>
+ SMI130_GYRO_SHIFT_4_POSITION;
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_OFC3_ADDR, &v_data1_u8r, 1);
+
+ v_data1_u8r = (unsigned char) (offset & 0x000E);
+ v_data2_u8r = SMI130_GYRO_SET_BITSLICE(v_data2_u8r,
+ SMI130_GYRO_OFC1_ADDR_OFFSET_Y, v_data1_u8r);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_OFC1_ADDR_OFFSET_Y__REG, &v_data2_u8r, 1);
+
+ v_data1_u8r = (unsigned char) (offset & 0x0001);
+ v_data2_u8r = SMI130_GYRO_SET_BITSLICE(v_data2_u8r,
+ SMI130_GYRO_TRIM_GP0_ADDR_OFFSET_Y, v_data1_u8r);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_TRIM_GP0_ADDR_OFFSET_Y__REG, &v_data2_u8r, 1);
+ break;
+ case SMI130_GYRO_Z_AXIS:
+ v_data1_u8r = ((signed char) (offset & 0x0FF0)) >>
+ SMI130_GYRO_SHIFT_4_POSITION;
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_OFC4_ADDR, &v_data1_u8r, 1);
+
+ v_data1_u8r = (unsigned char) (offset & 0x000E);
+ v_data2_u8r = SMI130_GYRO_SET_BITSLICE(v_data2_u8r,
+ SMI130_GYRO_OFC1_ADDR_OFFSET_Z, v_data1_u8r);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_OFC1_ADDR_OFFSET_Z__REG, &v_data2_u8r, 1);
+
+ v_data1_u8r = (unsigned char) (offset & 0x0001);
+ v_data2_u8r = SMI130_GYRO_SET_BITSLICE(v_data2_u8r,
+ SMI130_GYRO_TRIM_GP0_ADDR_OFFSET_Z, v_data1_u8r);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_TRIM_GP0_ADDR_OFFSET_Z__REG, &v_data2_u8r, 1);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get the status of general
+ * purpose register
+ *
+ *
+ *
+ *
+ *\param unsigned char param,unsigned char *value
+ * param ->
+ * SMI130_GYRO_GP0 0
+ * SMI130_GYRO_GP0 1
+ * *value -> Address of high_bw
+ * Pointer to a variable passed as a parameter
+ *
+ *
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_gp(unsigned char param,
+unsigned char *value)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (param) {
+ case SMI130_GYRO_GP0:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_TRIM_GP0_ADDR_GP0__REG, &v_data_u8r, 1);
+ *value = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_TRIM_GP0_ADDR_GP0);
+ break;
+ case SMI130_GYRO_GP1:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_TRIM_GP1_ADDR, &v_data_u8r, 1);
+ *value = v_data_u8r;
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set the status of general
+ * purpose register
+ *
+ *
+ *
+ *
+ *\param unsigned char param,unsigned char value
+ * param ->
+ * SMI130_GYRO_GP0 0
+ * SMI130_GYRO_GP0 1
+ * value -> Value to be written passed as a parameter
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_gp(unsigned char param,
+unsigned char value)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ switch (param) {
+ case SMI130_GYRO_GP0:
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_TRIM_GP0_ADDR_GP0__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_TRIM_GP0_ADDR_GP0, value);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_TRIM_GP0_ADDR_GP0__REG, &v_data_u8r, 1);
+ break;
+ case SMI130_GYRO_GP1:
+ v_data_u8r = value;
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_TRIM_GP1_ADDR, &v_data_u8r, 1);
+ break;
+ default:
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief Reads FIFI data from location 3Fh
+ *
+ *
+ *
+ *
+ * \param
+ * unsigned char *fifo_data : Address of FIFO data bits
+ *
+ *
+ *
+ *
+ * \return result of communication routines
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_FIFO_data_reg(unsigned char *fifo_data)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_FIFO_DATA_ADDR, &v_data_u8r, 1);
+ *fifo_data = v_data_u8r;
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief Reads interrupt fifo status register byte from 0Eh
+ *
+ *
+ *
+ *
+ * \param
+ * unsigned char *fifo_status : Address of Fifo status register
+ *
+ *
+ * \return
+ * Result of bus communication function
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_fifostatus_reg(
+unsigned char *fifo_status)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_FIFO_STATUS_ADDR, fifo_status, 1);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief Reads interrupt fifo status register byte from 0Eh
+ *
+ *
+ *
+ *
+ * \param
+ * unsigned char *fifo_framecount: Address of FIFO status register
+ *
+ *
+ * \return
+ * Result of bus communication function
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_fifo_framecount(
+unsigned char *fifo_framecount)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_FIFO_STATUS_FRAME_COUNTER__REG, &v_data_u8r, 1);
+ *fifo_framecount = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_FIFO_STATUS_FRAME_COUNTER);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief Reads interrupt fifo status register byte from 0Eh
+ *
+ *
+ *
+ *
+ * \param
+ * unsigned char *fifo_overrun: Address of FIFO status register
+ *
+ *
+ * \return
+ * Result of bus communication function
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_fifo_overrun(
+unsigned char *fifo_overrun)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_FIFO_STATUS_OVERRUN__REG, &v_data_u8r, 1);
+ *fifo_overrun = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_FIFO_STATUS_OVERRUN);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get the status of fifo mode
+ *
+ *
+ *
+ *
+ *\param unsigned char *mode : Address of mode
+ * fifo_mode 0 --> Bypass
+ * 1 --> FIFO
+ * 2 --> Stream
+ * 3 --> Reserved
+ *
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_fifo_mode(unsigned char *mode)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_FIFO_CGF0_ADDR_MODE__REG, &v_data_u8r, 1);
+ *mode = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_FIFO_CGF0_ADDR_MODE);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used set to FIFO mode
+ *
+ *
+ *
+ *
+* \param 0 --> BYPASS
+ * 1 --> FIFO
+ * 2 --> STREAM
+ *
+ *
+ * \return Communication Results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_fifo_mode(unsigned char mode)
+{
+ int comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ if (mode < C_SMI130_GYRO_Four_U8X) {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_FIFO_CGF0_ADDR_MODE__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_FIFO_CGF0_ADDR_MODE, mode);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_FIFO_CGF0_ADDR_MODE__REG, &v_data_u8r, 1);
+ } else {
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get the status of fifo data
+ * sel
+ *
+ *
+ *
+ *
+ *\param unsigned char *data_sel : Address of data_sel
+ * data_sel --> [0:3]
+ * 0 --> X,Y and Z (DEFAULT)
+ * 1 --> X only
+ * 2 --> Y only
+ * 3 --> Z only
+ *
+ *
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_fifo_data_sel(unsigned char *data_sel)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_FIFO_CGF0_ADDR_DATA_SEL__REG, &v_data_u8r, 1);
+ *data_sel = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_FIFO_CGF0_ADDR_DATA_SEL);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set the status of fifo data
+ * sel
+ *
+ *
+ *
+ *
+ *\param unsigned char data_sel
+ * data_sel --> [0:3]
+ * 0 --> X,Y and Z (DEFAULT)
+ * 1 --> X only
+ * 2 --> Y only
+ * 3 --> Z only
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_fifo_data_sel(unsigned char data_sel)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ if (data_sel < C_SMI130_GYRO_Four_U8X) {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_FIFO_CGF0_ADDR_DATA_SEL__REG, &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_FIFO_CGF0_ADDR_DATA_SEL, data_sel);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_FIFO_CGF0_ADDR_DATA_SEL__REG, &v_data_u8r, 1);
+ } else {
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get the operating modes of the
+ * sensor
+ *
+ *
+ *
+ *
+ *\param unsigned char * mode : Address of mode
+ * 0 -> NORMAL
+ * 1 -> SUSPEND
+ * 2 -> DEEP SUSPEND
+ * 3 -> FAST POWERUP
+ * 4 -> ADVANCED POWERSAVING
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_mode(unsigned char *mode)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char data1 = C_SMI130_GYRO_Zero_U8X;
+ unsigned char data2 = C_SMI130_GYRO_Zero_U8X;
+ unsigned char data3 = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == C_SMI130_GYRO_Zero_U8X) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MODE_LPM1_ADDR, &data1, C_SMI130_GYRO_One_U8X);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MODE_LPM2_ADDR, &data2, C_SMI130_GYRO_One_U8X);
+ data1 = (data1 & 0xA0) >> 5;
+ data3 = (data2 & 0x40) >> 6;
+ data2 = (data2 & 0x80) >> 7;
+ if (data3 == 0x01) {
+ *mode = SMI130_GYRO_MODE_ADVANCEDPOWERSAVING;
+ } else {
+ if ((data1 == 0x00) && (data2 == 0x00)) {
+ *mode = SMI130_GYRO_MODE_NORMAL;
+ } else {
+ if ((data1 == 0x01) || (data1 == 0x05)) {
+ *mode = SMI130_GYRO_MODE_DEEPSUSPEND;
+ } else {
+ if ((data1 == 0x04) &&
+ (data2 == 0x00)) {
+ *mode = SMI130_GYRO_MODE_SUSPEND;
+ } else {
+ if ((data1 == 0x04) &&
+ (data2 == 0x01))
+ *mode =
+ SMI130_GYRO_MODE_FASTPOWERUP;
+ }
+ }
+ }
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set the operating Modes of the
+ * sensor
+ *
+ *
+ *
+ *
+ *\param unsigned char Mode
+ * 0 -> NORMAL
+ * 1 -> DEEPSUSPEND
+ * 2 -> SUSPEND
+ * 3 -> Fast Powerup
+ * 4 -> Advance Powerup
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_mode(unsigned char mode)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char data1 = C_SMI130_GYRO_Zero_U8X;
+ unsigned char data2 = C_SMI130_GYRO_Zero_U8X;
+ unsigned char data3 = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_autosleepduration = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_bw_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == C_SMI130_GYRO_Zero_U8X) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ if (mode < C_SMI130_GYRO_Five_U8X) {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MODE_LPM1_ADDR, &data1, C_SMI130_GYRO_One_U8X);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MODE_LPM2_ADDR, &data2, C_SMI130_GYRO_One_U8X);
+ switch (mode) {
+ case SMI130_GYRO_MODE_NORMAL:
+ data1 = SMI130_GYRO_SET_BITSLICE(data1,
+ SMI130_GYRO_MODE_LPM1, C_SMI130_GYRO_Zero_U8X);
+ data2 = SMI130_GYRO_SET_BITSLICE(data2,
+ SMI130_GYRO_MODE_LPM2_ADDR_FAST_POWERUP,
+ C_SMI130_GYRO_Zero_U8X);
+ data3 = SMI130_GYRO_SET_BITSLICE(data2,
+ SMI130_GYRO_MODE_LPM2_ADDR_ADV_POWERSAVING,
+ C_SMI130_GYRO_Zero_U8X);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MODE_LPM1_ADDR, &data1, C_SMI130_GYRO_One_U8X);
+ p_smi130_gyro->delay_msec(1);/*A minimum delay of atleast
+ 450us is required for Multiple write.*/
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MODE_LPM2_ADDR, &data3, C_SMI130_GYRO_One_U8X);
+ break;
+ case SMI130_GYRO_MODE_DEEPSUSPEND:
+ data1 = SMI130_GYRO_SET_BITSLICE(data1,
+ SMI130_GYRO_MODE_LPM1, C_SMI130_GYRO_One_U8X);
+ data2 = SMI130_GYRO_SET_BITSLICE(data2,
+ SMI130_GYRO_MODE_LPM2_ADDR_FAST_POWERUP,
+ C_SMI130_GYRO_Zero_U8X);
+ data3 = SMI130_GYRO_SET_BITSLICE(data2,
+ SMI130_GYRO_MODE_LPM2_ADDR_ADV_POWERSAVING,
+ C_SMI130_GYRO_Zero_U8X);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MODE_LPM1_ADDR, &data1, C_SMI130_GYRO_One_U8X);
+ p_smi130_gyro->delay_msec(1);/*A minimum delay of atleast
+ 450us is required for Multiple write.*/
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MODE_LPM2_ADDR, &data3, C_SMI130_GYRO_One_U8X);
+ break;
+ case SMI130_GYRO_MODE_SUSPEND:
+ data1 = SMI130_GYRO_SET_BITSLICE(data1,
+ SMI130_GYRO_MODE_LPM1, C_SMI130_GYRO_Four_U8X);
+ data2 = SMI130_GYRO_SET_BITSLICE(data2,
+ SMI130_GYRO_MODE_LPM2_ADDR_FAST_POWERUP,
+ C_SMI130_GYRO_Zero_U8X);
+ data3 = SMI130_GYRO_SET_BITSLICE(data2,
+ SMI130_GYRO_MODE_LPM2_ADDR_ADV_POWERSAVING,
+ C_SMI130_GYRO_Zero_U8X);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MODE_LPM1_ADDR, &data1, C_SMI130_GYRO_One_U8X);
+ p_smi130_gyro->delay_msec(1);/*A minimum delay of atleast
+ 450us is required for Multiple write.*/
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MODE_LPM2_ADDR, &data3, C_SMI130_GYRO_One_U8X);
+ break;
+ case SMI130_GYRO_MODE_FASTPOWERUP:
+ data1 = SMI130_GYRO_SET_BITSLICE(data1,
+ SMI130_GYRO_MODE_LPM1, C_SMI130_GYRO_Four_U8X);
+ data2 = SMI130_GYRO_SET_BITSLICE(data2,
+ SMI130_GYRO_MODE_LPM2_ADDR_FAST_POWERUP,
+ C_SMI130_GYRO_One_U8X);
+ data3 = SMI130_GYRO_SET_BITSLICE(data2,
+ SMI130_GYRO_MODE_LPM2_ADDR_ADV_POWERSAVING,
+ C_SMI130_GYRO_Zero_U8X);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MODE_LPM1_ADDR, &data1, C_SMI130_GYRO_One_U8X);
+ p_smi130_gyro->delay_msec(1);/*A minimum delay of atleast
+ 450us is required for Multiple write.*/
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MODE_LPM2_ADDR, &data3, C_SMI130_GYRO_One_U8X);
+ break;
+ case SMI130_GYRO_MODE_ADVANCEDPOWERSAVING:
+ /* Configuring the proper settings for auto
+ sleep duration */
+ smi130_gyro_get_bw(&v_bw_u8r);
+ smi130_gyro_get_autosleepdur(&v_autosleepduration);
+ smi130_gyro_set_autosleepdur(v_autosleepduration,
+ v_bw_u8r);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MODE_LPM2_ADDR, &data2,
+ C_SMI130_GYRO_One_U8X);
+ /* Configuring the advanced power saving mode*/
+ data1 = SMI130_GYRO_SET_BITSLICE(data1,
+ SMI130_GYRO_MODE_LPM1, C_SMI130_GYRO_Zero_U8X);
+ data2 = SMI130_GYRO_SET_BITSLICE(data2,
+ SMI130_GYRO_MODE_LPM2_ADDR_FAST_POWERUP,
+ C_SMI130_GYRO_Zero_U8X);
+ data3 = SMI130_GYRO_SET_BITSLICE(data2,
+ SMI130_GYRO_MODE_LPM2_ADDR_ADV_POWERSAVING,
+ C_SMI130_GYRO_One_U8X);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MODE_LPM1_ADDR, &data1, C_SMI130_GYRO_One_U8X);
+ p_smi130_gyro->delay_msec(1);/*A minimum delay of atleast
+ 450us is required for Multiple write.*/
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MODE_LPM2_ADDR, &data3, C_SMI130_GYRO_One_U8X);
+ break;
+ }
+ } else {
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to to do selftest to sensor
+ * sensor
+ *
+ *
+ *
+ *
+ *\param unsigned char *result
+ *
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_selftest(unsigned char *result)
+ {
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char data1 = C_SMI130_GYRO_Zero_U8X;
+ unsigned char data2 = C_SMI130_GYRO_Zero_U8X;
+
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_SELF_TEST_ADDR, &data1, C_SMI130_GYRO_One_U8X);
+ data2 = SMI130_GYRO_GET_BITSLICE(data1, SMI130_GYRO_SELF_TEST_ADDR_RATEOK);
+ data1 = SMI130_GYRO_SET_BITSLICE(data1, SMI130_GYRO_SELF_TEST_ADDR_TRIGBIST,
+ C_SMI130_GYRO_One_U8X);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_SELF_TEST_ADDR_TRIGBIST__REG, &data1, C_SMI130_GYRO_One_U8X);
+
+ /* Waiting time to complete the selftest process */
+ p_smi130_gyro->delay_msec(10);
+
+ /* Reading Selftest result bir bist_failure */
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_SELF_TEST_ADDR_BISTFAIL__REG, &data1, C_SMI130_GYRO_One_U8X);
+ data1 = SMI130_GYRO_GET_BITSLICE(data1, SMI130_GYRO_SELF_TEST_ADDR_BISTFAIL);
+ if ((data1 == 0x00) && (data2 == 0x01))
+ *result = C_SMI130_GYRO_SUCCESS;
+ else
+ *result = C_SMI130_GYRO_FAILURE;
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get data auto sleep duration
+ *
+ *
+ *
+ *
+ *\param unsigned char *duration : Address of auto sleep duration
+ * Pointer to a variable passed as a parameter
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_autosleepdur(unsigned char *duration)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MODE_LPM2_ADDR_AUTOSLEEPDUR__REG, &v_data_u8r, 1);
+ *duration = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_MODE_LPM2_ADDR_AUTOSLEEPDUR);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set duration
+ *
+ *
+ *
+ *
+ *\param unsigned char duration:
+ * Value to be written passed as a parameter
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_autosleepdur(unsigned char duration,
+unsigned char bandwith)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_autosleepduration_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MODE_LPM2_ADDR_AUTOSLEEPDUR__REG,
+ &v_data_u8r, 1);
+ if (duration < C_SMI130_GYRO_Eight_U8X) {
+ switch (bandwith) {
+ case C_SMI130_GYRO_No_Filter_U8X:
+ if (duration >
+ C_SMI130_GYRO_4ms_AutoSleepDur_U8X)
+ v_autosleepduration_u8r =
+ duration;
+ else
+ v_autosleepduration_u8r =
+ C_SMI130_GYRO_4ms_AutoSleepDur_U8X;
+ break;
+ case C_SMI130_GYRO_BW_230Hz_U8X:
+ if (duration >
+ C_SMI130_GYRO_4ms_AutoSleepDur_U8X)
+ v_autosleepduration_u8r =
+ duration;
+ else
+ v_autosleepduration_u8r =
+ C_SMI130_GYRO_4ms_AutoSleepDur_U8X;
+ break;
+ case C_SMI130_GYRO_BW_116Hz_U8X:
+ if (duration >
+ C_SMI130_GYRO_4ms_AutoSleepDur_U8X)
+ v_autosleepduration_u8r =
+ duration;
+ else
+ v_autosleepduration_u8r =
+ C_SMI130_GYRO_4ms_AutoSleepDur_U8X;
+ break;
+ case C_SMI130_GYRO_BW_47Hz_U8X:
+ if (duration >
+ C_SMI130_GYRO_5ms_AutoSleepDur_U8X)
+ v_autosleepduration_u8r =
+ duration;
+ else
+ v_autosleepduration_u8r =
+ C_SMI130_GYRO_5ms_AutoSleepDur_U8X;
+ break;
+ case C_SMI130_GYRO_BW_23Hz_U8X:
+ if (duration >
+ C_SMI130_GYRO_10ms_AutoSleepDur_U8X)
+ v_autosleepduration_u8r =
+ duration;
+ else
+ v_autosleepduration_u8r =
+ C_SMI130_GYRO_10ms_AutoSleepDur_U8X;
+ break;
+ case C_SMI130_GYRO_BW_12Hz_U8X:
+ if (duration >
+ C_SMI130_GYRO_20ms_AutoSleepDur_U8X)
+ v_autosleepduration_u8r =
+ duration;
+ else
+ v_autosleepduration_u8r =
+ C_SMI130_GYRO_20ms_AutoSleepDur_U8X;
+ break;
+ case C_SMI130_GYRO_BW_64Hz_U8X:
+ if (duration >
+ C_SMI130_GYRO_10ms_AutoSleepDur_U8X)
+ v_autosleepduration_u8r =
+ duration;
+ else
+ v_autosleepduration_u8r =
+ C_SMI130_GYRO_10ms_AutoSleepDur_U8X;
+ break;
+ case C_SMI130_GYRO_BW_32Hz_U8X:
+ if (duration >
+ C_SMI130_GYRO_20ms_AutoSleepDur_U8X)
+ v_autosleepduration_u8r =
+ duration;
+ else
+ v_autosleepduration_u8r =
+ C_SMI130_GYRO_20ms_AutoSleepDur_U8X;
+ break;
+ default:
+ if (duration >
+ C_SMI130_GYRO_4ms_AutoSleepDur_U8X)
+ v_autosleepduration_u8r =
+ duration;
+ else
+ v_autosleepduration_u8r =
+ C_SMI130_GYRO_4ms_AutoSleepDur_U8X;
+ break;
+ }
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_MODE_LPM2_ADDR_AUTOSLEEPDUR,
+ v_autosleepduration_u8r);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MODE_LPM2_ADDR_AUTOSLEEPDUR__REG,
+ &v_data_u8r, 1);
+ } else {
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ }
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to get data sleep duration
+ *
+ *
+ *
+ *
+ *\param unsigned char *duration : Address of sleep duration
+ * Pointer to a variable passed as a parameter
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_sleepdur(unsigned char *duration)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC(p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MODELPM1_ADDR_SLEEPDUR__REG, &v_data_u8r, 1);
+ *duration = SMI130_GYRO_GET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_MODELPM1_ADDR_SLEEPDUR);
+ }
+ return comres;
+}
+/* Compiler Switch if applicable
+#ifdef
+
+#endif
+*/
+/*****************************************************************************
+ * Description: *//**brief This API is used to set duration
+ *
+ *
+ *
+ *
+ *\param unsigned char duration:
+ * Value to be written passed as a parameter
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_sleepdur(unsigned char duration)
+{
+ SMI130_GYRO_RETURN_FUNCTION_TYPE comres = C_SMI130_GYRO_Zero_U8X;
+ unsigned char v_data_u8r = C_SMI130_GYRO_Zero_U8X;
+ if (p_smi130_gyro == SMI130_GYRO_NULL) {
+ return E_SMI130_GYRO_NULL_PTR;
+ } else {
+ if (duration < C_SMI130_GYRO_Eight_U8X) {
+ comres = p_smi130_gyro->SMI130_GYRO_BUS_READ_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MODELPM1_ADDR_SLEEPDUR__REG,
+ &v_data_u8r, 1);
+ v_data_u8r = SMI130_GYRO_SET_BITSLICE(v_data_u8r,
+ SMI130_GYRO_MODELPM1_ADDR_SLEEPDUR, duration);
+ comres += p_smi130_gyro->SMI130_GYRO_BUS_WRITE_FUNC
+ (p_smi130_gyro->dev_addr,
+ SMI130_GYRO_MODELPM1_ADDR_SLEEPDUR__REG,
+ &v_data_u8r, 1);
+ } else {
+ comres = E_SMI130_GYRO_OUT_OF_RANGE;
+ }
+ }
+ return comres;
+}
+
diff --git a/drivers/input/sensors/smi130/smi130_gyro.h b/drivers/input/sensors/smi130/smi130_gyro.h
new file mode 100644
index 0000000..38e52ac
--- /dev/null
+++ b/drivers/input/sensors/smi130/smi130_gyro.h
@@ -0,0 +1,4705 @@
+/*!
+ * @section LICENSE
+ * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved
+ *
+ * (C) Modification Copyright 2018 Robert Bosch Kft All Rights Reserved
+ *
+ * This software program is licensed subject to the GNU General
+ * Public License (GPL).Version 2,June 1991,
+ * available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * Special: Description of the Software:
+ *
+ * This software module (hereinafter called "Software") and any
+ * information on application-sheets (hereinafter called "Information") is
+ * provided free of charge for the sole purpose to support your application
+ * work.
+ *
+ * As such, the Software is merely an experimental software, not tested for
+ * safety in the field and only intended for inspiration for further development
+ * and testing. Any usage in a safety-relevant field of use (like automotive,
+ * seafaring, spacefaring, industrial plants etc.) was not intended, so there are
+ * no precautions for such usage incorporated in the Software.
+ *
+ * The Software is specifically designed for the exclusive use for Bosch
+ * Sensortec products by personnel who have special experience and training. Do
+ * not use this Software if you do not have the proper experience or training.
+ *
+ * This Software package is provided as is and without any expressed or
+ * implied warranties, including without limitation, the implied warranties of
+ * merchantability and fitness for a particular purpose.
+ *
+ * Bosch Sensortec and their representatives and agents deny any liability for
+ * the functional impairment of this Software in terms of fitness, performance
+ * and safety. Bosch Sensortec and their representatives and agents shall not be
+ * liable for any direct or indirect damages or injury, except as otherwise
+ * stipulated in mandatory applicable law.
+ * The Information provided is believed to be accurate and reliable. Bosch
+ * Sensortec assumes no responsibility for the consequences of use of such
+ * Information nor for any infringement of patents or other rights of third
+ * parties which may result from its use.
+ *
+ *------------------------------------------------------------------------------
+ * The following Product Disclaimer does not apply to the BSX4-HAL-4.1NoFusion Software
+ * which is licensed under the Apache License, Version 2.0 as stated above.
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Product Disclaimer
+ *
+ * Common:
+ *
+ * Assessment of Products Returned from Field
+ *
+ * Returned products are considered good if they fulfill the specifications /
+ * test data for 0-mileage and field listed in this document.
+ *
+ * Engineering Samples
+ *
+ * Engineering samples are marked with (e) or (E). Samples may vary from the
+ * valid technical specifications of the series product contained in this
+ * data sheet. Therefore, they are not intended or fit for resale to
+ * third parties or for use in end products. Their sole purpose is internal
+ * client testing. The testing of an engineering sample may in no way replace
+ * the testing of a series product. Bosch assumes no liability for the use
+ * of engineering samples. The purchaser shall indemnify Bosch from all claims
+ * arising from the use of engineering samples.
+ *
+ * Intended use
+ *
+ * Provided that SMI130 is used within the conditions (environment, application,
+ * installation, loads) as described in this TCD and the corresponding
+ * agreed upon documents, Bosch ensures that the product complies with
+ * the agreed properties. Agreements beyond this require
+ * the written approval by Bosch. The product is considered fit for the intended
+ * use when the product successfully has passed the tests
+ * in accordance with the TCD and agreed upon documents.
+ *
+ * It is the responsibility of the customer to ensure the proper application
+ * of the product in the overall system/vehicle.
+ *
+ * Bosch does not assume any responsibility for changes to the environment
+ * of the product that deviate from the TCD and the agreed upon documents
+ * as well as all applications not released by Bosch
+ *
+ * The resale and/or use of products are at the purchaser’s own risk and
+ * responsibility. The examination and testing of the SMI130
+ * is the sole responsibility of the purchaser.
+ *
+ * The purchaser shall indemnify Bosch from all third party claims
+ * arising from any product use not covered by the parameters of
+ * this product data sheet or not approved by Bosch and reimburse Bosch
+ * for all costs and damages in connection with such claims.
+ *
+ * The purchaser must monitor the market for the purchased products,
+ * particularly with regard to product safety, and inform Bosch without delay
+ * of all security relevant incidents.
+ *
+ * Application Examples and Hints
+ *
+ * With respect to any application examples, advice, normal values
+ * and/or any information regarding the application of the device,
+ * Bosch hereby disclaims any and all warranties and liabilities of any kind,
+ * including without limitation warranties of
+ * non-infringement of intellectual property rights or copyrights
+ * of any third party.
+ * The information given in this document shall in no event be regarded
+ * as a guarantee of conditions or characteristics. They are provided
+ * for illustrative purposes only and no evaluation regarding infringement
+ * of intellectual property rights or copyrights or regarding functionality,
+ * performance or error has been made.
+ *
+ * @filename smi130_gyro.h
+ * @date 2013/11/25
+ * @Modification Date 2018/08/28 18:20
+ * @id "8fcde22"
+ * @version 1.5
+ *
+ * @brief Header of SMI130_GYRO API
+*/
+
+/* user defined code to be added here ... */
+#ifndef __SMI130_GYRO_H__
+#define __SMI130_GYRO_H__
+
+#ifdef __KERNEL__
+#define SMI130_GYRO_U16 unsigned short /* 16 bit achieved with short */
+#define SMI130_GYRO_S16 signed short
+#define SMI130_GYRO_S32 signed int /* 32 bit achieved with int */
+#else
+#include <limits.h> /*needed to test integer limits */
+
+
+/* find correct data type for signed/unsigned 16 bit variables \
+by checking max of unsigned variant */
+#if USHRT_MAX == 0xFFFF
+ /* 16 bit achieved with short */
+ #define SMI130_GYRO_U16 unsigned short
+ #define SMI130_GYRO_S16 signed short
+#elif UINT_MAX == 0xFFFF
+ /* 16 bit achieved with int */
+ #define SMI130_GYRO_U16 unsigned int
+ #define SMI130_GYRO_S16 signed int
+#else
+ #error SMI130_GYRO_U16 and SMI130_GYRO_S16 could not be
+ #error defined automatically, please do so manually
+#endif
+
+/* find correct data type for signed 32 bit variables */
+#if INT_MAX == 0x7FFFFFFF
+ /* 32 bit achieved with int */
+ #define SMI130_GYRO_S32 signed int
+#elif LONG_MAX == 0x7FFFFFFF
+ /* 32 bit achieved with long int */
+ #define SMI130_GYRO_S32 signed long int
+#else
+ #error SMI130_GYRO_S32 could not be
+ #error defined automatically, please do so manually
+#endif
+#endif
+
+/**\brief defines the calling parameter types of the SMI130_GYRO_WR_FUNCTION */
+#define SMI130_GYRO_BUS_WR_RETURN_TYPE char
+
+/**\brief links the order of parameters defined in
+SMI130_GYRO_BUS_WR_PARAM_TYPE to function calls used inside the API*/
+#define SMI130_GYRO_BUS_WR_PARAM_TYPES unsigned char, unsigned char,\
+unsigned char *, unsigned char
+
+/**\brief links the order of parameters defined in
+SMI130_GYRO_BUS_WR_PARAM_TYPE to function calls used inside the API*/
+#define SMI130_GYRO_BUS_WR_PARAM_ORDER(device_addr, register_addr,\
+register_data, wr_len)
+
+/* never change this line */
+#define SMI130_GYRO_BUS_WRITE_FUNC(device_addr, register_addr,\
+register_data, wr_len) bus_write(device_addr, register_addr,\
+register_data, wr_len)
+/**\brief defines the return parameter type of the SMI130_GYRO_RD_FUNCTION
+*/
+#define SMI130_GYRO_BUS_RD_RETURN_TYPE char
+/**\brief defines the calling parameter types of the SMI130_GYRO_RD_FUNCTION
+*/
+#define SMI130_GYRO_BUS_RD_PARAM_TYPES unsigned char, unsigned char,\
+unsigned char *, unsigned char
+/**\brief links the order of parameters defined in \
+SMI130_GYRO_BUS_RD_PARAM_TYPE to function calls used inside the API
+*/
+#define SMI130_GYRO_BUS_RD_PARAM_ORDER (device_addr, register_addr,\
+register_data)
+/* never change this line */
+#define SMI130_GYRO_BUS_READ_FUNC(device_addr, register_addr,\
+register_data, rd_len)bus_read(device_addr, register_addr,\
+register_data, rd_len)
+/**\brief defines the return parameter type of the SMI130_GYRO_RD_FUNCTION
+*/
+#define SMI130_GYRO_BURST_RD_RETURN_TYPE char
+/**\brief defines the calling parameter types of the SMI130_GYRO_RD_FUNCTION
+*/
+#define SMI130_GYRO_BURST_RD_PARAM_TYPES unsigned char,\
+unsigned char, unsigned char *, signed int
+/**\brief links the order of parameters defined in \
+SMI130_GYRO_BURST_RD_PARAM_TYPE to function calls used inside the API
+*/
+#define SMI130_GYRO_BURST_RD_PARAM_ORDER (device_addr, register_addr,\
+register_data)
+/* never change this line */
+#define SMI130_GYRO_BURST_READ_FUNC(device_addr, register_addr,\
+register_data, rd_len)burst_read(device_addr, \
+register_addr, register_data, rd_len)
+/**\brief defines the return parameter type of the SMI130_GYRO_DELAY_FUNCTION
+*/
+#define SMI130_GYRO_DELAY_RETURN_TYPE void
+/* never change this line */
+#define SMI130_GYRO_DELAY_FUNC(delay_in_msec)\
+ delay_func(delay_in_msec)
+#define SMI130_GYRO_RETURN_FUNCTION_TYPE int
+/**< This refers SMI130_GYRO return type as char */
+
+#define SMI130_GYRO_I2C_ADDR1 0x68
+#define SMI130_GYRO_I2C_ADDR SMI130_GYRO_I2C_ADDR1
+#define SMI130_GYRO_I2C_ADDR2 0x69
+
+
+
+/*Define of registers*/
+
+/* Hard Wired */
+#define SMI130_GYRO_CHIP_ID_ADDR 0x00
+/**<Address of Chip ID Register*/
+
+
+/* Data Register */
+#define SMI130_GYRO_RATE_X_LSB_ADDR 0x02
+/**< Address of X axis Rate LSB Register */
+#define SMI130_GYRO_RATE_X_MSB_ADDR 0x03
+/**< Address of X axis Rate MSB Register */
+#define SMI130_GYRO_RATE_Y_LSB_ADDR 0x04
+/**< Address of Y axis Rate LSB Register */
+#define SMI130_GYRO_RATE_Y_MSB_ADDR 0x05
+/**< Address of Y axis Rate MSB Register */
+#define SMI130_GYRO_RATE_Z_LSB_ADDR 0x06
+/**< Address of Z axis Rate LSB Register */
+#define SMI130_GYRO_RATE_Z_MSB_ADDR 0x07
+/**< Address of Z axis Rate MSB Register */
+#define SMI130_GYRO_TEMP_ADDR 0x08
+/**< Address of Temperature Data LSB Register */
+
+/* Status Register */
+#define SMI130_GYRO_INT_STATUS0_ADDR 0x09
+/**< Address of Interrupt status Register 0 */
+#define SMI130_GYRO_INT_STATUS1_ADDR 0x0A
+/**< Address of Interrupt status Register 1 */
+#define SMI130_GYRO_INT_STATUS2_ADDR 0x0B
+/**< Address of Interrupt status Register 2 */
+#define SMI130_GYRO_INT_STATUS3_ADDR 0x0C
+/**< Address of Interrupt status Register 3 */
+#define SMI130_GYRO_FIFO_STATUS_ADDR 0x0E
+/**< Address of FIFO status Register */
+
+/* Control Register */
+#define SMI130_GYRO_RANGE_ADDR 0x0F
+/**< Address of Range address Register */
+#define SMI130_GYRO_BW_ADDR 0x10
+/**< Address of Bandwidth Register */
+#define SMI130_GYRO_MODE_LPM1_ADDR 0x11
+/**< Address of Mode LPM1 Register */
+#define SMI130_GYRO_MODE_LPM2_ADDR 0x12
+/**< Address of Mode LPM2 Register */
+#define SMI130_GYRO_RATED_HBW_ADDR 0x13
+/**< Address of Rate HBW Register */
+#define SMI130_GYRO_BGW_SOFTRESET_ADDR 0x14
+/**< Address of BGW Softreset Register */
+#define SMI130_GYRO_INT_ENABLE0_ADDR 0x15
+/**< Address of Interrupt Enable 0 */
+#define SMI130_GYRO_INT_ENABLE1_ADDR 0x16
+/**< Address of Interrupt Enable 1 */
+#define SMI130_GYRO_INT_MAP_0_ADDR 0x17
+/**< Address of Interrupt MAP 0 */
+#define SMI130_GYRO_INT_MAP_1_ADDR 0x18
+/**< Address of Interrupt MAP 1 */
+#define SMI130_GYRO_INT_MAP_2_ADDR 0x19
+/**< Address of Interrupt MAP 2 */
+#define SMI130_GYRO_INT_0_ADDR 0x1A
+/**< Address of Interrupt 0 register */
+#define SMI130_GYRO_INT_1_ADDR 0x1B
+/**< Address of Interrupt 1 register */
+#define SMI130_GYRO_INT_2_ADDR 0x1C
+/**< Address of Interrupt 2 register */
+#define SMI130_GYRO_INT_4_ADDR 0x1E
+/**< Address of Interrupt 4 register */
+#define SMI130_GYRO_RST_LATCH_ADDR 0x21
+/**< Address of Reset Latch Register */
+#define SMI130_GYRO_HIGH_TH_X_ADDR 0x22
+/**< Address of High Th x Address register */
+#define SMI130_GYRO_HIGH_DUR_X_ADDR 0x23
+/**< Address of High Dur x Address register */
+#define SMI130_GYRO_HIGH_TH_Y_ADDR 0x24
+/**< Address of High Th y Address register */
+#define SMI130_GYRO_HIGH_DUR_Y_ADDR 0x25
+/**< Address of High Dur y Address register */
+#define SMI130_GYRO_HIGH_TH_Z_ADDR 0x26
+/**< Address of High Th z Address register */
+#define SMI130_GYRO_HIGH_DUR_Z_ADDR 0x27
+/**< Address of High Dur z Address register */
+#define SMI130_GYRO_SOC_ADDR 0x31
+/**< Address of SOC register */
+#define SMI130_GYRO_A_FOC_ADDR 0x32
+/**< Address of A_FOC Register */
+#define SMI130_GYRO_TRIM_NVM_CTRL_ADDR 0x33
+/**< Address of Trim NVM control register */
+#define SMI130_GYRO_BGW_SPI3_WDT_ADDR 0x34
+/**< Address of BGW SPI3,WDT Register */
+
+
+/* Trim Register */
+#define SMI130_GYRO_OFC1_ADDR 0x36
+/**< Address of OFC1 Register */
+#define SMI130_GYRO_OFC2_ADDR 0x37
+/**< Address of OFC2 Register */
+#define SMI130_GYRO_OFC3_ADDR 0x38
+/**< Address of OFC3 Register */
+#define SMI130_GYRO_OFC4_ADDR 0x39
+/**< Address of OFC4 Register */
+#define SMI130_GYRO_TRIM_GP0_ADDR 0x3A
+/**< Address of Trim GP0 Register */
+#define SMI130_GYRO_TRIM_GP1_ADDR 0x3B
+/**< Address of Trim GP1 Register */
+#define SMI130_GYRO_SELF_TEST_ADDR 0x3C
+/**< Address of BGW Self test Register */
+
+/* Control Register */
+#define SMI130_GYRO_FIFO_CGF1_ADDR 0x3D
+/**< Address of FIFO CGF0 Register */
+#define SMI130_GYRO_FIFO_CGF0_ADDR 0x3E
+/**< Address of FIFO CGF1 Register */
+
+/* Data Register */
+#define SMI130_GYRO_FIFO_DATA_ADDR 0x3F
+/**< Address of FIFO Data Register */
+
+/* Rate X LSB Register */
+#define SMI130_GYRO_RATE_X_LSB_VALUEX__POS 0
+
+/**< Last 8 bits of RateX LSB Registers */
+#define SMI130_GYRO_RATE_X_LSB_VALUEX__LEN 8
+#define SMI130_GYRO_RATE_X_LSB_VALUEX__MSK 0xFF
+#define SMI130_GYRO_RATE_X_LSB_VALUEX__REG SMI130_GYRO_RATE_X_LSB_ADDR
+
+/* Rate Y LSB Register */
+/**< Last 8 bits of RateY LSB Registers */
+#define SMI130_GYRO_RATE_Y_LSB_VALUEY__POS 0
+#define SMI130_GYRO_RATE_Y_LSB_VALUEY__LEN 8
+#define SMI130_GYRO_RATE_Y_LSB_VALUEY__MSK 0xFF
+#define SMI130_GYRO_RATE_Y_LSB_VALUEY__REG SMI130_GYRO_RATE_Y_LSB_ADDR
+
+/* Rate Z LSB Register */
+/**< Last 8 bits of RateZ LSB Registers */
+#define SMI130_GYRO_RATE_Z_LSB_VALUEZ__POS 0
+#define SMI130_GYRO_RATE_Z_LSB_VALUEZ__LEN 8
+#define SMI130_GYRO_RATE_Z_LSB_VALUEZ__MSK 0xFF
+#define SMI130_GYRO_RATE_Z_LSB_VALUEZ__REG SMI130_GYRO_RATE_Z_LSB_ADDR
+
+/* Interrupt status 0 Register */
+ /**< 2th bit of Interrupt status 0 register */
+#define SMI130_GYRO_INT_STATUS0_ANY_INT__POS 2
+#define SMI130_GYRO_INT_STATUS0_ANY_INT__LEN 1
+#define SMI130_GYRO_INT_STATUS0_ANY_INT__MSK 0x04
+#define SMI130_GYRO_INT_STATUS0_ANY_INT__REG SMI130_GYRO_INT_STATUS0_ADDR
+
+/**< 1st bit of Interrupt status 0 register */
+#define SMI130_GYRO_INT_STATUS0_HIGH_INT__POS 1
+#define SMI130_GYRO_INT_STATUS0_HIGH_INT__LEN 1
+#define SMI130_GYRO_INT_STATUS0_HIGH_INT__MSK 0x02
+#define SMI130_GYRO_INT_STATUS0_HIGH_INT__REG SMI130_GYRO_INT_STATUS0_ADDR
+
+ /**< 1st and 2nd bit of Interrupt status 0 register */
+#define SMI130_GYRO_INT_STATUSZERO__POS 1
+#define SMI130_GYRO_INT_STATUSZERO__LEN 2
+#define SMI130_GYRO_INT_STATUSZERO__MSK 0x06
+#define SMI130_GYRO_INT_STATUSZERO__REG SMI130_GYRO_INT_STATUS0_ADDR
+
+/* Interrupt status 1 Register */
+/**< 7th bit of Interrupt status 1 register */
+#define SMI130_GYRO_INT_STATUS1_DATA_INT__POS 7
+#define SMI130_GYRO_INT_STATUS1_DATA_INT__LEN 1
+#define SMI130_GYRO_INT_STATUS1_DATA_INT__MSK 0x80
+#define SMI130_GYRO_INT_STATUS1_DATA_INT__REG SMI130_GYRO_INT_STATUS1_ADDR
+
+ /**< 6th bit of Interrupt status 1 register */
+#define SMI130_GYRO_INT_STATUS1_AUTO_OFFSET_INT__POS 6
+#define SMI130_GYRO_INT_STATUS1_AUTO_OFFSET_INT__LEN 1
+#define SMI130_GYRO_INT_STATUS1_AUTO_OFFSET_INT__MSK 0x40
+#define SMI130_GYRO_INT_STATUS1_AUTO_OFFSET_INT__REG SMI130_GYRO_INT_STATUS1_ADDR
+
+/**< 5th bit of Interrupt status 1 register */
+#define SMI130_GYRO_INT_STATUS1_FAST_OFFSET_INT__POS 5
+#define SMI130_GYRO_INT_STATUS1_FAST_OFFSET_INT__LEN 1
+#define SMI130_GYRO_INT_STATUS1_FAST_OFFSET_INT__MSK 0x20
+#define SMI130_GYRO_INT_STATUS1_FAST_OFFSET_INT__REG SMI130_GYRO_INT_STATUS1_ADDR
+
+/**< 4th bit of Interrupt status 1 register */
+#define SMI130_GYRO_INT_STATUS1_FIFO_INT__POS 4
+#define SMI130_GYRO_INT_STATUS1_FIFO_INT__LEN 1
+#define SMI130_GYRO_INT_STATUS1_FIFO_INT__MSK 0x10
+#define SMI130_GYRO_INT_STATUS1_FIFO_INT__REG SMI130_GYRO_INT_STATUS1_ADDR
+
+/**< MSB 4 bits of Interrupt status1 register */
+#define SMI130_GYRO_INT_STATUSONE__POS 4
+#define SMI130_GYRO_INT_STATUSONE__LEN 4
+#define SMI130_GYRO_INT_STATUSONE__MSK 0xF0
+#define SMI130_GYRO_INT_STATUSONE__REG SMI130_GYRO_INT_STATUS1_ADDR
+
+/* Interrupt status 2 Register */
+/**< 3th bit of Interrupt status 2 register */
+#define SMI130_GYRO_INT_STATUS2_ANY_SIGN_INT__POS 3
+#define SMI130_GYRO_INT_STATUS2_ANY_SIGN_INT__LEN 1
+#define SMI130_GYRO_INT_STATUS2_ANY_SIGN_INT__MSK 0x08
+#define SMI130_GYRO_INT_STATUS2_ANY_SIGN_INT__REG SMI130_GYRO_INT_STATUS2_ADDR
+
+/**< 2th bit of Interrupt status 2 register */
+#define SMI130_GYRO_INT_STATUS2_ANY_FIRSTZ_INT__POS 2
+#define SMI130_GYRO_INT_STATUS2_ANY_FIRSTZ_INT__LEN 1
+#define SMI130_GYRO_INT_STATUS2_ANY_FIRSTZ_INT__MSK 0x04
+#define SMI130_GYRO_INT_STATUS2_ANY_FIRSTZ_INT__REG SMI130_GYRO_INT_STATUS2_ADDR
+
+/**< 1st bit of Interrupt status 2 register */
+#define SMI130_GYRO_INT_STATUS2_ANY_FIRSTY_INT__POS 1
+#define SMI130_GYRO_INT_STATUS2_ANY_FIRSTY_INT__LEN 1
+#define SMI130_GYRO_INT_STATUS2_ANY_FIRSTY_INT__MSK 0x02
+#define SMI130_GYRO_INT_STATUS2_ANY_FIRSTY_INT__REG SMI130_GYRO_INT_STATUS2_ADDR
+
+/**< 0th bit of Interrupt status 2 register */
+#define SMI130_GYRO_INT_STATUS2_ANY_FIRSTX_INT__POS 0
+#define SMI130_GYRO_INT_STATUS2_ANY_FIRSTX_INT__LEN 1
+#define SMI130_GYRO_INT_STATUS2_ANY_FIRSTX_INT__MSK 0x01
+#define SMI130_GYRO_INT_STATUS2_ANY_FIRSTX_INT__REG SMI130_GYRO_INT_STATUS2_ADDR
+
+/**< 4 bits of Interrupt status 2 register */
+#define SMI130_GYRO_INT_STATUSTWO__POS 0
+#define SMI130_GYRO_INT_STATUSTWO__LEN 4
+#define SMI130_GYRO_INT_STATUSTWO__MSK 0x0F
+#define SMI130_GYRO_INT_STATUSTWO__REG SMI130_GYRO_INT_STATUS2_ADDR
+
+/* Interrupt status 3 Register */
+/**< 3th bit of Interrupt status 3 register */
+#define SMI130_GYRO_INT_STATUS3_HIGH_SIGN_INT__POS 3
+#define SMI130_GYRO_INT_STATUS3_HIGH_SIGN_INT__LEN 1
+#define SMI130_GYRO_INT_STATUS3_HIGH_SIGN_INT__MSK 0x08
+#define SMI130_GYRO_INT_STATUS3_HIGH_SIGN_INT__REG SMI130_GYRO_INT_STATUS3_ADDR
+
+/**< 2th bit of Interrupt status 3 register */
+#define SMI130_GYRO_INT_STATUS3_HIGH_FIRSTZ_INT__POS 2
+#define SMI130_GYRO_INT_STATUS3_HIGH_FIRSTZ_INT__LEN 1
+#define SMI130_GYRO_INT_STATUS3_HIGH_FIRSTZ_INT__MSK 0x04
+#define SMI130_GYRO_INT_STATUS3_HIGH_FIRSTZ_INT__REG SMI130_GYRO_INT_STATUS3_ADDR
+
+/**< 1st bit of Interrupt status 3 register */
+#define SMI130_GYRO_INT_STATUS3_HIGH_FIRSTY_INT__POS 1
+#define SMI130_GYRO_INT_STATUS3_HIGH_FIRSTY_INT__LEN 1
+#define SMI130_GYRO_INT_STATUS3_HIGH_FIRSTY_INT__MSK 0x02
+#define SMI130_GYRO_INT_STATUS3_HIGH_FIRSTY_INT__REG SMI130_GYRO_INT_STATUS3_ADDR
+
+/**< 0th bit of Interrupt status 3 register */
+#define SMI130_GYRO_INT_STATUS3_HIGH_FIRSTX_INT__POS 0
+#define SMI130_GYRO_INT_STATUS3_HIGH_FIRSTX_INT__LEN 1
+#define SMI130_GYRO_INT_STATUS3_HIGH_FIRSTX_INT__MSK 0x01
+#define SMI130_GYRO_INT_STATUS3_HIGH_FIRSTX_INT__REG SMI130_GYRO_INT_STATUS3_ADDR
+
+/**< LSB 4 bits of Interrupt status 3 register */
+#define SMI130_GYRO_INT_STATUSTHREE__POS 0
+#define SMI130_GYRO_INT_STATUSTHREE__LEN 4
+#define SMI130_GYRO_INT_STATUSTHREE__MSK 0x0F
+#define SMI130_GYRO_INT_STATUSTHREE__REG SMI130_GYRO_INT_STATUS3_ADDR
+
+/* SMI130_GYRO FIFO Status Register */
+/**< 7th bit of FIFO status Register */
+#define SMI130_GYRO_FIFO_STATUS_OVERRUN__POS 7
+#define SMI130_GYRO_FIFO_STATUS_OVERRUN__LEN 1
+#define SMI130_GYRO_FIFO_STATUS_OVERRUN__MSK 0x80
+#define SMI130_GYRO_FIFO_STATUS_OVERRUN__REG SMI130_GYRO_FIFO_STATUS_ADDR
+
+/**< First 7 bits of FIFO status Register */
+#define SMI130_GYRO_FIFO_STATUS_FRAME_COUNTER__POS 0
+#define SMI130_GYRO_FIFO_STATUS_FRAME_COUNTER__LEN 7
+#define SMI130_GYRO_FIFO_STATUS_FRAME_COUNTER__MSK 0x7F
+#define SMI130_GYRO_FIFO_STATUS_FRAME_COUNTER__REG SMI130_GYRO_FIFO_STATUS_ADDR
+
+/**< First 3 bits of range Registers */
+#define SMI130_GYRO_RANGE_ADDR_RANGE__POS 0
+#define SMI130_GYRO_RANGE_ADDR_RANGE__LEN 3
+#define SMI130_GYRO_RANGE_ADDR_RANGE__MSK 0x07
+#define SMI130_GYRO_RANGE_ADDR_RANGE__REG SMI130_GYRO_RANGE_ADDR
+
+/**< Last bit of Bandwidth Registers */
+#define SMI130_GYRO_BW_ADDR_HIGH_RES__POS 7
+#define SMI130_GYRO_BW_ADDR_HIGH_RES__LEN 1
+#define SMI130_GYRO_BW_ADDR_HIGH_RES__MSK 0x80
+#define SMI130_GYRO_BW_ADDR_HIGH_RES__REG SMI130_GYRO_BW_ADDR
+
+/**< First 3 bits of Bandwidth Registers */
+#define SMI130_GYRO_BW_ADDR__POS 0
+#define SMI130_GYRO_BW_ADDR__LEN 3
+#define SMI130_GYRO_BW_ADDR__MSK 0x07
+#define SMI130_GYRO_BW_ADDR__REG SMI130_GYRO_BW_ADDR
+
+/**< 6th bit of Bandwidth Registers */
+#define SMI130_GYRO_BW_ADDR_IMG_STB__POS 6
+#define SMI130_GYRO_BW_ADDR_IMG_STB__LEN 1
+#define SMI130_GYRO_BW_ADDR_IMG_STB__MSK 0x40
+#define SMI130_GYRO_BW_ADDR_IMG_STB__REG SMI130_GYRO_BW_ADDR
+
+/**< 5th and 7th bit of LPM1 Register */
+#define SMI130_GYRO_MODE_LPM1__POS 5
+#define SMI130_GYRO_MODE_LPM1__LEN 3
+#define SMI130_GYRO_MODE_LPM1__MSK 0xA0
+#define SMI130_GYRO_MODE_LPM1__REG SMI130_GYRO_MODE_LPM1_ADDR
+
+/**< 1st to 3rd bit of LPM1 Register */
+#define SMI130_GYRO_MODELPM1_ADDR_SLEEPDUR__POS 1
+#define SMI130_GYRO_MODELPM1_ADDR_SLEEPDUR__LEN 3
+#define SMI130_GYRO_MODELPM1_ADDR_SLEEPDUR__MSK 0x0E
+#define SMI130_GYRO_MODELPM1_ADDR_SLEEPDUR__REG SMI130_GYRO_MODE_LPM1_ADDR
+
+/**< 7th bit of Mode LPM2 Register */
+#define SMI130_GYRO_MODE_LPM2_ADDR_FAST_POWERUP__POS 7
+#define SMI130_GYRO_MODE_LPM2_ADDR_FAST_POWERUP__LEN 1
+#define SMI130_GYRO_MODE_LPM2_ADDR_FAST_POWERUP__MSK 0x80
+#define SMI130_GYRO_MODE_LPM2_ADDR_FAST_POWERUP__REG SMI130_GYRO_MODE_LPM2_ADDR
+
+/**< 6th bit of Mode LPM2 Register */
+#define SMI130_GYRO_MODE_LPM2_ADDR_ADV_POWERSAVING__POS 6
+#define SMI130_GYRO_MODE_LPM2_ADDR_ADV_POWERSAVING__LEN 1
+#define SMI130_GYRO_MODE_LPM2_ADDR_ADV_POWERSAVING__MSK 0x40
+#define SMI130_GYRO_MODE_LPM2_ADDR_ADV_POWERSAVING__REG SMI130_GYRO_MODE_LPM2_ADDR
+
+/**< 4th & 5th bit of Mode LPM2 Register */
+#define SMI130_GYRO_MODE_LPM2_ADDR_EXT_TRI_SEL__POS 4
+#define SMI130_GYRO_MODE_LPM2_ADDR_EXT_TRI_SEL__LEN 2
+#define SMI130_GYRO_MODE_LPM2_ADDR_EXT_TRI_SEL__MSK 0x30
+#define SMI130_GYRO_MODE_LPM2_ADDR_EXT_TRI_SEL__REG SMI130_GYRO_MODE_LPM2_ADDR
+
+/**< 0th to 2nd bit of LPM2 Register */
+#define SMI130_GYRO_MODE_LPM2_ADDR_AUTOSLEEPDUR__POS 0
+#define SMI130_GYRO_MODE_LPM2_ADDR_AUTOSLEEPDUR__LEN 3
+#define SMI130_GYRO_MODE_LPM2_ADDR_AUTOSLEEPDUR__MSK 0x07
+#define SMI130_GYRO_MODE_LPM2_ADDR_AUTOSLEEPDUR__REG SMI130_GYRO_MODE_LPM2_ADDR
+
+/**< 7th bit of HBW Register */
+#define SMI130_GYRO_RATED_HBW_ADDR_DATA_HIGHBW__POS 7
+#define SMI130_GYRO_RATED_HBW_ADDR_DATA_HIGHBW__LEN 1
+#define SMI130_GYRO_RATED_HBW_ADDR_DATA_HIGHBW__MSK 0x80
+#define SMI130_GYRO_RATED_HBW_ADDR_DATA_HIGHBW__REG SMI130_GYRO_RATED_HBW_ADDR
+
+/**< 6th bit of HBW Register */
+#define SMI130_GYRO_RATED_HBW_ADDR_SHADOW_DIS__POS 6
+#define SMI130_GYRO_RATED_HBW_ADDR_SHADOW_DIS__LEN 1
+#define SMI130_GYRO_RATED_HBW_ADDR_SHADOW_DIS__MSK 0x40
+#define SMI130_GYRO_RATED_HBW_ADDR_SHADOW_DIS__REG SMI130_GYRO_RATED_HBW_ADDR
+
+/**< 7th bit of Interrupt Enable 0 Registers */
+#define SMI130_GYRO_INT_ENABLE0_DATAEN__POS 7
+#define SMI130_GYRO_INT_ENABLE0_DATAEN__LEN 1
+#define SMI130_GYRO_INT_ENABLE0_DATAEN__MSK 0x80
+#define SMI130_GYRO_INT_ENABLE0_DATAEN__REG SMI130_GYRO_INT_ENABLE0_ADDR
+
+/**< 6th bit of Interrupt Enable 0 Registers */
+#define SMI130_GYRO_INT_ENABLE0_FIFOEN__POS 6
+#define SMI130_GYRO_INT_ENABLE0_FIFOEN__LEN 1
+#define SMI130_GYRO_INT_ENABLE0_FIFOEN__MSK 0x40
+#define SMI130_GYRO_INT_ENABLE0_FIFOEN__REG SMI130_GYRO_INT_ENABLE0_ADDR
+
+/**< 2nd bit of Interrupt Enable 0 Registers */
+#define SMI130_GYRO_INT_ENABLE0_AUTO_OFFSETEN__POS 2
+#define SMI130_GYRO_INT_ENABLE0_AUTO_OFFSETEN__LEN 1
+#define SMI130_GYRO_INT_ENABLE0_AUTO_OFFSETEN__MSK 0x04
+#define SMI130_GYRO_INT_ENABLE0_AUTO_OFFSETEN__REG SMI130_GYRO_INT_ENABLE0_ADDR
+
+/**< 3rd bit of Interrupt Enable 1 Registers */
+#define SMI130_GYRO_INT_ENABLE1_IT2_OD__POS 3
+#define SMI130_GYRO_INT_ENABLE1_IT2_OD__LEN 1
+#define SMI130_GYRO_INT_ENABLE1_IT2_OD__MSK 0x08
+#define SMI130_GYRO_INT_ENABLE1_IT2_OD__REG SMI130_GYRO_INT_ENABLE1_ADDR
+
+/**< 2nd bit of Interrupt Enable 1 Registers */
+#define SMI130_GYRO_INT_ENABLE1_IT2_LVL__POS 2
+#define SMI130_GYRO_INT_ENABLE1_IT2_LVL__LEN 1
+#define SMI130_GYRO_INT_ENABLE1_IT2_LVL__MSK 0x04
+#define SMI130_GYRO_INT_ENABLE1_IT2_LVL__REG SMI130_GYRO_INT_ENABLE1_ADDR
+
+/**< 1st bit of Interrupt Enable 1 Registers */
+#define SMI130_GYRO_INT_ENABLE1_IT1_OD__POS 1
+#define SMI130_GYRO_INT_ENABLE1_IT1_OD__LEN 1
+#define SMI130_GYRO_INT_ENABLE1_IT1_OD__MSK 0x02
+#define SMI130_GYRO_INT_ENABLE1_IT1_OD__REG SMI130_GYRO_INT_ENABLE1_ADDR
+
+/**< 0th bit of Interrupt Enable 1 Registers */
+#define SMI130_GYRO_INT_ENABLE1_IT1_LVL__POS 0
+#define SMI130_GYRO_INT_ENABLE1_IT1_LVL__LEN 1
+#define SMI130_GYRO_INT_ENABLE1_IT1_LVL__MSK 0x01
+#define SMI130_GYRO_INT_ENABLE1_IT1_LVL__REG SMI130_GYRO_INT_ENABLE1_ADDR
+
+/**< 3rd bit of Interrupt MAP 0 Registers */
+#define SMI130_GYRO_INT_MAP_0_INT1_HIGH__POS 3
+#define SMI130_GYRO_INT_MAP_0_INT1_HIGH__LEN 1
+#define SMI130_GYRO_INT_MAP_0_INT1_HIGH__MSK 0x08
+#define SMI130_GYRO_INT_MAP_0_INT1_HIGH__REG SMI130_GYRO_INT_MAP_0_ADDR
+
+/**< 1st bit of Interrupt MAP 0 Registers */
+#define SMI130_GYRO_INT_MAP_0_INT1_ANY__POS 1
+#define SMI130_GYRO_INT_MAP_0_INT1_ANY__LEN 1
+#define SMI130_GYRO_INT_MAP_0_INT1_ANY__MSK 0x02
+#define SMI130_GYRO_INT_MAP_0_INT1_ANY__REG SMI130_GYRO_INT_MAP_0_ADDR
+
+/**< 7th bit of MAP_1Registers */
+#define SMI130_GYRO_MAP_1_INT2_DATA__POS 7
+#define SMI130_GYRO_MAP_1_INT2_DATA__LEN 1
+#define SMI130_GYRO_MAP_1_INT2_DATA__MSK 0x80
+#define SMI130_GYRO_MAP_1_INT2_DATA__REG SMI130_GYRO_INT_MAP_1_ADDR
+
+/**< 6th bit of MAP_1Registers */
+#define SMI130_GYRO_MAP_1_INT2_FAST_OFFSET__POS 6
+#define SMI130_GYRO_MAP_1_INT2_FAST_OFFSET__LEN 1
+#define SMI130_GYRO_MAP_1_INT2_FAST_OFFSET__MSK 0x40
+#define SMI130_GYRO_MAP_1_INT2_FAST_OFFSET__REG SMI130_GYRO_INT_MAP_1_ADDR
+
+/**< 5th bit of MAP_1Registers */
+#define SMI130_GYRO_MAP_1_INT2_FIFO__POS 5
+#define SMI130_GYRO_MAP_1_INT2_FIFO__LEN 1
+#define SMI130_GYRO_MAP_1_INT2_FIFO__MSK 0x20
+#define SMI130_GYRO_MAP_1_INT2_FIFO__REG SMI130_GYRO_INT_MAP_1_ADDR
+
+/**< 4th bit of MAP_1Registers */
+#define SMI130_GYRO_MAP_1_INT2_AUTO_OFFSET__POS 4
+#define SMI130_GYRO_MAP_1_INT2_AUTO_OFFSET__LEN 1
+#define SMI130_GYRO_MAP_1_INT2_AUTO_OFFSET__MSK 0x10
+#define SMI130_GYRO_MAP_1_INT2_AUTO_OFFSET__REG SMI130_GYRO_INT_MAP_1_ADDR
+
+/**< 3rd bit of MAP_1Registers */
+#define SMI130_GYRO_MAP_1_INT1_AUTO_OFFSET__POS 3
+#define SMI130_GYRO_MAP_1_INT1_AUTO_OFFSET__LEN 1
+#define SMI130_GYRO_MAP_1_INT1_AUTO_OFFSET__MSK 0x08
+#define SMI130_GYRO_MAP_1_INT1_AUTO_OFFSET__REG SMI130_GYRO_INT_MAP_1_ADDR
+
+/**< 2nd bit of MAP_1Registers */
+#define SMI130_GYRO_MAP_1_INT1_FIFO__POS 2
+#define SMI130_GYRO_MAP_1_INT1_FIFO__LEN 1
+#define SMI130_GYRO_MAP_1_INT1_FIFO__MSK 0x04
+#define SMI130_GYRO_MAP_1_INT1_FIFO__REG SMI130_GYRO_INT_MAP_1_ADDR
+
+/**< 1st bit of MAP_1Registers */
+#define SMI130_GYRO_MAP_1_INT1_FAST_OFFSET__POS 1
+#define SMI130_GYRO_MAP_1_INT1_FAST_OFFSET__LEN 1
+#define SMI130_GYRO_MAP_1_INT1_FAST_OFFSET__MSK 0x02
+#define SMI130_GYRO_MAP_1_INT1_FAST_OFFSET__REG SMI130_GYRO_INT_MAP_1_ADDR
+
+/**< 0th bit of MAP_1Registers */
+#define SMI130_GYRO_MAP_1_INT1_DATA__POS 0
+#define SMI130_GYRO_MAP_1_INT1_DATA__LEN 1
+#define SMI130_GYRO_MAP_1_INT1_DATA__MSK 0x01
+#define SMI130_GYRO_MAP_1_INT1_DATA__REG SMI130_GYRO_INT_MAP_1_ADDR
+
+/**< 3rd bit of Interrupt Map 2 Registers */
+#define SMI130_GYRO_INT_MAP_2_INT2_HIGH__POS 3
+#define SMI130_GYRO_INT_MAP_2_INT2_HIGH__LEN 1
+#define SMI130_GYRO_INT_MAP_2_INT2_HIGH__MSK 0x08
+#define SMI130_GYRO_INT_MAP_2_INT2_HIGH__REG SMI130_GYRO_INT_MAP_2_ADDR
+
+/**< 1st bit of Interrupt Map 2 Registers */
+#define SMI130_GYRO_INT_MAP_2_INT2_ANY__POS 1
+#define SMI130_GYRO_INT_MAP_2_INT2_ANY__LEN 1
+#define SMI130_GYRO_INT_MAP_2_INT2_ANY__MSK 0x02
+#define SMI130_GYRO_INT_MAP_2_INT2_ANY__REG SMI130_GYRO_INT_MAP_2_ADDR
+
+/**< 5th bit of Interrupt 0 Registers */
+#define SMI130_GYRO_INT_0_ADDR_SLOW_OFFSET_UNFILT__POS 5
+#define SMI130_GYRO_INT_0_ADDR_SLOW_OFFSET_UNFILT__LEN 1
+#define SMI130_GYRO_INT_0_ADDR_SLOW_OFFSET_UNFILT__MSK 0x20
+#define SMI130_GYRO_INT_0_ADDR_SLOW_OFFSET_UNFILT__REG SMI130_GYRO_INT_0_ADDR
+
+/**< 3rd bit of Interrupt 0 Registers */
+#define SMI130_GYRO_INT_0_ADDR_HIGH_UNFILT_DATA__POS 3
+#define SMI130_GYRO_INT_0_ADDR_HIGH_UNFILT_DATA__LEN 1
+#define SMI130_GYRO_INT_0_ADDR_HIGH_UNFILT_DATA__MSK 0x08
+#define SMI130_GYRO_INT_0_ADDR_HIGH_UNFILT_DATA__REG SMI130_GYRO_INT_0_ADDR
+
+/**< 1st bit of Interrupt 0 Registers */
+#define SMI130_GYRO_INT_0_ADDR_ANY_UNFILT_DATA__POS 1
+#define SMI130_GYRO_INT_0_ADDR_ANY_UNFILT_DATA__LEN 1
+#define SMI130_GYRO_INT_0_ADDR_ANY_UNFILT_DATA__MSK 0x02
+#define SMI130_GYRO_INT_0_ADDR_ANY_UNFILT_DATA__REG SMI130_GYRO_INT_0_ADDR
+
+/**< 7th bit of INT_1 Registers */
+#define SMI130_GYRO_INT_1_ADDR_FAST_OFFSET_UNFILT__POS 7
+#define SMI130_GYRO_INT_1_ADDR_FAST_OFFSET_UNFILT__LEN 1
+#define SMI130_GYRO_INT_1_ADDR_FAST_OFFSET_UNFILT__MSK 0x80
+#define SMI130_GYRO_INT_1_ADDR_FAST_OFFSET_UNFILT__REG SMI130_GYRO_INT_1_ADDR
+
+/**< First 7 bits of INT_1 Registers */
+#define SMI130_GYRO_INT_1_ADDR_ANY_TH__POS 0
+#define SMI130_GYRO_INT_1_ADDR_ANY_TH__LEN 7
+#define SMI130_GYRO_INT_1_ADDR_ANY_TH__MSK 0x7F
+#define SMI130_GYRO_INT_1_ADDR_ANY_TH__REG SMI130_GYRO_INT_1_ADDR
+
+/**< Last 2 bits of INT 2Registers */
+#define SMI130_GYRO_INT_2_ADDR_AWAKE_DUR__POS 6
+#define SMI130_GYRO_INT_2_ADDR_AWAKE_DUR__LEN 2
+#define SMI130_GYRO_INT_2_ADDR_AWAKE_DUR__MSK 0xC0
+#define SMI130_GYRO_INT_2_ADDR_AWAKE_DUR__REG SMI130_GYRO_INT_2_ADDR
+
+/**< 4th & 5th bit of INT 2Registers */
+#define SMI130_GYRO_INT_2_ADDR_ANY_DURSAMPLE__POS 4
+#define SMI130_GYRO_INT_2_ADDR_ANY_DURSAMPLE__LEN 2
+#define SMI130_GYRO_INT_2_ADDR_ANY_DURSAMPLE__MSK 0x30
+#define SMI130_GYRO_INT_2_ADDR_ANY_DURSAMPLE__REG SMI130_GYRO_INT_2_ADDR
+
+/**< 2nd bit of INT 2Registers */
+#define SMI130_GYRO_INT_2_ADDR_ANY_EN_Z__POS 2
+#define SMI130_GYRO_INT_2_ADDR_ANY_EN_Z__LEN 1
+#define SMI130_GYRO_INT_2_ADDR_ANY_EN_Z__MSK 0x04
+#define SMI130_GYRO_INT_2_ADDR_ANY_EN_Z__REG SMI130_GYRO_INT_2_ADDR
+
+/**< 1st bit of INT 2Registers */
+#define SMI130_GYRO_INT_2_ADDR_ANY_EN_Y__POS 1
+#define SMI130_GYRO_INT_2_ADDR_ANY_EN_Y__LEN 1
+#define SMI130_GYRO_INT_2_ADDR_ANY_EN_Y__MSK 0x02
+#define SMI130_GYRO_INT_2_ADDR_ANY_EN_Y__REG SMI130_GYRO_INT_2_ADDR
+
+/**< 0th bit of INT 2Registers */
+#define SMI130_GYRO_INT_2_ADDR_ANY_EN_X__POS 0
+#define SMI130_GYRO_INT_2_ADDR_ANY_EN_X__LEN 1
+#define SMI130_GYRO_INT_2_ADDR_ANY_EN_X__MSK 0x01
+#define SMI130_GYRO_INT_2_ADDR_ANY_EN_X__REG SMI130_GYRO_INT_2_ADDR
+
+/**< Last bit of INT 4 Registers */
+#define SMI130_GYRO_INT_4_FIFO_WM_EN__POS 7
+#define SMI130_GYRO_INT_4_FIFO_WM_EN__LEN 1
+#define SMI130_GYRO_INT_4_FIFO_WM_EN__MSK 0x80
+#define SMI130_GYRO_INT_4_FIFO_WM_EN__REG SMI130_GYRO_INT_4_ADDR
+
+/**< Last bit of Reset Latch Registers */
+#define SMI130_GYRO_RST_LATCH_ADDR_RESET_INT__POS 7
+#define SMI130_GYRO_RST_LATCH_ADDR_RESET_INT__LEN 1
+#define SMI130_GYRO_RST_LATCH_ADDR_RESET_INT__MSK 0x80
+#define SMI130_GYRO_RST_LATCH_ADDR_RESET_INT__REG SMI130_GYRO_RST_LATCH_ADDR
+
+/**< 6th bit of Reset Latch Registers */
+#define SMI130_GYRO_RST_LATCH_ADDR_OFFSET_RESET__POS 6
+#define SMI130_GYRO_RST_LATCH_ADDR_OFFSET_RESET__LEN 1
+#define SMI130_GYRO_RST_LATCH_ADDR_OFFSET_RESET__MSK 0x40
+#define SMI130_GYRO_RST_LATCH_ADDR_OFFSET_RESET__REG SMI130_GYRO_RST_LATCH_ADDR
+
+/**< 4th bit of Reset Latch Registers */
+#define SMI130_GYRO_RST_LATCH_ADDR_LATCH_STATUS__POS 4
+#define SMI130_GYRO_RST_LATCH_ADDR_LATCH_STATUS__LEN 1
+#define SMI130_GYRO_RST_LATCH_ADDR_LATCH_STATUS__MSK 0x10
+#define SMI130_GYRO_RST_LATCH_ADDR_LATCH_STATUS__REG SMI130_GYRO_RST_LATCH_ADDR
+
+/**< First 4 bits of Reset Latch Registers */
+#define SMI130_GYRO_RST_LATCH_ADDR_LATCH_INT__POS 0
+#define SMI130_GYRO_RST_LATCH_ADDR_LATCH_INT__LEN 4
+#define SMI130_GYRO_RST_LATCH_ADDR_LATCH_INT__MSK 0x0F
+#define SMI130_GYRO_RST_LATCH_ADDR_LATCH_INT__REG SMI130_GYRO_RST_LATCH_ADDR
+
+/**< Last 2 bits of HIGH_TH_X Registers */
+#define SMI130_GYRO_HIGH_HY_X__POS 6
+#define SMI130_GYRO_HIGH_HY_X__LEN 2
+#define SMI130_GYRO_HIGH_HY_X__MSK 0xC0
+#define SMI130_GYRO_HIGH_HY_X__REG SMI130_GYRO_HIGH_TH_X_ADDR
+
+/**< 5 bits of HIGH_TH_X Registers */
+#define SMI130_GYRO_HIGH_TH_X__POS 1
+#define SMI130_GYRO_HIGH_TH_X__LEN 5
+#define SMI130_GYRO_HIGH_TH_X__MSK 0x3E
+#define SMI130_GYRO_HIGH_TH_X__REG SMI130_GYRO_HIGH_TH_X_ADDR
+
+/**< 0th bit of HIGH_TH_X Registers */
+#define SMI130_GYRO_HIGH_EN_X__POS 0
+#define SMI130_GYRO_HIGH_EN_X__LEN 1
+#define SMI130_GYRO_HIGH_EN_X__MSK 0x01
+#define SMI130_GYRO_HIGH_EN_X__REG SMI130_GYRO_HIGH_TH_X_ADDR
+
+/**< Last 2 bits of HIGH_TH_Y Registers */
+#define SMI130_GYRO_HIGH_HY_Y__POS 6
+#define SMI130_GYRO_HIGH_HY_Y__LEN 2
+#define SMI130_GYRO_HIGH_HY_Y__MSK 0xC0
+#define SMI130_GYRO_HIGH_HY_Y__REG SMI130_GYRO_HIGH_TH_Y_ADDR
+
+/**< 5 bits of HIGH_TH_Y Registers */
+#define SMI130_GYRO_HIGH_TH_Y__POS 1
+#define SMI130_GYRO_HIGH_TH_Y__LEN 5
+#define SMI130_GYRO_HIGH_TH_Y__MSK 0x3E
+#define SMI130_GYRO_HIGH_TH_Y__REG SMI130_GYRO_HIGH_TH_Y_ADDR
+
+/**< 0th bit of HIGH_TH_Y Registers */
+#define SMI130_GYRO_HIGH_EN_Y__POS 0
+#define SMI130_GYRO_HIGH_EN_Y__LEN 1
+#define SMI130_GYRO_HIGH_EN_Y__MSK 0x01
+#define SMI130_GYRO_HIGH_EN_Y__REG SMI130_GYRO_HIGH_TH_Y_ADDR
+
+/**< Last 2 bits of HIGH_TH_Z Registers */
+#define SMI130_GYRO_HIGH_HY_Z__POS 6
+#define SMI130_GYRO_HIGH_HY_Z__LEN 2
+#define SMI130_GYRO_HIGH_HY_Z__MSK 0xC0
+#define SMI130_GYRO_HIGH_HY_Z__REG SMI130_GYRO_HIGH_TH_Z_ADDR
+
+/**< 5 bits of HIGH_TH_Z Registers */
+#define SMI130_GYRO_HIGH_TH_Z__POS 1
+#define SMI130_GYRO_HIGH_TH_Z__LEN 5
+#define SMI130_GYRO_HIGH_TH_Z__MSK 0x3E
+#define SMI130_GYRO_HIGH_TH_Z__REG SMI130_GYRO_HIGH_TH_Z_ADDR
+
+/**< 0th bit of HIGH_TH_Z Registers */
+#define SMI130_GYRO_HIGH_EN_Z__POS 0
+#define SMI130_GYRO_HIGH_EN_Z__LEN 1
+#define SMI130_GYRO_HIGH_EN_Z__MSK 0x01
+#define SMI130_GYRO_HIGH_EN_Z__REG SMI130_GYRO_HIGH_TH_Z_ADDR
+
+/**< Last 3 bits of INT OFF0 Registers */
+#define SMI130_GYRO_SLOW_OFFSET_TH__POS 6
+#define SMI130_GYRO_SLOW_OFFSET_TH__LEN 2
+#define SMI130_GYRO_SLOW_OFFSET_TH__MSK 0xC0
+#define SMI130_GYRO_SLOW_OFFSET_TH__REG SMI130_GYRO_SOC_ADDR
+
+/**< 2 bits of INT OFF0 Registers */
+#define SMI130_GYRO_SLOW_OFFSET_DUR__POS 3
+#define SMI130_GYRO_SLOW_OFFSET_DUR__LEN 3
+#define SMI130_GYRO_SLOW_OFFSET_DUR__MSK 0x38
+#define SMI130_GYRO_SLOW_OFFSET_DUR__REG SMI130_GYRO_SOC_ADDR
+
+/**< 2nd bit of INT OFF0 Registers */
+#define SMI130_GYRO_SLOW_OFFSET_EN_Z__POS 2
+#define SMI130_GYRO_SLOW_OFFSET_EN_Z__LEN 1
+#define SMI130_GYRO_SLOW_OFFSET_EN_Z__MSK 0x04
+#define SMI130_GYRO_SLOW_OFFSET_EN_Z__REG SMI130_GYRO_SOC_ADDR
+
+/**< 1st bit of INT OFF0 Registers */
+#define SMI130_GYRO_SLOW_OFFSET_EN_Y__POS 1
+#define SMI130_GYRO_SLOW_OFFSET_EN_Y__LEN 1
+#define SMI130_GYRO_SLOW_OFFSET_EN_Y__MSK 0x02
+#define SMI130_GYRO_SLOW_OFFSET_EN_Y__REG SMI130_GYRO_SOC_ADDR
+
+/**< 0th bit of INT OFF0 Registers */
+#define SMI130_GYRO_SLOW_OFFSET_EN_X__POS 0
+#define SMI130_GYRO_SLOW_OFFSET_EN_X__LEN 1
+#define SMI130_GYRO_SLOW_OFFSET_EN_X__MSK 0x01
+#define SMI130_GYRO_SLOW_OFFSET_EN_X__REG SMI130_GYRO_SOC_ADDR
+
+/**< Last 2 bits of INT OFF1 Registers */
+#define SMI130_GYRO_AUTO_OFFSET_WL__POS 6
+#define SMI130_GYRO_AUTO_OFFSET_WL__LEN 2
+#define SMI130_GYRO_AUTO_OFFSET_WL__MSK 0xC0
+#define SMI130_GYRO_AUTO_OFFSET_WL__REG SMI130_GYRO_A_FOC_ADDR
+
+/**< 2 bits of INT OFF1 Registers */
+#define SMI130_GYRO_FAST_OFFSET_WL__POS 4
+#define SMI130_GYRO_FAST_OFFSET_WL__LEN 2
+#define SMI130_GYRO_FAST_OFFSET_WL__MSK 0x30
+#define SMI130_GYRO_FAST_OFFSET_WL__REG SMI130_GYRO_A_FOC_ADDR
+
+/**< 3nd bit of INT OFF1 Registers */
+#define SMI130_GYRO_FAST_OFFSET_EN__POS 3
+#define SMI130_GYRO_FAST_OFFSET_EN__LEN 1
+#define SMI130_GYRO_FAST_OFFSET_EN__MSK 0x08
+#define SMI130_GYRO_FAST_OFFSET_EN__REG SMI130_GYRO_A_FOC_ADDR
+
+/**< 2nd bit of INT OFF1 Registers */
+#define SMI130_GYRO_FAST_OFFSET_EN_Z__POS 2
+#define SMI130_GYRO_FAST_OFFSET_EN_Z__LEN 1
+#define SMI130_GYRO_FAST_OFFSET_EN_Z__MSK 0x04
+#define SMI130_GYRO_FAST_OFFSET_EN_Z__REG SMI130_GYRO_A_FOC_ADDR
+
+/**< 1st bit of INT OFF1 Registers */
+#define SMI130_GYRO_FAST_OFFSET_EN_Y__POS 1
+#define SMI130_GYRO_FAST_OFFSET_EN_Y__LEN 1
+#define SMI130_GYRO_FAST_OFFSET_EN_Y__MSK 0x02
+#define SMI130_GYRO_FAST_OFFSET_EN_Y__REG SMI130_GYRO_A_FOC_ADDR
+
+/**< 0th bit of INT OFF1 Registers */
+#define SMI130_GYRO_FAST_OFFSET_EN_X__POS 0
+#define SMI130_GYRO_FAST_OFFSET_EN_X__LEN 1
+#define SMI130_GYRO_FAST_OFFSET_EN_X__MSK 0x01
+#define SMI130_GYRO_FAST_OFFSET_EN_X__REG SMI130_GYRO_A_FOC_ADDR
+
+/**< 0 to 2 bits of INT OFF1 Registers */
+#define SMI130_GYRO_FAST_OFFSET_EN_XYZ__POS 0
+#define SMI130_GYRO_FAST_OFFSET_EN_XYZ__LEN 3
+#define SMI130_GYRO_FAST_OFFSET_EN_XYZ__MSK 0x07
+#define SMI130_GYRO_FAST_OFFSET_EN_XYZ__REG SMI130_GYRO_A_FOC_ADDR
+
+/**< Last 4 bits of Trim NVM control Registers */
+#define SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_REMAIN__POS 4
+#define SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_REMAIN__LEN 4
+#define SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_REMAIN__MSK 0xF0
+#define SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_REMAIN__REG \
+SMI130_GYRO_TRIM_NVM_CTRL_ADDR
+
+/**< 3rd bit of Trim NVM control Registers */
+#define SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_LOAD__POS 3
+#define SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_LOAD__LEN 1
+#define SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_LOAD__MSK 0x08
+#define SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_LOAD__REG \
+SMI130_GYRO_TRIM_NVM_CTRL_ADDR
+
+/**< 2nd bit of Trim NVM control Registers */
+#define SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_RDY__POS 2
+#define SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_RDY__LEN 1
+#define SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_RDY__MSK 0x04
+#define SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_RDY__REG \
+SMI130_GYRO_TRIM_NVM_CTRL_ADDR
+
+ /**< 1st bit of Trim NVM control Registers */
+#define SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_PROG_TRIG__POS 1
+#define SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_PROG_TRIG__LEN 1
+#define SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_PROG_TRIG__MSK 0x02
+#define SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_PROG_TRIG__REG \
+SMI130_GYRO_TRIM_NVM_CTRL_ADDR
+
+/**< 0th bit of Trim NVM control Registers */
+#define SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_PROG_MODE__POS 0
+#define SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_PROG_MODE__LEN 1
+#define SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_PROG_MODE__MSK 0x01
+#define SMI130_GYRO_TRIM_NVM_CTRL_ADDR_NVM_PROG_MODE__REG \
+SMI130_GYRO_TRIM_NVM_CTRL_ADDR
+
+ /**< 2nd bit of SPI3 WDT Registers */
+#define SMI130_GYRO_BGW_SPI3_WDT_ADDR_I2C_WDT_EN__POS 2
+#define SMI130_GYRO_BGW_SPI3_WDT_ADDR_I2C_WDT_EN__LEN 1
+#define SMI130_GYRO_BGW_SPI3_WDT_ADDR_I2C_WDT_EN__MSK 0x04
+#define SMI130_GYRO_BGW_SPI3_WDT_ADDR_I2C_WDT_EN__REG \
+SMI130_GYRO_BGW_SPI3_WDT_ADDR
+
+ /**< 1st bit of SPI3 WDT Registers */
+#define SMI130_GYRO_BGW_SPI3_WDT_ADDR_I2C_WDT_SEL__POS 1
+#define SMI130_GYRO_BGW_SPI3_WDT_ADDR_I2C_WDT_SEL__LEN 1
+#define SMI130_GYRO_BGW_SPI3_WDT_ADDR_I2C_WDT_SEL__MSK 0x02
+#define SMI130_GYRO_BGW_SPI3_WDT_ADDR_I2C_WDT_SEL__REG \
+SMI130_GYRO_BGW_SPI3_WDT_ADDR
+
+/**< 0th bit of SPI3 WDT Registers */
+#define SMI130_GYRO_BGW_SPI3_WDT_ADDR_SPI3__POS 0
+#define SMI130_GYRO_BGW_SPI3_WDT_ADDR_SPI3__LEN 1
+#define SMI130_GYRO_BGW_SPI3_WDT_ADDR_SPI3__MSK 0x01
+#define SMI130_GYRO_BGW_SPI3_WDT_ADDR_SPI3__REG \
+SMI130_GYRO_BGW_SPI3_WDT_ADDR
+
+/**< 4th bit of Self test Registers */
+#define SMI130_GYRO_SELF_TEST_ADDR_RATEOK__POS 4
+#define SMI130_GYRO_SELF_TEST_ADDR_RATEOK__LEN 1
+#define SMI130_GYRO_SELF_TEST_ADDR_RATEOK__MSK 0x10
+#define SMI130_GYRO_SELF_TEST_ADDR_RATEOK__REG \
+SMI130_GYRO_SELF_TEST_ADDR
+
+/**< 2nd bit of Self test Registers */
+#define SMI130_GYRO_SELF_TEST_ADDR_BISTFAIL__POS 2
+#define SMI130_GYRO_SELF_TEST_ADDR_BISTFAIL__LEN 1
+#define SMI130_GYRO_SELF_TEST_ADDR_BISTFAIL__MSK 0x04
+#define SMI130_GYRO_SELF_TEST_ADDR_BISTFAIL__REG \
+SMI130_GYRO_SELF_TEST_ADDR
+
+/**< 1st bit of Self test Registers */
+#define SMI130_GYRO_SELF_TEST_ADDR_BISTRDY__POS 1
+#define SMI130_GYRO_SELF_TEST_ADDR_BISTRDY__LEN 1
+#define SMI130_GYRO_SELF_TEST_ADDR_BISTRDY__MSK 0x02
+#define SMI130_GYRO_SELF_TEST_ADDR_BISTRDY__REG \
+SMI130_GYRO_SELF_TEST_ADDR
+
+/**< 0th bit of Self test Registers */
+#define SMI130_GYRO_SELF_TEST_ADDR_TRIGBIST__POS 0
+#define SMI130_GYRO_SELF_TEST_ADDR_TRIGBIST__LEN 1
+#define SMI130_GYRO_SELF_TEST_ADDR_TRIGBIST__MSK 0x01
+#define SMI130_GYRO_SELF_TEST_ADDR_TRIGBIST__REG \
+SMI130_GYRO_SELF_TEST_ADDR
+
+/**< 7th bit of FIFO CGF1 Registers */
+#define SMI130_GYRO_FIFO_CGF1_ADDR_TAG__POS 7
+#define SMI130_GYRO_FIFO_CGF1_ADDR_TAG__LEN 1
+#define SMI130_GYRO_FIFO_CGF1_ADDR_TAG__MSK 0x80
+#define SMI130_GYRO_FIFO_CGF1_ADDR_TAG__REG SMI130_GYRO_FIFO_CGF1_ADDR
+
+/**< First 7 bits of FIFO CGF1 Registers */
+#define SMI130_GYRO_FIFO_CGF1_ADDR_WML__POS 0
+#define SMI130_GYRO_FIFO_CGF1_ADDR_WML__LEN 7
+#define SMI130_GYRO_FIFO_CGF1_ADDR_WML__MSK 0x7F
+#define SMI130_GYRO_FIFO_CGF1_ADDR_WML__REG SMI130_GYRO_FIFO_CGF1_ADDR
+
+/**< Last 2 bits of FIFO CGF0 Addr Registers */
+#define SMI130_GYRO_FIFO_CGF0_ADDR_MODE__POS 6
+#define SMI130_GYRO_FIFO_CGF0_ADDR_MODE__LEN 2
+#define SMI130_GYRO_FIFO_CGF0_ADDR_MODE__MSK 0xC0
+#define SMI130_GYRO_FIFO_CGF0_ADDR_MODE__REG SMI130_GYRO_FIFO_CGF0_ADDR
+
+/**< First 2 bits of FIFO CGF0 Addr Registers */
+#define SMI130_GYRO_FIFO_CGF0_ADDR_DATA_SEL__POS 0
+#define SMI130_GYRO_FIFO_CGF0_ADDR_DATA_SEL__LEN 2
+#define SMI130_GYRO_FIFO_CGF0_ADDR_DATA_SEL__MSK 0x03
+#define SMI130_GYRO_FIFO_CGF0_ADDR_DATA_SEL__REG SMI130_GYRO_FIFO_CGF0_ADDR
+
+ /**< Last 2 bits of INL Offset MSB Registers */
+#define SMI130_GYRO_OFC1_ADDR_OFFSET_X__POS 6
+#define SMI130_GYRO_OFC1_ADDR_OFFSET_X__LEN 2
+#define SMI130_GYRO_OFC1_ADDR_OFFSET_X__MSK 0xC0
+#define SMI130_GYRO_OFC1_ADDR_OFFSET_X__REG SMI130_GYRO_OFC1_ADDR
+
+/**< 3 bits of INL Offset MSB Registers */
+#define SMI130_GYRO_OFC1_ADDR_OFFSET_Y__POS 3
+#define SMI130_GYRO_OFC1_ADDR_OFFSET_Y__LEN 3
+#define SMI130_GYRO_OFC1_ADDR_OFFSET_Y__MSK 0x38
+#define SMI130_GYRO_OFC1_ADDR_OFFSET_Y__REG SMI130_GYRO_OFC1_ADDR
+
+/**< First 3 bits of INL Offset MSB Registers */
+#define SMI130_GYRO_OFC1_ADDR_OFFSET_Z__POS 0
+#define SMI130_GYRO_OFC1_ADDR_OFFSET_Z__LEN 3
+#define SMI130_GYRO_OFC1_ADDR_OFFSET_Z__MSK 0x07
+#define SMI130_GYRO_OFC1_ADDR_OFFSET_Z__REG SMI130_GYRO_OFC1_ADDR
+
+/**< 4 bits of Trim GP0 Registers */
+#define SMI130_GYRO_TRIM_GP0_ADDR_GP0__POS 4
+#define SMI130_GYRO_TRIM_GP0_ADDR_GP0__LEN 4
+#define SMI130_GYRO_TRIM_GP0_ADDR_GP0__MSK 0xF0
+#define SMI130_GYRO_TRIM_GP0_ADDR_GP0__REG SMI130_GYRO_TRIM_GP0_ADDR
+
+/**< 2 bits of Trim GP0 Registers */
+#define SMI130_GYRO_TRIM_GP0_ADDR_OFFSET_X__POS 2
+#define SMI130_GYRO_TRIM_GP0_ADDR_OFFSET_X__LEN 2
+#define SMI130_GYRO_TRIM_GP0_ADDR_OFFSET_X__MSK 0x0C
+#define SMI130_GYRO_TRIM_GP0_ADDR_OFFSET_X__REG SMI130_GYRO_TRIM_GP0_ADDR
+
+/**< 1st bit of Trim GP0 Registers */
+#define SMI130_GYRO_TRIM_GP0_ADDR_OFFSET_Y__POS 1
+#define SMI130_GYRO_TRIM_GP0_ADDR_OFFSET_Y__LEN 1
+#define SMI130_GYRO_TRIM_GP0_ADDR_OFFSET_Y__MSK 0x02
+#define SMI130_GYRO_TRIM_GP0_ADDR_OFFSET_Y__REG SMI130_GYRO_TRIM_GP0_ADDR
+
+/**< First bit of Trim GP0 Registers */
+#define SMI130_GYRO_TRIM_GP0_ADDR_OFFSET_Z__POS 0
+#define SMI130_GYRO_TRIM_GP0_ADDR_OFFSET_Z__LEN 1
+#define SMI130_GYRO_TRIM_GP0_ADDR_OFFSET_Z__MSK 0x01
+#define SMI130_GYRO_TRIM_GP0_ADDR_OFFSET_Z__REG SMI130_GYRO_TRIM_GP0_ADDR
+
+/* For Axis Selection */
+/**< It refers SMI130_GYRO X-axis */
+#define SMI130_GYRO_X_AXIS 0
+/**< It refers SMI130_GYRO Y-axis */
+#define SMI130_GYRO_Y_AXIS 1
+/**< It refers SMI130_GYRO Z-axis */
+#define SMI130_GYRO_Z_AXIS 2
+
+/* For Mode Settings */
+#define SMI130_GYRO_MODE_NORMAL 0
+#define SMI130_GYRO_MODE_DEEPSUSPEND 1
+#define SMI130_GYRO_MODE_SUSPEND 2
+#define SMI130_GYRO_MODE_FASTPOWERUP 3
+#define SMI130_GYRO_MODE_ADVANCEDPOWERSAVING 4
+
+/* get bit slice */
+#define SMI130_GYRO_GET_BITSLICE(regvar, bitname)\
+((regvar & bitname##__MSK) >> bitname##__POS)
+
+/* Set bit slice */
+#define SMI130_GYRO_SET_BITSLICE(regvar, bitname, val)\
+((regvar&~bitname##__MSK)|((val<<bitname##__POS)&bitname##__MSK))
+/* Constants */
+
+#define SMI130_GYRO_NULL 0
+/**< constant declaration of NULL */
+#define SMI130_GYRO_DISABLE 0
+/**< It refers SMI130_GYRO disable */
+#define SMI130_GYRO_ENABLE 1
+/**< It refers SMI130_GYRO enable */
+#define SMI130_GYRO_OFF 0
+/**< It refers SMI130_GYRO OFF state */
+#define SMI130_GYRO_ON 1
+/**< It refers SMI130_GYRO ON state */
+
+
+#define SMI130_GYRO_TURN1 0
+/**< It refers SMI130_GYRO TURN1 */
+#define SMI130_GYRO_TURN2 1
+/**< It refers SMI130_GYRO TURN2 */
+
+#define SMI130_GYRO_INT1 0
+/**< It refers SMI130_GYRO INT1 */
+#define SMI130_GYRO_INT2 1
+/**< It refers SMI130_GYRO INT2 */
+
+#define SMI130_GYRO_SLOW_OFFSET 0
+/**< It refers SMI130_GYRO Slow Offset */
+#define SMI130_GYRO_AUTO_OFFSET 1
+/**< It refers SMI130_GYRO Auto Offset */
+#define SMI130_GYRO_FAST_OFFSET 2
+/**< It refers SMI130_GYRO Fast Offset */
+#define SMI130_GYRO_S_TAP 0
+/**< It refers SMI130_GYRO Single Tap */
+#define SMI130_GYRO_D_TAP 1
+/**< It refers SMI130_GYRO Double Tap */
+#define SMI130_GYRO_INT1_DATA 0
+/**< It refers SMI130_GYRO Int1 Data */
+#define SMI130_GYRO_INT2_DATA 1
+/**< It refers SMI130_GYRO Int2 Data */
+#define SMI130_GYRO_TAP_UNFILT_DATA 0
+/**< It refers SMI130_GYRO Tap unfilt data */
+#define SMI130_GYRO_HIGH_UNFILT_DATA 1
+/**< It refers SMI130_GYRO High unfilt data */
+#define SMI130_GYRO_CONST_UNFILT_DATA 2
+/**< It refers SMI130_GYRO Const unfilt data */
+#define SMI130_GYRO_ANY_UNFILT_DATA 3
+/**< It refers SMI130_GYRO Any unfilt data */
+#define SMI130_GYRO_SHAKE_UNFILT_DATA 4
+/**< It refers SMI130_GYRO Shake unfilt data */
+#define SMI130_GYRO_SHAKE_TH 0
+/**< It refers SMI130_GYRO Shake Threshold */
+#define SMI130_GYRO_SHAKE_TH2 1
+/**< It refers SMI130_GYRO Shake Threshold2 */
+#define SMI130_GYRO_AUTO_OFFSET_WL 0
+/**< It refers SMI130_GYRO Auto Offset word length */
+#define SMI130_GYRO_FAST_OFFSET_WL 1
+/**< It refers SMI130_GYRO Fast Offset word length */
+#define SMI130_GYRO_I2C_WDT_EN 0
+/**< It refers SMI130_GYRO I2C WDT En */
+#define SMI130_GYRO_I2C_WDT_SEL 1
+/**< It refers SMI130_GYRO I2C WDT Sel */
+#define SMI130_GYRO_EXT_MODE 0
+/**< It refers SMI130_GYRO Ext Mode */
+#define SMI130_GYRO_EXT_PAGE 1
+/**< It refers SMI130_GYRO Ext page */
+#define SMI130_GYRO_START_ADDR 0
+/**< It refers SMI130_GYRO Start Address */
+#define SMI130_GYRO_STOP_ADDR 1
+/**< It refers SMI130_GYRO Stop Address */
+#define SMI130_GYRO_SLOW_CMD 0
+/**< It refers SMI130_GYRO Slow Command */
+#define SMI130_GYRO_FAST_CMD 1
+/**< It refers SMI130_GYRO Fast Command */
+#define SMI130_GYRO_TRIM_VRA 0
+/**< It refers SMI130_GYRO Trim VRA */
+#define SMI130_GYRO_TRIM_VRD 1
+/**< It refers SMI130_GYRO Trim VRD */
+#define SMI130_GYRO_LOGBIT_EM 0
+/**< It refers SMI130_GYRO LogBit Em */
+#define SMI130_GYRO_LOGBIT_VM 1
+/**< It refers SMI130_GYRO LogBit VM */
+#define SMI130_GYRO_GP0 0
+/**< It refers SMI130_GYRO GP0 */
+#define SMI130_GYRO_GP1 1
+/**< It refers SMI130_GYRO GP1*/
+#define SMI130_GYRO_LOW_SPEED 0
+/**< It refers SMI130_GYRO Low Speed Oscillator */
+#define SMI130_GYRO_HIGH_SPEED 1
+/**< It refers SMI130_GYRO High Speed Oscillator */
+#define SMI130_GYRO_DRIVE_OFFSET_P 0
+/**< It refers SMI130_GYRO Drive Offset P */
+#define SMI130_GYRO_DRIVE_OFFSET_N 1
+/**< It refers SMI130_GYRO Drive Offset N */
+#define SMI130_GYRO_TEST_MODE_EN 0
+/**< It refers SMI130_GYRO Test Mode Enable */
+#define SMI130_GYRO_TEST_MODE_REG 1
+/**< It refers SMI130_GYRO Test Mode reg */
+#define SMI130_GYRO_IBIAS_DRIVE_TRIM 0
+/**< It refers SMI130_GYRO IBIAS Drive Trim */
+#define SMI130_GYRO_IBIAS_RATE_TRIM 1
+/**< It refers SMI130_GYRO IBIAS Rate Trim */
+#define SMI130_GYRO_BAA_MODE 0
+/**< It refers SMI130_GYRO BAA Mode Trim */
+#define SMI130_GYRO_SMI_ACC_MODE 1
+/**< It refers SMI130_GYRO SMI_ACC Mode Trim */
+#define SMI130_GYRO_PI_KP 0
+/**< It refers SMI130_GYRO PI KP */
+#define SMI130_GYRO_PI_KI 1
+/**< It refers SMI130_GYRO PI KI */
+
+
+#define C_SMI130_GYRO_SUCCESS 0
+/**< It refers SMI130_GYRO operation is success */
+#define C_SMI130_GYRO_FAILURE 1
+/**< It refers SMI130_GYRO operation is Failure */
+
+#define SMI130_GYRO_SPI_RD_MASK 0x80
+/**< Read mask **/
+#define SMI130_GYRO_READ_SET 0x01
+/**< Setting for rading data **/
+
+#define SMI130_GYRO_SHIFT_1_POSITION 1
+/**< Shift bit by 1 Position **/
+#define SMI130_GYRO_SHIFT_2_POSITION 2
+/**< Shift bit by 2 Position **/
+#define SMI130_GYRO_SHIFT_3_POSITION 3
+/**< Shift bit by 3 Position **/
+#define SMI130_GYRO_SHIFT_4_POSITION 4
+/**< Shift bit by 4 Position **/
+#define SMI130_GYRO_SHIFT_5_POSITION 5
+/**< Shift bit by 5 Position **/
+#define SMI130_GYRO_SHIFT_6_POSITION 6
+/**< Shift bit by 6 Position **/
+#define SMI130_GYRO_SHIFT_7_POSITION 7
+/**< Shift bit by 7 Position **/
+#define SMI130_GYRO_SHIFT_8_POSITION 8
+/**< Shift bit by 8 Position **/
+#define SMI130_GYRO_SHIFT_12_POSITION 12
+/**< Shift bit by 12 Position **/
+
+#define C_SMI130_GYRO_Null_U8X 0
+#define C_SMI130_GYRO_Zero_U8X 0
+#define C_SMI130_GYRO_One_U8X 1
+#define C_SMI130_GYRO_Two_U8X 2
+#define C_SMI130_GYRO_Three_U8X 3
+#define C_SMI130_GYRO_Four_U8X 4
+#define C_SMI130_GYRO_Five_U8X 5
+#define C_SMI130_GYRO_Six_U8X 6
+#define C_SMI130_GYRO_Seven_U8X 7
+#define C_SMI130_GYRO_Eight_U8X 8
+#define C_SMI130_GYRO_Nine_U8X 9
+#define C_SMI130_GYRO_Ten_U8X 10
+#define C_SMI130_GYRO_Eleven_U8X 11
+#define C_SMI130_GYRO_Twelve_U8X 12
+#define C_SMI130_GYRO_Thirteen_U8X 13
+#define C_SMI130_GYRO_Fifteen_U8X 15
+#define C_SMI130_GYRO_Sixteen_U8X 16
+#define C_SMI130_GYRO_TwentyTwo_U8X 22
+#define C_SMI130_GYRO_TwentyThree_U8X 23
+#define C_SMI130_GYRO_TwentyFour_U8X 24
+#define C_SMI130_GYRO_TwentyFive_U8X 25
+#define C_SMI130_GYRO_ThirtyTwo_U8X 32
+#define C_SMI130_GYRO_Hundred_U8X 100
+#define C_SMI130_GYRO_OneTwentySeven_U8X 127
+#define C_SMI130_GYRO_OneTwentyEight_U8X 128
+#define C_SMI130_GYRO_TwoFiftyFive_U8X 255
+#define C_SMI130_GYRO_TwoFiftySix_U16X 256
+
+#define E_SMI130_GYRO_NULL_PTR (signed char)(-127)
+#define E_SMI130_GYRO_COMM_RES (signed char)(-1)
+#define E_SMI130_GYRO_OUT_OF_RANGE (signed char)(-2)
+
+#define C_SMI130_GYRO_No_Filter_U8X 0
+#define C_SMI130_GYRO_BW_230Hz_U8X 1
+#define C_SMI130_GYRO_BW_116Hz_U8X 2
+#define C_SMI130_GYRO_BW_47Hz_U8X 3
+#define C_SMI130_GYRO_BW_23Hz_U8X 4
+#define C_SMI130_GYRO_BW_12Hz_U8X 5
+#define C_SMI130_GYRO_BW_64Hz_U8X 6
+#define C_SMI130_GYRO_BW_32Hz_U8X 7
+
+#define C_SMI130_GYRO_No_AutoSleepDur_U8X 0
+#define C_SMI130_GYRO_4ms_AutoSleepDur_U8X 1
+#define C_SMI130_GYRO_5ms_AutoSleepDur_U8X 2
+#define C_SMI130_GYRO_8ms_AutoSleepDur_U8X 3
+#define C_SMI130_GYRO_10ms_AutoSleepDur_U8X 4
+#define C_SMI130_GYRO_15ms_AutoSleepDur_U8X 5
+#define C_SMI130_GYRO_20ms_AutoSleepDur_U8X 6
+#define C_SMI130_GYRO_40ms_AutoSleepDur_U8X 7
+
+
+
+
+#define SMI130_GYRO_WR_FUNC_PTR int (*bus_write)\
+(unsigned char, unsigned char, unsigned char *, unsigned char)
+#define SMI130_GYRO_RD_FUNC_PTR int (*bus_read)\
+(unsigned char, unsigned char, unsigned char *, unsigned char)
+#define SMI130_GYRO_BRD_FUNC_PTR int (*burst_read)\
+(unsigned char, unsigned char, unsigned char *, SMI130_GYRO_S32)
+#define SMI130_GYRO_MDELAY_DATA_TYPE SMI130_GYRO_U16
+
+
+
+
+/*user defined Structures*/
+struct smi130_gyro_data_t {
+ SMI130_GYRO_S16 datax;
+ SMI130_GYRO_S16 datay;
+ SMI130_GYRO_S16 dataz;
+ char intstatus[5];
+};
+
+
+struct smi130_gyro_offset_t {
+ SMI130_GYRO_U16 datax;
+ SMI130_GYRO_U16 datay;
+ SMI130_GYRO_U16 dataz;
+};
+
+
+struct smi130_gyro_t {
+ unsigned char chip_id;
+ unsigned char dev_addr;
+ SMI130_GYRO_BRD_FUNC_PTR;
+ SMI130_GYRO_WR_FUNC_PTR;
+ SMI130_GYRO_RD_FUNC_PTR;
+ void(*delay_msec)(SMI130_GYRO_MDELAY_DATA_TYPE);
+};
+
+/***************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ***************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ***************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_init(struct smi130_gyro_t *p_smi130_gyro);
+/***************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ***************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_dataX(SMI130_GYRO_S16 *data_x);
+/****************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ***************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_dataY(SMI130_GYRO_S16 *data_y);
+/***************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ***************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_dataZ(SMI130_GYRO_S16 *data_z);
+/************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ***************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_dataXYZ(struct smi130_gyro_data_t *data);
+/***************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ********************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_dataXYZI(struct smi130_gyro_data_t *data);
+/********************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ********************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_Temperature(unsigned char *temperature);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_FIFO_data_reg
+(unsigned char *fifo_data);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_read_register(unsigned char addr,
+unsigned char *data, unsigned char len);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_burst_read(unsigned char addr,
+unsigned char *data, SMI130_GYRO_S32 len);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_write_register(unsigned char addr,
+unsigned char *data, unsigned char len);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_interrupt_status_reg_0
+(unsigned char *status0_data);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_interrupt_status_reg_1
+(unsigned char *status1_data);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_interrupt_status_reg_2
+(unsigned char *status2_data);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_interrupt_status_reg_3
+(unsigned char *status3_data);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_fifostatus_reg
+(unsigned char *fifo_status);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_range_reg
+(unsigned char *range);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_range_reg
+(unsigned char range);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_high_res
+(unsigned char *high_res);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_high_res
+(unsigned char high_res);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_bw(unsigned char *bandwidth);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_bw(unsigned char bandwidth);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_pmu_ext_tri_sel
+(unsigned char *pwu_ext_tri_sel);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_pmu_ext_tri_sel
+(unsigned char pwu_ext_tri_sel);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_high_bw
+(unsigned char *high_bw);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_high_bw
+(unsigned char high_bw);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_shadow_dis
+(unsigned char *shadow_dis);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_shadow_dis
+(unsigned char shadow_dis);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_soft_reset(void);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_data_enable(unsigned char *data_en);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_data_en(unsigned char data_en);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_fifo_enable(unsigned char *fifo_en);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_fifo_enable(unsigned char fifo_en);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_offset_enable
+(unsigned char mode, unsigned char *offset_en);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_offset_enable
+(unsigned char mode, unsigned char offset_en);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_int_od
+(unsigned char param, unsigned char *int_od);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_int_od
+(unsigned char param, unsigned char int_od);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_int_lvl
+(unsigned char param, unsigned char *int_lvl);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_int_lvl
+(unsigned char param, unsigned char int_lvl);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_int1_high
+(unsigned char *int1_high);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_int1_high
+(unsigned char int1_high);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_int1_any
+(unsigned char *int1_any);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_int1_any
+(unsigned char int1_any);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_int_data
+(unsigned char axis, unsigned char *int_data);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_int_data
+(unsigned char axis, unsigned char int_data);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_int2_offset
+(unsigned char axis, unsigned char *int2_offset);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_int2_offset
+(unsigned char axis, unsigned char int2_offset);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_int1_offset
+(unsigned char axis, unsigned char *int1_offset);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_int1_offset
+(unsigned char axis, unsigned char int1_offset);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_int_fifo(unsigned char *int_fifo);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_int_fifo
+(unsigned char axis, unsigned char int_fifo);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_int2_high
+(unsigned char *int2_high);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_int2_high
+(unsigned char int2_high);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_int2_any
+(unsigned char *int2_any);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_int2_any
+(unsigned char int2_any);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_offset_unfilt
+(unsigned char param, unsigned char *offset_unfilt);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_offset_unfilt
+(unsigned char param, unsigned char offset_unfilt);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_unfilt_data
+(unsigned char param, unsigned char *unfilt_data);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_unfilt_data
+(unsigned char param, unsigned char unfilt_data);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_any_th
+(unsigned char *any_th);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_any_th
+(unsigned char any_th);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_awake_dur
+(unsigned char *awake_dur);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_awake_dur
+(unsigned char awake_dur);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_any_dursample
+(unsigned char *dursample);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_any_dursample
+(unsigned char dursample);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_any_en_ch
+(unsigned char channel, unsigned char *data);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_any_en_ch
+(unsigned char channel, unsigned char data);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_fifo_watermark_enable
+(unsigned char *fifo_wn_en);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_fifo_watermark_enable
+(unsigned char fifo_wn_en);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_reset_int
+(unsigned char reset_int);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_offset_reset
+(unsigned char offset_reset);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_latch_status
+(unsigned char *latch_status);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_latch_status
+(unsigned char latch_status);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_latch_int
+(unsigned char *latch_int);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_latch_int
+(unsigned char latch_int);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_high_hy
+(unsigned char channel, unsigned char *high_hy);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_high_hy
+(unsigned char channel, unsigned char high_hy);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_high_th
+(unsigned char channel, unsigned char *high_th);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_high_th
+(unsigned char channel, unsigned char high_th);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_high_en_ch
+(unsigned char channel, unsigned char *high_en);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_high_en_ch
+(unsigned char channel, unsigned char high_en);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_high_dur_ch
+(unsigned char channel, unsigned char *high_dur);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_high_dur_ch
+(unsigned char channel, unsigned char high_dur);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_slow_offset_th
+(unsigned char *offset_th);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_slow_offset_th
+(unsigned char offset_th);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_slow_offset_dur
+(unsigned char *offset_dur);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_slow_offset_dur
+(unsigned char offset_dur);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_slow_offset_en_ch
+(unsigned char channel, unsigned char *slow_offset);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_slow_offset_en_ch
+(unsigned char channel, unsigned char slow_offset);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_offset_wl
+(unsigned char channel, unsigned char *offset_wl);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_offset_wl
+(unsigned char channel, unsigned char offset_wl);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_fast_offset_en
+(unsigned char fast_offset);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_fast_offset_en_ch
+(unsigned char *fast_offset);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_fast_offset_en_ch
+(unsigned char channel, unsigned char fast_offset);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_enable_fast_offset(void);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_nvm_remain
+(unsigned char *nvm_remain);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_nvm_load
+(unsigned char nvm_load);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_nvm_rdy
+(unsigned char *nvm_rdy);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_nvm_prog_trig
+(unsigned char prog_trig);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_nvm_prog_mode
+(unsigned char *prog_mode);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_nvm_prog_mode
+(unsigned char prog_mode);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_i2c_wdt
+(unsigned char i2c_wdt, unsigned char *prog_mode);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_i2c_wdt
+(unsigned char i2c_wdt, unsigned char prog_mode);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_spi3(unsigned char *spi3);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_spi3(unsigned char spi3);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_fifo_tag(unsigned char *tag);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_fifo_tag(unsigned char tag);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_fifo_watermarklevel
+(unsigned char *water_mark_level);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_fifo_watermarklevel
+(unsigned char water_mark_level);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_fifo_mode
+(unsigned char *mode);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_fifo_mode(unsigned char mode);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_fifo_data_sel
+(unsigned char *data_sel);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_fifo_data_sel
+(unsigned char data_sel);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_offset
+(unsigned char axis, SMI130_GYRO_S16 *offset);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_offset
+(unsigned char axis, SMI130_GYRO_S16 offset);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_gp
+(unsigned char param, unsigned char *value);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_gp
+(unsigned char param, unsigned char value);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_fifo_framecount
+(unsigned char *fifo_framecount);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_fifo_overrun
+(unsigned char *fifo_overrun);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_int2_fifo
+(unsigned char *int_fifo);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_int1_fifo
+(unsigned char *int_fifo);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_int2_fifo
+(unsigned char fifo_int2);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_int1_fifo
+(unsigned char fifo_int1);
+/****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_mode(unsigned char *mode);
+/*****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_mode(unsigned char mode);
+/*****************************************************************************
+ * Description: *//**\brief
+ *
+ *
+ *
+ *
+ * \param
+ *
+ *
+ * \return
+ *
+ *
+ ****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ ****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_selftest(unsigned char *result);
+/*****************************************************************************
+ * Description: *//**\brief This API is used to get data auto sleep duration
+ *
+ *
+ *
+ *
+ * \param unsigned char *duration : Address of auto sleep duration
+ * Pointer to a variable passed as a parameter
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_autosleepdur(unsigned char *duration);
+/*****************************************************************************
+ * Description: *//**\brief This API is used to set duration
+ *
+ *
+ *
+ *
+ * \param unsigned char duration:
+ * Value to be written passed as a parameter
+ * unsigned char bandwidth:
+ * Value to be written passed as a parameter
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_autosleepdur(unsigned char duration,
+unsigned char bandwith);
+/*****************************************************************************
+ * Description: *//**\brief This API is used to get data sleep duration
+ *
+ *
+ *
+ *
+ * \param unsigned char *duration : Address of sleep duration
+ * Pointer to a variable passed as a parameter
+ *
+ *
+ *
+ * \return
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_sleepdur(unsigned char *duration);
+/*****************************************************************************
+ * Description: *//**\brief This API is used to set duration
+ *
+ *
+ *
+ *
+ * \param unsigned char duration:
+ * Value to be written passed as a parameter
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_sleepdur(unsigned char duration);
+/*****************************************************************************
+ * Description: *//**\brief This API is used to set auto offset
+ *
+ *
+ *
+ *
+ * \param unsigned char duration:
+ * Value to be written passed as a parameter
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_set_auto_offset_en(unsigned char offset_en);
+/*****************************************************************************
+ * Description: *//**\brief This API is used to get auto offset
+ *
+ *
+ *
+ *
+ * \param unsigned char duration:
+ * Value to be written passed as a parameter
+ *
+ *
+ *
+ * \return communication results
+ *
+ *
+ *****************************************************************************/
+/* Scheduling:
+ *
+ *
+ *
+ * Usage guide:
+ *
+ *
+ * Remarks:
+ *
+ *****************************************************************************/
+SMI130_GYRO_RETURN_FUNCTION_TYPE smi130_gyro_get_auto_offset_en(
+unsigned char *offset_en);
+#endif
diff --git a/drivers/input/sensors/smi130/smi130_gyro_driver.c b/drivers/input/sensors/smi130/smi130_gyro_driver.c
new file mode 100644
index 0000000..65e303c
--- /dev/null
+++ b/drivers/input/sensors/smi130/smi130_gyro_driver.c
@@ -0,0 +1,2036 @@
+/*!
+ * @section LICENSE
+ * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved
+ *
+ * (C) Modification Copyright 2018 Robert Bosch Kft All Rights Reserved
+ *
+ * This software program is licensed subject to the GNU General
+ * Public License (GPL).Version 2,June 1991,
+ * available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * Special: Description of the Software:
+ *
+ * This software module (hereinafter called "Software") and any
+ * information on application-sheets (hereinafter called "Information") is
+ * provided free of charge for the sole purpose to support your application
+ * work.
+ *
+ * As such, the Software is merely an experimental software, not tested for
+ * safety in the field and only intended for inspiration for further development
+ * and testing. Any usage in a safety-relevant field of use (like automotive,
+ * seafaring, spacefaring, industrial plants etc.) was not intended, so there are
+ * no precautions for such usage incorporated in the Software.
+ *
+ * The Software is specifically designed for the exclusive use for Bosch
+ * Sensortec products by personnel who have special experience and training. Do
+ * not use this Software if you do not have the proper experience or training.
+ *
+ * This Software package is provided as is and without any expressed or
+ * implied warranties, including without limitation, the implied warranties of
+ * merchantability and fitness for a particular purpose.
+ *
+ * Bosch Sensortec and their representatives and agents deny any liability for
+ * the functional impairment of this Software in terms of fitness, performance
+ * and safety. Bosch Sensortec and their representatives and agents shall not be
+ * liable for any direct or indirect damages or injury, except as otherwise
+ * stipulated in mandatory applicable law.
+ * The Information provided is believed to be accurate and reliable. Bosch
+ * Sensortec assumes no responsibility for the consequences of use of such
+ * Information nor for any infringement of patents or other rights of third
+ * parties which may result from its use.
+ *
+ *------------------------------------------------------------------------------
+ * The following Product Disclaimer does not apply to the BSX4-HAL-4.1NoFusion Software
+ * which is licensed under the Apache License, Version 2.0 as stated above.
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Product Disclaimer
+ *
+ * Common:
+ *
+ * Assessment of Products Returned from Field
+ *
+ * Returned products are considered good if they fulfill the specifications /
+ * test data for 0-mileage and field listed in this document.
+ *
+ * Engineering Samples
+ *
+ * Engineering samples are marked with (e) or (E). Samples may vary from the
+ * valid technical specifications of the series product contained in this
+ * data sheet. Therefore, they are not intended or fit for resale to
+ * third parties or for use in end products. Their sole purpose is internal
+ * client testing. The testing of an engineering sample may in no way replace
+ * the testing of a series product. Bosch assumes no liability for the use
+ * of engineering samples. The purchaser shall indemnify Bosch from all claims
+ * arising from the use of engineering samples.
+ *
+ * Intended use
+ *
+ * Provided that SMI130 is used within the conditions (environment, application,
+ * installation, loads) as described in this TCD and the corresponding
+ * agreed upon documents, Bosch ensures that the product complies with
+ * the agreed properties. Agreements beyond this require
+ * the written approval by Bosch. The product is considered fit for the intended
+ * use when the product successfully has passed the tests
+ * in accordance with the TCD and agreed upon documents.
+ *
+ * It is the responsibility of the customer to ensure the proper application
+ * of the product in the overall system/vehicle.
+ *
+ * Bosch does not assume any responsibility for changes to the environment
+ * of the product that deviate from the TCD and the agreed upon documents
+ * as well as all applications not released by Bosch
+ *
+ * The resale and/or use of products are at the purchaser’s own risk and
+ * responsibility. The examination and testing of the SMI130
+ * is the sole responsibility of the purchaser.
+ *
+ * The purchaser shall indemnify Bosch from all third party claims
+ * arising from any product use not covered by the parameters of
+ * this product data sheet or not approved by Bosch and reimburse Bosch
+ * for all costs and damages in connection with such claims.
+ *
+ * The purchaser must monitor the market for the purchased products,
+ * particularly with regard to product safety, and inform Bosch without delay
+ * of all security relevant incidents.
+ *
+ * Application Examples and Hints
+ *
+ * With respect to any application examples, advice, normal values
+ * and/or any information regarding the application of the device,
+ * Bosch hereby disclaims any and all warranties and liabilities of any kind,
+ * including without limitation warranties of
+ * non-infringement of intellectual property rights or copyrights
+ * of any third party.
+ * The information given in this document shall in no event be regarded
+ * as a guarantee of conditions or characteristics. They are provided
+ * for illustrative purposes only and no evaluation regarding infringement
+ * of intellectual property rights or copyrights or regarding functionality,
+ * performance or error has been made.
+ * @filename smi130_gyro_driver.c
+ * @date 2015/11/17 13:44
+ * @Modification Date 2018/08/28 18:20
+ * @id "836294d"
+ * @version 1.5.9
+ *
+ * @brief SMI130_GYRO Linux Driver
+ */
+#ifdef __KERNEL__
+#include <linux/kernel.h>
+#include <linux/unistd.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#else
+#include <unistd.h>
+#include <sys/types.h>
+#include <string.h>
+#endif
+#include <linux/math64.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/of_irq.h>
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+
+#include "smi130_gyro.h"
+#include "bs_log.h"
+
+/* sensor specific */
+#define SENSOR_NAME "smi130_gyro"
+#define SMI130_GYRO_ENABLE_INT1 1
+#define SENSOR_CHIP_ID_SMI_GYRO (0x0f)
+#define CHECK_CHIP_ID_TIME_MAX 5
+#define DRIVER_VERSION "0.0.53.0"
+#define SMI_GYRO_USE_FIFO 1
+#define SMI_GYRO_USE_BASIC_I2C_FUNC 1
+#define SMI_GYRO_REG_NAME(name) SMI130_GYRO_##name
+#define SMI_GYRO_VAL_NAME(name) SMI130_GYRO_##name
+#define SMI_GYRO_CALL_API(name) smi130_gyro_##name
+#define MSC_TIME 6
+
+#define SMI_GYRO_I2C_WRITE_DELAY_TIME 1
+
+/* generic */
+#define SMI_GYRO_MAX_RETRY_I2C_XFER (100)
+#define SMI_GYRO_MAX_RETRY_WAKEUP (5)
+#define SMI_GYRO_MAX_RETRY_WAIT_DRDY (100)
+
+#define SMI_GYRO_DELAY_MIN (1)
+#define SMI_GYRO_DELAY_DEFAULT (200)
+
+#define SMI_GYRO_VALUE_MAX (32767)
+#define SMI_GYRO_VALUE_MIN (-32768)
+
+#define BYTES_PER_LINE (16)
+
+#define SMI_GYRO_SELF_TEST 0
+
+#define SMI_GYRO_SOFT_RESET_VALUE 0xB6
+
+#ifdef SMI_GYRO_USE_FIFO
+#define MAX_FIFO_F_LEVEL 100
+#define MAX_FIFO_F_BYTES 8
+#define SMI130_GYRO_FIFO_DAT_SEL_X 1
+#define SMI130_GYRO_FIFO_DAT_SEL_Y 2
+#define SMI130_GYRO_FIFO_DAT_SEL_Z 3
+#endif
+
+/*!
+ * @brief:BMI058 feature
+ * macro definition
+*/
+#ifdef CONFIG_SENSORS_BMI058
+/*! BMI058 X AXIS definition*/
+#define BMI058_X_AXIS SMI130_GYRO_Y_AXIS
+/*! BMI058 Y AXIS definition*/
+#define BMI058_Y_AXIS SMI130_GYRO_X_AXIS
+
+#define C_BMI058_One_U8X 1
+#define C_BMI058_Two_U8X 2
+#endif
+
+/*! Bosch sensor unknown place*/
+#define BOSCH_SENSOR_PLACE_UNKNOWN (-1)
+/*! Bosch sensor remapping table size P0~P7*/
+#define MAX_AXIS_REMAP_TAB_SZ 8
+
+
+struct bosch_sensor_specific {
+ char *name;
+ /* 0 to 7 */
+ int place;
+ int irq;
+ int (*irq_gpio_cfg)(void);
+};
+
+
+/*!
+ * we use a typedef to hide the detail,
+ * because this type might be changed
+ */
+struct bosch_sensor_axis_remap {
+ /* src means which source will be mapped to target x, y, z axis */
+ /* if an target OS axis is remapped from (-)x,
+ * src is 0, sign_* is (-)1 */
+ /* if an target OS axis is remapped from (-)y,
+ * src is 1, sign_* is (-)1 */
+ /* if an target OS axis is remapped from (-)z,
+ * src is 2, sign_* is (-)1 */
+ int src_x:3;
+ int src_y:3;
+ int src_z:3;
+
+ int sign_x:2;
+ int sign_y:2;
+ int sign_z:2;
+};
+
+
+struct bosch_sensor_data {
+ union {
+ int16_t v[3];
+ struct {
+ int16_t x;
+ int16_t y;
+ int16_t z;
+ };
+ };
+};
+
+struct smi_gyro_client_data {
+ struct smi130_gyro_t device;
+ struct i2c_client *client;
+ struct input_dev *input;
+ struct delayed_work work;
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ struct early_suspend early_suspend_handler;
+#endif
+
+ atomic_t delay;
+ uint8_t debug_level;
+ struct smi130_gyro_data_t value;
+ u8 enable:1;
+ unsigned int fifo_count;
+ unsigned char fifo_datasel;
+ uint64_t timestamp;
+ uint64_t base_time;
+ uint64_t fifo_time;
+ uint64_t gyro_count;
+ uint64_t time_odr;
+ /* controls not only reg, but also workqueue */
+ struct mutex mutex_op_mode;
+ struct mutex mutex_enable;
+ struct bosch_sensor_specific *bosch_pd;
+ struct work_struct report_data_work;
+ int is_timer_running;
+ struct hrtimer timer;
+ ktime_t work_delay_kt;
+ uint8_t gpio_pin;
+ int16_t IRQ;
+ struct work_struct irq_work;
+};
+
+static struct i2c_client *smi_gyro_client;
+/* i2c operation for API */
+static int smi_gyro_i2c_read(struct i2c_client *client, u8 reg_addr,
+ u8 *data, u8 len);
+static int smi_gyro_i2c_write(struct i2c_client *client, u8 reg_addr,
+ u8 *data, u8 len);
+
+static void smi_gyro_dump_reg(struct i2c_client *client);
+static int smi_gyro_check_chip_id(struct i2c_client *client);
+
+static int smi_gyro_pre_suspend(struct i2c_client *client);
+static int smi_gyro_post_resume(struct i2c_client *client);
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void smi_gyro_early_suspend(struct early_suspend *handler);
+static void smi_gyro_late_resume(struct early_suspend *handler);
+#endif
+
+static void smi130_gyro_delay(SMI130_GYRO_U16 msec)
+{
+ if (msec <= 20)
+ usleep_range(msec * 1000, msec * 1000);
+ else
+ msleep(msec);
+}
+
+/*!
+* SMI130_GYRO sensor remapping function
+* need to give some parameter in BSP files first.
+*/
+static const struct bosch_sensor_axis_remap
+ bosch_axis_remap_tab_dft[MAX_AXIS_REMAP_TAB_SZ] = {
+ /* src_x src_y src_z sign_x sign_y sign_z */
+ { 0, 1, 2, 1, 1, 1 }, /* P0 */
+ { 1, 0, 2, 1, -1, 1 }, /* P1 */
+ { 0, 1, 2, -1, -1, 1 }, /* P2 */
+ { 1, 0, 2, -1, 1, 1 }, /* P3 */
+
+ { 0, 1, 2, -1, 1, -1 }, /* P4 */
+ { 1, 0, 2, -1, -1, -1 }, /* P5 */
+ { 0, 1, 2, 1, -1, -1 }, /* P6 */
+ { 1, 0, 2, 1, 1, -1 }, /* P7 */
+};
+
+static void bosch_remap_sensor_data(struct bosch_sensor_data *data,
+ const struct bosch_sensor_axis_remap *remap)
+{
+ struct bosch_sensor_data tmp;
+
+ tmp.x = data->v[remap->src_x] * remap->sign_x;
+ tmp.y = data->v[remap->src_y] * remap->sign_y;
+ tmp.z = data->v[remap->src_z] * remap->sign_z;
+
+ memcpy(data, &tmp, sizeof(*data));
+}
+
+static void bosch_remap_sensor_data_dft_tab(struct bosch_sensor_data *data,
+ int place)
+{
+/* sensor with place 0 needs not to be remapped */
+ if ((place <= 0) || (place >= MAX_AXIS_REMAP_TAB_SZ))
+ return;
+ bosch_remap_sensor_data(data, &bosch_axis_remap_tab_dft[place]);
+}
+
+static void smi130_gyro_remap_sensor_data(struct smi130_gyro_data_t *val,
+ struct smi_gyro_client_data *client_data)
+{
+ struct bosch_sensor_data bsd;
+ int place;
+
+ if ((NULL == client_data->bosch_pd) || (BOSCH_SENSOR_PLACE_UNKNOWN
+ == client_data->bosch_pd->place))
+ place = BOSCH_SENSOR_PLACE_UNKNOWN;
+ else
+ place = client_data->bosch_pd->place;
+
+#ifdef CONFIG_SENSORS_BMI058
+/*x,y need to be invesed becase of HW Register for BMI058*/
+ bsd.y = val->datax;
+ bsd.x = val->datay;
+ bsd.z = val->dataz;
+#else
+ bsd.x = val->datax;
+ bsd.y = val->datay;
+ bsd.z = val->dataz;
+#endif
+
+ bosch_remap_sensor_data_dft_tab(&bsd, place);
+
+ val->datax = bsd.x;
+ val->datay = bsd.y;
+ val->dataz = bsd.z;
+
+}
+
+static int smi_gyro_check_chip_id(struct i2c_client *client)
+{
+ int err = -1;
+ u8 chip_id = 0;
+ u8 read_count = 0;
+
+ while (read_count++ < CHECK_CHIP_ID_TIME_MAX) {
+ smi_gyro_i2c_read(client, SMI_GYRO_REG_NAME(CHIP_ID_ADDR), &chip_id, 1);
+ PINFO("read chip id result: %#x", chip_id);
+
+ if ((chip_id & 0xff) != SENSOR_CHIP_ID_SMI_GYRO) {
+ smi130_gyro_delay(1);
+ } else {
+ err = 0;
+ break;
+ }
+ }
+ return err;
+}
+
+static void smi_gyro_dump_reg(struct i2c_client *client)
+{
+ int i;
+ u8 dbg_buf[64];
+ u8 dbg_buf_str[64 * 3 + 1] = "";
+
+ for (i = 0; i < BYTES_PER_LINE; i++) {
+ dbg_buf[i] = i;
+ snprintf(dbg_buf_str + i * 3, 16, "%02x%c",
+ dbg_buf[i],
+ (((i + 1) % BYTES_PER_LINE == 0) ? '\n' : ' '));
+ }
+ dev_dbg(&client->dev, "%s\n", dbg_buf_str);
+
+ smi_gyro_i2c_read(client, SMI_GYRO_REG_NAME(CHIP_ID_ADDR), dbg_buf, 64);
+ for (i = 0; i < 64; i++) {
+ snprintf(dbg_buf_str + i * 3, 16, "%02x%c",
+ dbg_buf[i],
+ (((i + 1) % BYTES_PER_LINE == 0) ? '\n' : ' '));
+ }
+ dev_dbg(&client->dev, "%s\n", dbg_buf_str);
+}
+
+/*i2c read routine for API*/
+static int smi_gyro_i2c_read(struct i2c_client *client, u8 reg_addr,
+ u8 *data, u8 len)
+{
+#if !defined SMI_GYRO_USE_BASIC_I2C_FUNC
+ s32 dummy;
+ if (NULL == client)
+ return -ENODEV;
+
+ while (0 != len--) {
+#ifdef SMI_GYRO_SMBUS
+ dummy = i2c_smbus_read_byte_data(client, reg_addr);
+ if (dummy < 0) {
+ dev_err(&client->dev, "i2c bus read error");
+ return -EIO;
+ }
+ *data = (u8)(dummy & 0xff);
+#else
+ dummy = i2c_master_send(client, (char *)®_addr, 1);
+ if (dummy < 0)
+ return -EIO;
+
+ dummy = i2c_master_recv(client, (char *)data, 1);
+ if (dummy < 0)
+ return -EIO;
+#endif
+ reg_addr++;
+ data++;
+ }
+ return 0;
+#else
+ int retry;
+
+ struct i2c_msg msg[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 1,
+ .buf = ®_addr,
+ },
+
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = len,
+ .buf = data,
+ },
+ };
+
+ for (retry = 0; retry < SMI_GYRO_MAX_RETRY_I2C_XFER; retry++) {
+ if (i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)) > 0)
+ break;
+ else
+ smi130_gyro_delay(SMI_GYRO_I2C_WRITE_DELAY_TIME);
+ }
+
+ if (SMI_GYRO_MAX_RETRY_I2C_XFER <= retry) {
+ dev_err(&client->dev, "I2C xfer error");
+ return -EIO;
+ }
+
+ return 0;
+#endif
+}
+
+#ifdef SMI_GYRO_USE_FIFO
+static int smi_gyro_i2c_burst_read(struct i2c_client *client, u8 reg_addr,
+ u8 *data, u16 len)
+{
+ int retry;
+
+ struct i2c_msg msg[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 1,
+ .buf = ®_addr,
+ },
+
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = len,
+ .buf = data,
+ },
+ };
+
+ for (retry = 0; retry < SMI_GYRO_MAX_RETRY_I2C_XFER; retry++) {
+ if (i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)) > 0)
+ break;
+ else
+ smi130_gyro_delay(SMI_GYRO_I2C_WRITE_DELAY_TIME);
+ }
+
+ if (SMI_GYRO_MAX_RETRY_I2C_XFER <= retry) {
+ dev_err(&client->dev, "I2C xfer error");
+ return -EIO;
+ }
+
+ return 0;
+}
+#endif
+
+/*i2c write routine for */
+static int smi_gyro_i2c_write(struct i2c_client *client, u8 reg_addr,
+ u8 *data, u8 len)
+{
+#if !defined SMI_GYRO_USE_BASIC_I2C_FUNC
+ s32 dummy;
+
+#ifndef SMI_GYRO_SMBUS
+ u8 buffer[2];
+#endif
+
+ if (NULL == client)
+ return -ENODEV;
+
+ while (0 != len--) {
+#ifdef SMI_GYRO_SMBUS
+ dummy = i2c_smbus_write_byte_data(client, reg_addr, *data);
+#else
+ buffer[0] = reg_addr;
+ buffer[1] = *data;
+ dummy = i2c_master_send(client, (char *)buffer, 2);
+#endif
+ reg_addr++;
+ data++;
+ if (dummy < 0) {
+ dev_err(&client->dev, "error writing i2c bus");
+ return -EIO;
+ }
+
+ }
+ return 0;
+#else
+ u8 buffer[2];
+ int retry;
+ struct i2c_msg msg[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 2,
+ .buf = buffer,
+ },
+ };
+
+ while (0 != len--) {
+ buffer[0] = reg_addr;
+ buffer[1] = *data;
+ for (retry = 0; retry < SMI_GYRO_MAX_RETRY_I2C_XFER; retry++) {
+ if (i2c_transfer(client->adapter, msg,
+ ARRAY_SIZE(msg)) > 0) {
+ break;
+ } else {
+ smi130_gyro_delay(SMI_GYRO_I2C_WRITE_DELAY_TIME);
+ }
+ }
+ if (SMI_GYRO_MAX_RETRY_I2C_XFER <= retry) {
+ dev_err(&client->dev, "I2C xfer error");
+ return -EIO;
+ }
+ reg_addr++;
+ data++;
+ }
+
+ return 0;
+#endif
+}
+
+static int smi_gyro_i2c_read_wrapper(u8 dev_addr, u8 reg_addr, u8 *data, u8 len)
+{
+ int err;
+ err = smi_gyro_i2c_read(smi_gyro_client, reg_addr, data, len);
+ return err;
+}
+
+static int smi_gyro_i2c_write_wrapper(u8 dev_addr, u8 reg_addr, u8 *data, u8 len)
+{
+ int err;
+ err = smi_gyro_i2c_write(smi_gyro_client, reg_addr, data, len);
+ return err;
+}
+
+
+static void smi_gyro_work_func(struct work_struct *work)
+{
+ struct smi_gyro_client_data *client_data =
+ container_of((struct delayed_work *)work,
+ struct smi_gyro_client_data, work);
+
+ unsigned long delay =
+ msecs_to_jiffies(atomic_read(&client_data->delay));
+ struct smi130_gyro_data_t gyro_data;
+
+ SMI_GYRO_CALL_API(get_dataXYZ)(&gyro_data);
+ /*remapping for SMI130_GYRO sensor*/
+ smi130_gyro_remap_sensor_data(&gyro_data, client_data);
+
+ input_report_abs(client_data->input, ABS_X, gyro_data.datax);
+ input_report_abs(client_data->input, ABS_Y, gyro_data.datay);
+ input_report_abs(client_data->input, ABS_Z, gyro_data.dataz);
+ input_sync(client_data->input);
+
+ schedule_delayed_work(&client_data->work, delay);
+}
+
+static struct workqueue_struct *reportdata_wq;
+
+uint64_t smi130_gyro_get_alarm_timestamp(void)
+{
+ uint64_t ts_ap;
+ struct timespec tmp_time;
+ get_monotonic_boottime(&tmp_time);
+ ts_ap = (uint64_t)tmp_time.tv_sec * 1000000000 + tmp_time.tv_nsec;
+ return ts_ap;
+}
+#define ABS(x) ((x) > 0 ? (x) : -(x))
+
+static void smi130_gyro_work_func(struct work_struct *work)
+{
+ struct smi_gyro_client_data *smi130_gyro =
+ container_of(work,
+ struct smi_gyro_client_data, report_data_work);
+ int i;
+ struct smi130_gyro_data_t gyro_lsb;
+ unsigned char fifo_framecount;
+ signed char fifo_data_out[MAX_FIFO_F_LEVEL * MAX_FIFO_F_BYTES] = {0};
+ unsigned char f_len = 0;
+ uint64_t del;
+ uint64_t time_internal;
+ struct timespec ts;
+ int64_t drift_time = 0;
+ static uint64_t time_odr;
+ static uint32_t data_cnt;
+ static uint32_t pre_data_cnt;
+ static int64_t sample_drift_offset;
+ if (smi130_gyro->fifo_datasel)
+ /*Select one axis data output for every fifo frame*/
+ f_len = 2;
+ else
+ /*Select X Y Z axis data output for every fifo frame*/
+ f_len = 6;
+ if (SMI_GYRO_CALL_API(get_fifo_framecount)(&fifo_framecount) < 0) {
+ PERR("bm160_get_fifo_framecount err\n");
+ return;
+ }
+ if (fifo_framecount == 0)
+ return;
+ if (fifo_framecount > MAX_FIFO_F_LEVEL)
+ fifo_framecount = MAX_FIFO_F_LEVEL;
+ if (smi_gyro_i2c_burst_read(smi130_gyro->client, SMI130_GYRO_FIFO_DATA_ADDR,
+ fifo_data_out, fifo_framecount * f_len) < 0) {
+ PERR("smi130_gyro read fifo err\n");
+ return;
+ }
+ smi130_gyro->fifo_time = smi130_gyro_get_alarm_timestamp();
+ if (smi130_gyro->gyro_count == 0)
+ smi130_gyro->base_time = smi130_gyro->timestamp =
+ smi130_gyro->fifo_time - (fifo_framecount-1) * smi130_gyro->time_odr;
+
+ smi130_gyro->gyro_count += fifo_framecount;
+ del = smi130_gyro->fifo_time - smi130_gyro->base_time;
+ time_internal = div64_u64(del, smi130_gyro->gyro_count);
+ data_cnt++;
+ if (data_cnt == 1)
+ time_odr = smi130_gyro->time_odr;
+ if (time_internal > time_odr) {
+ if (time_internal - time_odr > div64_u64 (time_odr, 200))
+ time_internal = time_odr + div64_u64(time_odr, 200);
+ } else {
+ if (time_odr - time_internal > div64_u64(time_odr, 200))
+ time_internal = time_odr - div64_u64(time_odr, 200);
+ }
+
+ /* Select X Y Z axis data output for every frame */
+ for (i = 0; i < fifo_framecount; i++) {
+ if (smi130_gyro->debug_level & 0x01)
+ printk(KERN_INFO "smi_gyro time =%llu fifo_time = %llu time_internal = %llu smi_gyro->count= %llu count = %d",
+ smi130_gyro->timestamp, smi130_gyro->fifo_time,
+ time_internal, smi130_gyro->gyro_count, fifo_framecount);
+ ts = ns_to_timespec(smi130_gyro->timestamp);
+ gyro_lsb.datax =
+ ((unsigned char)fifo_data_out[i * f_len + 1] << 8
+ | (unsigned char)fifo_data_out[i * f_len + 0]);
+ gyro_lsb.datay =
+ ((unsigned char)fifo_data_out[i * f_len + 3] << 8
+ | (unsigned char)fifo_data_out[i * f_len + 2]);
+ gyro_lsb.dataz =
+ ((unsigned char)fifo_data_out[i * f_len + 5] << 8
+ | (unsigned char)fifo_data_out[i * f_len + 4]);
+ smi130_gyro_remap_sensor_data(&gyro_lsb, smi130_gyro);
+ input_event(smi130_gyro->input, EV_MSC, MSC_TIME,
+ ts.tv_sec);
+ input_event(smi130_gyro->input, EV_MSC, MSC_TIME,
+ ts.tv_nsec);
+ input_event(smi130_gyro->input, EV_MSC,
+ MSC_GESTURE, gyro_lsb.datax);
+ input_event(smi130_gyro->input, EV_MSC,
+ MSC_RAW, gyro_lsb.datay);
+ input_event(smi130_gyro->input, EV_MSC,
+ MSC_SCAN, gyro_lsb.dataz);
+ input_sync(smi130_gyro->input);
+ smi130_gyro->timestamp += time_internal - sample_drift_offset;
+ }
+ drift_time = smi130_gyro->timestamp - smi130_gyro->fifo_time;
+ if (data_cnt % 20 == 0) {
+ if (ABS(drift_time) > div64_u64(time_odr, 5)) {
+ sample_drift_offset =
+ div64_s64(drift_time, smi130_gyro->gyro_count - pre_data_cnt);
+ pre_data_cnt = smi130_gyro->gyro_count;
+ time_odr = time_internal;
+ }
+ }
+}
+
+
+static enum hrtimer_restart reportdata_timer_fun(
+ struct hrtimer *hrtimer)
+{
+ struct smi_gyro_client_data *client_data =
+ container_of(hrtimer, struct smi_gyro_client_data, timer);
+ int32_t delay = 0;
+ delay = 10;
+ queue_work(reportdata_wq, &(client_data->report_data_work));
+ client_data->work_delay_kt = ns_to_ktime(delay*1000000);
+ hrtimer_forward(hrtimer, ktime_get(), client_data->work_delay_kt);
+
+ return HRTIMER_RESTART;
+}
+
+static ssize_t smi_gyro_show_enable_timer(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_gyro_client_data *client_data = input_get_drvdata(input);
+
+ return snprintf(buf, 16, "%d\n", client_data->is_timer_running);
+}
+
+static ssize_t smi_gyro_store_enable_timer(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_gyro_client_data *client_data = input_get_drvdata(input);
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+ if (data) {
+ if (0 == client_data->is_timer_running) {
+ hrtimer_start(&client_data->timer,
+ ns_to_ktime(10000000),
+ HRTIMER_MODE_REL);
+ client_data->is_timer_running = 1;
+ client_data->base_time = 0;
+ client_data->timestamp = 0;
+ client_data->gyro_count = 0;
+ }
+ } else {
+ if (1 == client_data->is_timer_running) {
+ hrtimer_cancel(&client_data->timer);
+ client_data->is_timer_running = 0;
+ client_data->base_time = 0;
+ client_data->timestamp = 0;
+ client_data->gyro_count = 0;
+ }
+ }
+ return count;
+}
+
+static ssize_t smi130_gyro_show_debug_level(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_gyro_client_data *client_data = input_get_drvdata(input);
+ err = snprintf(buf, 8, "%d\n", client_data->debug_level);
+ return err;
+}
+static ssize_t smi130_gyro_store_debug_level(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int32_t ret = 0;
+ unsigned long data;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_gyro_client_data *client_data = input_get_drvdata(input);
+ ret = kstrtoul(buf, 16, &data);
+ if (ret)
+ return ret;
+ client_data->debug_level = (uint8_t)data;
+ return count;
+}
+
+static int smi_gyro_set_soft_reset(struct i2c_client *client)
+{
+ int err = 0;
+ unsigned char data = SMI_GYRO_SOFT_RESET_VALUE;
+ err = smi_gyro_i2c_write(client, SMI130_GYRO_BGW_SOFTRESET_ADDR, &data, 1);
+ return err;
+}
+
+static ssize_t smi_gyro_show_chip_id(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return snprintf(buf, 16, "%d\n", SENSOR_CHIP_ID_SMI_GYRO);
+}
+
+static ssize_t smi_gyro_show_op_mode(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int ret;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_gyro_client_data *client_data = input_get_drvdata(input);
+ u8 op_mode = 0xff;
+
+ mutex_lock(&client_data->mutex_op_mode);
+ SMI_GYRO_CALL_API(get_mode)(&op_mode);
+ mutex_unlock(&client_data->mutex_op_mode);
+
+ ret = snprintf(buf, 16, "%d\n", op_mode);
+
+ return ret;
+}
+
+static ssize_t smi_gyro_store_op_mode(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_gyro_client_data *client_data = input_get_drvdata(input);
+
+ long op_mode;
+
+ err = kstrtoul(buf, 10, &op_mode);
+ if (err)
+ return err;
+ mutex_lock(&client_data->mutex_op_mode);
+
+ err = SMI_GYRO_CALL_API(set_mode)(op_mode);
+
+ mutex_unlock(&client_data->mutex_op_mode);
+
+ if (err)
+ return err;
+ else
+ return count;
+}
+
+
+
+static ssize_t smi_gyro_show_value(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_gyro_client_data *client_data = input_get_drvdata(input);
+ int count;
+
+ struct smi130_gyro_data_t value_data;
+ SMI_GYRO_CALL_API(get_dataXYZ)(&value_data);
+ /*SMI130_GYRO sensor raw data remapping*/
+ smi130_gyro_remap_sensor_data(&value_data, client_data);
+
+ count = snprintf(buf, 96, "%hd %hd %hd\n",
+ value_data.datax,
+ value_data.datay,
+ value_data.dataz);
+
+ return count;
+}
+
+static ssize_t smi_gyro_show_range(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char range = 0;
+ SMI_GYRO_CALL_API(get_range_reg)(&range);
+ err = snprintf(buf, 16, "%d\n", range);
+ return err;
+}
+
+static ssize_t smi_gyro_store_range(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long range;
+ err = kstrtoul(buf, 10, &range);
+ if (err)
+ return err;
+ SMI_GYRO_CALL_API(set_range_reg)(range);
+ return count;
+}
+
+/*
+decimation odr filter bandwidth bits
+20 100HZ 32HZ 7
+10 200Hz 64HZ 6
+20 100HZ 12HZ 5
+10 200hz 23HZ 4
+5 400HZ 47HZ 3
+2 1000HZ 116HZ 2
+0 2000HZ 230HZ 1
+0 2000HZ Unfiltered(523HZ) 0
+*/
+
+static const uint64_t odr_map[8] = {
+500000, 500000, 1000000, 2500000, 5000000, 10000000, 5000000, 10000000};
+
+static ssize_t smi_gyro_show_bandwidth(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char bandwidth = 0;
+ SMI_GYRO_CALL_API(get_bw)(&bandwidth);
+ err = snprintf(buf, 16, "%d\n", bandwidth);
+ return err;
+}
+
+static ssize_t smi_gyro_store_bandwidth(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_gyro_client_data *client_data = input_get_drvdata(input);
+ unsigned long bandwidth;
+ u8 op_mode = 0xff;
+ err = kstrtoul(buf, 10, &bandwidth);
+ if (err)
+ return err;
+ /*
+ set bandwidth only in the op_mode=0
+ */
+ err = SMI_GYRO_CALL_API(get_mode)(&op_mode);
+ if (op_mode == 0) {
+ err += SMI_GYRO_CALL_API(set_bw)(bandwidth);
+ } else {
+ err += SMI_GYRO_CALL_API(set_mode)(0);
+ err += SMI_GYRO_CALL_API(set_bw)(bandwidth);
+ smi130_gyro_delay(1);
+ err += SMI_GYRO_CALL_API(set_mode)(2);
+ smi130_gyro_delay(3);
+ }
+
+ if (err)
+ PERR("set failed");
+ client_data->time_odr = odr_map[bandwidth];
+ client_data->base_time = 0;
+ client_data->gyro_count = 0;
+ return count;
+}
+
+
+static ssize_t smi_gyro_show_enable(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_gyro_client_data *client_data = input_get_drvdata(input);
+ int err;
+
+ mutex_lock(&client_data->mutex_enable);
+ err = snprintf(buf, 16, "%d\n", client_data->enable);
+ mutex_unlock(&client_data->mutex_enable);
+ return err;
+}
+
+static ssize_t smi_gyro_store_enable(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_gyro_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ data = data ? 1 : 0;
+ mutex_lock(&client_data->mutex_enable);
+ if (data != client_data->enable) {
+ if (data) {
+ schedule_delayed_work(
+ &client_data->work,
+ msecs_to_jiffies(atomic_read(
+ &client_data->delay)));
+ } else {
+ cancel_delayed_work_sync(&client_data->work);
+ }
+
+ client_data->enable = data;
+ }
+ mutex_unlock(&client_data->mutex_enable);
+
+ return count;
+}
+
+static ssize_t smi_gyro_show_delay(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_gyro_client_data *client_data = input_get_drvdata(input);
+
+ return snprintf(buf, 16, "%d\n", atomic_read(&client_data->delay));
+
+}
+
+static ssize_t smi_gyro_store_delay(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_gyro_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ if (data == 0) {
+ err = -EINVAL;
+ return err;
+ }
+
+ if (data < SMI_GYRO_DELAY_MIN)
+ data = SMI_GYRO_DELAY_MIN;
+
+ atomic_set(&client_data->delay, data);
+
+ return count;
+}
+
+
+static ssize_t smi_gyro_store_fastoffset_en(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long fastoffset_en;
+ err = kstrtoul(buf, 10, &fastoffset_en);
+ if (err)
+ return err;
+ if (fastoffset_en) {
+
+#ifdef CONFIG_SENSORS_BMI058
+ SMI_GYRO_CALL_API(set_fast_offset_en_ch)(BMI058_X_AXIS, 1);
+ SMI_GYRO_CALL_API(set_fast_offset_en_ch)(BMI058_Y_AXIS, 1);
+#else
+ SMI_GYRO_CALL_API(set_fast_offset_en_ch)(SMI130_GYRO_X_AXIS, 1);
+ SMI_GYRO_CALL_API(set_fast_offset_en_ch)(SMI130_GYRO_Y_AXIS, 1);
+#endif
+
+ SMI_GYRO_CALL_API(set_fast_offset_en_ch)(SMI130_GYRO_Z_AXIS, 1);
+ SMI_GYRO_CALL_API(enable_fast_offset)();
+ }
+ return count;
+}
+
+static ssize_t smi_gyro_store_slowoffset_en(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long slowoffset_en;
+ err = kstrtoul(buf, 10, &slowoffset_en);
+ if (err)
+ return err;
+ if (slowoffset_en) {
+ SMI_GYRO_CALL_API(set_slow_offset_th)(3);
+ SMI_GYRO_CALL_API(set_slow_offset_dur)(0);
+#ifdef CONFIG_SENSORS_BMI058
+ SMI_GYRO_CALL_API(set_slow_offset_en_ch)(BMI058_X_AXIS, 1);
+ SMI_GYRO_CALL_API(set_slow_offset_en_ch)(BMI058_Y_AXIS, 1);
+#else
+ SMI_GYRO_CALL_API(set_slow_offset_en_ch)(SMI130_GYRO_X_AXIS, 1);
+ SMI_GYRO_CALL_API(set_slow_offset_en_ch)(SMI130_GYRO_Y_AXIS, 1);
+#endif
+ SMI_GYRO_CALL_API(set_slow_offset_en_ch)(SMI130_GYRO_Z_AXIS, 1);
+ } else {
+#ifdef CONFIG_SENSORS_BMI058
+ SMI_GYRO_CALL_API(set_slow_offset_en_ch)(BMI058_X_AXIS, 0);
+ SMI_GYRO_CALL_API(set_slow_offset_en_ch)(BMI058_Y_AXIS, 0);
+#else
+ SMI_GYRO_CALL_API(set_slow_offset_en_ch)(SMI130_GYRO_X_AXIS, 0);
+ SMI_GYRO_CALL_API(set_slow_offset_en_ch)(SMI130_GYRO_Y_AXIS, 0);
+#endif
+ SMI_GYRO_CALL_API(set_slow_offset_en_ch)(SMI130_GYRO_Z_AXIS, 0);
+ }
+
+ return count;
+}
+
+static ssize_t smi_gyro_show_selftest(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char selftest;
+ SMI_GYRO_CALL_API(selftest)(&selftest);
+ err = snprintf(buf, 16, "%d\n", selftest);
+ return err;
+}
+
+static ssize_t smi_gyro_show_sleepdur(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char sleepdur;
+ SMI_GYRO_CALL_API(get_sleepdur)(&sleepdur);
+ err = snprintf(buf, 16, "%d\n", sleepdur);
+ return err;
+}
+
+static ssize_t smi_gyro_store_sleepdur(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long sleepdur;
+ err = kstrtoul(buf, 10, &sleepdur);
+ if (err)
+ return err;
+ SMI_GYRO_CALL_API(set_sleepdur)(sleepdur);
+ return count;
+}
+
+static ssize_t smi_gyro_show_autosleepdur(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char autosleepdur;
+ SMI_GYRO_CALL_API(get_autosleepdur)(&autosleepdur);
+ err = snprintf(buf, 16, "%d\n", autosleepdur);
+ return err;
+}
+
+static ssize_t smi_gyro_store_autosleepdur(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long autosleepdur;
+ unsigned char bandwidth;
+ err = kstrtoul(buf, 10, &autosleepdur);
+ if (err)
+ return err;
+ SMI_GYRO_CALL_API(get_bw)(&bandwidth);
+ SMI_GYRO_CALL_API(set_autosleepdur)(autosleepdur, bandwidth);
+ return count;
+}
+
+static ssize_t smi_gyro_show_place(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_gyro_client_data *client_data = input_get_drvdata(input);
+ int place = BOSCH_SENSOR_PLACE_UNKNOWN;
+
+ if (NULL != client_data->bosch_pd)
+ place = client_data->bosch_pd->place;
+
+ return snprintf(buf, 16, "%d\n", place);
+}
+
+
+#ifdef SMI_GYRO_DEBUG
+static ssize_t smi_gyro_store_softreset(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long softreset;
+ err = kstrtoul(buf, 10, &softreset);
+ if (err)
+ return err;
+ SMI_GYRO_CALL_API(set_soft_reset)();
+ return count;
+}
+
+static ssize_t smi_gyro_show_dumpreg(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ size_t count = 0;
+ u8 reg[0x40];
+ int i;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_gyro_client_data *client_data = input_get_drvdata(input);
+
+ for (i = 0; i < 0x40; i++) {
+ smi_gyro_i2c_read(client_data->client, i, reg+i, 1);
+
+ count += snprintf(&buf[count], 48, "0x%x: 0x%x\n", i, reg[i]);
+ }
+ return count;
+}
+#endif
+
+#ifdef SMI_GYRO_USE_FIFO
+static ssize_t smi_gyro_show_fifo_mode(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char fifo_mode;
+ SMI_GYRO_CALL_API(get_fifo_mode)(&fifo_mode);
+ err = snprintf(buf, 16, "%d\n", fifo_mode);
+ return err;
+}
+
+static ssize_t smi_gyro_store_fifo_mode(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long fifo_mode;
+ err = kstrtoul(buf, 10, &fifo_mode);
+ if (err)
+ return err;
+ SMI_GYRO_CALL_API(set_fifo_mode)(fifo_mode);
+ return count;
+}
+
+static ssize_t smi_gyro_show_fifo_framecount(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char fifo_framecount;
+ SMI_GYRO_CALL_API(get_fifo_framecount)(&fifo_framecount);
+ err = snprintf(buf, 32, "%d\n", fifo_framecount);
+ return err;
+}
+
+static ssize_t smi_gyro_store_fifo_framecount(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_gyro_client_data *client_data = input_get_drvdata(input);
+ error = kstrtoul(buf, 10, &data);
+ if (error)
+ return error;
+ client_data->fifo_count = (unsigned int) data;
+
+ return count;
+}
+
+static ssize_t smi_gyro_show_fifo_overrun(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char fifo_overrun;
+ SMI_GYRO_CALL_API(get_fifo_overrun)(&fifo_overrun);
+ err = snprintf(buf, 16, "%d\n", fifo_overrun);
+ return err;
+}
+
+static ssize_t smi_gyro_show_fifo_data_frame(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char f_len = 0;
+ unsigned char fifo_framecount;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_gyro_client_data *client_data = input_get_drvdata(input);
+
+ if (client_data->fifo_datasel)
+ /*Select one axis data output for every fifo frame*/
+ f_len = 2;
+ else
+ /*Select X Y Z axis data output for every fifo frame*/
+ f_len = 6;
+
+ if (SMI_GYRO_CALL_API(get_fifo_framecount)(&fifo_framecount) < 0) {
+ PERR("bm160_get_fifo_framecount err\n");
+ return -EINVAL;
+ }
+ if (fifo_framecount == 0)
+ return 0;
+
+ smi_gyro_i2c_burst_read(client_data->client, SMI130_GYRO_FIFO_DATA_ADDR,
+ buf, fifo_framecount * f_len);
+ return fifo_framecount * f_len;
+}
+
+/*!
+ * @brief show fifo_data_sel axis definition(Android definition, not sensor HW reg).
+ * 0--> x, y, z axis fifo data for every frame
+ * 1--> only x axis fifo data for every frame
+ * 2--> only y axis fifo data for every frame
+ * 3--> only z axis fifo data for every frame
+ */
+static ssize_t smi_gyro_show_fifo_data_sel(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char fifo_data_sel;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct smi_gyro_client_data *client_data = i2c_get_clientdata(client);
+ signed char place = BOSCH_SENSOR_PLACE_UNKNOWN;
+
+ SMI_GYRO_CALL_API(get_fifo_data_sel)(&fifo_data_sel);
+
+ /*remapping fifo_dat_sel if define virtual place in BSP files*/
+ if ((NULL != client_data->bosch_pd) &&
+ (BOSCH_SENSOR_PLACE_UNKNOWN != client_data->bosch_pd->place)) {
+ place = client_data->bosch_pd->place;
+ /* sensor with place 0 needs not to be remapped */
+ if ((place > 0) && (place < MAX_AXIS_REMAP_TAB_SZ)) {
+ if (SMI130_GYRO_FIFO_DAT_SEL_X == fifo_data_sel)
+ /* SMI130_GYRO_FIFO_DAT_SEL_X: 1, Y:2, Z:3;
+ *bosch_axis_remap_tab_dft[i].src_x:0, y:1, z:2
+ *so we need to +1*/
+ fifo_data_sel =
+ bosch_axis_remap_tab_dft[place].src_x + 1;
+
+ else if (SMI130_GYRO_FIFO_DAT_SEL_Y == fifo_data_sel)
+ fifo_data_sel =
+ bosch_axis_remap_tab_dft[place].src_y + 1;
+ }
+
+ }
+
+ err = snprintf(buf, 16, "%d\n", fifo_data_sel);
+ return err;
+}
+
+/*!
+ * @brief store fifo_data_sel axis definition(Android definition, not sensor HW reg).
+ * 0--> x, y, z axis fifo data for every frame
+ * 1--> only x axis fifo data for every frame
+ * 2--> only y axis fifo data for every frame
+ * 3--> only z axis fifo data for every frame
+ */
+static ssize_t smi_gyro_store_fifo_data_sel(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+
+{
+ int err;
+ unsigned long fifo_data_sel;
+
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_gyro_client_data *client_data = input_get_drvdata(input);
+ signed char place;
+
+ err = kstrtoul(buf, 10, &fifo_data_sel);
+ if (err)
+ return err;
+
+ /*save fifo_data_sel(android axis definition)*/
+ client_data->fifo_datasel = (unsigned char) fifo_data_sel;
+
+ /*remaping fifo_dat_sel if define virtual place*/
+ if ((NULL != client_data->bosch_pd) &&
+ (BOSCH_SENSOR_PLACE_UNKNOWN != client_data->bosch_pd->place)) {
+ place = client_data->bosch_pd->place;
+ /* sensor with place 0 needs not to be remapped */
+ if ((place > 0) && (place < MAX_AXIS_REMAP_TAB_SZ)) {
+ /*Need X Y axis revesal sensor place: P1, P3, P5, P7 */
+ /* SMI130_GYRO_FIFO_DAT_SEL_X: 1, Y:2, Z:3;
+ * but bosch_axis_remap_tab_dft[i].src_x:0, y:1, z:2
+ * so we need to +1*/
+ if (SMI130_GYRO_FIFO_DAT_SEL_X == fifo_data_sel)
+ fifo_data_sel =
+ bosch_axis_remap_tab_dft[place].src_x + 1;
+
+ else if (SMI130_GYRO_FIFO_DAT_SEL_Y == fifo_data_sel)
+ fifo_data_sel =
+ bosch_axis_remap_tab_dft[place].src_y + 1;
+ }
+ }
+
+ if (SMI_GYRO_CALL_API(set_fifo_data_sel)(fifo_data_sel) < 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static ssize_t smi_gyro_show_fifo_tag(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char fifo_tag;
+ SMI_GYRO_CALL_API(get_fifo_tag)(&fifo_tag);
+ err = snprintf(buf, 16, "%d\n", fifo_tag);
+ return err;
+}
+
+static ssize_t smi_gyro_store_fifo_tag(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+
+{
+ int err;
+ unsigned long fifo_tag;
+ err = kstrtoul(buf, 10, &fifo_tag);
+ if (err)
+ return err;
+ SMI_GYRO_CALL_API(set_fifo_tag)(fifo_tag);
+ return count;
+}
+#endif
+
+static ssize_t smi130_gyro_driver_version_show(struct device *dev
+ , struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_gyro_client_data *client_data = input_get_drvdata(input);
+ int ret;
+
+ if (client_data == NULL) {
+ printk(KERN_ERR "Invalid client_data pointer");
+ return -ENODEV;
+ }
+
+ ret = snprintf(buf, 128, "Driver version: %s\n",
+ DRIVER_VERSION);
+ return ret;
+}
+static DEVICE_ATTR(chip_id, S_IRUSR,
+ smi_gyro_show_chip_id, NULL);
+static DEVICE_ATTR(op_mode, S_IRUGO | S_IWUSR,
+ smi_gyro_show_op_mode, smi_gyro_store_op_mode);
+static DEVICE_ATTR(value, S_IRUSR,
+ smi_gyro_show_value, NULL);
+static DEVICE_ATTR(range, S_IRUGO | S_IWUSR,
+ smi_gyro_show_range, smi_gyro_store_range);
+static DEVICE_ATTR(bandwidth, S_IRUGO | S_IWUSR,
+ smi_gyro_show_bandwidth, smi_gyro_store_bandwidth);
+static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR,
+ smi_gyro_show_enable, smi_gyro_store_enable);
+static DEVICE_ATTR(delay, S_IRUGO | S_IWUSR,
+ smi_gyro_show_delay, smi_gyro_store_delay);
+static DEVICE_ATTR(fastoffset_en, S_IWUSR,
+ NULL, smi_gyro_store_fastoffset_en);
+static DEVICE_ATTR(slowoffset_en, S_IWUSR,
+ NULL, smi_gyro_store_slowoffset_en);
+static DEVICE_ATTR(selftest, S_IRUGO,
+ smi_gyro_show_selftest, NULL);
+static DEVICE_ATTR(sleepdur, S_IRUGO | S_IWUSR,
+ smi_gyro_show_sleepdur, smi_gyro_store_sleepdur);
+static DEVICE_ATTR(autosleepdur, S_IRUGO | S_IWUSR,
+ smi_gyro_show_autosleepdur, smi_gyro_store_autosleepdur);
+static DEVICE_ATTR(place, S_IRUSR,
+ smi_gyro_show_place, NULL);
+static DEVICE_ATTR(enable_timer, S_IRUGO | S_IWUSR,
+ smi_gyro_show_enable_timer, smi_gyro_store_enable_timer);
+static DEVICE_ATTR(debug_level, S_IRUGO | S_IWUSR,
+ smi130_gyro_show_debug_level, smi130_gyro_store_debug_level);
+static DEVICE_ATTR(driver_version, S_IRUSR,
+ smi130_gyro_driver_version_show, NULL);
+#ifdef SMI_GYRO_DEBUG
+static DEVICE_ATTR(softreset, S_IWUSR,
+ NULL, smi_gyro_store_softreset);
+static DEVICE_ATTR(regdump, S_IRUSR,
+ smi_gyro_show_dumpreg, NULL);
+#endif
+#ifdef SMI_GYRO_USE_FIFO
+static DEVICE_ATTR(fifo_mode, S_IRUGO | S_IWUSR,
+ smi_gyro_show_fifo_mode, smi_gyro_store_fifo_mode);
+static DEVICE_ATTR(fifo_framecount, S_IRUGO | S_IWUSR,
+ smi_gyro_show_fifo_framecount, smi_gyro_store_fifo_framecount);
+static DEVICE_ATTR(fifo_overrun, S_IRUGO,
+ smi_gyro_show_fifo_overrun, NULL);
+static DEVICE_ATTR(fifo_data_frame, S_IRUSR,
+ smi_gyro_show_fifo_data_frame, NULL);
+static DEVICE_ATTR(fifo_data_sel, S_IRUGO | S_IWUSR,
+ smi_gyro_show_fifo_data_sel, smi_gyro_store_fifo_data_sel);
+static DEVICE_ATTR(fifo_tag, S_IRUGO | S_IWUSR,
+ smi_gyro_show_fifo_tag, smi_gyro_store_fifo_tag);
+#endif
+
+static struct attribute *smi_gyro_attributes[] = {
+ &dev_attr_chip_id.attr,
+ &dev_attr_op_mode.attr,
+ &dev_attr_value.attr,
+ &dev_attr_range.attr,
+ &dev_attr_bandwidth.attr,
+ &dev_attr_enable.attr,
+ &dev_attr_delay.attr,
+ &dev_attr_fastoffset_en.attr,
+ &dev_attr_slowoffset_en.attr,
+ &dev_attr_selftest.attr,
+ &dev_attr_sleepdur.attr,
+ &dev_attr_autosleepdur.attr,
+ &dev_attr_place.attr,
+ &dev_attr_enable_timer.attr,
+ &dev_attr_debug_level.attr,
+ &dev_attr_driver_version.attr,
+#ifdef SMI_GYRO_DEBUG
+ &dev_attr_softreset.attr,
+ &dev_attr_regdump.attr,
+#endif
+#ifdef SMI_GYRO_USE_FIFO
+ &dev_attr_fifo_mode.attr,
+ &dev_attr_fifo_framecount.attr,
+ &dev_attr_fifo_overrun.attr,
+ &dev_attr_fifo_data_frame.attr,
+ &dev_attr_fifo_data_sel.attr,
+ &dev_attr_fifo_tag.attr,
+#endif
+ NULL
+};
+
+static struct attribute_group smi_gyro_attribute_group = {
+ .attrs = smi_gyro_attributes
+};
+
+
+static int smi_gyro_input_init(struct smi_gyro_client_data *client_data)
+{
+ struct input_dev *dev;
+ int err = 0;
+
+ dev = input_allocate_device();
+ if (NULL == dev)
+ return -ENOMEM;
+
+ dev->name = SENSOR_NAME;
+ dev->id.bustype = BUS_I2C;
+
+ input_set_capability(dev, EV_ABS, ABS_MISC);
+ input_set_abs_params(dev, ABS_X, SMI_GYRO_VALUE_MIN, SMI_GYRO_VALUE_MAX, 0, 0);
+ input_set_abs_params(dev, ABS_Y, SMI_GYRO_VALUE_MIN, SMI_GYRO_VALUE_MAX, 0, 0);
+ input_set_abs_params(dev, ABS_Z, SMI_GYRO_VALUE_MIN, SMI_GYRO_VALUE_MAX, 0, 0);
+ input_set_capability(dev, EV_MSC, MSC_GESTURE);
+ input_set_capability(dev, EV_MSC, MSC_RAW);
+ input_set_capability(dev, EV_MSC, MSC_SCAN);
+ input_set_capability(dev, EV_MSC, MSC_TIME);
+ input_set_drvdata(dev, client_data);
+
+ err = input_register_device(dev);
+ if (err < 0) {
+ input_free_device(dev);
+ return err;
+ }
+ client_data->input = dev;
+
+ return 0;
+}
+
+static void smi_gyro_input_destroy(struct smi_gyro_client_data *client_data)
+{
+ struct input_dev *dev = client_data->input;
+
+ input_unregister_device(dev);
+ input_free_device(dev);
+}
+
+#if defined(SMI130_GYRO_ENABLE_INT1) || defined(SMI130_GYRO_ENABLE_INT2)
+static void smi130_gyro_irq_work_func(struct work_struct *work)
+{
+ struct smi_gyro_client_data *client_data = container_of(work,
+ struct smi_gyro_client_data, irq_work);
+ struct smi130_gyro_data_t gyro_data;
+ struct timespec ts;
+ ts = ns_to_timespec(client_data->timestamp);
+
+ SMI_GYRO_CALL_API(get_dataXYZ)(&gyro_data);
+ /*remapping for SMI130_GYRO sensor*/
+ smi130_gyro_remap_sensor_data(&gyro_data, client_data);
+ input_event(client_data->input, EV_MSC, MSC_TIME,
+ ts.tv_sec);
+ input_event(client_data->input, EV_MSC, MSC_TIME,
+ ts.tv_nsec);
+ input_event(client_data->input, EV_MSC,
+ MSC_GESTURE, gyro_data.datax);
+ input_event(client_data->input, EV_MSC,
+ MSC_RAW, gyro_data.datay);
+ input_event(client_data->input, EV_MSC,
+ MSC_SCAN, gyro_data.dataz);
+ input_sync(client_data->input);
+
+}
+
+static irqreturn_t smi_gyro_irq_handler(int irq, void *handle)
+{
+ struct smi_gyro_client_data *client_data = handle;
+ client_data->timestamp= smi130_gyro_get_alarm_timestamp();
+ schedule_work(&client_data->irq_work);
+ return IRQ_HANDLED;
+}
+#endif
+static int smi_gyro_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+ int err = 0;
+ struct smi_gyro_client_data *client_data = NULL;
+ PINFO("function entrance");
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ PERR("i2c_check_functionality error!");
+ err = -EIO;
+ goto exit_err_clean;
+ }
+
+ if (NULL == smi_gyro_client) {
+ smi_gyro_client = client;
+ } else {
+ PERR("this driver does not support multiple clients");
+ err = -EINVAL;
+ goto exit_err_clean;
+ }
+
+ /* check chip id */
+ err = smi_gyro_check_chip_id(client);
+ if (!err) {
+ PINFO("Bosch Sensortec Device %s detected", SENSOR_NAME);
+ } else {
+ PERR("Bosch Sensortec Device not found, chip id mismatch");
+ err = -1;
+ goto exit_err_clean;
+ }
+
+ /* do soft reset */
+ smi130_gyro_delay(5);
+ err = smi_gyro_set_soft_reset(client);
+ if (err < 0) {
+ PERR("erro soft reset!\n");
+ err = -EINVAL;
+ goto exit_err_clean;
+ }
+ smi130_gyro_delay(30);
+
+
+ client_data = kzalloc(sizeof(struct smi_gyro_client_data), GFP_KERNEL);
+ if (NULL == client_data) {
+ PERR("no memory available");
+ err = -ENOMEM;
+ goto exit_err_clean;
+ }
+
+ i2c_set_clientdata(client, client_data);
+ client_data->client = client;
+
+ mutex_init(&client_data->mutex_op_mode);
+ mutex_init(&client_data->mutex_enable);
+
+ /* input device init */
+ err = smi_gyro_input_init(client_data);
+ if (err < 0)
+ goto exit_err_clean;
+
+ /* sysfs node creation */
+ err = sysfs_create_group(&client_data->input->dev.kobj,
+ &smi_gyro_attribute_group);
+
+ if (err < 0)
+ goto exit_err_sysfs;
+
+ if (NULL != client->dev.platform_data) {
+ client_data->bosch_pd = kzalloc(sizeof(*client_data->bosch_pd),
+ GFP_KERNEL);
+
+ if (NULL != client_data->bosch_pd) {
+ memcpy(client_data->bosch_pd, client->dev.platform_data,
+ sizeof(*client_data->bosch_pd));
+ PINFO("%s sensor driver set place: p%d",
+ SENSOR_NAME,
+ client_data->bosch_pd->place);
+ }
+ }
+
+ /* workqueue init */
+ INIT_DELAYED_WORK(&client_data->work, smi_gyro_work_func);
+ atomic_set(&client_data->delay, SMI_GYRO_DELAY_DEFAULT);
+
+ /* h/w init */
+ client_data->device.bus_read = smi_gyro_i2c_read_wrapper;
+ client_data->device.bus_write = smi_gyro_i2c_write_wrapper;
+ client_data->device.delay_msec = smi130_gyro_delay;
+ SMI_GYRO_CALL_API(init)(&client_data->device);
+
+ smi_gyro_dump_reg(client);
+
+ client_data->enable = 0;
+ client_data->fifo_datasel = 0;
+ client_data->fifo_count = 0;
+
+ /*workqueue init*/
+ INIT_WORK(&client_data->report_data_work,
+ smi130_gyro_work_func);
+ reportdata_wq = create_singlethread_workqueue("smi130_gyro_wq");
+ if (NULL == reportdata_wq)
+ PERR("fail to create the reportdta_wq %d", -ENOMEM);
+ hrtimer_init(&client_data->timer, CLOCK_MONOTONIC,
+ HRTIMER_MODE_REL);
+ client_data->timer.function = reportdata_timer_fun;
+ client_data->work_delay_kt = ns_to_ktime(10000000);
+ client_data->is_timer_running = 0;
+ client_data->time_odr = 500000;
+#ifdef SMI130_GYRO_ENABLE_INT1
+ err = SMI_GYRO_CALL_API(set_mode)(SMI130_GYRO_MODE_NORMAL);
+ smi130_gyro_delay(5);
+ /*config the interrupt and map the interrupt*/
+ /*high level trigger*/
+ err += smi130_gyro_set_int_lvl(SMI130_GYRO_INT1_DATA, 1);
+ smi130_gyro_delay(5);
+ err += smi130_gyro_set_int_od(SMI130_GYRO_INT1, 0);
+ smi130_gyro_delay(5);
+ err += smi130_gyro_set_int_data(SMI130_GYRO_INT1_DATA, SMI130_GYRO_ENABLE);
+ smi130_gyro_delay(5);
+ err += smi130_gyro_set_data_en(SMI130_GYRO_ENABLE);
+ smi130_gyro_delay(5);
+ /*default odr is 100HZ*/
+ err += SMI_GYRO_CALL_API(set_bw)(7);
+ smi130_gyro_delay(5);
+ if (err)
+ PERR("config sensor data ready interrupt failed");
+#endif
+#ifdef SMI130_GYRO_ENABLE_INT2
+ err = SMI_GYRO_CALL_API(set_mode)(SMI130_GYRO_MODE_NORMAL);
+ /*config the interrupt and map the interrupt*/
+ /*high level trigger*/
+ err += smi130_gyro_set_int_lvl(SMI130_GYRO_INT2_DATA, 1);
+ smi130_gyro_delay(3);
+ err += smi130_gyro_set_int_od(SMI130_GYRO_INT2, 0);
+ smi130_gyro_delay(5);
+ err += smi130_gyro_set_int_data(SMI130_GYRO_INT2_DATA, SMI130_GYRO_ENABLE);
+ smi130_gyro_delay(3);
+ err += smi130_gyro_set_data_en(SMI130_GYRO_ENABLE);
+ /*default odr is 100HZ*/
+ err += SMI_GYRO_CALL_API(set_bw)(7);
+ smi130_gyro_delay(5);
+ if (err)
+ PERR("config sensor data ready interrupt failed");
+#endif
+ err += SMI_GYRO_CALL_API(set_mode)(
+ SMI_GYRO_VAL_NAME(MODE_SUSPEND));
+ if (err < 0)
+ goto exit_err_sysfs;
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ client_data->early_suspend_handler.suspend = smi_gyro_early_suspend;
+ client_data->early_suspend_handler.resume = smi_gyro_late_resume;
+ register_early_suspend(&client_data->early_suspend_handler);
+#endif
+#if defined(SMI130_GYRO_ENABLE_INT1) || defined(SMI130_GYRO_ENABLE_INT2)
+ client_data->gpio_pin = of_get_named_gpio_flags(
+ client->dev.of_node,
+ "smi130_gyro,gpio_irq", 0, NULL);
+ PDEBUG("smi130_gyro qpio number:%d\n", client_data->gpio_pin);
+ err = gpio_request_one(client_data->gpio_pin,
+ GPIOF_IN, "bm160_interrupt");
+ if (err < 0) {
+ PDEBUG("requestgpio failed\n");
+ client_data->gpio_pin = 0;
+ }
+ if (client_data->gpio_pin != 0) {
+ err = gpio_direction_input(client_data->gpio_pin);
+ if (err < 0) {
+ PDEBUG("request failed\n");
+ }
+ client_data->IRQ = gpio_to_irq(client_data->gpio_pin);
+ err = request_irq(client_data->IRQ, smi_gyro_irq_handler,
+ IRQF_TRIGGER_RISING,
+ SENSOR_NAME, client_data);
+ if (err < 0)
+ PDEBUG("request handle failed\n");
+ }
+ INIT_WORK(&client_data->irq_work, smi130_gyro_irq_work_func);
+#endif
+ PINFO("sensor %s probed successfully", SENSOR_NAME);
+
+ dev_dbg(&client->dev,
+ "i2c_client: %p client_data: %p i2c_device: %p input: %p",
+ client, client_data, &client->dev, client_data->input);
+
+ return 0;
+
+exit_err_sysfs:
+ if (err)
+ smi_gyro_input_destroy(client_data);
+
+exit_err_clean:
+ if (err) {
+ if (client_data != NULL) {
+ kfree(client_data);
+ client_data = NULL;
+ }
+
+ smi_gyro_client = NULL;
+ }
+
+ return err;
+}
+
+static int smi_gyro_pre_suspend(struct i2c_client *client)
+{
+ int err = 0;
+ struct smi_gyro_client_data *client_data =
+ (struct smi_gyro_client_data *)i2c_get_clientdata(client);
+ PINFO("function entrance");
+
+ mutex_lock(&client_data->mutex_enable);
+ if (client_data->enable) {
+ cancel_delayed_work_sync(&client_data->work);
+ PINFO("cancel work");
+ }
+ mutex_unlock(&client_data->mutex_enable);
+ if (client_data->is_timer_running) {
+ hrtimer_cancel(&client_data->timer);
+ client_data->base_time = 0;
+ client_data->timestamp = 0;
+ client_data->fifo_time = 0;
+ client_data->gyro_count = 0;
+ }
+ return err;
+}
+
+static int smi_gyro_post_resume(struct i2c_client *client)
+{
+ int err = 0;
+ struct smi_gyro_client_data *client_data =
+ (struct smi_gyro_client_data *)i2c_get_clientdata(client);
+
+ PINFO("function entrance");
+ mutex_lock(&client_data->mutex_enable);
+ if (client_data->enable) {
+ schedule_delayed_work(&client_data->work,
+ msecs_to_jiffies(
+ atomic_read(&client_data->delay)));
+ }
+ mutex_unlock(&client_data->mutex_enable);
+ if (client_data->is_timer_running) {
+ hrtimer_start(&client_data->timer,
+ ns_to_ktime(client_data->time_odr),
+ HRTIMER_MODE_REL);
+ client_data->base_time = 0;
+ client_data->timestamp = 0;
+ client_data->is_timer_running = 1;
+ client_data->gyro_count = 0;
+ }
+ return err;
+}
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void smi_gyro_early_suspend(struct early_suspend *handler)
+{
+ int err = 0;
+ struct smi_gyro_client_data *client_data =
+ (struct smi_gyro_client_data *)container_of(handler,
+ struct smi_gyro_client_data, early_suspend_handler);
+ struct i2c_client *client = client_data->client;
+
+ PINFO("function entrance");
+
+ mutex_lock(&client_data->mutex_op_mode);
+ if (client_data->enable) {
+ err = smi_gyro_pre_suspend(client);
+ err = SMI_GYRO_CALL_API(set_mode)(
+ SMI_GYRO_VAL_NAME(MODE_SUSPEND));
+ }
+ mutex_unlock(&client_data->mutex_op_mode);
+}
+
+static void smi_gyro_late_resume(struct early_suspend *handler)
+{
+
+ int err = 0;
+ struct smi_gyro_client_data *client_data =
+ (struct smi_gyro_client_data *)container_of(handler,
+ struct smi_gyro_client_data, early_suspend_handler);
+ struct i2c_client *client = client_data->client;
+
+ PINFO("function entrance");
+
+ mutex_lock(&client_data->mutex_op_mode);
+
+ if (client_data->enable)
+ err = SMI_GYRO_CALL_API(set_mode)(SMI_GYRO_VAL_NAME(MODE_NORMAL));
+
+ /* post resume operation */
+ smi_gyro_post_resume(client);
+
+ mutex_unlock(&client_data->mutex_op_mode);
+}
+#else
+static int smi_gyro_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+ int err = 0;
+ struct smi_gyro_client_data *client_data =
+ (struct smi_gyro_client_data *)i2c_get_clientdata(client);
+
+ PINFO("function entrance");
+
+ mutex_lock(&client_data->mutex_op_mode);
+ if (client_data->enable) {
+ err = smi_gyro_pre_suspend(client);
+ err = SMI_GYRO_CALL_API(set_mode)(
+ SMI_GYRO_VAL_NAME(MODE_SUSPEND));
+ }
+ mutex_unlock(&client_data->mutex_op_mode);
+ return err;
+}
+
+static int smi_gyro_resume(struct i2c_client *client)
+{
+
+ int err = 0;
+ struct smi_gyro_client_data *client_data =
+ (struct smi_gyro_client_data *)i2c_get_clientdata(client);
+
+ PINFO("function entrance");
+
+ mutex_lock(&client_data->mutex_op_mode);
+
+ if (client_data->enable)
+ err = SMI_GYRO_CALL_API(set_mode)(SMI_GYRO_VAL_NAME(MODE_NORMAL));
+
+ /* post resume operation */
+ smi_gyro_post_resume(client);
+
+ mutex_unlock(&client_data->mutex_op_mode);
+ return err;
+}
+#endif
+
+void smi_gyro_shutdown(struct i2c_client *client)
+{
+ struct smi_gyro_client_data *client_data =
+ (struct smi_gyro_client_data *)i2c_get_clientdata(client);
+
+ mutex_lock(&client_data->mutex_op_mode);
+ SMI_GYRO_CALL_API(set_mode)(
+ SMI_GYRO_VAL_NAME(MODE_DEEPSUSPEND));
+ mutex_unlock(&client_data->mutex_op_mode);
+}
+
+static int smi_gyro_remove(struct i2c_client *client)
+{
+ int err = 0;
+ u8 op_mode;
+
+ struct smi_gyro_client_data *client_data =
+ (struct smi_gyro_client_data *)i2c_get_clientdata(client);
+
+ if (NULL != client_data) {
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ unregister_early_suspend(&client_data->early_suspend_handler);
+#endif
+ mutex_lock(&client_data->mutex_op_mode);
+ SMI_GYRO_CALL_API(get_mode)(&op_mode);
+ if (SMI_GYRO_VAL_NAME(MODE_NORMAL) == op_mode) {
+ cancel_delayed_work_sync(&client_data->work);
+ PINFO("cancel work");
+ }
+ mutex_unlock(&client_data->mutex_op_mode);
+
+ err = SMI_GYRO_CALL_API(set_mode)(
+ SMI_GYRO_VAL_NAME(MODE_SUSPEND));
+ smi130_gyro_delay(SMI_GYRO_I2C_WRITE_DELAY_TIME);
+
+ sysfs_remove_group(&client_data->input->dev.kobj,
+ &smi_gyro_attribute_group);
+ smi_gyro_input_destroy(client_data);
+ kfree(client_data);
+
+ smi_gyro_client = NULL;
+ }
+
+ return err;
+}
+
+static const struct i2c_device_id smi_gyro_id[] = {
+ { SENSOR_NAME, 0 },
+ { }
+};
+
+MODULE_DEVICE_TABLE(i2c, smi_gyro_id);
+static const struct of_device_id smi130_gyro_of_match[] = {
+ { .compatible = "smi130_gyro", },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, smi130_gyro_of_match);
+
+static struct i2c_driver smi_gyro_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = SENSOR_NAME,
+ .of_match_table = smi130_gyro_of_match,
+ },
+ .class = I2C_CLASS_HWMON,
+ .id_table = smi_gyro_id,
+ .probe = smi_gyro_probe,
+ .remove = smi_gyro_remove,
+ .shutdown = smi_gyro_shutdown,
+#ifndef CONFIG_HAS_EARLYSUSPEND
+ //.suspend = smi_gyro_suspend,
+ //.resume = smi_gyro_resume,
+#endif
+};
+
+static int __init SMI_GYRO_init(void)
+{
+ return i2c_add_driver(&smi_gyro_driver);
+}
+
+static void __exit SMI_GYRO_exit(void)
+{
+ i2c_del_driver(&smi_gyro_driver);
+}
+
+MODULE_AUTHOR("contact@bosch-sensortec.com>");
+MODULE_DESCRIPTION("SMI_GYRO GYROSCOPE SENSOR DRIVER");
+MODULE_LICENSE("GPL v2");
+
+module_init(SMI_GYRO_init);
+module_exit(SMI_GYRO_exit);
diff --git a/drivers/input/sensors/smi130/smi130_i2c.c b/drivers/input/sensors/smi130/smi130_i2c.c
new file mode 100644
index 0000000..09c4d29
--- /dev/null
+++ b/drivers/input/sensors/smi130/smi130_i2c.c
@@ -0,0 +1,472 @@
+/*!
+ * @section LICENSE
+ * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved
+ *
+ * (C) Modification Copyright 2018 Robert Bosch Kft All Rights Reserved
+ *
+ * This software program is licensed subject to the GNU General
+ * Public License (GPL).Version 2,June 1991,
+ * available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * Special: Description of the Software:
+ *
+ * This software module (hereinafter called "Software") and any
+ * information on application-sheets (hereinafter called "Information") is
+ * provided free of charge for the sole purpose to support your application
+ * work.
+ *
+ * As such, the Software is merely an experimental software, not tested for
+ * safety in the field and only intended for inspiration for further development
+ * and testing. Any usage in a safety-relevant field of use (like automotive,
+ * seafaring, spacefaring, industrial plants etc.) was not intended, so there are
+ * no precautions for such usage incorporated in the Software.
+ *
+ * The Software is specifically designed for the exclusive use for Bosch
+ * Sensortec products by personnel who have special experience and training. Do
+ * not use this Software if you do not have the proper experience or training.
+ *
+ * This Software package is provided as is and without any expressed or
+ * implied warranties, including without limitation, the implied warranties of
+ * merchantability and fitness for a particular purpose.
+ *
+ * Bosch Sensortec and their representatives and agents deny any liability for
+ * the functional impairment of this Software in terms of fitness, performance
+ * and safety. Bosch Sensortec and their representatives and agents shall not be
+ * liable for any direct or indirect damages or injury, except as otherwise
+ * stipulated in mandatory applicable law.
+ * The Information provided is believed to be accurate and reliable. Bosch
+ * Sensortec assumes no responsibility for the consequences of use of such
+ * Information nor for any infringement of patents or other rights of third
+ * parties which may result from its use.
+ *
+ *------------------------------------------------------------------------------
+ * The following Product Disclaimer does not apply to the BSX4-HAL-4.1NoFusion Software
+ * which is licensed under the Apache License, Version 2.0 as stated above.
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Product Disclaimer
+ *
+ * Common:
+ *
+ * Assessment of Products Returned from Field
+ *
+ * Returned products are considered good if they fulfill the specifications /
+ * test data for 0-mileage and field listed in this document.
+ *
+ * Engineering Samples
+ *
+ * Engineering samples are marked with (e) or (E). Samples may vary from the
+ * valid technical specifications of the series product contained in this
+ * data sheet. Therefore, they are not intended or fit for resale to
+ * third parties or for use in end products. Their sole purpose is internal
+ * client testing. The testing of an engineering sample may in no way replace
+ * the testing of a series product. Bosch assumes no liability for the use
+ * of engineering samples. The purchaser shall indemnify Bosch from all claims
+ * arising from the use of engineering samples.
+ *
+ * Intended use
+ *
+ * Provided that SMI130 is used within the conditions (environment, application,
+ * installation, loads) as described in this TCD and the corresponding
+ * agreed upon documents, Bosch ensures that the product complies with
+ * the agreed properties. Agreements beyond this require
+ * the written approval by Bosch. The product is considered fit for the intended
+ * use when the product successfully has passed the tests
+ * in accordance with the TCD and agreed upon documents.
+ *
+ * It is the responsibility of the customer to ensure the proper application
+ * of the product in the overall system/vehicle.
+ *
+ * Bosch does not assume any responsibility for changes to the environment
+ * of the product that deviate from the TCD and the agreed upon documents
+ * as well as all applications not released by Bosch
+ *
+ * The resale and/or use of products are at the purchaser’s own risk and
+ * responsibility. The examination and testing of the SMI130
+ * is the sole responsibility of the purchaser.
+ *
+ * The purchaser shall indemnify Bosch from all third party claims
+ * arising from any product use not covered by the parameters of
+ * this product data sheet or not approved by Bosch and reimburse Bosch
+ * for all costs and damages in connection with such claims.
+ *
+ * The purchaser must monitor the market for the purchased products,
+ * particularly with regard to product safety, and inform Bosch without delay
+ * of all security relevant incidents.
+ *
+ * Application Examples and Hints
+ *
+ * With respect to any application examples, advice, normal values
+ * and/or any information regarding the application of the device,
+ * Bosch hereby disclaims any and all warranties and liabilities of any kind,
+ * including without limitation warranties of
+ * non-infringement of intellectual property rights or copyrights
+ * of any third party.
+ * The information given in this document shall in no event be regarded
+ * as a guarantee of conditions or characteristics. They are provided
+ * for illustrative purposes only and no evaluation regarding infringement
+ * of intellectual property rights or copyrights or regarding functionality,
+ * performance or error has been made.
+ *
+ * @filename smi130_i2c.c
+ * @date 2014/11/25 14:40
+ * @Modification Date 2018/08/28 18:20
+ * @id "20f77db"
+ * @version 1.3
+ *
+ * @brief
+ * This file implements moudle function, which add
+ * the driver to I2C core.
+*/
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include "smi130_driver.h"
+
+/*! @defgroup smi130_i2c_src
+ * @brief smi130 i2c driver module
+ @{*/
+
+static struct i2c_client *smi_client;
+/*!
+ * @brief define i2c wirte function
+ *
+ * @param client the pointer of i2c client
+ * @param reg_addr register address
+ * @param data the pointer of data buffer
+ * @param len block size need to write
+ *
+ * @return zero success, non-zero failed
+ * @retval zero success
+ * @retval non-zero failed
+*/
+/* i2c read routine for API*/
+static s8 smi_i2c_read(struct i2c_client *client, u8 reg_addr,
+ u8 *data, u8 len)
+ {
+#if !defined SMI_USE_BASIC_I2C_FUNC
+ s32 dummy;
+ if (NULL == client)
+ return -EINVAL;
+
+ while (0 != len--) {
+#ifdef SMI_SMBUS
+ dummy = i2c_smbus_read_byte_data(client, reg_addr);
+ if (dummy < 0) {
+ dev_err(&client->dev, "i2c smbus read error");
+ return -EIO;
+ }
+ *data = (u8)(dummy & 0xff);
+#else
+ dummy = i2c_master_send(client, (char *)®_addr, 1);
+ if (dummy < 0) {
+ dev_err(&client->dev, "i2c bus master write error");
+ return -EIO;
+ }
+
+ dummy = i2c_master_recv(client, (char *)data, 1);
+ if (dummy < 0) {
+ dev_err(&client->dev, "i2c bus master read error");
+ return -EIO;
+ }
+#endif
+ reg_addr++;
+ data++;
+ }
+ return 0;
+#else
+ int retry;
+
+ struct i2c_msg msg[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 1,
+ .buf = ®_addr,
+ },
+
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = len,
+ .buf = data,
+ },
+ };
+
+ for (retry = 0; retry < SMI_MAX_RETRY_I2C_XFER; retry++) {
+ if (i2c_transfer(client->adapter, msg,
+ ARRAY_SIZE(msg)) > 0)
+ break;
+ else
+ usleep_range(SMI_I2C_WRITE_DELAY_TIME * 1000,
+ SMI_I2C_WRITE_DELAY_TIME * 1000);
+ }
+
+ if (SMI_MAX_RETRY_I2C_XFER <= retry) {
+ dev_err(&client->dev, "I2C xfer error");
+ return -EIO;
+ }
+
+ return 0;
+#endif
+ }
+
+
+static s8 smi_i2c_burst_read(struct i2c_client *client, u8 reg_addr,
+ u8 *data, u16 len)
+{
+ int retry;
+
+ struct i2c_msg msg[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 1,
+ .buf = ®_addr,
+ },
+
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = len,
+ .buf = data,
+ },
+ };
+
+ for (retry = 0; retry < SMI_MAX_RETRY_I2C_XFER; retry++) {
+ if (i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)) > 0)
+ break;
+ else
+ usleep_range(SMI_I2C_WRITE_DELAY_TIME * 1000,
+ SMI_I2C_WRITE_DELAY_TIME * 1000);
+ }
+
+ if (SMI_MAX_RETRY_I2C_XFER <= retry) {
+ dev_err(&client->dev, "I2C xfer error");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+
+/* i2c write routine for */
+static s8 smi_i2c_write(struct i2c_client *client, u8 reg_addr,
+ u8 *data, u8 len)
+{
+#if !defined SMI_USE_BASIC_I2C_FUNC
+ s32 dummy;
+
+#ifndef SMI_SMBUS
+ u8 buffer[2];
+#endif
+
+ if (NULL == client)
+ return -EPERM;
+
+ while (0 != len--) {
+#ifdef SMI_SMBUS
+ dummy = i2c_smbus_write_byte_data(client, reg_addr, *data);
+#else
+ buffer[0] = reg_addr;
+ buffer[1] = *data;
+ dummy = i2c_master_send(client, (char *)buffer, 2);
+#endif
+ reg_addr++;
+ data++;
+ if (dummy < 0) {
+ dev_err(&client->dev, "error writing i2c bus");
+ return -EPERM;
+ }
+
+ }
+ usleep_range(SMI_I2C_WRITE_DELAY_TIME * 1000,
+ SMI_I2C_WRITE_DELAY_TIME * 1000);
+ return 0;
+#else
+ u8 buffer[2];
+ int retry;
+ struct i2c_msg msg[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 2,
+ .buf = buffer,
+ },
+ };
+
+ while (0 != len--) {
+ buffer[0] = reg_addr;
+ buffer[1] = *data;
+ for (retry = 0; retry < SMI_MAX_RETRY_I2C_XFER; retry++) {
+ if (i2c_transfer(client->adapter, msg,
+ ARRAY_SIZE(msg)) > 0) {
+ break;
+ } else {
+ usleep_range(SMI_I2C_WRITE_DELAY_TIME * 1000,
+ SMI_I2C_WRITE_DELAY_TIME * 1000);
+ }
+ }
+ if (SMI_MAX_RETRY_I2C_XFER <= retry) {
+ dev_err(&client->dev, "I2C xfer error");
+ return -EIO;
+ }
+ reg_addr++;
+ data++;
+ }
+
+ usleep_range(SMI_I2C_WRITE_DELAY_TIME * 1000,
+ SMI_I2C_WRITE_DELAY_TIME * 1000);
+ return 0;
+#endif
+}
+
+
+static s8 smi_i2c_read_wrapper(u8 dev_addr, u8 reg_addr, u8 *data, u8 len)
+{
+ int err = 0;
+ err = smi_i2c_read(smi_client, reg_addr, data, len);
+ return err;
+}
+
+static s8 smi_i2c_write_wrapper(u8 dev_addr, u8 reg_addr, u8 *data, u8 len)
+{
+ int err = 0;
+ err = smi_i2c_write(smi_client, reg_addr, data, len);
+ return err;
+}
+
+s8 smi_burst_read_wrapper(u8 dev_addr, u8 reg_addr, u8 *data, u16 len)
+{
+ int err = 0;
+ err = smi_i2c_burst_read(smi_client, reg_addr, data, len);
+ return err;
+}
+EXPORT_SYMBOL(smi_burst_read_wrapper);
+/*!
+ * @brief SMI probe function via i2c bus
+ *
+ * @param client the pointer of i2c client
+ * @param id the pointer of i2c device id
+ *
+ * @return zero success, non-zero failed
+ * @retval zero success
+ * @retval non-zero failed
+*/
+static int smi_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int err = 0;
+ struct smi_client_data *client_data = NULL;
+
+ dev_info(&client->dev, "SMI130 i2c function probe entrance");
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ dev_err(&client->dev, "i2c_check_functionality error!");
+ err = -EIO;
+ goto exit_err_clean;
+ }
+
+ if (NULL == smi_client) {
+ smi_client = client;
+ } else {
+ dev_err(&client->dev,
+ "this driver does not support multiple clients");
+ err = -EBUSY;
+ goto exit_err_clean;
+ }
+
+ client_data = kzalloc(sizeof(struct smi_client_data),
+ GFP_KERNEL);
+ if (NULL == client_data) {
+ dev_err(&client->dev, "no memory available");
+ err = -ENOMEM;
+ goto exit_err_clean;
+ }
+
+ client_data->device.bus_read = smi_i2c_read_wrapper;
+ client_data->device.bus_write = smi_i2c_write_wrapper;
+
+ return smi_probe(client_data, &client->dev);
+
+exit_err_clean:
+ if (err)
+ smi_client = NULL;
+ return err;
+}
+/*
+static int smi_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+ int err = 0;
+ err = smi_suspend(&client->dev);
+ return err;
+}
+
+static int smi_i2c_resume(struct i2c_client *client)
+{
+ int err = 0;
+
+ err = smi_resume(&client->dev);
+
+ return err;
+}
+*/
+
+static int smi_i2c_remove(struct i2c_client *client)
+{
+ int err = 0;
+ err = smi_remove(&client->dev);
+ smi_client = NULL;
+
+ return err;
+}
+
+
+
+static const struct i2c_device_id smi_id[] = {
+ {SENSOR_NAME, 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, smi_id);
+
+static const struct of_device_id smi130_of_match[] = {
+ { .compatible = "bosch-sensortec,smi130", },
+ { .compatible = "smi130", },
+ { .compatible = "bosch, smi130", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, smi130_of_match);
+
+static struct i2c_driver smi_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = SENSOR_NAME,
+ .of_match_table = smi130_of_match,
+ },
+ .class = I2C_CLASS_HWMON,
+ .id_table = smi_id,
+ .probe = smi_i2c_probe,
+ .remove = smi_i2c_remove,
+ /*.suspend = smi_i2c_suspend,
+ .resume = smi_i2c_resume,*/
+};
+
+static int __init SMI_i2c_init(void)
+{
+ return i2c_add_driver(&smi_i2c_driver);
+}
+
+static void __exit SMI_i2c_exit(void)
+{
+ i2c_del_driver(&smi_i2c_driver);
+}
+
+MODULE_AUTHOR("Contact <contact@bosch-sensortec.com>");
+MODULE_DESCRIPTION("driver for " SENSOR_NAME);
+MODULE_LICENSE("GPL v2");
+
+module_init(SMI_i2c_init);
+module_exit(SMI_i2c_exit);
+
diff --git a/drivers/input/sensors/smi130/smi130_spi.c b/drivers/input/sensors/smi130/smi130_spi.c
new file mode 100644
index 0000000..b02efbf1
--- /dev/null
+++ b/drivers/input/sensors/smi130/smi130_spi.c
@@ -0,0 +1,402 @@
+/*!
+ * @section LICENSE
+ * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved
+ *
+ * (C) Modification Copyright 2018 Robert Bosch Kft All Rights Reserved
+ *
+ * This software program is licensed subject to the GNU General
+ * Public License (GPL).Version 2,June 1991,
+ * available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * Special: Description of the Software:
+ *
+ * This software module (hereinafter called "Software") and any
+ * information on application-sheets (hereinafter called "Information") is
+ * provided free of charge for the sole purpose to support your application
+ * work.
+ *
+ * As such, the Software is merely an experimental software, not tested for
+ * safety in the field and only intended for inspiration for further development
+ * and testing. Any usage in a safety-relevant field of use (like automotive,
+ * seafaring, spacefaring, industrial plants etc.) was not intended, so there are
+ * no precautions for such usage incorporated in the Software.
+ *
+ * The Software is specifically designed for the exclusive use for Bosch
+ * Sensortec products by personnel who have special experience and training. Do
+ * not use this Software if you do not have the proper experience or training.
+ *
+ * This Software package is provided as is and without any expressed or
+ * implied warranties, including without limitation, the implied warranties of
+ * merchantability and fitness for a particular purpose.
+ *
+ * Bosch Sensortec and their representatives and agents deny any liability for
+ * the functional impairment of this Software in terms of fitness, performance
+ * and safety. Bosch Sensortec and their representatives and agents shall not be
+ * liable for any direct or indirect damages or injury, except as otherwise
+ * stipulated in mandatory applicable law.
+ * The Information provided is believed to be accurate and reliable. Bosch
+ * Sensortec assumes no responsibility for the consequences of use of such
+ * Information nor for any infringement of patents or other rights of third
+ * parties which may result from its use.
+ *
+ *------------------------------------------------------------------------------
+ * The following Product Disclaimer does not apply to the BSX4-HAL-4.1NoFusion Software
+ * which is licensed under the Apache License, Version 2.0 as stated above.
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Product Disclaimer
+ *
+ * Common:
+ *
+ * Assessment of Products Returned from Field
+ *
+ * Returned products are considered good if they fulfill the specifications /
+ * test data for 0-mileage and field listed in this document.
+ *
+ * Engineering Samples
+ *
+ * Engineering samples are marked with (e) or (E). Samples may vary from the
+ * valid technical specifications of the series product contained in this
+ * data sheet. Therefore, they are not intended or fit for resale to
+ * third parties or for use in end products. Their sole purpose is internal
+ * client testing. The testing of an engineering sample may in no way replace
+ * the testing of a series product. Bosch assumes no liability for the use
+ * of engineering samples. The purchaser shall indemnify Bosch from all claims
+ * arising from the use of engineering samples.
+ *
+ * Intended use
+ *
+ * Provided that SMI130 is used within the conditions (environment, application,
+ * installation, loads) as described in this TCD and the corresponding
+ * agreed upon documents, Bosch ensures that the product complies with
+ * the agreed properties. Agreements beyond this require
+ * the written approval by Bosch. The product is considered fit for the intended
+ * use when the product successfully has passed the tests
+ * in accordance with the TCD and agreed upon documents.
+ *
+ * It is the responsibility of the customer to ensure the proper application
+ * of the product in the overall system/vehicle.
+ *
+ * Bosch does not assume any responsibility for changes to the environment
+ * of the product that deviate from the TCD and the agreed upon documents
+ * as well as all applications not released by Bosch
+ *
+ * The resale and/or use of products are at the purchaser’s own risk and
+ * responsibility. The examination and testing of the SMI130
+ * is the sole responsibility of the purchaser.
+ *
+ * The purchaser shall indemnify Bosch from all third party claims
+ * arising from any product use not covered by the parameters of
+ * this product data sheet or not approved by Bosch and reimburse Bosch
+ * for all costs and damages in connection with such claims.
+ *
+ * The purchaser must monitor the market for the purchased products,
+ * particularly with regard to product safety, and inform Bosch without delay
+ * of all security relevant incidents.
+ *
+ * Application Examples and Hints
+ *
+ * With respect to any application examples, advice, normal values
+ * and/or any information regarding the application of the device,
+ * Bosch hereby disclaims any and all warranties and liabilities of any kind,
+ * including without limitation warranties of
+ * non-infringement of intellectual property rights or copyrights
+ * of any third party.
+ * The information given in this document shall in no event be regarded
+ * as a guarantee of conditions or characteristics. They are provided
+ * for illustrative purposes only and no evaluation regarding infringement
+ * of intellectual property rights or copyrights or regarding functionality,
+ * performance or error has been made.
+ *
+ * @filename smi130_spi.c
+ * @date 2014/11/25 14:40
+ * @Modification Date 2018/08/28 18:20
+ * @id "20f77db"
+ * @version 1.3
+ *
+ * @brief
+ * This file implements moudle function, which add
+ * the driver to SPI core.
+*/
+
+#include <linux/module.h>
+#include <linux/spi/spi.h>
+#include <linux/delay.h>
+#include "smi130_driver.h"
+
+/*! @defgroup smi130_spi_src
+ * @brief smi130 spi driver module
+ @{*/
+/*! the maximum of transfer buffer size */
+#define SMI_MAX_BUFFER_SIZE 32
+
+static struct spi_device *smi_spi_client;
+
+/*!
+ * @brief define spi wirte function
+ *
+ * @param dev_addr sensor device address
+ * @param reg_addr register address
+ * @param data the pointer of data buffer
+ * @param len block size need to write
+ *
+ * @return zero success, non-zero failed
+ * @retval zero success
+ * @retval non-zero failed
+*/
+static char smi_spi_write_block(u8 dev_addr, u8 reg_addr, u8 *data, u8 len)
+{
+ struct spi_device *client = smi_spi_client;
+ u8 buffer[SMI_MAX_BUFFER_SIZE + 1];
+ struct spi_transfer xfer = {
+ .tx_buf = buffer,
+ .len = len + 1,
+ };
+ struct spi_message msg;
+
+ if (len > SMI_MAX_BUFFER_SIZE)
+ return -EINVAL;
+
+ buffer[0] = reg_addr&0x7F;/* write: MSB = 0 */
+ memcpy(&buffer[1], data, len);
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ return spi_sync(client, &msg);
+}
+
+/*!
+ * @brief define spi read function
+ *
+ * @param dev_addr sensor device address
+ * @param reg_addr register address
+ * @param data the pointer of data buffer
+ * @param len block size need to read
+ *
+ * @return zero success, non-zero failed
+ * @retval zero success
+ * @retval non-zero failed
+*/
+static char smi_spi_read_block(u8 dev_addr, u8 reg_addr, u8 *data, u8 len)
+{
+ struct spi_device *client = smi_spi_client;
+ u8 reg = reg_addr | 0x80;/* read: MSB = 1 */
+ struct spi_transfer xfer[2] = {
+ [0] = {
+ .tx_buf = ®,
+ .len = 1,
+ },
+ [1] = {
+ .rx_buf = data,
+ .len = len,
+ }
+ };
+ struct spi_message msg;
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer[0], &msg);
+ spi_message_add_tail(&xfer[1], &msg);
+ return spi_sync(client, &msg);
+}
+
+s8 smi_burst_read_wrapper(u8 dev_addr, u8 reg_addr, u8 *data, u16 len)
+{
+ struct spi_device *client = smi_spi_client;
+ u8 reg = reg_addr | 0x80;/* read: MSB = 1 */
+ struct spi_transfer xfer[2] = {
+ [0] = {
+ .tx_buf = ®,
+ .len = 1,
+ },
+ [1] = {
+ .rx_buf = data,
+ .len = len,
+ }
+ };
+ struct spi_message msg;
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer[0], &msg);
+ spi_message_add_tail(&xfer[1], &msg);
+ return spi_sync(client, &msg);
+}
+EXPORT_SYMBOL(smi_burst_read_wrapper);
+/*!
+ * @brief SMI probe function via spi bus
+ *
+ * @param client the pointer of spi client
+ *
+ * @return zero success, non-zero failed
+ * @retval zero success
+ * @retval non-zero failed
+*/
+static int smi_spi_probe(struct spi_device *client)
+{
+ int status;
+ int err = 0;
+ struct smi_client_data *client_data = NULL;
+
+ if (NULL == smi_spi_client)
+ smi_spi_client = client;
+ else{
+ dev_err(&client->dev, "This driver does not support multiple clients!\n");
+ return -EBUSY;
+ }
+
+ client->bits_per_word = 8;
+ status = spi_setup(client);
+ if (status < 0) {
+ dev_err(&client->dev, "spi_setup failed!\n");
+ return status;
+ }
+
+ client_data = kzalloc(sizeof(struct smi_client_data), GFP_KERNEL);
+ if (NULL == client_data) {
+ dev_err(&client->dev, "no memory available");
+ err = -ENOMEM;
+ goto exit_err_clean;
+ }
+
+ client_data->device.bus_read = smi_spi_read_block;
+ client_data->device.bus_write = smi_spi_write_block;
+
+ return smi_probe(client_data, &client->dev);
+
+exit_err_clean:
+ if (err)
+ smi_spi_client = NULL;
+ return err;
+}
+
+/*!
+ * @brief shutdown smi device in spi driver
+ *
+ * @param client the pointer of spi client
+ *
+ * @return no return value
+*/
+static void smi_spi_shutdown(struct spi_device *client)
+{
+#ifdef CONFIG_PM
+ smi_suspend(&client->dev);
+#endif
+}
+
+/*!
+ * @brief remove smi spi client
+ *
+ * @param client the pointer of spi client
+ *
+ * @return zero
+ * @retval zero
+*/
+static int smi_spi_remove(struct spi_device *client)
+{
+ int err = 0;
+ err = smi_remove(&client->dev);
+ smi_spi_client = NULL;
+
+ return err;
+}
+
+#ifdef CONFIG_PM
+/*!
+ * @brief suspend smi device in spi driver
+ *
+ * @param dev the pointer of device
+ *
+ * @return zero
+ * @retval zero
+*/
+static int smi_spi_suspend(struct device *dev)
+{
+ int err = 0;
+ err = smi_suspend(dev);
+ return err;
+}
+
+/*!
+ * @brief resume smi device in spi driver
+ *
+ * @param dev the pointer of device
+ *
+ * @return zero
+ * @retval zero
+*/
+static int smi_spi_resume(struct device *dev)
+{
+ int err = 0;
+ /* post resume operation */
+ err = smi_resume(dev);
+
+ return err;
+}
+
+/*!
+ * @brief register spi device power manager hooks
+*/
+static const struct dev_pm_ops smi_spi_pm_ops = {
+ /**< device suspend */
+ .suspend = smi_spi_suspend,
+ /**< device resume */
+ .resume = smi_spi_resume
+};
+#endif
+
+/*!
+ * @brief register spi device id
+*/
+static const struct spi_device_id smi_id[] = {
+ { SENSOR_NAME, 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(spi, smi_id);
+
+/*!
+ * @brief register spi driver hooks
+*/
+static struct spi_driver smi_spi_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = SENSOR_NAME,
+#ifdef CONFIG_PM
+ .pm = &smi_spi_pm_ops,
+#endif
+ },
+ .id_table = smi_id,
+ .probe = smi_spi_probe,
+ .shutdown = smi_spi_shutdown,
+ .remove = smi_spi_remove
+};
+
+/*!
+ * @brief initialize smi spi module
+ *
+ * @return zero success, non-zero failed
+ * @retval zero success
+ * @retval non-zero failed
+*/
+static int __init smi_spi_init(void)
+{
+ return spi_register_driver(&smi_spi_driver);
+}
+
+/*!
+ * @brief remove smi spi module
+ *
+ * @return no return value
+*/
+static void __exit smi_spi_exit(void)
+{
+ spi_unregister_driver(&smi_spi_driver);
+}
+
+
+MODULE_AUTHOR("Contact <contact@bosch-sensortec.com>");
+MODULE_DESCRIPTION("SMI130 SPI DRIVER");
+MODULE_LICENSE("GPL v2");
+
+module_init(smi_spi_init);
+module_exit(smi_spi_exit);
+/*@}*/
+
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index e484ea2..34be096 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -527,6 +527,13 @@
DMI_MATCH(DMI_PRODUCT_NAME, "N24_25BU"),
},
},
+ {
+ /* Lenovo LaVie Z */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo LaVie Z"),
+ },
+ },
{ }
};
diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig
index dafa981..bb1935f 100644
--- a/drivers/md/Kconfig
+++ b/drivers/md/Kconfig
@@ -292,6 +292,22 @@
To compile this code as a module, choose M here: the module will
be called dm-req-crypt.
+config DM_DEFAULT_KEY
+ tristate "Default-key crypt target support"
+ depends on BLK_DEV_DM
+ depends on PFK
+ ---help---
+ This (currently Android-specific) device-mapper target allows you to
+ create a device that assigns a default encryption key to bios that
+ don't already have one. This can sit between inline cryptographic
+ acceleration hardware and filesystems that use it. This ensures that
+ where the filesystem doesn't explicitly specify a key, such as for
+ filesystem metadata, a default key will be used instead, leaving no
+ sectors unencrypted.
+
+ To compile this code as a module, choose M here: the module will be
+ called dm-default-key.
+
If unsure, say N.
config DM_SNAPSHOT
@@ -535,14 +551,14 @@
config DM_ANDROID_VERITY
bool "Android verity target support"
+ depends on BLK_DEV_DM=y
depends on DM_VERITY=y
depends on X509_CERTIFICATE_PARSER
depends on SYSTEM_TRUSTED_KEYRING
- depends on PUBLIC_KEY_ALGO_RSA
+ depends on CRYPTO_RSA
depends on KEYS
depends on ASYMMETRIC_KEY_TYPE
depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE
- depends on MD_LINEAR=y
select DM_VERITY_HASH_PREFETCH_MIN_SIZE_128
---help---
This device-mapper target is virtually a VERITY target. This
@@ -554,8 +570,8 @@
config DM_ANDROID_VERITY_AT_MOST_ONCE_DEFAULT_ENABLED
bool "Verity will validate blocks at most once"
- depends on DM_VERITY
- ---help---
+ depends on DM_VERITY
+ ---help---
Default enables at_most_once option for dm-verity
Verify data blocks only the first time they are read from the
diff --git a/drivers/md/Makefile b/drivers/md/Makefile
index f14e2fc..c3bf33b 100644
--- a/drivers/md/Makefile
+++ b/drivers/md/Makefile
@@ -40,6 +40,7 @@
obj-$(CONFIG_DM_BUFIO) += dm-bufio.o
obj-$(CONFIG_DM_BIO_PRISON) += dm-bio-prison.o
obj-$(CONFIG_DM_CRYPT) += dm-crypt.o
+obj-$(CONFIG_DM_DEFAULT_KEY) += dm-default-key.o
obj-$(CONFIG_DM_DELAY) += dm-delay.o
obj-$(CONFIG_DM_FLAKEY) += dm-flakey.o
obj-$(CONFIG_DM_MULTIPATH) += dm-multipath.o dm-round-robin.o
diff --git a/drivers/md/dm-android-verity.c b/drivers/md/dm-android-verity.c
index eb4bdf6..f9491de 100644
--- a/drivers/md/dm-android-verity.c
+++ b/drivers/md/dm-android-verity.c
@@ -33,6 +33,7 @@
#include <asm/setup.h>
#include <crypto/hash.h>
+#include <crypto/hash_info.h>
#include <crypto/public_key.h>
#include <crypto/sha.h>
#include <keys/asymmetric-type.h>
@@ -122,75 +123,6 @@
return !strncmp(verifiedbootstate, unlocked, sizeof(unlocked));
}
-static int table_extract_mpi_array(struct public_key_signature *pks,
- const void *data, size_t len)
-{
- MPI mpi = mpi_read_raw_data(data, len);
-
- if (!mpi) {
- DMERR("Error while allocating mpi array");
- return -ENOMEM;
- }
-
- pks->mpi[0] = mpi;
- pks->nr_mpi = 1;
- return 0;
-}
-
-static struct public_key_signature *table_make_digest(
- enum hash_algo hash,
- const void *table,
- unsigned long table_len)
-{
- struct public_key_signature *pks = NULL;
- struct crypto_shash *tfm;
- struct shash_desc *desc;
- size_t digest_size, desc_size;
- int ret;
-
- /* Allocate the hashing algorithm we're going to need and find out how
- * big the hash operational data will be.
- */
- tfm = crypto_alloc_shash(hash_algo_name[hash], 0, 0);
- if (IS_ERR(tfm))
- return ERR_CAST(tfm);
-
- desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
- digest_size = crypto_shash_digestsize(tfm);
-
- /* We allocate the hash operational data storage on the end of out
- * context data and the digest output buffer on the end of that.
- */
- ret = -ENOMEM;
- pks = kzalloc(digest_size + sizeof(*pks) + desc_size, GFP_KERNEL);
- if (!pks)
- goto error;
-
- pks->pkey_hash_algo = hash;
- pks->digest = (u8 *)pks + sizeof(*pks) + desc_size;
- pks->digest_size = digest_size;
-
- desc = (struct shash_desc *)(pks + 1);
- desc->tfm = tfm;
- desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
-
- ret = crypto_shash_init(desc);
- if (ret < 0)
- goto error;
-
- ret = crypto_shash_finup(desc, table, table_len, pks->digest);
- if (ret < 0)
- goto error;
-
- crypto_free_shash(tfm);
- return pks;
-
-error:
- kfree(pks);
- crypto_free_shash(tfm);
- return ERR_PTR(ret);
-}
-
static int read_block_dev(struct bio_read *payload, struct block_device *bdev,
sector_t offset, int length)
{
@@ -207,6 +139,7 @@
bio->bi_bdev = bdev;
bio->bi_iter.bi_sector = offset;
+ bio_set_op_attrs(bio, REQ_OP_READ, READ_SYNC);
payload->page_io = kzalloc(sizeof(struct page *) *
payload->number_of_pages, GFP_KERNEL);
@@ -230,7 +163,7 @@
}
}
- if (!submit_bio_wait(READ, bio))
+ if (!submit_bio_wait(bio))
/* success */
goto free_bio;
DMERR("bio read failed");
@@ -567,51 +500,6 @@
return DM_VERITY_MODE_EIO;
}
-static int verify_verity_signature(char *key_id,
- struct android_metadata *metadata)
-{
- key_ref_t key_ref;
- struct key *key;
- struct public_key_signature *pks = NULL;
- int retval = -EINVAL;
-
- key_ref = keyring_search(make_key_ref(system_trusted_keyring, 1),
- &key_type_asymmetric, key_id);
-
- if (IS_ERR(key_ref)) {
- DMERR("keyring: key not found");
- return -ENOKEY;
- }
-
- key = key_ref_to_ptr(key_ref);
-
- pks = table_make_digest(HASH_ALGO_SHA256,
- (const void *)metadata->verity_table,
- le32_to_cpu(metadata->header->table_length));
-
- if (IS_ERR(pks)) {
- DMERR("hashing failed");
- retval = PTR_ERR(pks);
- pks = NULL;
- goto error;
- }
-
- retval = table_extract_mpi_array(pks, &metadata->header->signature[0],
- RSANUMBYTES);
- if (retval < 0) {
- DMERR("Error extracting mpi %d", retval);
- goto error;
- }
-
- retval = verify_signature(key, pks);
- mpi_free(pks->rsa.s);
-error:
- kfree(pks);
- key_put(key);
-
- return retval;
-}
-
static void handle_error(void)
{
int mode = verity_mode();
@@ -623,6 +511,95 @@
}
}
+static struct public_key_signature *table_make_digest(
+ enum hash_algo hash,
+ const void *table,
+ unsigned long table_len)
+{
+ struct public_key_signature *pks = NULL;
+ struct crypto_shash *tfm;
+ struct shash_desc *desc;
+ size_t digest_size, desc_size;
+ int ret;
+
+ /* Allocate the hashing algorithm we're going to need and find out how
+ * big the hash operational data will be.
+ */
+ tfm = crypto_alloc_shash(hash_algo_name[hash], 0, 0);
+ if (IS_ERR(tfm))
+ return ERR_CAST(tfm);
+
+ desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
+ digest_size = crypto_shash_digestsize(tfm);
+
+ /* We allocate the hash operational data storage on the end of out
+ * context data and the digest output buffer on the end of that.
+ */
+ ret = -ENOMEM;
+ pks = kzalloc(digest_size + sizeof(*pks) + desc_size, GFP_KERNEL);
+ if (!pks)
+ goto error;
+
+ pks->pkey_algo = "rsa";
+ pks->hash_algo = hash_algo_name[hash];
+ pks->digest = (u8 *)pks + sizeof(*pks) + desc_size;
+ pks->digest_size = digest_size;
+
+ desc = (struct shash_desc *)(pks + 1);
+ desc->tfm = tfm;
+ desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
+
+ ret = crypto_shash_init(desc);
+ if (ret < 0)
+ goto error;
+
+ ret = crypto_shash_finup(desc, table, table_len, pks->digest);
+ if (ret < 0)
+ goto error;
+
+ crypto_free_shash(tfm);
+ return pks;
+
+error:
+ kfree(pks);
+ crypto_free_shash(tfm);
+ return ERR_PTR(ret);
+}
+
+
+static int verify_verity_signature(char *key_id,
+ struct android_metadata *metadata)
+{
+ struct public_key_signature *pks = NULL;
+ int retval = -EINVAL;
+
+ if (!key_id)
+ goto error;
+
+ pks = table_make_digest(HASH_ALGO_SHA256,
+ (const void *)metadata->verity_table,
+ le32_to_cpu(metadata->header->table_length));
+ if (IS_ERR(pks)) {
+ DMERR("hashing failed");
+ retval = PTR_ERR(pks);
+ pks = NULL;
+ goto error;
+ }
+
+ pks->s = kmemdup(&metadata->header->signature[0], RSANUMBYTES, GFP_KERNEL);
+ if (!pks->s) {
+ DMERR("Error allocating memory for signature");
+ goto error;
+ }
+ pks->s_size = RSANUMBYTES;
+
+ retval = verify_signature_one(pks, NULL, key_id);
+ kfree(pks->s);
+error:
+ kfree(pks);
+ return retval;
+}
+
static inline bool test_mult_overflow(sector_t a, u32 b)
{
sector_t r = (sector_t)~0ULL;
@@ -694,8 +671,8 @@
dev_t uninitialized_var(dev);
struct android_metadata *metadata = NULL;
int err = 0, i, mode;
- char *key_id, *table_ptr, dummy, *target_device,
- *verity_table_args[VERITY_TABLE_ARGS + 2 + VERITY_TABLE_OPT_FEC_ARGS];
+ char *key_id = NULL, *table_ptr, dummy, *target_device;
+ char *verity_table_args[VERITY_TABLE_ARGS + 2 + VERITY_TABLE_OPT_FEC_ARGS];
/* One for specifying number of opt args and one for mode */
sector_t data_sectors;
u32 data_block_size;
@@ -714,16 +691,16 @@
handle_error();
return -EINVAL;
}
- } else if (argc == 2)
- key_id = argv[1];
- else {
+ target_device = argv[0];
+ } else if (argc == 2) {
+ key_id = argv[0];
+ target_device = argv[1];
+ } else {
DMERR("Incorrect number of arguments");
handle_error();
return -EINVAL;
}
- target_device = argv[0];
-
dev = name_to_dev_t(target_device);
if (!dev) {
DMERR("no dev found for %s", target_device);
@@ -877,12 +854,11 @@
}
err = verity_ctr(ti, no_of_args, verity_table_args);
-
- if (err)
- DMERR("android-verity failed to mount as verity target");
- else {
+ if (err) {
+ DMERR("android-verity failed to create a verity target");
+ } else {
target_added = true;
- DMINFO("android-verity mounted as verity target");
+ DMINFO("android-verity created as verity target");
}
free_metadata:
diff --git a/drivers/md/dm-default-key.c b/drivers/md/dm-default-key.c
new file mode 100644
index 0000000..ca50de1
--- /dev/null
+++ b/drivers/md/dm-default-key.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2017 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/device-mapper.h>
+#include <linux/module.h>
+#include <linux/pfk.h>
+
+#define DM_MSG_PREFIX "default-key"
+
+struct default_key_c {
+ struct dm_dev *dev;
+ sector_t start;
+ struct blk_encryption_key key;
+};
+
+static void default_key_dtr(struct dm_target *ti)
+{
+ struct default_key_c *dkc = ti->private;
+
+ if (dkc->dev)
+ dm_put_device(ti, dkc->dev);
+ kzfree(dkc);
+}
+
+/*
+ * Construct a default-key mapping: <mode> <key> <dev_path> <start>
+ */
+static int default_key_ctr(struct dm_target *ti, unsigned int argc, char **argv)
+{
+ struct default_key_c *dkc;
+ size_t key_size;
+ unsigned long long tmp;
+ char dummy;
+ int err;
+
+ if (argc != 4) {
+ ti->error = "Invalid argument count";
+ return -EINVAL;
+ }
+
+ dkc = kzalloc(sizeof(*dkc), GFP_KERNEL);
+ if (!dkc) {
+ ti->error = "Out of memory";
+ return -ENOMEM;
+ }
+ ti->private = dkc;
+
+ if (strcmp(argv[0], "AES-256-XTS") != 0) {
+ ti->error = "Unsupported encryption mode";
+ err = -EINVAL;
+ goto bad;
+ }
+
+ key_size = strlen(argv[1]);
+ if (key_size != 2 * BLK_ENCRYPTION_KEY_SIZE_AES_256_XTS) {
+ ti->error = "Unsupported key size";
+ err = -EINVAL;
+ goto bad;
+ }
+ key_size /= 2;
+
+ if (hex2bin(dkc->key.raw, argv[1], key_size) != 0) {
+ ti->error = "Malformed key string";
+ err = -EINVAL;
+ goto bad;
+ }
+
+ err = dm_get_device(ti, argv[2], dm_table_get_mode(ti->table),
+ &dkc->dev);
+ if (err) {
+ ti->error = "Device lookup failed";
+ goto bad;
+ }
+
+ if (sscanf(argv[3], "%llu%c", &tmp, &dummy) != 1) {
+ ti->error = "Invalid start sector";
+ err = -EINVAL;
+ goto bad;
+ }
+ dkc->start = tmp;
+
+ if (!blk_queue_inlinecrypt(bdev_get_queue(dkc->dev->bdev))) {
+ ti->error = "Device does not support inline encryption";
+ err = -EINVAL;
+ goto bad;
+ }
+
+ /* Pass flush requests through to the underlying device. */
+ ti->num_flush_bios = 1;
+
+ /*
+ * We pass discard requests through to the underlying device, although
+ * the discarded blocks will be zeroed, which leaks information about
+ * unused blocks. It's also impossible for dm-default-key to know not
+ * to decrypt discarded blocks, so they will not be read back as zeroes
+ * and we must set discard_zeroes_data_unsupported.
+ */
+ ti->num_discard_bios = 1;
+
+ /*
+ * It's unclear whether WRITE_SAME would work with inline encryption; it
+ * would depend on whether the hardware duplicates the data before or
+ * after encryption. But since the internal storage in some devices
+ * (MSM8998-based) doesn't claim to support WRITE_SAME anyway, we don't
+ * currently have a way to test it. Leave it disabled it for now.
+ */
+ /*ti->num_write_same_bios = 1;*/
+
+ return 0;
+
+bad:
+ default_key_dtr(ti);
+ return err;
+}
+
+static int default_key_map(struct dm_target *ti, struct bio *bio)
+{
+ const struct default_key_c *dkc = ti->private;
+
+ bio->bi_bdev = dkc->dev->bdev;
+ if (bio_sectors(bio)) {
+ bio->bi_iter.bi_sector = dkc->start +
+ dm_target_offset(ti, bio->bi_iter.bi_sector);
+ }
+
+ if (!bio->bi_crypt_key && !bio->bi_crypt_skip)
+ bio->bi_crypt_key = &dkc->key;
+
+ return DM_MAPIO_REMAPPED;
+}
+
+static void default_key_status(struct dm_target *ti, status_type_t type,
+ unsigned int status_flags, char *result,
+ unsigned int maxlen)
+{
+ const struct default_key_c *dkc = ti->private;
+ unsigned int sz = 0;
+
+ switch (type) {
+ case STATUSTYPE_INFO:
+ result[0] = '\0';
+ break;
+
+ case STATUSTYPE_TABLE:
+
+ /* encryption mode */
+ DMEMIT("AES-256-XTS");
+
+ /* reserved for key; dm-crypt shows it, but we don't for now */
+ DMEMIT(" -");
+
+ /* name of underlying device, and the start sector in it */
+ DMEMIT(" %s %llu", dkc->dev->name,
+ (unsigned long long)dkc->start);
+ break;
+ }
+}
+
+static int default_key_prepare_ioctl(struct dm_target *ti,
+ struct block_device **bdev, fmode_t *mode)
+{
+ struct default_key_c *dkc = ti->private;
+ struct dm_dev *dev = dkc->dev;
+
+ *bdev = dev->bdev;
+
+ /*
+ * Only pass ioctls through if the device sizes match exactly.
+ */
+ if (dkc->start ||
+ ti->len != i_size_read(dev->bdev->bd_inode) >> SECTOR_SHIFT)
+ return 1;
+ return 0;
+}
+
+static int default_key_iterate_devices(struct dm_target *ti,
+ iterate_devices_callout_fn fn,
+ void *data)
+{
+ struct default_key_c *dkc = ti->private;
+
+ return fn(ti, dkc->dev, dkc->start, ti->len, data);
+}
+
+static struct target_type default_key_target = {
+ .name = "default-key",
+ .version = {1, 0, 0},
+ .module = THIS_MODULE,
+ .ctr = default_key_ctr,
+ .dtr = default_key_dtr,
+ .map = default_key_map,
+ .status = default_key_status,
+ .prepare_ioctl = default_key_prepare_ioctl,
+ .iterate_devices = default_key_iterate_devices,
+};
+
+static int __init dm_default_key_init(void)
+{
+ return dm_register_target(&default_key_target);
+}
+
+static void __exit dm_default_key_exit(void)
+{
+ dm_unregister_target(&default_key_target);
+}
+
+module_init(dm_default_key_init);
+module_exit(dm_default_key_exit);
+
+MODULE_AUTHOR("Paul Lawrence <paullawrence@google.com>");
+MODULE_AUTHOR("Paul Crowley <paulcrowley@google.com>");
+MODULE_AUTHOR("Eric Biggers <ebiggers@google.com>");
+MODULE_DESCRIPTION(DM_NAME " target for encrypting filesystem metadata");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index b75ccef..6b7b4dd 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -511,14 +511,14 @@
* On the other hand, dm-switch needs to process bulk data using messages and
* excessive use of GFP_NOIO could cause trouble.
*/
-static char **realloc_argv(unsigned *array_size, char **old_argv)
+static char **realloc_argv(unsigned *size, char **old_argv)
{
char **argv;
unsigned new_size;
gfp_t gfp;
- if (*array_size) {
- new_size = *array_size * 2;
+ if (*size) {
+ new_size = *size * 2;
gfp = GFP_KERNEL;
} else {
new_size = 8;
@@ -526,8 +526,8 @@
}
argv = kmalloc(new_size * sizeof(*argv), gfp);
if (argv) {
- memcpy(argv, old_argv, *array_size * sizeof(*argv));
- *array_size = new_size;
+ memcpy(argv, old_argv, *size * sizeof(*argv));
+ *size = new_size;
}
kfree(old_argv);
@@ -1495,6 +1495,16 @@
return q && !test_bit(QUEUE_FLAG_NO_SG_MERGE, &q->queue_flags);
}
+static int queue_supports_inline_encryption(struct dm_target *ti,
+ struct dm_dev *dev,
+ sector_t start, sector_t len,
+ void *data)
+{
+ struct request_queue *q = bdev_get_queue(dev->bdev);
+
+ return q && blk_queue_inlinecrypt(q);
+}
+
static bool dm_table_all_devices_attribute(struct dm_table *t,
iterate_devices_callout_fn func)
{
@@ -1615,6 +1625,11 @@
else
queue_flag_set_unlocked(QUEUE_FLAG_NO_SG_MERGE, q);
+ if (dm_table_all_devices_attribute(t, queue_supports_inline_encryption))
+ queue_flag_set_unlocked(QUEUE_FLAG_INLINECRYPT, q);
+ else
+ queue_flag_clear_unlocked(QUEUE_FLAG_INLINECRYPT, q);
+
dm_table_verify_integrity(t);
/*
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 13b3424..bf2d2df 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -6192,6 +6192,9 @@
char b[BDEVNAME_SIZE];
struct md_rdev *rdev;
+ if (!mddev->pers)
+ return -ENODEV;
+
rdev = find_rdev(mddev, dev);
if (!rdev)
return -ENXIO;
diff --git a/drivers/media/common/siano/smsendian.c b/drivers/media/common/siano/smsendian.c
index bfe831c..b95a631 100644
--- a/drivers/media/common/siano/smsendian.c
+++ b/drivers/media/common/siano/smsendian.c
@@ -35,7 +35,7 @@
switch (msg->x_msg_header.msg_type) {
case MSG_SMS_DATA_DOWNLOAD_REQ:
{
- msg->msg_data[0] = le32_to_cpu(msg->msg_data[0]);
+ msg->msg_data[0] = le32_to_cpu((__force __le32)(msg->msg_data[0]));
break;
}
@@ -44,7 +44,7 @@
sizeof(struct sms_msg_hdr))/4;
for (i = 0; i < msg_words; i++)
- msg->msg_data[i] = le32_to_cpu(msg->msg_data[i]);
+ msg->msg_data[i] = le32_to_cpu((__force __le32)msg->msg_data[i]);
break;
}
@@ -64,7 +64,7 @@
{
struct sms_version_res *ver =
(struct sms_version_res *) msg;
- ver->chip_model = le16_to_cpu(ver->chip_model);
+ ver->chip_model = le16_to_cpu((__force __le16)ver->chip_model);
break;
}
@@ -81,7 +81,7 @@
sizeof(struct sms_msg_hdr))/4;
for (i = 0; i < msg_words; i++)
- msg->msg_data[i] = le32_to_cpu(msg->msg_data[i]);
+ msg->msg_data[i] = le32_to_cpu((__force __le32)msg->msg_data[i]);
break;
}
@@ -95,9 +95,9 @@
#ifdef __BIG_ENDIAN
struct sms_msg_hdr *phdr = (struct sms_msg_hdr *)msg;
- phdr->msg_type = le16_to_cpu(phdr->msg_type);
- phdr->msg_length = le16_to_cpu(phdr->msg_length);
- phdr->msg_flags = le16_to_cpu(phdr->msg_flags);
+ phdr->msg_type = le16_to_cpu((__force __le16)phdr->msg_type);
+ phdr->msg_length = le16_to_cpu((__force __le16)phdr->msg_length);
+ phdr->msg_flags = le16_to_cpu((__force __le16)phdr->msg_flags);
#endif /* __BIG_ENDIAN */
}
EXPORT_SYMBOL_GPL(smsendian_handle_message_header);
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c
index 44f8c7e..8ffa13f 100644
--- a/drivers/media/i2c/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -991,7 +991,7 @@
if (rval)
goto out;
- for (i = 0; i < 1000; i++) {
+ for (i = 1000; i > 0; i--) {
rval = smiapp_read(
sensor,
SMIAPP_REG_U8_DATA_TRANSFER_IF_1_STATUS, &s);
@@ -1002,11 +1002,10 @@
if (s & SMIAPP_DATA_TRANSFER_IF_1_STATUS_RD_READY)
break;
- if (--i == 0) {
- rval = -ETIMEDOUT;
- goto out;
- }
-
+ }
+ if (!i) {
+ rval = -ETIMEDOUT;
+ goto out;
}
for (i = 0; i < SMIAPP_NVM_PAGE_SIZE; i++) {
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index cc8de56..6f46c59 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -60,7 +60,7 @@
static long media_device_get_info(struct media_device *dev, void *arg)
{
- struct media_device_info *info = (struct media_device_info *)arg;
+ struct media_device_info *info = arg;
memset(info, 0, sizeof(*info));
@@ -100,7 +100,7 @@
static long media_device_enum_entities(struct media_device *mdev, void *arg)
{
- struct media_entity_desc *entd = (struct media_entity_desc *)arg;
+ struct media_entity_desc *entd = arg;
struct media_entity *ent;
ent = find_entity(mdev, entd->id);
@@ -153,7 +153,7 @@
static long media_device_enum_links(struct media_device *mdev, void *arg)
{
- struct media_links_enum *links = (struct media_links_enum *)arg;
+ struct media_links_enum *links = arg;
struct media_entity *entity;
entity = find_entity(mdev, links->entity);
@@ -201,7 +201,7 @@
static long media_device_setup_link(struct media_device *mdev, void *arg)
{
- struct media_link_desc *linkd = (struct media_link_desc *)arg;
+ struct media_link_desc *linkd = arg;
struct media_link *link = NULL;
struct media_entity *source;
struct media_entity *sink;
@@ -229,7 +229,7 @@
static long media_device_get_topology(struct media_device *mdev, void *arg)
{
- struct media_v2_topology *topo = (struct media_v2_topology *)arg;
+ struct media_v2_topology *topo = arg;
struct media_entity *entity;
struct media_interface *intf;
struct media_pad *pad;
diff --git a/drivers/media/pci/saa7164/saa7164-fw.c b/drivers/media/pci/saa7164/saa7164-fw.c
index 269e078..93d5319 100644
--- a/drivers/media/pci/saa7164/saa7164-fw.c
+++ b/drivers/media/pci/saa7164/saa7164-fw.c
@@ -430,7 +430,8 @@
__func__, fw->size);
if (fw->size != fwlength) {
- printk(KERN_ERR "xc5000: firmware incorrect size\n");
+ printk(KERN_ERR "saa7164: firmware incorrect size %zu != %u\n",
+ fw->size, fwlength);
ret = -ENOMEM;
goto out;
}
diff --git a/drivers/media/pci/tw686x/tw686x-video.c b/drivers/media/pci/tw686x/tw686x-video.c
index c3fafa9..0ea8dd4 100644
--- a/drivers/media/pci/tw686x/tw686x-video.c
+++ b/drivers/media/pci/tw686x/tw686x-video.c
@@ -1228,7 +1228,8 @@
vc->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
vc->vidq.min_buffers_needed = 2;
vc->vidq.lock = &vc->vb_mutex;
- vc->vidq.gfp_flags = GFP_DMA32;
+ vc->vidq.gfp_flags = dev->dma_mode != TW686X_DMA_MODE_MEMCPY ?
+ GFP_DMA32 : 0;
vc->vidq.dev = &dev->pci_dev->dev;
err = vb2_queue_init(&vc->vidq);
diff --git a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_hw_core.c b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_hw_core.c
index f2796be..4ae2f0a 100644
--- a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_hw_core.c
+++ b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_hw_core.c
@@ -624,7 +624,8 @@
}
static void cam_hw_cdm_iommu_fault_handler(struct iommu_domain *domain,
- struct device *dev, unsigned long iova, int flags, void *token)
+ struct device *dev, unsigned long iova, int flags, void *token,
+ uint32_t buf_info)
{
struct cam_hw_info *cdm_hw = NULL;
struct cam_cdm *core = NULL;
@@ -910,7 +911,7 @@
CAM_ERR(CAM_CDM, "cpas-cdm get iommu handle failed");
goto unlock_release_mem;
}
- cam_smmu_reg_client_page_fault_handler(cdm_core->iommu_hdl.non_secure,
+ cam_smmu_set_client_page_fault_handler(cdm_core->iommu_hdl.non_secure,
cam_hw_cdm_iommu_fault_handler, cdm_hw);
rc = cam_smmu_ops(cdm_core->iommu_hdl.non_secure, CAM_SMMU_ATTACH);
@@ -1034,7 +1035,7 @@
flush_workqueue(cdm_core->work_queue);
destroy_workqueue(cdm_core->work_queue);
destroy_non_secure_hdl:
- cam_smmu_reg_client_page_fault_handler(cdm_core->iommu_hdl.non_secure,
+ cam_smmu_set_client_page_fault_handler(cdm_core->iommu_hdl.non_secure,
NULL, cdm_hw);
if (cam_smmu_destroy_handle(cdm_core->iommu_hdl.non_secure))
CAM_ERR(CAM_CDM, "Release iommu secure hdl failed");
@@ -1106,8 +1107,8 @@
if (cam_smmu_destroy_handle(cdm_core->iommu_hdl.non_secure))
CAM_ERR(CAM_CDM, "Release iommu secure hdl failed");
- cam_smmu_reg_client_page_fault_handler(cdm_core->iommu_hdl.non_secure,
- NULL, cdm_hw);
+ cam_smmu_unset_client_page_fault_handler(
+ cdm_core->iommu_hdl.non_secure, cdm_hw);
mutex_destroy(&cdm_hw->hw_mutex);
kfree(cdm_hw->soc_info.soc_private);
diff --git a/drivers/media/platform/msm/camera/cam_core/cam_context.c b/drivers/media/platform/msm/camera/cam_core/cam_context.c
index da78527..4ed53f9 100644
--- a/drivers/media/platform/msm/camera/cam_core/cam_context.c
+++ b/drivers/media/platform/msm/camera/cam_core/cam_context.c
@@ -42,6 +42,7 @@
int rc = 0;
int32_t ctx_hdl = ctx->dev_hdl;
+ mutex_lock(&ctx->ctx_mutex);
if (ctx->state_machine[ctx->state].ioctl_ops.stop_dev) {
rc = ctx->state_machine[ctx->state].ioctl_ops.stop_dev(
ctx, NULL);
@@ -54,6 +55,7 @@
if (rc < 0)
CAM_ERR(CAM_CORE, "Error while dev release %d", rc);
}
+ mutex_unlock(&ctx->ctx_mutex);
if (!rc)
rc = cam_destroy_device_hdl(ctx_hdl);
@@ -221,6 +223,27 @@
return rc;
}
+int cam_context_dump_pf_info(struct cam_context *ctx, unsigned long iova,
+ uint32_t buf_info)
+{
+ int rc = 0;
+
+ if (!ctx->state_machine) {
+ CAM_ERR(CAM_CORE, "Context is not ready");
+ return -EINVAL;
+ }
+
+ if (ctx->state_machine[ctx->state].pagefault_ops) {
+ rc = ctx->state_machine[ctx->state].pagefault_ops(ctx, iova,
+ buf_info);
+ } else {
+ CAM_WARN(CAM_CORE, "No dump ctx in dev %d, state %d",
+ ctx->dev_hdl, ctx->state);
+ }
+
+ return rc;
+}
+
int cam_context_handle_acquire_dev(struct cam_context *ctx,
struct cam_acquire_dev_cmd *cmd)
{
diff --git a/drivers/media/platform/msm/camera/cam_core/cam_context.h b/drivers/media/platform/msm/camera/cam_core/cam_context.h
index ffceea2..420f9f6 100644
--- a/drivers/media/platform/msm/camera/cam_core/cam_context.h
+++ b/drivers/media/platform/msm/camera/cam_core/cam_context.h
@@ -57,23 +57,25 @@
* @num_out_acked: Number of out fence acked
* @flushed: Request is flushed
* @ctx: The context to which this request belongs
+ * @pf_data page fault debug data
*
*/
struct cam_ctx_request {
- struct list_head list;
- uint32_t status;
- uint64_t request_id;
+ struct list_head list;
+ uint32_t status;
+ uint64_t request_id;
void *req_priv;
- struct cam_hw_update_entry hw_update_entries[CAM_CTX_CFG_MAX];
- uint32_t num_hw_update_entries;
- struct cam_hw_fence_map_entry in_map_entries[CAM_CTX_CFG_MAX];
- uint32_t num_in_map_entries;
- struct cam_hw_fence_map_entry out_map_entries[CAM_CTX_CFG_MAX];
- uint32_t num_out_map_entries;
- atomic_t num_in_acked;
- uint32_t num_out_acked;
- int flushed;
- struct cam_context *ctx;
+ struct cam_hw_update_entry hw_update_entries[CAM_CTX_CFG_MAX];
+ uint32_t num_hw_update_entries;
+ struct cam_hw_fence_map_entry in_map_entries[CAM_CTX_CFG_MAX];
+ uint32_t num_in_map_entries;
+ struct cam_hw_fence_map_entry out_map_entries[CAM_CTX_CFG_MAX];
+ uint32_t num_out_map_entries;
+ atomic_t num_in_acked;
+ uint32_t num_out_acked;
+ int flushed;
+ struct cam_context *ctx;
+ struct cam_hw_mgr_dump_pf_data pf_data;
};
/**
@@ -135,12 +137,14 @@
* @ioctl_ops: Ioctl funciton table
* @crm_ops: CRM to context interface function table
* @irq_ops: Hardware event handle function
+ * @pagefault_ops: Function to be called on page fault
*
*/
struct cam_ctx_ops {
struct cam_ctx_ioctl_ops ioctl_ops;
struct cam_ctx_crm_ops crm_ops;
cam_hw_event_cb_func irq_ops;
+ cam_hw_pagefault_cb_func pagefault_ops;
};
/**
@@ -292,6 +296,19 @@
struct cam_req_mgr_link_evt_data *process_evt);
/**
+ * cam_context_dump_pf_info()
+ *
+ * @brief: Handle dump active request request command
+ *
+ * @ctx: Object pointer for cam_context
+ * @iova: Page fault address
+ * @buf_info: Information about closest memory handle
+ *
+ */
+int cam_context_dump_pf_info(struct cam_context *ctx, unsigned long iova,
+ uint32_t buf_info);
+
+/**
* cam_context_handle_acquire_dev()
*
* @brief: Handle acquire device command
diff --git a/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c b/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c
index 6c2383e..d78203a 100644
--- a/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c
+++ b/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c
@@ -337,6 +337,7 @@
cfg.out_map_entries = req->out_map_entries;
cfg.max_in_map_entries = CAM_CTX_CFG_MAX;
cfg.in_map_entries = req->in_map_entries;
+ cfg.pf_data = &(req->pf_data);
rc = ctx->hw_mgr_intf->hw_prepare_update(
ctx->hw_mgr_intf->hw_mgr_priv, &cfg);
@@ -905,3 +906,38 @@
end:
return rc;
}
+
+int32_t cam_context_dump_pf_info_to_hw(struct cam_context *ctx,
+ struct cam_packet *packet, unsigned long iova, uint32_t buf_info,
+ bool *mem_found)
+{
+ int rc = 0;
+ struct cam_hw_cmd_args cmd_args;
+
+ if (!ctx) {
+ CAM_ERR(CAM_CTXT, "Invalid input params %pK ", ctx);
+ rc = -EINVAL;
+ goto end;
+ }
+
+ if (!ctx->hw_mgr_intf) {
+ CAM_ERR(CAM_CTXT, "[%s][%d] HW interface is not ready",
+ ctx->dev_name, ctx->ctx_id);
+ rc = -EFAULT;
+ goto end;
+ }
+
+ if (ctx->hw_mgr_intf->hw_cmd) {
+ cmd_args.ctxt_to_hw_map = ctx->ctxt_to_hw_map;
+ cmd_args.cmd_type = CAM_HW_MGR_CMD_DUMP_PF_INFO;
+ cmd_args.u.pf_args.pf_data.packet = packet;
+ cmd_args.u.pf_args.iova = iova;
+ cmd_args.u.pf_args.buf_info = buf_info;
+ cmd_args.u.pf_args.mem_found = mem_found;
+ ctx->hw_mgr_intf->hw_cmd(ctx->hw_mgr_intf->hw_mgr_priv,
+ &cmd_args);
+ }
+
+end:
+ return rc;
+}
diff --git a/drivers/media/platform/msm/camera/cam_core/cam_context_utils.h b/drivers/media/platform/msm/camera/cam_core/cam_context_utils.h
index 9b95ead..43e6940 100644
--- a/drivers/media/platform/msm/camera/cam_core/cam_context_utils.h
+++ b/drivers/media/platform/msm/camera/cam_core/cam_context_utils.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -31,5 +31,8 @@
int32_t cam_context_flush_ctx_to_hw(struct cam_context *ctx);
int32_t cam_context_flush_req_to_hw(struct cam_context *ctx,
struct cam_flush_dev_cmd *cmd);
+int32_t cam_context_dump_pf_info_to_hw(struct cam_context *ctx,
+ struct cam_packet *packet, unsigned long iova, uint32_t buf_info,
+ bool *mem_found);
#endif /* _CAM_CONTEXT_UTILS_H_ */
diff --git a/drivers/media/platform/msm/camera/cam_core/cam_hw_mgr_intf.h b/drivers/media/platform/msm/camera/cam_core/cam_hw_mgr_intf.h
index f7990b6..ecd00b69 100644
--- a/drivers/media/platform/msm/camera/cam_core/cam_hw_mgr_intf.h
+++ b/drivers/media/platform/msm/camera/cam_core/cam_hw_mgr_intf.h
@@ -29,6 +29,10 @@
typedef int (*cam_hw_event_cb_func)(void *context, uint32_t evt_id,
void *evt_data);
+/* hardware page fault callback function type */
+typedef int (*cam_hw_pagefault_cb_func)(void *context, unsigned long iova,
+ uint32_t buf_info);
+
/**
* struct cam_hw_update_entry - Entry for hardware config
*
@@ -131,6 +135,16 @@
void *args;
};
+
+/**
+ * struct cam_hw_mgr_dump_pf_data - page fault debug data
+ *
+ * packet: pointer to packet
+ */
+struct cam_hw_mgr_dump_pf_data {
+ void *packet;
+};
+
/**
* struct cam_hw_prepare_update_args - Payload for prepare command
*
@@ -146,6 +160,7 @@
* @in_map_entries: Actual input fence mapping list (returned)
* @num_in_map_entries: Number of acutal input fence mapping (returned)
* @priv: Private pointer of hw update
+ * @pf_data: Debug data for page fault
*
*/
struct cam_hw_prepare_update_args {
@@ -161,6 +176,7 @@
struct cam_hw_fence_map_entry *in_map_entries;
uint32_t num_in_map_entries;
void *priv;
+ struct cam_hw_mgr_dump_pf_data *pf_data;
};
/**
@@ -207,6 +223,48 @@
};
/**
+ * struct cam_hw_dump_pf_args - Payload for dump pf info command
+ *
+ * @pf_data: Debug data for page fault
+ * @iova: Page fault address
+ * @buf_info: Info about memory buffer where page
+ * fault occurred
+ * @mem_found: If fault memory found in current
+ * request
+ *
+ */
+struct cam_hw_dump_pf_args {
+ struct cam_hw_mgr_dump_pf_data pf_data;
+ unsigned long iova;
+ uint32_t buf_info;
+ bool *mem_found;
+};
+
+/* enum cam_hw_mgr_command - Hardware manager command type */
+enum cam_hw_mgr_command {
+ CAM_HW_MGR_CMD_INTERNAL,
+ CAM_HW_MGR_CMD_DUMP_PF_INFO,
+};
+
+/**
+ * struct cam_hw_cmd_args - Payload for hw manager command
+ *
+ * @ctxt_to_hw_map: HW context from the acquire
+ * @cmd_type HW command type
+ * @internal_args Arguments for internal command
+ * @pf_args Arguments for Dump PF info command
+ *
+ */
+struct cam_hw_cmd_args {
+ void *ctxt_to_hw_map;
+ uint32_t cmd_type;
+ union {
+ void *internal_args;
+ struct cam_hw_dump_pf_args pf_args;
+ } u;
+};
+
+/**
* cam_hw_mgr_intf - HW manager interface
*
* @hw_mgr_priv: HW manager object
diff --git a/drivers/media/platform/msm/camera/cam_core/cam_node.c b/drivers/media/platform/msm/camera/cam_core/cam_node.c
index 3f24c6d..1a33722 100644
--- a/drivers/media/platform/msm/camera/cam_core/cam_node.c
+++ b/drivers/media/platform/msm/camera/cam_core/cam_node.c
@@ -286,20 +286,30 @@
return -EINVAL;
}
- rc = cam_context_handle_release_dev(ctx, release);
- if (rc)
- CAM_ERR(CAM_CORE, "context release failed node %s", node->name);
+ if (ctx->state > CAM_CTX_UNINIT && ctx->state < CAM_CTX_STATE_MAX) {
+ rc = cam_context_handle_release_dev(ctx, release);
+ if (rc)
+ CAM_ERR(CAM_CORE, "context release failed for node %s",
+ node->name);
+ } else {
+ CAM_WARN(CAM_CORE,
+ "node %s context id %u state %d invalid to release hdl",
+ node->name, ctx->ctx_id, ctx->state);
+ goto destroy_dev_hdl;
+ }
+ cam_context_putref(ctx);
+
+destroy_dev_hdl:
rc = cam_destroy_device_hdl(release->dev_handle);
if (rc)
- CAM_ERR(CAM_CORE, "destroy device handle is failed node %s",
+ CAM_ERR(CAM_CORE, "destroy device hdl failed for node %s",
node->name);
CAM_DBG(CAM_CORE, "[%s] Release ctx_id=%d, refcount=%d",
node->name, ctx->ctx_id,
atomic_read(&(ctx->refcount.refcount)));
- cam_context_putref(ctx);
return rc;
}
@@ -420,6 +430,9 @@
for (i = 0; i < node->ctx_size; i++) {
if (node->ctx_list[i].dev_hdl > 0) {
+ CAM_DBG(CAM_CORE,
+ "Node [%s] invoking shutdown on context [%d]",
+ node->name, i);
rc = cam_context_shutdown(&(node->ctx_list[i]));
if (rc)
continue;
diff --git a/drivers/media/platform/msm/camera/cam_icp/cam_icp_context.c b/drivers/media/platform/msm/camera/cam_icp/cam_icp_context.c
index 502c95d..522a602 100644
--- a/drivers/media/platform/msm/camera/cam_icp/cam_icp_context.c
+++ b/drivers/media/platform/msm/camera/cam_icp/cam_icp_context.c
@@ -25,9 +25,46 @@
#include "cam_mem_mgr.h"
#include "cam_trace.h"
#include "cam_debug_util.h"
+#include "cam_packet_util.h"
static const char icp_dev_name[] = "icp";
+static int cam_icp_context_dump_active_request(void *data, unsigned long iova,
+ uint32_t buf_info)
+{
+ struct cam_context *ctx = (struct cam_context *)data;
+ struct cam_ctx_request *req = NULL;
+ struct cam_ctx_request *req_temp = NULL;
+ struct cam_hw_mgr_dump_pf_data *pf_dbg_entry = NULL;
+ int rc = 0;
+ bool b_mem_found = false;
+
+ if (!ctx) {
+ CAM_ERR(CAM_ICP, "Invalid ctx");
+ return -EINVAL;
+ }
+
+ CAM_INFO(CAM_ICP, "iommu fault for icp ctx %d state %d",
+ ctx->ctx_id, ctx->state);
+
+ list_for_each_entry_safe(req, req_temp,
+ &ctx->active_req_list, list) {
+ pf_dbg_entry = &(req->pf_data);
+ CAM_INFO(CAM_ICP, "req_id : %lld", req->request_id);
+
+ rc = cam_context_dump_pf_info_to_hw(ctx, pf_dbg_entry->packet,
+ iova, buf_info, &b_mem_found);
+ if (rc)
+ CAM_ERR(CAM_ICP, "Failed to dump pf info");
+
+ if (b_mem_found)
+ CAM_ERR(CAM_ICP, "Found page fault in req %lld %d",
+ req->request_id, rc);
+ }
+
+ return rc;
+}
+
static int __cam_icp_acquire_dev_in_available(struct cam_context *ctx,
struct cam_acquire_dev_cmd *cmd)
{
@@ -156,6 +193,7 @@
},
.crm_ops = {},
.irq_ops = __cam_icp_handle_buf_done_in_ready,
+ .pagefault_ops = cam_icp_context_dump_active_request,
},
/* Ready */
{
@@ -167,12 +205,14 @@
},
.crm_ops = {},
.irq_ops = __cam_icp_handle_buf_done_in_ready,
+ .pagefault_ops = cam_icp_context_dump_active_request,
},
/* Activated */
{
.ioctl_ops = {},
.crm_ops = {},
.irq_ops = NULL,
+ .pagefault_ops = cam_icp_context_dump_active_request,
},
};
diff --git a/drivers/media/platform/msm/camera/cam_icp/cam_icp_subdev.c b/drivers/media/platform/msm/camera/cam_icp/cam_icp_subdev.c
index 7df806b..2ea7738 100644
--- a/drivers/media/platform/msm/camera/cam_icp/cam_icp_subdev.c
+++ b/drivers/media/platform/msm/camera/cam_icp/cam_icp_subdev.c
@@ -35,6 +35,7 @@
#include "cam_hw_mgr_intf.h"
#include "cam_icp_hw_mgr_intf.h"
#include "cam_debug_util.h"
+#include "cam_smmu_api.h"
#define CAM_ICP_DEV_NAME "cam-icp"
@@ -55,6 +56,25 @@
{}
};
+static void cam_icp_dev_iommu_fault_handler(
+ struct iommu_domain *domain, struct device *dev, unsigned long iova,
+ int flags, void *token, uint32_t buf_info)
+{
+ int i = 0;
+ struct cam_node *node = NULL;
+
+ if (!token) {
+ CAM_ERR(CAM_ICP, "invalid token in page handler cb");
+ return;
+ }
+
+ node = (struct cam_node *)token;
+
+ for (i = 0; i < node->ctx_size; i++)
+ cam_context_dump_pf_info(&(node->ctx_list[i]), iova,
+ buf_info);
+}
+
static int cam_icp_subdev_open(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
@@ -96,7 +116,7 @@
mutex_lock(&g_icp_dev.icp_lock);
if (g_icp_dev.open_cnt <= 0) {
- CAM_ERR(CAM_ICP, "ICP subdev is already closed");
+ CAM_DBG(CAM_ICP, "ICP subdev is already closed");
rc = -EINVAL;
goto end;
}
@@ -135,6 +155,7 @@
int rc = 0, i = 0;
struct cam_node *node;
struct cam_hw_mgr_intf *hw_mgr_intf;
+ int iommu_hdl = -1;
if (!pdev) {
CAM_ERR(CAM_ICP, "pdev is NULL");
@@ -158,7 +179,8 @@
goto hw_alloc_fail;
}
- rc = cam_icp_hw_mgr_init(pdev->dev.of_node, (uint64_t *)hw_mgr_intf);
+ rc = cam_icp_hw_mgr_init(pdev->dev.of_node, (uint64_t *)hw_mgr_intf,
+ &iommu_hdl);
if (rc) {
CAM_ERR(CAM_ICP, "ICP HW manager init failed: %d", rc);
goto hw_init_fail;
@@ -181,6 +203,9 @@
goto ctx_fail;
}
+ cam_smmu_set_client_page_fault_handler(iommu_hdl,
+ cam_icp_dev_iommu_fault_handler, node);
+
g_icp_dev.open_cnt = 0;
mutex_init(&g_icp_dev.icp_lock);
diff --git a/drivers/media/platform/msm/camera/cam_icp/hfi.c b/drivers/media/platform/msm/camera/cam_icp/hfi.c
index 14a3e65..cbe6886 100644
--- a/drivers/media/platform/msm/camera/cam_icp/hfi.c
+++ b/drivers/media/platform/msm/camera/cam_icp/hfi.c
@@ -42,6 +42,9 @@
#define HFI_MAX_POLL_TRY 5
+#define HFI_MAX_PC_POLL_TRY 50
+#define HFI_POLL_TRY_SLEEP 20
+
static struct hfi_info *g_hfi;
unsigned int g_icp_mmu_hdl;
static DEFINE_MUTEX(hfi_cmd_q_mutex);
@@ -513,8 +516,8 @@
uint32_t val;
uint32_t try = 0;
- while (try < HFI_MAX_POLL_TRY) {
- data = cam_io_r(icp_base + HFI_REG_A5_CSR_A5_STATUS);
+ while (try < HFI_MAX_PC_POLL_TRY) {
+ data = cam_io_r_mb(icp_base + HFI_REG_A5_CSR_A5_STATUS);
CAM_DBG(CAM_HFI, "wfi status = %x\n", (int)data);
if (data & ICP_CSR_A5_STATUS_WFI)
@@ -523,7 +526,7 @@
* and Host can the proceed. No interrupt is expected from FW
* at this time.
*/
- msleep(100);
+ msleep_interruptible(HFI_POLL_TRY_SLEEP);
try++;
}
@@ -533,6 +536,11 @@
val = cam_io_r(icp_base + HFI_REG_A5_CSR_NSEC_RESET);
cam_io_w_mb(val, icp_base + HFI_REG_A5_CSR_NSEC_RESET);
+
+ cam_io_w_mb((uint32_t)ICP_INIT_REQUEST_RESET,
+ icp_base + HFI_REG_HOST_ICP_INIT_REQUEST);
+ cam_io_w_mb((uint32_t)INTR_DISABLE,
+ g_hfi->csr_base + HFI_REG_A5_CSR_A2HOSTINTEN);
}
void cam_hfi_enable_cpu(void __iomem *icp_base)
@@ -883,11 +891,6 @@
g_hfi->cmd_q_state = false;
g_hfi->msg_q_state = false;
- cam_io_w_mb((uint32_t)ICP_INIT_REQUEST_RESET,
- icp_base + HFI_REG_HOST_ICP_INIT_REQUEST);
-
- cam_io_w_mb((uint32_t)INTR_DISABLE,
- g_hfi->csr_base + HFI_REG_A5_CSR_A2HOSTINTEN);
kzfree(g_hfi);
g_hfi = NULL;
diff --git a/drivers/media/platform/msm/camera/cam_icp/icp_hw/bps_hw/bps_core.c b/drivers/media/platform/msm/camera/cam_icp/icp_hw/bps_hw/bps_core.c
index d016374..b969c92 100644
--- a/drivers/media/platform/msm/camera/cam_icp/icp_hw/bps_hw/bps_core.c
+++ b/drivers/media/platform/msm/camera/cam_icp/icp_hw/bps_hw/bps_core.c
@@ -199,8 +199,10 @@
cam_cpas_reg_read(core_info->cpas_handle,
CAM_CPAS_REG_CPASTOP, hw_info->pwr_ctrl, true, &pwr_ctrl);
if (pwr_ctrl & BPS_COLLAPSE_MASK) {
- CAM_ERR(CAM_ICP, "BPS: pwr_ctrl(%x)", pwr_ctrl);
- return -EINVAL;
+ CAM_DBG(CAM_ICP, "BPS: pwr_ctrl set(%x)", pwr_ctrl);
+ cam_cpas_reg_write(core_info->cpas_handle,
+ CAM_CPAS_REG_CPASTOP,
+ hw_info->pwr_ctrl, true, 0);
}
rc = cam_bps_transfer_gdsc_control(soc_info);
diff --git a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
index 1d5e483..c33c6a5 100644
--- a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
@@ -3388,10 +3388,11 @@
prepare_args->num_out_map_entries++;
}
CAM_DBG(CAM_REQ,
- "ctx_id: %u req_id: %llu dir[%d]: %u, fence: %u resource_type = %u",
+ "ctx_id: %u req_id: %llu dir[%d]: %u, fence: %u resource_type = %u memh %x",
ctx_data->ctx_id, packet->header.request_id, i,
io_cfg_ptr[i].direction, io_cfg_ptr[i].fence,
- io_cfg_ptr[i].resource_type);
+ io_cfg_ptr[i].resource_type,
+ io_cfg_ptr[i].mem_handle[0]);
}
if (prepare_args->num_in_map_entries > 1)
@@ -3593,6 +3594,77 @@
return rc;
}
+static void cam_icp_mgr_print_io_bufs(struct cam_packet *packet,
+ int32_t iommu_hdl, int32_t sec_mmu_hdl, uint32_t pf_buf_info,
+ bool *mem_found)
+{
+ uint64_t iova_addr;
+ size_t src_buf_size;
+ int i;
+ int j;
+ int rc = 0;
+ int32_t mmu_hdl;
+
+ struct cam_buf_io_cfg *io_cfg = NULL;
+
+ if (mem_found)
+ *mem_found = false;
+
+ io_cfg = (struct cam_buf_io_cfg *)((uint32_t *)&packet->payload +
+ packet->io_configs_offset / 4);
+
+ for (i = 0; i < packet->num_io_configs; i++) {
+ for (j = 0; j < CAM_PACKET_MAX_PLANES; j++) {
+ if (!io_cfg[i].mem_handle[j])
+ break;
+
+ if (GET_FD_FROM_HANDLE(io_cfg[i].mem_handle[j]) ==
+ GET_FD_FROM_HANDLE(pf_buf_info)) {
+ CAM_INFO(CAM_ICP,
+ "Found PF at port: %d mem %x fd: %x",
+ io_cfg[i].resource_type,
+ io_cfg[i].mem_handle[j],
+ pf_buf_info);
+ if (mem_found)
+ *mem_found = true;
+ }
+
+ CAM_INFO(CAM_ICP, "port: %d f: %u format: %d dir %d",
+ io_cfg[i].resource_type,
+ io_cfg[i].fence,
+ io_cfg[i].format,
+ io_cfg[i].direction);
+
+ mmu_hdl = cam_mem_is_secure_buf(
+ io_cfg[i].mem_handle[j]) ? sec_mmu_hdl :
+ iommu_hdl;
+ rc = cam_mem_get_io_buf(io_cfg[i].mem_handle[j],
+ mmu_hdl, &iova_addr, &src_buf_size);
+ if (rc < 0) {
+ CAM_ERR(CAM_UTIL, "get src buf address fail");
+ continue;
+ }
+ if (iova_addr >> 32) {
+ CAM_ERR(CAM_ICP, "Invalid mapped address");
+ rc = -EINVAL;
+ continue;
+ }
+
+ CAM_INFO(CAM_ICP,
+ "pln %d w %d h %d size %d addr 0x%x offset 0x%x memh %x",
+ j, io_cfg[i].planes[j].width,
+ io_cfg[i].planes[j].height,
+ (int32_t)src_buf_size,
+ (unsigned int)iova_addr,
+ io_cfg[i].offsets[j],
+ io_cfg[i].mem_handle[j]);
+
+ iova_addr += io_cfg[i].offsets[j];
+
+ }
+ }
+}
+
static int cam_icp_mgr_prepare_hw_update(void *hw_mgr_priv,
void *prepare_hw_update_args)
{
@@ -3635,6 +3707,8 @@
return rc;
}
+ prepare_args->pf_data->packet = packet;
+
CAM_DBG(CAM_REQ, "req id = %lld for ctx = %u",
packet->header.request_id, ctx_data->ctx_id);
/* Update Buffer Address from handles and patch information */
@@ -4551,7 +4625,35 @@
return rc;
}
-int cam_icp_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl)
+static int cam_icp_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
+{
+ int rc = 0;
+ struct cam_hw_cmd_args *hw_cmd_args = cmd_args;
+ struct cam_icp_hw_mgr *hw_mgr = hw_mgr_priv;
+
+ if (!hw_mgr_priv || !cmd_args) {
+ CAM_ERR(CAM_ICP, "Invalid arguments");
+ return -EINVAL;
+ }
+
+ switch (hw_cmd_args->cmd_type) {
+ case CAM_HW_MGR_CMD_DUMP_PF_INFO:
+ cam_icp_mgr_print_io_bufs(
+ hw_cmd_args->u.pf_args.pf_data.packet,
+ hw_mgr->iommu_hdl,
+ hw_mgr->iommu_sec_hdl,
+ hw_cmd_args->u.pf_args.buf_info,
+ hw_cmd_args->u.pf_args.mem_found);
+ break;
+ default:
+ CAM_ERR(CAM_ICP, "Invalid cmd");
+ }
+
+ return rc;
+}
+
+int cam_icp_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
+ int *iommu_hdl)
{
int i, rc = 0;
struct cam_hw_mgr_intf *hw_mgr_intf;
@@ -4574,6 +4676,7 @@
hw_mgr_intf->hw_open = cam_icp_mgr_hw_open_u;
hw_mgr_intf->hw_close = cam_icp_mgr_hw_close_u;
hw_mgr_intf->hw_flush = cam_icp_mgr_hw_flush;
+ hw_mgr_intf->hw_cmd = cam_icp_mgr_cmd;
icp_hw_mgr.secure_mode = CAM_SECURE_MODE_NON_SECURE;
mutex_init(&icp_hw_mgr.hw_mgr_mutex);
@@ -4617,6 +4720,9 @@
if (rc)
goto icp_wq_create_failed;
+ if (iommu_hdl)
+ *iommu_hdl = icp_hw_mgr.iommu_hdl;
+
init_completion(&icp_hw_mgr.a5_complete);
return rc;
diff --git a/drivers/media/platform/msm/camera/cam_icp/icp_hw/include/cam_icp_hw_mgr_intf.h b/drivers/media/platform/msm/camera/cam_icp/icp_hw/include/cam_icp_hw_mgr_intf.h
index 771c4ed..7bb9b9ed 100644
--- a/drivers/media/platform/msm/camera/cam_icp/icp_hw/include/cam_icp_hw_mgr_intf.h
+++ b/drivers/media/platform/msm/camera/cam_icp/icp_hw/include/cam_icp_hw_mgr_intf.h
@@ -28,7 +28,7 @@
#define CPAS_IPE1_BIT 0x2000
int cam_icp_hw_mgr_init(struct device_node *of_node,
- uint64_t *hw_mgr_hdl);
+ uint64_t *hw_mgr_hdl, int *iommu_hdl);
/**
* struct cam_icp_cpas_vote
diff --git a/drivers/media/platform/msm/camera/cam_icp/icp_hw/ipe_hw/ipe_core.c b/drivers/media/platform/msm/camera/cam_icp/icp_hw/ipe_hw/ipe_core.c
index 620a4bd..142fcdc 100644
--- a/drivers/media/platform/msm/camera/cam_icp/icp_hw/ipe_hw/ipe_core.c
+++ b/drivers/media/platform/msm/camera/cam_icp/icp_hw/ipe_hw/ipe_core.c
@@ -195,9 +195,12 @@
CAM_CPAS_REG_CPASTOP, hw_info->pwr_ctrl,
true, &pwr_ctrl);
if (pwr_ctrl & IPE_COLLAPSE_MASK) {
- CAM_ERR(CAM_ICP, "IPE: resume failed : %d", pwr_ctrl);
- return -EINVAL;
+ CAM_DBG(CAM_ICP, "IPE pwr_ctrl set(%x)", pwr_ctrl);
+ cam_cpas_reg_write(core_info->cpas_handle,
+ CAM_CPAS_REG_CPASTOP,
+ hw_info->pwr_ctrl, true, 0);
}
+
rc = cam_ipe_transfer_gdsc_control(soc_info);
cam_cpas_reg_read(core_info->cpas_handle,
CAM_CPAS_REG_CPASTOP, hw_info->pwr_ctrl, true, &pwr_ctrl);
diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c
index 5760371..1aaa5c3 100644
--- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c
+++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c
@@ -23,8 +23,14 @@
#include "cam_req_mgr_dev.h"
#include "cam_trace.h"
#include "cam_debug_util.h"
+#include "cam_packet_util.h"
+#include "cam_context_utils.h"
static const char isp_dev_name[] = "isp";
+
+static int cam_isp_context_dump_active_request(void *data, unsigned long iova,
+ uint32_t buf_info);
+
static void __cam_isp_ctx_update_state_monitor_array(
struct cam_isp_context *ctx_isp,
enum cam_isp_state_change_trigger trigger_type,
@@ -375,7 +381,7 @@
continue;
}
- if (!bubble_state) {
+ if (!req_isp->bubble_detected) {
CAM_DBG(CAM_ISP,
"Sync with success: req %lld res 0x%x fd 0x%x",
req->request_id,
@@ -402,15 +408,14 @@
} else {
/*
* Ignore the buffer done if bubble detect is on
- * In most case, active list should be empty when
- * bubble detects. But for safety, we just move the
- * current active request to the pending list here.
+ * Increment the ack number here, and queue the
+ * request back to pending list whenever all the
+ * buffers are done.
*/
+ req_isp->num_acked++;
CAM_DBG(CAM_ISP,
"buf done with bubble state %d recovery %d",
bubble_state, req_isp->bubble_report);
- list_del_init(&req->list);
- list_add(&req->list, &ctx->pending_req_list);
continue;
}
@@ -431,10 +436,25 @@
req_isp->num_fence_map_out);
WARN_ON(req_isp->num_acked > req_isp->num_fence_map_out);
}
- if (req_isp->num_acked == req_isp->num_fence_map_out) {
+
+ if (req_isp->num_acked != req_isp->num_fence_map_out)
+ return rc;
+
+ ctx_isp->active_req_cnt--;
+
+ if (req_isp->bubble_detected && req_isp->bubble_report) {
+ req_isp->num_acked = 0;
+ req_isp->bubble_detected = false;
+ list_del_init(&req->list);
+ list_add(&req->list, &ctx->pending_req_list);
+
+ CAM_DBG(CAM_REQ,
+ "Move active request %lld to pending list(cnt = %d) [bubble recovery]",
+ req->request_id, ctx_isp->active_req_cnt);
+ } else {
list_del_init(&req->list);
list_add_tail(&req->list, &ctx->free_req_list);
- ctx_isp->active_req_cnt--;
+
CAM_DBG(CAM_REQ,
"Move active request %lld to free list(cnt = %d) [all fences done]",
req->request_id, ctx_isp->active_req_cnt);
@@ -732,15 +752,13 @@
req = list_first_entry(&ctx->wait_req_list, struct cam_ctx_request,
list);
req_isp = (struct cam_isp_ctx_req *)req->req_priv;
+ req_isp->bubble_detected = true;
CAM_DBG(CAM_ISP, "Report Bubble flag %d", req_isp->bubble_report);
if (req_isp->bubble_report && ctx->ctx_crm_intf &&
ctx->ctx_crm_intf->notify_err) {
struct cam_req_mgr_error_notify notify;
- list_del_init(&req->list);
- list_add(&req->list, &ctx->pending_req_list);
-
notify.link_hdl = ctx->link_hdl;
notify.dev_hdl = ctx->dev_hdl;
notify.req_id = req->request_id;
@@ -749,18 +767,19 @@
CAM_DBG(CAM_ISP, "Notify CRM about Bubble frame %lld",
ctx_isp->frame_id);
} else {
- /*
- * Since can not bubble report, always move the request to
- * active list.
- */
- list_del_init(&req->list);
- list_add_tail(&req->list, &ctx->active_req_list);
- ctx_isp->active_req_cnt++;
- CAM_DBG(CAM_REQ, "move request %lld to active list(cnt = %d)",
- req->request_id, ctx_isp->active_req_cnt);
req_isp->bubble_report = 0;
}
+ /*
+ * Always move the request to active list. Let buf done
+ * function handles the rest.
+ */
+ CAM_DBG(CAM_REQ, "move request %lld to active list(cnt = %d)",
+ req->request_id, ctx_isp->active_req_cnt);
+ ctx_isp->active_req_cnt++;
+ list_del_init(&req->list);
+ list_add_tail(&req->list, &ctx->active_req_list);
+
if (req->request_id > ctx_isp->reported_req_id) {
request_id = req->request_id;
ctx_isp->reported_req_id = request_id;
@@ -882,13 +901,12 @@
req = list_first_entry(&ctx->wait_req_list, struct cam_ctx_request,
list);
req_isp = (struct cam_isp_ctx_req *)req->req_priv;
- list_del_init(&req->list);
+ req_isp->bubble_detected = true;
if (req_isp->bubble_report && ctx->ctx_crm_intf &&
ctx->ctx_crm_intf->notify_err) {
struct cam_req_mgr_error_notify notify;
- list_add(&req->list, &ctx->pending_req_list);
notify.link_hdl = ctx->link_hdl;
notify.dev_hdl = ctx->dev_hdl;
notify.req_id = req->request_id;
@@ -898,17 +916,19 @@
"Notify CRM about Bubble req_id %llu frame %lld",
req->request_id, ctx_isp->frame_id);
} else {
- /*
- * If we can not report bubble, then treat it as if no bubble
- * report. Just move the req to active list.
- */
- list_add_tail(&req->list, &ctx->active_req_list);
- ctx_isp->active_req_cnt++;
- CAM_DBG(CAM_ISP, "move request %lld to active list(cnt = %d)",
- req->request_id, ctx_isp->active_req_cnt);
req_isp->bubble_report = 0;
}
+ /*
+ * Always move the request to active list. Let buf done
+ * function handles the rest.
+ */
+ CAM_DBG(CAM_ISP, "move request %lld to active list(cnt = %d)",
+ req->request_id, ctx_isp->active_req_cnt);
+ ctx_isp->active_req_cnt++;
+ list_del_init(&req->list);
+ list_add_tail(&req->list, &ctx->active_req_list);
+
if (!req_isp->bubble_report) {
if (req->request_id > ctx_isp->reported_req_id) {
request_id = req->request_id;
@@ -1411,6 +1431,7 @@
CAM_DBG(CAM_ISP, "try to flush active list");
rc = __cam_isp_ctx_flush_req(ctx, &ctx->active_req_list,
flush_req);
+ ctx_isp->active_req_cnt = 0;
spin_unlock_bh(&ctx->lock);
/* Start hw */
@@ -1609,12 +1630,12 @@
CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx",
ctx_isp->frame_id, ctx_isp->sof_timestamp_val);
- if (list_empty(&ctx->pending_req_list)) {
+ if (list_empty(&ctx->wait_req_list)) {
/*
* If no pending req in epoch, this is an error case.
* The recovery is to go back to sof state
*/
- CAM_ERR(CAM_ISP, "No pending request");
+ CAM_ERR(CAM_ISP, "No wait request");
ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
/* Send SOF event as empty frame*/
@@ -1624,9 +1645,10 @@
goto end;
}
- req = list_first_entry(&ctx->pending_req_list, struct cam_ctx_request,
+ req = list_first_entry(&ctx->wait_req_list, struct cam_ctx_request,
list);
req_isp = (struct cam_isp_ctx_req *)req->req_priv;
+ req_isp->bubble_detected = true;
CAM_DBG(CAM_ISP, "Report Bubble flag %d", req_isp->bubble_report);
if (req_isp->bubble_report && ctx->ctx_crm_intf &&
@@ -1641,18 +1663,19 @@
CAM_DBG(CAM_ISP, "Notify CRM about Bubble frame %lld",
ctx_isp->frame_id);
} else {
- /*
- * Since can not bubble report, always move the request to
- * active list.
- */
- list_del_init(&req->list);
- list_add_tail(&req->list, &ctx->active_req_list);
- ctx_isp->active_req_cnt++;
- CAM_DBG(CAM_ISP, "move request %lld to active list(cnt = %d)",
- req->request_id, ctx_isp->active_req_cnt);
req_isp->bubble_report = 0;
}
+ /*
+ * Always move the request to active list. Let buf done
+ * function handles the rest.
+ */
+ ctx_isp->active_req_cnt++;
+ list_del_init(&req->list);
+ list_add_tail(&req->list, &ctx->active_req_list);
+ CAM_DBG(CAM_ISP, "move request %lld to active list(cnt = %d)",
+ req->request_id, ctx_isp->active_req_cnt);
+
if (!req_isp->bubble_report) {
if (req->request_id > ctx_isp->reported_req_id) {
request_id = req->request_id;
@@ -2066,6 +2089,7 @@
cfg.out_map_entries = req_isp->fence_map_out;
cfg.in_map_entries = req_isp->fence_map_in;
cfg.priv = &req_isp->hw_update_data;
+ cfg.pf_data = &(req->pf_data);
CAM_DBG(CAM_ISP, "try to prepare config packet......");
@@ -2080,6 +2104,7 @@
req_isp->num_fence_map_out = cfg.num_out_map_entries;
req_isp->num_fence_map_in = cfg.num_in_map_entries;
req_isp->num_acked = 0;
+ req_isp->bubble_detected = false;
for (i = 0; i < req_isp->num_fence_map_out; i++) {
rc = cam_sync_get_obj_ref(req_isp->fence_map_out[i].sync_id);
@@ -2164,7 +2189,8 @@
struct cam_hw_release_args release;
struct cam_isp_context *ctx_isp =
(struct cam_isp_context *) ctx->ctx_priv;
- struct cam_isp_hw_cmd_args hw_cmd_args;
+ struct cam_hw_cmd_args hw_cmd_args;
+ struct cam_isp_hw_cmd_args isp_hw_cmd_args;
if (!ctx->hw_mgr_intf) {
CAM_ERR(CAM_ISP, "HW interface is not ready");
@@ -2221,7 +2247,9 @@
/* Query the context has rdi only resource */
hw_cmd_args.ctxt_to_hw_map = param.ctxt_to_hw_map;
- hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_CMD_IS_RDI_ONLY_CONTEXT;
+ hw_cmd_args.cmd_type = CAM_HW_MGR_CMD_INTERNAL;
+ isp_hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_CMD_IS_RDI_ONLY_CONTEXT;
+ hw_cmd_args.u.internal_args = (void *)&isp_hw_cmd_args;
rc = ctx->hw_mgr_intf->hw_cmd(ctx->hw_mgr_intf->hw_mgr_priv,
&hw_cmd_args);
if (rc) {
@@ -2229,7 +2257,7 @@
goto free_hw;
}
- if (hw_cmd_args.u.is_rdi_only_context) {
+ if (isp_hw_cmd_args.u.is_rdi_only_context) {
/*
* this context has rdi only resource assign rdi only
* state machine
@@ -2248,8 +2276,9 @@
cam_isp_ctx_activated_state_machine;
}
- ctx_isp->rdi_only_context = hw_cmd_args.u.is_rdi_only_context;
+ ctx_isp->rdi_only_context = isp_hw_cmd_args.u.is_rdi_only_context;
ctx_isp->hw_ctx = param.ctxt_to_hw_map;
+ ctx->ctxt_to_hw_map = param.ctxt_to_hw_map;
req_hdl_param.session_hdl = cmd->session_handle;
/* bridge is not ready for these flags. so false for now */
@@ -2276,7 +2305,7 @@
CAM_DBG(CAM_ISP,
"Acquire success on session_hdl 0x%x num_rsrces %d RDI only %d ctx %u",
cmd->session_handle, cmd->num_resources,
- (hw_cmd_args.u.is_rdi_only_context ? 1 : 0), ctx->ctx_id);
+ (isp_hw_cmd_args.u.is_rdi_only_context ? 1 : 0), ctx->ctx_id);
kfree(isp_res);
return rc;
@@ -2567,12 +2596,15 @@
static int __cam_isp_ctx_link_pause(struct cam_context *ctx)
{
int rc = 0;
- struct cam_isp_hw_cmd_args hw_cmd_args;
+ struct cam_hw_cmd_args hw_cmd_args;
+ struct cam_isp_hw_cmd_args isp_hw_cmd_args;
struct cam_isp_context *ctx_isp =
(struct cam_isp_context *) ctx->ctx_priv;
hw_cmd_args.ctxt_to_hw_map = ctx_isp->hw_ctx;
- hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_CMD_PAUSE_HW;
+ hw_cmd_args.cmd_type = CAM_HW_MGR_CMD_INTERNAL;
+ isp_hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_CMD_PAUSE_HW;
+ hw_cmd_args.u.internal_args = (void *)&isp_hw_cmd_args;
rc = ctx->hw_mgr_intf->hw_cmd(ctx->hw_mgr_intf->hw_mgr_priv,
&hw_cmd_args);
@@ -2582,12 +2614,15 @@
static int __cam_isp_ctx_link_resume(struct cam_context *ctx)
{
int rc = 0;
- struct cam_isp_hw_cmd_args hw_cmd_args;
+ struct cam_hw_cmd_args hw_cmd_args;
+ struct cam_isp_hw_cmd_args isp_hw_cmd_args;
struct cam_isp_context *ctx_isp =
(struct cam_isp_context *) ctx->ctx_priv;
hw_cmd_args.ctxt_to_hw_map = ctx_isp->hw_ctx;
- hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_CMD_RESUME_HW;
+ hw_cmd_args.cmd_type = CAM_HW_MGR_CMD_INTERNAL;
+ isp_hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_CMD_RESUME_HW;
+ hw_cmd_args.u.internal_args = (void *)&isp_hw_cmd_args;
rc = ctx->hw_mgr_intf->hw_cmd(ctx->hw_mgr_intf->hw_mgr_priv,
&hw_cmd_args);
@@ -2598,13 +2633,16 @@
struct cam_context *ctx)
{
int rc = 0;
- struct cam_isp_hw_cmd_args hw_cmd_args;
+ struct cam_hw_cmd_args hw_cmd_args;
+ struct cam_isp_hw_cmd_args isp_hw_cmd_args;
struct cam_isp_context *ctx_isp =
(struct cam_isp_context *) ctx->ctx_priv;
hw_cmd_args.ctxt_to_hw_map = ctx_isp->hw_ctx;
- hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_CMD_SOF_DEBUG;
- hw_cmd_args.u.sof_irq_enable = 1;
+ hw_cmd_args.cmd_type = CAM_HW_MGR_CMD_INTERNAL;
+ isp_hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_CMD_SOF_DEBUG;
+ isp_hw_cmd_args.u.sof_irq_enable = 1;
+ hw_cmd_args.u.internal_args = (void *)&isp_hw_cmd_args;
rc = ctx->hw_mgr_intf->hw_cmd(ctx->hw_mgr_intf->hw_mgr_priv,
&hw_cmd_args);
@@ -2746,6 +2784,7 @@
.flush_req = __cam_isp_ctx_flush_req_in_top_state,
},
.irq_ops = NULL,
+ .pagefault_ops = cam_isp_context_dump_active_request,
},
/* Ready */
{
@@ -2759,6 +2798,7 @@
.flush_req = __cam_isp_ctx_flush_req_in_ready,
},
.irq_ops = NULL,
+ .pagefault_ops = cam_isp_context_dump_active_request,
},
/* Activated */
{
@@ -2774,10 +2814,55 @@
.process_evt = __cam_isp_ctx_process_evt,
},
.irq_ops = __cam_isp_ctx_handle_irq_in_activated,
+ .pagefault_ops = cam_isp_context_dump_active_request,
},
};
+static int cam_isp_context_dump_active_request(void *data, unsigned long iova,
+ uint32_t buf_info)
+{
+
+ struct cam_context *ctx = (struct cam_context *)data;
+ struct cam_ctx_request *req = NULL;
+ struct cam_ctx_request *req_temp = NULL;
+ struct cam_isp_ctx_req *req_isp = NULL;
+ struct cam_isp_prepare_hw_update_data *hw_update_data = NULL;
+ struct cam_hw_mgr_dump_pf_data *pf_dbg_entry = NULL;
+ bool mem_found = false;
+ int rc = 0;
+
+ struct cam_isp_context *isp_ctx =
+ (struct cam_isp_context *)ctx->ctx_priv;
+
+ if (!isp_ctx) {
+ CAM_ERR(CAM_ISP, "Invalid isp ctx");
+ return -EINVAL;
+ }
+
+ CAM_INFO(CAM_ISP, "iommu fault handler for isp ctx %d state %d",
+ ctx->ctx_id, ctx->state);
+
+ list_for_each_entry_safe(req, req_temp,
+ &ctx->active_req_list, list) {
+ req_isp = (struct cam_isp_ctx_req *) req->req_priv;
+ hw_update_data = &req_isp->hw_update_data;
+ pf_dbg_entry = &(req->pf_data);
+ CAM_INFO(CAM_ISP, "req_id : %lld ", req->request_id);
+
+ rc = cam_context_dump_pf_info_to_hw(ctx, pf_dbg_entry->packet,
+ iova, buf_info, &mem_found);
+ if (rc)
+ CAM_ERR(CAM_ISP, "Failed to dump pf info");
+
+ if (mem_found)
+ CAM_ERR(CAM_ISP, "Found page fault in req %lld %d",
+ req->request_id, rc);
+ }
+
+ return rc;
+}
+
int cam_isp_context_init(struct cam_isp_context *ctx,
struct cam_context *ctx_base,
struct cam_req_mgr_kmd_ops *crm_node_intf,
diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h
index 4592e42..6f89841 100644
--- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h
+++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h
@@ -115,6 +115,7 @@
uint32_t num_acked;
int32_t bubble_report;
struct cam_isp_prepare_hw_update_data hw_update_data;
+ bool bubble_detected;
};
/**
diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_dev.c b/drivers/media/platform/msm/camera/cam_isp/cam_isp_dev.c
index a067915..c7e5d38 100644
--- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_dev.c
+++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_dev.c
@@ -26,9 +26,29 @@
#include "cam_isp_hw_mgr_intf.h"
#include "cam_node.h"
#include "cam_debug_util.h"
+#include "cam_smmu_api.h"
static struct cam_isp_dev g_isp_dev;
+static void cam_isp_dev_iommu_fault_handler(
+ struct iommu_domain *domain, struct device *dev, unsigned long iova,
+ int flags, void *token, uint32_t buf_info)
+{
+ int i = 0;
+ struct cam_node *node = NULL;
+
+ if (!token) {
+ CAM_ERR(CAM_ISP, "invalid token in page handler cb");
+ return;
+ }
+
+ node = (struct cam_node *)token;
+
+ for (i = 0; i < node->ctx_size; i++)
+ cam_context_dump_pf_info(&(node->ctx_list[i]), iova,
+ buf_info);
+}
+
static const struct of_device_id cam_isp_dt_match[] = {
{
.compatible = "qcom,cam-isp"
@@ -36,23 +56,47 @@
{}
};
-static int cam_isp_subdev_close(struct v4l2_subdev *sd,
+static int cam_isp_subdev_open(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
- struct cam_node *node = v4l2_get_subdevdata(sd);
-
- if (!node) {
- CAM_ERR(CAM_ISP, "Node ptr is NULL");
- return -EINVAL;
- }
-
- cam_node_shutdown(node);
+ mutex_lock(&g_isp_dev.isp_mutex);
+ g_isp_dev.open_cnt++;
+ mutex_unlock(&g_isp_dev.isp_mutex);
return 0;
}
+static int cam_isp_subdev_close(struct v4l2_subdev *sd,
+ struct v4l2_subdev_fh *fh)
+{
+ int rc = 0;
+ struct cam_node *node = v4l2_get_subdevdata(sd);
+
+ mutex_lock(&g_isp_dev.isp_mutex);
+ if (g_isp_dev.open_cnt <= 0) {
+ CAM_DBG(CAM_ISP, "ISP subdev is already closed");
+ rc = -EINVAL;
+ goto end;
+ }
+
+ g_isp_dev.open_cnt--;
+ if (!node) {
+ CAM_ERR(CAM_ISP, "Node ptr is NULL");
+ rc = -EINVAL;
+ goto end;
+ }
+
+ if (g_isp_dev.open_cnt == 0)
+ cam_node_shutdown(node);
+
+end:
+ mutex_unlock(&g_isp_dev.isp_mutex);
+ return rc;
+}
+
static const struct v4l2_subdev_internal_ops cam_isp_subdev_internal_ops = {
.close = cam_isp_subdev_close,
+ .open = cam_isp_subdev_open,
};
static int cam_isp_dev_remove(struct platform_device *pdev)
@@ -82,6 +126,7 @@
int i;
struct cam_hw_mgr_intf hw_mgr_intf;
struct cam_node *node;
+ int iommu_hdl = -1;
g_isp_dev.sd.internal_ops = &cam_isp_subdev_internal_ops;
/* Initialze the v4l2 subdevice first. (create cam_node) */
@@ -94,7 +139,7 @@
node = (struct cam_node *) g_isp_dev.sd.token;
memset(&hw_mgr_intf, 0, sizeof(hw_mgr_intf));
- rc = cam_isp_hw_mgr_init(pdev->dev.of_node, &hw_mgr_intf);
+ rc = cam_isp_hw_mgr_init(pdev->dev.of_node, &hw_mgr_intf, &iommu_hdl);
if (rc != 0) {
CAM_ERR(CAM_ISP, "Can not initialized ISP HW manager!");
goto unregister;
@@ -119,6 +164,11 @@
goto unregister;
}
+ cam_smmu_set_client_page_fault_handler(iommu_hdl,
+ cam_isp_dev_iommu_fault_handler, node);
+
+ mutex_init(&g_isp_dev.isp_mutex);
+
CAM_INFO(CAM_ISP, "Camera ISP probe complete");
return 0;
diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_dev.h b/drivers/media/platform/msm/camera/cam_isp/cam_isp_dev.h
index 95463ca..a88ed55 100644
--- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_dev.h
+++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_dev.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -24,12 +24,15 @@
* @sd: Commone camera subdevice node
* @ctx: Isp base context storage
* @ctx_isp: Isp private context storage
- *
+ * @isp_mutex: ISP dev mutex
+ * @open_cnt: Open device count
*/
struct cam_isp_dev {
struct cam_subdev sd;
struct cam_context ctx[CAM_CTX_MAX];
struct cam_isp_context ctx_isp[CAM_CTX_MAX];
+ struct mutex isp_mutex;
+ int32_t open_cnt;
};
#endif /* __CAM_ISP_DEV_H__ */
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
index aab323e..4d09a9a 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
@@ -28,6 +28,7 @@
#include "cam_packet_util.h"
#include "cam_debug_util.h"
#include "cam_cpas_api.h"
+#include "cam_mem_mgr_api.h"
#define CAM_IFE_HW_ENTRIES_MAX 20
@@ -762,6 +763,8 @@
if (!ife_src_res->hw_res[j])
continue;
+ hw_intf = ife_src_res->hw_res[j]->hw_intf;
+
if (j == CAM_ISP_HW_SPLIT_LEFT) {
vfe_acquire.vfe_out.split_id =
CAM_ISP_HW_SPLIT_LEFT;
@@ -769,7 +772,7 @@
/*TBD */
vfe_acquire.vfe_out.is_master = 1;
vfe_acquire.vfe_out.dual_slave_core =
- 1;
+ (hw_intf->hw_idx == 0) ? 1 : 0;
} else {
vfe_acquire.vfe_out.is_master = 0;
vfe_acquire.vfe_out.dual_slave_core =
@@ -779,10 +782,10 @@
vfe_acquire.vfe_out.split_id =
CAM_ISP_HW_SPLIT_RIGHT;
vfe_acquire.vfe_out.is_master = 0;
- vfe_acquire.vfe_out.dual_slave_core = 0;
+ vfe_acquire.vfe_out.dual_slave_core =
+ (hw_intf->hw_idx == 0) ? 1 : 0;
}
- hw_intf = ife_src_res->hw_res[j]->hw_intf;
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
&vfe_acquire,
sizeof(struct cam_vfe_acquire_args));
@@ -1038,7 +1041,7 @@
}
/* Acquire Left if not already acquired */
- for (i = 0; i < CAM_IFE_CSID_HW_NUM_MAX; i++) {
+ for (i = CAM_IFE_CSID_HW_NUM_MAX - 1; i >= 0; i--) {
if (!ife_hw_mgr->csid_devices[i])
continue;
@@ -1054,7 +1057,7 @@
}
}
- if (i == CAM_IFE_CSID_HW_NUM_MAX || !csid_acquire.node_res) {
+ if (i == -1 || !csid_acquire.node_res) {
CAM_ERR(CAM_ISP, "Can not acquire ife cid resource for path %d",
csid_path);
goto put_res;
@@ -2159,7 +2162,8 @@
struct cam_isp_stop_args stop_isp;
struct cam_ife_hw_mgr_ctx *ctx;
struct cam_ife_hw_mgr_res *hw_mgr_res;
- uint32_t i;
+ struct cam_isp_resource_node *rsrc_node = NULL;
+ uint32_t i, camif_debug;
if (!hw_mgr_priv || !start_isp) {
CAM_ERR(CAM_ISP, "Invalid arguments");
@@ -2193,6 +2197,24 @@
sizeof(g_ife_hw_mgr.debug_cfg.csid_debug));
}
+ camif_debug = g_ife_hw_mgr.debug_cfg.camif_debug;
+ list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) {
+ for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
+ if (!hw_mgr_res->hw_res[i])
+ continue;
+
+ rsrc_node = hw_mgr_res->hw_res[i];
+ if (rsrc_node->process_cmd && (rsrc_node->res_id ==
+ CAM_ISP_HW_VFE_IN_CAMIF)) {
+ rc = hw_mgr_res->hw_res[i]->process_cmd(
+ hw_mgr_res->hw_res[i],
+ CAM_ISP_HW_CMD_SET_CAMIF_DEBUG,
+ &camif_debug,
+ sizeof(camif_debug));
+ }
+ }
+ }
+
rc = cam_ife_hw_mgr_init_hw(ctx);
if (rc) {
CAM_ERR(CAM_ISP, "Init failed");
@@ -2804,45 +2826,133 @@
return rc;
}
+static void cam_ife_mgr_print_io_bufs(struct cam_packet *packet,
+ int32_t iommu_hdl, int32_t sec_mmu_hdl, uint32_t pf_buf_info,
+ bool *mem_found)
+{
+ uint64_t iova_addr;
+ size_t src_buf_size;
+ int i;
+ int j;
+ int rc = 0;
+ int32_t mmu_hdl;
+
+ struct cam_buf_io_cfg *io_cfg = NULL;
+
+ if (mem_found)
+ *mem_found = false;
+
+ io_cfg = (struct cam_buf_io_cfg *)((uint32_t *)&packet->payload +
+ packet->io_configs_offset / 4);
+
+ for (i = 0; i < packet->num_io_configs; i++) {
+ for (j = 0; j < CAM_PACKET_MAX_PLANES; j++) {
+ if (!io_cfg[i].mem_handle[j])
+ break;
+
+ if (GET_FD_FROM_HANDLE(io_cfg[i].mem_handle[j]) ==
+ GET_FD_FROM_HANDLE(pf_buf_info)) {
+ CAM_INFO(CAM_ISP,
+ "Found PF at port: %d mem %x fd: %x",
+ io_cfg[i].resource_type,
+ io_cfg[i].mem_handle[j],
+ pf_buf_info);
+ if (mem_found)
+ *mem_found = true;
+ }
+
+ CAM_INFO(CAM_ISP, "port: %d f: %u format: %d dir %d",
+ io_cfg[i].resource_type,
+ io_cfg[i].fence,
+ io_cfg[i].format,
+ io_cfg[i].direction);
+
+ mmu_hdl = cam_mem_is_secure_buf(
+ io_cfg[i].mem_handle[j]) ? sec_mmu_hdl :
+ iommu_hdl;
+ rc = cam_mem_get_io_buf(io_cfg[i].mem_handle[j],
+ mmu_hdl, &iova_addr, &src_buf_size);
+ if (rc < 0) {
+ CAM_ERR(CAM_ISP, "get src buf address fail");
+ continue;
+ }
+ if (iova_addr >> 32) {
+ CAM_ERR(CAM_ISP, "Invalid mapped address");
+ rc = -EINVAL;
+ continue;
+ }
+
+ CAM_INFO(CAM_ISP,
+ "pln %d w %d h %d size %d addr 0x%x offset 0x%x memh %x",
+ j, io_cfg[i].planes[j].width,
+ io_cfg[i].planes[j].height,
+ (int32_t)src_buf_size,
+ (unsigned int)iova_addr,
+ io_cfg[i].offsets[j],
+ io_cfg[i].mem_handle[j]);
+ }
+ }
+}
+
static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
{
int rc = 0;
- struct cam_isp_hw_cmd_args *hw_cmd_args = cmd_args;
- struct cam_ife_hw_mgr_ctx *ctx;
+ struct cam_hw_cmd_args *hw_cmd_args = cmd_args;
+ struct cam_ife_hw_mgr *hw_mgr = hw_mgr_priv;
+ struct cam_ife_hw_mgr_ctx *ctx = (struct cam_ife_hw_mgr_ctx *)
+ hw_cmd_args->ctxt_to_hw_map;
if (!hw_mgr_priv || !cmd_args) {
CAM_ERR(CAM_ISP, "Invalid arguments");
return -EINVAL;
}
- ctx = (struct cam_ife_hw_mgr_ctx *)hw_cmd_args->ctxt_to_hw_map;
if (!ctx || !ctx->ctx_in_use) {
CAM_ERR(CAM_ISP, "Fatal: Invalid context is used");
return -EPERM;
}
switch (hw_cmd_args->cmd_type) {
- case CAM_ISP_HW_MGR_CMD_IS_RDI_ONLY_CONTEXT:
- if (ctx->is_rdi_only_context)
- hw_cmd_args->u.is_rdi_only_context = 1;
- else
- hw_cmd_args->u.is_rdi_only_context = 0;
+ case CAM_HW_MGR_CMD_INTERNAL: {
+ struct cam_isp_hw_cmd_args *isp_hw_cmd_args =
+ (struct cam_isp_hw_cmd_args *)hw_cmd_args->
+ u.internal_args;
+ switch (isp_hw_cmd_args->cmd_type) {
+ case CAM_ISP_HW_MGR_CMD_IS_RDI_ONLY_CONTEXT:
+ if (ctx->is_rdi_only_context)
+ isp_hw_cmd_args->u.is_rdi_only_context = 1;
+ else
+ isp_hw_cmd_args->u.is_rdi_only_context = 0;
+ break;
+ case CAM_ISP_HW_MGR_CMD_PAUSE_HW:
+ cam_ife_mgr_pause_hw(ctx);
+ break;
+ case CAM_ISP_HW_MGR_CMD_RESUME_HW:
+ cam_ife_mgr_resume_hw(ctx);
+ break;
+ case CAM_ISP_HW_MGR_CMD_SOF_DEBUG:
+ cam_ife_mgr_sof_irq_debug(ctx,
+ isp_hw_cmd_args->u.sof_irq_enable);
+ break;
+ default:
+ CAM_ERR(CAM_ISP, "Invalid HW mgr command:0x%x",
+ hw_cmd_args->cmd_type);
+ rc = -EINVAL;
+ break;
+ }
break;
- case CAM_ISP_HW_MGR_CMD_PAUSE_HW:
- cam_ife_mgr_pause_hw(ctx);
- break;
- case CAM_ISP_HW_MGR_CMD_RESUME_HW:
- cam_ife_mgr_resume_hw(ctx);
- break;
- case CAM_ISP_HW_MGR_CMD_SOF_DEBUG:
- cam_ife_mgr_sof_irq_debug(ctx, hw_cmd_args->u.sof_irq_enable);
+ }
+ case CAM_HW_MGR_CMD_DUMP_PF_INFO:
+ cam_ife_mgr_print_io_bufs(
+ hw_cmd_args->u.pf_args.pf_data.packet,
+ hw_mgr->mgr_common.img_iommu_hdl,
+ hw_mgr->mgr_common.img_iommu_hdl_secure,
+ hw_cmd_args->u.pf_args.buf_info,
+ hw_cmd_args->u.pf_args.mem_found);
break;
default:
- CAM_ERR(CAM_ISP, "Invalid HW mgr command:0x%x",
- hw_cmd_args->cmd_type);
- rc = -EINVAL;
- break;
+ CAM_ERR(CAM_ISP, "Invalid cmd");
}
return rc;
@@ -4174,6 +4284,28 @@
cam_ife_get_csid_debug,
cam_ife_set_csid_debug, "%16llu");
+static int cam_ife_set_camif_debug(void *data, u64 val)
+{
+ g_ife_hw_mgr.debug_cfg.camif_debug = val;
+ CAM_DBG(CAM_ISP,
+ "Set camif enable_diag_sensor_status value :%lld", val);
+ return 0;
+}
+
+static int cam_ife_get_camif_debug(void *data, u64 *val)
+{
+ *val = g_ife_hw_mgr.debug_cfg.camif_debug;
+ CAM_DBG(CAM_ISP,
+ "Set camif enable_diag_sensor_status value :%lld",
+ g_ife_hw_mgr.debug_cfg.csid_debug);
+
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(cam_ife_camif_debug,
+ cam_ife_get_camif_debug,
+ cam_ife_set_camif_debug, "%16llu");
+
static int cam_ife_hw_mgr_debug_register(void)
{
g_ife_hw_mgr.debug_cfg.dentry = debugfs_create_dir("camera_ife",
@@ -4199,6 +4331,14 @@
CAM_ERR(CAM_ISP, "failed to create enable_recovery");
goto err;
}
+
+ if (!debugfs_create_file("ife_camif_debug",
+ 0644,
+ g_ife_hw_mgr.debug_cfg.dentry, NULL,
+ &cam_ife_camif_debug)) {
+ CAM_ERR(CAM_ISP, "failed to create cam_ife_camif_debug");
+ goto err;
+ }
g_ife_hw_mgr.debug_cfg.enable_recovery = 0;
return 0;
@@ -4208,7 +4348,7 @@
return -ENOMEM;
}
-int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf)
+int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
{
int rc = -EFAULT;
int i, j;
@@ -4380,6 +4520,9 @@
hw_mgr_intf->hw_config = cam_ife_mgr_config_hw;
hw_mgr_intf->hw_cmd = cam_ife_mgr_cmd;
+ if (iommu_hdl)
+ *iommu_hdl = g_ife_hw_mgr.mgr_common.img_iommu_hdl;
+
cam_ife_hw_mgr_debug_register();
CAM_DBG(CAM_ISP, "Exit");
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h
index 0198f3d..9bfa34f 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h
@@ -81,15 +81,17 @@
/**
* struct cam_ife_hw_mgr_debug - contain the debug information
*
- * @dentry: Debugfs entry
- * @csid_debug: csid debug information
- * @enable_recovery enable recovery
+ * @dentry: Debugfs entry
+ * @csid_debug: csid debug information
+ * @enable_recovery: enable recovery
+ * @enable_diag_sensor_status: enable sensor diagnosis status
*
*/
struct cam_ife_hw_mgr_debug {
struct dentry *dentry;
uint64_t csid_debug;
uint32_t enable_recovery;
+ uint32_t camif_debug;
};
/**
@@ -203,9 +205,10 @@
* etnry functinon for the IFE HW manager.
*
* @hw_mgr_intf: IFE hardware manager object returned
+ * @iommu_hdl: Iommu handle to be returned
*
*/
-int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf);
+int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl);
/**
* cam_ife_mgr_do_tasklet_buf_done()
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_isp_hw_mgr.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_isp_hw_mgr.c
index 2f18895..8b9c555 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_isp_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_isp_hw_mgr.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -16,7 +16,7 @@
int cam_isp_hw_mgr_init(struct device_node *of_node,
- struct cam_hw_mgr_intf *hw_mgr)
+ struct cam_hw_mgr_intf *hw_mgr, int *iommu_hdl)
{
int rc = 0;
const char *compat_str = NULL;
@@ -25,7 +25,7 @@
(const char **)&compat_str);
if (strnstr(compat_str, "ife", strlen(compat_str)))
- rc = cam_ife_hw_mgr_init(hw_mgr);
+ rc = cam_ife_hw_mgr_init(hw_mgr, iommu_hdl);
else {
CAM_ERR(CAM_ISP, "Invalid ISP hw type");
rc = -EINVAL;
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c
index eaa7325..c30d27f 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c
@@ -457,6 +457,7 @@
num_out_buf = 0;
num_in_buf = 0;
io_cfg_used_bytes = 0;
+ prepare->pf_data->packet = prepare->packet;
/* Max one hw entries required for each base */
if (prepare->num_hw_update_entries + 1 >=
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h
index fd71c37..1586216 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h
@@ -203,13 +203,11 @@
/**
* struct cam_isp_hw_cmd_args - Payload for hw manager command
*
- * @ctxt_to_hw_map: HW context from the acquire
* @cmd_type HW command type
* @get_context Get context type information
*/
struct cam_isp_hw_cmd_args {
- void *ctxt_to_hw_map;
- uint32_t cmd_type;
+ uint32_t cmd_type;
union {
uint32_t is_rdi_only_context;
uint32_t sof_irq_enable;
@@ -225,9 +223,9 @@
* @of_node: Device node input
* @hw_mgr: Input/output structure for the ISP hardware manager
* initialization
- *
+ * @iommu_hdl: Iommu handle to be returned
*/
int cam_isp_hw_mgr_init(struct device_node *of_node,
- struct cam_hw_mgr_intf *hw_mgr);
+ struct cam_hw_mgr_intf *hw_mgr, int *iommu_hdl);
#endif /* __CAM_ISP_HW_MGR_INTF_H__ */
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170.h
index c68ddf7..f90356a 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -52,6 +52,7 @@
.csid_ipp_timestamp_perv1_eof_addr = 0x2ac,
/* configurations */
.pix_store_en_shift_val = 7,
+ .early_eof_en_shift_val = 29,
};
static struct cam_ife_csid_rdi_reg_offset cam_ife_csid_170_rdi_0_reg_offset = {
@@ -286,6 +287,8 @@
.crop_shift = 16,
.ipp_irq_mask_all = 0x7FFF,
.rdi_irq_mask_all = 0x7FFF,
+ .measure_en_hbi_vbi_cnt_mask = 0xC,
+ .format_measure_en_val = 1,
};
struct cam_ife_csid_reg_offset cam_ife_csid_170_reg_offset = {
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
index c3431ca..9ffd923 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
@@ -45,6 +45,9 @@
/* Max number of sof irq's triggered in case of SOF freeze */
#define CAM_CSID_IRQ_SOF_DEBUG_CNT_MAX 6
+/* Max CSI Rx irq error count threshold value */
+#define CAM_IFE_CSID_MAX_IRQ_ERROR_COUNT 100
+
static int cam_ife_csid_is_ipp_format_supported(
uint32_t in_format)
{
@@ -423,6 +426,7 @@
if (val != 0)
CAM_ERR(CAM_ISP, "CSID:%d IRQ value after reset rc = %d",
csid_hw->hw_intf->hw_idx, val);
+ csid_hw->error_irq_count = 0;
return rc;
}
@@ -1046,6 +1050,7 @@
csid_hw->hw_intf->hw_idx);
csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN;
+ csid_hw->error_irq_count = 0;
return rc;
}
@@ -1390,8 +1395,12 @@
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
csid_reg->ipp_reg->csid_ipp_cfg0_addr);
+ val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ csid_reg->ipp_reg->csid_ipp_cfg1_addr);
+
/* select the post irq sub sample strobe for time stamp capture */
- cam_io_w_mb(CSID_TIMESTAMP_STB_POST_IRQ, soc_info->reg_map[0].mem_base +
+ val |= CSID_TIMESTAMP_STB_POST_IRQ;
+ cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
csid_reg->ipp_reg->csid_ipp_cfg1_addr);
if (path_data->crop_enable) {
@@ -1410,6 +1419,16 @@
csid_reg->ipp_reg->csid_ipp_vcrop_addr);
CAM_DBG(CAM_ISP, "CSID:%d Vertical Crop config val: 0x%x",
csid_hw->hw_intf->hw_idx, val);
+
+ /* Enable generating early eof strobe based on crop config */
+ if (!(csid_hw->csid_debug & CSID_DEBUG_DISABLE_EARLY_EOF)) {
+ val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ csid_reg->ipp_reg->csid_ipp_cfg0_addr);
+ val |= (1 <<
+ csid_reg->ipp_reg->early_eof_en_shift_val);
+ cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+ csid_reg->ipp_reg->csid_ipp_cfg0_addr);
+ }
}
/* set frame drop pattern to 0 and period to 1 */
@@ -1438,9 +1457,23 @@
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
csid_reg->ipp_reg->csid_ipp_cfg0_addr);
val |= (1 << csid_reg->cmn_reg->path_en_shift_val);
+
+ if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_HBI_VBI_INFO)
+ val |= csid_reg->cmn_reg->format_measure_en_val;
+
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
csid_reg->ipp_reg->csid_ipp_cfg0_addr);
+ /* Enable the HBI/VBI counter */
+ if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_HBI_VBI_INFO) {
+ val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ csid_reg->ipp_reg->csid_ipp_format_measure_cfg0_addr);
+ val |= csid_reg->cmn_reg->measure_en_hbi_vbi_cnt_mask;
+ cam_io_w_mb(val,
+ soc_info->reg_map[0].mem_base +
+ csid_reg->ipp_reg->csid_ipp_format_measure_cfg0_addr);
+ }
+
/* configure the rx packet capture based on csid debug set */
val = 0;
if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE)
@@ -1479,8 +1512,10 @@
struct cam_isp_resource_node *res)
{
int rc = 0;
+ uint32_t val = 0;
struct cam_ife_csid_reg_offset *csid_reg;
struct cam_hw_soc_info *soc_info;
+ struct cam_ife_csid_ipp_reg_offset *ipp_reg;
csid_reg = csid_hw->csid_info->csid_reg;
soc_info = &csid_hw->hw_info->soc_info;
@@ -1498,8 +1533,26 @@
csid_hw->hw_intf->hw_idx,
res->res_id);
rc = -EINVAL;
+ goto end;
}
+ ipp_reg = csid_reg->ipp_reg;
+ val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ ipp_reg->csid_ipp_cfg0_addr);
+ if (val & csid_reg->cmn_reg->format_measure_en_val) {
+ val &= ~csid_reg->cmn_reg->format_measure_en_val;
+ cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+ ipp_reg->csid_ipp_cfg0_addr);
+
+ /* Disable the HBI/VBI counter */
+ val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ ipp_reg->csid_ipp_format_measure_cfg0_addr);
+ val &= ~csid_reg->cmn_reg->measure_en_hbi_vbi_cnt_mask;
+ cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+ ipp_reg->csid_ipp_format_measure_cfg0_addr);
+ }
+
+end:
res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
return rc;
}
@@ -1644,6 +1697,7 @@
struct cam_ife_csid_reg_offset *csid_reg;
struct cam_hw_soc_info *soc_info;
uint32_t path_format = 0, plain_fmt = 0, val = 0, id;
+ uint32_t format_measure_addr;
path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
csid_reg = csid_hw->csid_info->csid_reg;
@@ -1737,9 +1791,24 @@
csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
val |= (1 << csid_reg->cmn_reg->path_en_shift_val);
+ if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_HBI_VBI_INFO)
+ val |= csid_reg->cmn_reg->format_measure_en_val;
+
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
+ format_measure_addr =
+ csid_reg->rdi_reg[id]->csid_rdi_format_measure_cfg0_addr;
+
+ /* Enable the HBI/VBI counter */
+ if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_HBI_VBI_INFO) {
+ val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ format_measure_addr);
+ val |= csid_reg->cmn_reg->measure_en_hbi_vbi_cnt_mask;
+ cam_io_w_mb(val,
+ soc_info->reg_map[0].mem_base + format_measure_addr);
+ }
+
/* configure the rx packet capture based on csid debug set */
if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE)
val = ((1 <<
@@ -1775,7 +1844,7 @@
struct cam_isp_resource_node *res)
{
int rc = 0;
- uint32_t id;
+ uint32_t id, val, format_measure_addr;
struct cam_ife_csid_reg_offset *csid_reg;
struct cam_hw_soc_info *soc_info;
@@ -1792,6 +1861,24 @@
return -EINVAL;
}
+ format_measure_addr =
+ csid_reg->rdi_reg[id]->csid_rdi_format_measure_cfg0_addr;
+
+ if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_HBI_VBI_INFO) {
+ val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
+ val &= ~csid_reg->cmn_reg->format_measure_en_val;
+ cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+ csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
+
+ /* Disable the HBI/VBI counter */
+ val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ format_measure_addr);
+ val &= ~csid_reg->cmn_reg->measure_en_hbi_vbi_cnt_mask;
+ cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+ format_measure_addr);
+ }
+
res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
return rc;
}
@@ -1894,6 +1981,55 @@
return rc;
}
+static int cam_ife_csid_get_hbi_vbi(
+ struct cam_ife_csid_hw *csid_hw,
+ struct cam_isp_resource_node *res)
+{
+ uint32_t hbi, vbi;
+ const struct cam_ife_csid_reg_offset *csid_reg;
+ const struct cam_ife_csid_rdi_reg_offset *rdi_reg;
+ struct cam_hw_soc_info *soc_info;
+
+ csid_reg = csid_hw->csid_info->csid_reg;
+ soc_info = &csid_hw->hw_info->soc_info;
+
+ if (res->res_type != CAM_ISP_RESOURCE_PIX_PATH ||
+ res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) {
+ CAM_ERR(CAM_ISP, "CSID:%d Invalid res_type:%d res id%d",
+ csid_hw->hw_intf->hw_idx, res->res_type,
+ res->res_id);
+ return -EINVAL;
+ }
+
+ if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) {
+ CAM_ERR(CAM_ISP, "CSID:%d Invalid dev state :%d",
+ csid_hw->hw_intf->hw_idx,
+ csid_hw->hw_info->hw_state);
+ return -EINVAL;
+ }
+
+ if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) {
+ hbi = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ csid_reg->ipp_reg->csid_ipp_format_measure1_addr);
+ vbi = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ csid_reg->ipp_reg->csid_ipp_format_measure2_addr);
+ } else {
+ rdi_reg = csid_reg->rdi_reg[res->res_id];
+ hbi = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ rdi_reg->csid_rdi_format_measure1_addr);
+ vbi = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ rdi_reg->csid_rdi_format_measure2_addr);
+ }
+
+ CAM_INFO_RATE_LIMIT(CAM_ISP, "Resource %u HBI: 0x%x", res->res_id,
+ hbi);
+ CAM_INFO_RATE_LIMIT(CAM_ISP, "Resource %u VBI: 0x%x", res->res_id,
+ vbi);
+
+ return 0;
+}
+
+
static int cam_ife_csid_get_time_stamp(
struct cam_ife_csid_hw *csid_hw, void *cmd_args)
{
@@ -2547,6 +2683,7 @@
int rc = 0;
struct cam_ife_csid_hw *csid_hw;
struct cam_hw_info *csid_hw_info;
+ struct cam_isp_resource_node *res = NULL;
if (!hw_priv || !cmd_args) {
CAM_ERR(CAM_ISP, "CSID: Invalid arguments");
@@ -2559,6 +2696,11 @@
switch (cmd_type) {
case CAM_IFE_CSID_CMD_GET_TIME_STAMP:
rc = cam_ife_csid_get_time_stamp(csid_hw, cmd_args);
+ if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_HBI_VBI_INFO) {
+ res = ((struct cam_csid_get_time_stamp_args *)
+ cmd_args)->node_res;
+ cam_ife_csid_get_hbi_vbi(csid_hw, res);
+ }
break;
case CAM_IFE_CSID_SET_CSID_DEBUG:
rc = cam_ife_csid_set_csid_debug(csid_hw, cmd_args);
@@ -2645,18 +2787,22 @@
if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE0_FIFO_OVERFLOW) {
CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 0 over flow",
csid_hw->hw_intf->hw_idx);
+ csid_hw->error_irq_count++;
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE1_FIFO_OVERFLOW) {
CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 1 over flow",
csid_hw->hw_intf->hw_idx);
+ csid_hw->error_irq_count++;
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE2_FIFO_OVERFLOW) {
CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 2 over flow",
csid_hw->hw_intf->hw_idx);
+ csid_hw->error_irq_count++;
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE3_FIFO_OVERFLOW) {
CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 3 over flow",
csid_hw->hw_intf->hw_idx);
+ csid_hw->error_irq_count++;
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW) {
CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d TG OVER FLOW",
@@ -2677,6 +2823,7 @@
if (irq_status_rx & CSID_CSI2_RX_ERROR_CRC) {
CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d ERROR_CRC",
csid_hw->hw_intf->hw_idx);
+ csid_hw->error_irq_count++;
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_ECC) {
CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d ERROR_ECC",
@@ -2689,10 +2836,12 @@
if (irq_status_rx & CSID_CSI2_RX_ERROR_STREAM_UNDERFLOW) {
CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d ERROR_STREAM_UNDERFLOW",
csid_hw->hw_intf->hw_idx);
+ csid_hw->error_irq_count++;
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_UNBOUNDED_FRAME) {
CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d UNBOUNDED_FRAME",
csid_hw->hw_intf->hw_idx);
+ csid_hw->error_irq_count++;
}
if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOT_IRQ) {
@@ -2858,6 +3007,26 @@
csid_hw->irq_debug_cnt = 0;
}
+ if (csid_hw->error_irq_count >
+ CAM_IFE_CSID_MAX_IRQ_ERROR_COUNT) {
+ /* Mask line overflow, underflow, unbound interrupts */
+ val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
+
+ val &= ~(CSID_CSI2_RX_ERROR_LANE0_FIFO_OVERFLOW |
+ CSID_CSI2_RX_ERROR_LANE1_FIFO_OVERFLOW |
+ CSID_CSI2_RX_ERROR_LANE2_FIFO_OVERFLOW |
+ CSID_CSI2_RX_ERROR_LANE3_FIFO_OVERFLOW |
+ CSID_CSI2_RX_ERROR_CRC |
+ CSID_CSI2_RX_ERROR_STREAM_UNDERFLOW |
+ CSID_CSI2_RX_ERROR_UNBOUNDED_FRAME);
+
+ cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+ csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
+ CAM_WARN(CAM_ISP, "Masked csi rx error interrupts");
+ csid_hw->error_irq_count = 0;
+ }
+
CAM_DBG(CAM_ISP, "IRQ Handling exit");
return IRQ_HANDLED;
}
@@ -2975,6 +3144,7 @@
}
ife_csid_hw->csid_debug = 0;
+ ife_csid_hw->error_irq_count = 0;
return 0;
err:
if (rc) {
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h
index ad993eb..c547f4c 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h
@@ -76,6 +76,8 @@
#define CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE BIT(4)
#define CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE BIT(5)
#define CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE BIT(6)
+#define CSID_DEBUG_ENABLE_HBI_VBI_INFO BIT(7)
+#define CSID_DEBUG_DISABLE_EARLY_EOF BIT(8)
/* enum cam_csid_path_halt_mode select the path halt mode control */
enum cam_csid_path_halt_mode {
@@ -135,6 +137,7 @@
/* configuration */
uint32_t pix_store_en_shift_val;
+ uint32_t early_eof_en_shift_val;
};
struct cam_ife_csid_rdi_reg_offset {
@@ -285,6 +288,8 @@
uint32_t crop_shift;
uint32_t ipp_irq_mask_all;
uint32_t rdi_irq_mask_all;
+ uint32_t measure_en_hbi_vbi_cnt_mask;
+ uint32_t format_measure_en_val;
};
/**
@@ -438,6 +443,8 @@
* @sof_irq_triggered: Flag is set on receiving event to enable sof irq
* incase of SOF freeze.
* @irq_debug_cnt: Counter to track sof irq's when above flag is set.
+ * @error_irq_count Error IRQ count, if continuous error irq comes
+ * need to stop the CSID and mask interrupts.
*
*/
struct cam_ife_csid_hw {
@@ -461,6 +468,7 @@
uint64_t clk_rate;
bool sof_irq_triggered;
uint32_t irq_debug_cnt;
+ uint32_t error_irq_count;
};
int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
index 28cfcc8..54aa4c2 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
@@ -96,6 +96,7 @@
CAM_ISP_HW_CMD_STOP_BUS_ERR_IRQ,
CAM_ISP_HW_CMD_GET_REG_DUMP,
CAM_ISP_HW_CMD_SOF_IRQ_DEBUG,
+ CAM_ISP_HW_CMD_SET_CAMIF_DEBUG,
CAM_ISP_HW_CMD_MAX,
};
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe170/cam_vfe170.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe170/cam_vfe170.h
index c7d3aa2..d1284d9 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe170/cam_vfe170.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe170/cam_vfe170.h
@@ -50,6 +50,8 @@
.raw_crop_width_cfg = 0x00000CE4,
.raw_crop_height_cfg = 0x00000CE8,
.reg_update_cmd = 0x000004AC,
+ .vfe_diag_config = 0x00000C48,
+ .vfe_diag_sensor_status = 0x00000C4C,
};
static struct cam_vfe_camif_reg_data vfe_170_camif_reg_data = {
@@ -79,6 +81,7 @@
.eof_irq_mask = 0x00000002,
.error_irq_mask0 = 0x0003FC00,
.error_irq_mask1 = 0x0FFF7E80,
+ .enable_diagnostic_hw = 0x1,
};
struct cam_vfe_top_ver2_reg_offset_module_ctrl lens_170_reg = {
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
index 73b4ee7..fc257ec 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
@@ -43,6 +43,7 @@
uint32_t last_line;
bool enable_sof_irq_debug;
uint32_t irq_debug_cnt;
+ uint32_t camif_debug;
};
static int cam_vfe_camif_validate_pix_pattern(uint32_t pattern)
@@ -211,6 +212,8 @@
uint32_t epoch0_irq_mask;
uint32_t epoch1_irq_mask;
uint32_t computed_epoch_line_cfg;
+ uint32_t camera_hw_version = 0;
+ int rc = 0;
if (!camif_res) {
CAM_ERR(CAM_ISP, "Error! Invalid input arguments");
@@ -250,16 +253,50 @@
rsrc_data->common_reg->module_ctrl[
CAM_VFE_TOP_VER2_MODULE_STATS]->cgc_ovd);
+ /* get the HW version */
+ rc = cam_cpas_get_cpas_hw_version(&camera_hw_version);
+
+ if (rc) {
+ CAM_ERR(CAM_ISP, "Couldn't find HW version. rc: %d", rc);
+ return rc;
+ }
+
/* epoch config */
- epoch0_irq_mask = ((rsrc_data->last_line - rsrc_data->first_line) / 2) +
- rsrc_data->first_line;
- epoch1_irq_mask = rsrc_data->reg_data->epoch_line_cfg & 0xFFFF;
- computed_epoch_line_cfg = (epoch0_irq_mask << 16) | epoch1_irq_mask;
- cam_io_w_mb(computed_epoch_line_cfg,
- rsrc_data->mem_base + rsrc_data->camif_reg->epoch_irq);
- CAM_DBG(CAM_ISP, "first_line:%u last_line:%u epoch_line_cfg: 0x%x",
- rsrc_data->first_line, rsrc_data->last_line,
- computed_epoch_line_cfg);
+ switch (camera_hw_version) {
+ case CAM_CPAS_TITAN_175_V101:
+ case CAM_CPAS_TITAN_175_V100:
+ epoch0_irq_mask = ((rsrc_data->last_line -
+ rsrc_data->first_line) / 2) +
+ rsrc_data->first_line;
+ epoch1_irq_mask = rsrc_data->reg_data->epoch_line_cfg &
+ 0xFFFF;
+ computed_epoch_line_cfg = (epoch0_irq_mask << 16) |
+ epoch1_irq_mask;
+ cam_io_w_mb(computed_epoch_line_cfg,
+ rsrc_data->mem_base +
+ rsrc_data->camif_reg->epoch_irq);
+ CAM_DBG(CAM_ISP, "first_line: %u\n"
+ "last_line: %u\n"
+ "epoch_line_cfg: 0x%x",
+ rsrc_data->first_line,
+ rsrc_data->last_line,
+ computed_epoch_line_cfg);
+ break;
+ case CAM_CPAS_TITAN_170_V100:
+ case CAM_CPAS_TITAN_170_V110:
+ case CAM_CPAS_TITAN_170_V120:
+ cam_io_w_mb(rsrc_data->reg_data->epoch_line_cfg,
+ rsrc_data->mem_base +
+ rsrc_data->camif_reg->epoch_irq);
+ break;
+ default:
+ cam_io_w_mb(rsrc_data->reg_data->epoch_line_cfg,
+ rsrc_data->mem_base +
+ rsrc_data->camif_reg->epoch_irq);
+ CAM_WARN(CAM_ISP, "Hardware version not proper: 0x%x",
+ camera_hw_version);
+ break;
+ }
camif_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
@@ -273,6 +310,15 @@
rsrc_data->enable_sof_irq_debug = false;
rsrc_data->irq_debug_cnt = 0;
+ if (rsrc_data->camif_debug &
+ CAMIF_DEBUG_ENABLE_SENSOR_DIAG_STATUS) {
+ val = cam_io_r_mb(rsrc_data->mem_base +
+ rsrc_data->camif_reg->vfe_diag_config);
+ val |= rsrc_data->reg_data->enable_diagnostic_hw;
+ cam_io_w_mb(val, rsrc_data->mem_base +
+ rsrc_data->camif_reg->vfe_diag_config);
+ }
+
CAM_DBG(CAM_ISP, "Start Camif IFE %d Done", camif_res->hw_intf->hw_idx);
return 0;
}
@@ -364,6 +410,14 @@
if (camif_res->res_state == CAM_ISP_RESOURCE_STATE_STREAMING)
camif_res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
+ val = cam_io_r_mb(camif_priv->mem_base +
+ camif_priv->camif_reg->vfe_diag_config);
+ if (val & camif_priv->reg_data->enable_diagnostic_hw) {
+ val &= ~camif_priv->reg_data->enable_diagnostic_hw;
+ cam_io_w_mb(val, camif_priv->mem_base +
+ camif_priv->camif_reg->vfe_diag_config);
+ }
+
return rc;
}
@@ -388,6 +442,7 @@
uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
{
int rc = -EINVAL;
+ struct cam_vfe_mux_camif_data *camif_priv = NULL;
if (!rsrc_node || !cmd_args) {
CAM_ERR(CAM_ISP, "Invalid input arguments");
@@ -405,6 +460,11 @@
case CAM_ISP_HW_CMD_SOF_IRQ_DEBUG:
rc = cam_vfe_camif_sof_irq_debug(rsrc_node, cmd_args);
break;
+ case CAM_ISP_HW_CMD_SET_CAMIF_DEBUG:
+ camif_priv =
+ (struct cam_vfe_mux_camif_data *)rsrc_node->res_priv;
+ camif_priv->camif_debug = *((uint32_t *)cmd_args);
+ break;
default:
CAM_ERR(CAM_ISP,
"unsupported process command:%d", cmd_type);
@@ -429,6 +489,7 @@
struct cam_vfe_top_irq_evt_payload *payload;
uint32_t irq_status0;
uint32_t irq_status1;
+ uint32_t val;
if (!handler_priv || !evt_payload_priv) {
CAM_ERR(CAM_ISP, "Invalid params");
@@ -491,6 +552,14 @@
} else {
ret = CAM_ISP_HW_ERROR_NONE;
}
+
+ if (camif_priv->camif_debug &
+ CAMIF_DEBUG_ENABLE_SENSOR_DIAG_STATUS) {
+ val = cam_io_r(camif_priv->mem_base +
+ camif_priv->camif_reg->vfe_diag_sensor_status);
+ CAM_DBG(CAM_ISP, "VFE_DIAG_SENSOR_STATUS: 0x%x",
+ camif_priv->mem_base, val);
+ }
break;
default:
break;
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.h
index 4a73bd7..7a69589 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -16,6 +16,11 @@
#include "cam_isp_hw.h"
#include "cam_vfe_top.h"
+/*
+ * Debug values for camif module
+ */
+#define CAMIF_DEBUG_ENABLE_SENSOR_DIAG_STATUS BIT(0)
+
struct cam_vfe_camif_ver2_reg {
uint32_t camif_cmd;
uint32_t camif_config;
@@ -27,6 +32,8 @@
uint32_t raw_crop_width_cfg;
uint32_t raw_crop_height_cfg;
uint32_t reg_update_cmd;
+ uint32_t vfe_diag_config;
+ uint32_t vfe_diag_sensor_status;
};
struct cam_vfe_camif_reg_data {
@@ -63,6 +70,8 @@
uint32_t eof_irq_mask;
uint32_t error_irq_mask0;
uint32_t error_irq_mask1;
+
+ uint32_t enable_diagnostic_hw;
};
struct cam_vfe_camif_ver2_hw_info {
diff --git a/drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_context.c b/drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_context.c
index 02334a4..287d4a4 100644
--- a/drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_context.c
+++ b/drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_context.c
@@ -20,9 +20,49 @@
#include "cam_jpeg_context.h"
#include "cam_context_utils.h"
#include "cam_debug_util.h"
+#include "cam_packet_util.h"
static const char jpeg_dev_name[] = "jpeg";
+static int cam_jpeg_context_dump_active_request(void *data, unsigned long iova,
+ uint32_t buf_info)
+{
+
+ struct cam_context *ctx = (struct cam_context *)data;
+ struct cam_ctx_request *req = NULL;
+ struct cam_ctx_request *req_temp = NULL;
+ struct cam_hw_mgr_dump_pf_data *pf_dbg_entry = NULL;
+ int rc = 0;
+ int closest_port;
+ bool b_mem_found = false;
+
+
+ if (!ctx) {
+ CAM_ERR(CAM_JPEG, "Invalid ctx");
+ return -EINVAL;
+ }
+
+ CAM_INFO(CAM_JPEG, "iommu fault for jpeg ctx %d state %d",
+ ctx->ctx_id, ctx->state);
+
+ list_for_each_entry_safe(req, req_temp,
+ &ctx->active_req_list, list) {
+ pf_dbg_entry = &(req->pf_data);
+ closest_port = -1;
+ CAM_INFO(CAM_JPEG, "req_id : %lld ", req->request_id);
+
+ rc = cam_context_dump_pf_info_to_hw(ctx, pf_dbg_entry->packet,
+ iova, buf_info, &b_mem_found);
+ if (rc)
+ CAM_ERR(CAM_JPEG, "Failed to dump pf info");
+
+ if (b_mem_found)
+ CAM_ERR(CAM_JPEG, "Found page fault in req %lld %d",
+ req->request_id, rc);
+ }
+ return rc;
+}
+
static int __cam_jpeg_ctx_acquire_dev_in_available(struct cam_context *ctx,
struct cam_acquire_dev_cmd *cmd)
{
@@ -116,6 +156,7 @@
},
.crm_ops = { },
.irq_ops = __cam_jpeg_ctx_handle_buf_done_in_acquired,
+ .pagefault_ops = cam_jpeg_context_dump_active_request,
},
};
diff --git a/drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_dev.c b/drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_dev.c
index 46cc08f..1489222 100644
--- a/drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_dev.c
+++ b/drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_dev.c
@@ -22,11 +22,31 @@
#include "cam_jpeg_hw_mgr_intf.h"
#include "cam_jpeg_dev.h"
#include "cam_debug_util.h"
+#include "cam_smmu_api.h"
#define CAM_JPEG_DEV_NAME "cam-jpeg"
static struct cam_jpeg_dev g_jpeg_dev;
+static void cam_jpeg_dev_iommu_fault_handler(
+ struct iommu_domain *domain, struct device *dev, unsigned long iova,
+ int flags, void *token, uint32_t buf_info)
+{
+ int i = 0;
+ struct cam_node *node = NULL;
+
+ if (!token) {
+ CAM_ERR(CAM_JPEG, "invalid token in page handler cb");
+ return;
+ }
+
+ node = (struct cam_node *)token;
+
+ for (i = 0; i < node->ctx_size; i++)
+ cam_context_dump_pf_info(&(node->ctx_list[i]), iova,
+ buf_info);
+}
+
static const struct of_device_id cam_jpeg_dt_match[] = {
{
.compatible = "qcom,cam-jpeg"
@@ -34,23 +54,50 @@
{ }
};
-static int cam_jpeg_subdev_close(struct v4l2_subdev *sd,
+static int cam_jpeg_subdev_open(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
- struct cam_node *node = v4l2_get_subdevdata(sd);
- if (!node) {
- CAM_ERR(CAM_JPEG, "Node ptr is NULL");
- return -EINVAL;
- }
-
- cam_node_shutdown(node);
+ mutex_lock(&g_jpeg_dev.jpeg_mutex);
+ g_jpeg_dev.open_cnt++;
+ mutex_unlock(&g_jpeg_dev.jpeg_mutex);
return 0;
}
+static int cam_jpeg_subdev_close(struct v4l2_subdev *sd,
+ struct v4l2_subdev_fh *fh)
+{
+ int rc = 0;
+ struct cam_node *node = v4l2_get_subdevdata(sd);
+
+
+ mutex_lock(&g_jpeg_dev.jpeg_mutex);
+ if (g_jpeg_dev.open_cnt <= 0) {
+ CAM_DBG(CAM_JPEG, "JPEG subdev is already closed");
+ rc = -EINVAL;
+ goto end;
+ }
+
+ g_jpeg_dev.open_cnt--;
+
+ if (!node) {
+ CAM_ERR(CAM_JPEG, "Node ptr is NULL");
+ rc = -EINVAL;
+ goto end;
+ }
+
+ if (g_jpeg_dev.open_cnt == 0)
+ cam_node_shutdown(node);
+
+end:
+ mutex_unlock(&g_jpeg_dev.jpeg_mutex);
+ return rc;
+}
+
static const struct v4l2_subdev_internal_ops cam_jpeg_subdev_internal_ops = {
.close = cam_jpeg_subdev_close,
+ .open = cam_jpeg_subdev_open,
};
static int cam_jpeg_dev_remove(struct platform_device *pdev)
@@ -78,6 +125,7 @@
int i;
struct cam_hw_mgr_intf hw_mgr_intf;
struct cam_node *node;
+ int iommu_hdl = -1;
g_jpeg_dev.sd.internal_ops = &cam_jpeg_subdev_internal_ops;
rc = cam_subdev_probe(&g_jpeg_dev.sd, pdev, CAM_JPEG_DEV_NAME,
@@ -89,7 +137,7 @@
node = (struct cam_node *)g_jpeg_dev.sd.token;
rc = cam_jpeg_hw_mgr_init(pdev->dev.of_node,
- (uint64_t *)&hw_mgr_intf);
+ (uint64_t *)&hw_mgr_intf, &iommu_hdl);
if (rc) {
CAM_ERR(CAM_JPEG, "Can not initialize JPEG HWmanager %d", rc);
goto unregister;
@@ -114,6 +162,9 @@
goto ctx_init_fail;
}
+ cam_smmu_set_client_page_fault_handler(iommu_hdl,
+ cam_jpeg_dev_iommu_fault_handler, node);
+
mutex_init(&g_jpeg_dev.jpeg_mutex);
CAM_INFO(CAM_JPEG, "Camera JPEG probe complete");
diff --git a/drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_dev.h b/drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_dev.h
index deab2d5..0d15ced 100644
--- a/drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_dev.h
+++ b/drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_dev.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -26,6 +26,7 @@
* @ctx: JPEG base context storage
* @ctx_jpeg: JPEG private context storage
* @jpeg_mutex: Jpeg dev mutex
+ * @open_cnt: Open device count
*/
struct cam_jpeg_dev {
struct cam_subdev sd;
@@ -33,5 +34,6 @@
struct cam_context ctx[CAM_CTX_MAX];
struct cam_jpeg_context ctx_jpeg[CAM_CTX_MAX];
struct mutex jpeg_mutex;
+ int32_t open_cnt;
};
#endif /* __CAM_JPEG_DEV_H__ */
diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
index f0913b2..a82e0d2 100644
--- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
@@ -600,6 +600,74 @@
return rc;
}
+static void cam_jpeg_mgr_print_io_bufs(struct cam_packet *packet,
+ int32_t iommu_hdl, int32_t sec_mmu_hdl, uint32_t pf_buf_info,
+ bool *mem_found)
+{
+ uint64_t iova_addr;
+ size_t src_buf_size;
+ int i;
+ int j;
+ int rc = 0;
+ int32_t mmu_hdl;
+ struct cam_buf_io_cfg *io_cfg = NULL;
+
+ if (mem_found)
+ *mem_found = false;
+
+ io_cfg = (struct cam_buf_io_cfg *)((uint32_t *)&packet->payload +
+ packet->io_configs_offset / 4);
+
+ for (i = 0; i < packet->num_io_configs; i++) {
+ for (j = 0; j < CAM_PACKET_MAX_PLANES; j++) {
+ if (!io_cfg[i].mem_handle[j])
+ break;
+
+ if (GET_FD_FROM_HANDLE(io_cfg[i].mem_handle[j]) ==
+ GET_FD_FROM_HANDLE(pf_buf_info)) {
+ CAM_INFO(CAM_JPEG,
+ "Found PF at port: %d mem %x fd: %x",
+ io_cfg[i].resource_type,
+ io_cfg[i].mem_handle[j],
+ pf_buf_info);
+ if (mem_found)
+ *mem_found = true;
+ }
+
+ CAM_INFO(CAM_JPEG, "port: %d f: %u format: %d dir %d",
+ io_cfg[i].resource_type,
+ io_cfg[i].fence,
+ io_cfg[i].format,
+ io_cfg[i].direction);
+
+ mmu_hdl = cam_mem_is_secure_buf(
+ io_cfg[i].mem_handle[j]) ? sec_mmu_hdl :
+ iommu_hdl;
+ rc = cam_mem_get_io_buf(io_cfg[i].mem_handle[j],
+ mmu_hdl, &iova_addr, &src_buf_size);
+ if (rc < 0) {
+ CAM_ERR(CAM_UTIL, "get src buf address fail");
+ continue;
+ }
+ if (iova_addr >> 32) {
+ CAM_ERR(CAM_JPEG, "Invalid mapped address");
+ rc = -EINVAL;
+ continue;
+ }
+
+ CAM_INFO(CAM_JPEG,
+ "pln %d w %d h %d size %d addr 0x%x offset 0x%x memh %x",
+ j, io_cfg[i].planes[j].width,
+ io_cfg[i].planes[j].height,
+ (int32_t)src_buf_size,
+ (unsigned int)iova_addr,
+ io_cfg[i].offsets[j],
+ io_cfg[i].mem_handle[j]);
+
+ iova_addr += io_cfg[i].offsets[j];
+ }
+ }
+}
static int cam_jpeg_mgr_prepare_hw_update(void *hw_mgr_priv,
void *prepare_hw_update_args)
@@ -675,6 +743,7 @@
CAM_DBG(CAM_JPEG, "packet = %pK io_cfg_ptr = %pK size = %lu",
(void *)packet, (void *)io_cfg_ptr,
sizeof(struct cam_buf_io_cfg));
+ prepare_args->pf_data->packet = packet;
prepare_args->num_out_map_entries = 0;
@@ -1410,7 +1479,35 @@
return rc;
}
-int cam_jpeg_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl)
+static int cam_jpeg_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
+{
+ int rc = 0;
+ struct cam_hw_cmd_args *hw_cmd_args = cmd_args;
+ struct cam_jpeg_hw_mgr *hw_mgr = hw_mgr_priv;
+
+ if (!hw_mgr_priv || !cmd_args) {
+ CAM_ERR(CAM_JPEG, "Invalid arguments");
+ return -EINVAL;
+ }
+
+ switch (hw_cmd_args->cmd_type) {
+ case CAM_HW_MGR_CMD_DUMP_PF_INFO:
+ cam_jpeg_mgr_print_io_bufs(
+ hw_cmd_args->u.pf_args.pf_data.packet,
+ hw_mgr->iommu_hdl,
+ hw_mgr->iommu_sec_hdl,
+ hw_cmd_args->u.pf_args.buf_info,
+ hw_cmd_args->u.pf_args.mem_found);
+ break;
+ default:
+ CAM_ERR(CAM_JPEG, "Invalid cmd");
+ }
+
+ return rc;
+}
+
+int cam_jpeg_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
+ int *iommu_hdl)
{
int i, rc;
uint32_t num_dev;
@@ -1434,6 +1531,7 @@
hw_mgr_intf->hw_config = cam_jpeg_mgr_config_hw;
hw_mgr_intf->hw_flush = cam_jpeg_mgr_hw_flush;
hw_mgr_intf->hw_stop = cam_jpeg_mgr_hw_stop;
+ hw_mgr_intf->hw_cmd = cam_jpeg_mgr_cmd;
mutex_init(&g_jpeg_hw_mgr.hw_mgr_mutex);
spin_lock_init(&g_jpeg_hw_mgr.hw_mgr_lock);
@@ -1495,6 +1593,9 @@
goto cdm_iommu_failed;
}
+ if (iommu_hdl)
+ *iommu_hdl = g_jpeg_hw_mgr.iommu_hdl;
+
return rc;
cdm_iommu_failed:
diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/include/cam_jpeg_hw_mgr_intf.h b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/include/cam_jpeg_hw_mgr_intf.h
index 5fb4e3ad..5705890 100644
--- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/include/cam_jpeg_hw_mgr_intf.h
+++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/include/cam_jpeg_hw_mgr_intf.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -17,8 +17,7 @@
#include <uapi/media/cam_defs.h>
#include <linux/of.h>
-
int cam_jpeg_hw_mgr_init(struct device_node *of_node,
- uint64_t *hw_mgr_hdl);
+ uint64_t *hw_mgr_hdl, int *iommu_hdl);
#endif /* CAM_JPEG_HW_MGR_INTF_H */
diff --git a/drivers/media/platform/msm/camera/cam_lrme/cam_lrme_context.c b/drivers/media/platform/msm/camera/cam_lrme/cam_lrme_context.c
index 3d0266d..5dc8763 100644
--- a/drivers/media/platform/msm/camera/cam_lrme/cam_lrme_context.c
+++ b/drivers/media/platform/msm/camera/cam_lrme/cam_lrme_context.c
@@ -25,7 +25,7 @@
uint64_t ctxt_to_hw_map = (uint64_t)ctx->ctxt_to_hw_map;
struct cam_lrme_context *lrme_ctx = ctx->ctx_priv;
- CAM_DBG(CAM_LRME, "Enter");
+ CAM_DBG(CAM_LRME, "Enter ctx %d", ctx->ctx_id);
rc = cam_context_acquire_dev_to_hw(ctx, cmd);
if (rc) {
@@ -46,7 +46,7 @@
{
int rc = 0;
- CAM_DBG(CAM_LRME, "Enter");
+ CAM_DBG(CAM_LRME, "Enter ctx %d", ctx->ctx_id);
rc = cam_context_release_dev_to_hw(ctx, cmd);
if (rc) {
@@ -64,7 +64,7 @@
{
int rc = 0;
- CAM_DBG(CAM_LRME, "Enter");
+ CAM_DBG(CAM_LRME, "Enter ctx %d", ctx->ctx_id);
rc = cam_context_start_dev_to_hw(ctx, cmd);
if (rc) {
@@ -82,7 +82,7 @@
{
int rc;
- CAM_DBG(CAM_LRME, "Enter");
+ CAM_DBG(CAM_LRME, "Enter ctx %d", ctx->ctx_id);
rc = cam_context_prepare_dev_to_hw(ctx, cmd);
if (rc) {
@@ -98,6 +98,8 @@
{
int rc;
+ CAM_DBG(CAM_LRME, "Enter ctx %d", ctx->ctx_id);
+
rc = cam_context_flush_dev_to_hw(ctx, cmd);
if (rc)
CAM_ERR(CAM_LRME, "Failed to flush device");
@@ -109,7 +111,7 @@
{
int rc = 0;
- CAM_DBG(CAM_LRME, "Enter");
+ CAM_DBG(CAM_LRME, "Enter ctx %d", ctx->ctx_id);
rc = cam_context_stop_dev_to_hw(ctx);
if (rc) {
@@ -127,7 +129,7 @@
{
int rc = 0;
- CAM_DBG(CAM_LRME, "Enter");
+ CAM_DBG(CAM_LRME, "Enter ctx %d", ctx->ctx_id);
rc = __cam_lrme_ctx_stop_dev_in_activated(ctx, NULL);
if (rc) {
@@ -182,6 +184,7 @@
/* Acquired */
{
.ioctl_ops = {
+ .config_dev = __cam_lrme_ctx_config_dev_in_activated,
.release_dev = __cam_lrme_ctx_release_dev_in_acquired,
.start_dev = __cam_lrme_ctx_start_dev_in_acquired,
},
diff --git a/drivers/media/platform/msm/camera/cam_lrme/cam_lrme_dev.c b/drivers/media/platform/msm/camera/cam_lrme/cam_lrme_dev.c
index a4ee104..6b1250a 100644
--- a/drivers/media/platform/msm/camera/cam_lrme/cam_lrme_dev.c
+++ b/drivers/media/platform/msm/camera/cam_lrme/cam_lrme_dev.c
@@ -81,6 +81,7 @@
static int cam_lrme_dev_close(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
+ int rc = 0;
struct cam_lrme_dev *lrme_dev = g_lrme_dev;
struct cam_node *node = v4l2_get_subdevdata(sd);
@@ -90,18 +91,25 @@
}
mutex_lock(&lrme_dev->lock);
- lrme_dev->open_cnt--;
- mutex_unlock(&lrme_dev->lock);
+ if (lrme_dev->open_cnt <= 0) {
+ CAM_DBG(CAM_LRME, "LRME subdev is already closed");
+ rc = -EINVAL;
+ goto end;
+ }
+ lrme_dev->open_cnt--;
if (!node) {
CAM_ERR(CAM_LRME, "Node is NULL");
- return -EINVAL;
+ rc = -EINVAL;
+ goto end;
}
if (lrme_dev->open_cnt == 0)
cam_node_shutdown(node);
- return 0;
+end:
+ mutex_unlock(&lrme_dev->lock);
+ return rc;
}
static const struct v4l2_subdev_internal_ops cam_lrme_subdev_internal_ops = {
diff --git a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c
index fa8984c..79d23cb 100644
--- a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c
@@ -765,6 +765,12 @@
return -EINVAL;
}
+ rc = hw_device->hw_intf.hw_ops.process_cmd(
+ hw_device->hw_intf.hw_priv,
+ CAM_LRME_HW_CMD_DUMP_REGISTER,
+ &g_lrme_hw_mgr.debugfs_entry.dump_register,
+ sizeof(bool));
+
return rc;
}
@@ -963,6 +969,35 @@
return rc;
}
+static int cam_lrme_mgr_create_debugfs_entry(void)
+{
+ int rc = 0;
+
+ g_lrme_hw_mgr.debugfs_entry.dentry =
+ debugfs_create_dir("camera_lrme", NULL);
+ if (!g_lrme_hw_mgr.debugfs_entry.dentry) {
+ CAM_ERR(CAM_LRME, "failed to create dentry");
+ return -ENOMEM;
+ }
+
+ if (!debugfs_create_bool("dump_register",
+ 0644,
+ g_lrme_hw_mgr.debugfs_entry.dentry,
+ &g_lrme_hw_mgr.debugfs_entry.dump_register)) {
+ CAM_ERR(CAM_LRME, "failed to create dump register entry");
+ rc = -ENOMEM;
+ goto err;
+ }
+
+ return rc;
+
+err:
+ debugfs_remove_recursive(g_lrme_hw_mgr.debugfs_entry.dentry);
+ g_lrme_hw_mgr.debugfs_entry.dentry = NULL;
+ return rc;
+}
+
+
int cam_lrme_mgr_register_device(
struct cam_hw_intf *lrme_hw_intf,
struct cam_iommu_handle *device_iommu,
@@ -1113,6 +1148,8 @@
g_lrme_hw_mgr.event_cb = cam_lrme_dev_buf_done_cb;
+ cam_lrme_mgr_create_debugfs_entry();
+
CAM_DBG(CAM_LRME, "Hw mgr init done");
return rc;
}
diff --git a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.h b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.h
index f7ce4d2..53d3c63 100644
--- a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.h
+++ b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.h
@@ -52,13 +52,24 @@
/**
* struct cam_lrme_mgr_work_data : HW Mgr work data
*
- * hw_device : Pointer to the hw device
+ * @hw_device : Pointer to the hw device
*/
struct cam_lrme_mgr_work_data {
struct cam_lrme_device *hw_device;
};
/**
+ * struct cam_lrme_debugfs_entry : debugfs entry struct
+ *
+ * @dentry : entry of debugfs
+ * @dump_register : flag to dump registers
+ */
+struct cam_lrme_debugfs_entry {
+ struct dentry *dentry;
+ bool dump_register;
+};
+
+/**
* struct cam_lrme_device : LRME HW device
*
* @hw_caps : HW device's capabilities
@@ -98,6 +109,7 @@
* @frame_req : List of frame request to use
* @lrme_caps : LRME capabilities
* @event_cb : IRQ callback function
+ * @debugfs_entry : debugfs entry to set debug prop
*/
struct cam_lrme_hw_mgr {
uint32_t device_count;
@@ -110,6 +122,7 @@
struct cam_lrme_frame_request frame_req[CAM_CTX_REQ_MAX * CAM_CTX_MAX];
struct cam_lrme_query_cap_cmd lrme_caps;
cam_hw_event_cb_func event_cb;
+ struct cam_lrme_debugfs_entry debugfs_entry;
};
int cam_lrme_mgr_register_device(struct cam_hw_intf *lrme_hw_intf,
diff --git a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_core.c b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_core.c
index 595bb81..022e1a7 100644
--- a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_core.c
+++ b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_core.c
@@ -14,6 +14,20 @@
#include "cam_lrme_hw_soc.h"
#include "cam_smmu_api.h"
+static void cam_lrme_dump_registers(void __iomem *base)
+{
+ /* dump the clc registers */
+ cam_io_dump(base, 0x60, (0xc0 - 0x60) / 0x4);
+ /* dump the fe and we registers */
+ cam_io_dump(base, 0x200, (0x29c - 0x200) / 0x4);
+ cam_io_dump(base, 0x2f0, (0x330 - 0x2f0) / 0x4);
+ cam_io_dump(base, 0x500, (0x5b4 - 0x500) / 0x4);
+ cam_io_dump(base, 0x700, (0x778 - 0x700) / 0x4);
+ cam_io_dump(base, 0x800, (0x878 - 0x800) / 0x4);
+ /* dump lrme sw registers, interrupts */
+ cam_io_dump(base, 0x900, (0x928 - 0x900) / 0x4);
+}
+
static void cam_lrme_cdm_write_reg_val_pair(uint32_t *buffer,
uint32_t *index, uint32_t reg_offset, uint32_t reg_value)
{
@@ -64,7 +78,8 @@
cam_lrme_cdm_write_reg_val_pair(reg_val_pair, num_cmd,
hw_info->bus_rd_reg.bus_client_reg[index].unpack_cfg_0,
0x0);
- else if (io_buf->io_cfg->format == CAM_FORMAT_Y_ONLY)
+ else if (io_buf->io_cfg->format == CAM_FORMAT_Y_ONLY ||
+ io_buf->io_cfg->format == CAM_FORMAT_PLAIN8)
cam_lrme_cdm_write_reg_val_pair(reg_val_pair, num_cmd,
hw_info->bus_rd_reg.bus_client_reg[index].unpack_cfg_0,
0x1);
@@ -567,6 +582,8 @@
lrme_core->state);
}
+ cam_lrme_dump_registers(lrme_hw->soc_info.reg_map[0].mem_base);
+
CAM_ERR_RATE_LIMIT(CAM_LRME, "Start recovery");
lrme_core->state = CAM_LRME_CORE_STATE_RECOVERY;
rc = cam_lrme_hw_util_reset(lrme_hw, CAM_LRME_HW_RESET_TYPE_HW_RESET);
@@ -610,6 +627,9 @@
lrme_core->req_proc = lrme_core->req_submit;
lrme_core->req_submit = NULL;
+ if (lrme_core->dump_flag)
+ cam_lrme_dump_registers(lrme_hw->soc_info.reg_map[0].mem_base);
+
return 0;
}
@@ -654,13 +674,13 @@
cam_io_w_mb(0xFFFF,
soc_info->reg_map[0].mem_base +
hw_info->titan_reg.top_irq_mask);
- cam_io_w_mb(0xFFFF,
+ cam_io_w_mb(0xFFFFF,
soc_info->reg_map[0].mem_base +
hw_info->bus_wr_reg.common_reg.irq_mask_0);
- cam_io_w_mb(0xFFFF,
+ cam_io_w_mb(0xFFFFF,
soc_info->reg_map[0].mem_base +
hw_info->bus_wr_reg.common_reg.irq_mask_1);
- cam_io_w_mb(0xFFFF,
+ cam_io_w_mb(0xFFFFF,
soc_info->reg_map[0].mem_base +
hw_info->bus_rd_reg.common_reg.irq_mask);
break;
@@ -952,6 +972,7 @@
}
lrme_core->req_submit = frame_req;
+
mutex_unlock(&lrme_hw->hw_mutex);
CAM_DBG(CAM_LRME, "Release lock, submit done for req %llu",
frame_req->req_id);
@@ -1235,6 +1256,14 @@
break;
}
+ case CAM_LRME_HW_CMD_DUMP_REGISTER: {
+ struct cam_lrme_core *lrme_core =
+ (struct cam_lrme_core *)lrme_hw->core_info;
+ lrme_core->dump_flag = *(bool *)cmd_args;
+ CAM_DBG(CAM_LRME, "dump_flag %d", lrme_core->dump_flag);
+ break;
+ }
+
default:
break;
}
diff --git a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_core.h b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_core.h
index bf2f370..cf8e740 100644
--- a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_core.h
+++ b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_core.h
@@ -137,6 +137,7 @@
struct cam_lrme_frame_request *req_submit;
struct cam_lrme_cdm_info *hw_cdm_info;
uint32_t hw_idx;
+ bool dump_flag;
};
/**
diff --git a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_intf.h b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_intf.h
index d16b174..26b5608 100644
--- a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_intf.h
+++ b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_intf.h
@@ -65,11 +65,13 @@
* @CAM_LRME_HW_CMD_prepare_hw_update : Prepare HW update
* @CAM_LRME_HW_CMD_REGISTER_CB : register HW manager callback
* @CAM_LRME_HW_CMD_SUBMIT : Submit frame to HW
+ * @CAM_LRME_HW_CMD_DUMP_REGISTER : dump register values
*/
enum cam_lrme_hw_cmd_type {
CAM_LRME_HW_CMD_PREPARE_HW_UPDATE,
CAM_LRME_HW_CMD_REGISTER_CB,
CAM_LRME_HW_CMD_SUBMIT,
+ CAM_LRME_HW_CMD_DUMP_REGISTER,
};
/**
diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c
index 460b3df..4c4afc1 100644
--- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c
+++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c
@@ -1325,9 +1325,9 @@
return NULL;
}
- if (session->num_links >= MAX_LINKS_PER_SESSION) {
+ if (session->num_links >= MAXIMUM_LINKS_PER_SESSION) {
CAM_ERR(CAM_CRM, "Reached max links %d per session limit %d",
- session->num_links, MAX_LINKS_PER_SESSION);
+ session->num_links, MAXIMUM_LINKS_PER_SESSION);
return NULL;
}
@@ -1362,7 +1362,7 @@
mutex_lock(&session->lock);
/* Loop through and find a free index */
- for (i = 0; i < MAX_LINKS_PER_SESSION; i++) {
+ for (i = 0; i < MAXIMUM_LINKS_PER_SESSION; i++) {
if (!session->links[i]) {
CAM_DBG(CAM_CRM,
"Free link index %d found, num_links=%d",
@@ -1372,7 +1372,7 @@
}
}
- if (i == MAX_LINKS_PER_SESSION) {
+ if (i == MAXIMUM_LINKS_PER_SESSION) {
CAM_ERR(CAM_CRM, "Free link index not found");
goto error;
}
@@ -1433,7 +1433,7 @@
return;
}
- for (i = 0; i < MAX_LINKS_PER_SESSION; i++) {
+ for (i = 0; i < MAXIMUM_LINKS_PER_SESSION; i++) {
if (session->links[i] == link)
session->links[i] = NULL;
}
@@ -1445,7 +1445,7 @@
* of only having 2 links in a given session
*/
session->sync_mode = CAM_REQ_MGR_SYNC_MODE_NO_SYNC;
- for (i = 0; i < MAX_LINKS_PER_SESSION; i++) {
+ for (i = 0; i < MAXIMUM_LINKS_PER_SESSION; i++) {
if (session->links[i])
session->links[i]->sync_link = NULL;
}
@@ -2387,7 +2387,7 @@
ses_info->session_hdl,
cam_session->num_links);
- for (i = 0; i < MAX_LINKS_PER_SESSION; i++) {
+ for (i = 0; i < MAXIMUM_LINKS_PER_SESSION; i++) {
link = cam_session->links[i];
if (!link)
@@ -2628,7 +2628,8 @@
}
if ((sync_info->num_links < 0) ||
- (sync_info->num_links > MAX_LINKS_PER_SESSION)) {
+ (sync_info->num_links >
+ MAX_LINKS_PER_SESSION)) {
CAM_ERR(CAM_CRM, "Invalid num links %d", sync_info->num_links);
return -EINVAL;
}
@@ -2777,6 +2778,13 @@
goto end;
}
+ if (control->num_links > MAX_LINKS_PER_SESSION) {
+ CAM_ERR(CAM_CRM, "Invalid number of links %d",
+ control->num_links);
+ rc = -EINVAL;
+ goto end;
+ }
+
mutex_lock(&g_crm_core_dev->crm_lock);
for (i = 0; i < control->num_links; i++) {
link = (struct cam_req_mgr_core_link *)
diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h
index 68ec09b..8b86931 100644
--- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h
+++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.h
@@ -34,6 +34,8 @@
#define SYNC_LINK_SOF_CNT_MAX_LMT 1
+#define MAXIMUM_LINKS_PER_SESSION 4
+
/**
* enum crm_workq_task_type
* @codes: to identify which type of task is present
@@ -353,7 +355,7 @@
struct cam_req_mgr_core_session {
int32_t session_hdl;
uint32_t num_links;
- struct cam_req_mgr_core_link *links[MAX_LINKS_PER_SESSION];
+ struct cam_req_mgr_core_link *links[MAXIMUM_LINKS_PER_SESSION];
struct list_head entry;
struct mutex lock;
int32_t force_err_recovery;
diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.c
index 0d21064..f68ca06 100644
--- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.c
+++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.c
@@ -153,6 +153,10 @@
static int cam_req_mgr_close(struct file *filep)
{
+ struct v4l2_subdev *sd;
+ struct v4l2_fh *vfh = filep->private_data;
+ struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);
+
mutex_lock(&g_dev.cam_lock);
if (g_dev.open_cnt <= 0) {
@@ -161,6 +165,17 @@
}
cam_req_mgr_handle_core_shutdown();
+
+ list_for_each_entry(sd, &g_dev.v4l2_dev->subdevs, list) {
+ if (!(sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE))
+ continue;
+ if (sd->internal_ops && sd->internal_ops->close) {
+ CAM_DBG(CAM_CRM, "Invoke subdev close for device %s",
+ sd->name);
+ sd->internal_ops->close(sd, subdev_fh);
+ }
+ }
+
g_dev.open_cnt--;
v4l2_fh_release(filep);
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c
index ed0a26b..31d9d35 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c
@@ -141,7 +141,7 @@
CAM_ERR(CAM_ACTUATOR, "failed: power_info %pK", power_info);
return -EINVAL;
}
- rc = msm_camera_power_down(power_info, soc_info);
+ rc = cam_sensor_util_power_down(power_info, soc_info);
if (rc) {
CAM_ERR(CAM_ACTUATOR, "power down the core is failed:%d", rc);
return rc;
@@ -301,7 +301,7 @@
trace_cam_apply_req("Actuator", apply->request_id);
CAM_DBG(CAM_ACTUATOR, "Request Id: %lld", apply->request_id);
-
+ mutex_lock(&(a_ctrl->actuator_mutex));
if ((apply->request_id ==
a_ctrl->i2c_data.per_frame[request_id].request_id) &&
(a_ctrl->i2c_data.per_frame[request_id].is_settings_valid)
@@ -312,7 +312,7 @@
CAM_ERR(CAM_ACTUATOR,
"Failed in applying the request: %lld\n",
apply->request_id);
- return rc;
+ goto release_mutex;
}
}
del_req_id = (request_id +
@@ -327,12 +327,14 @@
CAM_ERR(CAM_ACTUATOR,
"Fail deleting the req: %d err: %d\n",
del_req_id, rc);
- return rc;
+ goto release_mutex;
}
} else {
CAM_DBG(CAM_ACTUATOR, "No Valid Req to clean Up");
}
+release_mutex:
+ mutex_unlock(&(a_ctrl->actuator_mutex));
return rc;
}
@@ -352,6 +354,8 @@
CAM_ERR(CAM_ACTUATOR, "Device data is NULL");
return -EINVAL;
}
+
+ mutex_lock(&(a_ctrl->actuator_mutex));
if (link->link_enable) {
a_ctrl->bridge_intf.link_hdl = link->link_hdl;
a_ctrl->bridge_intf.crm_cb = link->crm_cb;
@@ -359,6 +363,7 @@
a_ctrl->bridge_intf.link_hdl = -1;
a_ctrl->bridge_intf.crm_cb = NULL;
}
+ mutex_unlock(&(a_ctrl->actuator_mutex));
return 0;
}
@@ -891,7 +896,9 @@
continue;
if (i2c_set->is_settings_valid == 1) {
+ mutex_lock(&(a_ctrl->actuator_mutex));
rc = delete_request(i2c_set);
+ mutex_unlock(&(a_ctrl->actuator_mutex));
if (rc < 0)
CAM_ERR(CAM_ACTUATOR,
"delete request: %lld rc: %d",
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
index 2e9aa6c..5179fae 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
@@ -21,19 +21,23 @@
#define SCM_SVC_CAMERASS 0x18
#define SECURE_SYSCALL_ID 0x6
+#define SECURE_SYSCALL_ID_2 0x7
+
static int csiphy_dump;
module_param(csiphy_dump, int, 0644);
-static int cam_csiphy_notify_secure_mode(int phy, bool protect)
+static int cam_csiphy_notify_secure_mode(struct csiphy_device *csiphy_dev,
+ bool protect, int32_t offset)
{
struct scm_desc desc = {0};
+ if (offset >= CSIPHY_MAX_INSTANCES)
+ return -EINVAL;
desc.arginfo = SCM_ARGS(2, SCM_VAL, SCM_VAL);
desc.args[0] = protect;
- desc.args[1] = phy;
+ desc.args[1] = csiphy_dev->csiphy_cpas_cp_reg_mask[offset];
- CAM_DBG(CAM_CSIPHY, "phy : %d, protect : %d", phy, protect);
- if (scm_call2(SCM_SIP_FNID(SCM_SVC_CAMERASS, SECURE_SYSCALL_ID),
+ if (scm_call2(SCM_SIP_FNID(SCM_SVC_CAMERASS, SECURE_SYSCALL_ID_2),
&desc)) {
CAM_ERR(CAM_CSIPHY, "scm call to hypervisor failed");
return -EINVAL;
@@ -42,6 +46,27 @@
return 0;
}
+static int32_t cam_csiphy_get_instance_offset(
+ struct csiphy_device *csiphy_dev,
+ int32_t dev_handle)
+{
+ int32_t i;
+
+ if (csiphy_dev->acquire_count >
+ CSIPHY_MAX_INSTANCES) {
+ CAM_ERR(CAM_CSIPHY, "Invalid acquire count");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < csiphy_dev->acquire_count; i++) {
+ if (dev_handle ==
+ csiphy_dev->bridge_intf.device_hdl[i])
+ break;
+ }
+
+ return i;
+}
+
void cam_csiphy_query_cap(struct csiphy_device *csiphy_dev,
struct cam_csiphy_query_cap *csiphy_cap)
{
@@ -75,6 +100,51 @@
}
}
+static int32_t cam_csiphy_update_secure_info(
+ struct csiphy_device *csiphy_dev,
+ struct cam_csiphy_info *cam_cmd_csiphy_info,
+ struct cam_config_dev_cmd *cfg_dev)
+{
+ uint32_t clock_lane, adj_lane_mask, temp;
+ int32_t offset;
+
+ if (csiphy_dev->acquire_count >=
+ CSIPHY_MAX_INSTANCES) {
+ CAM_ERR(CAM_CSIPHY, "Invalid acquire count");
+ return -EINVAL;
+ }
+
+ offset = cam_csiphy_get_instance_offset(csiphy_dev,
+ cfg_dev->dev_handle);
+ if (offset < 0 || offset >= CSIPHY_MAX_INSTANCES) {
+ CAM_ERR(CAM_CSIPHY, "Invalid offset");
+ return -EINVAL;
+ }
+
+ if (cam_cmd_csiphy_info->combo_mode)
+ clock_lane =
+ csiphy_dev->ctrl_reg->csiphy_reg.csiphy_combo_clk_lane;
+ else
+ clock_lane =
+ csiphy_dev->ctrl_reg->csiphy_reg.csiphy_clock_lane;
+
+ adj_lane_mask = cam_cmd_csiphy_info->lane_mask & 0x1F &
+ ~clock_lane;
+ temp = adj_lane_mask & (clock_lane - 1);
+ adj_lane_mask =
+ ((adj_lane_mask & (~((clock_lane - 1)))) >> 1) | temp;
+
+ csiphy_dev->csiphy_info.secure_mode[offset] = 1;
+
+ csiphy_dev->csiphy_cpas_cp_reg_mask[offset] =
+ adj_lane_mask << (csiphy_dev->soc_info.index *
+ (CAM_CSIPHY_MAX_DPHY_LANES + CAM_CSIPHY_MAX_CPHY_LANES) +
+ (!cam_cmd_csiphy_info->csiphy_3phase) *
+ (CAM_CSIPHY_MAX_CPHY_LANES));
+
+ return 0;
+}
+
int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev,
struct cam_config_dev_cmd *cfg_dev)
{
@@ -136,7 +206,10 @@
csiphy_dev->csiphy_info.settle_time =
cam_cmd_csiphy_info->settle_time;
csiphy_dev->csiphy_info.data_rate = cam_cmd_csiphy_info->data_rate;
- csiphy_dev->csiphy_info.secure_mode = cam_cmd_csiphy_info->secure_mode;
+
+ if (cam_cmd_csiphy_info->secure_mode == 1)
+ cam_csiphy_update_secure_info(csiphy_dev,
+ cam_cmd_csiphy_info, cfg_dev);
return rc;
}
@@ -330,8 +403,10 @@
CAM_DBG(CAM_CSIPHY, "Do Nothing");
break;
}
- usleep_range(reg_array[lane_pos][i].delay*1000,
- reg_array[lane_pos][i].delay*1000 + 1000);
+ if (reg_array[lane_pos][i].delay > 0) {
+ usleep_range(reg_array[lane_pos][i].delay*1000,
+ reg_array[lane_pos][i].delay*1000 + 10);
+ }
}
lane_mask >>= 1;
lane_pos++;
@@ -345,6 +420,7 @@
void cam_csiphy_shutdown(struct csiphy_device *csiphy_dev)
{
struct cam_hw_soc_info *soc_info;
+ int32_t i = 0;
if (csiphy_dev->csiphy_state == CAM_CSIPHY_INIT)
return;
@@ -352,13 +428,17 @@
if (csiphy_dev->csiphy_state == CAM_CSIPHY_START) {
soc_info = &csiphy_dev->soc_info;
- if (csiphy_dev->csiphy_info.secure_mode)
- cam_csiphy_notify_secure_mode(
- csiphy_dev->soc_info.index,
- CAM_SECURE_MODE_NON_SECURE);
+ for (i = 0; i < csiphy_dev->acquire_count; i++) {
+ if (csiphy_dev->csiphy_info.secure_mode[i])
+ cam_csiphy_notify_secure_mode(
+ csiphy_dev,
+ CAM_SECURE_MODE_NON_SECURE, i);
- csiphy_dev->csiphy_info.secure_mode =
- CAM_SECURE_MODE_NON_SECURE;
+ csiphy_dev->csiphy_info.secure_mode[i] =
+ CAM_SECURE_MODE_NON_SECURE;
+
+ csiphy_dev->csiphy_cpas_cp_reg_mask[i] = 0;
+ }
cam_csiphy_reset(csiphy_dev);
cam_soc_util_disable_platform_resource(soc_info, true, true);
@@ -549,6 +629,16 @@
}
break;
case CAM_STOP_DEV: {
+ int32_t offset, rc = 0;
+ struct cam_start_stop_dev_cmd config;
+
+ rc = copy_from_user(&config, (void __user *)cmd->handle,
+ sizeof(config));
+ if (rc < 0) {
+ CAM_ERR(CAM_CSIPHY, "Failed copying from User");
+ goto release_mutex;
+ }
+
if ((csiphy_dev->csiphy_state != CAM_CSIPHY_START) ||
!csiphy_dev->start_dev_count) {
CAM_ERR(CAM_CSIPHY, "Not in right state to stop : %d",
@@ -556,20 +646,38 @@
goto release_mutex;
}
- if (--csiphy_dev->start_dev_count) {
- CAM_DBG(CAM_CSIPHY, "Stop Dev ref Cnt: %d",
- csiphy_dev->start_dev_count);
+ offset = cam_csiphy_get_instance_offset(csiphy_dev,
+ config.dev_handle);
+ if (offset < 0 || offset >= CSIPHY_MAX_INSTANCES) {
+ CAM_ERR(CAM_CSIPHY, "Invalid offset");
goto release_mutex;
}
- if (csiphy_dev->csiphy_info.secure_mode)
- cam_csiphy_notify_secure_mode(
- csiphy_dev->soc_info.index,
- CAM_SECURE_MODE_NON_SECURE);
+ if (--csiphy_dev->start_dev_count) {
+ CAM_DBG(CAM_CSIPHY, "Stop Dev ref Cnt: %d",
+ csiphy_dev->start_dev_count);
+ if (csiphy_dev->csiphy_info.secure_mode[offset])
+ cam_csiphy_notify_secure_mode(
+ csiphy_dev,
+ CAM_SECURE_MODE_NON_SECURE, offset);
- csiphy_dev->csiphy_info.secure_mode =
+ csiphy_dev->csiphy_info.secure_mode[offset] =
+ CAM_SECURE_MODE_NON_SECURE;
+ csiphy_dev->csiphy_cpas_cp_reg_mask[offset] = 0;
+
+ goto release_mutex;
+ }
+
+ if (csiphy_dev->csiphy_info.secure_mode[offset])
+ cam_csiphy_notify_secure_mode(
+ csiphy_dev,
+ CAM_SECURE_MODE_NON_SECURE, offset);
+
+ csiphy_dev->csiphy_info.secure_mode[offset] =
CAM_SECURE_MODE_NON_SECURE;
+ csiphy_dev->csiphy_cpas_cp_reg_mask[offset] = 0x0;
+
rc = cam_csiphy_disable_hw(csiphy_dev);
if (rc < 0)
CAM_ERR(CAM_CSIPHY, "Failed in csiphy release");
@@ -643,12 +751,28 @@
case CAM_START_DEV: {
struct cam_ahb_vote ahb_vote;
struct cam_axi_vote axi_vote;
+ struct cam_start_stop_dev_cmd config;
+ int32_t offset;
+
+ rc = copy_from_user(&config, (void __user *)cmd->handle,
+ sizeof(config));
+ if (rc < 0) {
+ CAM_ERR(CAM_CSIPHY, "Failed copying from User");
+ goto release_mutex;
+ }
if (csiphy_dev->csiphy_state == CAM_CSIPHY_START) {
csiphy_dev->start_dev_count++;
goto release_mutex;
}
+ offset = cam_csiphy_get_instance_offset(csiphy_dev,
+ config.dev_handle);
+ if (offset < 0 || offset >= CSIPHY_MAX_INSTANCES) {
+ CAM_ERR(CAM_CSIPHY, "Invalid offset");
+ goto release_mutex;
+ }
+
ahb_vote.type = CAM_VOTE_ABSOLUTE;
ahb_vote.vote.level = CAM_SVS_VOTE;
axi_vote.compressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
@@ -661,12 +785,12 @@
goto release_mutex;
}
- if (csiphy_dev->csiphy_info.secure_mode) {
+ if (csiphy_dev->csiphy_info.secure_mode[offset] == 1) {
rc = cam_csiphy_notify_secure_mode(
- csiphy_dev->soc_info.index,
- CAM_SECURE_MODE_SECURE);
+ csiphy_dev,
+ CAM_SECURE_MODE_SECURE, offset);
if (rc < 0)
- csiphy_dev->csiphy_info.secure_mode =
+ csiphy_dev->csiphy_info.secure_mode[offset] =
CAM_SECURE_MODE_NON_SECURE;
}
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h
index 9c85af3..ac96255 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h
@@ -58,6 +58,11 @@
#define CSIPHY_SETTLE_CNT_HIGHER_BYTE 3
#define CSIPHY_DNP_PARAMS 4
+#define CSIPHY_MAX_INSTANCES 2
+
+#define CAM_CSIPHY_MAX_DPHY_LANES 4
+#define CAM_CSIPHY_MAX_CPHY_LANES 3
+
#define ENABLE_IRQ false
#undef CDBG
@@ -101,6 +106,12 @@
uint32_t csiphy_reset_array_size;
uint32_t csiphy_2ph_config_array_size;
uint32_t csiphy_3ph_config_array_size;
+ uint32_t csiphy_cpas_cp_bits_per_phy;
+ uint32_t csiphy_cpas_cp_is_interleaved;
+ uint32_t csiphy_cpas_cp_2ph_offset;
+ uint32_t csiphy_cpas_cp_3ph_offset;
+ uint32_t csiphy_clock_lane;
+ uint32_t csiphy_combo_clk_lane;
};
/**
@@ -111,9 +122,9 @@
* @crm_cb: Callback API pointers
*/
struct intf_params {
- int32_t device_hdl[2];
- int32_t session_hdl[2];
- int32_t link_hdl[2];
+ int32_t device_hdl[CSIPHY_MAX_INSTANCES];
+ int32_t session_hdl[CSIPHY_MAX_INSTANCES];
+ int32_t link_hdl[CSIPHY_MAX_INSTANCES];
struct cam_req_mgr_kmd_ops ops;
struct cam_req_mgr_crm_cb *crm_cb;
};
@@ -175,7 +186,7 @@
uint8_t csiphy_3phase;
uint8_t combo_mode;
uint8_t lane_cnt;
- uint8_t secure_mode;
+ uint8_t secure_mode[CSIPHY_MAX_INSTANCES];
uint64_t settle_time;
uint64_t settle_time_combo_sensor;
uint64_t data_rate;
@@ -231,6 +242,7 @@
struct cam_hw_soc_info soc_info;
uint32_t cpas_handle;
uint32_t config_count;
+ uint64_t csiphy_cpas_cp_reg_mask[CSIPHY_MAX_INSTANCES];
};
#endif /* _CAM_CSIPHY_DEV_H_ */
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_0_hwreg.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_0_hwreg.h
index 3245093..82cff27 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_0_hwreg.h
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_0_hwreg.h
@@ -23,6 +23,8 @@
.csiphy_reset_array_size = 5,
.csiphy_2ph_config_array_size = 14,
.csiphy_3ph_config_array_size = 19,
+ .csiphy_clock_lane = 0x1,
+ .csiphy_combo_clk_lane = 0x10,
};
struct csiphy_reg_t csiphy_common_reg_1_0[] = {
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c
index c8730ca..2e1b3cf 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c
@@ -31,7 +31,8 @@
{
int rc = 0;
int j;
- struct cam_sensor_i2c_reg_setting i2c_reg_settings;
+ struct cam_sensor_i2c_reg_setting i2c_reg_settings = {
+ NULL, 0, 0, 0, 0};
struct cam_sensor_i2c_reg_array i2c_reg_array;
struct cam_eeprom_memory_map_t *emap = block->map;
struct cam_eeprom_soc_private *eb_info;
@@ -221,7 +222,7 @@
CAM_ERR(CAM_EEPROM, "failed: power_info %pK", power_info);
return -EINVAL;
}
- rc = msm_camera_power_down(power_info, soc_info);
+ rc = cam_sensor_util_power_down(power_info, soc_info);
if (rc) {
CAM_ERR(CAM_EEPROM, "power down the core is failed:%d", rc);
return rc;
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_dev.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_dev.c
index cc34a70..6d8820a 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_dev.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_dev.c
@@ -261,9 +261,10 @@
for (i = 0; i < soc_info->num_clk; i++)
devm_clk_put(soc_info->dev, soc_info->clk[i]);
- if (soc_private)
- kfree(soc_private);
-
+ mutex_destroy(&(e_ctrl->eeprom_mutex));
+ kfree(soc_private);
+ kfree(e_ctrl->io_master_info.cci_client);
+ v4l2_set_subdevdata(&e_ctrl->v4l2_dev_str.sd, NULL);
kfree(e_ctrl);
return 0;
@@ -394,6 +395,8 @@
kfree(soc_private->power_info.gpio_num_info);
kfree(soc_private);
}
+ mutex_destroy(&(e_ctrl->eeprom_mutex));
+ v4l2_set_subdevdata(&e_ctrl->v4l2_dev_str.sd, NULL);
kfree(e_ctrl);
return 0;
@@ -489,8 +492,11 @@
for (i = 0; i < soc_info->num_clk; i++)
devm_clk_put(soc_info->dev, soc_info->clk[i]);
+ mutex_destroy(&(e_ctrl->eeprom_mutex));
kfree(soc_info->soc_private);
kfree(e_ctrl->io_master_info.cci_client);
+ platform_set_drvdata(pdev, NULL);
+ v4l2_set_subdevdata(&e_ctrl->v4l2_dev_str.sd, NULL);
kfree(e_ctrl);
return 0;
}
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/Makefile b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/Makefile
index c7889a5..4d1cbdc 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/Makefile
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/Makefile
@@ -1,10 +1,11 @@
-ccflags-y += -Idrivers/media/platform/msm/camera/cam_utils
-ccflags-y += -Idrivers/media/platform/msm/camera/cam_sync
-ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_res_mgr
-ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils
-ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io
-ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_cci
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_core
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_cpas/include
ccflags-y += -Idrivers/media/platform/msm/camera/cam_req_mgr
-ccflags-y += -Idrivers/media/platform/msm/camera/cam_smmu/
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_cci
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_res_mgr
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_smmu
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_utils
obj-$(CONFIG_SPECTRA_CAMERA) += cam_flash_dev.o cam_flash_core.o cam_flash_soc.o
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.c
index e997168..3040cdf 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.c
@@ -16,7 +16,7 @@
#include "cam_flash_core.h"
#include "cam_res_mgr_api.h"
-int cam_flash_prepare(struct cam_flash_ctrl *flash_ctrl,
+static int cam_flash_prepare(struct cam_flash_ctrl *flash_ctrl,
bool regulator_enable)
{
int rc = 0;
@@ -55,7 +55,7 @@
return rc;
}
-static int cam_flash_flush_nrt(struct cam_flash_ctrl *fctrl)
+static int cam_flash_pmic_flush_nrt(struct cam_flash_ctrl *fctrl)
{
int j = 0;
struct cam_flash_frame_setting *nrt_settings;
@@ -86,20 +86,187 @@
return 0;
}
-int cam_flash_flush_request(struct cam_req_mgr_flush_request *flush)
+static int cam_flash_i2c_flush_nrt(struct cam_flash_ctrl *fctrl)
+{
+ int rc = 0;
+
+ if (fctrl->i2c_data.init_settings.is_settings_valid == true) {
+ rc = delete_request(&fctrl->i2c_data.init_settings);
+ if (rc) {
+ CAM_WARN(CAM_FLASH,
+ "Failed to delete Init i2c_setting: %d",
+ rc);
+ return rc;
+ }
+ }
+ if (fctrl->i2c_data.config_settings.is_settings_valid == true) {
+ rc = delete_request(&fctrl->i2c_data.config_settings);
+ if (rc) {
+ CAM_WARN(CAM_FLASH,
+ "Failed to delete NRT i2c_setting: %d",
+ rc);
+ return rc;
+ }
+ }
+
+ return rc;
+}
+
+static int cam_flash_construct_default_power_setting(
+ struct cam_sensor_power_ctrl_t *power_info)
+{
+ int rc = 0;
+
+ power_info->power_setting_size = 1;
+ power_info->power_setting =
+ (struct cam_sensor_power_setting *)
+ kzalloc(sizeof(struct cam_sensor_power_setting),
+ GFP_KERNEL);
+ if (!power_info->power_setting)
+ return -ENOMEM;
+
+ power_info->power_setting[0].seq_type = SENSOR_CUSTOM_REG1;
+ power_info->power_setting[0].seq_val = CAM_V_CUSTOM1;
+ power_info->power_setting[0].config_val = 0;
+ power_info->power_setting[0].delay = 2;
+
+ power_info->power_down_setting_size = 1;
+ power_info->power_down_setting =
+ (struct cam_sensor_power_setting *)
+ kzalloc(sizeof(struct cam_sensor_power_setting),
+ GFP_KERNEL);
+ if (!power_info->power_down_setting) {
+ rc = -ENOMEM;
+ goto free_power_settings;
+ }
+
+ power_info->power_down_setting[0].seq_type = SENSOR_CUSTOM_REG1;
+ power_info->power_down_setting[0].seq_val = CAM_V_CUSTOM1;
+ power_info->power_down_setting[0].config_val = 0;
+
+ return rc;
+
+free_power_settings:
+ kfree(power_info->power_setting);
+ power_info->power_setting = NULL;
+ power_info->power_setting_size = 0;
+ return rc;
+}
+
+int cam_flash_pmic_power_ops(struct cam_flash_ctrl *fctrl,
+ bool regulator_enable)
+{
+ int rc = 0;
+
+ if (!(fctrl->switch_trigger)) {
+ CAM_ERR(CAM_FLASH, "Invalid argument");
+ return -EINVAL;
+ }
+
+ if (regulator_enable) {
+ rc = cam_flash_prepare(fctrl, true);
+ if (rc) {
+ CAM_ERR(CAM_FLASH,
+ "Enable Regulator Failed rc = %d", rc);
+ return rc;
+ }
+ }
+
+ if (!regulator_enable) {
+ if ((fctrl->flash_state == CAM_FLASH_STATE_START) &&
+ (fctrl->is_regulator_enabled == true)) {
+ rc = cam_flash_prepare(fctrl, false);
+ if (rc)
+ CAM_ERR(CAM_FLASH,
+ "Disable Regulator Failed rc: %d", rc);
+ }
+ }
+
+ return rc;
+}
+
+int cam_flash_i2c_power_ops(struct cam_flash_ctrl *fctrl,
+ bool regulator_enable)
+{
+ int rc = 0;
+ struct cam_hw_soc_info *soc_info = &fctrl->soc_info;
+ struct cam_sensor_power_ctrl_t *power_info =
+ &fctrl->power_info;
+
+ if (!power_info || !soc_info) {
+ CAM_ERR(CAM_FLASH, "Power Info is NULL");
+ return -EINVAL;
+ }
+ power_info->dev = soc_info->dev;
+
+ if (regulator_enable && (fctrl->is_regulator_enabled == false)) {
+ if ((power_info->power_setting == NULL) &&
+ (power_info->power_down_setting == NULL)) {
+ CAM_INFO(CAM_FLASH,
+ "Using default power settings");
+ rc = cam_flash_construct_default_power_setting(
+ power_info);
+ if (rc < 0) {
+ CAM_ERR(CAM_FLASH,
+ "Construct default pwr setting failed rc: %d",
+ rc);
+ return rc;
+ }
+ }
+
+ rc = cam_sensor_core_power_up(power_info, soc_info);
+ if (rc) {
+ CAM_ERR(CAM_FLASH, "power up the core is failed:%d",
+ rc);
+ goto free_pwr_settings;
+ }
+
+ rc = camera_io_init(&(fctrl->io_master_info));
+ if (rc) {
+ CAM_ERR(CAM_FLASH, "cci_init failed: rc: %d", rc);
+ cam_sensor_util_power_down(power_info, soc_info);
+ goto free_pwr_settings;
+ }
+ fctrl->is_regulator_enabled = true;
+ } else if ((!regulator_enable) &&
+ (fctrl->is_regulator_enabled == true)) {
+ rc = cam_sensor_util_power_down(power_info, soc_info);
+ if (rc) {
+ CAM_ERR(CAM_FLASH, "power down the core is failed:%d",
+ rc);
+ return rc;
+ }
+ camera_io_release(&(fctrl->io_master_info));
+ fctrl->is_regulator_enabled = false;
+ goto free_pwr_settings;
+ }
+ return rc;
+
+free_pwr_settings:
+ kfree(power_info->power_setting);
+ kfree(power_info->power_down_setting);
+ power_info->power_setting = NULL;
+ power_info->power_down_setting = NULL;
+ power_info->power_setting_size = 0;
+ power_info->power_down_setting_size = 0;
+
+ return rc;
+}
+
+int cam_flash_pmic_flush_request(struct cam_flash_ctrl *fctrl,
+ enum cam_flash_flush_type type, uint64_t req_id)
{
int rc = 0;
int i = 0, j = 0;
- struct cam_flash_ctrl *fctrl = NULL;
int frame_offset = 0;
- fctrl = (struct cam_flash_ctrl *) cam_get_device_priv(flush->dev_hdl);
if (!fctrl) {
CAM_ERR(CAM_FLASH, "Device data is NULL");
return -EINVAL;
}
- if (flush->type == CAM_REQ_MGR_FLUSH_TYPE_ALL) {
+ if (type == FLUSH_ALL) {
+ cam_flash_off(fctrl);
/* flush all requests*/
for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) {
fctrl->per_frame[i].cmn_attr.request_id = 0;
@@ -109,19 +276,105 @@
fctrl->per_frame[i].led_current_ma[j] = 0;
}
- rc = cam_flash_flush_nrt(fctrl);
- if (rc)
- CAM_ERR(CAM_FLASH, "NonRealTime flush error");
- } else if (flush->type == CAM_REQ_MGR_FLUSH_TYPE_CANCEL_REQ) {
+ cam_flash_pmic_flush_nrt(fctrl);
+ } else if ((type == FLUSH_REQ) && (req_id != 0)) {
/* flush request with req_id*/
- frame_offset = flush->req_id % MAX_PER_FRAME_ARRAY;
+ frame_offset = req_id % MAX_PER_FRAME_ARRAY;
fctrl->per_frame[frame_offset].cmn_attr.request_id = 0;
fctrl->per_frame[frame_offset].cmn_attr.is_settings_valid =
false;
fctrl->per_frame[frame_offset].cmn_attr.count = 0;
for (i = 0; i < CAM_FLASH_MAX_LED_TRIGGERS; i++)
fctrl->per_frame[frame_offset].led_current_ma[i] = 0;
+ } else if ((type == FLUSH_REQ) && (req_id == 0)) {
+ /* Handels NonRealTime usecase */
+ cam_flash_pmic_flush_nrt(fctrl);
+ } else {
+ CAM_ERR(CAM_FLASH, "Invalid arguments");
+ return -EINVAL;
}
+
+ return rc;
+}
+
+int cam_flash_i2c_flush_request(struct cam_flash_ctrl *fctrl,
+ enum cam_flash_flush_type type, uint64_t req_id)
+{
+ int rc = 0;
+ int i = 0;
+ uint32_t cancel_req_id_found = 0;
+ struct i2c_settings_array *i2c_set = NULL;
+
+ if (!fctrl) {
+ CAM_ERR(CAM_FLASH, "Device data is NULL");
+ return -EINVAL;
+ }
+ if ((type == FLUSH_REQ) && (req_id == 0)) {
+ /* This setting will be called only when NonRealTime
+ * settings needs to clean.
+ */
+ cam_flash_i2c_flush_nrt(fctrl);
+ } else {
+ /* All other usecase will be handle here */
+ for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) {
+ i2c_set = &(fctrl->i2c_data.per_frame[i]);
+
+ if ((type == FLUSH_REQ) &&
+ (i2c_set->request_id != req_id))
+ continue;
+
+ if (i2c_set->is_settings_valid == 1) {
+ rc = delete_request(i2c_set);
+ if (rc < 0)
+ CAM_ERR(CAM_FLASH,
+ "delete request: %lld rc: %d",
+ i2c_set->request_id, rc);
+
+ if (type == FLUSH_REQ) {
+ cancel_req_id_found = 1;
+ break;
+ }
+ }
+ }
+ }
+
+ if ((type == FLUSH_REQ) && (req_id != 0) &&
+ (!cancel_req_id_found))
+ CAM_DBG(CAM_FLASH,
+ "Flush request id:%lld not found in the pending list",
+ req_id);
+
+ return rc;
+}
+
+int cam_flash_flush_request(struct cam_req_mgr_flush_request *flush)
+{
+ int rc = 0;
+ struct cam_flash_ctrl *fctrl = NULL;
+
+ fctrl = (struct cam_flash_ctrl *) cam_get_device_priv(flush->dev_hdl);
+ if (!fctrl) {
+ CAM_ERR(CAM_FLASH, "Device data is NULL");
+ return -EINVAL;
+ }
+
+ mutex_lock(&fctrl->flash_mutex);
+ if (flush->type == CAM_REQ_MGR_FLUSH_TYPE_ALL) {
+ rc = fctrl->func_tbl.flush_req(fctrl, FLUSH_ALL, 0);
+ if (rc) {
+ CAM_ERR(CAM_FLASH, "FLUSH_TYPE_ALL failed rc: %d", rc);
+ goto end;
+ }
+ } else if (flush->type == CAM_REQ_MGR_FLUSH_TYPE_CANCEL_REQ) {
+ rc = fctrl->func_tbl.flush_req(fctrl,
+ FLUSH_REQ, flush->req_id);
+ if (rc) {
+ CAM_ERR(CAM_FLASH, "FLUSH_REQ failed rc: %d", rc);
+ goto end;
+ }
+ }
+end:
+ mutex_unlock(&fctrl->flash_mutex);
return rc;
}
@@ -254,26 +507,51 @@
return rc;
}
-static int delete_req(struct cam_flash_ctrl *fctrl, uint64_t req_id)
+static int cam_flash_i2c_delete_req(struct cam_flash_ctrl *fctrl,
+ uint64_t req_id)
+{
+ int i = 0, rc = 0;
+ uint64_t top = 0, del_req_id = 0;
+
+ if (req_id != 0) {
+ for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) {
+ if ((req_id >=
+ fctrl->i2c_data.per_frame[i].request_id) &&
+ (top <
+ fctrl->i2c_data.per_frame[i].request_id) &&
+ (fctrl->i2c_data.per_frame[i].is_settings_valid
+ == 1)) {
+ del_req_id = top;
+ top = fctrl->i2c_data.per_frame[i].request_id;
+ }
+ }
+
+ if (top < req_id) {
+ if ((((top % MAX_PER_FRAME_ARRAY) - (req_id %
+ MAX_PER_FRAME_ARRAY)) >= BATCH_SIZE_MAX) ||
+ (((top % MAX_PER_FRAME_ARRAY) - (req_id %
+ MAX_PER_FRAME_ARRAY)) <= -BATCH_SIZE_MAX))
+ del_req_id = req_id;
+ }
+
+ if (!del_req_id)
+ return rc;
+
+ CAM_DBG(CAM_FLASH, "top: %llu, del_req_id:%llu",
+ top, del_req_id);
+ }
+ fctrl->func_tbl.flush_req(fctrl, FLUSH_REQ, del_req_id);
+ return 0;
+}
+
+static int cam_flash_pmic_delete_req(struct cam_flash_ctrl *fctrl,
+ uint64_t req_id)
{
int i = 0;
struct cam_flash_frame_setting *flash_data = NULL;
uint64_t top = 0, del_req_id = 0;
- if (req_id == 0) {
- flash_data = &fctrl->nrt_info;
- if ((fctrl->nrt_info.cmn_attr.cmd_type ==
- CAMERA_SENSOR_FLASH_CMD_TYPE_WIDGET) ||
- (fctrl->nrt_info.cmn_attr.cmd_type ==
- CAMERA_SENSOR_FLASH_CMD_TYPE_RER)) {
- flash_data->cmn_attr.is_settings_valid = false;
- for (i = 0; i < flash_data->cmn_attr.count; i++)
- flash_data->led_current_ma[i] = 0;
- } else {
- fctrl->flash_init_setting.cmn_attr.is_settings_valid
- = false;
- }
- } else {
+ if (req_id != 0) {
for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) {
flash_data = &fctrl->per_frame[i];
if (req_id >= flash_data->cmn_attr.request_id &&
@@ -305,28 +583,100 @@
CAM_DBG(CAM_FLASH, "top: %llu, del_req_id:%llu",
top, del_req_id);
+ }
- for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) {
- flash_data = &fctrl->per_frame[i];
- if ((del_req_id ==
- flash_data->cmn_attr.request_id) &&
- (flash_data->cmn_attr.
- is_settings_valid == 1)) {
- CAM_DBG(CAM_FLASH, "Deleting request[%d] %llu",
- i, flash_data->cmn_attr.request_id);
- flash_data->cmn_attr.request_id = 0;
- flash_data->cmn_attr.is_settings_valid = false;
- flash_data->opcode = 0;
- for (i = 0; i < flash_data->cmn_attr.count; i++)
- flash_data->led_current_ma[i] = 0;
+ fctrl->func_tbl.flush_req(fctrl, FLUSH_REQ, del_req_id);
+ return 0;
+}
+
+static int32_t cam_flash_slaveInfo_pkt_parser(struct cam_flash_ctrl *fctrl,
+ uint32_t *cmd_buf)
+{
+ int32_t rc = 0;
+ struct cam_cmd_i2c_info *i2c_info = (struct cam_cmd_i2c_info *)cmd_buf;
+
+ if (fctrl->io_master_info.master_type == CCI_MASTER) {
+ fctrl->io_master_info.cci_client->cci_i2c_master =
+ fctrl->cci_i2c_master;
+ fctrl->io_master_info.cci_client->i2c_freq_mode =
+ i2c_info->i2c_freq_mode;
+ fctrl->io_master_info.cci_client->sid =
+ i2c_info->slave_addr >> 1;
+ CAM_DBG(CAM_FLASH, "Slave addr: 0x%x Freq Mode: %d",
+ i2c_info->slave_addr, i2c_info->i2c_freq_mode);
+ } else if (fctrl->io_master_info.master_type == I2C_MASTER) {
+ fctrl->io_master_info.client->addr = i2c_info->slave_addr;
+ CAM_DBG(CAM_FLASH, "Slave addr: 0x%x", i2c_info->slave_addr);
+ } else {
+ CAM_ERR(CAM_FLASH, "Invalid Master type: %d",
+ fctrl->io_master_info.master_type);
+ rc = -EINVAL;
+ }
+
+ return rc;
+}
+
+int cam_flash_i2c_apply_setting(struct cam_flash_ctrl *fctrl,
+ uint64_t req_id)
+{
+ struct i2c_settings_list *i2c_list;
+ struct i2c_settings_array *i2c_set = NULL;
+ int frame_offset = 0, rc = 0;
+
+ if (req_id == 0) {
+ /* NonRealTime Init settings*/
+ if (fctrl->i2c_data.init_settings.is_settings_valid == true) {
+ list_for_each_entry(i2c_list,
+ &(fctrl->i2c_data.init_settings.list_head),
+ list) {
+ rc = cam_sensor_util_i2c_apply_setting
+ (&(fctrl->io_master_info), i2c_list);
+ if (rc) {
+ CAM_ERR(CAM_FLASH,
+ "Failed to apply init settings: %d",
+ rc);
+ return rc;
+ }
+ }
+ }
+ /* NonRealTime (Widget/RER/INIT_FIRE settings) */
+ if (fctrl->i2c_data.config_settings.is_settings_valid == true) {
+ list_for_each_entry(i2c_list,
+ &(fctrl->i2c_data.config_settings.list_head),
+ list) {
+ rc = cam_sensor_util_i2c_apply_setting
+ (&(fctrl->io_master_info), i2c_list);
+ if (rc) {
+ CAM_ERR(CAM_FLASH,
+ "Failed to apply NRT settings: %d", rc);
+ return rc;
+ }
+ }
+ }
+ } else {
+ /* RealTime */
+ frame_offset = req_id % MAX_PER_FRAME_ARRAY;
+ i2c_set = &fctrl->i2c_data.per_frame[frame_offset];
+ if ((i2c_set->is_settings_valid == true) &&
+ (i2c_set->request_id == req_id)) {
+ list_for_each_entry(i2c_list,
+ &(i2c_set->list_head), list) {
+ rc = cam_sensor_util_i2c_apply_setting(
+ &(fctrl->io_master_info), i2c_list);
+ if (rc) {
+ CAM_ERR(CAM_FLASH,
+ "Failed to apply settings: %d", rc);
+ return rc;
+ }
}
}
}
- return 0;
+ cam_flash_i2c_delete_req(fctrl, req_id);
+ return rc;
}
-int cam_flash_apply_setting(struct cam_flash_ctrl *fctrl,
+int cam_flash_pmic_apply_setting(struct cam_flash_ctrl *fctrl,
uint64_t req_id)
{
int rc = 0, i = 0;
@@ -344,12 +694,12 @@
if (flash_data->opcode ==
CAMERA_SENSOR_FLASH_OP_FIREHIGH) {
- if (fctrl->flash_state !=
- CAM_FLASH_STATE_CONFIG) {
+ if (fctrl->flash_state ==
+ CAM_FLASH_STATE_START) {
CAM_WARN(CAM_FLASH,
- "Cannot apply Start Dev:Prev state: %d",
+ "Wrong state :Prev state: %d",
fctrl->flash_state);
- return rc;
+ return -EINVAL;
}
rc = cam_flash_prepare(fctrl, true);
if (rc) {
@@ -360,8 +710,27 @@
rc = cam_flash_high(fctrl, flash_data);
if (rc)
CAM_ERR(CAM_FLASH,
- "FLASH ON failed : %d",
- rc);
+ "FLASH ON failed : %d", rc);
+ }
+ if (flash_data->opcode ==
+ CAMERA_SENSOR_FLASH_OP_FIRELOW) {
+ if (fctrl->flash_state ==
+ CAM_FLASH_STATE_START) {
+ CAM_WARN(CAM_FLASH,
+ "Wrong state :Prev state: %d",
+ fctrl->flash_state);
+ return -EINVAL;
+ }
+ rc = cam_flash_prepare(fctrl, true);
+ if (rc) {
+ CAM_ERR(CAM_FLASH,
+ "Enable Regulator Failed rc = %d", rc);
+ return rc;
+ }
+ rc = cam_flash_low(fctrl, flash_data);
+ if (rc)
+ CAM_ERR(CAM_FLASH,
+ "TORCH ON failed : %d", rc);
}
if (flash_data->opcode ==
CAMERA_SENSOR_FLASH_OP_OFF) {
@@ -409,7 +778,6 @@
} else if (fctrl->nrt_info.cmn_attr.cmd_type ==
CAMERA_SENSOR_FLASH_CMD_TYPE_RER) {
flash_data = &fctrl->nrt_info;
-
if (fctrl->flash_state != CAM_FLASH_STATE_START) {
rc = cam_flash_off(fctrl);
if (rc) {
@@ -442,8 +810,7 @@
rc = cam_flash_off(fctrl);
if (rc) {
CAM_ERR(CAM_FLASH,
- "Flash off failed: %d",
- rc);
+ "Flash off failed: %d", rc);
continue;
}
fctrl->flash_state = CAM_FLASH_STATE_START;
@@ -505,12 +872,321 @@
}
nrt_del_req:
- delete_req(fctrl, req_id);
+ cam_flash_pmic_delete_req(fctrl, req_id);
apply_setting_err:
return rc;
}
-int cam_flash_parser(struct cam_flash_ctrl *fctrl, void *arg)
+int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
+{
+ int rc = 0, i = 0;
+ uint64_t generic_ptr;
+ uint32_t total_cmd_buf_in_bytes = 0;
+ uint32_t processed_cmd_buf_in_bytes = 0;
+ uint16_t cmd_length_in_bytes = 0;
+ uint32_t *cmd_buf = NULL;
+ uint32_t *offset = NULL;
+ uint32_t frm_offset = 0;
+ size_t len_of_buffer;
+ struct cam_flash_init *flash_init = NULL;
+ struct common_header *cmn_hdr = NULL;
+ struct cam_control *ioctl_ctrl = NULL;
+ struct cam_packet *csl_packet = NULL;
+ struct cam_cmd_buf_desc *cmd_desc = NULL;
+ struct cam_config_dev_cmd config;
+ struct cam_req_mgr_add_request add_req;
+ struct i2c_data_settings *i2c_data = NULL;
+ struct i2c_settings_array *i2c_reg_settings = NULL;
+ struct cam_sensor_power_ctrl_t *power_info = NULL;
+
+ if (!fctrl || !arg) {
+ CAM_ERR(CAM_FLASH, "fctrl/arg is NULL");
+ return -EINVAL;
+ }
+ /* getting CSL Packet */
+ ioctl_ctrl = (struct cam_control *)arg;
+
+ if (copy_from_user((&config), (void __user *) ioctl_ctrl->handle,
+ sizeof(config))) {
+ CAM_ERR(CAM_FLASH, "Copy cmd handle from user failed");
+ return -EFAULT;
+ }
+
+ rc = cam_mem_get_cpu_buf(config.packet_handle,
+ (uint64_t *)&generic_ptr, &len_of_buffer);
+ if (rc) {
+ CAM_ERR(CAM_FLASH, "Failed in getting the buffer : %d", rc);
+ return rc;
+ }
+
+ if (config.offset > len_of_buffer) {
+ CAM_ERR(CAM_FLASH,
+ "offset is out of bounds: offset: %lld len: %zu",
+ config.offset, len_of_buffer);
+ return -EINVAL;
+ }
+
+ /* Add offset to the flash csl header */
+ csl_packet = (struct cam_packet *)(generic_ptr + config.offset);
+ switch (csl_packet->header.op_code & 0xFFFFFF) {
+ case CAM_FLASH_PACKET_OPCODE_INIT: {
+ /* INIT packet*/
+ offset = (uint32_t *)((uint8_t *)&csl_packet->payload +
+ csl_packet->cmd_buf_offset);
+ cmd_desc = (struct cam_cmd_buf_desc *)(offset);
+
+ /* Loop through multiple command buffers */
+ for (i = 1; i < csl_packet->num_cmd_buf; i++) {
+ total_cmd_buf_in_bytes = cmd_desc[i].length;
+ processed_cmd_buf_in_bytes = 0;
+ if (!total_cmd_buf_in_bytes)
+ continue;
+ rc = cam_mem_get_cpu_buf(cmd_desc[i].mem_handle,
+ (uint64_t *)&generic_ptr, &len_of_buffer);
+ if (rc < 0) {
+ CAM_ERR(CAM_FLASH, "Failed to get cpu buf");
+ return rc;
+ }
+ cmd_buf = (uint32_t *)generic_ptr;
+ if (!cmd_buf) {
+ CAM_ERR(CAM_FLASH, "invalid cmd buf");
+ return -EINVAL;
+ }
+ cmd_buf += cmd_desc[i].offset / sizeof(uint32_t);
+ cmn_hdr = (struct common_header *)cmd_buf;
+
+ /* Loop through cmd formats in one cmd buffer */
+ CAM_DBG(CAM_FLASH,
+ "command Type: %d,Processed: %d,Total: %d",
+ cmn_hdr->cmd_type, processed_cmd_buf_in_bytes,
+ total_cmd_buf_in_bytes);
+ switch (cmn_hdr->cmd_type) {
+ case CAMERA_SENSOR_FLASH_CMD_TYPE_INIT_INFO:
+ flash_init = (struct cam_flash_init *)cmd_buf;
+ fctrl->flash_type = flash_init->flash_type;
+ cmd_length_in_bytes =
+ sizeof(struct cam_flash_init);
+ processed_cmd_buf_in_bytes +=
+ cmd_length_in_bytes;
+ cmd_buf += cmd_length_in_bytes/
+ sizeof(uint32_t);
+ break;
+ case CAMERA_SENSOR_CMD_TYPE_I2C_INFO:
+ rc = cam_flash_slaveInfo_pkt_parser(
+ fctrl, cmd_buf);
+ if (rc < 0) {
+ CAM_ERR(CAM_FLASH,
+ "Failed parsing slave info: rc: %d",
+ rc);
+ return rc;
+ }
+ cmd_length_in_bytes =
+ sizeof(struct cam_cmd_i2c_info);
+ processed_cmd_buf_in_bytes +=
+ cmd_length_in_bytes;
+ cmd_buf += cmd_length_in_bytes/
+ sizeof(uint32_t);
+ break;
+ case CAMERA_SENSOR_CMD_TYPE_PWR_UP:
+ case CAMERA_SENSOR_CMD_TYPE_PWR_DOWN:
+ CAM_DBG(CAM_FLASH,
+ "Received power settings");
+ cmd_length_in_bytes =
+ total_cmd_buf_in_bytes;
+ rc = cam_sensor_update_power_settings(
+ cmd_buf,
+ total_cmd_buf_in_bytes,
+ &fctrl->power_info);
+ processed_cmd_buf_in_bytes +=
+ cmd_length_in_bytes;
+ cmd_buf += cmd_length_in_bytes/
+ sizeof(uint32_t);
+ if (rc) {
+ CAM_ERR(CAM_FLASH,
+ "Failed update power settings");
+ return rc;
+ }
+ break;
+ default:
+ CAM_DBG(CAM_FLASH,
+ "Received initSettings");
+ i2c_data = &(fctrl->i2c_data);
+ i2c_reg_settings =
+ &fctrl->i2c_data.init_settings;
+
+ i2c_reg_settings->request_id = 0;
+ i2c_reg_settings->is_settings_valid = 1;
+ rc = cam_sensor_i2c_command_parser(
+ &fctrl->io_master_info,
+ i2c_reg_settings,
+ &cmd_desc[i], 1);
+ if (rc < 0) {
+ CAM_ERR(CAM_FLASH,
+ "pkt parsing failed: %d", rc);
+ return rc;
+ }
+ cmd_length_in_bytes =
+ cmd_desc[i].length;
+ processed_cmd_buf_in_bytes +=
+ cmd_length_in_bytes;
+ cmd_buf += cmd_length_in_bytes/
+ sizeof(uint32_t);
+
+ break;
+ }
+ }
+ power_info = &fctrl->power_info;
+ if (!power_info) {
+ CAM_ERR(CAM_FLASH, "Power_info is NULL");
+ return -EINVAL;
+ }
+
+ /* Parse and fill vreg params for power up settings */
+ rc = msm_camera_fill_vreg_params(&fctrl->soc_info,
+ power_info->power_setting,
+ power_info->power_setting_size);
+ if (rc) {
+ CAM_ERR(CAM_FLASH,
+ "failed to fill vreg params for power up rc:%d",
+ rc);
+ return rc;
+ }
+
+ /* Parse and fill vreg params for power down settings*/
+ rc = msm_camera_fill_vreg_params(
+ &fctrl->soc_info,
+ power_info->power_down_setting,
+ power_info->power_down_setting_size);
+ if (rc) {
+ CAM_ERR(CAM_FLASH,
+ "failed to fill vreg params power down rc:%d",
+ rc);
+ return rc;
+ }
+
+ rc = fctrl->func_tbl.power_ops(fctrl, true);
+ if (rc) {
+ CAM_ERR(CAM_FLASH,
+ "Enable Regulator Failed rc = %d", rc);
+ return rc;
+ }
+
+ rc = fctrl->func_tbl.apply_setting(fctrl, 0);
+ if (rc) {
+ CAM_ERR(CAM_FLASH, "cannot apply settings rc = %d", rc);
+ return rc;
+ }
+
+ fctrl->flash_state = CAM_FLASH_STATE_CONFIG;
+ break;
+ }
+ case CAM_FLASH_PACKET_OPCODE_SET_OPS: {
+ offset = (uint32_t *)((uint8_t *)&csl_packet->payload +
+ csl_packet->cmd_buf_offset);
+ frm_offset = csl_packet->header.request_id %
+ MAX_PER_FRAME_ARRAY;
+ /* add support for handling i2c_data*/
+ i2c_reg_settings =
+ &fctrl->i2c_data.per_frame[frm_offset];
+ if (i2c_reg_settings->is_settings_valid == true) {
+ i2c_reg_settings->request_id = 0;
+ i2c_reg_settings->is_settings_valid = false;
+ goto update_req_mgr;
+ }
+ i2c_reg_settings->is_settings_valid = true;
+ i2c_reg_settings->request_id =
+ csl_packet->header.request_id;
+ cmd_desc = (struct cam_cmd_buf_desc *)(offset);
+ rc = cam_sensor_i2c_command_parser(
+ &fctrl->io_master_info,
+ i2c_reg_settings, cmd_desc, 1);
+ if (rc) {
+ CAM_ERR(CAM_FLASH,
+ "Failed in parsing i2c packets");
+ return rc;
+ }
+ break;
+ }
+ case CAM_FLASH_PACKET_OPCODE_NON_REALTIME_SET_OPS: {
+ offset = (uint32_t *)((uint8_t *)&csl_packet->payload +
+ csl_packet->cmd_buf_offset);
+
+ /* add support for handling i2c_data*/
+ i2c_reg_settings = &fctrl->i2c_data.config_settings;
+ if (i2c_reg_settings->is_settings_valid == true) {
+ i2c_reg_settings->request_id = 0;
+ i2c_reg_settings->is_settings_valid = false;
+
+ rc = delete_request(i2c_reg_settings);
+ if (rc) {
+ CAM_ERR(CAM_FLASH,
+ "Failed in Deleting the err: %d", rc);
+ return rc;
+ }
+ }
+ i2c_reg_settings->is_settings_valid = true;
+ i2c_reg_settings->request_id =
+ csl_packet->header.request_id;
+ cmd_desc = (struct cam_cmd_buf_desc *)(offset);
+ rc = cam_sensor_i2c_command_parser(
+ &fctrl->io_master_info,
+ i2c_reg_settings, cmd_desc, 1);
+ if (rc) {
+ CAM_ERR(CAM_FLASH,
+ "Failed in parsing i2c NRT packets");
+ return rc;
+ }
+ rc = fctrl->func_tbl.apply_setting(fctrl, 0);
+ if (rc)
+ CAM_ERR(CAM_FLASH,
+ "Apply setting failed: %d", rc);
+ return rc;
+ }
+ case CAM_PKT_NOP_OPCODE: {
+ if ((fctrl->flash_state == CAM_FLASH_STATE_INIT) ||
+ (fctrl->flash_state == CAM_FLASH_STATE_ACQUIRE)) {
+ CAM_WARN(CAM_FLASH,
+ "Rxed NOP packets without linking");
+ frm_offset = csl_packet->header.request_id %
+ MAX_PER_FRAME_ARRAY;
+ fctrl->i2c_data.per_frame[frm_offset].is_settings_valid
+ = false;
+ return 0;
+ }
+
+ CAM_DBG(CAM_FLASH, "NOP Packet is Received: req_id: %u",
+ csl_packet->header.request_id);
+ goto update_req_mgr;
+ }
+ default:
+ CAM_ERR(CAM_FLASH, "Wrong Opcode : %d",
+ (csl_packet->header.op_code & 0xFFFFFF));
+ return -EINVAL;
+ }
+update_req_mgr:
+ if (((csl_packet->header.op_code & 0xFFFFF) ==
+ CAM_PKT_NOP_OPCODE) ||
+ ((csl_packet->header.op_code & 0xFFFFF) ==
+ CAM_FLASH_PACKET_OPCODE_SET_OPS)) {
+ add_req.link_hdl = fctrl->bridge_intf.link_hdl;
+ add_req.req_id = csl_packet->header.request_id;
+ add_req.dev_hdl = fctrl->bridge_intf.device_hdl;
+
+ if ((csl_packet->header.op_code & 0xFFFFF) ==
+ CAM_FLASH_PACKET_OPCODE_SET_OPS)
+ add_req.skip_before_applying = 1;
+ else
+ add_req.skip_before_applying = 0;
+
+ if (fctrl->bridge_intf.crm_cb &&
+ fctrl->bridge_intf.crm_cb->add_req)
+ fctrl->bridge_intf.crm_cb->add_req(&add_req);
+ CAM_DBG(CAM_FLASH, "add req to req_mgr= %lld", add_req.req_id);
+ }
+ return rc;
+}
+
+int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
{
int rc = 0, i = 0;
uint64_t generic_ptr;
@@ -566,8 +1242,6 @@
/* INIT packet*/
offset = (uint32_t *)((uint8_t *)&csl_packet->payload +
csl_packet->cmd_buf_offset);
- fctrl->flash_init_setting.cmn_attr.request_id = 0;
- fctrl->flash_init_setting.cmn_attr.is_settings_valid = true;
cmd_desc = (struct cam_cmd_buf_desc *)(offset);
rc = cam_mem_get_cpu_buf(cmd_desc->mem_handle,
(uint64_t *)&generic_ptr, &len_of_buffer);
@@ -576,40 +1250,53 @@
cam_flash_info = (struct cam_flash_init *)cmd_buf;
switch (cam_flash_info->cmd_type) {
- case CAMERA_SENSOR_FLASH_CMD_TYPE_INIT_INFO:
+ case CAMERA_SENSOR_FLASH_CMD_TYPE_INIT_INFO: {
+ CAM_DBG(CAM_FLASH, "INIT_INFO CMD CALLED");
+ fctrl->flash_init_setting.cmn_attr.request_id = 0;
+ fctrl->flash_init_setting.cmn_attr.is_settings_valid =
+ true;
fctrl->flash_type = cam_flash_info->flash_type;
fctrl->is_regulator_enabled = false;
fctrl->nrt_info.cmn_attr.cmd_type =
CAMERA_SENSOR_FLASH_CMD_TYPE_INIT_INFO;
+
+ rc = fctrl->func_tbl.power_ops(fctrl, true);
+ if (rc) {
+ CAM_ERR(CAM_FLASH,
+ "Enable Regulator Failed rc = %d", rc);
+ return rc;
+ }
+
fctrl->flash_state =
CAM_FLASH_STATE_CONFIG;
break;
- case CAMERA_SENSOR_FLASH_CMD_TYPE_INIT_FIRE:
- CAM_DBG(CAM_FLASH, "Widget Flash Operation");
- flash_operation_info =
- (struct cam_flash_set_on_off *) cmd_buf;
- fctrl->nrt_info.cmn_attr.count =
- flash_operation_info->count;
- fctrl->nrt_info.cmn_attr.request_id = 0;
- fctrl->nrt_info.opcode =
- flash_operation_info->opcode;
- fctrl->nrt_info.cmn_attr.cmd_type =
- CAMERA_SENSOR_FLASH_CMD_TYPE_INIT_FIRE;
- for (i = 0;
- i < flash_operation_info->count; i++)
- fctrl->nrt_info.led_current_ma[i] =
- flash_operation_info->led_current_ma[i];
+ }
+ case CAMERA_SENSOR_FLASH_CMD_TYPE_INIT_FIRE: {
+ CAM_DBG(CAM_FLASH, "INIT_FIRE Operation");
- mutex_lock(&fctrl->flash_wq_mutex);
- rc = cam_flash_apply_setting(fctrl, 0);
- if (rc)
- CAM_ERR(CAM_FLASH,
- "Apply setting failed: %d",
- rc);
- mutex_unlock(&fctrl->flash_wq_mutex);
- fctrl->flash_state =
- CAM_FLASH_STATE_CONFIG;
+ flash_operation_info =
+ (struct cam_flash_set_on_off *) cmd_buf;
+ fctrl->nrt_info.cmn_attr.count =
+ flash_operation_info->count;
+ fctrl->nrt_info.cmn_attr.request_id = 0;
+ fctrl->nrt_info.opcode =
+ flash_operation_info->opcode;
+ fctrl->nrt_info.cmn_attr.cmd_type =
+ CAMERA_SENSOR_FLASH_CMD_TYPE_INIT_FIRE;
+ for (i = 0;
+ i < flash_operation_info->count; i++)
+ fctrl->nrt_info.led_current_ma[i] =
+ flash_operation_info->led_current_ma[i];
+
+ rc = fctrl->func_tbl.apply_setting(fctrl, 0);
+ if (rc)
+ CAM_ERR(CAM_FLASH,
+ "Apply setting failed: %d",
+ rc);
+
+ fctrl->flash_state = CAM_FLASH_STATE_CONFIG;
break;
+ }
default:
CAM_ERR(CAM_FLASH, "Wrong cmd_type = %d",
cam_flash_info->cmd_type);
@@ -647,7 +1334,7 @@
switch (cmn_hdr->cmd_type) {
case CAMERA_SENSOR_FLASH_CMD_TYPE_FIRE: {
CAM_DBG(CAM_FLASH,
- "CAMERA_FLASH_CMD_TYPE_OPS case called");
+ "CAMERA_SENSOR_FLASH_CMD_TYPE_FIRE cmd called");
if ((fctrl->flash_state == CAM_FLASH_STATE_INIT) ||
(fctrl->flash_state ==
CAM_FLASH_STATE_ACQUIRE)) {
@@ -671,8 +1358,8 @@
for (i = 0; i < flash_operation_info->count; i++)
flash_data->led_current_ma[i]
= flash_operation_info->led_current_ma[i];
- }
- break;
+ }
+ break;
default:
CAM_ERR(CAM_FLASH, "Wrong cmd_type = %d",
cmn_hdr->cmd_type);
@@ -708,12 +1395,10 @@
fctrl->nrt_info.led_current_ma[i] =
flash_operation_info->led_current_ma[i];
- mutex_lock(&fctrl->flash_wq_mutex);
- rc = cam_flash_apply_setting(fctrl, 0);
+ rc = fctrl->func_tbl.apply_setting(fctrl, 0);
if (rc)
CAM_ERR(CAM_FLASH, "Apply setting failed: %d",
rc);
- mutex_unlock(&fctrl->flash_wq_mutex);
return rc;
}
case CAMERA_SENSOR_FLASH_CMD_TYPE_QUERYCURR: {
@@ -754,12 +1439,10 @@
flash_rer_info->led_current_ma[i];
- mutex_lock(&fctrl->flash_wq_mutex);
- rc = cam_flash_apply_setting(fctrl, 0);
+ rc = fctrl->func_tbl.apply_setting(fctrl, 0);
if (rc)
CAM_ERR(CAM_FLASH, "apply_setting failed: %d",
rc);
- mutex_unlock(&fctrl->flash_wq_mutex);
return rc;
}
default:
@@ -767,7 +1450,6 @@
cmn_hdr->cmd_type);
return -EINVAL;
}
-
break;
}
case CAM_PKT_NOP_OPCODE: {
@@ -785,7 +1467,7 @@
fctrl->per_frame[frm_offset].cmn_attr.is_settings_valid = false;
fctrl->per_frame[frm_offset].cmn_attr.request_id = 0;
fctrl->per_frame[frm_offset].opcode = CAM_PKT_NOP_OPCODE;
- CAM_DBG(CAM_FLASH, "NOP Packet is Received: req_id: %u",
+ CAM_DBG(CAM_FLASH, "NOP Packet is Received: req_id: %llu",
csl_packet->header.request_id);
goto update_req_mgr;
}
@@ -839,7 +1521,7 @@
CAM_ERR(CAM_FLASH, " Device data is NULL");
return -EINVAL;
}
-
+ mutex_lock(&fctrl->flash_mutex);
if (link->link_enable) {
fctrl->bridge_intf.link_hdl = link->link_hdl;
fctrl->bridge_intf.crm_cb = link->crm_cb;
@@ -847,43 +1529,11 @@
fctrl->bridge_intf.link_hdl = -1;
fctrl->bridge_intf.crm_cb = NULL;
}
+ mutex_unlock(&fctrl->flash_mutex);
return 0;
}
-
-int cam_flash_stop_dev(struct cam_flash_ctrl *fctrl)
-{
- int rc = 0, i, j;
-
- cam_flash_off(fctrl);
-
- for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) {
- fctrl->per_frame[i].cmn_attr.request_id = 0;
- fctrl->per_frame[i].cmn_attr.is_settings_valid = false;
- fctrl->per_frame[i].cmn_attr.count = 0;
- for (j = 0; j < CAM_FLASH_MAX_LED_TRIGGERS; j++)
- fctrl->per_frame[i].led_current_ma[j] = 0;
- }
-
- rc = cam_flash_flush_nrt(fctrl);
- if (rc) {
- CAM_ERR(CAM_FLASH,
- "NonRealTime Dev flush failed rc: %d", rc);
- return rc;
- }
-
- if ((fctrl->flash_state == CAM_FLASH_STATE_START) &&
- (fctrl->is_regulator_enabled == true)) {
- rc = cam_flash_prepare(fctrl, false);
- if (rc)
- CAM_ERR(CAM_FLASH, "Disable Regulator Failed rc: %d",
- rc);
- }
-
- return rc;
-}
-
int cam_flash_release_dev(struct cam_flash_ctrl *fctrl)
{
int rc = 0;
@@ -911,9 +1561,13 @@
if ((fctrl->flash_state == CAM_FLASH_STATE_CONFIG) ||
(fctrl->flash_state == CAM_FLASH_STATE_START)) {
- rc = cam_flash_stop_dev(fctrl);
+ mutex_lock(&(fctrl->flash_mutex));
+ fctrl->func_tbl.flush_req(fctrl, FLUSH_ALL, 0);
+ mutex_unlock(&(fctrl->flash_mutex));
+ rc = fctrl->func_tbl.power_ops(fctrl, false);
if (rc)
- CAM_ERR(CAM_FLASH, "Stop Failed rc: %d", rc);
+ CAM_ERR(CAM_FLASH, "Power Down Failed rc: %d",
+ rc);
}
rc = cam_flash_release_dev(fctrl);
@@ -937,12 +1591,12 @@
return -EINVAL;
}
- mutex_lock(&fctrl->flash_wq_mutex);
- rc = cam_flash_apply_setting(fctrl, apply->request_id);
+ mutex_lock(&fctrl->flash_mutex);
+ rc = fctrl->func_tbl.apply_setting(fctrl, apply->request_id);
if (rc)
CAM_ERR(CAM_FLASH, "apply_setting failed with rc=%d",
rc);
- mutex_unlock(&fctrl->flash_wq_mutex);
+ mutex_unlock(&fctrl->flash_mutex);
return rc;
}
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.h
index f73409a..1bd3b31 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.h
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -16,20 +16,12 @@
#include <linux/leds-qpnp-flash.h>
#include <media/cam_sensor.h>
#include "cam_flash_dev.h"
-#include "cam_sync_api.h"
-#include "cam_mem_mgr_api.h"
-int cam_flash_parser(struct cam_flash_ctrl *fctrl, void *arg);
int cam_flash_publish_dev_info(struct cam_req_mgr_device_info *info);
int cam_flash_establish_link(struct cam_req_mgr_core_dev_link_setup *link);
-int cam_flash_apply_setting(struct cam_flash_ctrl *fctrl, uint64_t req_id);
int cam_flash_apply_request(struct cam_req_mgr_apply_request *apply);
int cam_flash_process_evt(struct cam_req_mgr_link_evt_data *event_data);
int cam_flash_flush_request(struct cam_req_mgr_flush_request *flush);
-int cam_flash_off(struct cam_flash_ctrl *fctrl);
-int cam_flash_prepare(struct cam_flash_ctrl *flash_ctrl,
- bool regulator_enable);
-void cam_flash_shutdown(struct cam_flash_ctrl *flash_ctrl);
-int cam_flash_stop_dev(struct cam_flash_ctrl *flash_ctrl);
-int cam_flash_release_dev(struct cam_flash_ctrl *fctrl);
+
+
#endif /*_CAM_FLASH_CORE_H_*/
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.c
index d9b5f64..199b505 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.c
@@ -93,7 +93,7 @@
if ((fctrl->flash_state == CAM_FLASH_STATE_INIT) ||
(fctrl->flash_state == CAM_FLASH_STATE_START)) {
CAM_WARN(CAM_FLASH,
- "Cannot apply Release dev: Prev state:%d",
+ "Wrong state for Release dev: Prev state:%d",
fctrl->flash_state);
}
@@ -106,11 +106,18 @@
rc = -EINVAL;
goto release_mutex;
}
- rc = cam_flash_release_dev(fctrl);
- if (rc)
- CAM_ERR(CAM_FLASH,
- "Failed in destroying the device Handle rc= %d",
- rc);
+
+ if ((fctrl->flash_state == CAM_FLASH_STATE_CONFIG) ||
+ (fctrl->flash_state == CAM_FLASH_STATE_START))
+ fctrl->func_tbl.flush_req(fctrl, FLUSH_ALL, 0);
+
+ if (cam_flash_release_dev(fctrl))
+ CAM_WARN(CAM_FLASH,
+ "Failed in destroying the device Handle");
+
+ if (fctrl->func_tbl.power_ops(fctrl, false))
+ CAM_WARN(CAM_FLASH, "Power Down Failed");
+
fctrl->flash_state = CAM_FLASH_STATE_INIT;
break;
}
@@ -149,17 +156,6 @@
goto release_mutex;
}
- rc = cam_flash_prepare(fctrl, true);
- if (rc) {
- CAM_ERR(CAM_FLASH,
- "Enable Regulator Failed rc = %d", rc);
- goto release_mutex;
- }
- rc = cam_flash_apply_setting(fctrl, 0);
- if (rc) {
- CAM_ERR(CAM_FLASH, "cannot apply settings rc = %d", rc);
- goto release_mutex;
- }
fctrl->flash_state = CAM_FLASH_STATE_START;
break;
}
@@ -173,18 +169,13 @@
goto release_mutex;
}
- rc = cam_flash_stop_dev(fctrl);
- if (rc) {
- CAM_ERR(CAM_FLASH, "Stop Dev Failed rc = %d",
- rc);
- goto release_mutex;
- }
+ fctrl->func_tbl.flush_req(fctrl, FLUSH_ALL, 0);
fctrl->flash_state = CAM_FLASH_STATE_ACQUIRE;
break;
}
case CAM_CONFIG_DEV: {
CAM_DBG(CAM_FLASH, "CAM_CONFIG_DEV");
- rc = cam_flash_parser(fctrl, arg);
+ rc = fctrl->func_tbl.parser(fctrl, arg);
if (rc) {
CAM_ERR(CAM_FLASH, "Failed Flash Config: rc=%d\n", rc);
goto release_mutex;
@@ -201,6 +192,35 @@
return rc;
}
+static int32_t cam_flash_init_default_params(struct cam_flash_ctrl *fctrl)
+{
+ /* Validate input parameters */
+ if (!fctrl) {
+ CAM_ERR(CAM_FLASH, "failed: invalid params fctrl %pK",
+ fctrl);
+ return -EINVAL;
+ }
+
+ CAM_DBG(CAM_FLASH,
+ "master_type: %d", fctrl->io_master_info.master_type);
+ /* Initialize cci_client */
+ if (fctrl->io_master_info.master_type == CCI_MASTER) {
+ fctrl->io_master_info.cci_client = kzalloc(sizeof(
+ struct cam_sensor_cci_client), GFP_KERNEL);
+ if (!(fctrl->io_master_info.cci_client))
+ return -ENOMEM;
+ } else if (fctrl->io_master_info.master_type == I2C_MASTER) {
+ if (!(fctrl->io_master_info.client))
+ return -EINVAL;
+ } else {
+ CAM_ERR(CAM_FLASH,
+ "Invalid master / Master type Not supported");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static const struct of_device_id cam_flash_dt_match[] = {
{.compatible = "qcom,camera-flash", .data = NULL},
{}
@@ -291,20 +311,36 @@
return 0;
}
+static int32_t cam_flash_i2c_driver_remove(struct i2c_client *client)
+{
+ int32_t rc = 0;
+ struct cam_flash_ctrl *fctrl = i2c_get_clientdata(client);
+ /* Handle I2C Devices */
+ if (!fctrl) {
+ CAM_ERR(CAM_FLASH, "Flash device is NULL");
+ return -EINVAL;
+ }
+ /*Free Allocated Mem */
+ kfree(fctrl->i2c_data.per_frame);
+ fctrl->i2c_data.per_frame = NULL;
+ kfree(fctrl);
+ return rc;
+}
+
static int cam_flash_subdev_close(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
- struct cam_flash_ctrl *flash_ctrl =
+ struct cam_flash_ctrl *fctrl =
v4l2_get_subdevdata(sd);
- if (!flash_ctrl) {
+ if (!fctrl) {
CAM_ERR(CAM_FLASH, "Flash ctrl ptr is NULL");
return -EINVAL;
}
- mutex_lock(&flash_ctrl->flash_mutex);
- cam_flash_shutdown(flash_ctrl);
- mutex_unlock(&flash_ctrl->flash_mutex);
+ mutex_lock(&fctrl->flash_mutex);
+ cam_flash_shutdown(fctrl);
+ mutex_unlock(&fctrl->flash_mutex);
return 0;
}
@@ -324,10 +360,30 @@
.close = cam_flash_subdev_close,
};
+static int cam_flash_init_subdev(struct cam_flash_ctrl *fctrl)
+{
+ int rc = 0;
+
+ fctrl->v4l2_dev_str.internal_ops =
+ &cam_flash_internal_ops;
+ fctrl->v4l2_dev_str.ops = &cam_flash_subdev_ops;
+ fctrl->v4l2_dev_str.name = CAMX_FLASH_DEV_NAME;
+ fctrl->v4l2_dev_str.sd_flags =
+ V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
+ fctrl->v4l2_dev_str.ent_function = CAM_FLASH_DEVICE_TYPE;
+ fctrl->v4l2_dev_str.token = fctrl;
+
+ rc = cam_register_subdev(&(fctrl->v4l2_dev_str));
+ if (rc)
+ CAM_ERR(CAM_FLASH, "Fail to create subdev with %d", rc);
+
+ return rc;
+}
+
static int32_t cam_flash_platform_probe(struct platform_device *pdev)
{
- int32_t rc = 0;
- struct cam_flash_ctrl *flash_ctrl = NULL;
+ int32_t rc = 0, i = 0;
+ struct cam_flash_ctrl *fctrl = NULL;
CAM_DBG(CAM_FLASH, "Enter");
if (!pdev->dev.of_node) {
@@ -335,53 +391,181 @@
return -EINVAL;
}
- flash_ctrl = kzalloc(sizeof(struct cam_flash_ctrl), GFP_KERNEL);
- if (!flash_ctrl)
+ fctrl = kzalloc(sizeof(struct cam_flash_ctrl), GFP_KERNEL);
+ if (!fctrl)
return -ENOMEM;
- flash_ctrl->pdev = pdev;
- flash_ctrl->soc_info.pdev = pdev;
- flash_ctrl->soc_info.dev = &pdev->dev;
- flash_ctrl->soc_info.dev_name = pdev->name;
+ fctrl->pdev = pdev;
+ fctrl->soc_info.pdev = pdev;
+ fctrl->soc_info.dev = &pdev->dev;
+ fctrl->soc_info.dev_name = pdev->name;
- rc = cam_flash_get_dt_data(flash_ctrl, &flash_ctrl->soc_info);
+ platform_set_drvdata(pdev, fctrl);
+
+ rc = cam_flash_get_dt_data(fctrl, &fctrl->soc_info);
if (rc) {
CAM_ERR(CAM_FLASH, "cam_flash_get_dt_data failed with %d", rc);
- kfree(flash_ctrl);
+ kfree(fctrl);
return -EINVAL;
}
- flash_ctrl->v4l2_dev_str.internal_ops =
- &cam_flash_internal_ops;
- flash_ctrl->v4l2_dev_str.ops = &cam_flash_subdev_ops;
- flash_ctrl->v4l2_dev_str.name = CAMX_FLASH_DEV_NAME;
- flash_ctrl->v4l2_dev_str.sd_flags =
- V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
- flash_ctrl->v4l2_dev_str.ent_function = CAM_FLASH_DEVICE_TYPE;
- flash_ctrl->v4l2_dev_str.token = flash_ctrl;
+ if (of_find_property(pdev->dev.of_node, "cci-master", NULL)) {
+ /* Get CCI master */
+ rc = of_property_read_u32(pdev->dev.of_node, "cci-master",
+ &fctrl->cci_i2c_master);
+ CAM_DBG(CAM_FLASH, "cci-master %d, rc %d",
+ fctrl->cci_i2c_master, rc);
+ if (rc < 0) {
+ /* Set default master 0 */
+ fctrl->cci_i2c_master = MASTER_0;
+ rc = 0;
+ }
- rc = cam_register_subdev(&(flash_ctrl->v4l2_dev_str));
- if (rc) {
- CAM_ERR(CAM_FLASH, "Fail to create subdev with %d", rc);
- goto free_resource;
+ fctrl->io_master_info.master_type = CCI_MASTER;
+ rc = cam_flash_init_default_params(fctrl);
+ if (rc) {
+ CAM_ERR(CAM_FLASH,
+ "failed: cam_flash_init_default_params rc %d",
+ rc);
+ return rc;
+ }
+
+ fctrl->i2c_data.per_frame = (struct i2c_settings_array *)
+ kzalloc(sizeof(struct i2c_settings_array) *
+ MAX_PER_FRAME_ARRAY, GFP_KERNEL);
+ if (fctrl->i2c_data.per_frame == NULL) {
+ CAM_ERR(CAM_FLASH, "No Memory");
+ rc = -ENOMEM;
+ goto free_cci_resource;
+ }
+
+ INIT_LIST_HEAD(&(fctrl->i2c_data.init_settings.list_head));
+ INIT_LIST_HEAD(&(fctrl->i2c_data.config_settings.list_head));
+ for (i = 0; i < MAX_PER_FRAME_ARRAY; i++)
+ INIT_LIST_HEAD(
+ &(fctrl->i2c_data.per_frame[i].list_head));
+
+ fctrl->func_tbl.parser = cam_flash_i2c_pkt_parser;
+ fctrl->func_tbl.apply_setting = cam_flash_i2c_apply_setting;
+ fctrl->func_tbl.power_ops = cam_flash_i2c_power_ops;
+ fctrl->func_tbl.flush_req = cam_flash_i2c_flush_request;
+ } else {
+ /* PMIC Flash */
+ fctrl->func_tbl.parser = cam_flash_pmic_pkt_parser;
+ fctrl->func_tbl.apply_setting = cam_flash_pmic_apply_setting;
+ fctrl->func_tbl.power_ops = cam_flash_pmic_power_ops;
+ fctrl->func_tbl.flush_req = cam_flash_pmic_flush_request;
}
- flash_ctrl->bridge_intf.device_hdl = -1;
- flash_ctrl->bridge_intf.ops.get_dev_info = cam_flash_publish_dev_info;
- flash_ctrl->bridge_intf.ops.link_setup = cam_flash_establish_link;
- flash_ctrl->bridge_intf.ops.apply_req = cam_flash_apply_request;
- flash_ctrl->bridge_intf.ops.flush_req = cam_flash_flush_request;
- platform_set_drvdata(pdev, flash_ctrl);
- v4l2_set_subdevdata(&flash_ctrl->v4l2_dev_str.sd, flash_ctrl);
+ rc = cam_flash_init_subdev(fctrl);
+ if (rc) {
+ if (fctrl->io_master_info.cci_client != NULL)
+ goto free_cci_resource;
+ else
+ goto free_resource;
+ }
- mutex_init(&(flash_ctrl->flash_mutex));
- mutex_init(&(flash_ctrl->flash_wq_mutex));
+ fctrl->bridge_intf.device_hdl = -1;
+ fctrl->bridge_intf.ops.get_dev_info = cam_flash_publish_dev_info;
+ fctrl->bridge_intf.ops.link_setup = cam_flash_establish_link;
+ fctrl->bridge_intf.ops.apply_req = cam_flash_apply_request;
+ fctrl->bridge_intf.ops.flush_req = cam_flash_flush_request;
- flash_ctrl->flash_state = CAM_FLASH_STATE_INIT;
+ mutex_init(&(fctrl->flash_mutex));
+
+ fctrl->flash_state = CAM_FLASH_STATE_INIT;
CAM_DBG(CAM_FLASH, "Probe success");
return rc;
+
+free_cci_resource:
+ kfree(fctrl->io_master_info.cci_client);
+ fctrl->io_master_info.cci_client = NULL;
free_resource:
- kfree(flash_ctrl);
+ kfree(fctrl->i2c_data.per_frame);
+ kfree(fctrl->soc_info.soc_private);
+ cam_soc_util_release_platform_resource(&fctrl->soc_info);
+ fctrl->i2c_data.per_frame = NULL;
+ fctrl->soc_info.soc_private = NULL;
+ kfree(fctrl);
+ fctrl = NULL;
+ return rc;
+}
+
+static int32_t cam_flash_i2c_driver_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int32_t rc = 0, i = 0;
+ struct cam_flash_ctrl *fctrl;
+
+ if (client == NULL || id == NULL) {
+ CAM_ERR(CAM_FLASH, "Invalid Args client: %pK id: %pK",
+ client, id);
+ return -EINVAL;
+ }
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ CAM_ERR(CAM_FLASH, "%s :: i2c_check_functionality failed",
+ client->name);
+ return -EFAULT;
+ }
+
+ /* Create sensor control structure */
+ fctrl = kzalloc(sizeof(*fctrl), GFP_KERNEL);
+ if (!fctrl)
+ return -ENOMEM;
+
+ i2c_set_clientdata(client, fctrl);
+
+ fctrl->io_master_info.client = client;
+ fctrl->soc_info.dev = &client->dev;
+ fctrl->soc_info.dev_name = client->name;
+ fctrl->io_master_info.master_type = I2C_MASTER;
+
+ rc = cam_flash_get_dt_data(fctrl, &fctrl->soc_info);
+ if (rc) {
+ CAM_ERR(CAM_FLASH, "failed: cam_sensor_parse_dt rc %d", rc);
+ goto free_ctrl;
+ }
+
+ rc = cam_flash_init_subdev(fctrl);
+ if (rc)
+ goto free_ctrl;
+
+ fctrl->i2c_data.per_frame =
+ (struct i2c_settings_array *)
+ kzalloc(sizeof(struct i2c_settings_array) *
+ MAX_PER_FRAME_ARRAY, GFP_KERNEL);
+ if (fctrl->i2c_data.per_frame == NULL) {
+ rc = -ENOMEM;
+ goto unreg_subdev;
+ }
+
+ INIT_LIST_HEAD(&(fctrl->i2c_data.init_settings.list_head));
+ INIT_LIST_HEAD(&(fctrl->i2c_data.config_settings.list_head));
+ for (i = 0; i < MAX_PER_FRAME_ARRAY; i++)
+ INIT_LIST_HEAD(&(fctrl->i2c_data.per_frame[i].list_head));
+
+ fctrl->func_tbl.parser = cam_flash_i2c_pkt_parser;
+ fctrl->func_tbl.apply_setting = cam_flash_i2c_apply_setting;
+ fctrl->func_tbl.power_ops = cam_flash_i2c_power_ops;
+ fctrl->func_tbl.flush_req = cam_flash_i2c_flush_request;
+
+ fctrl->bridge_intf.device_hdl = -1;
+ fctrl->bridge_intf.ops.get_dev_info = cam_flash_publish_dev_info;
+ fctrl->bridge_intf.ops.link_setup = cam_flash_establish_link;
+ fctrl->bridge_intf.ops.apply_req = cam_flash_apply_request;
+ fctrl->bridge_intf.ops.flush_req = cam_flash_flush_request;
+
+ mutex_init(&(fctrl->flash_mutex));
+ fctrl->flash_state = CAM_FLASH_STATE_INIT;
+
+ return rc;
+
+unreg_subdev:
+ cam_unregister_subdev(&(fctrl->v4l2_dev_str));
+free_ctrl:
+ kfree(fctrl);
+ fctrl = NULL;
return rc;
}
@@ -398,20 +582,40 @@
},
};
-static int __init cam_flash_init_module(void)
+static const struct i2c_device_id i2c_id[] = {
+ {FLASH_DRIVER_I2C, (kernel_ulong_t)NULL},
+ { }
+};
+
+static struct i2c_driver cam_flash_i2c_driver = {
+ .id_table = i2c_id,
+ .probe = cam_flash_i2c_driver_probe,
+ .remove = cam_flash_i2c_driver_remove,
+ .driver = {
+ .name = FLASH_DRIVER_I2C,
+ },
+};
+
+static int32_t __init cam_flash_init_module(void)
{
int32_t rc = 0;
rc = platform_driver_register(&cam_flash_platform_driver);
- if (rc)
- CAM_ERR(CAM_FLASH, "platform probe for flash failed");
+ if (rc == 0) {
+ CAM_DBG(CAM_FLASH, "platform probe success");
+ return 0;
+ }
+ rc = i2c_add_driver(&cam_flash_i2c_driver);
+ if (rc)
+ CAM_ERR(CAM_FLASH, "i2c_add_driver failed rc: %d", rc);
return rc;
}
static void __exit cam_flash_exit_module(void)
{
platform_driver_unregister(&cam_flash_platform_driver);
+ i2c_del_driver(&cam_flash_i2c_driver);
}
module_init(cam_flash_init_module);
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.h
index 4adc1b2..cb54239 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.h
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.h
@@ -33,15 +33,21 @@
#include "cam_sensor_cmn_header.h"
#include "cam_soc_util.h"
#include "cam_debug_util.h"
+#include "cam_sensor_io.h"
+#include "cam_flash_core.h"
#define CAMX_FLASH_DEV_NAME "cam-flash-dev"
#define CAM_FLASH_PIPELINE_DELAY 1
+#define FLASH_DRIVER_I2C "i2c_flash"
+
#define CAM_FLASH_PACKET_OPCODE_INIT 0
#define CAM_FLASH_PACKET_OPCODE_SET_OPS 1
#define CAM_FLASH_PACKET_OPCODE_NON_REALTIME_SET_OPS 2
+struct cam_flash_ctrl;
+
enum cam_flash_switch_trigger_ops {
LED_SWITCH_OFF = 0,
LED_SWITCH_ON,
@@ -54,6 +60,12 @@
CAM_FLASH_STATE_START,
};
+enum cam_flash_flush_type {
+ FLUSH_ALL = 0,
+ FLUSH_REQ,
+ FLUSH_MAX,
+};
+
/**
* struct cam_flash_intf_params
* @device_hdl : Device Handle
@@ -136,6 +148,14 @@
uint32_t torch_max_current[CAM_FLASH_MAX_LED_TRIGGERS];
};
+struct cam_flash_func_tbl {
+ int (*parser)(struct cam_flash_ctrl *fctrl, void *arg);
+ int (*apply_setting)(struct cam_flash_ctrl *fctrl, uint64_t req_id);
+ int (*power_ops)(struct cam_flash_ctrl *fctrl, bool regulator_enable);
+ int (*flush_req)(struct cam_flash_ctrl *fctrl,
+ enum cam_flash_flush_type type, uint64_t req_id);
+};
+
/**
* struct cam_flash_ctrl
* @soc_info : Soc related information
@@ -150,32 +170,57 @@
* @flash_num_sources : Number of flash sources
* @torch_num_source : Number of torch sources
* @flash_mutex : Mutex for flash operations
- * @flash_wq_mutex : Mutex for flash apply setting
- * @flash_state : Current flash state (LOW/OFF/ON/INIT)
+ * @flash_state : Current flash state (LOW/OFF/ON/INIT)
* @flash_type : Flash types (PMIC/I2C/GPIO)
* @is_regulator_enable : Regulator disable/enable notifier
+ * @func_tbl : Function table for different HW
+ * (e.g. i2c/pmic/gpio)
* @flash_trigger : Flash trigger ptr
* @torch_trigger : Torch trigger ptr
+ * @cci_i2c_master : I2C structure
+ * @io_master_info : Information about the communication master
+ * @i2c_data : I2C register settings
*/
struct cam_flash_ctrl {
- struct cam_hw_soc_info soc_info;
- struct platform_device *pdev;
- struct cam_flash_frame_setting per_frame[MAX_PER_FRAME_ARRAY];
- struct cam_flash_frame_setting nrt_info;
- struct device_node *of_node;
- struct cam_subdev v4l2_dev_str;
- struct cam_flash_intf_params bridge_intf;
- struct cam_flash_init_packet flash_init_setting;
- struct led_trigger *switch_trigger;
- uint32_t flash_num_sources;
- uint32_t torch_num_sources;
- struct mutex flash_mutex;
- struct mutex flash_wq_mutex;
- enum cam_flash_state flash_state;
- uint8_t flash_type;
- bool is_regulator_enabled;
+ struct cam_hw_soc_info soc_info;
+ struct platform_device *pdev;
+ struct cam_sensor_power_ctrl_t power_info;
+ struct cam_flash_frame_setting per_frame[MAX_PER_FRAME_ARRAY];
+ struct cam_flash_frame_setting nrt_info;
+ struct device_node *of_node;
+ struct cam_subdev v4l2_dev_str;
+ struct cam_flash_intf_params bridge_intf;
+ struct cam_flash_init_packet flash_init_setting;
+ struct led_trigger *switch_trigger;
+ uint32_t flash_num_sources;
+ uint32_t torch_num_sources;
+ struct mutex flash_mutex;
+ enum cam_flash_state flash_state;
+ uint8_t flash_type;
+ bool is_regulator_enabled;
+ struct cam_flash_func_tbl func_tbl;
struct led_trigger *flash_trigger[CAM_FLASH_MAX_LED_TRIGGERS];
struct led_trigger *torch_trigger[CAM_FLASH_MAX_LED_TRIGGERS];
+/* I2C related setting */
+ enum cci_i2c_master_t cci_i2c_master;
+ struct camera_io_master io_master_info;
+ struct i2c_data_settings i2c_data;
};
+int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg);
+int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg);
+int cam_flash_pmic_apply_setting(struct cam_flash_ctrl *fctrl, uint64_t req_id);
+int cam_flash_i2c_apply_setting(struct cam_flash_ctrl *fctrl, uint64_t req_id);
+int cam_flash_off(struct cam_flash_ctrl *fctrl);
+int cam_flash_pmic_power_ops(struct cam_flash_ctrl *fctrl,
+ bool regulator_enable);
+int cam_flash_i2c_power_ops(struct cam_flash_ctrl *fctrl,
+ bool regulator_enable);
+int cam_flash_i2c_flush_request(struct cam_flash_ctrl *fctrl,
+ enum cam_flash_flush_type type, uint64_t req_id);
+int cam_flash_pmic_flush_request(struct cam_flash_ctrl *fctrl,
+ enum cam_flash_flush_type, uint64_t req_id);
+void cam_flash_shutdown(struct cam_flash_ctrl *fctrl);
+int cam_flash_release_dev(struct cam_flash_ctrl *fctrl);
+
#endif /*_CAM_FLASH_DEV_H_*/
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_soc.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_soc.c
index a195762..22a124d 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_soc.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_soc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -193,32 +193,31 @@
return -EINVAL;
}
- of_node = fctrl->pdev->dev.of_node;
-
- rc = cam_soc_util_get_dt_properties(soc_info);
- if (rc < 0) {
- CAM_ERR(CAM_FLASH, "Get_dt_properties failed rc %d", rc);
- return rc;
- }
-
soc_info->soc_private =
kzalloc(sizeof(struct cam_flash_private_soc), GFP_KERNEL);
if (!soc_info->soc_private) {
rc = -ENOMEM;
goto release_soc_res;
}
+ of_node = fctrl->pdev->dev.of_node;
+
+ rc = cam_soc_util_get_dt_properties(soc_info);
+ if (rc) {
+ CAM_ERR(CAM_FLASH, "Get_dt_properties failed rc %d", rc);
+ goto free_soc_private;
+ }
rc = cam_get_source_node_info(of_node, fctrl, soc_info->soc_private);
- if (rc < 0) {
+ if (rc) {
CAM_ERR(CAM_FLASH,
"cam_flash_get_pmic_source_info failed rc %d", rc);
goto free_soc_private;
}
-
return rc;
free_soc_private:
kfree(soc_info->soc_private);
+ soc_info->soc_private = NULL;
release_soc_res:
cam_soc_util_release_platform_resource(soc_info);
return rc;
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c
index 0570655..09e8d53 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c
@@ -193,7 +193,7 @@
return -EINVAL;
}
- rc = msm_camera_power_down(power_info, soc_info);
+ rc = cam_sensor_util_power_down(power_info, soc_info);
if (rc) {
CAM_ERR(CAM_OIS, "power down the core is failed:%d", rc);
return rc;
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c
index a2431be..4aae41e 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c
@@ -62,30 +62,12 @@
}
}
-static void cam_sensor_release_resource(
+static void cam_sensor_release_per_frame_resource(
struct cam_sensor_ctrl_t *s_ctrl)
{
struct i2c_settings_array *i2c_set = NULL;
int i, rc;
- i2c_set = &(s_ctrl->i2c_data.init_settings);
- if (i2c_set->is_settings_valid == 1) {
- i2c_set->is_settings_valid = -1;
- rc = delete_request(i2c_set);
- if (rc < 0)
- CAM_ERR(CAM_SENSOR,
- "failed while deleting Init settings");
- }
-
- i2c_set = &(s_ctrl->i2c_data.config_settings);
- if (i2c_set->is_settings_valid == 1) {
- i2c_set->is_settings_valid = -1;
- rc = delete_request(i2c_set);
- if (rc < 0)
- CAM_ERR(CAM_SENSOR,
- "failed while deleting Res settings");
- }
-
if (s_ctrl->i2c_data.per_frame != NULL) {
for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) {
i2c_set = &(s_ctrl->i2c_data.per_frame[i]);
@@ -503,10 +485,9 @@
(s_ctrl->is_probe_succeed == 0))
return;
- cam_sensor_release_resource(s_ctrl);
cam_sensor_release_stream_rsc(s_ctrl);
- if (s_ctrl->sensor_state >= CAM_SENSOR_ACQUIRE)
- cam_sensor_power_down(s_ctrl);
+ cam_sensor_release_per_frame_resource(s_ctrl);
+ cam_sensor_power_down(s_ctrl);
rc = cam_destroy_device_hdl(s_ctrl->bridge_intf.device_hdl);
if (rc < 0)
@@ -731,7 +712,7 @@
goto release_mutex;
}
- cam_sensor_release_resource(s_ctrl);
+ cam_sensor_release_per_frame_resource(s_ctrl);
cam_sensor_release_stream_rsc(s_ctrl);
if (s_ctrl->bridge_intf.device_hdl == -1) {
CAM_ERR(CAM_SENSOR,
@@ -816,7 +797,7 @@
}
}
- cam_sensor_release_resource(s_ctrl);
+ cam_sensor_release_per_frame_resource(s_ctrl);
s_ctrl->sensor_state = CAM_SENSOR_ACQUIRE;
CAM_INFO(CAM_SENSOR,
"CAM_STOP_DEV Success, sensor_id:0x%x,sensor_slave_addr:0x%x",
@@ -918,6 +899,8 @@
CAM_ERR(CAM_SENSOR, "Device data is NULL");
return -EINVAL;
}
+
+ mutex_lock(&s_ctrl->cam_sensor_mutex);
if (link->link_enable) {
s_ctrl->bridge_intf.link_hdl = link->link_hdl;
s_ctrl->bridge_intf.crm_cb = link->crm_cb;
@@ -925,6 +908,7 @@
s_ctrl->bridge_intf.link_hdl = -1;
s_ctrl->bridge_intf.crm_cb = NULL;
}
+ mutex_unlock(&s_ctrl->cam_sensor_mutex);
return 0;
}
@@ -1005,7 +989,7 @@
CAM_ERR(CAM_SENSOR, "failed: power_info %pK", power_info);
return -EINVAL;
}
- rc = msm_camera_power_down(power_info, soc_info);
+ rc = cam_sensor_util_power_down(power_info, soc_info);
if (rc < 0) {
CAM_ERR(CAM_SENSOR, "power down the core is failed:%d", rc);
return rc;
@@ -1155,8 +1139,10 @@
}
CAM_DBG(CAM_REQ, " Sensor update req id: %lld", apply->request_id);
trace_cam_apply_req("Sensor", apply->request_id);
+ mutex_lock(&(s_ctrl->cam_sensor_mutex));
rc = cam_sensor_apply_settings(s_ctrl, apply->request_id,
CAM_SENSOR_PACKET_OPCODE_SENSOR_UPDATE);
+ mutex_unlock(&(s_ctrl->cam_sensor_mutex));
return rc;
}
@@ -1190,7 +1176,9 @@
continue;
if (i2c_set->is_settings_valid == 1) {
+ mutex_lock(&(s_ctrl->cam_sensor_mutex));
rc = delete_request(i2c_set);
+ mutex_unlock(&(s_ctrl->cam_sensor_mutex));
if (rc < 0)
CAM_ERR(CAM_SENSOR,
"delete request: %lld rc: %d",
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c
index 46bda05..c49a892 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c
@@ -439,6 +439,75 @@
return rc;
}
+int cam_sensor_util_i2c_apply_setting(
+ struct camera_io_master *io_master_info,
+ struct i2c_settings_list *i2c_list)
+{
+ int32_t rc = 0;
+ uint32_t i, size;
+
+ switch (i2c_list->op_code) {
+ case CAM_SENSOR_I2C_WRITE_RANDOM: {
+ rc = camera_io_dev_write(io_master_info,
+ &(i2c_list->i2c_settings));
+ if (rc < 0) {
+ CAM_ERR(CAM_SENSOR,
+ "Failed to random write I2C settings: %d",
+ rc);
+ return rc;
+ }
+ break;
+ }
+ case CAM_SENSOR_I2C_WRITE_SEQ: {
+ rc = camera_io_dev_write_continuous(
+ io_master_info, &(i2c_list->i2c_settings), 0);
+ if (rc < 0) {
+ CAM_ERR(CAM_SENSOR,
+ "Failed to seq write I2C settings: %d",
+ rc);
+ return rc;
+ }
+ break;
+ }
+ case CAM_SENSOR_I2C_WRITE_BURST: {
+ rc = camera_io_dev_write_continuous(
+ io_master_info, &(i2c_list->i2c_settings), 1);
+ if (rc < 0) {
+ CAM_ERR(CAM_SENSOR,
+ "Failed to burst write I2C settings: %d",
+ rc);
+ return rc;
+ }
+ break;
+ }
+ case CAM_SENSOR_I2C_POLL: {
+ size = i2c_list->i2c_settings.size;
+ for (i = 0; i < size; i++) {
+ rc = camera_io_dev_poll(
+ io_master_info,
+ i2c_list->i2c_settings.reg_setting[i].reg_addr,
+ i2c_list->i2c_settings.reg_setting[i].reg_data,
+ i2c_list->i2c_settings.reg_setting[i].data_mask,
+ i2c_list->i2c_settings.addr_type,
+ i2c_list->i2c_settings.data_type,
+ i2c_list->i2c_settings.reg_setting[i].delay);
+ if (rc < 0) {
+ CAM_ERR(CAM_SENSOR,
+ "i2c poll apply setting Fail: %d", rc);
+ return rc;
+ }
+ }
+ break;
+ }
+ default:
+ CAM_ERR(CAM_SENSOR, "Wrong Opcode: %d", i2c_list->op_code);
+ rc = -EINVAL;
+ break;
+ }
+
+ return rc;
+}
+
int32_t msm_camera_fill_vreg_params(
struct cam_hw_soc_info *soc_info,
struct cam_sensor_power_setting *power_setting,
@@ -1710,7 +1779,7 @@
return ps;
}
-int msm_camera_power_down(struct cam_sensor_power_ctrl_t *ctrl,
+int cam_sensor_util_power_down(struct cam_sensor_power_ctrl_t *ctrl,
struct cam_hw_soc_info *soc_info)
{
int index = 0, ret = 0, num_vreg = 0, i;
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.h
index 6c0287e..583ddb1 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.h
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.h
@@ -39,6 +39,9 @@
struct i2c_settings_array *i2c_reg_settings,
struct cam_cmd_buf_desc *cmd_desc, int32_t num_cmd_buffers);
+int cam_sensor_util_i2c_apply_setting(struct camera_io_master *io_master_info,
+ struct i2c_settings_list *i2c_list);
+
int32_t delete_request(struct i2c_settings_array *i2c_array);
int cam_sensor_util_request_gpio_table(
struct cam_hw_soc_info *soc_info, int gpio_en);
@@ -49,7 +52,7 @@
int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl,
struct cam_hw_soc_info *soc_info);
-int msm_camera_power_down(struct cam_sensor_power_ctrl_t *ctrl,
+int cam_sensor_util_power_down(struct cam_sensor_power_ctrl_t *ctrl,
struct cam_hw_soc_info *soc_info);
int msm_camera_fill_vreg_params(struct cam_hw_soc_info *soc_info,
diff --git a/drivers/media/platform/msm/camera/cam_smmu/Makefile b/drivers/media/platform/msm/camera/cam_smmu/Makefile
index e17dac6..96f3968 100644
--- a/drivers/media/platform/msm/camera/cam_smmu/Makefile
+++ b/drivers/media/platform/msm/camera/cam_smmu/Makefile
@@ -1,3 +1,4 @@
ccflags-y += -Idrivers/media/platform/msm/camera/cam_utils
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_req_mgr
obj-$(CONFIG_SPECTRA_CAMERA) += cam_smmu_api.o
diff --git a/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.c b/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.c
index 52da37f..fd1b843 100644
--- a/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.c
+++ b/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.c
@@ -23,6 +23,7 @@
#include <linux/genalloc.h>
#include <soc/qcom/scm.h>
#include <soc/qcom/secure_buffer.h>
+#include <uapi/media/cam_req_mgr.h>
#include "cam_smmu_api.h"
#include "cam_debug_util.h"
@@ -34,11 +35,14 @@
#define COOKIE_SIZE (BYTE_SIZE*COOKIE_NUM_BYTE)
#define COOKIE_MASK ((1<<COOKIE_SIZE)-1)
#define HANDLE_INIT (-1)
-#define CAM_SMMU_CB_MAX 2
+#define CAM_SMMU_CB_MAX 5
#define GET_SMMU_HDL(x, y) (((x) << COOKIE_SIZE) | ((y) & COOKIE_MASK))
#define GET_SMMU_TABLE_IDX(x) (((x) >> COOKIE_SIZE) & COOKIE_MASK)
+static int g_num_pf_handled = 4;
+module_param(g_num_pf_handled, int, 0644);
+
struct firmware_alloc_info {
struct device *fw_dev;
void *fw_kva;
@@ -129,12 +133,11 @@
int handle;
enum cam_smmu_ops_param state;
- void (*handler[CAM_SMMU_CB_MAX])(struct iommu_domain *,
- struct device *, unsigned long,
- int, void*);
+ cam_smmu_client_page_fault_handler handler[CAM_SMMU_CB_MAX];
void *token[CAM_SMMU_CB_MAX];
int cb_count;
int secure_count;
+ int pf_count;
};
struct cam_iommu_cb_set {
@@ -252,13 +255,14 @@
static int cam_smmu_probe(struct platform_device *pdev);
-static void cam_smmu_check_vaddr_in_range(int idx, void *vaddr);
+static uint32_t cam_smmu_find_closest_mapping(int idx, void *vaddr);
static void cam_smmu_page_fault_work(struct work_struct *work)
{
int j;
int idx;
struct cam_smmu_work_payload *payload;
+ uint32_t buf_info;
mutex_lock(&iommu_cb_set.payload_list_lock);
if (list_empty(&iommu_cb_set.payload_list)) {
@@ -275,8 +279,11 @@
/* Dereference the payload to call the handler */
idx = payload->idx;
- mutex_lock(&iommu_cb_set.cb_info[idx].lock);
- cam_smmu_check_vaddr_in_range(idx, (void *)payload->iova);
+ buf_info = cam_smmu_find_closest_mapping(idx, (void *)payload->iova);
+ if (buf_info != 0) {
+ CAM_INFO(CAM_SMMU, "closest buf 0x%x idx %d", buf_info, idx);
+ }
+
for (j = 0; j < CAM_SMMU_CB_MAX; j++) {
if ((iommu_cb_set.cb_info[idx].handler[j])) {
iommu_cb_set.cb_info[idx].handler[j](
@@ -284,10 +291,10 @@
payload->dev,
payload->iova,
payload->flags,
- iommu_cb_set.cb_info[idx].token[j]);
+ iommu_cb_set.cb_info[idx].token[j],
+ buf_info);
}
}
- mutex_unlock(&iommu_cb_set.cb_info[idx].lock);
kfree(payload);
}
@@ -333,10 +340,13 @@
}
}
-static void cam_smmu_check_vaddr_in_range(int idx, void *vaddr)
+static uint32_t cam_smmu_find_closest_mapping(int idx, void *vaddr)
{
- struct cam_dma_buff_info *mapping;
+ struct cam_dma_buff_info *mapping, *closest_mapping = NULL;
unsigned long start_addr, end_addr, current_addr;
+ uint32_t buf_handle = 0;
+
+ long delta = 0, lowest_delta = 0;
current_addr = (unsigned long)vaddr;
list_for_each_entry(mapping,
@@ -344,31 +354,51 @@
start_addr = (unsigned long)mapping->paddr;
end_addr = (unsigned long)mapping->paddr + mapping->len;
- if (start_addr <= current_addr && current_addr < end_addr) {
- CAM_ERR(CAM_SMMU,
- "va %pK valid: range:%pK-%pK, fd = %d cb: %s",
- vaddr, (void *)start_addr, (void *)end_addr,
- mapping->ion_fd,
+ if (start_addr <= current_addr && current_addr <= end_addr) {
+ closest_mapping = mapping;
+ CAM_INFO(CAM_SMMU,
+ "Found va 0x%lx in:0x%lx-0x%lx, fd %d cb:%s",
+ current_addr, start_addr,
+ end_addr, mapping->ion_fd,
iommu_cb_set.cb_info[idx].name);
goto end;
} else {
+ if (start_addr > current_addr)
+ delta = start_addr - current_addr;
+ else
+ delta = current_addr - end_addr - 1;
+
+ if (delta < lowest_delta || lowest_delta == 0) {
+ lowest_delta = delta;
+ closest_mapping = mapping;
+ }
CAM_DBG(CAM_SMMU,
- "va %pK is not in this range: %pK-%pK, fd = %d",
- vaddr, (void *)start_addr, (void *)end_addr,
- mapping->ion_fd);
+ "approx va %lx not in range: %lx-%lx fd = %0x",
+ current_addr, start_addr,
+ end_addr, mapping->ion_fd);
}
}
- CAM_ERR(CAM_SMMU,
- "Cannot find vaddr:%pK in SMMU %s uses invalid virt address",
- vaddr, iommu_cb_set.cb_info[idx].name);
+
end:
- return;
+ if (closest_mapping) {
+ buf_handle = GET_MEM_HANDLE(idx, closest_mapping->ion_fd);
+ CAM_INFO(CAM_SMMU,
+ "Closest map fd %d 0x%lx 0x%lx-0x%lx buf=%pK mem %0x",
+ closest_mapping->ion_fd, current_addr,
+ (unsigned long)closest_mapping->paddr,
+ (unsigned long)closest_mapping->paddr + mapping->len,
+ closest_mapping->buf,
+ buf_handle);
+ } else
+ CAM_INFO(CAM_SMMU,
+ "Cannot find vaddr:%lx in SMMU %s virt address",
+ current_addr, iommu_cb_set.cb_info[idx].name);
+
+ return buf_handle;
}
-void cam_smmu_reg_client_page_fault_handler(int handle,
- void (*client_page_fault_handler)(struct iommu_domain *,
- struct device *, unsigned long,
- int, void*), void *token)
+void cam_smmu_set_client_page_fault_handler(int handle,
+ cam_smmu_client_page_fault_handler handler_cb, void *token)
{
int idx, i = 0;
@@ -394,7 +424,7 @@
return;
}
- if (client_page_fault_handler) {
+ if (handler_cb) {
if (iommu_cb_set.cb_info[idx].cb_count == CAM_SMMU_CB_MAX) {
CAM_ERR(CAM_SMMU,
"%s Should not regiester more handlers",
@@ -402,12 +432,14 @@
mutex_unlock(&iommu_cb_set.cb_info[idx].lock);
return;
}
+
iommu_cb_set.cb_info[idx].cb_count++;
+
for (i = 0; i < iommu_cb_set.cb_info[idx].cb_count; i++) {
if (iommu_cb_set.cb_info[idx].token[i] == NULL) {
iommu_cb_set.cb_info[idx].token[i] = token;
iommu_cb_set.cb_info[idx].handler[i] =
- client_page_fault_handler;
+ handler_cb;
break;
}
}
@@ -429,6 +461,47 @@
mutex_unlock(&iommu_cb_set.cb_info[idx].lock);
}
+void cam_smmu_unset_client_page_fault_handler(int handle, void *token)
+{
+ int idx, i = 0;
+
+ if (!token || (handle == HANDLE_INIT)) {
+ CAM_ERR(CAM_SMMU, "Error: token is NULL or invalid handle");
+ return;
+ }
+
+ idx = GET_SMMU_TABLE_IDX(handle);
+ if (idx < 0 || idx >= iommu_cb_set.cb_num) {
+ CAM_ERR(CAM_SMMU,
+ "Error: handle or index invalid. idx = %d hdl = %x",
+ idx, handle);
+ return;
+ }
+
+ mutex_lock(&iommu_cb_set.cb_info[idx].lock);
+ if (iommu_cb_set.cb_info[idx].handle != handle) {
+ CAM_ERR(CAM_SMMU,
+ "Error: hdl is not valid, table_hdl = %x, hdl = %x",
+ iommu_cb_set.cb_info[idx].handle, handle);
+ mutex_unlock(&iommu_cb_set.cb_info[idx].lock);
+ return;
+ }
+
+ for (i = 0; i < CAM_SMMU_CB_MAX; i++) {
+ if (iommu_cb_set.cb_info[idx].token[i] == token) {
+ iommu_cb_set.cb_info[idx].token[i] = NULL;
+ iommu_cb_set.cb_info[idx].handler[i] =
+ NULL;
+ iommu_cb_set.cb_info[idx].cb_count--;
+ break;
+ }
+ }
+ if (i == CAM_SMMU_CB_MAX)
+ CAM_ERR(CAM_SMMU, "Error: hdl %x no matching tokens: %s",
+ handle, iommu_cb_set.cb_info[idx].name);
+ mutex_unlock(&iommu_cb_set.cb_info[idx].lock);
+}
+
static int cam_smmu_iommu_fault_handler(struct iommu_domain *domain,
struct device *dev, unsigned long iova,
int flags, void *token)
@@ -459,6 +532,13 @@
return -EINVAL;
}
+ if (++iommu_cb_set.cb_info[idx].pf_count > g_num_pf_handled) {
+ CAM_INFO(CAM_SMMU, "PF already handled %d %d %d",
+ g_num_pf_handled, idx,
+ iommu_cb_set.cb_info[idx].pf_count);
+ return -EINVAL;
+ }
+
payload = kzalloc(sizeof(struct cam_smmu_work_payload), GFP_ATOMIC);
if (!payload)
return -EINVAL;
@@ -474,7 +554,7 @@
list_add_tail(&payload->list, &iommu_cb_set.payload_list);
mutex_unlock(&iommu_cb_set.payload_list_lock);
- schedule_work(&iommu_cb_set.smmu_work);
+ cam_smmu_page_fault_work(&iommu_cb_set.smmu_work);
return -EINVAL;
}
@@ -528,6 +608,7 @@
iommu_cb_set.cb_info[i].state = CAM_SMMU_DETACH;
iommu_cb_set.cb_info[i].dev = NULL;
iommu_cb_set.cb_info[i].cb_count = 0;
+ iommu_cb_set.cb_info[i].pf_count = 0;
for (j = 0; j < CAM_SMMU_CB_MAX; j++) {
iommu_cb_set.cb_info[i].token[j] = NULL;
iommu_cb_set.cb_info[i].handler[j] = NULL;
diff --git a/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.h b/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.h
index 254e382..6c72902 100644
--- a/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.h
+++ b/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -51,6 +51,21 @@
};
/**
+ * @brief : Callback function type that gets called back on cam
+ * smmu page fault.
+ *
+ * @param domain : Iommu domain received in iommu page fault handler
+ * @param dev : Device received in iommu page fault handler
+ * @param iova : IOVA where page fault occurred
+ * @param flags : Flags received in iommu page fault handler
+ * @param token : Userdata given during callback registration
+ * @param buf_info : Closest mapped buffer info
+ */
+typedef void (*cam_smmu_client_page_fault_handler)(struct iommu_domain *domain,
+ struct device *dev, unsigned long iova, int flags, void *token,
+ uint32_t buf_info);
+
+/**
* @brief : Structure to store region information
*
* @param iova_start : Start address of region
@@ -215,13 +230,19 @@
* @brief : Registers smmu fault handler for client
*
* @param handle: Handle to identify the CAM SMMU client (VFE, CPP, FD etc.)
- * @param client_page_fault_handler: It is triggered in IOMMU page fault
+ * @param handler_cb: It is triggered in IOMMU page fault
* @param token: It is input param when trigger page fault handler
*/
-void cam_smmu_reg_client_page_fault_handler(int handle,
- void (*client_page_fault_handler)(struct iommu_domain *,
- struct device *, unsigned long,
- int, void*), void *token);
+void cam_smmu_set_client_page_fault_handler(int handle,
+ cam_smmu_client_page_fault_handler handler_cb, void *token);
+
+/**
+ * @brief : Unregisters smmu fault handler for client
+ *
+ * @param handle: Handle to identify the CAM SMMU client (VFE, CPP, FD etc.)
+ * @param token: It is input param when trigger page fault handler
+ */
+void cam_smmu_unset_client_page_fault_handler(int handle, void *token);
/**
* @brief Maps memory from an ION fd into IOVA space
diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.c b/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.c
index a5456a9..37d7e7d 100644
--- a/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.c
+++ b/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.c
@@ -100,8 +100,10 @@
return "SVSL1[4]";
case CAM_NOMINAL_VOTE:
return "NOM[5]";
+ case CAM_NOMINALL1_VOTE:
+ return "NOML1[6]";
case CAM_TURBO_VOTE:
- return "TURBO[6]";
+ return "TURBO[7]";
default:
return "";
}
@@ -281,6 +283,8 @@
*level = CAM_SVSL1_VOTE;
} else if (!strcmp(string, "nominal")) {
*level = CAM_NOMINAL_VOTE;
+ } else if (!strcmp(string, "nominal_l1")) {
+ *level = CAM_NOMINALL1_VOTE;
} else if (!strcmp(string, "turbo")) {
*level = CAM_TURBO_VOTE;
} else {
diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.h b/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.h
index 4c6ed4b..d7432d9 100644
--- a/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.h
+++ b/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.h
@@ -50,14 +50,15 @@
/**
* enum cam_vote_level - Enum for voting level
*
- * @CAM_SUSPEND_VOTE : Suspend vote
- * @CAM_MINSVS_VOTE : Min SVS vote
- * @CAM_LOWSVS_VOTE : Low SVS vote
- * @CAM_SVS_VOTE : SVS vote
- * @CAM_SVSL1_VOTE : SVS Plus vote
- * @CAM_NOMINAL_VOTE : Nominal vote
- * @CAM_TURBO_VOTE : Turbo vote
- * @CAM_MAX_VOTE : Max voting level, This is invalid level.
+ * @CAM_SUSPEND_VOTE : Suspend vote
+ * @CAM_MINSVS_VOTE : Min SVS vote
+ * @CAM_LOWSVS_VOTE : Low SVS vote
+ * @CAM_SVS_VOTE : SVS vote
+ * @CAM_SVSL1_VOTE : SVS Plus vote
+ * @CAM_NOMINAL_VOTE : Nominal vote
+ * @CAM_NOMINALL1_VOTE: Nominal plus vote
+ * @CAM_TURBO_VOTE : Turbo vote
+ * @CAM_MAX_VOTE : Max voting level, This is invalid level.
*/
enum cam_vote_level {
CAM_SUSPEND_VOTE,
@@ -66,6 +67,7 @@
CAM_SVS_VOTE,
CAM_SVSL1_VOTE,
CAM_NOMINAL_VOTE,
+ CAM_NOMINALL1_VOTE,
CAM_TURBO_VOTE,
CAM_MAX_VOTE,
};
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
index 6196a8c..7a0a069 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
@@ -676,6 +676,10 @@
rc = 0;
break;
case MSM_ISP_BUFFER_STATE_QUEUED:
+ if (IS_ENABLED(CONFIG_MSM_ISP_V1)) {
+ rc = 0;
+ break;
+ }
case MSM_ISP_BUFFER_STATE_DIVERTED:
default:
WARN(1, "%s: bufq 0x%x, buf idx 0x%x, incorrect state = %d",
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
index 7c55ad8..a62c465 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
@@ -450,7 +450,7 @@
{
struct page *page;
struct vfe_device *vfe_dev = vma->vm_private_data;
- struct isp_proc *isp_page = NULL;
+ struct isp_kstate *isp_page = NULL;
isp_page = vfe_dev->isp_page;
@@ -728,7 +728,7 @@
vfe_dev->buf_mgr->init_done = 1;
vfe_dev->vfe_open_cnt = 0;
/*Allocate a page in kernel and map it to camera user process*/
- vfe_dev->isp_page = (struct isp_proc *)get_zeroed_page(GFP_KERNEL);
+ vfe_dev->isp_page = (struct isp_kstate *)get_zeroed_page(GFP_KERNEL);
if (vfe_dev->isp_page == NULL) {
pr_err("%s: no enough memory\n", __func__);
rc = -ENOMEM;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
index 4f97618..fa55d64 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
@@ -761,11 +761,6 @@
struct msm_vfe_common_dev_data *common_data;
};
-struct isp_proc {
- uint32_t kernel_sofid;
- uint32_t vfeid;
-};
-
struct vfe_device {
/* Driver private data */
struct platform_device *pdev;
@@ -850,7 +845,7 @@
uint32_t recovery_irq1_mask;
/* total bandwidth per vfe */
uint64_t total_bandwidth;
- struct isp_proc *isp_page;
+ struct isp_kstate *isp_page;
};
struct vfe_parent_device {
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
index a95917c..74679b2 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
@@ -26,7 +26,7 @@
#define VFE32_EQUAL_SLICE_UB 194
#define VFE32_AXI_SLICE_UB 792
#define VFE32_WM_BASE(idx) (0x4C + 0x18 * idx)
-#define VFE32_RDI_BASE(idx) (idx ? 0x734 + 0x4 * (idx - 1) : 0x06FC)
+#define VFE32_RDI_BASE(idx) (idx ? 0x734 + 0x70 * (idx - 1) : 0x06FC)
#define VFE32_XBAR_BASE(idx) (0x40 + 0x4 * (idx / 4))
#define VFE32_XBAR_SHIFT(idx) ((idx % 4) * 8)
#define VFE32_PING_PONG_BASE(wm, ping_pong) \
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
index c5c05d2..a2d4c4a 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
@@ -749,13 +749,13 @@
return;
if (irq_status0 & BIT(2)) {
- msm_isp_notify(vfe_dev, ISP_EVENT_SOF, VFE_PIX_0, ts);
ISP_DBG("%s: EPOCH0 IRQ\n", __func__);
msm_isp_process_reg_upd_epoch_irq(vfe_dev, VFE_PIX_0,
MSM_ISP_COMP_IRQ_EPOCH, ts);
msm_isp_process_stats_reg_upd_epoch_irq(vfe_dev,
MSM_ISP_COMP_IRQ_EPOCH);
msm_isp_update_error_frame_count(vfe_dev);
+ msm_isp_notify(vfe_dev, ISP_EVENT_SOF, VFE_PIX_0, ts);
if (vfe_dev->axi_data.src_info[VFE_PIX_0].raw_stream_count > 0
&& vfe_dev->axi_data.src_info[VFE_PIX_0].
stream_count == 0) {
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
index 1b04e1d..1ddbb94 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
@@ -175,6 +175,8 @@
stream_info->bufq_handle[k] = 0;
stream_info->vfe_mask = 0;
stream_info->state = AVAILABLE;
+ memset(&stream_info->request_queue_cmd,
+ 0, sizeof(stream_info->request_queue_cmd));
}
}
@@ -598,7 +600,8 @@
*
* Returns void
*/
-static void msm_isp_update_framedrop_reg(struct msm_vfe_axi_stream *stream_info)
+static void msm_isp_update_framedrop_reg(struct msm_vfe_axi_stream *stream_info,
+ uint32_t drop_reconfig)
{
if (stream_info->stream_type == BURST_STREAM) {
if (stream_info->runtime_num_burst_capture == 0 ||
@@ -608,7 +611,8 @@
MSM_VFE_STREAM_STOP_PERIOD;
}
- if (stream_info->undelivered_request_cnt > 0)
+ if (stream_info->undelivered_request_cnt > 0 &&
+ drop_reconfig != 1)
stream_info->current_framedrop_period =
MSM_VFE_STREAM_STOP_PERIOD;
@@ -663,7 +667,8 @@
break;
case MSM_ISP_COMP_IRQ_EPOCH:
if (stream_info->state == ACTIVE)
- msm_isp_update_framedrop_reg(stream_info);
+ msm_isp_update_framedrop_reg(stream_info,
+ vfe_dev->isp_page->drop_reconfig);
break;
default:
WARN(1, "Invalid irq %d\n", irq);
@@ -3543,6 +3548,14 @@
frame_src = SRC_TO_INTF(stream_info->stream_src);
pingpong_status = vfe_dev->hw_info->
vfe_ops.axi_ops.get_pingpong_status(vfe_dev);
+
+ /* As MCT is still processing it, need to drop the additional requests*/
+ if (vfe_dev->isp_page->drop_reconfig) {
+ pr_err("%s: MCT has not yet delayed %d drop request %d\n",
+ __func__, vfe_dev->isp_page->drop_reconfig, frame_id);
+ goto error;
+ }
+
/*
* If PIX stream is active then RDI path uses SOF frame ID of PIX
* In case of standalone RDI streaming, SOF are used from
@@ -3556,9 +3569,18 @@
vfe_dev->axi_data.src_info[frame_src].accept_frame == false) {
pr_debug("%s:%d invalid time to request frame %d\n",
__func__, __LINE__, frame_id);
- goto error;
- }
- if ((vfe_dev->axi_data.src_info[frame_src].active && (frame_id !=
+ vfe_dev->isp_page->drop_reconfig = 1;
+ } else if ((vfe_dev->axi_data.src_info[frame_src].active) &&
+ (frame_id ==
+ vfe_dev->axi_data.src_info[frame_src].frame_id) &&
+ (stream_info->undelivered_request_cnt <=
+ MAX_BUFFERS_IN_HW)) {
+ vfe_dev->isp_page->drop_reconfig = 1;
+ pr_debug("%s: vfe_%d request_frame %d cur frame id %d pix %d\n",
+ __func__, vfe_dev->pdev->id, frame_id,
+ vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id,
+ vfe_dev->axi_data.src_info[VFE_PIX_0].active);
+ } else if ((vfe_dev->axi_data.src_info[frame_src].active && (frame_id !=
vfe_dev->axi_data.src_info[frame_src].frame_id + vfe_dev->
axi_data.src_info[frame_src].sof_counter_step)) ||
((!vfe_dev->axi_data.src_info[frame_src].active))) {
@@ -3662,6 +3684,9 @@
stream_info->undelivered_request_cnt--;
pr_err_ratelimited("%s:%d fail to cfg HAL buffer\n",
__func__, __LINE__);
+ queue_req->cmd_used = 0;
+ list_del(&queue_req->list);
+ stream_info->request_q_cnt--;
return rc;
}
@@ -3698,6 +3723,9 @@
flags);
pr_err_ratelimited("%s:%d fail to cfg HAL buffer\n",
__func__, __LINE__);
+ queue_req->cmd_used = 0;
+ list_del(&queue_req->list);
+ stream_info->request_q_cnt--;
return rc;
}
} else {
diff --git a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
index e458b4df..c86528e 100644
--- a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
+++ b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
@@ -575,15 +575,13 @@
k_ioctl = *ptr;
switch (k_ioctl.id) {
case MSM_CAMERA_BUF_MNGR_IOCTL_ID_GET_BUF_BY_IDX: {
+ struct msm_buf_mngr_info buf_info, *tmp = NULL;
if (k_ioctl.size != sizeof(struct msm_buf_mngr_info))
return -EINVAL;
if (!k_ioctl.ioctl_ptr)
return -EINVAL;
-#ifndef CONFIG_COMPAT
- {
- struct msm_buf_mngr_info buf_info, *tmp = NULL;
-
+ if (!is_compat_task()) {
MSM_CAM_GET_IOCTL_ARG_PTR(&tmp,
&k_ioctl.ioctl_ptr, sizeof(tmp));
if (copy_from_user(&buf_info, tmp,
@@ -592,7 +590,7 @@
}
k_ioctl.ioctl_ptr = (uintptr_t)&buf_info;
}
-#endif
+
argp = &k_ioctl;
rc = msm_cam_buf_mgr_ops(cmd, argp);
}
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
index 53dd371..ee659f6 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
@@ -836,7 +836,7 @@
break;
case VIDIOC_MSM_CSID_RELEASE:
case MSM_SD_SHUTDOWN:
- if (adsp_shmem_get_state() == CAMERA_STATUS_END) {
+ if (adsp_shmem_get_state() != CAMERA_STATUS_END) {
/* aDSP still in use */
rc = 0;
break;
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c
index e16629c..118cb93 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c
@@ -223,6 +223,8 @@
rc = msm_camera_qup_i2c_txdata(client, buf, len);
if (rc < 0)
S_I2C_DBG("%s fail\n", __func__);
+ kfree(buf);
+ buf = NULL;
return rc;
}
@@ -272,6 +274,8 @@
rc = msm_camera_qup_i2c_txdata(client, buf, len+num_byte);
if (rc < 0)
S_I2C_DBG("%s fail\n", __func__);
+ kfree(buf);
+ buf = NULL;
return rc;
}
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
index c15a2e9..802e581 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
@@ -932,6 +932,12 @@
break;
}
}
+
+ if (!inst->clk_data.entry) {
+ dprintk(VIDC_ERR, "%s No match found\n", __func__);
+ rc = -EINVAL;
+ }
+
return rc;
}
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index b878971..176b9c6 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -3138,7 +3138,11 @@
return -EINVAL;
}
- msm_comm_init_clocks_and_bus_data(inst);
+ rc = msm_comm_init_clocks_and_bus_data(inst);
+ if (rc) {
+ dprintk(VIDC_ERR, "Failed to initialize clocks and bus data\n");
+ goto exit;
+ }
dprintk(VIDC_DBG, "%s: inst %pK\n", __func__, inst);
rc = call_hfi_op(hdev, session_init, hdev->hfi_device_data,
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_platform.c b/drivers/media/platform/msm/vidc/msm_vidc_platform.c
index f975409..93418fe 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_platform.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_platform.c
@@ -183,7 +183,7 @@
},
{
.key = "qcom,max-hw-load",
- .value = 2219400,
+ .value = 2241480,
},
{
.key = "qcom,max-hq-mbs-per-frame",
diff --git a/drivers/media/platform/msm/vidc_3x/msm_vidc.c b/drivers/media/platform/msm/vidc_3x/msm_vidc.c
index 983e600c..e289527 100644
--- a/drivers/media/platform/msm/vidc_3x/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc_3x/msm_vidc.c
@@ -1084,7 +1084,7 @@
q->ops = msm_venc_get_vb2q_ops();
q->mem_ops = &msm_vidc_vb2_mem_ops;
q->drv_priv = inst;
- q->allow_zero_bytesused = 1;
+ q->allow_zero_bytesused = !V4L2_TYPE_IS_OUTPUT(type);
return vb2_queue_init(q);
}
@@ -1206,6 +1206,7 @@
INIT_MSM_VIDC_LIST(&inst->pending_getpropq);
INIT_MSM_VIDC_LIST(&inst->outputbufs);
INIT_MSM_VIDC_LIST(&inst->registeredbufs);
+ INIT_MSM_VIDC_LIST(&inst->eosbufs);
kref_init(&inst->kref);
@@ -1292,6 +1293,7 @@
msm_comm_ctrl_deinit(inst);
msm_smem_delete_client(inst->mem_client);
fail_mem_client:
+ DEINIT_MSM_VIDC_LIST(&inst->eosbufs);
kfree(inst);
inst = NULL;
err_invalid_core:
@@ -1323,6 +1325,8 @@
"Failed to release persist buffers\n");
}
+ msm_comm_release_eos_buffers(inst);
+
if (msm_comm_release_output_buffers(inst)) {
dprintk(VIDC_ERR,
"Failed to release output buffers\n");
@@ -1364,6 +1368,8 @@
for (i = 0; i < MAX_PORT_NUM; i++)
vb2_queue_release(&inst->bufq[i].vb2_bufq);
+ DEINIT_MSM_VIDC_LIST(&inst->eosbufs);
+
mutex_destroy(&inst->sync_lock);
mutex_destroy(&inst->bufq[CAPTURE_PORT].lock);
mutex_destroy(&inst->bufq[OUTPUT_PORT].lock);
diff --git a/drivers/media/platform/msm/vidc_3x/msm_vidc_common.c b/drivers/media/platform/msm/vidc_3x/msm_vidc_common.c
index 502a5c7..998b397 100644
--- a/drivers/media/platform/msm/vidc_3x/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc_3x/msm_vidc_common.c
@@ -1774,6 +1774,27 @@
return vb;
}
+static bool is_eos_buffer(struct msm_vidc_inst *inst, u32 device_addr)
+{
+ struct eos_buf *temp, *next;
+ bool found = false;
+
+ mutex_lock(&inst->eosbufs.lock);
+ list_for_each_entry_safe(temp, next, &inst->eosbufs.list, list) {
+ if (temp->smem.device_addr == device_addr) {
+ found = true;
+ list_del(&temp->list);
+ msm_comm_smem_free(inst, &temp->smem);
+ kfree(temp);
+ break;
+ }
+ }
+ mutex_unlock(&inst->eosbufs.lock);
+
+ return found;
+}
+
+
static void handle_ebd(enum hal_command_response cmd, void *data)
{
struct msm_vidc_cb_data_done *response = data;
@@ -1808,6 +1829,13 @@
response->clnt_data)
dprintk(VIDC_INFO, "Client data != bufaddr\n");
empty_buf_done = (struct vidc_hal_ebd *)&response->input_done;
+ /* If this is internal EOS buffer, handle it in driver */
+ if (is_eos_buffer(inst, empty_buf_done->packet_buffer)) {
+ dprintk(VIDC_DBG, "Received EOS buffer %pK\n",
+ (void *)empty_buf_done->packet_buffer);
+ goto exit;
+ }
+
if (empty_buf_done) {
if (empty_buf_done->status == VIDC_ERR_NOT_SUPPORTED) {
dprintk(VIDC_INFO,
@@ -1844,7 +1872,7 @@
mutex_unlock(&inst->bufq[OUTPUT_PORT].lock);
msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_EBD);
}
-
+exit:
put_inst(inst);
}
@@ -3502,7 +3530,6 @@
flags = dec->flags;
}
-
switch (which_cmd) {
case V4L2_QCOM_CMD_FLUSH:
if (core->state != VIDC_CORE_INVALID &&
@@ -3552,6 +3579,61 @@
}
break;
}
+ case V4L2_DEC_CMD_STOP:
+ {
+ struct vidc_frame_data data = {0};
+ struct hfi_device *hdev = NULL;
+ struct eos_buf *binfo = NULL;
+ u32 smem_flags = 0;
+
+ if (inst->state != MSM_VIDC_START_DONE) {
+ dprintk(VIDC_DBG,
+ "Inst = %pK is not ready for EOS\n", inst);
+ rc = -EINVAL;
+ break;
+ }
+ if (inst->session_type != MSM_VIDC_DECODER) {
+ dprintk(VIDC_DBG,
+ "Non-Decoder session. DEC_STOP is not valid\n");
+ rc = -EINVAL;
+ break;
+ }
+
+ binfo = kzalloc(sizeof(*binfo), GFP_KERNEL);
+ if (!binfo) {
+ dprintk(VIDC_ERR, "%s: Out of memory\n", __func__);
+ rc = -ENOMEM;
+ break;
+ }
+
+ if (inst->flags & VIDC_SECURE)
+ smem_flags |= SMEM_SECURE;
+
+ msm_comm_smem_alloc(inst,
+ SZ_4K, 1, smem_flags, HAL_BUFFER_INPUT, 0);
+
+ mutex_lock(&inst->eosbufs.lock);
+ list_add_tail(&binfo->list, &inst->eosbufs.list);
+ mutex_unlock(&inst->eosbufs.lock);
+
+ data.alloc_len = binfo->smem.size;
+ data.device_addr = binfo->smem.device_addr;
+ data.clnt_data = data.device_addr;
+ data.buffer_type = HAL_BUFFER_INPUT;
+ data.filled_len = 0;
+ data.offset = 0;
+ data.flags = HAL_BUFFERFLAG_EOS;
+ data.timestamp = LLONG_MAX;
+ data.extradata_addr = data.device_addr;
+ data.extradata_size = 0;
+ dprintk(VIDC_DBG, "Queueing EOS buffer %pK\n",
+ (void *)data.device_addr);
+ hdev = inst->core->device;
+
+ rc = call_hfi_op(hdev, session_etb, inst->session, &data);
+ break;
+ }
+
default:
dprintk(VIDC_ERR, "Unknown Command %d\n", which_cmd);
rc = -ENOTSUPP;
@@ -4268,6 +4350,26 @@
return rc;
}
+void msm_comm_release_eos_buffers(struct msm_vidc_inst *inst)
+{
+ struct eos_buf *buf, *next;
+
+ if (!inst) {
+ dprintk(VIDC_ERR,
+ "Invalid instance pointer = %pK\n", inst);
+ return;
+ }
+
+ mutex_lock(&inst->eosbufs.lock);
+ list_for_each_entry_safe(buf, next, &inst->eosbufs.list, list) {
+ list_del(&buf->list);
+ kfree(buf);
+ }
+
+ INIT_LIST_HEAD(&inst->eosbufs.list);
+ mutex_unlock(&inst->eosbufs.lock);
+}
+
int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst)
{
struct msm_smem *handle;
diff --git a/drivers/media/platform/msm/vidc_3x/msm_vidc_common.h b/drivers/media/platform/msm/vidc_3x/msm_vidc_common.h
index 9b71709..8b140a7 100644
--- a/drivers/media/platform/msm/vidc_3x/msm_vidc_common.h
+++ b/drivers/media/platform/msm/vidc_3x/msm_vidc_common.h
@@ -55,6 +55,7 @@
int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst,
bool check_for_reuse);
int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst);
+void msm_comm_release_eos_buffers(struct msm_vidc_inst *inst);
int msm_comm_release_output_buffers(struct msm_vidc_inst *inst);
int msm_comm_force_cleanup(struct msm_vidc_inst *inst);
int msm_comm_suspend(int core_id);
diff --git a/drivers/media/platform/msm/vidc_3x/msm_vidc_internal.h b/drivers/media/platform/msm/vidc_3x/msm_vidc_internal.h
index c7eb5f1..00cbafb 100644
--- a/drivers/media/platform/msm/vidc_3x/msm_vidc_internal.h
+++ b/drivers/media/platform/msm/vidc_3x/msm_vidc_internal.h
@@ -121,6 +121,10 @@
INIT_LIST_HEAD(&mlist->list);
}
+static inline void DEINIT_MSM_VIDC_LIST(struct msm_vidc_list *mlist)
+{
+ mutex_destroy(&mlist->lock);
+}
enum buffer_owner {
DRIVER,
FIRMWARE,
@@ -128,6 +132,11 @@
MAX_OWNER
};
+struct eos_buf {
+ struct list_head list;
+ struct msm_smem smem;
+};
+
struct internal_buf {
struct list_head list;
enum hal_buffer buffer_type;
@@ -268,6 +277,7 @@
struct msm_vidc_list persistbufs;
struct msm_vidc_list pending_getpropq;
struct msm_vidc_list outputbufs;
+ struct msm_vidc_list eosbufs;
struct msm_vidc_list registeredbufs;
struct buffer_requirements buff_req;
void *mem_client;
diff --git a/drivers/media/platform/msm/vidc_3x/venus_hfi.c b/drivers/media/platform/msm/vidc_3x/venus_hfi.c
index c385088..1bd6ae8 100644
--- a/drivers/media/platform/msm/vidc_3x/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc_3x/venus_hfi.c
@@ -3645,6 +3645,12 @@
i < num_responses; ++i) {
struct msm_vidc_cb_info *r = &device->response_pkt[i];
+ if (!__core_in_valid_state(device)) {
+ dprintk(VIDC_ERR,
+ "Ignore responses from %d to %d as device is in invalid state",
+ (i + 1), num_responses);
+ break;
+ }
device->callback(r->response_type, &r->response);
}
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 0321d84..15a86bb 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -1941,6 +1941,7 @@
static void isp_detach_iommu(struct isp_device *isp)
{
+ arm_iommu_detach_device(isp->dev);
arm_iommu_release_mapping(isp->mapping);
isp->mapping = NULL;
iommu_group_remove_device(isp->dev);
@@ -1974,8 +1975,7 @@
mapping = arm_iommu_create_mapping(&platform_bus_type, SZ_1G, SZ_2G);
if (IS_ERR(mapping)) {
dev_err(isp->dev, "failed to create ARM IOMMU mapping\n");
- ret = PTR_ERR(mapping);
- goto error;
+ return PTR_ERR(mapping);
}
isp->mapping = mapping;
@@ -1990,7 +1990,8 @@
return 0;
error:
- isp_detach_iommu(isp);
+ arm_iommu_release_mapping(isp->mapping);
+ isp->mapping = NULL;
return ret;
}
diff --git a/drivers/media/platform/rcar_jpu.c b/drivers/media/platform/rcar_jpu.c
index d1746ec..db1110a 100644
--- a/drivers/media/platform/rcar_jpu.c
+++ b/drivers/media/platform/rcar_jpu.c
@@ -1280,7 +1280,7 @@
/* ...issue software reset */
ret = jpu_reset(jpu);
if (ret)
- goto device_prepare_rollback;
+ goto jpu_reset_rollback;
}
jpu->ref_count++;
@@ -1288,6 +1288,8 @@
mutex_unlock(&jpu->mutex);
return 0;
+jpu_reset_rollback:
+ clk_disable_unprepare(jpu->clk);
device_prepare_rollback:
mutex_unlock(&jpu->mutex);
v4l_prepare_rollback:
diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c
index ee0470a..f218886 100644
--- a/drivers/media/radio/si470x/radio-si470x-i2c.c
+++ b/drivers/media/radio/si470x/radio-si470x-i2c.c
@@ -96,7 +96,7 @@
*/
int si470x_get_register(struct si470x_device *radio, int regnr)
{
- u16 buf[READ_REG_NUM];
+ __be16 buf[READ_REG_NUM];
struct i2c_msg msgs[1] = {
{
.addr = radio->client->addr,
@@ -121,7 +121,7 @@
int si470x_set_register(struct si470x_device *radio, int regnr)
{
int i;
- u16 buf[WRITE_REG_NUM];
+ __be16 buf[WRITE_REG_NUM];
struct i2c_msg msgs[1] = {
{
.addr = radio->client->addr,
@@ -151,7 +151,7 @@
static int si470x_get_all_registers(struct si470x_device *radio)
{
int i;
- u16 buf[READ_REG_NUM];
+ __be16 buf[READ_REG_NUM];
struct i2c_msg msgs[1] = {
{
.addr = radio->client->addr,
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index 4299ce0..b3a9fa7 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -914,9 +914,12 @@
dprintk(4, "done processing on buffer %d, state: %d\n",
vb->index, state);
- /* sync buffers */
- for (plane = 0; plane < vb->num_planes; ++plane)
- call_void_memop(vb, finish, vb->planes[plane].mem_priv);
+ if (state != VB2_BUF_STATE_QUEUED &&
+ state != VB2_BUF_STATE_REQUEUEING) {
+ /* sync buffers */
+ for (plane = 0; plane < vb->num_planes; ++plane)
+ call_void_memop(vb, finish, vb->planes[plane].mem_priv);
+ }
spin_lock_irqsave(&q->done_lock, flags);
if (state == VB2_BUF_STATE_QUEUED ||
diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
index a4803ac..1d49a8d 100644
--- a/drivers/memory/tegra/mc.c
+++ b/drivers/memory/tegra/mc.c
@@ -20,14 +20,6 @@
#include "mc.h"
#define MC_INTSTATUS 0x000
-#define MC_INT_DECERR_MTS (1 << 16)
-#define MC_INT_SECERR_SEC (1 << 13)
-#define MC_INT_DECERR_VPR (1 << 12)
-#define MC_INT_INVALID_APB_ASID_UPDATE (1 << 11)
-#define MC_INT_INVALID_SMMU_PAGE (1 << 10)
-#define MC_INT_ARBITRATION_EMEM (1 << 9)
-#define MC_INT_SECURITY_VIOLATION (1 << 8)
-#define MC_INT_DECERR_EMEM (1 << 6)
#define MC_INTMASK 0x004
@@ -248,12 +240,13 @@
static irqreturn_t tegra_mc_irq(int irq, void *data)
{
struct tegra_mc *mc = data;
- unsigned long status, mask;
+ unsigned long status;
unsigned int bit;
/* mask all interrupts to avoid flooding */
- status = mc_readl(mc, MC_INTSTATUS);
- mask = mc_readl(mc, MC_INTMASK);
+ status = mc_readl(mc, MC_INTSTATUS) & mc->soc->intmask;
+ if (!status)
+ return IRQ_NONE;
for_each_set_bit(bit, &status, 32) {
const char *error = status_names[bit] ?: "unknown";
@@ -346,7 +339,6 @@
const struct of_device_id *match;
struct resource *res;
struct tegra_mc *mc;
- u32 value;
int err;
match = of_match_node(tegra_mc_of_match, pdev->dev.of_node);
@@ -414,11 +406,7 @@
WARN(!mc->soc->client_id_mask, "Missing client ID mask for this SoC\n");
- value = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
- MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE |
- MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM;
-
- mc_writel(mc, value, MC_INTMASK);
+ mc_writel(mc, mc->soc->intmask, MC_INTMASK);
return 0;
}
diff --git a/drivers/memory/tegra/mc.h b/drivers/memory/tegra/mc.h
index ddb1667..24e020b 100644
--- a/drivers/memory/tegra/mc.h
+++ b/drivers/memory/tegra/mc.h
@@ -14,6 +14,15 @@
#include <soc/tegra/mc.h>
+#define MC_INT_DECERR_MTS (1 << 16)
+#define MC_INT_SECERR_SEC (1 << 13)
+#define MC_INT_DECERR_VPR (1 << 12)
+#define MC_INT_INVALID_APB_ASID_UPDATE (1 << 11)
+#define MC_INT_INVALID_SMMU_PAGE (1 << 10)
+#define MC_INT_ARBITRATION_EMEM (1 << 9)
+#define MC_INT_SECURITY_VIOLATION (1 << 8)
+#define MC_INT_DECERR_EMEM (1 << 6)
+
static inline u32 mc_readl(struct tegra_mc *mc, unsigned long offset)
{
return readl(mc->regs + offset);
diff --git a/drivers/memory/tegra/tegra114.c b/drivers/memory/tegra/tegra114.c
index ba8fff3..6d2a5a8 100644
--- a/drivers/memory/tegra/tegra114.c
+++ b/drivers/memory/tegra/tegra114.c
@@ -930,4 +930,6 @@
.atom_size = 32,
.client_id_mask = 0x7f,
.smmu = &tegra114_smmu_soc,
+ .intmask = MC_INT_INVALID_SMMU_PAGE | MC_INT_SECURITY_VIOLATION |
+ MC_INT_DECERR_EMEM,
};
diff --git a/drivers/memory/tegra/tegra124.c b/drivers/memory/tegra/tegra124.c
index 5a58e44..9f68a56 100644
--- a/drivers/memory/tegra/tegra124.c
+++ b/drivers/memory/tegra/tegra124.c
@@ -1020,6 +1020,9 @@
.smmu = &tegra124_smmu_soc,
.emem_regs = tegra124_mc_emem_regs,
.num_emem_regs = ARRAY_SIZE(tegra124_mc_emem_regs),
+ .intmask = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
+ MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE |
+ MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
};
#endif /* CONFIG_ARCH_TEGRA_124_SOC */
@@ -1042,5 +1045,8 @@
.atom_size = 32,
.client_id_mask = 0x7f,
.smmu = &tegra132_smmu_soc,
+ .intmask = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
+ MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE |
+ MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
};
#endif /* CONFIG_ARCH_TEGRA_132_SOC */
diff --git a/drivers/memory/tegra/tegra210.c b/drivers/memory/tegra/tegra210.c
index 5e144ab..47c78a6 100644
--- a/drivers/memory/tegra/tegra210.c
+++ b/drivers/memory/tegra/tegra210.c
@@ -1077,4 +1077,7 @@
.atom_size = 64,
.client_id_mask = 0xff,
.smmu = &tegra210_smmu_soc,
+ .intmask = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
+ MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE |
+ MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
};
diff --git a/drivers/memory/tegra/tegra30.c b/drivers/memory/tegra/tegra30.c
index b447378..d068942 100644
--- a/drivers/memory/tegra/tegra30.c
+++ b/drivers/memory/tegra/tegra30.c
@@ -952,4 +952,6 @@
.atom_size = 16,
.client_id_mask = 0x7f,
.smmu = &tegra30_smmu_soc,
+ .intmask = MC_INT_INVALID_SMMU_PAGE | MC_INT_SECURITY_VIOLATION |
+ MC_INT_DECERR_EMEM,
};
diff --git a/drivers/mfd/cros_ec.c b/drivers/mfd/cros_ec.c
index abd8342..3e18d25 100644
--- a/drivers/mfd/cros_ec.c
+++ b/drivers/mfd/cros_ec.c
@@ -86,7 +86,11 @@
mutex_init(&ec_dev->lock);
- cros_ec_query_all(ec_dev);
+ err = cros_ec_query_all(ec_dev);
+ if (err) {
+ dev_err(dev, "Cannot identify the EC: error %d\n", err);
+ return err;
+ }
if (ec_dev->irq) {
err = request_threaded_irq(ec_dev->irq, NULL, ec_irq_thread,
diff --git a/drivers/misc/ibmasm/ibmasmfs.c b/drivers/misc/ibmasm/ibmasmfs.c
index 520f584..65ad7e5 100644
--- a/drivers/misc/ibmasm/ibmasmfs.c
+++ b/drivers/misc/ibmasm/ibmasmfs.c
@@ -507,35 +507,14 @@
static ssize_t remote_settings_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
{
void __iomem *address = (void __iomem *)file->private_data;
- unsigned char *page;
- int retval;
int len = 0;
unsigned int value;
-
- if (*offset < 0)
- return -EINVAL;
- if (count == 0 || count > 1024)
- return 0;
- if (*offset != 0)
- return 0;
-
- page = (unsigned char *)__get_free_page(GFP_KERNEL);
- if (!page)
- return -ENOMEM;
+ char lbuf[20];
value = readl(address);
- len = sprintf(page, "%d\n", value);
+ len = snprintf(lbuf, sizeof(lbuf), "%d\n", value);
- if (copy_to_user(buf, page, len)) {
- retval = -EFAULT;
- goto exit;
- }
- *offset += len;
- retval = len;
-
-exit:
- free_page((unsigned long)page);
- return retval;
+ return simple_read_from_buffer(buf, count, offset, lbuf, len);
}
static ssize_t remote_settings_file_write(struct file *file, const char __user *ubuff, size_t count, loff_t *offset)
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 8e5987c..63184bf 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -182,6 +182,7 @@
size_t sb_length;
struct ion_handle *ihandle; /* Retrieve phy addr */
wait_queue_head_t rcv_req_wq;
+ /* rcv_req_flag: -1: not ready; 0: ready and empty; 1: received req */
int rcv_req_flag;
int send_resp_flag;
bool listener_in_use;
@@ -1191,9 +1192,10 @@
rcvd_lstnr.sb_size))
return -EFAULT;
- data->listener.id = 0;
+ data->listener.id = rcvd_lstnr.listener_id;
if (!__qseecom_is_svc_unique(data, &rcvd_lstnr)) {
- pr_err("Service is not unique and is already registered\n");
+ pr_err("Service %d is not unique and failed to register\n",
+ rcvd_lstnr.listener_id);
data->released = true;
return -EBUSY;
}
@@ -1202,18 +1204,18 @@
if (!new_entry)
return -ENOMEM;
memcpy(&new_entry->svc, &rcvd_lstnr, sizeof(rcvd_lstnr));
- new_entry->rcv_req_flag = 0;
+ new_entry->rcv_req_flag = -1;
new_entry->svc.listener_id = rcvd_lstnr.listener_id;
new_entry->sb_length = rcvd_lstnr.sb_size;
new_entry->user_virt_sb_base = rcvd_lstnr.virt_sb_base;
if (__qseecom_set_sb_memory(new_entry, data, &rcvd_lstnr)) {
- pr_err("qseecom_set_sb_memoryfailed\n");
+ pr_err("qseecom_set_sb_memory failed for listener %d, size %d\n",
+ rcvd_lstnr.listener_id, rcvd_lstnr.sb_size);
kzfree(new_entry);
return -ENOMEM;
}
- data->listener.id = rcvd_lstnr.listener_id;
init_waitqueue_head(&new_entry->rcv_req_wq);
init_waitqueue_head(&new_entry->listener_block_app_wq);
new_entry->send_resp_flag = 0;
@@ -1222,6 +1224,7 @@
list_add_tail(&new_entry->list, &qseecom.registered_listener_list_head);
spin_unlock_irqrestore(&qseecom.registered_listener_list_lock, flags);
+ pr_warn("Service %d is registered\n", rcvd_lstnr.listener_id);
return ret;
}
@@ -1245,13 +1248,17 @@
static int qseecom_unregister_listener(struct qseecom_dev_handle *data)
{
int ret = 0;
- unsigned long flags;
- uint32_t unmap_mem = 0;
struct qseecom_register_listener_ireq req;
struct qseecom_registered_listener_list *ptr_svc = NULL;
struct qseecom_command_scm_resp resp;
struct ion_handle *ihandle = NULL; /* Retrieve phy addr */
+ ptr_svc = __qseecom_find_svc(data->listener.id);
+ if (!ptr_svc) {
+ pr_err("Unregiser invalid listener ID %d\n", data->listener.id);
+ return -ENODATA;
+ }
+
req.qsee_cmd_id = QSEOS_DEREGISTER_LISTENER;
req.listener_id = data->listener.id;
resp.result = QSEOS_RESULT_INCOMPLETE;
@@ -1261,59 +1268,41 @@
if (ret) {
pr_err("scm_call() failed with err: %d (lstnr id=%d)\n",
ret, data->listener.id);
- return ret;
+ goto exit;
}
if (resp.result != QSEOS_RESULT_SUCCESS) {
pr_err("Failed resp.result=%d,(lstnr id=%d)\n",
resp.result, data->listener.id);
- return -EPERM;
+ ret = -EPERM;
+ goto exit;
}
data->abort = 1;
- spin_lock_irqsave(&qseecom.registered_listener_list_lock, flags);
- list_for_each_entry(ptr_svc, &qseecom.registered_listener_list_head,
- list) {
- if (ptr_svc->svc.listener_id == data->listener.id) {
- ptr_svc->abort = 1;
- wake_up_all(&ptr_svc->rcv_req_wq);
- break;
- }
- }
- spin_unlock_irqrestore(&qseecom.registered_listener_list_lock, flags);
+ ptr_svc->abort = 1;
+ wake_up_all(&ptr_svc->rcv_req_wq);
while (atomic_read(&data->ioctl_count) > 1) {
if (wait_event_freezable(data->abort_wq,
atomic_read(&data->ioctl_count) <= 1)) {
pr_err("Interrupted from abort\n");
ret = -ERESTARTSYS;
- return ret;
}
}
- spin_lock_irqsave(&qseecom.registered_listener_list_lock, flags);
- list_for_each_entry(ptr_svc,
- &qseecom.registered_listener_list_head, list) {
- if (ptr_svc->svc.listener_id == data->listener.id) {
- if (ptr_svc->sb_virt) {
- unmap_mem = 1;
- ihandle = ptr_svc->ihandle;
- }
- list_del(&ptr_svc->list);
- kzfree(ptr_svc);
- break;
- }
- }
- spin_unlock_irqrestore(&qseecom.registered_listener_list_lock, flags);
-
- /* Unmap the memory */
- if (unmap_mem) {
+exit:
+ if (ptr_svc->sb_virt) {
+ ihandle = ptr_svc->ihandle;
if (!IS_ERR_OR_NULL(ihandle)) {
ion_unmap_kernel(qseecom.ion_clnt, ihandle);
ion_free(qseecom.ion_clnt, ihandle);
}
}
+ list_del(&ptr_svc->list);
+ kzfree(ptr_svc);
+
data->released = true;
+ pr_warn("Service %d is unregistered\n", data->listener.id);
return ret;
}
@@ -1651,6 +1640,22 @@
}
}
+/* wait listener retry delay (ms) and max attemp count */
+#define QSEECOM_WAIT_LISTENER_DELAY 10
+#define QSEECOM_WAIT_LISTENER_MAX_ATTEMP 3
+
+static int __is_listener_rcv_wq_not_ready(
+ struct qseecom_registered_listener_list *ptr_svc)
+{
+ int retry = 0;
+
+ while (ptr_svc->rcv_req_flag == -1 &&
+ retry++ < QSEECOM_WAIT_LISTENER_MAX_ATTEMP) {
+ msleep(QSEECOM_WAIT_LISTENER_DELAY);
+ }
+ return ptr_svc->rcv_req_flag == -1;
+}
+
static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data,
struct qseecom_command_scm_resp *resp)
{
@@ -1679,6 +1684,8 @@
list_for_each_entry(ptr_svc,
&qseecom.registered_listener_list_head, list) {
if (ptr_svc->svc.listener_id == lstnr) {
+ if (__is_listener_rcv_wq_not_ready(ptr_svc))
+ break;
ptr_svc->listener_in_use = true;
ptr_svc->rcv_req_flag = 1;
wake_up_interruptible(&ptr_svc->rcv_req_wq);
@@ -1718,6 +1725,16 @@
status = QSEOS_RESULT_FAILURE;
goto err_resp;
}
+
+ if (ptr_svc->rcv_req_flag == -1) {
+ pr_err("Service %d is not ready to receive request\n",
+ lstnr);
+ rc = -ENOENT;
+ status = QSEOS_RESULT_FAILURE;
+ goto err_resp;
+
+ }
+
pr_debug("waking up rcv_req_wq and waiting for send_resp_wq\n");
/* initialize the new signal mask with all signals*/
@@ -1990,6 +2007,8 @@
list_for_each_entry(ptr_svc,
&qseecom.registered_listener_list_head, list) {
if (ptr_svc->svc.listener_id == lstnr) {
+ if (__is_listener_rcv_wq_not_ready(ptr_svc))
+ break;
ptr_svc->listener_in_use = true;
ptr_svc->rcv_req_flag = 1;
wake_up_interruptible(&ptr_svc->rcv_req_wq);
@@ -2029,6 +2048,16 @@
status = QSEOS_RESULT_FAILURE;
goto err_resp;
}
+
+ if (ptr_svc->rcv_req_flag == -1) {
+ pr_err("Service %d is not ready to receive request\n",
+ lstnr);
+ rc = -ENOENT;
+ status = QSEOS_RESULT_FAILURE;
+ goto err_resp;
+
+ }
+
pr_debug("waking up rcv_req_wq and waiting for send_resp_wq\n");
/* initialize the new signal mask with all signals*/
@@ -3836,7 +3865,7 @@
{
int ret;
- ret = (svc->rcv_req_flag != 0);
+ ret = (svc->rcv_req_flag == 1);
return ret || data->abort || svc->abort;
}
@@ -3850,12 +3879,13 @@
pr_err("Invalid listener ID\n");
return -ENODATA;
}
+ this_lstnr->rcv_req_flag = 0;
while (1) {
if (wait_event_freezable(this_lstnr->rcv_req_wq,
__qseecom_listener_has_rcvd_req(data,
this_lstnr))) {
- pr_debug("Interrupted: exiting Listener Service = %d\n",
+ pr_warn("Interrupted: exiting Listener Service = %d\n",
(uint32_t)data->listener.id);
/* woken up for different reason */
return -ERESTARTSYS;
@@ -4545,7 +4575,6 @@
strlcpy(entry->app_name, app_name, MAX_APP_NAME_SIZE);
if (__qseecom_get_fw_size(app_name, &fw_size, &app_arch)) {
ret = -EIO;
- kfree(entry);
goto exit_entry_free;
}
entry->app_arch = app_arch;
@@ -7699,6 +7728,7 @@
data->type, data->mode, data);
switch (data->type) {
case QSEECOM_LISTENER_SERVICE:
+ pr_warn("release lsnr svc %d\n", data->listener.id);
__qseecom_listener_abort_all(1);
mutex_lock(&app_access_lock);
ret = qseecom_unregister_listener(data);
diff --git a/drivers/misc/vmw_balloon.c b/drivers/misc/vmw_balloon.c
index fe90b7e..5e047bf 100644
--- a/drivers/misc/vmw_balloon.c
+++ b/drivers/misc/vmw_balloon.c
@@ -467,7 +467,7 @@
unsigned int num_pages, bool is_2m_pages, unsigned int *target)
{
unsigned long status;
- unsigned long pfn = page_to_pfn(b->page);
+ unsigned long pfn = PHYS_PFN(virt_to_phys(b->batch_page));
STATS_INC(b->stats.lock[is_2m_pages]);
@@ -515,7 +515,7 @@
unsigned int num_pages, bool is_2m_pages, unsigned int *target)
{
unsigned long status;
- unsigned long pfn = page_to_pfn(b->page);
+ unsigned long pfn = PHYS_PFN(virt_to_phys(b->batch_page));
STATS_INC(b->stats.unlock[is_2m_pages]);
diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c
index 1304160..8cd9ddf 100644
--- a/drivers/mmc/core/pwrseq_simple.c
+++ b/drivers/mmc/core/pwrseq_simple.c
@@ -39,14 +39,18 @@
struct gpio_descs *reset_gpios = pwrseq->reset_gpios;
if (!IS_ERR(reset_gpios)) {
- int i;
- int values[reset_gpios->ndescs];
+ int i, *values;
+ int nvalues = reset_gpios->ndescs;
- for (i = 0; i < reset_gpios->ndescs; i++)
+ values = kmalloc_array(nvalues, sizeof(int), GFP_KERNEL);
+ if (!values)
+ return;
+
+ for (i = 0; i < nvalues; i++)
values[i] = value;
- gpiod_set_array_value_cansleep(
- reset_gpios->ndescs, reset_gpios->desc, values);
+ gpiod_set_array_value_cansleep(nvalues, reset_gpios->desc, values);
+ kfree(values);
}
}
diff --git a/drivers/mmc/host/cmdq_hci.c b/drivers/mmc/host/cmdq_hci.c
index 01811d9..5477221 100644
--- a/drivers/mmc/host/cmdq_hci.c
+++ b/drivers/mmc/host/cmdq_hci.c
@@ -884,11 +884,13 @@
cmdq_runtime_pm_put(cq_host);
- if (cq_host->ops->crypto_cfg_end) {
- err = cq_host->ops->crypto_cfg_end(mmc, mrq);
- if (err) {
- pr_err("%s: failed to end ice config: err %d tag %d\n",
- mmc_hostname(mmc), err, tag);
+ if (!(mrq->cmdq_req->cmdq_req_flags & DCMD)) {
+ if (cq_host->ops->crypto_cfg_end) {
+ err = cq_host->ops->crypto_cfg_end(mmc, mrq);
+ if (err) {
+ pr_err("%s: failed to end ice config: err %d tag %d\n",
+ mmc_hostname(mmc), err, tag);
+ }
}
}
if (!(cq_host->caps & CMDQ_CAP_CRYPTO_SUPPORT) &&
@@ -1108,7 +1110,7 @@
/* read CQTCN and complete the request */
comp_status = cmdq_readl(cq_host, CQTCN);
if (!comp_status)
- goto out;
+ goto hac;
/*
* The CQTCN must be cleared before notifying req completion
* to upper layers to avoid missing completion notification
@@ -1135,7 +1137,7 @@
}
}
}
-
+hac:
if (status & CQIS_HAC) {
if (cq_host->ops->post_cqe_halt)
cq_host->ops->post_cqe_halt(mmc);
@@ -1146,7 +1148,6 @@
complete(&cq_host->halt_comp);
}
-out:
return IRQ_HANDLED;
}
EXPORT_SYMBOL(cmdq_irq);
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index d382dbd..e10a00d 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -981,8 +981,8 @@
* It's used when HS400 mode is enabled.
*/
if (data->flags & MMC_DATA_WRITE &&
- !(host->timing != MMC_TIMING_MMC_HS400))
- return;
+ host->timing != MMC_TIMING_MMC_HS400)
+ goto disable;
if (data->flags & MMC_DATA_WRITE)
enable = SDMMC_CARD_WR_THR_EN;
@@ -990,7 +990,8 @@
enable = SDMMC_CARD_RD_THR_EN;
if (host->timing != MMC_TIMING_MMC_HS200 &&
- host->timing != MMC_TIMING_UHS_SDR104)
+ host->timing != MMC_TIMING_UHS_SDR104 &&
+ host->timing != MMC_TIMING_MMC_HS400)
goto disable;
blksz_depth = blksz / (1 << host->data_shift);
@@ -1163,6 +1164,8 @@
if (host->state == STATE_WAITING_CMD11_DONE)
sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
+ slot->mmc->actual_clock = 0;
+
if (!clock) {
mci_writel(host, CLKENA, 0);
mci_send_cmd(slot, sdmmc_cmd_bits, 0);
@@ -1208,6 +1211,8 @@
/* keep the last clock value that was requested from core */
slot->__clk_old = clock;
+ slot->mmc->actual_clock = div ? ((host->bus_hz / div) >> 1) :
+ host->bus_hz;
}
host->current_speed = clock;
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 9cf7fcd..16a7df2 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -172,7 +172,8 @@
t[1].rx_buf = buf;
t[1].rx_nbits = m25p80_rx_nbits(nor);
- t[1].len = min(len, spi_max_transfer_size(spi));
+ t[1].len = min3(len, spi_max_transfer_size(spi),
+ spi_max_message_size(spi) - t[0].len);
spi_message_add_tail(&t[1], &m);
ret = spi_sync(spi, &m);
diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
index 2f6b552..4c3b986 100644
--- a/drivers/mtd/nand/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/fsl_ifc_nand.c
@@ -372,9 +372,16 @@
case NAND_CMD_READID:
case NAND_CMD_PARAM: {
+ /*
+ * For READID, read 8 bytes that are currently used.
+ * For PARAM, read all 3 copies of 256-bytes pages.
+ */
+ int len = 8;
int timing = IFC_FIR_OP_RB;
- if (command == NAND_CMD_PARAM)
+ if (command == NAND_CMD_PARAM) {
timing = IFC_FIR_OP_RBCD;
+ len = 256 * 3;
+ }
ifc_out32((IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
(IFC_FIR_OP_UA << IFC_NAND_FIR0_OP1_SHIFT) |
@@ -384,12 +391,8 @@
&ifc->ifc_nand.nand_fcr0);
ifc_out32(column, &ifc->ifc_nand.row3);
- /*
- * although currently it's 8 bytes for READID, we always read
- * the maximum 256 bytes(for PARAM)
- */
- ifc_out32(256, &ifc->ifc_nand.nand_fbcr);
- ifc_nand_ctrl->read_bytes = 256;
+ ifc_out32(len, &ifc->ifc_nand.nand_fbcr);
+ ifc_nand_ctrl->read_bytes = len;
set_addr(mtd, 0, 0, 0);
fsl_ifc_run_command(mtd);
diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c
index c71a035..e680bab 100644
--- a/drivers/net/can/xilinx_can.c
+++ b/drivers/net/can/xilinx_can.c
@@ -2,6 +2,7 @@
*
* Copyright (C) 2012 - 2014 Xilinx, Inc.
* Copyright (C) 2009 PetaLogix. All rights reserved.
+ * Copyright (C) 2017 Sandvik Mining and Construction Oy
*
* Description:
* This driver is developed for Axi CAN IP and for Zynq CANPS Controller.
@@ -25,8 +26,10 @@
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/skbuff.h>
+#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/can/dev.h>
@@ -101,7 +104,7 @@
#define XCAN_INTR_ALL (XCAN_IXR_TXOK_MASK | XCAN_IXR_BSOFF_MASK |\
XCAN_IXR_WKUP_MASK | XCAN_IXR_SLP_MASK | \
XCAN_IXR_RXNEMP_MASK | XCAN_IXR_ERROR_MASK | \
- XCAN_IXR_ARBLST_MASK | XCAN_IXR_RXOK_MASK)
+ XCAN_IXR_RXOFLW_MASK | XCAN_IXR_ARBLST_MASK)
/* CAN register bit shift - XCAN_<REG>_<BIT>_SHIFT */
#define XCAN_BTR_SJW_SHIFT 7 /* Synchronous jump width */
@@ -118,6 +121,7 @@
/**
* struct xcan_priv - This definition define CAN driver instance
* @can: CAN private data structure.
+ * @tx_lock: Lock for synchronizing TX interrupt handling
* @tx_head: Tx CAN packets ready to send on the queue
* @tx_tail: Tx CAN packets successfully sended on the queue
* @tx_max: Maximum number packets the driver can send
@@ -132,6 +136,7 @@
*/
struct xcan_priv {
struct can_priv can;
+ spinlock_t tx_lock;
unsigned int tx_head;
unsigned int tx_tail;
unsigned int tx_max;
@@ -159,6 +164,11 @@
.brp_inc = 1,
};
+#define XCAN_CAP_WATERMARK 0x0001
+struct xcan_devtype_data {
+ unsigned int caps;
+};
+
/**
* xcan_write_reg_le - Write a value to the device register little endian
* @priv: Driver private data structure
@@ -238,6 +248,10 @@
usleep_range(500, 10000);
}
+ /* reset clears FIFOs */
+ priv->tx_head = 0;
+ priv->tx_tail = 0;
+
return 0;
}
@@ -392,6 +406,7 @@
struct net_device_stats *stats = &ndev->stats;
struct can_frame *cf = (struct can_frame *)skb->data;
u32 id, dlc, data[2] = {0, 0};
+ unsigned long flags;
if (can_dropped_invalid_skb(ndev, skb))
return NETDEV_TX_OK;
@@ -439,6 +454,9 @@
data[1] = be32_to_cpup((__be32 *)(cf->data + 4));
can_put_echo_skb(skb, ndev, priv->tx_head % priv->tx_max);
+
+ spin_lock_irqsave(&priv->tx_lock, flags);
+
priv->tx_head++;
/* Write the Frame to Xilinx CAN TX FIFO */
@@ -454,10 +472,16 @@
stats->tx_bytes += cf->can_dlc;
}
+ /* Clear TX-FIFO-empty interrupt for xcan_tx_interrupt() */
+ if (priv->tx_max > 1)
+ priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_TXFEMP_MASK);
+
/* Check if the TX buffer is full */
if ((priv->tx_head - priv->tx_tail) == priv->tx_max)
netif_stop_queue(ndev);
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
+
return NETDEV_TX_OK;
}
@@ -530,6 +554,123 @@
}
/**
+ * xcan_current_error_state - Get current error state from HW
+ * @ndev: Pointer to net_device structure
+ *
+ * Checks the current CAN error state from the HW. Note that this
+ * only checks for ERROR_PASSIVE and ERROR_WARNING.
+ *
+ * Return:
+ * ERROR_PASSIVE or ERROR_WARNING if either is active, ERROR_ACTIVE
+ * otherwise.
+ */
+static enum can_state xcan_current_error_state(struct net_device *ndev)
+{
+ struct xcan_priv *priv = netdev_priv(ndev);
+ u32 status = priv->read_reg(priv, XCAN_SR_OFFSET);
+
+ if ((status & XCAN_SR_ESTAT_MASK) == XCAN_SR_ESTAT_MASK)
+ return CAN_STATE_ERROR_PASSIVE;
+ else if (status & XCAN_SR_ERRWRN_MASK)
+ return CAN_STATE_ERROR_WARNING;
+ else
+ return CAN_STATE_ERROR_ACTIVE;
+}
+
+/**
+ * xcan_set_error_state - Set new CAN error state
+ * @ndev: Pointer to net_device structure
+ * @new_state: The new CAN state to be set
+ * @cf: Error frame to be populated or NULL
+ *
+ * Set new CAN error state for the device, updating statistics and
+ * populating the error frame if given.
+ */
+static void xcan_set_error_state(struct net_device *ndev,
+ enum can_state new_state,
+ struct can_frame *cf)
+{
+ struct xcan_priv *priv = netdev_priv(ndev);
+ u32 ecr = priv->read_reg(priv, XCAN_ECR_OFFSET);
+ u32 txerr = ecr & XCAN_ECR_TEC_MASK;
+ u32 rxerr = (ecr & XCAN_ECR_REC_MASK) >> XCAN_ESR_REC_SHIFT;
+
+ priv->can.state = new_state;
+
+ if (cf) {
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[6] = txerr;
+ cf->data[7] = rxerr;
+ }
+
+ switch (new_state) {
+ case CAN_STATE_ERROR_PASSIVE:
+ priv->can.can_stats.error_passive++;
+ if (cf)
+ cf->data[1] = (rxerr > 127) ?
+ CAN_ERR_CRTL_RX_PASSIVE :
+ CAN_ERR_CRTL_TX_PASSIVE;
+ break;
+ case CAN_STATE_ERROR_WARNING:
+ priv->can.can_stats.error_warning++;
+ if (cf)
+ cf->data[1] |= (txerr > rxerr) ?
+ CAN_ERR_CRTL_TX_WARNING :
+ CAN_ERR_CRTL_RX_WARNING;
+ break;
+ case CAN_STATE_ERROR_ACTIVE:
+ if (cf)
+ cf->data[1] |= CAN_ERR_CRTL_ACTIVE;
+ break;
+ default:
+ /* non-ERROR states are handled elsewhere */
+ WARN_ON(1);
+ break;
+ }
+}
+
+/**
+ * xcan_update_error_state_after_rxtx - Update CAN error state after RX/TX
+ * @ndev: Pointer to net_device structure
+ *
+ * If the device is in a ERROR-WARNING or ERROR-PASSIVE state, check if
+ * the performed RX/TX has caused it to drop to a lesser state and set
+ * the interface state accordingly.
+ */
+static void xcan_update_error_state_after_rxtx(struct net_device *ndev)
+{
+ struct xcan_priv *priv = netdev_priv(ndev);
+ enum can_state old_state = priv->can.state;
+ enum can_state new_state;
+
+ /* changing error state due to successful frame RX/TX can only
+ * occur from these states
+ */
+ if (old_state != CAN_STATE_ERROR_WARNING &&
+ old_state != CAN_STATE_ERROR_PASSIVE)
+ return;
+
+ new_state = xcan_current_error_state(ndev);
+
+ if (new_state != old_state) {
+ struct sk_buff *skb;
+ struct can_frame *cf;
+
+ skb = alloc_can_err_skb(ndev, &cf);
+
+ xcan_set_error_state(ndev, new_state, skb ? cf : NULL);
+
+ if (skb) {
+ struct net_device_stats *stats = &ndev->stats;
+
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+ netif_rx(skb);
+ }
+ }
+}
+
+/**
* xcan_err_interrupt - error frame Isr
* @ndev: net_device pointer
* @isr: interrupt status register value
@@ -544,16 +685,12 @@
struct net_device_stats *stats = &ndev->stats;
struct can_frame *cf;
struct sk_buff *skb;
- u32 err_status, status, txerr = 0, rxerr = 0;
+ u32 err_status;
skb = alloc_can_err_skb(ndev, &cf);
err_status = priv->read_reg(priv, XCAN_ESR_OFFSET);
priv->write_reg(priv, XCAN_ESR_OFFSET, err_status);
- txerr = priv->read_reg(priv, XCAN_ECR_OFFSET) & XCAN_ECR_TEC_MASK;
- rxerr = ((priv->read_reg(priv, XCAN_ECR_OFFSET) &
- XCAN_ECR_REC_MASK) >> XCAN_ESR_REC_SHIFT);
- status = priv->read_reg(priv, XCAN_SR_OFFSET);
if (isr & XCAN_IXR_BSOFF_MASK) {
priv->can.state = CAN_STATE_BUS_OFF;
@@ -563,28 +700,10 @@
can_bus_off(ndev);
if (skb)
cf->can_id |= CAN_ERR_BUSOFF;
- } else if ((status & XCAN_SR_ESTAT_MASK) == XCAN_SR_ESTAT_MASK) {
- priv->can.state = CAN_STATE_ERROR_PASSIVE;
- priv->can.can_stats.error_passive++;
- if (skb) {
- cf->can_id |= CAN_ERR_CRTL;
- cf->data[1] = (rxerr > 127) ?
- CAN_ERR_CRTL_RX_PASSIVE :
- CAN_ERR_CRTL_TX_PASSIVE;
- cf->data[6] = txerr;
- cf->data[7] = rxerr;
- }
- } else if (status & XCAN_SR_ERRWRN_MASK) {
- priv->can.state = CAN_STATE_ERROR_WARNING;
- priv->can.can_stats.error_warning++;
- if (skb) {
- cf->can_id |= CAN_ERR_CRTL;
- cf->data[1] |= (txerr > rxerr) ?
- CAN_ERR_CRTL_TX_WARNING :
- CAN_ERR_CRTL_RX_WARNING;
- cf->data[6] = txerr;
- cf->data[7] = rxerr;
- }
+ } else {
+ enum can_state new_state = xcan_current_error_state(ndev);
+
+ xcan_set_error_state(ndev, new_state, skb ? cf : NULL);
}
/* Check for Arbitration lost interrupt */
@@ -600,7 +719,6 @@
if (isr & XCAN_IXR_RXOFLW_MASK) {
stats->rx_over_errors++;
stats->rx_errors++;
- priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_RESET_MASK);
if (skb) {
cf->can_id |= CAN_ERR_CRTL;
cf->data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
@@ -709,26 +827,20 @@
isr = priv->read_reg(priv, XCAN_ISR_OFFSET);
while ((isr & XCAN_IXR_RXNEMP_MASK) && (work_done < quota)) {
- if (isr & XCAN_IXR_RXOK_MASK) {
- priv->write_reg(priv, XCAN_ICR_OFFSET,
- XCAN_IXR_RXOK_MASK);
- work_done += xcan_rx(ndev);
- } else {
- priv->write_reg(priv, XCAN_ICR_OFFSET,
- XCAN_IXR_RXNEMP_MASK);
- break;
- }
+ work_done += xcan_rx(ndev);
priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_RXNEMP_MASK);
isr = priv->read_reg(priv, XCAN_ISR_OFFSET);
}
- if (work_done)
+ if (work_done) {
can_led_event(ndev, CAN_LED_EVENT_RX);
+ xcan_update_error_state_after_rxtx(ndev);
+ }
if (work_done < quota) {
napi_complete(napi);
ier = priv->read_reg(priv, XCAN_IER_OFFSET);
- ier |= (XCAN_IXR_RXOK_MASK | XCAN_IXR_RXNEMP_MASK);
+ ier |= XCAN_IXR_RXNEMP_MASK;
priv->write_reg(priv, XCAN_IER_OFFSET, ier);
}
return work_done;
@@ -743,18 +855,71 @@
{
struct xcan_priv *priv = netdev_priv(ndev);
struct net_device_stats *stats = &ndev->stats;
+ unsigned int frames_in_fifo;
+ int frames_sent = 1; /* TXOK => at least 1 frame was sent */
+ unsigned long flags;
+ int retries = 0;
- while ((priv->tx_head - priv->tx_tail > 0) &&
- (isr & XCAN_IXR_TXOK_MASK)) {
+ /* Synchronize with xmit as we need to know the exact number
+ * of frames in the FIFO to stay in sync due to the TXFEMP
+ * handling.
+ * This also prevents a race between netif_wake_queue() and
+ * netif_stop_queue().
+ */
+ spin_lock_irqsave(&priv->tx_lock, flags);
+
+ frames_in_fifo = priv->tx_head - priv->tx_tail;
+
+ if (WARN_ON_ONCE(frames_in_fifo == 0)) {
+ /* clear TXOK anyway to avoid getting back here */
priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_TXOK_MASK);
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
+ return;
+ }
+
+ /* Check if 2 frames were sent (TXOK only means that at least 1
+ * frame was sent).
+ */
+ if (frames_in_fifo > 1) {
+ WARN_ON(frames_in_fifo > priv->tx_max);
+
+ /* Synchronize TXOK and isr so that after the loop:
+ * (1) isr variable is up-to-date at least up to TXOK clear
+ * time. This avoids us clearing a TXOK of a second frame
+ * but not noticing that the FIFO is now empty and thus
+ * marking only a single frame as sent.
+ * (2) No TXOK is left. Having one could mean leaving a
+ * stray TXOK as we might process the associated frame
+ * via TXFEMP handling as we read TXFEMP *after* TXOK
+ * clear to satisfy (1).
+ */
+ while ((isr & XCAN_IXR_TXOK_MASK) && !WARN_ON(++retries == 100)) {
+ priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_TXOK_MASK);
+ isr = priv->read_reg(priv, XCAN_ISR_OFFSET);
+ }
+
+ if (isr & XCAN_IXR_TXFEMP_MASK) {
+ /* nothing in FIFO anymore */
+ frames_sent = frames_in_fifo;
+ }
+ } else {
+ /* single frame in fifo, just clear TXOK */
+ priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_TXOK_MASK);
+ }
+
+ while (frames_sent--) {
can_get_echo_skb(ndev, priv->tx_tail %
priv->tx_max);
priv->tx_tail++;
stats->tx_packets++;
- isr = priv->read_reg(priv, XCAN_ISR_OFFSET);
}
- can_led_event(ndev, CAN_LED_EVENT_TX);
+
netif_wake_queue(ndev);
+
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
+
+ can_led_event(ndev, CAN_LED_EVENT_TX);
+ xcan_update_error_state_after_rxtx(ndev);
}
/**
@@ -773,6 +938,7 @@
struct net_device *ndev = (struct net_device *)dev_id;
struct xcan_priv *priv = netdev_priv(ndev);
u32 isr, ier;
+ u32 isr_errors;
/* Get the interrupt status from Xilinx CAN */
isr = priv->read_reg(priv, XCAN_ISR_OFFSET);
@@ -791,18 +957,17 @@
xcan_tx_interrupt(ndev, isr);
/* Check for the type of error interrupt and Processing it */
- if (isr & (XCAN_IXR_ERROR_MASK | XCAN_IXR_RXOFLW_MASK |
- XCAN_IXR_BSOFF_MASK | XCAN_IXR_ARBLST_MASK)) {
- priv->write_reg(priv, XCAN_ICR_OFFSET, (XCAN_IXR_ERROR_MASK |
- XCAN_IXR_RXOFLW_MASK | XCAN_IXR_BSOFF_MASK |
- XCAN_IXR_ARBLST_MASK));
+ isr_errors = isr & (XCAN_IXR_ERROR_MASK | XCAN_IXR_RXOFLW_MASK |
+ XCAN_IXR_BSOFF_MASK | XCAN_IXR_ARBLST_MASK);
+ if (isr_errors) {
+ priv->write_reg(priv, XCAN_ICR_OFFSET, isr_errors);
xcan_err_interrupt(ndev, isr);
}
/* Check for the type of receive interrupt and Processing it */
- if (isr & (XCAN_IXR_RXNEMP_MASK | XCAN_IXR_RXOK_MASK)) {
+ if (isr & XCAN_IXR_RXNEMP_MASK) {
ier = priv->read_reg(priv, XCAN_IER_OFFSET);
- ier &= ~(XCAN_IXR_RXNEMP_MASK | XCAN_IXR_RXOK_MASK);
+ ier &= ~XCAN_IXR_RXNEMP_MASK;
priv->write_reg(priv, XCAN_IER_OFFSET, ier);
napi_schedule(&priv->napi);
}
@@ -819,13 +984,9 @@
static void xcan_chip_stop(struct net_device *ndev)
{
struct xcan_priv *priv = netdev_priv(ndev);
- u32 ier;
/* Disable interrupts and leave the can in configuration mode */
- ier = priv->read_reg(priv, XCAN_IER_OFFSET);
- ier &= ~XCAN_INTR_ALL;
- priv->write_reg(priv, XCAN_IER_OFFSET, ier);
- priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_RESET_MASK);
+ set_reset_mode(ndev);
priv->can.state = CAN_STATE_STOPPED;
}
@@ -958,10 +1119,15 @@
*/
static int __maybe_unused xcan_suspend(struct device *dev)
{
- if (!device_may_wakeup(dev))
- return pm_runtime_force_suspend(dev);
+ struct net_device *ndev = dev_get_drvdata(dev);
- return 0;
+ if (netif_running(ndev)) {
+ netif_stop_queue(ndev);
+ netif_device_detach(ndev);
+ xcan_chip_stop(ndev);
+ }
+
+ return pm_runtime_force_suspend(dev);
}
/**
@@ -973,11 +1139,27 @@
*/
static int __maybe_unused xcan_resume(struct device *dev)
{
- if (!device_may_wakeup(dev))
- return pm_runtime_force_resume(dev);
+ struct net_device *ndev = dev_get_drvdata(dev);
+ int ret;
+
+ ret = pm_runtime_force_resume(dev);
+ if (ret) {
+ dev_err(dev, "pm_runtime_force_resume failed on resume\n");
+ return ret;
+ }
+
+ if (netif_running(ndev)) {
+ ret = xcan_chip_start(ndev);
+ if (ret) {
+ dev_err(dev, "xcan_chip_start failed on resume\n");
+ return ret;
+ }
+
+ netif_device_attach(ndev);
+ netif_start_queue(ndev);
+ }
return 0;
-
}
/**
@@ -992,14 +1174,6 @@
struct net_device *ndev = dev_get_drvdata(dev);
struct xcan_priv *priv = netdev_priv(ndev);
- if (netif_running(ndev)) {
- netif_stop_queue(ndev);
- netif_device_detach(ndev);
- }
-
- priv->write_reg(priv, XCAN_MSR_OFFSET, XCAN_MSR_SLEEP_MASK);
- priv->can.state = CAN_STATE_SLEEPING;
-
clk_disable_unprepare(priv->bus_clk);
clk_disable_unprepare(priv->can_clk);
@@ -1018,7 +1192,6 @@
struct net_device *ndev = dev_get_drvdata(dev);
struct xcan_priv *priv = netdev_priv(ndev);
int ret;
- u32 isr, status;
ret = clk_prepare_enable(priv->bus_clk);
if (ret) {
@@ -1032,27 +1205,6 @@
return ret;
}
- priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_RESET_MASK);
- isr = priv->read_reg(priv, XCAN_ISR_OFFSET);
- status = priv->read_reg(priv, XCAN_SR_OFFSET);
-
- if (netif_running(ndev)) {
- if (isr & XCAN_IXR_BSOFF_MASK) {
- priv->can.state = CAN_STATE_BUS_OFF;
- priv->write_reg(priv, XCAN_SRR_OFFSET,
- XCAN_SRR_RESET_MASK);
- } else if ((status & XCAN_SR_ESTAT_MASK) ==
- XCAN_SR_ESTAT_MASK) {
- priv->can.state = CAN_STATE_ERROR_PASSIVE;
- } else if (status & XCAN_SR_ERRWRN_MASK) {
- priv->can.state = CAN_STATE_ERROR_WARNING;
- } else {
- priv->can.state = CAN_STATE_ERROR_ACTIVE;
- }
- netif_device_attach(ndev);
- netif_start_queue(ndev);
- }
-
return 0;
}
@@ -1061,6 +1213,18 @@
SET_RUNTIME_PM_OPS(xcan_runtime_suspend, xcan_runtime_resume, NULL)
};
+static const struct xcan_devtype_data xcan_zynq_data = {
+ .caps = XCAN_CAP_WATERMARK,
+};
+
+/* Match table for OF platform binding */
+static const struct of_device_id xcan_of_match[] = {
+ { .compatible = "xlnx,zynq-can-1.0", .data = &xcan_zynq_data },
+ { .compatible = "xlnx,axi-can-1.00.a", },
+ { /* end of list */ },
+};
+MODULE_DEVICE_TABLE(of, xcan_of_match);
+
/**
* xcan_probe - Platform registration call
* @pdev: Handle to the platform device structure
@@ -1075,8 +1239,10 @@
struct resource *res; /* IO mem resources */
struct net_device *ndev;
struct xcan_priv *priv;
+ const struct of_device_id *of_id;
+ int caps = 0;
void __iomem *addr;
- int ret, rx_max, tx_max;
+ int ret, rx_max, tx_max, tx_fifo_depth;
/* Get the virtual base address for the device */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1086,7 +1252,8 @@
goto err;
}
- ret = of_property_read_u32(pdev->dev.of_node, "tx-fifo-depth", &tx_max);
+ ret = of_property_read_u32(pdev->dev.of_node, "tx-fifo-depth",
+ &tx_fifo_depth);
if (ret < 0)
goto err;
@@ -1094,6 +1261,30 @@
if (ret < 0)
goto err;
+ of_id = of_match_device(xcan_of_match, &pdev->dev);
+ if (of_id) {
+ const struct xcan_devtype_data *devtype_data = of_id->data;
+
+ if (devtype_data)
+ caps = devtype_data->caps;
+ }
+
+ /* There is no way to directly figure out how many frames have been
+ * sent when the TXOK interrupt is processed. If watermark programming
+ * is supported, we can have 2 frames in the FIFO and use TXFEMP
+ * to determine if 1 or 2 frames have been sent.
+ * Theoretically we should be able to use TXFWMEMP to determine up
+ * to 3 frames, but it seems that after putting a second frame in the
+ * FIFO, with watermark at 2 frames, it can happen that TXFWMEMP (less
+ * than 2 frames in FIFO) is set anyway with no TXOK (a frame was
+ * sent), which is not a sensible state - possibly TXFWMEMP is not
+ * completely synchronized with the rest of the bits?
+ */
+ if (caps & XCAN_CAP_WATERMARK)
+ tx_max = min(tx_fifo_depth, 2);
+ else
+ tx_max = 1;
+
/* Create a CAN device instance */
ndev = alloc_candev(sizeof(struct xcan_priv), tx_max);
if (!ndev)
@@ -1108,6 +1299,7 @@
CAN_CTRLMODE_BERR_REPORTING;
priv->reg_base = addr;
priv->tx_max = tx_max;
+ spin_lock_init(&priv->tx_lock);
/* Get IRQ for the device */
ndev->irq = platform_get_irq(pdev, 0);
@@ -1172,9 +1364,9 @@
pm_runtime_put(&pdev->dev);
- netdev_dbg(ndev, "reg_base=0x%p irq=%d clock=%d, tx fifo depth:%d\n",
+ netdev_dbg(ndev, "reg_base=0x%p irq=%d clock=%d, tx fifo depth: actual %d, using %d\n",
priv->reg_base, ndev->irq, priv->can.clock.freq,
- priv->tx_max);
+ tx_fifo_depth, priv->tx_max);
return 0;
@@ -1208,14 +1400,6 @@
return 0;
}
-/* Match table for OF platform binding */
-static const struct of_device_id xcan_of_match[] = {
- { .compatible = "xlnx,zynq-can-1.0", },
- { .compatible = "xlnx,axi-can-1.00.a", },
- { /* end of list */ },
-};
-MODULE_DEVICE_TABLE(of, xcan_of_match);
-
static struct platform_driver xcan_driver = {
.probe = xcan_probe,
.remove = xcan_remove,
diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index b3df70d..7f64a76 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -474,7 +474,7 @@
static void
qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable)
{
- u32 mask = QCA8K_PORT_STATUS_TXMAC;
+ u32 mask = QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC;
/* Port 0 and 6 have no internal PHY */
if ((port > 0) && (port < 6))
@@ -491,6 +491,7 @@
{
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
int ret, i, phy_mode = -1;
+ u32 mask;
/* Make sure that port 0 is the cpu port */
if (!dsa_is_cpu_port(ds, 0)) {
@@ -516,7 +517,10 @@
if (ret < 0)
return ret;
- /* Enable CPU Port */
+ /* Enable CPU Port, force it to maximum bandwidth and full-duplex */
+ mask = QCA8K_PORT_STATUS_SPEED_1000 | QCA8K_PORT_STATUS_TXFLOW |
+ QCA8K_PORT_STATUS_RXFLOW | QCA8K_PORT_STATUS_DUPLEX;
+ qca8k_write(priv, QCA8K_REG_PORT_STATUS(QCA8K_CPU_PORT), mask);
qca8k_reg_set(priv, QCA8K_REG_GLOBAL_FW_CTRL0,
QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
qca8k_port_set_status(priv, QCA8K_CPU_PORT, 1);
@@ -585,6 +589,47 @@
return 0;
}
+static void
+qca8k_adjust_link(struct dsa_switch *ds, int port, struct phy_device *phy)
+{
+ struct qca8k_priv *priv = ds->priv;
+ u32 reg;
+
+ /* Force fixed-link setting for CPU port, skip others. */
+ if (!phy_is_pseudo_fixed_link(phy))
+ return;
+
+ /* Set port speed */
+ switch (phy->speed) {
+ case 10:
+ reg = QCA8K_PORT_STATUS_SPEED_10;
+ break;
+ case 100:
+ reg = QCA8K_PORT_STATUS_SPEED_100;
+ break;
+ case 1000:
+ reg = QCA8K_PORT_STATUS_SPEED_1000;
+ break;
+ default:
+ dev_dbg(priv->dev, "port%d link speed %dMbps not supported.\n",
+ port, phy->speed);
+ return;
+ }
+
+ /* Set duplex mode */
+ if (phy->duplex == DUPLEX_FULL)
+ reg |= QCA8K_PORT_STATUS_DUPLEX;
+
+ /* Force flow control */
+ if (dsa_is_cpu_port(ds, port))
+ reg |= QCA8K_PORT_STATUS_RXFLOW | QCA8K_PORT_STATUS_TXFLOW;
+
+ /* Force link down before changing MAC options */
+ qca8k_port_set_status(priv, port, 0);
+ qca8k_write(priv, QCA8K_REG_PORT_STATUS(port), reg);
+ qca8k_port_set_status(priv, port, 1);
+}
+
static int
qca8k_phy_read(struct dsa_switch *ds, int phy, int regnum)
{
@@ -914,6 +959,7 @@
static struct dsa_switch_ops qca8k_switch_ops = {
.get_tag_protocol = qca8k_get_tag_protocol,
.setup = qca8k_setup,
+ .adjust_link = qca8k_adjust_link,
.get_strings = qca8k_get_strings,
.phy_read = qca8k_phy_read,
.phy_write = qca8k_phy_write,
@@ -946,6 +992,7 @@
return -ENOMEM;
priv->bus = mdiodev->bus;
+ priv->dev = &mdiodev->dev;
/* read the switches ID register */
id = qca8k_read(priv, QCA8K_REG_MASK_CTRL);
@@ -1018,6 +1065,7 @@
qca8k_suspend, qca8k_resume);
static const struct of_device_id qca8k_of_match[] = {
+ { .compatible = "qca,qca8334" },
{ .compatible = "qca,qca8337" },
{ /* sentinel */ },
};
diff --git a/drivers/net/dsa/qca8k.h b/drivers/net/dsa/qca8k.h
index 2014647..9c22bc3 100644
--- a/drivers/net/dsa/qca8k.h
+++ b/drivers/net/dsa/qca8k.h
@@ -51,8 +51,10 @@
#define QCA8K_GOL_MAC_ADDR0 0x60
#define QCA8K_GOL_MAC_ADDR1 0x64
#define QCA8K_REG_PORT_STATUS(_i) (0x07c + (_i) * 4)
-#define QCA8K_PORT_STATUS_SPEED GENMASK(2, 0)
-#define QCA8K_PORT_STATUS_SPEED_S 0
+#define QCA8K_PORT_STATUS_SPEED GENMASK(1, 0)
+#define QCA8K_PORT_STATUS_SPEED_10 0
+#define QCA8K_PORT_STATUS_SPEED_100 0x1
+#define QCA8K_PORT_STATUS_SPEED_1000 0x2
#define QCA8K_PORT_STATUS_TXMAC BIT(2)
#define QCA8K_PORT_STATUS_RXMAC BIT(3)
#define QCA8K_PORT_STATUS_TXFLOW BIT(4)
@@ -167,6 +169,7 @@
struct ar8xxx_port_status port_sts[QCA8K_NUM_PORTS];
struct dsa_switch *ds;
struct mutex reg_mutex;
+ struct device *dev;
};
struct qca8k_mib_desc {
diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
index 08d91ef..c407840 100644
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -1063,7 +1063,8 @@
val = enet_readl(priv, ENET_CTL_REG);
val |= ENET_CTL_ENABLE_MASK;
enet_writel(priv, val, ENET_CTL_REG);
- enet_dma_writel(priv, ENETDMA_CFG_EN_MASK, ENETDMA_CFG_REG);
+ if (priv->dma_has_sram)
+ enet_dma_writel(priv, ENETDMA_CFG_EN_MASK, ENETDMA_CFG_REG);
enet_dmac_writel(priv, priv->dma_chan_en_mask,
ENETDMAC_CHANCFG, priv->rx_chan);
@@ -1790,7 +1791,9 @@
ret = PTR_ERR(priv->mac_clk);
goto out;
}
- clk_prepare_enable(priv->mac_clk);
+ ret = clk_prepare_enable(priv->mac_clk);
+ if (ret)
+ goto out_put_clk_mac;
/* initialize default and fetch platform data */
priv->rx_ring_size = BCMENET_DEF_RX_DESC;
@@ -1822,9 +1825,11 @@
if (IS_ERR(priv->phy_clk)) {
ret = PTR_ERR(priv->phy_clk);
priv->phy_clk = NULL;
- goto out_put_clk_mac;
+ goto out_disable_clk_mac;
}
- clk_prepare_enable(priv->phy_clk);
+ ret = clk_prepare_enable(priv->phy_clk);
+ if (ret)
+ goto out_put_clk_phy;
}
/* do minimal hardware init to be able to probe mii bus */
@@ -1915,13 +1920,16 @@
out_uninit_hw:
/* turn off mdc clock */
enet_writel(priv, 0, ENET_MIISC_REG);
- if (priv->phy_clk) {
+ if (priv->phy_clk)
clk_disable_unprepare(priv->phy_clk);
- clk_put(priv->phy_clk);
- }
-out_put_clk_mac:
+out_put_clk_phy:
+ if (priv->phy_clk)
+ clk_put(priv->phy_clk);
+
+out_disable_clk_mac:
clk_disable_unprepare(priv->mac_clk);
+out_put_clk_mac:
clk_put(priv->mac_clk);
out:
free_netdev(dev);
@@ -2766,7 +2774,9 @@
ret = PTR_ERR(priv->mac_clk);
goto out_unmap;
}
- clk_enable(priv->mac_clk);
+ ret = clk_prepare_enable(priv->mac_clk);
+ if (ret)
+ goto out_put_clk;
priv->rx_chan = 0;
priv->tx_chan = 1;
@@ -2787,7 +2797,7 @@
ret = register_netdev(dev);
if (ret)
- goto out_put_clk;
+ goto out_disable_clk;
netif_carrier_off(dev);
platform_set_drvdata(pdev, dev);
@@ -2796,6 +2806,9 @@
return 0;
+out_disable_clk:
+ clk_disable_unprepare(priv->mac_clk);
+
out_put_clk:
clk_put(priv->mac_clk);
@@ -2827,6 +2840,9 @@
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(res->start, resource_size(res));
+ clk_disable_unprepare(priv->mac_clk);
+ clk_put(priv->mac_clk);
+
free_netdev(dev);
return 0;
}
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index ca57eb5..8777c3a 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -5257,6 +5257,9 @@
}
mutex_unlock(&bp->hwrm_cmd_lock);
+ if (!BNXT_SINGLE_PF(bp))
+ return 0;
+
diff = link_info->support_auto_speeds ^ link_info->advertising;
if ((link_info->support_auto_speeds | diff) !=
link_info->support_auto_speeds) {
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 4ffbe85..6250989 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -9276,6 +9276,15 @@
tg3_restore_clk(tp);
+ /* Increase the core clock speed to fix tx timeout issue for 5762
+ * with 100Mbps link speed.
+ */
+ if (tg3_asic_rev(tp) == ASIC_REV_5762) {
+ val = tr32(TG3_CPMU_CLCK_ORIDE_ENABLE);
+ tw32(TG3_CPMU_CLCK_ORIDE_ENABLE, val |
+ TG3_CPMU_MAC_ORIDE_ENABLE);
+ }
+
/* Reprobe ASF enable state. */
tg3_flag_clear(tp, ENABLE_ASF);
tp->phy_flags &= ~(TG3_PHYFLG_1G_ON_VAUX_OK |
diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
index 43da891..dc0efbd 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
@@ -50,6 +50,7 @@
#include <linux/stringify.h>
#include <linux/sched.h>
#include <linux/slab.h>
+#include <linux/nospec.h>
#include <asm/uaccess.h>
#include "common.h"
@@ -2259,6 +2260,7 @@
if (t.qset_idx >= nqsets)
return -EINVAL;
+ t.qset_idx = array_index_nospec(t.qset_idx, nqsets);
q = &adapter->params.sge.qset[q1 + t.qset_idx];
t.rspq_size = q->rspq_size;
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 1499ce2b..0295132 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -3729,6 +3729,7 @@
return -EPERM;
ether_addr_copy(hw->mac.addr, addr->sa_data);
+ ether_addr_copy(hw->mac.perm_addr, addr->sa_data);
ether_addr_copy(netdev->dev_addr, addr->sa_data);
return 0;
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index d6b06be..9d1a7d5 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -2916,7 +2916,7 @@
u32 srqn = qp_get_srqn(qpc) & 0xffffff;
int use_srq = (qp_get_srqn(qpc) >> 24) & 1;
struct res_srq *srq;
- int local_qpn = be32_to_cpu(qpc->local_qpn) & 0xffffff;
+ int local_qpn = vhcr->in_modifier & 0xffffff;
err = adjust_qp_sched_queue(dev, slave, qpc, inbox);
if (err)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
index 6631fb0..9680c880 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
@@ -784,6 +784,7 @@
struct semaphore *sem;
unsigned long flags;
int alloc_ret;
+ int cmd_mode;
sem = ent->page_queue ? &cmd->pages_sem : &cmd->sem;
down(sem);
@@ -830,6 +831,7 @@
set_signature(ent, !cmd->checksum_disabled);
dump_command(dev, ent, 1);
ent->ts1 = ktime_get_ns();
+ cmd_mode = cmd->mode;
if (ent->callback)
schedule_delayed_work(&ent->cb_timeout_work, cb_timeout);
@@ -854,7 +856,7 @@
iowrite32be(1 << ent->idx, &dev->iseg->cmd_dbell);
mmiowb();
/* if not in polling don't use ent after this point */
- if (cmd->mode == CMD_MODE_POLLING) {
+ if (cmd_mode == CMD_MODE_POLLING) {
poll_timeout(ent);
/* make sure we read the descriptor after ownership is SW */
rmb();
@@ -1256,7 +1258,7 @@
{
struct mlx5_core_dev *dev = filp->private_data;
struct mlx5_cmd_debug *dbg = &dev->cmd.dbg;
- char outlen_str[8];
+ char outlen_str[8] = {0};
int outlen;
void *ptr;
int err;
@@ -1271,8 +1273,6 @@
if (copy_from_user(outlen_str, buf, count))
return -EFAULT;
- outlen_str[7] = 0;
-
err = sscanf(outlen_str, "%d", &outlen);
if (err < 0)
return err;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c
index a8cb387..4a51fc6 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c
@@ -383,14 +383,14 @@
HLIST_HEAD(del_list);
spin_lock_bh(&priv->fs.arfs.arfs_lock);
mlx5e_for_each_arfs_rule(arfs_rule, htmp, priv->fs.arfs.arfs_tables, i, j) {
- if (quota++ > MLX5E_ARFS_EXPIRY_QUOTA)
- break;
if (!work_pending(&arfs_rule->arfs_work) &&
rps_may_expire_flow(priv->netdev,
arfs_rule->rxq, arfs_rule->flow_id,
arfs_rule->filter_id)) {
hlist_del_init(&arfs_rule->hlist);
hlist_add_head(&arfs_rule->hlist, &del_list);
+ if (quota++ > MLX5E_ARFS_EXPIRY_QUOTA)
+ break;
}
}
spin_unlock_bh(&priv->fs.arfs.arfs_lock);
@@ -715,6 +715,9 @@
skb->protocol != htons(ETH_P_IPV6))
return -EPROTONOSUPPORT;
+ if (skb->encapsulation)
+ return -EPROTONOSUPPORT;
+
arfs_t = arfs_get_table(arfs, arfs_get_ip_proto(skb), skb->protocol);
if (!arfs_t)
return -EPROTONOSUPPORT;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_clock.c b/drivers/net/ethernet/mellanox/mlx5/core/en_clock.c
index 1612ec0..f8b99d0 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_clock.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_clock.c
@@ -233,6 +233,7 @@
void mlx5e_timestamp_init(struct mlx5e_priv *priv)
{
struct mlx5e_tstamp *tstamp = &priv->tstamp;
+ u64 overflow_cycles;
u64 ns;
u64 frac = 0;
u32 dev_freq;
@@ -257,10 +258,17 @@
/* Calculate period in seconds to call the overflow watchdog - to make
* sure counter is checked at least once every wrap around.
+ * The period is calculated as the minimum between max HW cycles count
+ * (The clock source mask) and max amount of cycles that can be
+ * multiplied by clock multiplier where the result doesn't exceed
+ * 64bits.
*/
- ns = cyclecounter_cyc2ns(&tstamp->cycles, tstamp->cycles.mask,
+ overflow_cycles = div64_u64(~0ULL >> 1, tstamp->cycles.mult);
+ overflow_cycles = min(overflow_cycles, tstamp->cycles.mask >> 1);
+
+ ns = cyclecounter_cyc2ns(&tstamp->cycles, overflow_cycles,
frac, &frac);
- do_div(ns, NSEC_PER_SEC / 2 / HZ);
+ do_div(ns, NSEC_PER_SEC / HZ);
tstamp->overflow_period = ns;
INIT_DELAYED_WORK(&tstamp->overflow_work, mlx5e_timestamp_overflow);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c b/drivers/net/ethernet/mellanox/mlx5/core/port.c
index 34e7184..43d7c83 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/port.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c
@@ -575,7 +575,7 @@
static int mlx5_set_port_qetcr_reg(struct mlx5_core_dev *mdev, u32 *in,
int inlen)
{
- u32 out[MLX5_ST_SZ_DW(qtct_reg)];
+ u32 out[MLX5_ST_SZ_DW(qetc_reg)];
if (!MLX5_CAP_GEN(mdev, ets))
return -ENOTSUPP;
@@ -587,7 +587,7 @@
static int mlx5_query_port_qetcr_reg(struct mlx5_core_dev *mdev, u32 *out,
int outlen)
{
- u32 in[MLX5_ST_SZ_DW(qtct_reg)];
+ u32 in[MLX5_ST_SZ_DW(qetc_reg)];
if (!MLX5_CAP_GEN(mdev, ets))
return -ENOTSUPP;
diff --git a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
index 9d59cb8..7b6824e 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
@@ -677,9 +677,9 @@
p_local = &p_hwfn->p_dcbx_info->lldp_local[LLDP_NEAREST_BRIDGE];
memcpy(params->lldp_local.local_chassis_id, p_local->local_chassis_id,
- ARRAY_SIZE(p_local->local_chassis_id));
+ sizeof(p_local->local_chassis_id));
memcpy(params->lldp_local.local_port_id, p_local->local_port_id,
- ARRAY_SIZE(p_local->local_port_id));
+ sizeof(p_local->local_port_id));
}
static void
@@ -692,9 +692,9 @@
p_remote = &p_hwfn->p_dcbx_info->lldp_remote[LLDP_NEAREST_BRIDGE];
memcpy(params->lldp_remote.peer_chassis_id, p_remote->peer_chassis_id,
- ARRAY_SIZE(p_remote->peer_chassis_id));
+ sizeof(p_remote->peer_chassis_id));
memcpy(params->lldp_remote.peer_port_id, p_remote->peer_port_id,
- ARRAY_SIZE(p_remote->peer_port_id));
+ sizeof(p_remote->peer_port_id));
}
static int
diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c
index 0b949c6..f36bd0b 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_main.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_main.c
@@ -23,6 +23,7 @@
#include <linux/vmalloc.h>
#include <linux/qed/qed_if.h>
#include <linux/qed/qed_ll2_if.h>
+#include <linux/crash_dump.h>
#include "qed.h"
#include "qed_sriov.h"
@@ -701,6 +702,14 @@
/* We want a minimum of one slowpath and one fastpath vector per hwfn */
cdev->int_params.in.min_msix_cnt = cdev->num_hwfns * 2;
+ if (is_kdump_kernel()) {
+ DP_INFO(cdev,
+ "Kdump kernel: Limit the max number of requested MSI-X vectors to %hd\n",
+ cdev->int_params.in.min_msix_cnt);
+ cdev->int_params.in.num_vectors =
+ cdev->int_params.in.min_msix_cnt;
+ }
+
rc = qed_set_int_mode(cdev, false);
if (rc) {
DP_ERR(cdev, "qed_slowpath_setup_int ERR\n");
diff --git a/drivers/net/ethernet/sun/sungem.c b/drivers/net/ethernet/sun/sungem.c
index d6ad0fb..920321b 100644
--- a/drivers/net/ethernet/sun/sungem.c
+++ b/drivers/net/ethernet/sun/sungem.c
@@ -59,8 +59,7 @@
#include <linux/sungem_phy.h>
#include "sungem.h"
-/* Stripping FCS is causing problems, disabled for now */
-#undef STRIP_FCS
+#define STRIP_FCS
#define DEFAULT_MSG (NETIF_MSG_DRV | \
NETIF_MSG_PROBE | \
@@ -434,7 +433,7 @@
writel(desc_dma & 0xffffffff, gp->regs + RXDMA_DBLOW);
writel(RX_RING_SIZE - 4, gp->regs + RXDMA_KICK);
val = (RXDMA_CFG_BASE | (RX_OFFSET << 10) |
- ((14 / 2) << 13) | RXDMA_CFG_FTHRESH_128);
+ (ETH_HLEN << 13) | RXDMA_CFG_FTHRESH_128);
writel(val, gp->regs + RXDMA_CFG);
if (readl(gp->regs + GREG_BIFCFG) & GREG_BIFCFG_M66EN)
writel(((5 & RXDMA_BLANK_IPKTS) |
@@ -759,7 +758,6 @@
struct net_device *dev = gp->dev;
int entry, drops, work_done = 0;
u32 done;
- __sum16 csum;
if (netif_msg_rx_status(gp))
printk(KERN_DEBUG "%s: rx interrupt, done: %d, rx_new: %d\n",
@@ -854,9 +852,13 @@
skb = copy_skb;
}
- csum = (__force __sum16)htons((status & RXDCTRL_TCPCSUM) ^ 0xffff);
- skb->csum = csum_unfold(csum);
- skb->ip_summed = CHECKSUM_COMPLETE;
+ if (likely(dev->features & NETIF_F_RXCSUM)) {
+ __sum16 csum;
+
+ csum = (__force __sum16)htons((status & RXDCTRL_TCPCSUM) ^ 0xffff);
+ skb->csum = csum_unfold(csum);
+ skb->ip_summed = CHECKSUM_COMPLETE;
+ }
skb->protocol = eth_type_trans(skb, gp->dev);
napi_gro_receive(&gp->napi, skb);
@@ -1754,7 +1756,7 @@
writel(0, gp->regs + TXDMA_KICK);
val = (RXDMA_CFG_BASE | (RX_OFFSET << 10) |
- ((14 / 2) << 13) | RXDMA_CFG_FTHRESH_128);
+ (ETH_HLEN << 13) | RXDMA_CFG_FTHRESH_128);
writel(val, gp->regs + RXDMA_CFG);
writel(desc_dma >> 32, gp->regs + RXDMA_DBHI);
@@ -2972,8 +2974,8 @@
pci_set_drvdata(pdev, dev);
/* We can do scatter/gather and HW checksum */
- dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM;
- dev->features |= dev->hw_features | NETIF_F_RXCSUM;
+ dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
+ dev->features = dev->hw_features;
if (pci_using_dac)
dev->features |= NETIF_F_HIGHDMA;
diff --git a/drivers/net/ethernet/ti/cpsw-phy-sel.c b/drivers/net/ethernet/ti/cpsw-phy-sel.c
index 1801364..0c1adad 100644
--- a/drivers/net/ethernet/ti/cpsw-phy-sel.c
+++ b/drivers/net/ethernet/ti/cpsw-phy-sel.c
@@ -177,12 +177,18 @@
}
dev = bus_find_device(&platform_bus_type, NULL, node, match);
- of_node_put(node);
+ if (!dev) {
+ dev_err(dev, "unable to find platform device for %pOF\n", node);
+ goto out;
+ }
+
priv = dev_get_drvdata(dev);
priv->cpsw_phy_sel(priv, phy_mode, slave);
put_device(dev);
+out:
+ of_node_put(node);
}
EXPORT_SYMBOL_GPL(cpsw_phy_sel);
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
index dfbc4ef..24eb575 100644
--- a/drivers/net/ipvlan/ipvlan_main.c
+++ b/drivers/net/ipvlan/ipvlan_main.c
@@ -525,7 +525,8 @@
ipvlan->dev = dev;
ipvlan->port = port;
ipvlan->sfeatures = IPVLAN_FEATURES;
- ipvlan_adjust_mtu(ipvlan, phy_dev);
+ if (!tb[IFLA_MTU])
+ ipvlan_adjust_mtu(ipvlan, phy_dev);
INIT_LIST_HEAD(&ipvlan->addrs);
/* TODO Probably put random address here to be presented to the
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 4d21764..5fde8e3 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -598,7 +598,7 @@
* negotiation may already be done and aneg interrupt may not be
* generated.
*/
- if (phy_interrupt_is_valid(phydev) && (phydev->state == PHY_AN)) {
+ if (phydev->irq != PHY_POLL && phydev->state == PHY_AN) {
err = phy_aneg_done(phydev);
if (err > 0) {
trigger = true;
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index bf02f8e..b131e55 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1579,11 +1579,8 @@
static int __set_phy_supported(struct phy_device *phydev, u32 max_speed)
{
- /* The default values for phydev->supported are provided by the PHY
- * driver "features" member, we want to reset to sane defaults first
- * before supporting higher speeds.
- */
- phydev->supported &= PHY_DEFAULT_FEATURES;
+ phydev->supported &= ~(PHY_1000BT_FEATURES | PHY_100BT_FEATURES |
+ PHY_10BT_FEATURES);
switch (max_speed) {
default:
diff --git a/drivers/net/ppp/pppolac.c b/drivers/net/ppp/pppolac.c
index 3a45cf8..8ed8091 100644
--- a/drivers/net/ppp/pppolac.c
+++ b/drivers/net/ppp/pppolac.c
@@ -83,7 +83,7 @@
/* Put it back if it is a control packet. */
if (skb->data[sizeof(struct udphdr)] & L2TP_CONTROL_BIT)
- return opt->backlog_rcv(sk_udp, skb);
+ return 2;
/* Skip UDP header. */
skb_pull(skb, sizeof(struct udphdr));
@@ -190,9 +190,10 @@
static int pppolac_recv(struct sock *sk_udp, struct sk_buff *skb)
{
+ int retval;
sock_hold(sk_udp);
- sk_receive_skb(sk_udp, skb, 0);
- return 0;
+ retval = sk_receive_skb(sk_udp, skb, 0);
+ return (retval >> 1);
}
static struct sk_buff_head delivery_queue;
diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c
index 32e9ec8..5be6b67 100644
--- a/drivers/net/usb/asix_devices.c
+++ b/drivers/net/usb/asix_devices.c
@@ -640,10 +640,12 @@
priv->presvd_phy_advertise);
/* Restore BMCR */
+ if (priv->presvd_phy_bmcr & BMCR_ANENABLE)
+ priv->presvd_phy_bmcr |= BMCR_ANRESTART;
+
asix_mdio_write_nopm(dev->net, dev->mii.phy_id, MII_BMCR,
priv->presvd_phy_bmcr);
- mii_nway_restart(&dev->mii);
priv->presvd_phy_advertise = 0;
priv->presvd_phy_bmcr = 0;
}
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
index 3e66e40..dc18a5a 100644
--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -2969,6 +2969,7 @@
pkt_cnt = 0;
count = 0;
length = 0;
+ spin_lock_irqsave(&tqp->lock, flags);
for (skb = tqp->next; pkt_cnt < tqp->qlen; skb = skb->next) {
if (skb_is_gso(skb)) {
if (pkt_cnt) {
@@ -2977,7 +2978,8 @@
}
count = 1;
length = skb->len - TX_OVERHEAD;
- skb2 = skb_dequeue(tqp);
+ __skb_unlink(skb, tqp);
+ spin_unlock_irqrestore(&tqp->lock, flags);
goto gso_skb;
}
@@ -2986,6 +2988,7 @@
skb_totallen = skb->len + roundup(skb_totallen, sizeof(u32));
pkt_cnt++;
}
+ spin_unlock_irqrestore(&tqp->lock, flags);
/* copy to a single skb */
skb = alloc_skb(skb_totallen, GFP_ATOMIC);
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index 85bc0ca..31a6d87 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -946,12 +946,14 @@
{QMI_FIXED_INTF(0x413c, 0x81b3, 8)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */
{QMI_FIXED_INTF(0x413c, 0x81b6, 8)}, /* Dell Wireless 5811e */
{QMI_FIXED_INTF(0x413c, 0x81b6, 10)}, /* Dell Wireless 5811e */
+ {QMI_FIXED_INTF(0x413c, 0x81d7, 1)}, /* Dell Wireless 5821e */
{QMI_FIXED_INTF(0x03f0, 0x4e1d, 8)}, /* HP lt4111 LTE/EV-DO/HSPA+ Gobi 4G Module */
{QMI_FIXED_INTF(0x03f0, 0x9d1d, 1)}, /* HP lt4120 Snapdragon X5 LTE */
{QMI_FIXED_INTF(0x22de, 0x9061, 3)}, /* WeTelecom WPD-600N */
{QMI_FIXED_INTF(0x1e0e, 0x9001, 5)}, /* SIMCom 7230E */
{QMI_QUIRK_SET_DTR(0x2c7c, 0x0125, 4)}, /* Quectel EC25, EC20 R2.0 Mini PCIe */
{QMI_QUIRK_SET_DTR(0x2c7c, 0x0121, 4)}, /* Quectel EC21 Mini PCIe */
+ {QMI_QUIRK_SET_DTR(0x2c7c, 0x0191, 4)}, /* Quectel EG91 */
{QMI_FIXED_INTF(0x2c7c, 0x0296, 4)}, /* Quectel BG96 */
{QMI_QUIRK_SET_DTR(0x2c7c, 0x0306, 4)}, /* Quectel EP06 Mini PCIe */
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index d3d89b0..5988674 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -3327,7 +3327,8 @@
#ifdef CONFIG_PM_SLEEP
unregister_pm_notifier(&tp->pm_notifier);
#endif
- napi_disable(&tp->napi);
+ if (!test_bit(RTL8152_UNPLUG, &tp->flags))
+ napi_disable(&tp->napi);
clear_bit(WORK_ENABLE, &tp->flags);
usb_kill_urb(tp->intr_urb);
cancel_delayed_work_sync(&tp->schedule);
diff --git a/drivers/net/wireless/ath/regd.h b/drivers/net/wireless/ath/regd.h
index 565d307..8553ab4 100644
--- a/drivers/net/wireless/ath/regd.h
+++ b/drivers/net/wireless/ath/regd.h
@@ -68,12 +68,14 @@
CTRY_AUSTRALIA = 36,
CTRY_AUSTRIA = 40,
CTRY_AZERBAIJAN = 31,
+ CTRY_BAHAMAS = 44,
CTRY_BAHRAIN = 48,
CTRY_BANGLADESH = 50,
CTRY_BARBADOS = 52,
CTRY_BELARUS = 112,
CTRY_BELGIUM = 56,
CTRY_BELIZE = 84,
+ CTRY_BERMUDA = 60,
CTRY_BOLIVIA = 68,
CTRY_BOSNIA_HERZ = 70,
CTRY_BRAZIL = 76,
@@ -159,6 +161,7 @@
CTRY_ROMANIA = 642,
CTRY_RUSSIA = 643,
CTRY_SAUDI_ARABIA = 682,
+ CTRY_SERBIA = 688,
CTRY_SERBIA_MONTENEGRO = 891,
CTRY_SINGAPORE = 702,
CTRY_SLOVAKIA = 703,
@@ -170,11 +173,13 @@
CTRY_SWITZERLAND = 756,
CTRY_SYRIA = 760,
CTRY_TAIWAN = 158,
+ CTRY_TANZANIA = 834,
CTRY_THAILAND = 764,
CTRY_TRINIDAD_Y_TOBAGO = 780,
CTRY_TUNISIA = 788,
CTRY_TURKEY = 792,
CTRY_UAE = 784,
+ CTRY_UGANDA = 800,
CTRY_UKRAINE = 804,
CTRY_UNITED_KINGDOM = 826,
CTRY_UNITED_STATES = 840,
diff --git a/drivers/net/wireless/ath/regd_common.h b/drivers/net/wireless/ath/regd_common.h
index bdd2b4d..15bbd1e 100644
--- a/drivers/net/wireless/ath/regd_common.h
+++ b/drivers/net/wireless/ath/regd_common.h
@@ -35,6 +35,7 @@
FRANCE_RES = 0x31,
FCC3_FCCA = 0x3A,
FCC3_WORLD = 0x3B,
+ FCC3_ETSIC = 0x3F,
ETSI1_WORLD = 0x37,
ETSI3_ETSIA = 0x32,
@@ -44,6 +45,7 @@
ETSI4_ETSIC = 0x38,
ETSI5_WORLD = 0x39,
ETSI6_WORLD = 0x34,
+ ETSI8_WORLD = 0x3D,
ETSI_RESERVED = 0x33,
MKK1_MKKA = 0x40,
@@ -59,6 +61,7 @@
MKK1_MKKA1 = 0x4A,
MKK1_MKKA2 = 0x4B,
MKK1_MKKC = 0x4C,
+ APL2_FCCA = 0x4D,
APL3_FCCA = 0x50,
APL1_WORLD = 0x52,
@@ -67,6 +70,7 @@
APL1_ETSIC = 0x55,
APL2_ETSIC = 0x56,
APL5_WORLD = 0x58,
+ APL13_WORLD = 0x5A,
APL6_WORLD = 0x5B,
APL7_FCCA = 0x5C,
APL8_WORLD = 0x5D,
@@ -168,6 +172,7 @@
{FCC2_ETSIC, CTL_FCC, CTL_ETSI},
{FCC3_FCCA, CTL_FCC, CTL_FCC},
{FCC3_WORLD, CTL_FCC, CTL_ETSI},
+ {FCC3_ETSIC, CTL_FCC, CTL_ETSI},
{FCC4_FCCA, CTL_FCC, CTL_FCC},
{FCC5_FCCA, CTL_FCC, CTL_FCC},
{FCC6_FCCA, CTL_FCC, CTL_FCC},
@@ -179,6 +184,7 @@
{ETSI4_WORLD, CTL_ETSI, CTL_ETSI},
{ETSI5_WORLD, CTL_ETSI, CTL_ETSI},
{ETSI6_WORLD, CTL_ETSI, CTL_ETSI},
+ {ETSI8_WORLD, CTL_ETSI, CTL_ETSI},
/* XXX: For ETSI3_ETSIA, Was NO_CTL meant for the 2 GHz band ? */
{ETSI3_ETSIA, CTL_ETSI, CTL_ETSI},
@@ -188,9 +194,11 @@
{FCC1_FCCA, CTL_FCC, CTL_FCC},
{APL1_WORLD, CTL_FCC, CTL_ETSI},
{APL2_WORLD, CTL_FCC, CTL_ETSI},
+ {APL2_FCCA, CTL_FCC, CTL_FCC},
{APL3_WORLD, CTL_FCC, CTL_ETSI},
{APL4_WORLD, CTL_FCC, CTL_ETSI},
{APL5_WORLD, CTL_FCC, CTL_ETSI},
+ {APL13_WORLD, CTL_ETSI, CTL_ETSI},
{APL6_WORLD, CTL_ETSI, CTL_ETSI},
{APL8_WORLD, CTL_ETSI, CTL_ETSI},
{APL9_WORLD, CTL_ETSI, CTL_ETSI},
@@ -298,6 +306,7 @@
{CTRY_AUSTRALIA2, FCC6_WORLD, "AU"},
{CTRY_AUSTRIA, ETSI1_WORLD, "AT"},
{CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ"},
+ {CTRY_BAHAMAS, FCC3_WORLD, "BS"},
{CTRY_BAHRAIN, APL6_WORLD, "BH"},
{CTRY_BANGLADESH, NULL1_WORLD, "BD"},
{CTRY_BARBADOS, FCC2_WORLD, "BB"},
@@ -305,6 +314,7 @@
{CTRY_BELGIUM, ETSI1_WORLD, "BE"},
{CTRY_BELGIUM2, ETSI4_WORLD, "BL"},
{CTRY_BELIZE, APL1_ETSIC, "BZ"},
+ {CTRY_BERMUDA, FCC3_FCCA, "BM"},
{CTRY_BOLIVIA, APL1_ETSIC, "BO"},
{CTRY_BOSNIA_HERZ, ETSI1_WORLD, "BA"},
{CTRY_BRAZIL, FCC3_WORLD, "BR"},
@@ -444,6 +454,7 @@
{CTRY_ROMANIA, NULL1_WORLD, "RO"},
{CTRY_RUSSIA, NULL1_WORLD, "RU"},
{CTRY_SAUDI_ARABIA, NULL1_WORLD, "SA"},
+ {CTRY_SERBIA, ETSI1_WORLD, "RS"},
{CTRY_SERBIA_MONTENEGRO, ETSI1_WORLD, "CS"},
{CTRY_SINGAPORE, APL6_WORLD, "SG"},
{CTRY_SLOVAKIA, ETSI1_WORLD, "SK"},
@@ -455,10 +466,12 @@
{CTRY_SWITZERLAND, ETSI1_WORLD, "CH"},
{CTRY_SYRIA, NULL1_WORLD, "SY"},
{CTRY_TAIWAN, APL3_FCCA, "TW"},
+ {CTRY_TANZANIA, APL1_WORLD, "TZ"},
{CTRY_THAILAND, FCC3_WORLD, "TH"},
{CTRY_TRINIDAD_Y_TOBAGO, FCC3_WORLD, "TT"},
{CTRY_TUNISIA, ETSI3_WORLD, "TN"},
{CTRY_TURKEY, ETSI3_WORLD, "TR"},
+ {CTRY_UGANDA, FCC3_WORLD, "UG"},
{CTRY_UKRAINE, NULL1_WORLD, "UA"},
{CTRY_UAE, NULL1_WORLD, "AE"},
{CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB"},
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index f70420f..846e47a 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -21,7 +21,8 @@
#include "ftm.h"
#define WIL_MAX_ROC_DURATION_MS 5000
-#define CTRY_CHINA "CN"
+#define WIL_BRD_SUFFIX_CN "CN"
+#define WIL_BRD_SUFFIX_FCC "FCC"
bool disable_ap_sme;
module_param(disable_ap_sme, bool, 0444);
@@ -60,6 +61,25 @@
};
#endif
+struct wil_regd_2_brd_suffix {
+ const char regdomain[3]; /* alpha2 */
+ const char *brd_suffix;
+};
+
+static struct wil_regd_2_brd_suffix wil_regd_2_brd_suffix_map[] = {
+ {"BO", WIL_BRD_SUFFIX_FCC},
+ {"CN", WIL_BRD_SUFFIX_CN},
+ {"EC", WIL_BRD_SUFFIX_FCC},
+ {"GU", WIL_BRD_SUFFIX_FCC},
+ {"HN", WIL_BRD_SUFFIX_FCC},
+ {"JM", WIL_BRD_SUFFIX_FCC},
+ {"MX", WIL_BRD_SUFFIX_FCC},
+ {"NI", WIL_BRD_SUFFIX_FCC},
+ {"PY", WIL_BRD_SUFFIX_FCC},
+ {"TT", WIL_BRD_SUFFIX_FCC},
+ {"US", WIL_BRD_SUFFIX_FCC},
+};
+
enum wil_nl_60g_cmd_type {
NL_60G_CMD_FW_WMI,
NL_60G_CMD_DEBUG,
@@ -1989,24 +2009,43 @@
return 0;
}
+static void wil_get_brd_reg_suffix(struct wil6210_priv *wil,
+ const u8 *new_regdomain,
+ char *brd_reg_suffix, size_t len)
+{
+ int i;
+ struct wil_regd_2_brd_suffix *entry;
+
+ for (i = 0; i < ARRAY_SIZE(wil_regd_2_brd_suffix_map); i++) {
+ entry = &wil_regd_2_brd_suffix_map[i];
+ if (!memcmp(entry->regdomain, new_regdomain, 2)) {
+ strlcpy(brd_reg_suffix, entry->brd_suffix, len);
+ return;
+ }
+ }
+
+ /* regdomain not found in our map, set suffix to none */
+ brd_reg_suffix[0] = '\0';
+}
+
static int wil_switch_board_file(struct wil6210_priv *wil,
const u8 *new_regdomain)
{
int rc = 0;
+ char brd_reg_suffix[WIL_BRD_SUFFIX_LEN];
if (!country_specific_board_file)
return 0;
- if (memcmp(wil->regdomain, CTRY_CHINA, 2) == 0) {
- wil_info(wil, "moving out of China reg domain, use default board file\n");
- wil->board_file_country[0] = '\0';
- } else if (memcmp(new_regdomain, CTRY_CHINA, 2) == 0) {
- wil_info(wil, "moving into China reg domain, use country specific board file\n");
- strlcpy(wil->board_file_country, CTRY_CHINA,
- sizeof(wil->board_file_country));
- } else {
+ wil_get_brd_reg_suffix(wil, new_regdomain, brd_reg_suffix,
+ sizeof(brd_reg_suffix));
+ if (!strcmp(wil->board_file_reg_suffix, brd_reg_suffix))
return 0;
- }
+
+ wil_info(wil, "switch board file suffix '%s' => '%s'\n",
+ wil->board_file_reg_suffix, brd_reg_suffix);
+ strlcpy(wil->board_file_reg_suffix, brd_reg_suffix,
+ sizeof(wil->board_file_reg_suffix));
/* need to switch board file - reset the device */
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index f37254d..4cd9411 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -954,19 +954,19 @@
const char *ext;
int prefix_len;
- if (wil->board_file_country[0] == '\0') {
+ if (wil->board_file_reg_suffix[0] == '\0') {
strlcpy(buf, board_file, len);
return;
}
/* use country specific board file */
- if (len < strlen(board_file) + 4 /* for _XX and terminating null */)
+ if (len < strlen(board_file) + 1 + WIL_BRD_SUFFIX_LEN) /* 1 for '_' */
return;
ext = strrchr(board_file, '.');
prefix_len = (ext ? ext - board_file : strlen(board_file));
- snprintf(buf, len, "%.*s_%.2s",
- prefix_len, board_file, wil->board_file_country);
+ snprintf(buf, len, "%.*s_%.3s",
+ prefix_len, board_file, wil->board_file_reg_suffix);
if (ext)
strlcat(buf, ext, len);
}
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 2b71deb..633e30f 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -50,6 +50,8 @@
#define WIL_DEFAULT_BUS_REQUEST_KBPS 128000 /* ~1Gbps */
#define WIL_MAX_BUS_REQUEST_KBPS 800000 /* ~6.1Gbps */
+#define WIL_BRD_SUFFIX_LEN 4 /* max 3 letters + terminating null */
+
/**
* extract bits [@b0:@b1] (inclusive) from the value @x
* it should be @b0 <= @b1, or result is incorrect
@@ -683,7 +685,7 @@
const char *hw_name;
const char *wil_fw_name;
char *board_file;
- char board_file_country[3]; /* alpha2 */
+ char board_file_reg_suffix[WIL_BRD_SUFFIX_LEN]; /* empty or CN or FCC */
u32 brd_file_addr;
u32 brd_file_max_size;
DECLARE_BITMAP(hw_capa, hw_capa_last);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 746f8c9..e69cf0e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -1099,6 +1099,7 @@
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43340),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43341),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43362),
+ BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43364),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4335_4339),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4339),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43430),
diff --git a/drivers/net/wireless/cnss2/bus.c b/drivers/net/wireless/cnss2/bus.c
index 6a8e67c..accd50a 100644
--- a/drivers/net/wireless/cnss2/bus.c
+++ b/drivers/net/wireless/cnss2/bus.c
@@ -332,3 +332,19 @@
return -EINVAL;
}
}
+
+int cnss_bus_update_status(struct cnss_plat_data *plat_priv,
+ enum cnss_driver_status status)
+{
+ if (!plat_priv)
+ return -ENODEV;
+
+ switch (plat_priv->bus_type) {
+ case CNSS_BUS_PCI:
+ return cnss_pci_update_status(plat_priv->bus_priv, status);
+ default:
+ cnss_pr_err("Unsupported bus type: %d\n",
+ plat_priv->bus_type);
+ return -EINVAL;
+ }
+}
diff --git a/drivers/net/wireless/cnss2/bus.h b/drivers/net/wireless/cnss2/bus.h
index 91356e9..cfa3524 100644
--- a/drivers/net/wireless/cnss2/bus.h
+++ b/drivers/net/wireless/cnss2/bus.h
@@ -51,5 +51,7 @@
int cnss_bus_unregister_driver_hdlr(struct cnss_plat_data *plat_priv);
int cnss_bus_call_driver_modem_status(struct cnss_plat_data *plat_priv,
int modem_current_status);
+int cnss_bus_update_status(struct cnss_plat_data *plat_priv,
+ enum cnss_driver_status status);
#endif /* _CNSS_BUS_H */
diff --git a/drivers/net/wireless/cnss2/debug.c b/drivers/net/wireless/cnss2/debug.c
index 53a4620..30e37a0 100644
--- a/drivers/net/wireless/cnss2/debug.c
+++ b/drivers/net/wireless/cnss2/debug.c
@@ -428,6 +428,82 @@
.llseek = seq_lseek,
};
+static ssize_t cnss_runtime_pm_debug_write(struct file *fp,
+ const char __user *user_buf,
+ size_t count, loff_t *off)
+{
+ struct cnss_plat_data *plat_priv =
+ ((struct seq_file *)fp->private_data)->private;
+ struct cnss_pci_data *pci_priv;
+ char buf[64];
+ char *cmd;
+ unsigned int len = 0;
+ int ret = 0;
+
+ if (!plat_priv)
+ return -ENODEV;
+
+ pci_priv = plat_priv->bus_priv;
+ if (!pci_priv)
+ return -ENODEV;
+
+ len = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, len))
+ return -EFAULT;
+
+ buf[len] = '\0';
+ cmd = buf;
+
+ if (sysfs_streq(cmd, "usage_count")) {
+ cnss_pci_pm_runtime_show_usage_count(pci_priv);
+ } else if (sysfs_streq(cmd, "get")) {
+ ret = cnss_pci_pm_runtime_get(pci_priv);
+ } else if (sysfs_streq(cmd, "get_noresume")) {
+ cnss_pci_pm_runtime_get_noresume(pci_priv);
+ } else if (sysfs_streq(cmd, "put_autosuspend")) {
+ ret = cnss_pci_pm_runtime_put_autosuspend(pci_priv);
+ } else if (sysfs_streq(cmd, "put_noidle")) {
+ cnss_pci_pm_runtime_put_noidle(pci_priv);
+ } else if (sysfs_streq(cmd, "mark_last_busy")) {
+ cnss_pci_pm_runtime_mark_last_busy(pci_priv);
+ } else {
+ cnss_pr_err("Runtime PM debugfs command is invalid\n");
+ ret = -EINVAL;
+ }
+
+ if (ret)
+ return ret;
+
+ return count;
+}
+
+static int cnss_runtime_pm_debug_show(struct seq_file *s, void *data)
+{
+ seq_puts(s, "\nUsage: echo <action> > <debugfs_path>/cnss/runtime_pm\n");
+ seq_puts(s, "<action> can be one of below:\n");
+ seq_puts(s, "usage_count: get runtime PM usage count\n");
+ seq_puts(s, "get: do runtime PM get\n");
+ seq_puts(s, "get_noresume: do runtime PM get noresume\n");
+ seq_puts(s, "put_noidle: do runtime PM put noidle\n");
+ seq_puts(s, "put_autosuspend: do runtime PM put autosuspend\n");
+ seq_puts(s, "mark_last_busy: do runtime PM mark last busy\n");
+
+ return 0;
+}
+
+static int cnss_runtime_pm_debug_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, cnss_runtime_pm_debug_show, inode->i_private);
+}
+
+static const struct file_operations cnss_runtime_pm_debug_fops = {
+ .read = seq_read,
+ .write = cnss_runtime_pm_debug_write,
+ .open = cnss_runtime_pm_debug_open,
+ .owner = THIS_MODULE,
+ .llseek = seq_lseek,
+};
+
#ifdef CONFIG_CNSS2_DEBUG
static int cnss_create_debug_only_node(struct cnss_plat_data *plat_priv)
{
@@ -439,6 +515,8 @@
&cnss_reg_read_debug_fops);
debugfs_create_file("reg_write", 0600, root_dentry, plat_priv,
&cnss_reg_write_debug_fops);
+ debugfs_create_file("runtime_pm", 0600, root_dentry, plat_priv,
+ &cnss_runtime_pm_debug_fops);
return 0;
}
diff --git a/drivers/net/wireless/cnss2/main.c b/drivers/net/wireless/cnss2/main.c
index 4433ae0..e711ab4 100644
--- a/drivers/net/wireless/cnss2/main.c
+++ b/drivers/net/wireless/cnss2/main.c
@@ -426,6 +426,7 @@
del_timer(&plat_priv->fw_boot_timer);
set_bit(CNSS_FW_READY, &plat_priv->driver_state);
+ clear_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state);
if (test_bit(CNSS_FW_BOOT_RECOVERY, &plat_priv->driver_state)) {
clear_bit(CNSS_FW_BOOT_RECOVERY, &plat_priv->driver_state);
@@ -901,7 +902,6 @@
break;
case CNSS_REASON_RDDM:
cnss_bus_collect_dump_info(plat_priv, false);
- clear_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state);
break;
case CNSS_REASON_DEFAULT:
case CNSS_REASON_TIMEOUT:
@@ -994,6 +994,8 @@
struct cnss_recovery_data *data;
int gfp = GFP_KERNEL;
+ cnss_bus_update_status(plat_priv, CNSS_FW_DOWN);
+
if (in_interrupt() || irqs_disabled())
gfp = GFP_ATOMIC;
@@ -1039,19 +1041,34 @@
{
int ret = 0;
- set_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state);
- ret = cnss_bus_dev_powerup(plat_priv);
- if (ret)
- clear_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state);
+ if (test_bit(CNSS_FW_READY, &plat_priv->driver_state) ||
+ test_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state) ||
+ test_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state)) {
+ cnss_pr_dbg("Device is already active, ignore calibration\n");
+ goto out;
+ }
+ set_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state);
+ reinit_completion(&plat_priv->cal_complete);
+ ret = cnss_bus_dev_powerup(plat_priv);
+ if (ret) {
+ complete(&plat_priv->cal_complete);
+ clear_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state);
+ }
+
+out:
return ret;
}
static int cnss_cold_boot_cal_done_hdlr(struct cnss_plat_data *plat_priv)
{
+ if (!test_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state))
+ return 0;
+
plat_priv->cal_done = true;
cnss_wlfw_wlan_mode_send_sync(plat_priv, CNSS_OFF);
cnss_bus_dev_shutdown(plat_priv);
+ complete(&plat_priv->cal_complete);
clear_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state);
return 0;
@@ -1537,6 +1554,36 @@
destroy_workqueue(plat_priv->event_wq);
}
+static int cnss_misc_init(struct cnss_plat_data *plat_priv)
+{
+ int ret;
+
+ setup_timer(&plat_priv->fw_boot_timer, cnss_bus_fw_boot_timeout_hdlr,
+ (unsigned long)plat_priv);
+
+ register_pm_notifier(&cnss_pm_notifier);
+
+ ret = device_init_wakeup(&plat_priv->plat_dev->dev, true);
+ if (ret)
+ cnss_pr_err("Failed to init platform device wakeup source, err = %d\n",
+ ret);
+
+ init_completion(&plat_priv->power_up_complete);
+ init_completion(&plat_priv->cal_complete);
+ mutex_init(&plat_priv->dev_lock);
+
+ return 0;
+}
+
+static void cnss_misc_deinit(struct cnss_plat_data *plat_priv)
+{
+ complete_all(&plat_priv->cal_complete);
+ complete_all(&plat_priv->power_up_complete);
+ device_init_wakeup(&plat_priv->plat_dev->dev, false);
+ unregister_pm_notifier(&cnss_pm_notifier);
+ del_timer(&plat_priv->fw_boot_timer);
+}
+
static const struct platform_device_id cnss_platform_id_table[] = {
{ .name = "qca6174", .driver_data = QCA6174_DEVICE_ID, },
{ .name = "qca6290", .driver_data = QCA6290_DEVICE_ID, },
@@ -1630,23 +1677,16 @@
if (ret)
goto deinit_qmi;
- setup_timer(&plat_priv->fw_boot_timer, cnss_bus_fw_boot_timeout_hdlr,
- (unsigned long)plat_priv);
-
- register_pm_notifier(&cnss_pm_notifier);
-
- ret = device_init_wakeup(&plat_dev->dev, true);
+ ret = cnss_misc_init(plat_priv);
if (ret)
- cnss_pr_err("Failed to init platform device wakeup source, err = %d\n",
- ret);
-
- init_completion(&plat_priv->power_up_complete);
- mutex_init(&plat_priv->dev_lock);
+ goto destroy_debugfs;
cnss_pr_info("Platform driver probed successfully.\n");
return 0;
+destroy_debugfs:
+ cnss_debugfs_destroy(plat_priv);
deinit_qmi:
cnss_qmi_deinit(plat_priv);
deinit_event_work:
@@ -1676,10 +1716,7 @@
{
struct cnss_plat_data *plat_priv = platform_get_drvdata(plat_dev);
- complete_all(&plat_priv->power_up_complete);
- device_init_wakeup(&plat_dev->dev, false);
- unregister_pm_notifier(&cnss_pm_notifier);
- del_timer(&plat_priv->fw_boot_timer);
+ cnss_misc_deinit(plat_priv);
cnss_debugfs_destroy(plat_priv);
cnss_qmi_deinit(plat_priv);
cnss_event_work_deinit(plat_priv);
diff --git a/drivers/net/wireless/cnss2/main.h b/drivers/net/wireless/cnss2/main.h
index a2f346a..dd14bbe 100644
--- a/drivers/net/wireless/cnss2/main.h
+++ b/drivers/net/wireless/cnss2/main.h
@@ -243,6 +243,7 @@
atomic_t pm_count;
struct timer_list fw_boot_timer;
struct completion power_up_complete;
+ struct completion cal_complete;
struct mutex dev_lock; /* mutex for register access through debugfs */
u32 diag_reg_read_addr;
u32 diag_reg_read_mem_type;
diff --git a/drivers/net/wireless/cnss2/pci.c b/drivers/net/wireless/cnss2/pci.c
index 0c07bef..c974a1bf 100644
--- a/drivers/net/wireless/cnss2/pci.c
+++ b/drivers/net/wireless/cnss2/pci.c
@@ -350,6 +350,25 @@
return 0;
}
+int cnss_pci_update_status(struct cnss_pci_data *pci_priv,
+ enum cnss_driver_status status)
+{
+ struct cnss_wlan_driver *driver_ops;
+
+ if (!pci_priv)
+ return -ENODEV;
+
+ driver_ops = pci_priv->driver_ops;
+ if (!driver_ops || !driver_ops->update_status)
+ return -EINVAL;
+
+ cnss_pr_dbg("Update driver status: %d\n", status);
+
+ driver_ops->update_status(pci_priv->pci_dev, status);
+
+ return 0;
+}
+
static int cnss_qca6174_powerup(struct cnss_pci_data *pci_priv)
{
int ret = 0;
@@ -693,6 +712,7 @@
int ret = 0;
struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(NULL);
struct cnss_pci_data *pci_priv;
+ unsigned int timeout;
if (!plat_priv) {
cnss_pr_err("plat_priv is NULL\n");
@@ -710,10 +730,27 @@
return -EEXIST;
}
+ if (!test_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state))
+ goto register_driver;
+
+ cnss_pr_dbg("Start to wait for calibration to complete\n");
+
+ timeout = cnss_get_boot_timeout(&pci_priv->pci_dev->dev);
+ ret = wait_for_completion_timeout(&plat_priv->cal_complete,
+ msecs_to_jiffies(timeout) << 2);
+ if (!ret) {
+ cnss_pr_err("Timeout waiting for calibration to complete\n");
+ ret = -EAGAIN;
+ goto out;
+ }
+
+register_driver:
ret = cnss_driver_event_post(plat_priv,
CNSS_DRIVER_EVENT_REGISTER_DRIVER,
CNSS_EVENT_SYNC_UNINTERRUPTIBLE,
driver_ops);
+
+out:
return ret;
}
EXPORT_SYMBOL(cnss_wlan_register_driver);
@@ -1124,6 +1161,59 @@
}
EXPORT_SYMBOL(cnss_wlan_pm_control);
+void cnss_pci_pm_runtime_show_usage_count(struct cnss_pci_data *pci_priv)
+{
+ struct device *dev;
+
+ if (!pci_priv)
+ return;
+
+ dev = &pci_priv->pci_dev->dev;
+
+ cnss_pr_dbg("Runtime PM usage count: %d\n",
+ atomic_read(&dev->power.usage_count));
+}
+
+int cnss_pci_pm_runtime_get(struct cnss_pci_data *pci_priv)
+{
+ if (!pci_priv)
+ return -ENODEV;
+
+ return pm_runtime_get(&pci_priv->pci_dev->dev);
+}
+
+void cnss_pci_pm_runtime_get_noresume(struct cnss_pci_data *pci_priv)
+{
+ if (!pci_priv)
+ return;
+
+ return pm_runtime_get_noresume(&pci_priv->pci_dev->dev);
+}
+
+int cnss_pci_pm_runtime_put_autosuspend(struct cnss_pci_data *pci_priv)
+{
+ if (!pci_priv)
+ return -ENODEV;
+
+ return pm_runtime_put_autosuspend(&pci_priv->pci_dev->dev);
+}
+
+void cnss_pci_pm_runtime_put_noidle(struct cnss_pci_data *pci_priv)
+{
+ if (!pci_priv)
+ return;
+
+ pm_runtime_put_noidle(&pci_priv->pci_dev->dev);
+}
+
+void cnss_pci_pm_runtime_mark_last_busy(struct cnss_pci_data *pci_priv)
+{
+ if (!pci_priv)
+ return;
+
+ pm_runtime_mark_last_busy(&pci_priv->pci_dev->dev);
+}
+
int cnss_auto_suspend(struct device *dev)
{
int ret = 0;
@@ -1238,6 +1328,94 @@
return pm_request_resume(&pci_dev->dev);
}
+#ifdef CONFIG_CNSS_QCA6390
+int cnss_pci_force_wake_request(struct device *dev)
+{
+ struct pci_dev *pci_dev = to_pci_dev(dev);
+ struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
+ struct mhi_controller *mhi_ctrl;
+
+ if (!pci_priv)
+ return -ENODEV;
+
+ if (pci_priv->device_id != QCA6390_DEVICE_ID)
+ return 0;
+
+ mhi_ctrl = pci_priv->mhi_ctrl;
+ if (!mhi_ctrl)
+ return -EINVAL;
+
+ read_lock_bh(&mhi_ctrl->pm_lock);
+ mhi_ctrl->wake_get(mhi_ctrl, true);
+ read_unlock_bh(&mhi_ctrl->pm_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(cnss_pci_force_wake_request);
+
+int cnss_pci_is_device_awake(struct device *dev)
+{
+ struct pci_dev *pci_dev = to_pci_dev(dev);
+ struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
+ struct mhi_controller *mhi_ctrl;
+
+ if (!pci_priv)
+ return -ENODEV;
+
+ if (pci_priv->device_id != QCA6390_DEVICE_ID)
+ return true;
+
+ mhi_ctrl = pci_priv->mhi_ctrl;
+ if (!mhi_ctrl)
+ return -EINVAL;
+
+ return mhi_ctrl->dev_state == MHI_STATE_M0 ? true : false;
+}
+EXPORT_SYMBOL(cnss_pci_is_device_awake);
+
+int cnss_pci_force_wake_release(struct device *dev)
+{
+ struct pci_dev *pci_dev = to_pci_dev(dev);
+ struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
+ struct mhi_controller *mhi_ctrl;
+
+ if (!pci_priv)
+ return -ENODEV;
+
+ if (pci_priv->device_id != QCA6390_DEVICE_ID)
+ return 0;
+
+ mhi_ctrl = pci_priv->mhi_ctrl;
+ if (!mhi_ctrl)
+ return -EINVAL;
+
+ read_lock_bh(&mhi_ctrl->pm_lock);
+ mhi_ctrl->wake_put(mhi_ctrl, false);
+ read_unlock_bh(&mhi_ctrl->pm_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(cnss_pci_force_wake_release);
+#else
+int cnss_pci_force_wake_request(struct device *dev)
+{
+ return 0;
+}
+EXPORT_SYMBOL(cnss_pci_force_wake_request);
+
+int cnss_pci_is_device_awake(struct device *dev)
+{
+ return true;
+}
+EXPORT_SYMBOL(cnss_pci_is_device_awake);
+
+int cnss_pci_force_wake_release(struct device *dev)
+{
+ return 0;
+}
+EXPORT_SYMBOL(cnss_pci_force_wake_release);
+#endif
+
int cnss_pci_alloc_fw_mem(struct cnss_pci_data *pci_priv)
{
struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
@@ -1851,9 +2029,10 @@
cnss_pr_dbg("MHI status cb is called with reason %d\n", reason);
- if (pci_priv->driver_ops && pci_priv->driver_ops->update_status)
- pci_priv->driver_ops->update_status(pci_priv->pci_dev,
- CNSS_FW_DOWN);
+ if (test_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state)) {
+ cnss_pr_dbg("Driver unload is in progress, ignore device error\n");
+ return;
+ }
switch (reason) {
case MHI_CB_EE_RDDM:
@@ -1867,8 +2046,7 @@
set_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state);
del_timer(&plat_priv->fw_boot_timer);
- cnss_schedule_recovery(&pci_priv->pci_dev->dev,
- cnss_reason);
+ cnss_schedule_recovery(&pci_priv->pci_dev->dev, cnss_reason);
}
static int cnss_pci_get_mhi_msi(struct cnss_pci_data *pci_priv)
diff --git a/drivers/net/wireless/cnss2/pci.h b/drivers/net/wireless/cnss2/pci.h
index c8de4d7..6476ce1 100644
--- a/drivers/net/wireless/cnss2/pci.h
+++ b/drivers/net/wireless/cnss2/pci.h
@@ -143,5 +143,13 @@
int cnss_pci_unregister_driver_hdlr(struct cnss_pci_data *pci_priv);
int cnss_pci_call_driver_modem_status(struct cnss_pci_data *pci_priv,
int modem_current_status);
+void cnss_pci_pm_runtime_show_usage_count(struct cnss_pci_data *pci_priv);
+int cnss_pci_pm_runtime_get(struct cnss_pci_data *pci_priv);
+void cnss_pci_pm_runtime_get_noresume(struct cnss_pci_data *pci_priv);
+int cnss_pci_pm_runtime_put_autosuspend(struct cnss_pci_data *pci_priv);
+void cnss_pci_pm_runtime_put_noidle(struct cnss_pci_data *pci_priv);
+void cnss_pci_pm_runtime_mark_last_busy(struct cnss_pci_data *pci_priv);
+int cnss_pci_update_status(struct cnss_pci_data *pci_priv,
+ enum cnss_driver_status status);
#endif /* _CNSS_PCI_H */
diff --git a/drivers/net/wireless/cnss2/qmi.c b/drivers/net/wireless/cnss2/qmi.c
index 2c375bb..d857b9f 100644
--- a/drivers/net/wireless/cnss2/qmi.c
+++ b/drivers/net/wireless/cnss2/qmi.c
@@ -242,6 +242,8 @@
req.fw_init_done_enable = 1;
req.pin_connect_result_enable_valid = 1;
req.pin_connect_result_enable = 1;
+ req.cal_done_enable_valid = 1;
+ req.cal_done_enable = 1;
req_desc.max_msg_len = WLFW_IND_REGISTER_REQ_MSG_V01_MAX_MSG_LEN;
req_desc.msg_id = QMI_WLFW_IND_REGISTER_REQ_V01;
@@ -1054,6 +1056,11 @@
case QMI_WLFW_PIN_CONNECT_RESULT_IND_V01:
cnss_qmi_pin_result_ind_hdlr(plat_priv, msg, msg_len);
break;
+ case QMI_WLFW_CAL_DONE_IND_V01:
+ cnss_driver_event_post(plat_priv,
+ CNSS_DRIVER_EVENT_COLD_BOOT_CAL_DONE,
+ 0, NULL);
+ break;
default:
cnss_pr_err("Invalid QMI WLFW indication, msg_id: 0x%x\n",
msg_id);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
index 6fe5546..996a928 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
@@ -898,6 +898,8 @@
WQ_HIGHPRI | WQ_UNBOUND, 1);
INIT_WORK(&rba->rx_alloc, iwl_pcie_rx_allocator_work);
+ cancel_work_sync(&rba->rx_alloc);
+
spin_lock(&rba->lock);
atomic_set(&rba->req_pending, 0);
atomic_set(&rba->req_ready, 0);
diff --git a/drivers/net/wireless/marvell/mwifiex/usb.c b/drivers/net/wireless/marvell/mwifiex/usb.c
index 73eb084..09185a1 100644
--- a/drivers/net/wireless/marvell/mwifiex/usb.c
+++ b/drivers/net/wireless/marvell/mwifiex/usb.c
@@ -624,6 +624,9 @@
MWIFIEX_FUNC_SHUTDOWN);
}
+ if (adapter->workqueue)
+ flush_workqueue(adapter->workqueue);
+
mwifiex_usb_free(card);
mwifiex_dbg(adapter, FATAL,
diff --git a/drivers/net/wireless/marvell/mwifiex/util.c b/drivers/net/wireless/marvell/mwifiex/util.c
index 18fbb96..d75756c 100644
--- a/drivers/net/wireless/marvell/mwifiex/util.c
+++ b/drivers/net/wireless/marvell/mwifiex/util.c
@@ -723,12 +723,14 @@
s8 nflr)
{
struct mwifiex_histogram_data *phist_data = priv->hist_data;
+ s8 nf = -nflr;
+ s8 rssi = snr - nflr;
atomic_inc(&phist_data->num_samples);
atomic_inc(&phist_data->rx_rate[rx_rate]);
- atomic_inc(&phist_data->snr[snr]);
- atomic_inc(&phist_data->noise_flr[128 + nflr]);
- atomic_inc(&phist_data->sig_str[nflr - snr]);
+ atomic_inc(&phist_data->snr[snr + 128]);
+ atomic_inc(&phist_data->noise_flr[nf + 128]);
+ atomic_inc(&phist_data->sig_str[rssi + 128]);
}
/* function to reset histogram data during init/reset */
diff --git a/drivers/net/wireless/realtek/rtlwifi/core.c b/drivers/net/wireless/realtek/rtlwifi/core.c
index 4da4e45..9526643 100644
--- a/drivers/net/wireless/realtek/rtlwifi/core.c
+++ b/drivers/net/wireless/realtek/rtlwifi/core.c
@@ -131,7 +131,6 @@
firmware->size);
rtlpriv->rtlhal.wowlan_fwsize = firmware->size;
}
- rtlpriv->rtlhal.fwsize = firmware->size;
release_firmware(firmware);
}
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c
index 8428858..fc895b4 100644
--- a/drivers/net/wireless/rsi/rsi_91x_sdio.c
+++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c
@@ -155,7 +155,6 @@
int err;
struct mmc_card *card = pfunction->card;
struct mmc_host *host = card->host;
- s32 bit = (fls(host->ocr_avail) - 1);
u8 cmd52_resp;
u32 clock, resp, i;
u16 rca;
@@ -175,7 +174,6 @@
msleep(20);
/* Initialize the SDIO card */
- host->ios.vdd = bit;
host->ios.chip_select = MMC_CS_DONTCARE;
host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
host->ios.power_mode = MMC_POWER_UP;
diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c
index 47fe7f9..6921cb0 100644
--- a/drivers/net/wireless/ti/wlcore/sdio.c
+++ b/drivers/net/wireless/ti/wlcore/sdio.c
@@ -404,6 +404,11 @@
mmc_pm_flag_t sdio_flags;
int ret = 0;
+ if (!wl) {
+ dev_err(dev, "no wilink module was probed\n");
+ goto out;
+ }
+
dev_dbg(dev, "wl1271 suspend. wow_enabled: %d\n",
wl->wow_enabled);
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 520050e..a5908e4 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -238,7 +238,7 @@
static int netfront_tx_slot_available(struct netfront_queue *queue)
{
return (queue->tx.req_prod_pvt - queue->tx.rsp_cons) <
- (NET_TX_RING_SIZE - MAX_SKB_FRAGS - 2);
+ (NET_TX_RING_SIZE - XEN_NETIF_NR_SLOTS_MIN - 1);
}
static void xennet_maybe_wake_tx(struct netfront_queue *queue)
@@ -789,7 +789,7 @@
RING_IDX cons = queue->rx.rsp_cons;
struct sk_buff *skb = xennet_get_rx_skb(queue, cons);
grant_ref_t ref = xennet_get_rx_ref(queue, cons);
- int max = MAX_SKB_FRAGS + (rx->status <= RX_COPY_THRESHOLD);
+ int max = XEN_NETIF_NR_SLOTS_MIN + (rx->status <= RX_COPY_THRESHOLD);
int slots = 1;
int err = 0;
unsigned long ret;
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index c823e93..979c6ec 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -2042,7 +2042,8 @@
mutex_lock(&ctrl->namespaces_mutex);
/* Forcibly start all queues to avoid having stuck requests */
- blk_mq_start_hw_queues(ctrl->admin_q);
+ if (ctrl->admin_q)
+ blk_mq_start_hw_queues(ctrl->admin_q);
list_for_each_entry(ns, &ctrl->namespaces, list) {
/*
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index a55d112..fadf151 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -1034,17 +1034,15 @@
static int nvme_alloc_sq_cmds(struct nvme_dev *dev, struct nvme_queue *nvmeq,
int qid, int depth)
{
- if (qid && dev->cmb && use_cmb_sqes && NVME_CMB_SQS(dev->cmbsz)) {
- unsigned offset = (qid - 1) * roundup(SQ_SIZE(depth),
- dev->ctrl.page_size);
- nvmeq->sq_dma_addr = dev->cmb_bus_addr + offset;
- nvmeq->sq_cmds_io = dev->cmb + offset;
- } else {
- nvmeq->sq_cmds = dma_alloc_coherent(dev->dev, SQ_SIZE(depth),
- &nvmeq->sq_dma_addr, GFP_KERNEL);
- if (!nvmeq->sq_cmds)
- return -ENOMEM;
- }
+
+ /* CMB SQEs will be mapped before creation */
+ if (qid && dev->cmb && use_cmb_sqes && NVME_CMB_SQS(dev->cmbsz))
+ return 0;
+
+ nvmeq->sq_cmds = dma_alloc_coherent(dev->dev, SQ_SIZE(depth),
+ &nvmeq->sq_dma_addr, GFP_KERNEL);
+ if (!nvmeq->sq_cmds)
+ return -ENOMEM;
return 0;
}
@@ -1117,6 +1115,13 @@
struct nvme_dev *dev = nvmeq->dev;
int result;
+ if (qid && dev->cmb && use_cmb_sqes && NVME_CMB_SQS(dev->cmbsz)) {
+ unsigned offset = (qid - 1) * roundup(SQ_SIZE(nvmeq->q_depth),
+ dev->ctrl.page_size);
+ nvmeq->sq_dma_addr = dev->cmb_bus_addr + offset;
+ nvmeq->sq_cmds_io = dev->cmb + offset;
+ }
+
nvmeq->cq_vector = qid - 1;
result = adapter_alloc_cq(dev, qid, nvmeq);
if (result < 0)
diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 1b4d93e..824e282 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -1031,6 +1031,8 @@
/* setup the first byte with lsb bits from nvmem */
rc = nvmem_reg_read(nvmem, cell->offset, &v, 1);
+ if (rc)
+ goto err;
*b++ |= GENMASK(bit_offset - 1, 0) & v;
/* setup rest of the byte if any */
@@ -1049,11 +1051,16 @@
/* setup the last byte with msb bits from nvmem */
rc = nvmem_reg_read(nvmem,
cell->offset + cell->bytes - 1, &v, 1);
+ if (rc)
+ goto err;
*p |= GENMASK(7, (nbits + bit_offset) % BITS_PER_BYTE) & v;
}
return buf;
+err:
+ kfree(buf);
+ return ERR_PTR(rc);
}
/**
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index f9f4d1c..e5d8e2e 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -180,13 +180,16 @@
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (!val) {
- if (pci_is_enabled(pdev))
- pci_disable_device(pdev);
- else
- result = -EIO;
- } else
+ device_lock(dev);
+ if (dev->driver)
+ result = -EBUSY;
+ else if (val)
result = pci_enable_device(pdev);
+ else if (pci_is_enabled(pdev))
+ pci_disable_device(pdev);
+ else
+ result = -EIO;
+ device_unlock(dev);
return result < 0 ? result : count;
}
diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c
index 28bbc1b..88ba9c5 100644
--- a/drivers/pinctrl/pinctrl-at91-pio4.c
+++ b/drivers/pinctrl/pinctrl-at91-pio4.c
@@ -573,8 +573,10 @@
for_each_child_of_node(np_config, np) {
ret = atmel_pctl_dt_subnode_to_map(pctldev, np, map,
&reserved_maps, num_maps);
- if (ret < 0)
+ if (ret < 0) {
+ of_node_put(np);
break;
+ }
}
}
diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig
index 9413da3..56ea1f4 100644
--- a/drivers/pinctrl/qcom/Kconfig
+++ b/drivers/pinctrl/qcom/Kconfig
@@ -139,6 +139,16 @@
Technologies Inc MSM8917 platform.
If unsure say N.
+config PINCTRL_MSM8940
+ tristate "Qualcomm Technologies Inc MSM8940 pin controller driver"
+ depends on GPIOLIB && OF
+ select PINCTRL_MSM
+ help
+ This is the pinctrl, pinmux, pinconf and gpiolib driver for the
+ Qualcomm Technologies Inc TLMM block found on the Qualcomm
+ Technologies Inc MSM8940 platform.
+ If unsure say N.
+
config PINCTRL_SDM845
tristate "Qualcomm Technologies Inc SDM845 pin controller driver"
depends on GPIOLIB && OF
diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
index dcfe105..aa29688 100644
--- a/drivers/pinctrl/qcom/pinctrl-msm.c
+++ b/drivers/pinctrl/qcom/pinctrl-msm.c
@@ -1307,7 +1307,7 @@
pctrl = gpiochip_get_data(gc);
if (pctrl->spi_cfg_regs) {
spi_cfg_reg = pctrl->spi_cfg_regs +
- (dir_conn_data->hwirq / 32) * 4;
+ ((dir_conn_data->hwirq - 32) / 32) * 4;
if (spi_cfg_reg < pctrl->spi_cfg_end) {
spin_lock_irqsave(&pctrl->lock, flags);
val = scm_io_read(spi_cfg_reg);
@@ -1315,7 +1315,8 @@
* Clear the respective bit for edge type
* interrupt
*/
- val &= ~(1 << (dir_conn_data->hwirq % 32));
+ val &= ~(1 << ((dir_conn_data->hwirq - 32)
+ % 32));
WARN_ON(scm_io_write(spi_cfg_reg, val));
spin_unlock_irqrestore(&pctrl->lock, flags);
} else
@@ -1392,13 +1393,13 @@
if (pctrl->spi_cfg_regs && type != IRQ_TYPE_NONE) {
spi_cfg_reg = pctrl->spi_cfg_regs +
- (parent_data->hwirq / 32) * 4;
+ ((parent_data->hwirq - 32) / 32) * 4;
if (spi_cfg_reg < pctrl->spi_cfg_end) {
spin_lock_irqsave(&pctrl->lock, flags);
val = scm_io_read(spi_cfg_reg);
- val &= ~(1 << (parent_data->hwirq % 32));
+ val &= ~(1 << ((parent_data->hwirq - 32) % 32));
if (config_val)
- val |= (1 << (parent_data->hwirq % 32));
+ val |= (1 << ((parent_data->hwirq - 32) % 32));
WARN_ON(scm_io_write(spi_cfg_reg, val));
spin_unlock_irqrestore(&pctrl->lock, flags);
} else
diff --git a/drivers/platform/msm/ep_pcie/ep_pcie_com.h b/drivers/platform/msm/ep_pcie/ep_pcie_com.h
index 36d49e4..ebc3b8f 100644
--- a/drivers/platform/msm/ep_pcie/ep_pcie_com.h
+++ b/drivers/platform/msm/ep_pcie/ep_pcie_com.h
@@ -55,6 +55,9 @@
#define PCIE20_PARF_SLV_ADDR_SPACE_SIZE_HI 0x35C
#define PCIE20_PARF_ATU_BASE_ADDR 0x634
#define PCIE20_PARF_ATU_BASE_ADDR_HI 0x638
+#define PCIE20_PARF_BUS_DISCONNECT_CTRL 0x648
+#define PCIE20_PARF_BUS_DISCONNECT_STATUS 0x64c
+
#define PCIE20_PARF_DEVICE_TYPE 0x1000
#define PCIE20_ELBI_VERSION 0x00
@@ -63,6 +66,8 @@
#define PCIE20_ELBI_CS2_ENABLE 0xA4
#define PCIE20_DEVICE_ID_VENDOR_ID 0x00
+#define PCIE20_MASK_DEVICE_ID GENMASK(31, 16)
+#define PCIE20_MASK_VENDOR_ID GENMASK(15, 0)
#define PCIE20_COMMAND_STATUS 0x04
#define PCIE20_CLASS_CODE_REVISION_ID 0x08
#define PCIE20_BIST_HDR_TYPE 0x0C
@@ -323,6 +328,8 @@
struct msm_bus_scale_pdata *bus_scale_table;
u32 bus_client;
+ u16 vendor_id;
+ u16 device_id;
u32 link_speed;
bool active_config;
bool aggregated_irq;
diff --git a/drivers/platform/msm/ep_pcie/ep_pcie_core.c b/drivers/platform/msm/ep_pcie/ep_pcie_core.c
index 0ada0bf..5c3828b 100644
--- a/drivers/platform/msm/ep_pcie/ep_pcie_core.c
+++ b/drivers/platform/msm/ep_pcie/ep_pcie_core.c
@@ -133,6 +133,63 @@
return true;
}
+static int ep_pcie_reset_init(struct ep_pcie_dev_t *dev)
+{
+ int i, rc = 0;
+ struct ep_pcie_reset_info_t *reset_info;
+
+ for (i = 0; i < EP_PCIE_MAX_RESET; i++) {
+ reset_info = &dev->reset[i];
+ if (!reset_info->hdl)
+ continue;
+
+ rc = reset_control_assert(reset_info->hdl);
+ if (rc) {
+ if (!reset_info->required) {
+ EP_PCIE_ERR(dev,
+ "PCIe V%d: Optional reset: %s assert failed\n",
+ dev->rev, reset_info->name);
+ continue;
+ } else {
+ EP_PCIE_ERR(dev,
+ "PCIe V%d: failed to assert reset for %s\n",
+ dev->rev, reset_info->name);
+ return rc;
+ }
+ } else {
+ EP_PCIE_DBG(dev,
+ "PCIe V%d: successfully asserted reset for %s\n",
+ dev->rev, reset_info->name);
+ }
+ EP_PCIE_ERR(dev, "After Reset assert %s\n",
+ reset_info->name);
+ /* add a 1ms delay to ensure the reset is asserted */
+ usleep_range(1000, 1005);
+
+ rc = reset_control_deassert(reset_info->hdl);
+ if (rc) {
+ if (!reset_info->required) {
+ EP_PCIE_ERR(dev,
+ "PCIe V%d: Optional reset: %s deassert failed\n",
+ dev->rev, reset_info->name);
+ continue;
+ } else {
+ EP_PCIE_ERR(dev,
+ "PCIe V%d: failed to deassert reset for %s\n",
+ dev->rev, reset_info->name);
+ return rc;
+ }
+ } else {
+ EP_PCIE_DBG(dev,
+ "PCIe V%d: successfully deasserted reset for %s\n",
+ dev->rev, reset_info->name);
+ }
+ EP_PCIE_ERR(dev, "After Reset de-assert %s\n",
+ reset_info->name);
+ }
+ return 0;
+}
+
static int ep_pcie_gpio_init(struct ep_pcie_dev_t *dev)
{
int i, rc = 0;
@@ -277,7 +334,6 @@
{
int i, rc = 0;
struct ep_pcie_clk_info_t *info;
- struct ep_pcie_reset_info_t *reset_info;
EP_PCIE_DBG(dev, "PCIe V%d\n", dev->rev);
@@ -349,34 +405,6 @@
regulator_disable(dev->gdsc);
}
- for (i = 0; i < EP_PCIE_MAX_RESET; i++) {
- reset_info = &dev->reset[i];
- if (reset_info->hdl) {
- rc = reset_control_assert(reset_info->hdl);
- if (rc)
- EP_PCIE_ERR(dev,
- "PCIe V%d: failed to assert reset for %s.\n",
- dev->rev, reset_info->name);
- else
- EP_PCIE_DBG(dev,
- "PCIe V%d: successfully asserted reset for %s.\n",
- dev->rev, reset_info->name);
-
- /* add a 1ms delay to ensure the reset is asserted */
- usleep_range(1000, 1005);
-
- rc = reset_control_deassert(reset_info->hdl);
- if (rc)
- EP_PCIE_ERR(dev,
- "PCIe V%d: failed to deassert reset for %s.\n",
- dev->rev, reset_info->name);
- else
- EP_PCIE_DBG(dev,
- "PCIe V%d: successfully deasserted reset for %s.\n",
- dev->rev, reset_info->name);
- }
- }
-
return rc;
}
@@ -524,11 +552,21 @@
static void ep_pcie_core_init(struct ep_pcie_dev_t *dev, bool configured)
{
+ uint32_t val = 0;
EP_PCIE_DBG(dev, "PCIe V%d\n", dev->rev);
/* enable debug IRQ */
ep_pcie_write_mask(dev->parf + PCIE20_PARF_DEBUG_INT_EN,
0, BIT(3) | BIT(2) | BIT(1));
+ /* Reconnect AXI master port */
+ val = readl_relaxed(dev->parf + PCIE20_PARF_BUS_DISCONNECT_STATUS);
+ if (val & BIT(0)) {
+ EP_PCIE_DBG(dev,
+ "PCIe V%d: AXI Master port was disconnected, reconnecting...\n",
+ dev->rev);
+ ep_pcie_write_mask(dev->parf + PCIE20_PARF_BUS_DISCONNECT_CTRL,
+ 0, BIT(0));
+ }
if (!configured) {
/* Configure PCIe to endpoint mode */
@@ -635,6 +673,17 @@
ep_pcie_write_mask(dev->dm_core + PCIE20_MISC_CONTROL_1, 0,
BIT(0));
+ /* Set Vendor ID and Device ID */
+ if (ep_pcie_dev.device_id != 0xFFFF)
+ ep_pcie_write_reg_field(dev->dm_core,
+ PCIE20_DEVICE_ID_VENDOR_ID,
+ PCIE20_MASK_DEVICE_ID,
+ ep_pcie_dev.device_id);
+ if (ep_pcie_dev.vendor_id != 0xFFFF)
+ ep_pcie_write_reg_field(dev->dm_core,
+ PCIE20_DEVICE_ID_VENDOR_ID,
+ PCIE20_MASK_VENDOR_ID,
+ ep_pcie_dev.vendor_id);
/* Set class code and revision ID */
ep_pcie_write_reg(dev->dm_core, PCIE20_CLASS_CODE_REVISION_ID,
0xff000000);
@@ -722,8 +771,8 @@
ep_pcie_write_mask(dev->parf + PCIE20_PARF_PM_CTRL, BIT(5), 0);
}
- /* Configure MMIO */
- ep_pcie_config_mmio(dev);
+ if (!configured)
+ ep_pcie_config_mmio(dev);
}
static void ep_pcie_config_inbound_iatu(struct ep_pcie_dev_t *dev)
@@ -1381,6 +1430,9 @@
}
}
+ ret = ep_pcie_reset_init(dev);
+ if (ret)
+ goto link_fail;
/* init PCIe PHY */
ep_pcie_phy_init(dev);
@@ -2477,6 +2529,30 @@
EP_PCIE_DBG(&ep_pcie_dev, "PCIe V%d: pcie-link-speed:%d.\n",
ep_pcie_dev.rev, ep_pcie_dev.link_speed);
+ ep_pcie_dev.vendor_id = 0xFFFF;
+ ret = of_property_read_u16((&pdev->dev)->of_node,
+ "qcom,pcie-vendor-id",
+ &ep_pcie_dev.vendor_id);
+ if (ret)
+ EP_PCIE_DBG(&ep_pcie_dev,
+ "PCIe V%d: pcie-vendor-id does not exist.\n",
+ ep_pcie_dev.rev);
+ else
+ EP_PCIE_DBG(&ep_pcie_dev, "PCIe V%d: pcie-vendor-id:%d.\n",
+ ep_pcie_dev.rev, ep_pcie_dev.vendor_id);
+
+ ep_pcie_dev.device_id = 0xFFFF;
+ ret = of_property_read_u16((&pdev->dev)->of_node,
+ "qcom,pcie-device-id",
+ &ep_pcie_dev.device_id);
+ if (ret)
+ EP_PCIE_DBG(&ep_pcie_dev,
+ "PCIe V%d: pcie-device-id does not exist.\n",
+ ep_pcie_dev.rev);
+ else
+ EP_PCIE_DBG(&ep_pcie_dev, "PCIe V%d: pcie-device-id:%d.\n",
+ ep_pcie_dev.rev, ep_pcie_dev.device_id);
+
ret = of_property_read_u32((&pdev->dev)->of_node,
"qcom,dbi-base-reg",
&ep_pcie_dev.dbi_base_reg);
@@ -2727,7 +2803,7 @@
platform_driver_unregister(&ep_pcie_driver);
}
-module_init(ep_pcie_init);
+subsys_initcall(ep_pcie_init);
module_exit(ep_pcie_exit);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("MSM PCIe Endpoint Driver");
diff --git a/drivers/platform/msm/ipa/ipa_clients/ipa_gsb.c b/drivers/platform/msm/ipa/ipa_clients/ipa_gsb.c
index 4e3a565..6bb9f8b 100644
--- a/drivers/platform/msm/ipa/ipa_clients/ipa_gsb.c
+++ b/drivers/platform/msm/ipa/ipa_clients/ipa_gsb.c
@@ -160,6 +160,7 @@
struct mutex iface_lock[MAX_SUPPORTED_IFACE];
spinlock_t iface_spinlock[MAX_SUPPORTED_IFACE];
u32 pm_hdl;
+ atomic_t disconnect_in_progress;
};
static struct ipa_gsb_context *ipa_gsb_ctx;
@@ -908,7 +909,7 @@
int ipa_bridge_disconnect(u32 hdl)
{
- int ret;
+ int ret = 0;
if (!ipa_gsb_ctx) {
IPA_GSB_ERR("ipa_gsb_ctx was not initialized\n");
@@ -923,31 +924,33 @@
IPA_GSB_DBG("client hdl: %d\n", hdl);
mutex_lock(&ipa_gsb_ctx->iface_lock[hdl]);
+ atomic_set(&ipa_gsb_ctx->disconnect_in_progress, 1);
+
if (!ipa_gsb_ctx->iface[hdl]) {
IPA_GSB_ERR("fail to find interface, hdl: %d\n", hdl);
- mutex_unlock(&ipa_gsb_ctx->iface_lock[hdl]);
- return -EFAULT;
+ ret = -EFAULT;
+ goto fail;
}
if (!ipa_gsb_ctx->iface[hdl]->is_connected) {
IPA_GSB_DBG("iface was not connected\n");
- mutex_unlock(&ipa_gsb_ctx->iface_lock[hdl]);
- return 0;
+ ret = 0;
+ goto fail;
}
if (ipa_gsb_ctx->num_connected_iface == 1) {
ret = ipa_gsb_disconnect_sys_pipe();
if (ret) {
IPA_GSB_ERR("fail to discon pipes\n");
- mutex_unlock(&ipa_gsb_ctx->iface_lock[hdl]);
- return -EFAULT;
+ ret = -EFAULT;
+ goto fail;
}
ret = ipa_pm_deactivate_sync(ipa_gsb_ctx->pm_hdl);
if (ret) {
IPA_GSB_ERR("failed to deactivate ipa pm\n");
- mutex_unlock(&ipa_gsb_ctx->iface_lock[hdl]);
- return -EFAULT;
+ ret = -EFAULT;
+ goto fail;
}
}
@@ -964,8 +967,10 @@
ipa_gsb_ctx->num_resumed_iface);
}
+fail:
+ atomic_set(&ipa_gsb_ctx->disconnect_in_progress, 0);
mutex_unlock(&ipa_gsb_ctx->iface_lock[hdl]);
- return 0;
+ return ret;
}
EXPORT_SYMBOL(ipa_bridge_disconnect);
@@ -1140,6 +1145,11 @@
return -EFAULT;
}
+ if (unlikely(atomic_read(&ipa_gsb_ctx->disconnect_in_progress))) {
+ IPA_GSB_ERR("ipa bridge disconnect_in_progress\n");
+ return -EFAULT;
+ }
+
/* make sure skb has enough headroom */
if (unlikely(skb_headroom(skb) < sizeof(struct ipa_gsb_mux_hdr))) {
IPA_GSB_DBG_LOW("skb doesn't have enough headroom\n");
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v2/ipa_debugfs.c
index 0224f98..d799480 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_debugfs.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_debugfs.c
@@ -92,6 +92,8 @@
__stringify(ADD_BRIDGE_VLAN_MAPPING),
__stringify(DEL_BRIDGE_VLAN_MAPPING),
__stringify(WLAN_FWR_SSR_BEFORE_SHUTDOWN),
+ __stringify(IPA_GSB_CONNECT),
+ __stringify(IPA_GSB_DISCONNECT),
};
const char *ipa_hdr_l2_type_name[] = {
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_nat.c b/drivers/platform/msm/ipa/ipa_v2/ipa_nat.c
index 0351442..39bd2da 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_nat.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_nat.c
@@ -327,14 +327,18 @@
size_t tmp;
gfp_t flag = GFP_KERNEL | (ipa_ctx->use_dma_zone ? GFP_DMA : 0);
+ mutex_lock(&ipa_ctx->nat_mem.lock);
+
if (!ipa_ctx->nat_mem.is_dev_init) {
IPAERR_RL("Nat table not initialized\n");
+ mutex_unlock(&ipa_ctx->nat_mem.lock);
return -EPERM;
}
IPADBG("\n");
if (init->table_entries == 0) {
IPADBG("Table entries is zero\n");
+ mutex_unlock(&ipa_ctx->nat_mem.lock);
return -EPERM;
}
@@ -342,6 +346,7 @@
if (init->ipv4_rules_offset >
(UINT_MAX - (TBL_ENTRY_SIZE * (init->table_entries + 1)))) {
IPAERR_RL("Detected overflow\n");
+ mutex_unlock(&ipa_ctx->nat_mem.lock);
return -EPERM;
}
/* Check Table Entry offset is not
@@ -354,6 +359,7 @@
IPAERR_RL("offset:%d entrys:%d size:%zu mem_size:%zu\n",
init->ipv4_rules_offset, (init->table_entries + 1),
tmp, ipa_ctx->nat_mem.size);
+ mutex_unlock(&ipa_ctx->nat_mem.lock);
return -EPERM;
}
@@ -361,6 +367,7 @@
if (init->expn_rules_offset >
UINT_MAX - (TBL_ENTRY_SIZE * init->expn_table_entries)) {
IPAERR_RL("Detected overflow\n");
+ mutex_unlock(&ipa_ctx->nat_mem.lock);
return -EPERM;
}
/* Check Expn Table Entry offset is not
@@ -373,6 +380,7 @@
IPAERR_RL("offset:%d entrys:%d size:%zu mem_size:%zu\n",
init->expn_rules_offset, init->expn_table_entries,
tmp, ipa_ctx->nat_mem.size);
+ mutex_unlock(&ipa_ctx->nat_mem.lock);
return -EPERM;
}
@@ -380,6 +388,7 @@
if (init->index_offset >
UINT_MAX - (INDX_TBL_ENTRY_SIZE * (init->table_entries + 1))) {
IPAERR_RL("Detected overflow\n");
+ mutex_unlock(&ipa_ctx->nat_mem.lock);
return -EPERM;
}
/* Check Indx Table Entry offset is not
@@ -392,6 +401,7 @@
IPAERR_RL("offset:%d entrys:%d size:%zu mem_size:%zu\n",
init->index_offset, (init->table_entries + 1),
tmp, ipa_ctx->nat_mem.size);
+ mutex_unlock(&ipa_ctx->nat_mem.lock);
return -EPERM;
}
@@ -399,6 +409,7 @@
if (init->index_expn_offset >
(UINT_MAX - (INDX_TBL_ENTRY_SIZE * init->expn_table_entries))) {
IPAERR_RL("Detected overflow\n");
+ mutex_unlock(&ipa_ctx->nat_mem.lock);
return -EPERM;
}
/* Check Expn Table entry offset is not
@@ -411,6 +422,7 @@
IPAERR_RL("offset:%d entrys:%d size:%zu mem_size:%zu\n",
init->index_expn_offset, init->expn_table_entries,
tmp, ipa_ctx->nat_mem.size);
+ mutex_unlock(&ipa_ctx->nat_mem.lock);
return -EPERM;
}
@@ -559,6 +571,7 @@
free_nop:
kfree(reg_write_nop);
bail:
+ mutex_unlock(&ipa_ctx->nat_mem.lock);
return result;
}
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c b/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c
index 073409b..be52968 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c
@@ -1344,6 +1344,8 @@
struct ipa_rt_entry *rule_next;
struct ipa_rt_tbl_set *rset;
u32 apps_start_idx;
+ struct ipa_hdr_entry *hdr_entry;
+ struct ipa_hdr_proc_ctx_entry *hdr_proc_entry;
int id;
bool tbl_user = false;
@@ -1397,6 +1399,27 @@
if (!user_only ||
rule->ipacm_installed) {
list_del(&rule->link);
+ if (rule->hdr) {
+ hdr_entry = ipa_id_find(
+ rule->rule.hdr_hdl);
+ if (!hdr_entry ||
+ hdr_entry->cookie != IPA_HDR_COOKIE) {
+ IPAERR_RL(
+ "Header already deleted\n");
+ return -EINVAL;
+ }
+ } else if (rule->proc_ctx) {
+ hdr_proc_entry =
+ ipa_id_find(
+ rule->rule.hdr_proc_ctx_hdl);
+ if (!hdr_proc_entry ||
+ hdr_proc_entry->cookie !=
+ IPA_PROC_HDR_COOKIE) {
+ IPAERR_RL(
+ "Proc entry already deleted\n");
+ return -EINVAL;
+ }
+ }
tbl->rule_cnt--;
if (rule->hdr)
__ipa_release_hdr(rule->hdr->id);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c
index bc032d9..e4c16cf 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c
@@ -605,6 +605,73 @@
return 0;
}
+static void ipa3_gsb_msg_free_cb(void *buff, u32 len, u32 type)
+{
+ if (!buff) {
+ IPAERR("Null buffer\n");
+ return;
+ }
+
+ switch (type) {
+ case IPA_GSB_CONNECT:
+ case IPA_GSB_DISCONNECT:
+ break;
+ default:
+ IPAERR("Wrong type given. buff %pK type %d\n", buff, type);
+ return;
+ }
+
+ kfree(buff);
+}
+
+static int ipa3_send_gsb_msg(unsigned long usr_param, uint8_t msg_type)
+{
+ int retval;
+ struct ipa_ioc_gsb_info *gsb_info;
+ struct ipa_msg_meta msg_meta;
+ void *buff;
+
+ IPADBG("type %d\n", msg_type);
+
+ memset(&msg_meta, 0, sizeof(msg_meta));
+ msg_meta.msg_type = msg_type;
+
+ if ((msg_type == IPA_GSB_CONNECT) ||
+ (msg_type == IPA_GSB_DISCONNECT)) {
+ gsb_info = kzalloc(sizeof(struct ipa_ioc_gsb_info),
+ GFP_KERNEL);
+ if (!gsb_info) {
+ IPAERR("no memory\n");
+ return -ENOMEM;
+ }
+
+ if (copy_from_user((u8 *)gsb_info, (void __user *)usr_param,
+ sizeof(struct ipa_ioc_gsb_info))) {
+ kfree(gsb_info);
+ return -EFAULT;
+ }
+
+ msg_meta.msg_len = sizeof(struct ipa_ioc_gsb_info);
+ buff = gsb_info;
+ } else {
+ IPAERR("Unexpected event\n");
+ return -EFAULT;
+ }
+
+ retval = ipa3_send_msg(&msg_meta, buff,
+ ipa3_gsb_msg_free_cb);
+ if (retval) {
+ IPAERR("ipa3_send_msg failed: %d, msg_type %d\n",
+ retval,
+ msg_type);
+ kfree(buff);
+ return retval;
+ }
+ IPADBG("exit\n");
+
+ return 0;
+}
+
static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
int retval = 0;
@@ -1795,6 +1862,22 @@
retval = ipa3_resend_wlan_msg();
break;
+ case IPA_IOC_GSB_CONNECT:
+ IPADBG("Got IPA_IOC_GSB_CONNECT\n");
+ if (ipa3_send_gsb_msg(arg, IPA_GSB_CONNECT)) {
+ retval = -EFAULT;
+ break;
+ }
+ break;
+
+ case IPA_IOC_GSB_DISCONNECT:
+ IPADBG("Got IPA_IOC_GSB_DISCONNECT\n");
+ if (ipa3_send_gsb_msg(arg, IPA_GSB_DISCONNECT)) {
+ retval = -EFAULT;
+ break;
+ }
+ break;
+
default:
IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
return -ENOTTY;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c
index 0925e8c..690d564 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c
@@ -76,6 +76,8 @@
__stringify(ADD_BRIDGE_VLAN_MAPPING),
__stringify(DEL_BRIDGE_VLAN_MAPPING),
__stringify(WLAN_FWR_SSR_BEFORE_SHUTDOWN),
+ __stringify(IPA_GSB_CONNECT),
+ __stringify(IPA_GSB_DISCONNECT),
};
const char *ipa3_hdr_l2_type_name[] = {
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c b/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c
index 2716d4a..7ab4a8b 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c
@@ -242,6 +242,7 @@
dev->smem_offset = smem_offset;
dev->is_dev_init = true;
+ dev->tmp_mem = tmp_mem;
mutex_unlock(&dev->lock);
IPADBG("ipa dev %s added successful. major:%d minor:%d\n", name,
@@ -838,19 +839,24 @@
IPADBG("\n");
+ mutex_lock(&ipa3_ctx->nat_mem.dev.lock);
+
if (!ipa3_ctx->nat_mem.dev.is_mapped) {
IPAERR_RL("attempt to init %s before mmap\n",
ipa3_ctx->nat_mem.dev.name);
+ mutex_unlock(&ipa3_ctx->nat_mem.dev.lock);
return -EPERM;
}
if (init->tbl_index >= 1) {
IPAERR_RL("Unsupported table index %d\n", init->tbl_index);
+ mutex_unlock(&ipa3_ctx->nat_mem.dev.lock);
return -EPERM;
}
if (init->table_entries == 0) {
IPAERR_RL("Table entries is zero\n");
+ mutex_unlock(&ipa3_ctx->nat_mem.dev.lock);
return -EPERM;
}
@@ -861,6 +867,7 @@
IPAHAL_NAT_IPV4);
if (result) {
IPAERR_RL("Bad params for NAT base table\n");
+ mutex_unlock(&ipa3_ctx->nat_mem.dev.lock);
return result;
}
@@ -871,6 +878,7 @@
IPAHAL_NAT_IPV4);
if (result) {
IPAERR_RL("Bad params for NAT expansion table\n");
+ mutex_unlock(&ipa3_ctx->nat_mem.dev.lock);
return result;
}
@@ -881,6 +889,7 @@
IPAHAL_NAT_IPV4_INDEX);
if (result) {
IPAERR_RL("Bad params for index table\n");
+ mutex_unlock(&ipa3_ctx->nat_mem.dev.lock);
return result;
}
@@ -891,6 +900,7 @@
IPAHAL_NAT_IPV4_INDEX);
if (result) {
IPAERR_RL("Bad params for index expansion table\n");
+ mutex_unlock(&ipa3_ctx->nat_mem.dev.lock);
return result;
}
@@ -924,6 +934,7 @@
result = ipa3_nat_send_init_cmd(&cmd, false);
if (result) {
IPAERR("Fail to send NAT init immediate command\n");
+ mutex_unlock(&ipa3_ctx->nat_mem.dev.lock);
return result;
}
@@ -949,6 +960,8 @@
ipa3_ctx->nat_mem.index_table_expansion_addr);
ipa3_ctx->nat_mem.dev.is_hw_init = true;
+ mutex_unlock(&ipa3_ctx->nat_mem.dev.lock);
+
IPADBG("return\n");
return 0;
}
@@ -1073,26 +1086,32 @@
struct ipahal_imm_cmd_pyld *cmd_pyld;
int result = 0;
struct ipa3_nat_mem *nat_ctx = &(ipa3_ctx->nat_mem);
- struct ipa_pdn_entry *pdn_entries = nat_ctx->pdn_mem.base;
+ struct ipa_pdn_entry *pdn_entries = NULL;
IPADBG("\n");
+ mutex_lock(&nat_ctx->dev.lock);
+
if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_0) {
IPAERR_RL("IPA HW does not support multi PDN\n");
- return -EPERM;
+ result = -EPERM;
+ goto bail;
}
+
if (!nat_ctx->dev.is_mem_allocated) {
IPAERR_RL(
"attempt to modify a PDN entry before the PDN table memory allocation\n");
- return -EPERM;
+ result = -EPERM;
+ goto bail;
}
if (mdfy_pdn->pdn_index > (IPA_MAX_PDN_NUM - 1)) {
IPAERR_RL("pdn index out of range %d\n", mdfy_pdn->pdn_index);
- return -EPERM;
+ result = -EPERM;
+ goto bail;
}
- mutex_lock(&nat_ctx->dev.lock);
+ pdn_entries = nat_ctx->pdn_mem.base;
/* store ip in pdn entries cache array */
pdn_entries[mdfy_pdn->pdn_index].public_ip =
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c b/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
index 2212b00..8a7b414 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
@@ -332,8 +332,8 @@
if ((tbl->sz[IPA_RULE_HASHABLE] +
tbl->sz[IPA_RULE_NON_HASHABLE]) == 0) {
- WARN_ON_RATELIMIT_IPA(1);
- IPAERR_RL("rt tbl %s is with zero total size\n", tbl->name);
+ IPADBG("rt tbl %s is with zero total size\n", tbl->name);
+ return 0;
}
hdr_width = ipahal_get_hw_tbl_hdr_width();
@@ -1047,13 +1047,12 @@
goto error;
}
/*
- * do not allow any rules to be added at end of the "default" routing
- * tables
+ * do not allow any rule to be added at "default" routing
+ * table
*/
if (!strcmp(tbl->name, IPA_DFLT_RT_TBL_NAME) &&
- (tbl->rule_cnt > 0) && (at_rear != 0)) {
- IPAERR_RL("cannot add rule at end of tbl rule_cnt=%d at_rear=%d"
- , tbl->rule_cnt, at_rear);
+ (tbl->rule_cnt > 0)) {
+ IPAERR_RL("cannot add rules to default rt table\n");
goto error;
}
@@ -1276,13 +1275,12 @@
}
/*
- * do not allow any rules to be added at end of the "default" routing
- * tables
+ * do not allow any rule to be added at "default" routing
+ * table
*/
if (!strcmp(tbl->name, IPA_DFLT_RT_TBL_NAME) &&
- (&entry->link == tbl->head_rt_rule_list.prev)) {
- IPAERR_RL("cannot add rule at end of tbl rule_cnt=%d\n",
- tbl->rule_cnt);
+ (tbl->rule_cnt > 0)) {
+ IPAERR_RL("cannot add rules to default rt table\n");
ret = -EINVAL;
goto bail;
}
@@ -1489,6 +1487,8 @@
struct ipa3_rt_entry *rule;
struct ipa3_rt_entry *rule_next;
struct ipa3_rt_tbl_set *rset;
+ struct ipa3_hdr_entry *hdr_entry;
+ struct ipa3_hdr_proc_ctx_entry *hdr_proc_entry;
u32 apps_start_idx;
int id;
bool tbl_user = false;
@@ -1542,6 +1542,27 @@
if (!user_only ||
rule->ipacm_installed) {
list_del(&rule->link);
+ if (rule->hdr) {
+ hdr_entry = ipa3_id_find(
+ rule->rule.hdr_hdl);
+ if (!hdr_entry ||
+ hdr_entry->cookie != IPA_HDR_COOKIE) {
+ IPAERR_RL(
+ "Header already deleted\n");
+ return -EINVAL;
+ }
+ } else if (rule->proc_ctx) {
+ hdr_proc_entry =
+ ipa3_id_find(
+ rule->rule.hdr_proc_ctx_hdl);
+ if (!hdr_proc_entry ||
+ hdr_proc_entry->cookie !=
+ IPA_PROC_HDR_COOKIE) {
+ IPAERR_RL(
+ "Proc entry already deleted\n");
+ return -EINVAL;
+ }
+ }
tbl->rule_cnt--;
if (rule->hdr)
__ipa3_release_hdr(rule->hdr->id);
@@ -1549,7 +1570,9 @@
__ipa3_release_hdr_proc_ctx(
rule->proc_ctx->id);
rule->cookie = 0;
- idr_remove(tbl->rule_ids, rule->rule_id);
+ if (!rule->rule_id_valid)
+ idr_remove(tbl->rule_ids,
+ rule->rule_id);
id = rule->id;
kmem_cache_free(ipa3_ctx->rt_rule_cache, rule);
@@ -1742,6 +1765,10 @@
goto error;
}
+ if (!strcmp(entry->tbl->name, IPA_DFLT_RT_TBL_NAME)) {
+ IPAERR_RL("Default tbl rule cannot be modified\n");
+ return -EINVAL;
+ }
/* Adding check to confirm still
* header entry present in header table or not
*/
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_uc.c b/drivers/platform/msm/ipa/ipa_v3/ipa_uc.c
index e746229..89dde7d 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc.c
@@ -569,7 +569,11 @@
if (ipa3_ctx->uc_ctx.uc_status ==
IPA_HW_PROD_DISABLE_CMD_GSI_STOP_FAILURE ||
ipa3_ctx->uc_ctx.uc_status ==
- IPA_HW_CONS_DISABLE_CMD_GSI_STOP_FAILURE) {
+ IPA_HW_CONS_DISABLE_CMD_GSI_STOP_FAILURE ||
+ ipa3_ctx->uc_ctx.uc_status ==
+ IPA_HW_CONS_STOP_FAILURE ||
+ ipa3_ctx->uc_ctx.uc_status ==
+ IPA_HW_PROD_STOP_FAILURE) {
retries++;
if (retries == IPA_GSI_CHANNEL_STOP_MAX_RETRY) {
IPAERR("Failed after %d tries\n", retries);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_offload_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_offload_i.h
index 8d415a1..bda4219 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_offload_i.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_offload_i.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -92,6 +92,8 @@
* @IPA_HW_INVALID_OPCODE : Invalid opcode sent
* @IPA_HW_INVALID_PARAMS : Invalid params for the requested command
* @IPA_HW_GSI_CH_NOT_EMPTY_FAILURE : GSI channel emptiness validation failed
+ * @IPA_HW_CONS_STOP_FAILURE : NTN/ETH CONS stop failed
+ * @IPA_HW_PROD_STOP_FAILURE : NTN/ETH PROD stop failed
*/
enum ipa3_hw_errors {
IPA_HW_ERROR_NONE =
@@ -111,7 +113,11 @@
IPA_HW_PROD_DISABLE_CMD_GSI_STOP_FAILURE =
FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 7),
IPA_HW_GSI_CH_NOT_EMPTY_FAILURE =
- FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 8)
+ FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 8),
+ IPA_HW_CONS_STOP_FAILURE =
+ FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 9),
+ IPA_HW_PROD_STOP_FAILURE =
+ FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 10)
};
/**
diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa_fd_ioctl.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa_fd_ioctl.c
index 929242a..2a406f5e 100644
--- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa_fd_ioctl.c
+++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa_fd_ioctl.c
@@ -82,8 +82,17 @@
DRIVER_NAME);
if (!ipa3_process_ioctl) {
- IPAWANDBG("modem is in SSR, ignoring ioctl\n");
- return -EAGAIN;
+
+ if ((cmd == WAN_IOC_SET_LAN_CLIENT_INFO) ||
+ (cmd == WAN_IOC_CLEAR_LAN_CLIENT_INFO)) {
+ IPAWANDBG("Modem is in SSR\n");
+ IPAWANDBG("Still allow IOCTL for exceptions (%d)\n",
+ cmd);
+ } else {
+ IPAWANERR("Modem is in SSR, ignoring ioctl (%d)\n",
+ cmd);
+ return -EAGAIN;
+ }
}
switch (cmd) {
diff --git a/drivers/platform/msm/mhi_dev/mhi.c b/drivers/platform/msm/mhi_dev/mhi.c
index c938e8e..c3e4bc59 100644
--- a/drivers/platform/msm/mhi_dev/mhi.c
+++ b/drivers/platform/msm/mhi_dev/mhi.c
@@ -1278,7 +1278,7 @@
ring = &mhi->ring[ch_num + mhi->ch_ring_start];
if (ring->state == RING_STATE_UINT) {
pr_debug("Channel not opened for %d\n", ch_num);
- break;
+ continue;
}
mhi_ring_set_state(ring, RING_STATE_PENDING);
list_add(&ring->list, &mhi->process_ring_list);
@@ -1429,7 +1429,7 @@
ch = client->channel;
mhi = ch->ring->mhi_dev;
el = req->el;
- transfer_len = req->len;
+ transfer_len = req->transfer_len;
snd_cmpl = req->snd_cmpl;
rd_offset = req->rd_offset;
ch->curr_ereq->context = ch;
@@ -2142,7 +2142,7 @@
(mreq->len - usr_buf_remaining);
ch->tre_bytes_left -= bytes_to_read;
mreq->el = el;
- mreq->actual_len = bytes_read;
+ mreq->transfer_len = bytes_to_read;
mreq->rd_offset = ring->rd_offset;
mhi_log(MHI_MSG_VERBOSE, "reading %d bytes from chan %d\n",
bytes_to_read, mreq->chan);
@@ -2306,6 +2306,7 @@
write_to_loc = el->tre.data_buf_ptr;
wreq->rd_offset = ring->rd_offset;
wreq->el = el;
+ wreq->transfer_len = bytes_to_write;
rc = mhi_transfer_device_to_host(write_to_loc,
(void *) read_from_loc,
bytes_to_write,
@@ -2362,6 +2363,64 @@
}
EXPORT_SYMBOL(mhi_dev_write_channel);
+static int mhi_dev_recover(struct mhi_dev *mhi)
+{
+ int rc = 0;
+ uint32_t syserr, max_cnt = 0, bhi_intvec = 0;
+ bool mhi_reset;
+ enum mhi_dev_state state;
+
+ /* Check if MHI is in syserr */
+ mhi_dev_mmio_masked_read(mhi, MHISTATUS,
+ MHISTATUS_SYSERR_MASK,
+ MHISTATUS_SYSERR_SHIFT, &syserr);
+
+ mhi_log(MHI_MSG_VERBOSE, "mhi_syserr = 0x%X\n", syserr);
+ if (syserr) {
+ rc = mhi_dev_mmio_read(mhi, BHI_INTVEC, &bhi_intvec);
+ if (rc)
+ return rc;
+
+ if (bhi_intvec != 0xffffffff) {
+ /* Indicate the host that the device is ready */
+ rc = ep_pcie_trigger_msi(mhi->phandle, bhi_intvec);
+ if (rc) {
+ pr_err("%s: error sending msi\n", __func__);
+ return rc;
+ }
+ }
+
+ /* Poll for the host to set the reset bit */
+ rc = mhi_dev_mmio_get_mhi_state(mhi, &state, &mhi_reset);
+ if (rc) {
+ pr_err("%s: get mhi state failed\n", __func__);
+ return rc;
+ }
+ while (mhi_reset != true && max_cnt < MHI_SUSPEND_TIMEOUT) {
+ /* Wait for Host to set the reset */
+ msleep(MHI_SUSPEND_MIN);
+ rc = mhi_dev_mmio_get_mhi_state(mhi, &state,
+ &mhi_reset);
+ if (rc) {
+ pr_err("%s: get mhi state failed\n", __func__);
+ return rc;
+ }
+ max_cnt++;
+ }
+
+ if (!mhi_reset) {
+ mhi_log(MHI_MSG_VERBOSE, "Host failed to set reset\n");
+ return -EINVAL;
+ }
+ }
+ /*
+ * Now mask the interrupts so that the state machine moves
+ * only after IPA is ready
+ */
+ mhi_dev_mmio_mask_interrupts(mhi);
+ return 0;
+}
+
static void mhi_dev_enable(struct work_struct *work)
{
int rc = 0;
@@ -2864,6 +2923,18 @@
mutex_init(&mhi_ctx->mhi_event_lock);
mutex_init(&mhi_ctx->mhi_write_test);
+ mhi_ctx->phandle = ep_pcie_get_phandle(mhi_ctx->ifc_id);
+ if (!mhi_ctx->phandle) {
+ pr_err("PCIe driver get handle failed.\n");
+ return -EINVAL;
+ }
+
+ rc = mhi_dev_recover(mhi_ctx);
+ if (rc) {
+ pr_err("%s: get mhi state failed\n", __func__);
+ return rc;
+ }
+
rc = mhi_init(mhi_ctx);
if (rc)
return rc;
@@ -2893,13 +2964,6 @@
pr_err("Failed to update the MHI version\n");
return rc;
}
-
- mhi_ctx->phandle = ep_pcie_get_phandle(mhi_ctx->ifc_id);
- if (!mhi_ctx->phandle) {
- pr_err("PCIe driver get handle failed.\n");
- return -EINVAL;
- }
-
mhi_ctx->event_reg.events = EP_PCIE_EVENT_PM_D3_HOT |
EP_PCIE_EVENT_PM_D3_COLD |
EP_PCIE_EVENT_PM_D0 |
@@ -3091,7 +3155,7 @@
{
return platform_driver_register(&mhi_dev_driver);
}
-module_init(mhi_dev_init);
+subsys_initcall(mhi_dev_init);
static void __exit mhi_dev_exit(void)
{
diff --git a/drivers/platform/msm/mhi_dev/mhi.h b/drivers/platform/msm/mhi_dev/mhi.h
index 6cb2d7d..fae39e0 100644
--- a/drivers/platform/msm/mhi_dev/mhi.h
+++ b/drivers/platform/msm/mhi_dev/mhi.h
@@ -906,6 +906,12 @@
int mhi_dev_mmio_read_erdb_status_interrupts(struct mhi_dev *dev);
/**
+ * mhi_dev_mmio_mask_interrupts() - Mask all MHI interrupts.
+ * @dev: MHI device structure.
+ */
+void mhi_dev_mmio_mask_interrupts(struct mhi_dev *dev);
+
+/**
* mhi_dev_mmio_clear_interrupts() - Clear all doorbell interrupts.
* @dev: MHI device structure.
*/
diff --git a/drivers/platform/msm/mhi_dev/mhi_dev_net.c b/drivers/platform/msm/mhi_dev/mhi_dev_net.c
index d8dc85f..d1f86a4 100644
--- a/drivers/platform/msm/mhi_dev/mhi_dev_net.c
+++ b/drivers/platform/msm/mhi_dev/mhi_dev_net.c
@@ -246,10 +246,10 @@
struct sk_buff *skb = mreq->context;
unsigned long flags;
- skb->len = mreq->actual_len;
+ skb->len = mreq->transfer_len;
skb->protocol =
mhi_dev_net_eth_type_trans(skb);
- skb_put(skb, mreq->actual_len);
+ skb_put(skb, mreq->transfer_len);
net_handle->dev->stats.rx_packets++;
skb->dev = net_handle->dev;
netif_rx(skb);
diff --git a/drivers/platform/msm/mhi_dev/mhi_mmio.c b/drivers/platform/msm/mhi_dev/mhi_mmio.c
index 559fa84..28d465a 100644
--- a/drivers/platform/msm/mhi_dev/mhi_mmio.c
+++ b/drivers/platform/msm/mhi_dev/mhi_mmio.c
@@ -568,7 +568,7 @@
}
EXPORT_SYMBOL(mhi_dev_mmio_disable_cmdb_interrupt);
-static void mhi_dev_mmio_mask_interrupts(struct mhi_dev *dev)
+void mhi_dev_mmio_mask_interrupts(struct mhi_dev *dev)
{
int rc = 0;
@@ -596,6 +596,7 @@
return;
}
}
+EXPORT_SYMBOL(mhi_dev_mmio_mask_interrupts);
int mhi_dev_mmio_clear_interrupts(struct mhi_dev *dev)
{
diff --git a/drivers/platform/msm/mhi_dev/mhi_uci.c b/drivers/platform/msm/mhi_dev/mhi_uci.c
index 52d324e..bbf4e1b 100644
--- a/drivers/platform/msm/mhi_dev/mhi_uci.c
+++ b/drivers/platform/msm/mhi_dev/mhi_uci.c
@@ -41,6 +41,7 @@
#define MAX_DEVICE_NAME_SIZE 80
#define MHI_UCI_ASYNC_READ_TIMEOUT msecs_to_jiffies(100)
+#define MHI_UCI_ASYNC_WRITE_TIMEOUT msecs_to_jiffies(100)
enum uci_dbg_level {
UCI_DBG_VERBOSE = 0x0,
@@ -73,12 +74,21 @@
u32 nr_trbs;
/* direction of the channel, see enum mhi_chan_dir */
enum mhi_chan_dir dir;
- /* need to register mhi channel state change callback */
- bool register_cb;
+ /* Optional mhi channel state change callback func pointer */
+ void (*chan_state_cb)(struct mhi_dev_client_cb_data *cb_data);
/* Name of char device */
char *device_name;
+ /* Client-specific TRE handler */
+ void (*tre_notif_cb)(struct mhi_dev_client_cb_reason *reason);
+ /* Write completion - false if not needed */
+ bool wr_cmpl;
+
};
+static void mhi_uci_adb_client_cb(struct mhi_dev_client_cb_data *cb_data);
+static void mhi_uci_at_ctrl_client_cb(struct mhi_dev_client_cb_data *cb_data);
+static void mhi_uci_at_ctrl_tre_cb(struct mhi_dev_client_cb_reason *reason);
+
/* UCI channel attributes table */
static const struct chan_attr uci_chan_attr_table[] = {
{
@@ -86,7 +96,7 @@
TRB_MAX_DATA_SIZE,
MAX_NR_TRBS_PER_CHAN,
MHI_DIR_OUT,
- false,
+ NULL,
NULL
},
{
@@ -94,7 +104,7 @@
TRB_MAX_DATA_SIZE,
MAX_NR_TRBS_PER_CHAN,
MHI_DIR_IN,
- false,
+ NULL,
NULL
},
{
@@ -102,7 +112,7 @@
TRB_MAX_DATA_SIZE,
MAX_NR_TRBS_PER_CHAN,
MHI_DIR_OUT,
- false,
+ NULL,
NULL
},
{
@@ -110,7 +120,7 @@
TRB_MAX_DATA_SIZE,
MAX_NR_TRBS_PER_CHAN,
MHI_DIR_IN,
- false,
+ NULL,
NULL
},
{
@@ -118,7 +128,7 @@
TRB_MAX_DATA_SIZE,
MAX_NR_TRBS_PER_CHAN,
MHI_DIR_OUT,
- false,
+ NULL,
NULL
},
{
@@ -126,7 +136,7 @@
TRB_MAX_DATA_SIZE,
MAX_NR_TRBS_PER_CHAN,
MHI_DIR_IN,
- false,
+ NULL,
NULL
},
{
@@ -134,7 +144,7 @@
TRB_MAX_DATA_SIZE,
MAX_NR_TRBS_PER_CHAN,
MHI_DIR_OUT,
- false,
+ NULL,
NULL
},
{
@@ -142,7 +152,7 @@
TRB_MAX_DATA_SIZE,
MAX_NR_TRBS_PER_CHAN,
MHI_DIR_IN,
- false,
+ NULL,
NULL
},
{
@@ -150,7 +160,7 @@
TRB_MAX_DATA_SIZE,
MAX_NR_TRBS_PER_CHAN,
MHI_DIR_OUT,
- false,
+ NULL,
NULL
},
{
@@ -158,7 +168,7 @@
TRB_MAX_DATA_SIZE,
MAX_NR_TRBS_PER_CHAN,
MHI_DIR_IN,
- false,
+ NULL,
NULL
},
{
@@ -166,7 +176,7 @@
TRB_MAX_DATA_SIZE,
MAX_NR_TRBS_PER_CHAN,
MHI_DIR_OUT,
- false,
+ NULL,
NULL
},
{
@@ -174,7 +184,7 @@
TRB_MAX_DATA_SIZE,
MAX_NR_TRBS_PER_CHAN,
MHI_DIR_IN,
- false,
+ NULL,
NULL
},
{
@@ -182,23 +192,26 @@
TRB_MAX_DATA_SIZE,
MAX_NR_TRBS_PER_CHAN,
MHI_DIR_OUT,
- false,
- NULL
+ mhi_uci_at_ctrl_client_cb,
+ NULL,
+ mhi_uci_at_ctrl_tre_cb
},
{
MHI_CLIENT_IP_CTRL_1_IN,
TRB_MAX_DATA_SIZE,
MAX_NR_TRBS_PER_CHAN,
MHI_DIR_IN,
- false,
- NULL
+ mhi_uci_at_ctrl_client_cb,
+ NULL,
+ NULL,
+ true
},
{
MHI_CLIENT_DUN_OUT,
TRB_MAX_DATA_SIZE,
MAX_NR_TRBS_PER_CHAN,
MHI_DIR_OUT,
- false,
+ NULL,
NULL
},
{
@@ -206,7 +219,7 @@
TRB_MAX_DATA_SIZE,
MAX_NR_TRBS_PER_CHAN,
MHI_DIR_IN,
- false,
+ NULL,
NULL
},
{
@@ -214,7 +227,7 @@
TRB_MAX_DATA_SIZE,
MAX_NR_TRBS_PER_CHAN,
MHI_DIR_OUT,
- true,
+ mhi_uci_adb_client_cb,
NULL
},
{
@@ -222,11 +235,33 @@
TRB_MAX_DATA_SIZE,
MAX_NR_TRBS_PER_CHAN,
MHI_DIR_IN,
- true,
+ mhi_uci_adb_client_cb,
"android_adb"
},
};
+/* Defines for AT messages */
+#define MHI_UCI_CTRL_MSG_MAGIC (0x4354524C)
+#define MHI_UCI_CTRL_MSG_DTR BIT(0)
+#define MHI_UCI_CTRL_MSG_RTS BIT(1)
+#define MHI_UCI_CTRL_MSG_DCD BIT(0)
+#define MHI_UCI_CTRL_MSG_DSR BIT(1)
+#define MHI_UCI_CTRL_MSG_RI BIT(3)
+
+#define MHI_UCI_CTRL_MSGID_SET_CTRL_LINE 0x10
+#define MHI_UCI_CTRL_MSGID_SERIAL_STATE 0x11
+#define MHI_UCI_TIOCM_GET TIOCMGET
+#define MHI_UCI_TIOCM_SET TIOCMSET
+
+/* AT message format */
+struct __packed mhi_uci_ctrl_msg {
+ u32 preamble;
+ u32 msg_id;
+ u32 dest_id;
+ u32 size;
+ u32 msg;
+};
+
struct uci_ctrl {
wait_queue_head_t ctrl_wq;
struct mhi_uci_ctxt_t *uci_ctxt;
@@ -262,8 +297,11 @@
struct mhi_req *wreqs;
struct list_head wr_req_list;
struct completion read_done;
+ struct completion *write_done;
int (*send)(struct uci_client*, void*, u32);
int (*read)(struct uci_client*, struct mhi_req*, int*);
+ unsigned int tiocm;
+ unsigned int at_ctrl_mask;
};
struct mhi_uci_ctxt_t {
@@ -278,6 +316,8 @@
struct class *mhi_uci_class;
atomic_t mhi_disabled;
atomic_t mhi_enable_notif_wq_active;
+ struct workqueue_struct *at_ctrl_wq;
+ struct work_struct at_ctrl_work;
};
#define CHAN_TO_CLIENT(_CHAN_NR) (_CHAN_NR / 2)
@@ -375,6 +415,9 @@
spin_lock_irqsave(&uci_handle->wr_req_lock, flags);
list_add_tail(&ureq->list, &uci_handle->wr_req_list);
spin_unlock_irqrestore(&uci_handle->wr_req_lock, flags);
+
+ if (uci_handle->write_done)
+ complete(uci_handle->write_done);
}
static void mhi_uci_read_completion_cb(void *req)
@@ -400,7 +443,8 @@
ret_val = mhi_dev_write_channel(&ureq);
- kfree(data_loc);
+ if (ret_val == size)
+ kfree(data_loc);
return ret_val;
}
@@ -441,7 +485,6 @@
return bytes_to_write;
error_async_transfer:
- kfree(data_loc);
ureq->buf = NULL;
spin_lock_irq(&uci_handle->wr_req_lock);
list_add_tail(&ureq->list, &uci_handle->wr_req_list);
@@ -450,41 +493,42 @@
return bytes_to_write;
}
-static int mhi_uci_send_packet(struct mhi_dev_client **client_handle,
- const char __user *buf, u32 size)
+static int mhi_uci_send_packet(struct uci_client *uci_handle, void *data_loc,
+ u32 size)
{
- void *data_loc;
- unsigned long memcpy_result;
- struct uci_client *uci_handle;
+ int ret_val;
- if (!client_handle || !buf || !size)
- return -EINVAL;
+ mutex_lock(&uci_handle->out_chan_lock);
+ do {
+ ret_val = uci_handle->send(uci_handle, data_loc, size);
+ if (ret_val < 0) {
+ uci_log(UCI_DBG_ERROR,
+ "Err sending data: chan %d, buf %pK, size %d\n",
+ uci_handle->out_chan, data_loc, size);
+ ret_val = -EIO;
+ break;
+ }
+ if (!ret_val) {
+ uci_log(UCI_DBG_VERBOSE,
+ "No descriptors available, did we poll, chan %d?\n",
+ uci_handle->out_chan);
+ mutex_unlock(&uci_handle->out_chan_lock);
+ if (uci_handle->f_flags & (O_NONBLOCK | O_NDELAY))
+ return -EAGAIN;
+ ret_val = wait_event_interruptible(uci_handle->write_wq,
+ !mhi_dev_channel_isempty(
+ uci_handle->out_handle));
+ if (-ERESTARTSYS == ret_val) {
+ uci_log(UCI_DBG_WARNING,
+ "Waitqueue cancelled by system\n");
+ return ret_val;
+ }
+ mutex_lock(&uci_handle->out_chan_lock);
+ }
+ } while (!ret_val);
+ mutex_unlock(&uci_handle->out_chan_lock);
- if (size > TRB_MAX_DATA_SIZE) {
- uci_log(UCI_DBG_ERROR,
- "Too big write size: %d, max supported size is %d\n",
- size, TRB_MAX_DATA_SIZE);
- return -EFBIG;
- }
-
- uci_handle = container_of(client_handle, struct uci_client,
- out_handle);
- data_loc = kmalloc(size, GFP_KERNEL);
- if (!data_loc) {
- uci_log(UCI_DBG_ERROR,
- "Failed to allocate kernel buf for user requested size 0x%x\n",
- size);
- return -ENOMEM;
- }
- memcpy_result = copy_from_user(data_loc, buf, size);
- if (memcpy_result)
- goto error_memcpy;
-
- return uci_handle->send(uci_handle, data_loc, size);
-
-error_memcpy:
- kfree(data_loc);
- return -EFAULT;
+ return ret_val;
}
static unsigned int mhi_uci_ctrl_poll(struct file *file, poll_table *wait)
@@ -523,6 +567,7 @@
poll_wait(file, &uci_handle->read_wq, wait);
poll_wait(file, &uci_handle->write_wq, wait);
+ mask = uci_handle->at_ctrl_mask;
if (!atomic_read(&uci_ctxt.mhi_disabled) &&
!mhi_dev_channel_isempty(uci_handle->in_handle)) {
uci_log(UCI_DBG_VERBOSE,
@@ -608,7 +653,7 @@
"wk up Read completed on ch %d\n", ureq->chan);
uci_handle->pkt_loc = (void *)ureq->buf;
- uci_handle->pkt_size = ureq->actual_len;
+ uci_handle->pkt_size = ureq->transfer_len;
uci_log(UCI_DBG_VERBOSE,
"Got pkt of sz 0x%x at adr %pK, ch %d\n",
@@ -641,7 +686,7 @@
if (*bytes_avail > 0) {
uci_handle->pkt_loc = (void *)ureq->buf;
- uci_handle->pkt_size = ureq->actual_len;
+ uci_handle->pkt_size = ureq->transfer_len;
uci_log(UCI_DBG_VERBOSE,
"Got pkt of sz 0x%x at adr %pK, ch %d\n",
@@ -912,81 +957,62 @@
return size;
}
-static ssize_t mhi_uci_client_read(struct file *file, char __user *ubuf,
- size_t uspace_buf_size, loff_t *bytes_pending)
+static int __mhi_uci_client_read(struct uci_client *uci_handle,
+ int *bytes_avail)
{
- struct uci_client *uci_handle = NULL;
- struct mhi_dev_client *client_handle = NULL;
- int bytes_avail = 0;
int ret_val = 0;
- struct mutex *mutex;
- ssize_t bytes_copied = 0;
- u32 addr_offset = 0;
+ struct mhi_dev_client *client_handle;
struct mhi_req ureq;
- if (!file || !ubuf || !uspace_buf_size ||
- !file->private_data)
- return -EINVAL;
-
- uci_handle = file->private_data;
client_handle = uci_handle->in_handle;
- mutex = &uci_handle->in_chan_lock;
ureq.chan = uci_handle->in_chan;
-
- mutex_lock(mutex);
ureq.client = client_handle;
ureq.buf = uci_handle->in_buf_list[0].addr;
ureq.len = uci_handle->in_buf_list[0].buf_size;
-
- uci_log(UCI_DBG_VERBOSE, "Client attempted read on chan %d\n",
- ureq.chan);
do {
if (!uci_handle->pkt_loc &&
!atomic_read(&uci_ctxt.mhi_disabled)) {
ret_val = uci_handle->read(uci_handle, &ureq,
- &bytes_avail);
+ bytes_avail);
if (ret_val)
- goto error;
- if (bytes_avail > 0)
- *bytes_pending = (loff_t)uci_handle->pkt_size;
+ return ret_val;
}
- if (bytes_avail == 0) {
+ if (*bytes_avail == 0) {
/* If nothing was copied yet, wait for data */
uci_log(UCI_DBG_VERBOSE,
"No data read_data_ready %d, chan %d\n",
atomic_read(&uci_handle->read_data_ready),
ureq.chan);
- if (uci_handle->f_flags & (O_NONBLOCK | O_NDELAY)) {
- ret_val = -EAGAIN;
- goto error;
- }
+ if (uci_handle->f_flags & (O_NONBLOCK | O_NDELAY))
+ return -EAGAIN;
+
ret_val = wait_event_interruptible(uci_handle->read_wq,
(!mhi_dev_channel_isempty(client_handle)));
if (ret_val == -ERESTARTSYS) {
uci_log(UCI_DBG_ERROR, "Exit signal caught\n");
- goto error;
+ return ret_val;
}
+
uci_log(UCI_DBG_VERBOSE,
"wk up Got data on ch %d read_data_ready %d\n",
ureq.chan,
atomic_read(&uci_handle->read_data_ready));
-
+ } else if (*bytes_avail > 0) {
/* A valid packet was returned from MHI */
- } else if (bytes_avail > 0) {
uci_log(UCI_DBG_VERBOSE,
"Got packet: avail pkts %d phy_adr %p, ch %d\n",
atomic_read(&uci_handle->read_data_ready),
ureq.buf,
ureq.chan);
break;
+ } else {
/*
* MHI did not return a valid packet, but we have one
* which we did not finish returning to user
*/
- } else {
uci_log(UCI_DBG_CRITICAL,
"chan %d err: avail pkts %d phy_adr %p",
ureq.chan,
@@ -996,10 +1022,36 @@
}
} while (!uci_handle->pkt_loc);
+ return ret_val;
+}
+
+static ssize_t mhi_uci_client_read(struct file *file, char __user *ubuf,
+ size_t uspace_buf_size, loff_t *bytes_pending)
+{
+ struct uci_client *uci_handle = NULL;
+ int bytes_avail = 0, ret_val = 0;
+ struct mutex *mutex;
+ ssize_t bytes_copied = 0;
+ u32 addr_offset = 0;
+
+ uci_handle = file->private_data;
+ mutex = &uci_handle->in_chan_lock;
+ mutex_lock(mutex);
+
+ uci_log(UCI_DBG_VERBOSE, "Client attempted read on chan %d\n",
+ uci_handle->in_chan);
+
+ ret_val = __mhi_uci_client_read(uci_handle, &bytes_avail);
+ if (ret_val)
+ goto error;
+
+ if (bytes_avail > 0)
+ *bytes_pending = (loff_t)uci_handle->pkt_size;
+
if (uspace_buf_size >= *bytes_pending) {
addr_offset = uci_handle->pkt_size - *bytes_pending;
if (copy_to_user(ubuf, uci_handle->pkt_loc + addr_offset,
- *bytes_pending)) {
+ *bytes_pending)) {
ret_val = -EIO;
goto error;
}
@@ -1007,50 +1059,51 @@
bytes_copied = *bytes_pending;
*bytes_pending = 0;
uci_log(UCI_DBG_VERBOSE, "Copied 0x%x of 0x%x, chan %d\n",
- bytes_copied, (u32)*bytes_pending, ureq.chan);
+ bytes_copied, (u32)*bytes_pending, uci_handle->in_chan);
} else {
addr_offset = uci_handle->pkt_size - *bytes_pending;
if (copy_to_user(ubuf, (void *) (uintptr_t)uci_handle->pkt_loc +
- addr_offset, uspace_buf_size)) {
+ addr_offset, uspace_buf_size)) {
ret_val = -EIO;
goto error;
}
bytes_copied = uspace_buf_size;
*bytes_pending -= uspace_buf_size;
uci_log(UCI_DBG_VERBOSE, "Copied 0x%x of 0x%x,chan %d\n",
- bytes_copied,
- (u32)*bytes_pending,
- ureq.chan);
+ bytes_copied,
+ (u32)*bytes_pending,
+ uci_handle->in_chan);
}
/* We finished with this buffer, map it back */
if (*bytes_pending == 0) {
uci_log(UCI_DBG_VERBOSE,
- "All data consumed. Pkt loc %p ,chan %d\n",
- uci_handle->pkt_loc, ureq.chan);
+ "All data consumed. Pkt loc %p ,chan %d\n",
+ uci_handle->pkt_loc, uci_handle->in_chan);
uci_handle->pkt_loc = 0;
uci_handle->pkt_size = 0;
}
uci_log(UCI_DBG_VERBOSE,
- "Returning 0x%x bytes, 0x%x bytes left\n",
- bytes_copied, (u32)*bytes_pending);
+ "Returning 0x%x bytes, 0x%x bytes left\n",
+ bytes_copied, (u32)*bytes_pending);
mutex_unlock(mutex);
return bytes_copied;
error:
mutex_unlock(mutex);
+
uci_log(UCI_DBG_ERROR, "Returning %d\n", ret_val);
return ret_val;
}
static ssize_t mhi_uci_client_write(struct file *file,
- const char __user *buf,
- size_t count, loff_t *offp)
+ const char __user *buf, size_t count, loff_t *offp)
{
struct uci_client *uci_handle = NULL;
- int ret_val = 0;
- u32 chan = 0xFFFFFFFF;
+ void *data_loc;
+ unsigned long memcpy_result;
+ int rc;
if (file == NULL || buf == NULL ||
- !count || file->private_data == NULL)
+ !count || file->private_data == NULL)
return -EINVAL;
uci_handle = file->private_data;
@@ -1061,39 +1114,32 @@
uci_handle->out_chan);
return -EIO;
}
- chan = uci_handle->out_chan;
- mutex_lock(&uci_handle->out_chan_lock);
- while (!ret_val) {
- ret_val = mhi_uci_send_packet(&uci_handle->out_handle,
- buf, count);
- if (ret_val < 0) {
- uci_log(UCI_DBG_ERROR,
- "Error while writing data to MHI, chan %d, buf %pK, size %d\n",
- chan, (void *)buf, count);
- ret_val = -EIO;
- break;
- }
- if (!ret_val) {
- uci_log(UCI_DBG_VERBOSE,
- "No descriptors available, did we poll, chan %d?\n",
- chan);
- mutex_unlock(&uci_handle->out_chan_lock);
- if (uci_handle->f_flags & (O_NONBLOCK | O_NDELAY))
- return -EAGAIN;
- ret_val = wait_event_interruptible(uci_handle->write_wq,
- !mhi_dev_channel_isempty(
- uci_handle->out_handle));
- mutex_lock(&uci_handle->out_chan_lock);
- if (-ERESTARTSYS == ret_val) {
- uci_log(UCI_DBG_WARNING,
- "Waitqueue cancelled by system\n");
- break;
- }
- }
+ if (count > TRB_MAX_DATA_SIZE) {
+ uci_log(UCI_DBG_ERROR,
+ "Too big write size: %d, max supported size is %d\n",
+ count, TRB_MAX_DATA_SIZE);
+ return -EFBIG;
}
- mutex_unlock(&uci_handle->out_chan_lock);
- return ret_val;
+
+ data_loc = kmalloc(count, GFP_KERNEL);
+ if (!data_loc)
+ return -ENOMEM;
+
+ memcpy_result = copy_from_user(data_loc, buf, count);
+ if (memcpy_result) {
+ rc = -EFAULT;
+ goto error_memcpy;
+ }
+
+ rc = mhi_uci_send_packet(uci_handle, data_loc, count);
+ if (rc == count)
+ return rc;
+
+error_memcpy:
+ kfree(data_loc);
+ return rc;
+
}
void uci_ctrl_update(struct mhi_dev_client_cb_reason *reason)
@@ -1119,13 +1165,18 @@
int client_index = 0;
struct uci_client *uci_handle = NULL;
- if (reason->reason == MHI_DEV_TRE_AVAILABLE) {
- client_index = reason->ch_id / 2;
- uci_handle = &uci_ctxt.client_handles[client_index];
+ client_index = reason->ch_id / 2;
+ uci_handle = &uci_ctxt.client_handles[client_index];
+ /*
+ * If this client has its own TRE event handler, call that
+ * else use the default handler.
+ */
+ if (uci_handle->out_chan_attr->tre_notif_cb) {
+ uci_handle->out_chan_attr->tre_notif_cb(reason);
+ } else if (reason->reason == MHI_DEV_TRE_AVAILABLE) {
uci_log(UCI_DBG_DBG,
"recived TRE available event for chan %d\n",
- uci_handle->in_chan);
-
+ uci_handle->in_chan);
if (reason->ch_id % 2) {
atomic_set(&uci_handle->write_data_ready, 1);
wake_up(&uci_handle->write_wq);
@@ -1150,12 +1201,126 @@
return 0;
}
+static int mhi_uci_ctrl_set_tiocm(struct uci_client *client,
+ unsigned int ser_state)
+{
+ unsigned int cur_ser_state;
+ unsigned long compl_ret;
+ struct mhi_uci_ctrl_msg *ctrl_msg;
+ int ret_val;
+ struct uci_client *ctrl_client =
+ &uci_ctxt.client_handles[CHAN_TO_CLIENT
+ (MHI_CLIENT_IP_CTRL_1_OUT)];
+
+ uci_log(UCI_DBG_VERBOSE, "Rcvd ser_state = 0x%x\n", ser_state);
+
+ cur_ser_state = client->tiocm & ~(TIOCM_DTR | TIOCM_RTS);
+ ser_state &= (TIOCM_CD | TIOCM_DSR | TIOCM_RI);
+
+ if (cur_ser_state == ser_state)
+ return 0;
+
+ ctrl_msg = kzalloc(sizeof(*ctrl_msg), GFP_KERNEL);
+ if (!ctrl_msg)
+ return -ENOMEM;
+
+ ctrl_msg->preamble = MHI_UCI_CTRL_MSG_MAGIC;
+ ctrl_msg->msg_id = MHI_UCI_CTRL_MSGID_SERIAL_STATE;
+ ctrl_msg->dest_id = client->out_chan;
+ ctrl_msg->size = sizeof(unsigned int);
+ if (ser_state & TIOCM_CD)
+ ctrl_msg->msg |= MHI_UCI_CTRL_MSG_DCD;
+ if (ser_state & TIOCM_DSR)
+ ctrl_msg->msg |= MHI_UCI_CTRL_MSG_DSR;
+ if (ser_state & TIOCM_RI)
+ ctrl_msg->msg |= MHI_UCI_CTRL_MSG_RI;
+
+ reinit_completion(ctrl_client->write_done);
+ ret_val = mhi_uci_send_packet(ctrl_client, ctrl_msg, sizeof(*ctrl_msg));
+ if (ret_val != sizeof(*ctrl_msg))
+ goto tiocm_error;
+ compl_ret = wait_for_completion_interruptible_timeout(
+ ctrl_client->write_done,
+ MHI_UCI_ASYNC_WRITE_TIMEOUT);
+ if (compl_ret == -ERESTARTSYS) {
+ uci_log(UCI_DBG_ERROR, "Exit signal caught\n");
+ ret_val = compl_ret;
+ goto tiocm_error;
+ } else if (compl_ret == 0) {
+ uci_log(UCI_DBG_ERROR, "Timed out trying to send ctrl msg\n");
+ ret_val = -EIO;
+ goto tiocm_error;
+ }
+
+ client->tiocm &= ~(TIOCM_CD | TIOCM_DSR | TIOCM_RI);
+ client->tiocm |= ser_state;
+ return 0;
+
+tiocm_error:
+ kfree(ctrl_msg);
+ return ret_val;
+}
+
+static void mhi_uci_at_ctrl_read(struct work_struct *work)
+{
+ int ret_val;
+ int msg_size = 0;
+ struct uci_client *ctrl_client =
+ &uci_ctxt.client_handles[CHAN_TO_CLIENT
+ (MHI_CLIENT_IP_CTRL_1_OUT)];
+ struct uci_client *tgt_client;
+ struct mhi_uci_ctrl_msg *ctrl_msg;
+ unsigned int chan;
+
+ ctrl_client->pkt_loc = NULL;
+ ctrl_client->pkt_size = 0;
+
+ ret_val = __mhi_uci_client_read(ctrl_client, &msg_size);
+ if (ret_val) {
+ uci_log(UCI_DBG_ERROR,
+ "Ctrl msg read failed, ret_val is %d!\n",
+ ret_val);
+ return;
+ }
+ if (msg_size != sizeof(*ctrl_msg)) {
+ uci_log(UCI_DBG_ERROR, "Invalid ctrl msg size!\n");
+ return;
+ }
+ if (!ctrl_client->pkt_loc) {
+ uci_log(UCI_DBG_ERROR, "ctrl msg pkt_loc null!\n");
+ return;
+ }
+ ctrl_msg = ctrl_client->pkt_loc;
+
+ chan = ctrl_msg->dest_id;
+ if (chan >= MHI_MAX_SOFTWARE_CHANNELS) {
+ uci_log(UCI_DBG_ERROR,
+ "Invalid channel number in ctrl msg!\n");
+ return;
+ }
+ tgt_client = &uci_ctxt.client_handles[CHAN_TO_CLIENT(chan)];
+ tgt_client->tiocm &= (TIOCM_CD | TIOCM_DSR | TIOCM_RI);
+
+ if (ctrl_msg->msg & MHI_UCI_CTRL_MSG_DCD)
+ tgt_client->tiocm |= TIOCM_CD;
+ if (ctrl_msg->msg & MHI_UCI_CTRL_MSG_DSR)
+ tgt_client->tiocm |= TIOCM_DSR;
+ if (ctrl_msg->msg & MHI_UCI_CTRL_MSG_RI)
+ tgt_client->tiocm |= TIOCM_RI;
+
+ uci_log(UCI_DBG_VERBOSE, "Rcvd tiocm %d\n", tgt_client->tiocm);
+
+ tgt_client->at_ctrl_mask = POLLPRI;
+ wake_up(&tgt_client->read_wq);
+}
+
static long mhi_uci_client_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
struct uci_client *uci_handle = NULL;
int rc = 0;
struct ep_info epinfo;
+ unsigned int tiocm;
if (file == NULL || file->private_data == NULL)
return -EINVAL;
@@ -1188,6 +1353,20 @@
sizeof(epinfo));
if (rc)
uci_log(UCI_DBG_ERROR, "copying to user space failed");
+ } else if (cmd == MHI_UCI_TIOCM_GET) {
+ rc = copy_to_user((void __user *)arg, &uci_handle->tiocm,
+ sizeof(uci_handle->tiocm));
+ if (rc) {
+ uci_log(UCI_DBG_ERROR,
+ "copying ctrl state to user space failed");
+ rc = -EFAULT;
+ }
+ uci_handle->at_ctrl_mask = 0;
+ } else if (cmd == MHI_UCI_TIOCM_SET) {
+ rc = get_user(tiocm, (unsigned int __user *)arg);
+ if (rc)
+ return rc;
+ rc = mhi_uci_ctrl_set_tiocm(uci_handle, tiocm);
} else {
uci_log(UCI_DBG_ERROR, "wrong parameter:%d\n", cmd);
rc = -EINVAL;
@@ -1279,7 +1458,50 @@
return r;
}
-static void mhi_uci_client_cb(struct mhi_dev_client_cb_data *cb_data)
+static void mhi_uci_at_ctrl_tre_cb(struct mhi_dev_client_cb_reason *reason)
+{
+ int client_index;
+ struct uci_client *uci_handle;
+
+ client_index = reason->ch_id / 2;
+ uci_handle = &uci_ctxt.client_handles[client_index];
+
+ if (reason->reason == MHI_DEV_TRE_AVAILABLE) {
+ if (reason->ch_id % 2) {
+ atomic_set(&uci_handle->write_data_ready, 1);
+ wake_up(&uci_handle->write_wq);
+ } else {
+ queue_work(uci_ctxt.at_ctrl_wq, &uci_ctxt.at_ctrl_work);
+ }
+ }
+}
+
+static void mhi_uci_at_ctrl_client_cb(struct mhi_dev_client_cb_data *cb_data)
+{
+ struct uci_client *client = cb_data->user_data;
+ int rc;
+
+ uci_log(UCI_DBG_VERBOSE, " Rcvd MHI cb for channel %d, state %d\n",
+ cb_data->channel, cb_data->ctrl_info);
+
+ if (cb_data->ctrl_info == MHI_STATE_CONNECTED) {
+ /* Open the AT ctrl channels */
+ rc = open_client_mhi_channels(client);
+ if (rc) {
+ uci_log(UCI_DBG_INFO,
+ "Failed to open channels ret %d\n", rc);
+ return;
+ }
+ /* Init the completion event for AT ctrl writes */
+ init_completion(client->write_done);
+ /* Create a work queue to process AT commands */
+ uci_ctxt.at_ctrl_wq =
+ create_singlethread_workqueue("mhi_at_ctrl_wq");
+ INIT_WORK(&uci_ctxt.at_ctrl_work, mhi_uci_at_ctrl_read);
+ }
+}
+
+static void mhi_uci_adb_client_cb(struct mhi_dev_client_cb_data *cb_data)
{
struct uci_client *client = cb_data->user_data;
@@ -1305,16 +1527,26 @@
client->in_chan_attr = ++chan_attrib;
client->in_chan = index * 2;
client->out_chan = index * 2 + 1;
+ client->at_ctrl_mask = 0;
client->in_buf_list =
kcalloc(chan_attrib->nr_trbs,
sizeof(struct mhi_dev_iov),
GFP_KERNEL);
if (!client->in_buf_list)
return -ENOMEM;
- /* Register callback with MHI if requested */
- if (client->out_chan_attr->register_cb)
- mhi_register_state_cb(mhi_uci_client_cb, client,
- client->out_chan);
+ /* Register channel state change cb with MHI if requested */
+ if (client->out_chan_attr->chan_state_cb)
+ mhi_register_state_cb(
+ client->out_chan_attr->chan_state_cb,
+ client,
+ client->out_chan);
+ if (client->in_chan_attr->wr_cmpl) {
+ client->write_done = kzalloc(
+ sizeof(*client->write_done),
+ GFP_KERNEL);
+ if (!client->write_done)
+ return -ENOMEM;
+ }
}
return 0;
}
@@ -1396,7 +1628,7 @@
* this client's channels is called by the MHI driver,
* if one is registered.
*/
- if (mhi_client->in_chan_attr->register_cb)
+ if (mhi_client->in_chan_attr->chan_state_cb)
continue;
ret_val = uci_device_create(mhi_client);
if (ret_val)
diff --git a/drivers/platform/msm/msm_11ad/msm_11ad.c b/drivers/platform/msm/msm_11ad/msm_11ad.c
index 4c0531f..5a379b4 100644
--- a/drivers/platform/msm/msm_11ad/msm_11ad.c
+++ b/drivers/platform/msm/msm_11ad/msm_11ad.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -57,6 +57,7 @@
struct device;
static const char * const gpio_en_name = "qcom,wigig-en";
+static const char * const gpio_dc_name = "qcom,wigig-dc";
static const char * const sleep_clk_en_name = "qcom,sleep-clk-en";
struct wigig_pci {
@@ -90,6 +91,7 @@
struct list_head list;
struct device *dev; /* for platform device */
int gpio_en; /* card enable */
+ int gpio_dc;
int sleep_clk_en; /* sleep clock enable for low PM management */
/* pci device */
@@ -539,6 +541,9 @@
if (ctx->gpio_en >= 0)
gpio_direction_output(ctx->gpio_en, 0);
+ if (ctx->gpio_dc >= 0)
+ gpio_direction_output(ctx->gpio_dc, 0);
+
if (ctx->sleep_clk_en >= 0)
gpio_direction_output(ctx->sleep_clk_en, 0);
@@ -569,6 +574,11 @@
if (ctx->sleep_clk_en >= 0)
gpio_direction_output(ctx->sleep_clk_en, 1);
+ if (ctx->gpio_dc >= 0) {
+ gpio_direction_output(ctx->gpio_dc, 1);
+ msleep(WIGIG_ENABLE_DELAY);
+ }
+
if (ctx->gpio_en >= 0) {
gpio_direction_output(ctx->gpio_en, 1);
msleep(WIGIG_ENABLE_DELAY);
@@ -1060,6 +1070,7 @@
* compatible = "qcom,wil6210";
* qcom,pcie-parent = <&pcie1>;
* qcom,wigig-en = <&tlmm 94 0>; (ctx->gpio_en)
+ * qcom,wigig-dc = <&tlmm 81 0>; (ctx->gpio_dc)
* qcom,sleep-clk-en = <&pm8994_gpios 18 0>; (ctx->sleep_clk_en)
* qcom,msm-bus,name = "wil6210";
* qcom,msm-bus,num-cases = <2>;
@@ -1075,7 +1086,11 @@
* qcom,smmu-exist;
*/
- /* wigig-en is optional property */
+ /* wigig-en and wigig-dc are optional properties */
+ ctx->gpio_dc = of_get_named_gpio(of_node, gpio_dc_name, 0);
+ if (ctx->gpio_dc < 0)
+ dev_warn(ctx->dev, "GPIO <%s> not found, dc GPIO not used\n",
+ gpio_dc_name);
ctx->gpio_en = of_get_named_gpio(of_node, gpio_en_name, 0);
if (ctx->gpio_en < 0)
dev_warn(ctx->dev, "GPIO <%s> not found, enable GPIO not used\n",
@@ -1150,6 +1165,22 @@
goto out_vreg_clk;
}
+ if (ctx->gpio_dc >= 0) {
+ rc = gpio_request(ctx->gpio_dc, gpio_dc_name);
+ if (rc < 0) {
+ dev_err(ctx->dev, "failed to request GPIO %d <%s>\n",
+ ctx->gpio_dc, gpio_dc_name);
+ goto out_req_dc;
+ }
+ rc = gpio_direction_output(ctx->gpio_dc, 1);
+ if (rc < 0) {
+ dev_err(ctx->dev, "failed to set GPIO %d <%s>\n",
+ ctx->gpio_dc, gpio_dc_name);
+ goto out_set_dc;
+ }
+ msleep(WIGIG_ENABLE_DELAY);
+ }
+
if (ctx->gpio_en >= 0) {
rc = gpio_request(ctx->gpio_en, gpio_en_name);
if (rc < 0) {
@@ -1260,12 +1291,13 @@
/* report */
dev_info(ctx->dev, "msm_11ad discovered. %p {\n"
" gpio_en = %d\n"
+ " gpio_dc = %d\n"
" sleep_clk_en = %d\n"
" rc_index = %d\n"
" use_smmu = %d\n"
" pcidev = %p\n"
- "}\n", ctx, ctx->gpio_en, ctx->sleep_clk_en, ctx->rc_index,
- ctx->use_smmu, ctx->pcidev);
+ "}\n", ctx, ctx->gpio_en, ctx->gpio_dc, ctx->sleep_clk_en,
+ ctx->rc_index, ctx->use_smmu, ctx->pcidev);
platform_set_drvdata(pdev, ctx);
device_disable_async_suspend(&pcidev->dev);
@@ -1285,6 +1317,13 @@
gpio_free(ctx->gpio_en);
out_req:
ctx->gpio_en = -EINVAL;
+ if (ctx->gpio_dc >= 0)
+ gpio_direction_output(ctx->gpio_dc, 0);
+out_set_dc:
+ if (ctx->gpio_dc >= 0)
+ gpio_free(ctx->gpio_dc);
+out_req_dc:
+ ctx->gpio_dc = -EINVAL;
out_vreg_clk:
msm_11ad_disable_clocks(ctx);
msm_11ad_release_clocks(ctx);
@@ -1309,6 +1348,10 @@
gpio_direction_output(ctx->gpio_en, 0);
gpio_free(ctx->gpio_en);
}
+ if (ctx->gpio_dc >= 0) {
+ gpio_direction_output(ctx->gpio_dc, 0);
+ gpio_free(ctx->gpio_dc);
+ }
if (ctx->sleep_clk_en >= 0)
gpio_free(ctx->sleep_clk_en);
diff --git a/drivers/power/supply/qcom/battery.c b/drivers/power/supply/qcom/battery.c
index 899cd31..696797f 100644
--- a/drivers/power/supply/qcom/battery.c
+++ b/drivers/power/supply/qcom/battery.c
@@ -45,6 +45,7 @@
#define USBIN_I_VOTER "USBIN_I_VOTER"
#define PL_FCC_LOW_VOTER "PL_FCC_LOW_VOTER"
#define ICL_LIMIT_VOTER "ICL_LIMIT_VOTER"
+#define FCC_STEPPER_VOTER "FCC_STEPPER_VOTER"
struct pl_data {
int pl_mode;
@@ -52,6 +53,7 @@
int pl_min_icl_ua;
int slave_pct;
int slave_fcc_ua;
+ int main_fcc_ua;
int restricted_current;
bool restricted_charging_enabled;
struct votable *fcc_votable;
@@ -65,15 +67,25 @@
struct work_struct pl_disable_forever_work;
struct work_struct pl_taper_work;
struct delayed_work pl_awake_work;
+ struct delayed_work fcc_stepper_work;
bool taper_work_running;
struct power_supply *main_psy;
struct power_supply *pl_psy;
struct power_supply *batt_psy;
struct power_supply *usb_psy;
+ struct power_supply *dc_psy;
int charge_type;
int total_settled_ua;
int pl_settled_ua;
int pl_fcc_max;
+ int fcc_stepper_enable;
+ int main_step_fcc_dir;
+ int main_step_fcc_count;
+ int main_step_fcc_residual;
+ int parallel_step_fcc_dir;
+ int parallel_step_fcc_count;
+ int parallel_step_fcc_residual;
+ int step_fcc;
u32 wa_flags;
struct class qcom_batt_class;
struct wakeup_source *pl_ws;
@@ -111,6 +123,7 @@
SLAVE_PCT,
RESTRICT_CHG_ENABLE,
RESTRICT_CHG_CURRENT,
+ FCC_STEPPING_IN_PROGRESS,
};
/*******
@@ -258,7 +271,6 @@
chip->total_settled_ua = total_settled_ua;
chip->pl_settled_ua = slave_ua;
-
}
static ssize_t version_show(struct class *c, struct class_attribute *attr,
@@ -373,6 +385,18 @@
return count;
}
+/****************************
+ * FCC STEPPING IN PROGRESS *
+ ****************************/
+static ssize_t fcc_stepping_in_progress_show(struct class *c,
+ struct class_attribute *attr, char *ubuf)
+{
+ struct pl_data *chip = container_of(c, struct pl_data,
+ qcom_batt_class);
+
+ return snprintf(ubuf, PAGE_SIZE, "%d\n", chip->step_fcc);
+}
+
static struct class_attribute pl_attributes[] = {
[VER] = __ATTR_RO(version),
[SLAVE_PCT] = __ATTR(parallel_pct, 0644,
@@ -381,6 +405,8 @@
restrict_chg_show, restrict_chg_store),
[RESTRICT_CHG_CURRENT] = __ATTR(restricted_current, 0644,
restrict_cur_show, restrict_cur_store),
+ [FCC_STEPPING_IN_PROGRESS]
+ = __ATTR_RO(fcc_stepping_in_progress),
__ATTR_NULL,
};
@@ -388,6 +414,10 @@
* FCC *
**********/
#define EFFICIENCY_PCT 80
+#define FCC_STEP_SIZE_UA 100000
+#define FCC_STEP_UPDATE_DELAY_MS 1000
+#define STEP_UP 1
+#define STEP_DOWN -1
static void get_fcc_split(struct pl_data *chip, int total_ua,
int *master_ua, int *slave_ua)
{
@@ -440,6 +470,47 @@
*master_ua = max(0, total_ua - *slave_ua);
}
+static void get_fcc_stepper_params(struct pl_data *chip, int main_fcc_ua,
+ int parallel_fcc_ua)
+{
+ union power_supply_propval pval = {0, };
+ int rc;
+
+ /* Read current FCC of main charger */
+ rc = power_supply_get_property(chip->main_psy,
+ POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, &pval);
+ if (rc < 0) {
+ pr_err("Couldn't get main charger current fcc, rc=%d\n", rc);
+ return;
+ }
+ chip->main_fcc_ua = pval.intval;
+
+ chip->main_step_fcc_dir = (main_fcc_ua > pval.intval) ?
+ STEP_UP : STEP_DOWN;
+ chip->main_step_fcc_count = abs((main_fcc_ua - pval.intval) /
+ FCC_STEP_SIZE_UA);
+ chip->main_step_fcc_residual = (main_fcc_ua - pval.intval) %
+ FCC_STEP_SIZE_UA;
+
+ chip->parallel_step_fcc_dir = (parallel_fcc_ua > chip->slave_fcc_ua) ?
+ STEP_UP : STEP_DOWN;
+ chip->parallel_step_fcc_count = abs((parallel_fcc_ua -
+ chip->slave_fcc_ua) / FCC_STEP_SIZE_UA);
+ chip->parallel_step_fcc_residual = (parallel_fcc_ua -
+ chip->slave_fcc_ua) % FCC_STEP_SIZE_UA;
+
+ if (chip->parallel_step_fcc_count || chip->parallel_step_fcc_residual
+ || chip->main_step_fcc_count || chip->main_step_fcc_residual)
+ chip->step_fcc = 1;
+
+ pr_debug("Main FCC Stepper parameters: main_step_direction: %d, main_step_count: %d, main_residual_fcc: %d\n",
+ chip->main_step_fcc_dir, chip->main_step_fcc_count,
+ chip->main_step_fcc_residual);
+ pr_debug("Parallel FCC Stepper parameters: parallel_step_direction: %d, parallel_step_count: %d, parallel_residual_fcc: %d\n",
+ chip->parallel_step_fcc_dir, chip->parallel_step_fcc_count,
+ chip->parallel_step_fcc_residual);
+}
+
#define MINIMUM_PARALLEL_FCC_UA 500000
#define PL_TAPER_WORK_DELAY_MS 500
#define TAPER_RESIDUAL_PCT 90
@@ -559,6 +630,195 @@
return 0;
}
+static void fcc_stepper_work(struct work_struct *work)
+{
+ struct pl_data *chip = container_of(work, struct pl_data,
+ fcc_stepper_work.work);
+ union power_supply_propval pval = {0, };
+ int reschedule_ms = 0, rc = 0, charger_present = 0;
+ int main_fcc = chip->main_fcc_ua;
+ int parallel_fcc = chip->slave_fcc_ua;
+
+ /* Check whether USB is present or not */
+ rc = power_supply_get_property(chip->usb_psy,
+ POWER_SUPPLY_PROP_PRESENT, &pval);
+ if (rc < 0)
+ pr_err("Couldn't get USB Present status, rc=%d\n", rc);
+
+ charger_present = pval.intval;
+
+ /*Check whether DC charger is present or not */
+ if (!chip->dc_psy)
+ chip->dc_psy = power_supply_get_by_name("dc");
+ if (chip->dc_psy) {
+ rc = power_supply_get_property(chip->dc_psy,
+ POWER_SUPPLY_PROP_PRESENT, &pval);
+ if (rc < 0)
+ pr_err("Couldn't get DC Present status, rc=%d\n", rc);
+
+ charger_present |= pval.intval;
+ }
+
+ /*
+ * If USB is not present, then set parallel FCC to min value and
+ * main FCC to the effective value of FCC votable and exit.
+ */
+ if (!charger_present) {
+ /* Disable parallel */
+ parallel_fcc = 0;
+
+ if (chip->pl_psy) {
+ pval.intval = 1;
+ rc = power_supply_set_property(chip->pl_psy,
+ POWER_SUPPLY_PROP_INPUT_SUSPEND, &pval);
+ if (rc < 0) {
+ pr_err("Couldn't change slave suspend state rc=%d\n",
+ rc);
+ goto out;
+ }
+
+ chip->pl_disable = true;
+ power_supply_changed(chip->pl_psy);
+ }
+
+ main_fcc = get_effective_result_locked(chip->fcc_votable);
+ pval.intval = main_fcc;
+ rc = power_supply_set_property(chip->main_psy,
+ POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, &pval);
+ if (rc < 0) {
+ pr_err("Couldn't set main charger fcc, rc=%d\n", rc);
+ goto out;
+ }
+
+ goto stepper_exit;
+ }
+
+ if (chip->main_step_fcc_count) {
+ main_fcc += (FCC_STEP_SIZE_UA * chip->main_step_fcc_dir);
+ chip->main_step_fcc_count--;
+ reschedule_ms = FCC_STEP_UPDATE_DELAY_MS;
+ } else if (chip->main_step_fcc_residual) {
+ main_fcc += chip->main_step_fcc_residual;
+ chip->main_step_fcc_residual = 0;
+ }
+
+ if (chip->parallel_step_fcc_count) {
+ parallel_fcc += (FCC_STEP_SIZE_UA *
+ chip->parallel_step_fcc_dir);
+ chip->parallel_step_fcc_count--;
+ reschedule_ms = FCC_STEP_UPDATE_DELAY_MS;
+ } else if (chip->parallel_step_fcc_residual) {
+ parallel_fcc += chip->parallel_step_fcc_residual;
+ chip->parallel_step_fcc_residual = 0;
+ }
+
+ if (parallel_fcc < chip->slave_fcc_ua) {
+ /* Set parallel FCC */
+ if (chip->pl_psy && !chip->pl_disable) {
+ if (parallel_fcc < MINIMUM_PARALLEL_FCC_UA) {
+ pval.intval = 1;
+ rc = power_supply_set_property(chip->pl_psy,
+ POWER_SUPPLY_PROP_INPUT_SUSPEND, &pval);
+ if (rc < 0) {
+ pr_err("Couldn't change slave suspend state rc=%d\n",
+ rc);
+ goto out;
+ }
+
+ if (IS_USBIN(chip->pl_mode))
+ split_settled(chip);
+
+ parallel_fcc = 0;
+ chip->parallel_step_fcc_count = 0;
+ chip->parallel_step_fcc_residual = 0;
+ chip->total_settled_ua = 0;
+ chip->pl_settled_ua = 0;
+ chip->pl_disable = true;
+ power_supply_changed(chip->pl_psy);
+ } else {
+ /* Set Parallel FCC */
+ pval.intval = parallel_fcc;
+ rc = power_supply_set_property(chip->pl_psy,
+ POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
+ &pval);
+ if (rc < 0) {
+ pr_err("Couldn't set parallel charger fcc, rc=%d\n",
+ rc);
+ goto out;
+ }
+ }
+ }
+
+ /* Set main FCC */
+ pval.intval = main_fcc;
+ rc = power_supply_set_property(chip->main_psy,
+ POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, &pval);
+ if (rc < 0) {
+ pr_err("Couldn't set main charger fcc, rc=%d\n", rc);
+ goto out;
+ }
+ } else {
+ /* Set main FCC */
+ pval.intval = main_fcc;
+ rc = power_supply_set_property(chip->main_psy,
+ POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, &pval);
+ if (rc < 0) {
+ pr_err("Couldn't set main charger fcc, rc=%d\n", rc);
+ goto out;
+ }
+
+ /* Set parallel FCC */
+ if (chip->pl_psy) {
+ pval.intval = parallel_fcc;
+ rc = power_supply_set_property(chip->pl_psy,
+ POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
+ &pval);
+ if (rc < 0) {
+ pr_err("Couldn't set parallel charger fcc, rc=%d\n",
+ rc);
+ goto out;
+ }
+
+ /*
+ * Enable parallel charger only if it was disabled
+ * earlier and configured slave fcc is greater than or
+ * equal to minimum parallel FCC value.
+ */
+ if (chip->pl_disable && parallel_fcc
+ >= MINIMUM_PARALLEL_FCC_UA) {
+ pval.intval = 0;
+ rc = power_supply_set_property(chip->pl_psy,
+ POWER_SUPPLY_PROP_INPUT_SUSPEND, &pval);
+ if (rc < 0) {
+ pr_err("Couldn't change slave suspend state rc=%d\n",
+ rc);
+ goto out;
+ }
+
+ if (IS_USBIN(chip->pl_mode))
+ split_settled(chip);
+
+ chip->pl_disable = false;
+ power_supply_changed(chip->pl_psy);
+ }
+ }
+ }
+
+stepper_exit:
+ chip->main_fcc_ua = main_fcc;
+ chip->slave_fcc_ua = parallel_fcc;
+
+ if (reschedule_ms) {
+ schedule_delayed_work(&chip->fcc_stepper_work,
+ msecs_to_jiffies(reschedule_ms));
+ pr_debug("Rescheduling FCC_STEPPER work\n");
+ return;
+ }
+out:
+ chip->step_fcc = 0;
+ vote(chip->pl_awake_votable, FCC_STEPPER_VOTER, false, 0);
+}
+
#define PARALLEL_FLOAT_VOLTAGE_DELTA_UV 50000
static int pl_fv_vote_callback(struct votable *votable, void *data,
int fv_uv, const char *client)
@@ -697,6 +957,17 @@
return !!chip->main_psy;
}
+static bool is_batt_available(struct pl_data *chip)
+{
+ if (!chip->batt_psy)
+ chip->batt_psy = power_supply_get_by_name("battery");
+
+ if (!chip->batt_psy)
+ return false;
+
+ return true;
+}
+
static int pl_disable_vote_callback(struct votable *votable,
void *data, int pl_disable, const char *client)
{
@@ -709,6 +980,30 @@
if (!is_main_available(chip))
return -ENODEV;
+ if (!is_batt_available(chip))
+ return -ENODEV;
+
+ if (!chip->usb_psy)
+ chip->usb_psy = power_supply_get_by_name("usb");
+ if (!chip->usb_psy) {
+ pr_err("Couldn't get usb psy\n");
+ return -ENODEV;
+ }
+
+ rc = power_supply_get_property(chip->batt_psy,
+ POWER_SUPPLY_PROP_FCC_STEPPER_ENABLE, &pval);
+ if (rc < 0) {
+ pr_err("Couldn't read FCC step update status, rc=%d\n", rc);
+ return rc;
+ }
+ chip->fcc_stepper_enable = pval.intval;
+ pr_debug("FCC Stepper %s\n", pval.intval ? "enabled" : "disabled");
+
+ if (chip->fcc_stepper_enable) {
+ cancel_delayed_work_sync(&chip->fcc_stepper_work);
+ vote(chip->pl_awake_votable, FCC_STEPPER_VOTER, false, 0);
+ }
+
total_fcc_ua = get_effective_result_locked(chip->fcc_votable);
if (chip->pl_mode != POWER_SUPPLY_PL_NONE && !pl_disable) {
@@ -744,73 +1039,87 @@
get_fcc_split(chip, total_fcc_ua, &master_fcc_ua,
&slave_fcc_ua);
- /*
- * If there is an increase in slave share
- * (Also handles parallel enable case)
- * Set Main ICL then slave FCC
- * else
- * (Also handles parallel disable case)
- * Set slave ICL then main FCC.
- */
- if (slave_fcc_ua > chip->slave_fcc_ua) {
- pval.intval = master_fcc_ua;
- rc = power_supply_set_property(chip->main_psy,
- POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
- &pval);
- if (rc < 0) {
- pr_err("Could not set main fcc, rc=%d\n", rc);
- return rc;
- }
-
- pval.intval = slave_fcc_ua;
- rc = power_supply_set_property(chip->pl_psy,
- POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
- &pval);
- if (rc < 0) {
- pr_err("Couldn't set parallel fcc, rc=%d\n",
- rc);
- return rc;
- }
-
- chip->slave_fcc_ua = slave_fcc_ua;
+ if (chip->fcc_stepper_enable) {
+ get_fcc_stepper_params(chip, master_fcc_ua,
+ slave_fcc_ua);
+ if (chip->step_fcc) {
+ vote(chip->pl_awake_votable, FCC_STEPPER_VOTER,
+ true, 0);
+ schedule_delayed_work(&chip->fcc_stepper_work,
+ 0);
+ }
} else {
- pval.intval = slave_fcc_ua;
- rc = power_supply_set_property(chip->pl_psy,
+ /*
+ * If there is an increase in slave share
+ * (Also handles parallel enable case)
+ * Set Main ICL then slave FCC
+ * else
+ * (Also handles parallel disable case)
+ * Set slave ICL then main FCC.
+ */
+ if (slave_fcc_ua > chip->slave_fcc_ua) {
+ pval.intval = master_fcc_ua;
+ rc = power_supply_set_property(chip->main_psy,
POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
- &pval);
- if (rc < 0) {
- pr_err("Couldn't set parallel fcc, rc=%d\n",
+ &pval);
+ if (rc < 0) {
+ pr_err("Could not set main fcc, rc=%d\n",
rc);
- return rc;
- }
+ return rc;
+ }
- chip->slave_fcc_ua = slave_fcc_ua;
-
- pval.intval = master_fcc_ua;
- rc = power_supply_set_property(chip->main_psy,
+ pval.intval = slave_fcc_ua;
+ rc = power_supply_set_property(chip->pl_psy,
POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
- &pval);
- if (rc < 0) {
- pr_err("Could not set main fcc, rc=%d\n", rc);
- return rc;
+ &pval);
+ if (rc < 0) {
+ pr_err("Couldn't set parallel fcc, rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ chip->slave_fcc_ua = slave_fcc_ua;
+ } else {
+ pval.intval = slave_fcc_ua;
+ rc = power_supply_set_property(chip->pl_psy,
+ POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
+ &pval);
+ if (rc < 0) {
+ pr_err("Couldn't set parallel fcc, rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ chip->slave_fcc_ua = slave_fcc_ua;
+
+ pval.intval = master_fcc_ua;
+ rc = power_supply_set_property(chip->main_psy,
+ POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
+ &pval);
+ if (rc < 0) {
+ pr_err("Could not set main fcc, rc=%d\n",
+ rc);
+ return rc;
+ }
}
+
+ /*
+ * Enable will be called with a valid pl_psy always. The
+ * PARALLEL_PSY_VOTER keeps it disabled unless a pl_psy
+ * is seen.
+ */
+ pval.intval = 0;
+ rc = power_supply_set_property(chip->pl_psy,
+ POWER_SUPPLY_PROP_INPUT_SUSPEND, &pval);
+ if (rc < 0)
+ pr_err("Couldn't change slave suspend state rc=%d\n",
+ rc);
+
+ if (IS_USBIN(chip->pl_mode))
+ split_settled(chip);
}
/*
- * Enable will be called with a valid pl_psy always. The
- * PARALLEL_PSY_VOTER keeps it disabled unless a pl_psy
- * is seen.
- */
- pval.intval = 0;
- rc = power_supply_set_property(chip->pl_psy,
- POWER_SUPPLY_PROP_INPUT_SUSPEND, &pval);
- if (rc < 0)
- pr_err("Couldn't change slave suspend state rc=%d\n",
- rc);
-
- if (IS_USBIN(chip->pl_mode))
- split_settled(chip);
- /*
* we could have been enabled while in taper mode,
* start the taper work if so
*/
@@ -835,43 +1144,54 @@
(master_fcc_ua * 100) / total_fcc_ua,
(slave_fcc_ua * 100) / total_fcc_ua);
} else {
- if (IS_USBIN(chip->pl_mode))
- split_settled(chip);
+ if (!chip->fcc_stepper_enable) {
+ if (IS_USBIN(chip->pl_mode))
+ split_settled(chip);
- /* pl_psy may be NULL while in the disable branch */
- if (chip->pl_psy) {
- pval.intval = 1;
- rc = power_supply_set_property(chip->pl_psy,
+ /* pl_psy may be NULL while in the disable branch */
+ if (chip->pl_psy) {
+ pval.intval = 1;
+ rc = power_supply_set_property(chip->pl_psy,
POWER_SUPPLY_PROP_INPUT_SUSPEND, &pval);
- if (rc < 0)
- pr_err("Couldn't change slave suspend state rc=%d\n",
- rc);
- }
+ if (rc < 0)
+ pr_err("Couldn't change slave suspend state rc=%d\n",
+ rc);
+ }
- /* main psy gets all share */
- pval.intval = total_fcc_ua;
- rc = power_supply_set_property(chip->main_psy,
+ /* main psy gets all share */
+ pval.intval = total_fcc_ua;
+ rc = power_supply_set_property(chip->main_psy,
POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
&pval);
- if (rc < 0) {
- pr_err("Could not set main fcc, rc=%d\n", rc);
- return rc;
+ if (rc < 0) {
+ pr_err("Could not set main fcc, rc=%d\n", rc);
+ return rc;
+ }
+
+ /* reset parallel FCC */
+ chip->slave_fcc_ua = 0;
+ chip->total_settled_ua = 0;
+ chip->pl_settled_ua = 0;
+ } else {
+ get_fcc_stepper_params(chip, total_fcc_ua, 0);
+ if (chip->step_fcc) {
+ vote(chip->pl_awake_votable, FCC_STEPPER_VOTER,
+ true, 0);
+ schedule_delayed_work(&chip->fcc_stepper_work,
+ 0);
+ }
}
- /* reset parallel FCC */
- chip->slave_fcc_ua = 0;
rerun_election(chip->fv_votable);
cancel_delayed_work_sync(&chip->pl_awake_work);
schedule_delayed_work(&chip->pl_awake_work,
msecs_to_jiffies(5000));
-
- chip->total_settled_ua = 0;
- chip->pl_settled_ua = 0;
}
/* notify parallel state change */
- if (chip->pl_psy && (chip->pl_disable != pl_disable)) {
+ if (chip->pl_psy && (chip->pl_disable != pl_disable)
+ && !chip->fcc_stepper_enable) {
power_supply_changed(chip->pl_psy);
chip->pl_disable = (bool)pl_disable;
}
@@ -906,17 +1226,6 @@
return 0;
}
-static bool is_batt_available(struct pl_data *chip)
-{
- if (!chip->batt_psy)
- chip->batt_psy = power_supply_get_by_name("battery");
-
- if (!chip->batt_psy)
- return false;
-
- return true;
-}
-
static bool is_parallel_available(struct pl_data *chip)
{
union power_supply_propval pval = {0, };
@@ -1080,6 +1389,7 @@
else
vote(chip->pl_enable_votable_indirect, USBIN_I_VOTER, true, 0);
+ rerun_election(chip->fcc_votable);
if (IS_USBIN(chip->pl_mode)) {
/*
@@ -1328,6 +1638,7 @@
INIT_WORK(&chip->pl_taper_work, pl_taper_work);
INIT_WORK(&chip->pl_disable_forever_work, pl_disable_forever_work);
INIT_DELAYED_WORK(&chip->pl_awake_work, pl_awake_work);
+ INIT_DELAYED_WORK(&chip->fcc_stepper_work, fcc_stepper_work);
rc = pl_register_notifier(chip);
if (rc < 0) {
@@ -1383,6 +1694,7 @@
cancel_work_sync(&chip->pl_taper_work);
cancel_work_sync(&chip->pl_disable_forever_work);
cancel_delayed_work_sync(&chip->pl_awake_work);
+ cancel_delayed_work_sync(&chip->fcc_stepper_work);
power_supply_unreg_notifier(&chip->nb);
destroy_votable(chip->pl_enable_votable_indirect);
diff --git a/drivers/power/supply/qcom/batterydata-interface.c b/drivers/power/supply/qcom/batterydata-interface.c
index 0187827..9a75de1 100644
--- a/drivers/power/supply/qcom/batterydata-interface.c
+++ b/drivers/power/supply/qcom/batterydata-interface.c
@@ -66,7 +66,7 @@
switch (cmd) {
case BPIOCXSOC:
- soc = interpolate_pc(battery->profile->pc_temp_ocv_lut,
+ soc = interpolate_pc_bms(battery->profile->pc_temp_ocv_lut,
bp.batt_temp, bp.ocv_uv / 1000);
rc = put_user(soc, &bp_user->soc);
if (rc) {
@@ -77,7 +77,7 @@
bp.ocv_uv / 1000, bp.batt_temp, soc);
break;
case BPIOCXRBATT:
- rbatt_sf = interpolate_scalingfactor(
+ rbatt_sf = interpolate_scalingfactor_bms(
battery->profile->rbatt_sf_lut,
bp.batt_temp, bp.soc);
rc = put_user(rbatt_sf, &bp_user->rbatt_sf);
@@ -89,7 +89,7 @@
bp.soc, bp.batt_temp, rbatt_sf);
break;
case BPIOCXSLOPE:
- slope = interpolate_slope(battery->profile->pc_temp_ocv_lut,
+ slope = interpolate_slope_bms(battery->profile->pc_temp_ocv_lut,
bp.batt_temp, bp.soc);
rc = put_user(slope, &bp_user->slope);
if (rc) {
@@ -100,7 +100,7 @@
bp.soc, bp.batt_temp, slope);
break;
case BPIOCXFCC:
- fcc_mah = interpolate_fcc(battery->profile->fcc_temp_lut,
+ fcc_mah = interpolate_fcc_bms(battery->profile->fcc_temp_lut,
bp.batt_temp);
rc = put_user(fcc_mah, &bp_user->fcc_mah);
if (rc) {
diff --git a/drivers/power/supply/qcom/batterydata-lib.c b/drivers/power/supply/qcom/batterydata-lib.c
index fae5658..d10d719 100644
--- a/drivers/power/supply/qcom/batterydata-lib.c
+++ b/drivers/power/supply/qcom/batterydata-lib.c
@@ -15,7 +15,7 @@
#include <linux/module.h>
#include <linux/batterydata-lib.h>
-int linear_interpolate(int y0, int x0, int y1, int x1, int x)
+int linear_interpolate_bms(int y0, int x0, int y1, int x1, int x)
{
if (y0 == y1 || x == x0)
return y0;
@@ -25,7 +25,7 @@
return y0 + ((y1 - y0) * (x - x0) / (x1 - x0));
}
-static int interpolate_single_lut_scaled(struct single_row_lut *lut,
+static int interpolate_single_lut_scaled_bms(struct single_row_lut *lut,
int x, int scale)
{
int i, result;
@@ -47,7 +47,7 @@
if (x == lut->x[i] * scale) {
result = lut->y[i];
} else {
- result = linear_interpolate(
+ result = linear_interpolate_bms(
lut->y[i - 1],
lut->x[i - 1] * scale,
lut->y[i],
@@ -57,14 +57,14 @@
return result;
}
-int interpolate_fcc(struct single_row_lut *fcc_temp_lut, int batt_temp)
+int interpolate_fcc_bms(struct single_row_lut *fcc_temp_lut, int batt_temp)
{
- return interpolate_single_lut_scaled(fcc_temp_lut,
+ return interpolate_single_lut_scaled_bms(fcc_temp_lut,
batt_temp,
DEGC_SCALE);
}
-int interpolate_scalingfactor_fcc(struct single_row_lut *fcc_sf_lut,
+int interpolate_scalingfactor_fcc_bms(struct single_row_lut *fcc_sf_lut,
int cycles)
{
/*
@@ -72,12 +72,12 @@
* that case return 100%
*/
if (fcc_sf_lut)
- return interpolate_single_lut_scaled(fcc_sf_lut, cycles, 1);
+ return interpolate_single_lut_scaled_bms(fcc_sf_lut, cycles, 1);
else
return 100;
}
-int interpolate_scalingfactor(struct sf_lut *sf_lut, int row_entry, int pc)
+int interpolate_scalingfactor_bms(struct sf_lut *sf_lut, int row_entry, int pc)
{
int i, scalefactorrow1, scalefactorrow2, scalefactor, rows, cols;
int row1 = 0;
@@ -124,7 +124,7 @@
if (row_entry <= sf_lut->row_entries[i] * DEGC_SCALE)
break;
if (row_entry == sf_lut->row_entries[i] * DEGC_SCALE) {
- scalefactor = linear_interpolate(
+ scalefactor = linear_interpolate_bms(
sf_lut->sf[row1][i],
sf_lut->percent[row1],
sf_lut->sf[row2][i],
@@ -133,21 +133,21 @@
return scalefactor;
}
- scalefactorrow1 = linear_interpolate(
+ scalefactorrow1 = linear_interpolate_bms(
sf_lut->sf[row1][i - 1],
sf_lut->row_entries[i - 1] * DEGC_SCALE,
sf_lut->sf[row1][i],
sf_lut->row_entries[i] * DEGC_SCALE,
row_entry);
- scalefactorrow2 = linear_interpolate(
+ scalefactorrow2 = linear_interpolate_bms(
sf_lut->sf[row2][i - 1],
sf_lut->row_entries[i - 1] * DEGC_SCALE,
sf_lut->sf[row2][i],
sf_lut->row_entries[i] * DEGC_SCALE,
row_entry);
- scalefactor = linear_interpolate(
+ scalefactor = linear_interpolate_bms(
scalefactorrow1,
sf_lut->percent[row1],
scalefactorrow2,
@@ -158,7 +158,7 @@
}
/* get ocv given a soc -- reverse lookup */
-int interpolate_ocv(struct pc_temp_ocv_lut *pc_temp_ocv,
+int interpolate_ocv_bms(struct pc_temp_ocv_lut *pc_temp_ocv,
int batt_temp, int pc)
{
int i, ocvrow1, ocvrow2, ocv, rows, cols;
@@ -199,7 +199,7 @@
if (batt_temp <= pc_temp_ocv->temp[i] * DEGC_SCALE)
break;
if (batt_temp == pc_temp_ocv->temp[i] * DEGC_SCALE) {
- ocv = linear_interpolate(
+ ocv = linear_interpolate_bms(
pc_temp_ocv->ocv[row1][i],
pc_temp_ocv->percent[row1],
pc_temp_ocv->ocv[row2][i],
@@ -208,21 +208,21 @@
return ocv;
}
- ocvrow1 = linear_interpolate(
+ ocvrow1 = linear_interpolate_bms(
pc_temp_ocv->ocv[row1][i - 1],
pc_temp_ocv->temp[i - 1] * DEGC_SCALE,
pc_temp_ocv->ocv[row1][i],
pc_temp_ocv->temp[i] * DEGC_SCALE,
batt_temp);
- ocvrow2 = linear_interpolate(
+ ocvrow2 = linear_interpolate_bms(
pc_temp_ocv->ocv[row2][i - 1],
pc_temp_ocv->temp[i - 1] * DEGC_SCALE,
pc_temp_ocv->ocv[row2][i],
pc_temp_ocv->temp[i] * DEGC_SCALE,
batt_temp);
- ocv = linear_interpolate(
+ ocv = linear_interpolate_bms(
ocvrow1,
pc_temp_ocv->percent[row1],
ocvrow2,
@@ -232,7 +232,7 @@
return ocv;
}
-int interpolate_pc(struct pc_temp_ocv_lut *pc_temp_ocv,
+int interpolate_pc_bms(struct pc_temp_ocv_lut *pc_temp_ocv,
int batt_temp, int ocv)
{
int i, j, pcj, pcj_minus_one, pc;
@@ -262,7 +262,7 @@
if (ocv >= pc_temp_ocv->ocv[i][j]) {
if (ocv == pc_temp_ocv->ocv[i][j])
return pc_temp_ocv->percent[i];
- pc = linear_interpolate(
+ pc = linear_interpolate_bms(
pc_temp_ocv->percent[i],
pc_temp_ocv->ocv[i][j],
pc_temp_ocv->percent[i - 1],
@@ -288,7 +288,7 @@
if (pcj == 0
&& is_between(pc_temp_ocv->ocv[i][j],
pc_temp_ocv->ocv[i+1][j], ocv)) {
- pcj = linear_interpolate(
+ pcj = linear_interpolate_bms(
pc_temp_ocv->percent[i],
pc_temp_ocv->ocv[i][j],
pc_temp_ocv->percent[i + 1],
@@ -299,7 +299,7 @@
if (pcj_minus_one == 0
&& is_between(pc_temp_ocv->ocv[i][j-1],
pc_temp_ocv->ocv[i+1][j-1], ocv)) {
- pcj_minus_one = linear_interpolate(
+ pcj_minus_one = linear_interpolate_bms(
pc_temp_ocv->percent[i],
pc_temp_ocv->ocv[i][j-1],
pc_temp_ocv->percent[i + 1],
@@ -308,7 +308,7 @@
}
if (pcj && pcj_minus_one) {
- pc = linear_interpolate(
+ pc = linear_interpolate_bms(
pcj_minus_one,
pc_temp_ocv->temp[j-1] * DEGC_SCALE,
pcj,
@@ -329,7 +329,7 @@
return 100;
}
-int interpolate_slope(struct pc_temp_ocv_lut *pc_temp_ocv,
+int interpolate_slope_bms(struct pc_temp_ocv_lut *pc_temp_ocv,
int batt_temp, int pc)
{
int i, ocvrow1, ocvrow2, rows, cols;
@@ -385,14 +385,14 @@
pc_temp_ocv->percent[row2]);
return slope;
}
- ocvrow1 = linear_interpolate(
+ ocvrow1 = linear_interpolate_bms(
pc_temp_ocv->ocv[row1][i - 1],
pc_temp_ocv->temp[i - 1] * DEGC_SCALE,
pc_temp_ocv->ocv[row1][i],
pc_temp_ocv->temp[i] * DEGC_SCALE,
batt_temp);
- ocvrow2 = linear_interpolate(
+ ocvrow2 = linear_interpolate_bms(
pc_temp_ocv->ocv[row2][i - 1],
pc_temp_ocv->temp[i - 1] * DEGC_SCALE,
pc_temp_ocv->ocv[row2][i],
@@ -411,7 +411,7 @@
}
-int interpolate_acc(struct ibat_temp_acc_lut *ibat_acc_lut,
+int interpolate_acc_bms(struct ibat_temp_acc_lut *ibat_acc_lut,
int batt_temp, int ibat)
{
int i, accrow1, accrow2, rows, cols;
@@ -457,7 +457,7 @@
break;
if (batt_temp == (ibat_acc_lut->temp[i] * DEGC_SCALE)) {
- acc = linear_interpolate(
+ acc = linear_interpolate_bms(
ibat_acc_lut->acc[row1][i],
ibat_acc_lut->ibat[row1],
ibat_acc_lut->acc[row2][i],
@@ -466,21 +466,21 @@
return acc;
}
- accrow1 = linear_interpolate(
+ accrow1 = linear_interpolate_bms(
ibat_acc_lut->acc[row1][i - 1],
ibat_acc_lut->temp[i - 1] * DEGC_SCALE,
ibat_acc_lut->acc[row1][i],
ibat_acc_lut->temp[i] * DEGC_SCALE,
batt_temp);
- accrow2 = linear_interpolate(
+ accrow2 = linear_interpolate_bms(
ibat_acc_lut->acc[row2][i - 1],
ibat_acc_lut->temp[i - 1] * DEGC_SCALE,
ibat_acc_lut->acc[row2][i],
ibat_acc_lut->temp[i] * DEGC_SCALE,
batt_temp);
- acc = linear_interpolate(accrow1,
+ acc = linear_interpolate_bms(accrow1,
ibat_acc_lut->ibat[row1],
accrow2,
ibat_acc_lut->ibat[row2],
diff --git a/drivers/power/supply/qcom/fg-core.h b/drivers/power/supply/qcom/fg-core.h
index 0b35847..8898edc 100644
--- a/drivers/power/supply/qcom/fg-core.h
+++ b/drivers/power/supply/qcom/fg-core.h
@@ -190,6 +190,7 @@
FG_SRAM_DELTA_MSOC_THR,
FG_SRAM_DELTA_BSOC_THR,
FG_SRAM_RECHARGE_SOC_THR,
+ FG_SRAM_SYNC_SLEEP_THR,
FG_SRAM_RECHARGE_VBATT_THR,
FG_SRAM_KI_COEFF_LOW_DISCHG,
FG_SRAM_KI_COEFF_MED_DISCHG,
@@ -282,6 +283,8 @@
bool linearize_soc;
bool auto_recharge_soc;
bool use_esr_sw;
+ bool disable_esr_pull_dn;
+ bool disable_fg_twm;
int cutoff_volt_mv;
int empty_volt_mv;
int vbatt_low_thr_mv;
@@ -296,6 +299,7 @@
int esr_timer_charging[NUM_ESR_TIMERS];
int esr_timer_awake[NUM_ESR_TIMERS];
int esr_timer_asleep[NUM_ESR_TIMERS];
+ int esr_timer_shutdown[NUM_ESR_TIMERS];
int rconn_mohms;
int esr_clamp_mohms;
int cl_start_soc;
@@ -318,6 +322,7 @@
int slope_limit_temp;
int esr_pulse_thresh_ma;
int esr_meas_curr_ma;
+ int sync_sleep_threshold_ma;
int bmd_en_delay_ms;
int ki_coeff_full_soc_dischg;
int ki_coeff_hi_chg;
@@ -448,6 +453,7 @@
struct fg_batt_props bp;
struct fg_cyc_ctr_data cyc_ctr;
struct notifier_block nb;
+ struct notifier_block twm_nb;
struct fg_cap_learning cl;
struct alarm esr_sw_timer;
struct ttf ttf;
@@ -496,6 +502,7 @@
bool slope_limit_en;
bool use_ima_single_mode;
bool usb_present;
+ bool twm_state;
bool use_dma;
bool qnovo_enable;
bool suspended;
diff --git a/drivers/power/supply/qcom/fg-reg.h b/drivers/power/supply/qcom/fg-reg.h
index 8ca4376..d645e05 100644
--- a/drivers/power/supply/qcom/fg-reg.h
+++ b/drivers/power/supply/qcom/fg-reg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -29,6 +29,7 @@
#define BATT_SOC_STS_CLR(chip) (chip->batt_soc_base + 0x4A)
#define BATT_SOC_LOW_PWR_CFG(chip) (chip->batt_soc_base + 0x52)
#define BATT_SOC_LOW_PWR_STS(chip) (chip->batt_soc_base + 0x56)
+#define BATT_SOC_RST_CTRL0(chip) (chip->batt_soc_base + 0xBA)
/* BATT_SOC_INT_RT_STS */
#define SOC_READY_BIT BIT(1)
@@ -40,6 +41,11 @@
/* BATT_SOC_RESTART */
#define RESTART_GO_BIT BIT(0)
+/* BATT_SOC_RST_CTRL0 */
+#define BCL_RST_BIT BIT(2)
+#define MEM_RST_BIT BIT(1)
+#define ALG_RST_BIT BIT(0)
+
/* FG_BATT_INFO register definitions */
#define BATT_INFO_BATT_TEMP_STS(chip) (chip->batt_info_base + 0x06)
#define BATT_INFO_SYS_BATT(chip) (chip->batt_info_base + 0x07)
diff --git a/drivers/power/supply/qcom/fg-util.c b/drivers/power/supply/qcom/fg-util.c
index 8ad4da8..7e38db6 100644
--- a/drivers/power/supply/qcom/fg-util.c
+++ b/drivers/power/supply/qcom/fg-util.c
@@ -471,7 +471,7 @@
return -ENXIO;
mutex_lock(&chip->bus_lock);
- sec_access = (addr & 0x00FF) > 0xD0;
+ sec_access = (addr & 0x00FF) > 0xB8;
if (sec_access) {
rc = regmap_write(chip->regmap, (addr & 0xFF00) | 0xD0, 0xA5);
if (rc < 0) {
diff --git a/drivers/power/supply/qcom/qg-core.h b/drivers/power/supply/qcom/qg-core.h
index b0ff18c..4f0773b 100644
--- a/drivers/power/supply/qcom/qg-core.h
+++ b/drivers/power/supply/qcom/qg-core.h
@@ -50,11 +50,13 @@
int delta_soc;
int rbat_conn_mohm;
int ignore_shutdown_soc_secs;
+ int shutdown_temp_diff;
int cold_temp_threshold;
int esr_qual_i_ua;
int esr_qual_v_uv;
int esr_disable_soc;
int esr_min_ibat_ua;
+ int shutdown_soc_threshold;
bool hold_soc_while_full;
bool linearize_soc;
bool cl_disable;
diff --git a/drivers/power/supply/qcom/qpnp-fg-gen3.c b/drivers/power/supply/qcom/qpnp-fg-gen3.c
index 975c0d6..d7ee5bd 100644
--- a/drivers/power/supply/qcom/qpnp-fg-gen3.c
+++ b/drivers/power/supply/qcom/qpnp-fg-gen3.c
@@ -23,6 +23,7 @@
#include <linux/thermal.h>
#include <linux/iio/consumer.h>
#include <linux/qpnp/qpnp-revid.h>
+#include <linux/qpnp/qpnp-misc.h>
#include "fg-core.h"
#include "fg-reg.h"
@@ -68,6 +69,8 @@
#define RECHARGE_SOC_THR_OFFSET 0
#define CHG_TERM_CURR_WORD 14
#define CHG_TERM_CURR_OFFSET 1
+#define SYNC_SLEEP_THR_WORD 14
+#define SYNC_SLEEP_THR_OFFSET 3
#define EMPTY_VOLT_WORD 15
#define EMPTY_VOLT_OFFSET 0
#define VBATT_LOW_WORD 15
@@ -139,6 +142,8 @@
#define DELTA_MSOC_THR_v2_OFFSET 0
#define RECHARGE_SOC_THR_v2_WORD 14
#define RECHARGE_SOC_THR_v2_OFFSET 1
+#define SYNC_SLEEP_THR_v2_WORD 14
+#define SYNC_SLEEP_THR_v2_OFFSET 2
#define CHG_TERM_CURR_v2_WORD 15
#define CHG_TERM_BASE_CURR_v2_OFFSET 0
#define CHG_TERM_CURR_v2_OFFSET 1
@@ -223,6 +228,8 @@
2048, 100, 0, fg_encode_default, NULL),
PARAM(RECHARGE_SOC_THR, RECHARGE_SOC_THR_WORD, RECHARGE_SOC_THR_OFFSET,
1, 256, 100, 0, fg_encode_default, NULL),
+ PARAM(SYNC_SLEEP_THR, SYNC_SLEEP_THR_WORD, SYNC_SLEEP_THR_OFFSET,
+ 1, 100000, 390625, 0, fg_encode_default, NULL),
PARAM(ESR_TIMER_DISCHG_MAX, ESR_TIMER_DISCHG_MAX_WORD,
ESR_TIMER_DISCHG_MAX_OFFSET, 2, 1, 1, 0, fg_encode_default,
NULL),
@@ -302,6 +309,8 @@
PARAM(RECHARGE_SOC_THR, RECHARGE_SOC_THR_v2_WORD,
RECHARGE_SOC_THR_v2_OFFSET, 1, 256, 100, 0, fg_encode_default,
NULL),
+ PARAM(SYNC_SLEEP_THR, SYNC_SLEEP_THR_v2_WORD, SYNC_SLEEP_THR_v2_OFFSET,
+ 1, 100000, 390625, 0, fg_encode_default, NULL),
PARAM(RECHARGE_VBATT_THR, RECHARGE_VBATT_THR_v2_WORD,
RECHARGE_VBATT_THR_v2_OFFSET, 1, 1000, 15625, -2000,
fg_encode_voltage, NULL),
@@ -2739,7 +2748,25 @@
mutex_unlock(&chip->cyc_ctr.lock);
}
-static const char *fg_get_cycle_count(struct fg_chip *chip)
+static int fg_get_cycle_count(struct fg_chip *chip)
+{
+ int i, len = 0;
+
+ if (!chip->cyc_ctr.en)
+ return 0;
+
+ mutex_lock(&chip->cyc_ctr.lock);
+ for (i = 0; i < BUCKET_COUNT; i++)
+ len += chip->cyc_ctr.count[i];
+
+ mutex_unlock(&chip->cyc_ctr.lock);
+
+ len = len / BUCKET_COUNT;
+
+ return len;
+}
+
+static const char *fg_get_cycle_counts(struct fg_chip *chip)
{
int i, len = 0;
char *buf;
@@ -4028,8 +4055,11 @@
case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
pval->intval = chip->bp.float_volt_uv;
break;
+ case POWER_SUPPLY_PROP_CYCLE_COUNT:
+ pval->intval = fg_get_cycle_count(chip);
+ break;
case POWER_SUPPLY_PROP_CYCLE_COUNTS:
- pval->strval = fg_get_cycle_count(chip);
+ pval->strval = fg_get_cycle_counts(chip);
break;
case POWER_SUPPLY_PROP_CHARGE_NOW_RAW:
rc = fg_get_charge_raw(chip, &pval->intval);
@@ -4232,6 +4262,22 @@
return NOTIFY_OK;
}
+static int twm_notifier_cb(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct fg_chip *chip = container_of(nb, struct fg_chip, twm_nb);
+
+ if (action != PMIC_TWM_CLEAR &&
+ action != PMIC_TWM_ENABLE) {
+ pr_debug("Unsupported option %lu\n", action);
+ return NOTIFY_OK;
+ }
+
+ chip->twm_state = (u8)action;
+
+ return NOTIFY_OK;
+}
+
static enum power_supply_property fg_psy_props[] = {
POWER_SUPPLY_PROP_CAPACITY,
POWER_SUPPLY_PROP_CAPACITY_RAW,
@@ -4248,6 +4294,7 @@
POWER_SUPPLY_PROP_BATTERY_TYPE,
POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
+ POWER_SUPPLY_PROP_CYCLE_COUNT,
POWER_SUPPLY_PROP_CYCLE_COUNTS,
POWER_SUPPLY_PROP_CHARGE_NOW_RAW,
POWER_SUPPLY_PROP_CHARGE_NOW,
@@ -4539,7 +4586,7 @@
return rc;
}
- if (is_debug_batt_id(chip)) {
+ if (is_debug_batt_id(chip) || chip->dt.disable_esr_pull_dn) {
val = ESR_NO_PULL_DOWN;
rc = fg_masked_write(chip, BATT_INFO_ESR_PULL_DN_CFG(chip),
ESR_PULL_DOWN_MODE_MASK, val);
@@ -4575,6 +4622,21 @@
}
}
+ if (chip->dt.sync_sleep_threshold_ma != -EINVAL) {
+ fg_encode(chip->sp, FG_SRAM_SYNC_SLEEP_THR,
+ chip->dt.sync_sleep_threshold_ma, buf);
+ rc = fg_sram_write(chip,
+ chip->sp[FG_SRAM_SYNC_SLEEP_THR].addr_word,
+ chip->sp[FG_SRAM_SYNC_SLEEP_THR].addr_byte, buf,
+ chip->sp[FG_SRAM_SYNC_SLEEP_THR].len,
+ FG_IMA_DEFAULT);
+ if (rc < 0) {
+ pr_err("Error in writing sync_sleep_threshold=%d\n",
+ rc);
+ return rc;
+ }
+ }
+
return 0;
}
@@ -5350,6 +5412,13 @@
chip->dt.esr_timer_asleep[TIMER_MAX] = -EINVAL;
}
+ rc = fg_parse_dt_property_u32_array(node, "qcom,fg-esr-timer-shutdown",
+ chip->dt.esr_timer_shutdown, NUM_ESR_TIMERS);
+ if (rc < 0) {
+ chip->dt.esr_timer_shutdown[TIMER_RETRY] = -EINVAL;
+ chip->dt.esr_timer_shutdown[TIMER_MAX] = -EINVAL;
+ }
+
chip->cyc_ctr.en = of_property_read_bool(node, "qcom,cycle-counter-en");
chip->dt.force_load_profile = of_property_read_bool(node,
@@ -5512,8 +5581,22 @@
chip->dt.bmd_en_delay_ms = temp;
}
+ chip->dt.sync_sleep_threshold_ma = -EINVAL;
+ rc = of_property_read_u32(node,
+ "qcom,fg-sync-sleep-threshold-ma", &temp);
+ if (!rc) {
+ if (temp >= 0 && temp < 997)
+ chip->dt.sync_sleep_threshold_ma = temp;
+ }
+
chip->dt.use_esr_sw = of_property_read_bool(node, "qcom,fg-use-sw-esr");
+ chip->dt.disable_esr_pull_dn = of_property_read_bool(node,
+ "qcom,fg-disable-esr-pull-dn");
+
+ chip->dt.disable_fg_twm = of_property_read_bool(node,
+ "qcom,fg-disable-in-twm");
+
return 0;
}
@@ -5521,13 +5604,24 @@
{
int i;
+ power_supply_unreg_notifier(&chip->nb);
+ qpnp_misc_twm_notifier_unregister(&chip->twm_nb);
+ cancel_delayed_work_sync(&chip->ttf_work);
+ cancel_delayed_work_sync(&chip->sram_dump_work);
+ if (chip->dt.use_esr_sw)
+ alarm_cancel(&chip->esr_sw_timer);
+ cancel_work_sync(&chip->esr_sw_work);
+ cancel_delayed_work_sync(&chip->profile_load_work);
+ cancel_work_sync(&chip->status_change_work);
+ cancel_work_sync(&chip->esr_filter_work);
+ cancel_delayed_work_sync(&chip->pl_enable_work);
+
for (i = 0; i < FG_IRQ_MAX; i++) {
if (fg_irqs[i].irq)
devm_free_irq(chip->dev, fg_irqs[i].irq, chip);
}
alarm_try_to_cancel(&chip->esr_filter_alarm);
- power_supply_unreg_notifier(&chip->nb);
debugfs_remove_recursive(chip->dfs_root);
if (chip->awake_votable)
destroy_votable(chip->awake_votable);
@@ -5729,6 +5823,11 @@
goto exit;
}
+ chip->twm_nb.notifier_call = twm_notifier_cb;
+ rc = qpnp_misc_twm_notifier_register(&chip->twm_nb);
+ if (rc < 0)
+ pr_err("Failed to register twm_notifier_cb rc=%d\n", rc);
+
rc = fg_register_interrupts(chip);
if (rc < 0) {
dev_err(chip->dev, "Error in registering interrupts, rc:%d\n",
@@ -5851,6 +5950,7 @@
{
struct fg_chip *chip = dev_get_drvdata(&pdev->dev);
int rc, bsoc;
+ u8 mask;
if (chip->charge_full) {
rc = fg_get_sram_prop(chip, FG_SRAM_BATT_SOC, &bsoc);
@@ -5868,6 +5968,24 @@
return;
}
}
+ rc = fg_set_esr_timer(chip, chip->dt.esr_timer_shutdown[TIMER_RETRY],
+ chip->dt.esr_timer_shutdown[TIMER_MAX], false,
+ FG_IMA_NO_WLOCK);
+ if (rc < 0)
+ pr_err("Error in setting ESR timer at shutdown, rc=%d\n", rc);
+
+ if (chip->twm_state == PMIC_TWM_ENABLE && chip->dt.disable_fg_twm) {
+ rc = fg_masked_write(chip, BATT_SOC_EN_CTL(chip),
+ FG_ALGORITHM_EN_BIT, 0);
+ if (rc < 0)
+ pr_err("Error in disabling FG rc=%d\n", rc);
+
+ mask = BCL_RST_BIT | MEM_RST_BIT | ALG_RST_BIT;
+ rc = fg_masked_write(chip, BATT_SOC_RST_CTRL0(chip),
+ mask, mask);
+ if (rc < 0)
+ pr_err("Error in disabling FG resets rc=%d\n", rc);
+ }
}
static const struct of_device_id fg_gen3_match_table[] = {
diff --git a/drivers/power/supply/qcom/qpnp-qg.c b/drivers/power/supply/qcom/qpnp-qg.c
index 855e31d..28086d3 100644
--- a/drivers/power/supply/qcom/qpnp-qg.c
+++ b/drivers/power/supply/qcom/qpnp-qg.c
@@ -2514,7 +2514,6 @@
return 0;
}
-
static struct ocv_all ocv[] = {
[S7_PON_OCV] = { 0, 0, "S7_PON_OCV"},
[S3_GOOD_OCV] = { 0, 0, "S3_GOOD_OCV"},
@@ -2528,7 +2527,8 @@
int rc = 0, batt_temp = 0, i;
bool use_pon_ocv = true;
unsigned long rtc_sec = 0;
- u32 ocv_uv = 0, soc = 0, shutdown[SDAM_MAX] = {0};
+ u32 ocv_uv = 0, soc = 0, pon_soc = 0, full_soc = 0, cutoff_soc = 0;
+ u32 shutdown[SDAM_MAX] = {0};
char ocv_type[20] = "NONE";
if (!chip->profile_loaded) {
@@ -2536,6 +2536,24 @@
return 0;
}
+ /* read all OCVs */
+ for (i = S7_PON_OCV; i < PON_OCV_MAX; i++) {
+ rc = qg_read_ocv(chip, &ocv[i].ocv_uv,
+ &ocv[i].ocv_raw, i);
+ if (rc < 0)
+ pr_err("Failed to read %s OCV rc=%d\n",
+ ocv[i].ocv_type, rc);
+ else
+ qg_dbg(chip, QG_DEBUG_PON, "%s OCV=%d\n",
+ ocv[i].ocv_type, ocv[i].ocv_uv);
+ }
+
+ rc = qg_get_battery_temp(chip, &batt_temp);
+ if (rc) {
+ pr_err("Failed to read BATT_TEMP at PON rc=%d\n", rc);
+ goto done;
+ }
+
rc = get_rtc_time(&rtc_sec);
if (rc < 0) {
pr_err("Failed to read RTC time rc=%d\n", rc);
@@ -2548,47 +2566,50 @@
goto use_pon_ocv;
}
- qg_dbg(chip, QG_DEBUG_PON, "Shutdown: Valid=%d SOC=%d OCV=%duV time=%dsecs, time_now=%ldsecs\n",
+ rc = lookup_soc_ocv(&pon_soc, ocv[S7_PON_OCV].ocv_uv, batt_temp, false);
+ if (rc < 0) {
+ pr_err("Failed to lookup S7_PON SOC rc=%d\n", rc);
+ goto done;
+ }
+
+ qg_dbg(chip, QG_DEBUG_PON, "Shutdown: Valid=%d SOC=%d OCV=%duV time=%dsecs temp=%d, time_now=%ldsecs temp_now=%d S7_soc=%d\n",
shutdown[SDAM_VALID],
shutdown[SDAM_SOC],
shutdown[SDAM_OCV_UV],
shutdown[SDAM_TIME_SEC],
- rtc_sec);
+ shutdown[SDAM_TEMP],
+ rtc_sec, batt_temp,
+ pon_soc);
/*
* Use the shutdown SOC if
- * 1. The device was powered off for < ignore_shutdown_time
- * 2. SDAM read is a success & SDAM data is valid
+ * 1. SDAM read is a success & SDAM data is valid
+ * 2. The device was powered off for < ignore_shutdown_time
+ * 2. Batt temp has not changed more than shutdown_temp_diff
*/
- if (shutdown[SDAM_VALID] && is_between(0,
- chip->dt.ignore_shutdown_soc_secs,
- (rtc_sec - shutdown[SDAM_TIME_SEC]))) {
- use_pon_ocv = false;
- ocv_uv = shutdown[SDAM_OCV_UV];
- soc = shutdown[SDAM_SOC];
- strlcpy(ocv_type, "SHUTDOWN_SOC", 20);
- qg_dbg(chip, QG_DEBUG_PON, "Using SHUTDOWN_SOC @ PON\n");
- }
+ if (!shutdown[SDAM_VALID])
+ goto use_pon_ocv;
+
+ if (!is_between(0, chip->dt.ignore_shutdown_soc_secs,
+ (rtc_sec - shutdown[SDAM_TIME_SEC])))
+ goto use_pon_ocv;
+
+ if (!is_between(0, chip->dt.shutdown_temp_diff,
+ abs(shutdown[SDAM_TEMP] - batt_temp)))
+ goto use_pon_ocv;
+
+ if ((chip->dt.shutdown_soc_threshold != -EINVAL) &&
+ !is_between(0, chip->dt.shutdown_soc_threshold,
+ abs(pon_soc - shutdown[SDAM_SOC])))
+ goto use_pon_ocv;
+
+ use_pon_ocv = false;
+ ocv_uv = shutdown[SDAM_OCV_UV];
+ soc = shutdown[SDAM_SOC];
+ strlcpy(ocv_type, "SHUTDOWN_SOC", 20);
+ qg_dbg(chip, QG_DEBUG_PON, "Using SHUTDOWN_SOC @ PON\n");
use_pon_ocv:
if (use_pon_ocv == true) {
- rc = qg_get_battery_temp(chip, &batt_temp);
- if (rc) {
- pr_err("Failed to read BATT_TEMP at PON rc=%d\n", rc);
- goto done;
- }
-
- /* read all OCVs */
- for (i = S7_PON_OCV; i < PON_OCV_MAX; i++) {
- rc = qg_read_ocv(chip, &ocv[i].ocv_uv,
- &ocv[i].ocv_raw, i);
- if (rc < 0)
- pr_err("Failed to read %s OCV rc=%d\n",
- ocv[i].ocv_type, rc);
- else
- qg_dbg(chip, QG_DEBUG_PON, "%s OCV=%d\n",
- ocv[i].ocv_type, ocv[i].ocv_uv);
- }
-
if (ocv[S3_LAST_OCV].ocv_raw == FIFO_V_RESET_VAL) {
if (!ocv[SDAM_PON_OCV].ocv_uv) {
strlcpy(ocv_type, "S7_PON_SOC", 20);
@@ -2618,11 +2639,36 @@
}
ocv_uv = CAP(QG_MIN_OCV_UV, QG_MAX_OCV_UV, ocv_uv);
- rc = lookup_soc_ocv(&soc, ocv_uv, batt_temp, false);
+ rc = lookup_soc_ocv(&pon_soc, ocv_uv, batt_temp, false);
if (rc < 0) {
pr_err("Failed to lookup SOC@PON rc=%d\n", rc);
goto done;
}
+
+ rc = lookup_soc_ocv(&full_soc, chip->bp.float_volt_uv,
+ batt_temp, true);
+ if (rc < 0) {
+ pr_err("Failed to lookup FULL_SOC@PON rc=%d\n", rc);
+ goto done;
+ }
+
+ rc = lookup_soc_ocv(&cutoff_soc,
+ chip->dt.vbatt_cutoff_mv * 1000,
+ batt_temp, false);
+ if (rc < 0) {
+ pr_err("Failed to lookup CUTOFF_SOC@PON rc=%d\n", rc);
+ goto done;
+ }
+
+ if ((full_soc - cutoff_soc) > 0 && (pon_soc - cutoff_soc) > 0)
+ soc = DIV_ROUND_UP(((pon_soc - cutoff_soc) * 100),
+ (full_soc - cutoff_soc));
+ else
+ soc = pon_soc;
+
+ qg_dbg(chip, QG_DEBUG_PON, "v_float=%d v_cutoff=%d FULL_SOC=%d CUTOFF_SOC=%d PON_SYS_SOC=%d pon_soc=%d\n",
+ chip->bp.float_volt_uv, chip->dt.vbatt_cutoff_mv * 1000,
+ full_soc, cutoff_soc, pon_soc, soc);
}
done:
if (rc < 0) {
@@ -3074,6 +3120,7 @@
#define DEFAULT_CL_MAX_DEC_DECIPERC 20
#define DEFAULT_CL_MIN_LIM_DECIPERC 500
#define DEFAULT_CL_MAX_LIM_DECIPERC 100
+#define DEFAULT_SHUTDOWN_TEMP_DIFF 60 /* 6 degC */
#define DEFAULT_ESR_QUAL_CURRENT_UA 130000
#define DEFAULT_ESR_QUAL_VBAT_UV 7000
#define DEFAULT_ESR_DISABLE_SOC 1000
@@ -3259,6 +3306,12 @@
else
chip->dt.ignore_shutdown_soc_secs = temp;
+ rc = of_property_read_u32(node, "qcom,shutdown-temp-diff", &temp);
+ if (rc < 0)
+ chip->dt.shutdown_temp_diff = DEFAULT_SHUTDOWN_TEMP_DIFF;
+ else
+ chip->dt.shutdown_temp_diff = temp;
+
chip->dt.hold_soc_while_full = of_property_read_bool(node,
"qcom,hold-soc-while-full");
@@ -3302,6 +3355,12 @@
else
chip->dt.esr_min_ibat_ua = (int)temp;
+ rc = of_property_read_u32(node, "qcom,shutdown_soc_threshold", &temp);
+ if (rc < 0)
+ chip->dt.shutdown_soc_threshold = -EINVAL;
+ else
+ chip->dt.shutdown_soc_threshold = temp;
+
chip->dt.qg_ext_sense = of_property_read_bool(node, "qcom,qg-ext-sns");
/* Capacity learning params*/
diff --git a/drivers/power/supply/qcom/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c
index e3e4f2b..dd0f889 100644
--- a/drivers/power/supply/qcom/qpnp-smb2.c
+++ b/drivers/power/supply/qcom/qpnp-smb2.c
@@ -217,6 +217,9 @@
return -EINVAL;
}
+ chg->reddragon_ipc_wa = of_property_read_bool(node,
+ "qcom,qcs605-ipc-wa");
+
chg->step_chg_enabled = of_property_read_bool(node,
"qcom,step-charging-enable");
@@ -334,6 +337,9 @@
chg->disable_stat_sw_override = of_property_read_bool(node,
"qcom,disable-stat-sw-override");
+ chg->fcc_stepper_enable = of_property_read_bool(node,
+ "qcom,fcc-stepping-enable");
+
return 0;
}
@@ -1001,6 +1007,7 @@
POWER_SUPPLY_PROP_CHARGE_COUNTER,
POWER_SUPPLY_PROP_CHARGE_FULL,
POWER_SUPPLY_PROP_CYCLE_COUNT,
+ POWER_SUPPLY_PROP_FCC_STEPPER_ENABLE,
};
static int smb2_batt_get_prop(struct power_supply *psy,
@@ -1115,6 +1122,9 @@
case POWER_SUPPLY_PROP_TEMP:
rc = smblib_get_prop_from_bms(chg, psp, val);
break;
+ case POWER_SUPPLY_PROP_FCC_STEPPER_ENABLE:
+ val->intval = chg->fcc_stepper_enable;
+ break;
default:
pr_err("batt power supply prop %d not supported\n", psp);
return -EINVAL;
diff --git a/drivers/power/supply/qcom/qpnp-smb5.c b/drivers/power/supply/qcom/qpnp-smb5.c
index 57aa0c6..0a677ec 100644
--- a/drivers/power/supply/qcom/qpnp-smb5.c
+++ b/drivers/power/supply/qcom/qpnp-smb5.c
@@ -282,7 +282,7 @@
break;
case PMI632_SUBTYPE:
chip->chg.smb_version = PMI632_SUBTYPE;
- chg->wa_flags |= WEAK_ADAPTER_WA;
+ chg->wa_flags |= WEAK_ADAPTER_WA | USBIN_OV_WA;
if (pmic_rev_id->rev4 >= 2)
chg->wa_flags |= MOISTURE_PROTECTION_WA;
chg->param = smb5_pmi632_params;
@@ -504,6 +504,9 @@
chg->moisture_protection_enabled = of_property_read_bool(node,
"qcom,moisture-protection-enable");
+ chg->fcc_stepper_enable = of_property_read_bool(node,
+ "qcom,fcc-stepping-enable");
+
return 0;
}
@@ -1258,6 +1261,7 @@
POWER_SUPPLY_PROP_CYCLE_COUNT,
POWER_SUPPLY_PROP_RECHARGE_SOC,
POWER_SUPPLY_PROP_CHARGE_FULL,
+ POWER_SUPPLY_PROP_FCC_STEPPER_ENABLE,
};
#define ITERM_SCALING_FACTOR_PMI632 1525
@@ -1414,6 +1418,9 @@
rc = smblib_get_prop_from_bms(chg,
POWER_SUPPLY_PROP_CHARGE_FULL, val);
break;
+ case POWER_SUPPLY_PROP_FCC_STEPPER_ENABLE:
+ val->intval = chg->fcc_stepper_enable;
+ break;
default:
pr_err("batt power supply prop %d not supported\n", psp);
return -EINVAL;
@@ -1732,6 +1739,14 @@
}
}
+ /* Disable TypeC and RID change source interrupts */
+ rc = smblib_write(chg, TYPE_C_INTERRUPT_EN_CFG_2_REG, 0);
+ if (rc < 0) {
+ dev_err(chg->dev,
+ "Couldn't configure Type-C interrupts rc=%d\n", rc);
+ return rc;
+ }
+
return rc;
}
@@ -2428,7 +2443,7 @@
},
[USBIN_OV_IRQ] = {
.name = "usbin-ov",
- .handler = default_irq_handler,
+ .handler = usbin_ov_irq_handler,
},
[USBIN_PLUGIN_IRQ] = {
.name = "usbin-plugin",
diff --git a/drivers/power/supply/qcom/qpnp-vm-bms.c b/drivers/power/supply/qcom/qpnp-vm-bms.c
index 042ce99..6faee2b 100644
--- a/drivers/power/supply/qcom/qpnp-vm-bms.c
+++ b/drivers/power/supply/qcom/qpnp-vm-bms.c
@@ -953,9 +953,9 @@
int soc_ocv = 0, soc_cutoff = 0, soc_final = 0;
int fcc, acc, soc_uuc = 0, soc_acc = 0, iavg_ma = 0;
- soc_ocv = interpolate_pc(chip->batt_data->pc_temp_ocv_lut,
+ soc_ocv = interpolate_pc_bms(chip->batt_data->pc_temp_ocv_lut,
batt_temp, ocv_uv / 1000);
- soc_cutoff = interpolate_pc(chip->batt_data->pc_temp_ocv_lut,
+ soc_cutoff = interpolate_pc_bms(chip->batt_data->pc_temp_ocv_lut,
batt_temp, chip->dt.cfg_v_cutoff_uv / 1000);
soc_final = DIV_ROUND_CLOSEST(100 * (soc_ocv - soc_cutoff),
@@ -974,9 +974,9 @@
else
iavg_ma = chip->current_now / 1000;
- fcc = interpolate_fcc(chip->batt_data->fcc_temp_lut,
+ fcc = interpolate_fcc_bms(chip->batt_data->fcc_temp_lut,
batt_temp);
- acc = interpolate_acc(chip->batt_data->ibat_acc_lut,
+ acc = interpolate_acc_bms(chip->batt_data->ibat_acc_lut,
batt_temp, iavg_ma);
if (acc <= 0) {
if (chip->last_acc)
@@ -1249,7 +1249,8 @@
return rbatt_mohm;
}
- scalefactor = interpolate_scalingfactor(chip->batt_data->rbatt_sf_lut,
+ scalefactor = interpolate_scalingfactor_bms(
+ chip->batt_data->rbatt_sf_lut,
batt_temp, soc);
rbatt_mohm = (rbatt_mohm * scalefactor) / 100;
@@ -2847,7 +2848,7 @@
if (die_temp == (temp_curr_comp_lut[i].temp_decideg))
return temp_curr_comp_lut[i].current_ma;
- return linear_interpolate(
+ return linear_interpolate_bms(
temp_curr_comp_lut[i - 1].current_ma,
temp_curr_comp_lut[i - 1].temp_decideg,
temp_curr_comp_lut[i].current_ma,
@@ -2864,7 +2865,7 @@
if (rc) {
pr_err("error reading adc channel=%d, rc=%d\n", DIE_TEMP, rc);
} else {
- pc = interpolate_pc(chip->batt_data->pc_temp_ocv_lut,
+ pc = interpolate_pc_bms(chip->batt_data->pc_temp_ocv_lut,
batt_temp, chip->last_ocv_uv / 1000);
/*
* For pc < 2, use the rbatt of pc = 2. This is to avoid
@@ -3476,8 +3477,8 @@
pr_err("cannot read battery id err = %lld\n", battery_id);
return battery_id;
}
- node = of_find_node_by_name(chip->pdev->dev.of_node,
- "qcom,battery-data");
+ node = of_parse_phandle(chip->pdev->dev.of_node,
+ "qcom,battery-data", 0);
if (!node) {
pr_err("No available batterydata\n");
return -EINVAL;
diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c
index 5546eae..3671891 100644
--- a/drivers/power/supply/qcom/smb-lib.c
+++ b/drivers/power/supply/qcom/smb-lib.c
@@ -1606,7 +1606,7 @@
smblib_dbg(chg, PR_OTG, "enabling OTG\n");
- if (chg->wa_flags & OTG_WA) {
+ if ((chg->wa_flags & OTG_WA) && (!chg->reddragon_ipc_wa)) {
rc = smblib_enable_otg_wa(chg);
if (rc < 0)
smblib_err(chg, "Couldn't enable OTG rc=%d\n", rc);
@@ -3518,8 +3518,17 @@
vbus_rising = (bool)(stat & USBIN_PLUGIN_RT_STS_BIT);
if (vbus_rising) {
+ /* Remove FCC_STEPPER 1.5A init vote to allow FCC ramp up */
+ if (chg->fcc_stepper_enable)
+ vote(chg->fcc_votable, FCC_STEPPER_VOTER, false, 0);
+
smblib_cc2_sink_removal_exit(chg);
} else {
+ /* Force 1500mA FCC on USB removal if fcc stepper is enabled */
+ if (chg->fcc_stepper_enable)
+ vote(chg->fcc_votable, FCC_STEPPER_VOTER,
+ true, 1500000);
+
smblib_cc2_sink_removal_enter(chg);
if (chg->wa_flags & BOOST_BACK_WA) {
data = chg->irq_info[SWITCH_POWER_OK_IRQ].irq_data;
@@ -3569,6 +3578,10 @@
if (rc < 0)
smblib_err(chg, "Couldn't to enable DPDM rc=%d\n", rc);
+ /* Remove FCC_STEPPER 1.5A init vote to allow FCC ramp up */
+ if (chg->fcc_stepper_enable)
+ vote(chg->fcc_votable, FCC_STEPPER_VOTER, false, 0);
+
/* Schedule work to enable parallel charger */
vote(chg->awake_votable, PL_DELAY_VOTER, true, 0);
schedule_delayed_work(&chg->pl_enable_work,
@@ -3596,6 +3609,11 @@
}
}
+ /* Force 1500mA FCC on removal if fcc stepper is enabled */
+ if (chg->fcc_stepper_enable)
+ vote(chg->fcc_votable, FCC_STEPPER_VOTER,
+ true, 1500000);
+
rc = smblib_request_dpdm(chg, false);
if (rc < 0)
smblib_err(chg, "Couldn't disable DPDM rc=%d\n", rc);
diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h
index 2457ed2..87a8303 100644
--- a/drivers/power/supply/qcom/smb-lib.h
+++ b/drivers/power/supply/qcom/smb-lib.h
@@ -72,6 +72,7 @@
#define HVDCP2_ICL_VOTER "HVDCP2_ICL_VOTER"
#define OV_VOTER "OV_VOTER"
#define FG_ESR_VOTER "FG_ESR_VOTER"
+#define FCC_STEPPER_VOTER "FCC_STEPPER_VOTER"
#define VCONN_MAX_ATTEMPTS 3
#define OTG_MAX_ATTEMPTS 3
@@ -356,6 +357,7 @@
bool is_audio_adapter;
bool disable_stat_sw_override;
bool in_chg_lock;
+ bool fcc_stepper_enable;
/* workaround flag */
u32 wa_flags;
@@ -367,6 +369,7 @@
int qc2_max_pulses;
bool non_compliant_chg_detected;
bool fake_usb_insertion;
+ bool reddragon_ipc_wa;
/* extcon for VBUS / ID notification to USB for uUSB */
struct extcon_dev *extcon;
diff --git a/drivers/power/supply/qcom/smb5-lib.c b/drivers/power/supply/qcom/smb5-lib.c
index f91d477..6f13635 100644
--- a/drivers/power/supply/qcom/smb5-lib.c
+++ b/drivers/power/supply/qcom/smb5-lib.c
@@ -801,6 +801,11 @@
smblib_err(chg, "Couldn't set USBIN_ADAPTER_ALLOW_5V_OR_9V_TO_12V rc=%d\n",
rc);
+ /* reset USBOV votes and cancel work */
+ cancel_delayed_work_sync(&chg->usbov_dbc_work);
+ vote(chg->awake_votable, USBOV_DBC_VOTER, false, 0);
+ chg->dbc_usbov = false;
+
chg->voltage_min_uv = MICRO_5V;
chg->voltage_max_uv = MICRO_5V;
chg->usb_icl_delta_ua = 0;
@@ -1393,7 +1398,32 @@
union power_supply_propval pval = {0, };
bool usb_online, dc_online;
u8 stat;
- int rc;
+ int rc, suspend = 0;
+
+ if (chg->dbc_usbov) {
+ rc = smblib_get_prop_usb_present(chg, &pval);
+ if (rc < 0) {
+ smblib_err(chg,
+ "Couldn't get usb present prop rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = smblib_get_usb_suspend(chg, &suspend);
+ if (rc < 0) {
+ smblib_err(chg,
+ "Couldn't get usb suspend rc=%d\n", rc);
+ return rc;
+ }
+
+ /*
+ * Report charging as long as USBOV is not debounced and
+ * charging path is un-suspended.
+ */
+ if (pval.intval && !suspend) {
+ val->intval = POWER_SUPPLY_STATUS_CHARGING;
+ return 0;
+ }
+ }
rc = smblib_get_prop_usb_online(chg, &pval);
if (rc < 0) {
@@ -2939,7 +2969,11 @@
vbus_rising = (bool)(stat & USBIN_PLUGIN_RT_STS_BIT);
- if (!vbus_rising) {
+ if (vbus_rising) {
+ /* Remove FCC_STEPPER 1.5A init vote to allow FCC ramp up */
+ if (chg->fcc_stepper_enable)
+ vote(chg->fcc_votable, FCC_STEPPER_VOTER, false, 0);
+ } else {
if (chg->wa_flags & BOOST_BACK_WA) {
data = chg->irq_info[SWITCHER_POWER_OK_IRQ].irq_data;
if (data) {
@@ -2952,6 +2986,11 @@
false, 0);
}
}
+
+ /* Force 1500mA FCC on USB removal if fcc stepper is enabled */
+ if (chg->fcc_stepper_enable)
+ vote(chg->fcc_votable, FCC_STEPPER_VOTER,
+ true, 1500000);
}
power_supply_changed(chg->usb_psy);
@@ -2983,6 +3022,10 @@
if (rc < 0)
smblib_err(chg, "Couldn't to enable DPDM rc=%d\n", rc);
+ /* Remove FCC_STEPPER 1.5A init vote to allow FCC ramp up */
+ if (chg->fcc_stepper_enable)
+ vote(chg->fcc_votable, FCC_STEPPER_VOTER, false, 0);
+
/* Schedule work to enable parallel charger */
vote(chg->awake_votable, PL_DELAY_VOTER, true, 0);
schedule_delayed_work(&chg->pl_enable_work,
@@ -3028,6 +3071,11 @@
false, 0);
}
+ /* Force 1500mA FCC on removal if fcc stepper is enabled */
+ if (chg->fcc_stepper_enable)
+ vote(chg->fcc_votable, FCC_STEPPER_VOTER,
+ true, 1500000);
+
rc = smblib_request_dpdm(chg, false);
if (rc < 0)
smblib_err(chg, "Couldn't disable DPDM rc=%d\n", rc);
@@ -3443,6 +3491,11 @@
vote(chg->pl_enable_votable_indirect, USBIN_V_VOTER, false, 0);
vote(chg->awake_votable, PL_DELAY_VOTER, false, 0);
+ /* reset USBOV votes and cancel work */
+ cancel_delayed_work_sync(&chg->usbov_dbc_work);
+ vote(chg->awake_votable, USBOV_DBC_VOTER, false, 0);
+ chg->dbc_usbov = false;
+
chg->pulse_cnt = 0;
chg->usb_icl_delta_ua = 0;
chg->voltage_min_uv = MICRO_5V;
@@ -3724,6 +3777,51 @@
return IRQ_HANDLED;
}
+static void smblib_usbov_dbc_work(struct work_struct *work)
+{
+ struct smb_charger *chg = container_of(work, struct smb_charger,
+ usbov_dbc_work.work);
+
+ smblib_dbg(chg, PR_MISC, "Resetting USBOV debounce\n");
+ chg->dbc_usbov = false;
+ vote(chg->awake_votable, USBOV_DBC_VOTER, false, 0);
+}
+
+irqreturn_t usbin_ov_irq_handler(int irq, void *data)
+{
+ struct smb_irq_data *irq_data = data;
+ struct smb_charger *chg = irq_data->parent_data;
+ u8 stat;
+ int rc;
+
+ if (!(chg->wa_flags & USBIN_OV_WA))
+ goto out;
+
+ rc = smblib_read(chg, USBIN_BASE + INT_RT_STS_OFFSET, &stat);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't read USB_INT_RT_STS rc=%d\n", rc);
+ goto out;
+ }
+ smblib_dbg(chg, PR_INTERRUPT, "IRQ: %s stat=%x\n", irq_data->name,
+ !!stat);
+
+ if (stat & USBIN_OV_RT_STS_BIT) {
+ chg->dbc_usbov = true;
+ vote(chg->awake_votable, USBOV_DBC_VOTER, true, 0);
+ schedule_delayed_work(&chg->usbov_dbc_work,
+ msecs_to_jiffies(1000));
+ } else {
+ cancel_delayed_work_sync(&chg->usbov_dbc_work);
+ chg->dbc_usbov = false;
+ vote(chg->awake_votable, USBOV_DBC_VOTER, true, 0);
+ }
+
+out:
+ smblib_dbg(chg, PR_MISC, "USBOV debounce status %d\n",
+ chg->dbc_usbov);
+ return IRQ_HANDLED;
+}
+
/**************
* Additional USB PSY getters/setters
* that call interrupt functions
@@ -4188,6 +4286,7 @@
INIT_DELAYED_WORK(&chg->pl_enable_work, smblib_pl_enable_work);
INIT_DELAYED_WORK(&chg->uusb_otg_work, smblib_uusb_otg_work);
INIT_DELAYED_WORK(&chg->bb_removal_work, smblib_bb_removal_work);
+ INIT_DELAYED_WORK(&chg->usbov_dbc_work, smblib_usbov_dbc_work);
if (chg->moisture_protection_enabled &&
(chg->wa_flags & MOISTURE_PROTECTION_WA)) {
@@ -4277,6 +4376,7 @@
cancel_delayed_work_sync(&chg->pl_enable_work);
cancel_delayed_work_sync(&chg->uusb_otg_work);
cancel_delayed_work_sync(&chg->bb_removal_work);
+ cancel_delayed_work_sync(&chg->usbov_dbc_work);
power_supply_unreg_notifier(&chg->nb);
smblib_destroy_votables(chg);
qcom_step_chg_deinit();
diff --git a/drivers/power/supply/qcom/smb5-lib.h b/drivers/power/supply/qcom/smb5-lib.h
index 9afd7cd..1bba206 100644
--- a/drivers/power/supply/qcom/smb5-lib.h
+++ b/drivers/power/supply/qcom/smb5-lib.h
@@ -70,6 +70,8 @@
#define FORCE_RECHARGE_VOTER "FORCE_RECHARGE_VOTER"
#define AICL_THRESHOLD_VOTER "AICL_THRESHOLD_VOTER"
#define MOISTURE_VOTER "MOISTURE_VOTER"
+#define USBOV_DBC_VOTER "USBOV_DBC_VOTER"
+#define FCC_STEPPER_VOTER "FCC_STEPPER_VOTER"
#define BOOST_BACK_STORM_COUNT 3
#define WEAK_CHG_STORM_COUNT 8
@@ -101,6 +103,7 @@
BOOST_BACK_WA = BIT(0),
WEAK_ADAPTER_WA = BIT(1),
MOISTURE_PROTECTION_WA = BIT(2),
+ USBIN_OV_WA = BIT(3),
};
enum {
@@ -348,6 +351,7 @@
struct delayed_work pl_enable_work;
struct delayed_work uusb_otg_work;
struct delayed_work bb_removal_work;
+ struct delayed_work usbov_dbc_work;
/* alarm */
struct alarm moisture_protection_alarm;
@@ -402,10 +406,12 @@
bool aicl_max_reached;
bool moisture_present;
bool moisture_protection_enabled;
+ bool fcc_stepper_enable;
/* workaround flag */
u32 wa_flags;
int boost_current_ua;
+ bool dbc_usbov;
/* extcon for VBUS / ID notification to USB for uUSB */
struct extcon_dev *extcon;
@@ -478,6 +484,7 @@
irqreturn_t switcher_power_ok_irq_handler(int irq, void *data);
irqreturn_t wdog_bark_irq_handler(int irq, void *data);
irqreturn_t typec_or_rid_detection_change_irq_handler(int irq, void *data);
+irqreturn_t usbin_ov_irq_handler(int irq, void *data);
int smblib_get_prop_input_suspend(struct smb_charger *chg,
union power_supply_propval *val);
diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
index 58a97d4..5136462 100644
--- a/drivers/ptp/ptp_chardev.c
+++ b/drivers/ptp/ptp_chardev.c
@@ -89,6 +89,7 @@
case PTP_PF_PHYSYNC:
if (chan != 0)
return -EINVAL;
+ break;
default:
return -EINVAL;
}
diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c
index cb18b5c..86b3487 100644
--- a/drivers/regulator/pfuze100-regulator.c
+++ b/drivers/regulator/pfuze100-regulator.c
@@ -153,6 +153,7 @@
static struct regulator_ops pfuze100_swb_regulator_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
.list_voltage = regulator_list_voltage_table,
.map_voltage = regulator_map_voltage_ascend,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
diff --git a/drivers/regulator/qpnp-lcdb-regulator.c b/drivers/regulator/qpnp-lcdb-regulator.c
index a0f0fcec..0fd7802 100644
--- a/drivers/regulator/qpnp-lcdb-regulator.c
+++ b/drivers/regulator/qpnp-lcdb-regulator.c
@@ -181,6 +181,7 @@
int soft_start_us;
int vreg_ok_dbc_us;
int voltage_mv;
+ int prev_voltage_mv;
};
struct ncp_regulator {
@@ -195,6 +196,7 @@
int soft_start_us;
int vreg_ok_dbc_us;
int voltage_mv;
+ int prev_voltage_mv;
};
struct bst_params {
@@ -216,6 +218,7 @@
struct device *dev;
struct platform_device *pdev;
struct regmap *regmap;
+ struct class lcdb_class;
struct pmic_revid_data *pmic_rev_id;
u32 base;
u32 wa_flags;
@@ -229,6 +232,8 @@
bool lcdb_enabled;
bool settings_saved;
bool lcdb_sc_disable;
+ bool secure_mode;
+ bool voltage_step_ramp;
int sc_count;
ktime_t sc_module_enable_time;
@@ -250,6 +255,7 @@
LDO,
NCP,
BST,
+ LDO_NCP,
};
enum pfm_hysteresis {
@@ -321,6 +327,12 @@
.valid = _valid \
} \
+static int qpnp_lcdb_set_voltage_step(struct qpnp_lcdb *lcdb,
+ int voltage_start_mv, u8 type);
+
+static int qpnp_lcdb_set_voltage(struct qpnp_lcdb *lcdb,
+ int voltage_mv, u8 type);
+
static bool is_between(int value, int min, int max)
{
if (value < min || value > max)
@@ -784,9 +796,13 @@
return 0;
}
+#define VOLTAGE_START_MV 4500
+#define VOLTAGE_STEP_MV 500
+
static int qpnp_lcdb_enable(struct qpnp_lcdb *lcdb)
{
int rc = 0, timeout, delay;
+ int voltage_mv = VOLTAGE_START_MV;
u8 val = 0;
if (lcdb->lcdb_enabled || lcdb->lcdb_sc_disable) {
@@ -809,6 +825,22 @@
return rc;
}
+ if (lcdb->voltage_step_ramp) {
+ if (lcdb->ldo.voltage_mv < VOLTAGE_START_MV)
+ voltage_mv = lcdb->ldo.voltage_mv;
+
+ rc = qpnp_lcdb_set_voltage(lcdb, voltage_mv, LDO);
+ if (rc < 0)
+ return rc;
+
+ if (lcdb->ncp.voltage_mv < VOLTAGE_START_MV)
+ voltage_mv = lcdb->ncp.voltage_mv;
+
+ rc = qpnp_lcdb_set_voltage(lcdb, voltage_mv, NCP);
+ if (rc < 0)
+ return rc;
+ }
+
val = MODULE_EN_BIT;
rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_ENABLE_CTL1_REG,
&val, 1);
@@ -845,6 +877,17 @@
}
lcdb->lcdb_enabled = true;
+ if (lcdb->voltage_step_ramp) {
+ usleep_range(10000, 11000);
+ rc = qpnp_lcdb_set_voltage_step(lcdb,
+ voltage_mv + VOLTAGE_STEP_MV,
+ LDO_NCP);
+ if (rc < 0) {
+ pr_err("Failed to set LCDB voltage rc=%d\n", rc);
+ return rc;
+ }
+ }
+
pr_debug("lcdb enabled successfully!\n");
return 0;
@@ -1131,6 +1174,56 @@
return rc;
}
+static int qpnp_lcdb_set_voltage_step(struct qpnp_lcdb *lcdb,
+ int voltage_start_mv, u8 type)
+{
+ int i, ldo_voltage, ncp_voltage, voltage, rc = 0;
+
+ for (i = voltage_start_mv; i <= (MAX_VOLTAGE_MV + VOLTAGE_STEP_MV);
+ i += VOLTAGE_STEP_MV) {
+
+ ldo_voltage = (lcdb->ldo.voltage_mv < i) ?
+ lcdb->ldo.voltage_mv : i;
+
+ ncp_voltage = (lcdb->ncp.voltage_mv < i) ?
+ lcdb->ncp.voltage_mv : i;
+ if (type == LDO_NCP) {
+ rc = qpnp_lcdb_set_voltage(lcdb, ldo_voltage, LDO);
+ if (rc < 0)
+ return rc;
+
+ rc = qpnp_lcdb_set_voltage(lcdb, ncp_voltage, NCP);
+ if (rc < 0)
+ return rc;
+
+ pr_debug(" LDO voltage step %d NCP voltage step %d\n",
+ ldo_voltage, ncp_voltage);
+
+ if ((i >= lcdb->ncp.voltage_mv) &&
+ (i >= lcdb->ldo.voltage_mv))
+ break;
+ } else {
+ voltage = (type == LDO) ? ldo_voltage : ncp_voltage;
+ rc = qpnp_lcdb_set_voltage(lcdb, voltage, type);
+ if (rc < 0)
+ return rc;
+
+ pr_debug("%s voltage step %d\n",
+ (type == LDO) ? "LDO" : "NCP", voltage);
+ if ((type == LDO) && (i >= lcdb->ldo.voltage_mv))
+ break;
+
+ if ((type == NCP) && (i >= lcdb->ncp.voltage_mv))
+ break;
+
+ }
+
+ usleep_range(1000, 1100);
+ }
+
+ return rc;
+}
+
static int qpnp_lcdb_get_voltage(struct qpnp_lcdb *lcdb,
u32 *voltage_mv, u8 type)
{
@@ -1203,6 +1296,9 @@
int rc = 0;
struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev);
+ if (lcdb->secure_mode)
+ return 0;
+
mutex_lock(&lcdb->lcdb_mutex);
rc = qpnp_lcdb_enable(lcdb);
if (rc < 0)
@@ -1217,6 +1313,9 @@
int rc = 0;
struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev);
+ if (lcdb->secure_mode)
+ return 0;
+
mutex_lock(&lcdb->lcdb_mutex);
rc = qpnp_lcdb_disable(lcdb);
if (rc < 0)
@@ -1239,11 +1338,20 @@
int rc = 0;
struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev);
- rc = qpnp_lcdb_set_voltage(lcdb, min_uV / 1000, LDO);
+ if (lcdb->secure_mode)
+ return 0;
+
+ lcdb->ldo.voltage_mv = min_uV / 1000;
+ if (lcdb->voltage_step_ramp)
+ rc = qpnp_lcdb_set_voltage_step(lcdb,
+ lcdb->ldo.prev_voltage_mv + VOLTAGE_STEP_MV, LDO);
+ else
+ rc = qpnp_lcdb_set_voltage(lcdb, lcdb->ldo.voltage_mv, LDO);
+
if (rc < 0)
pr_err("Failed to set LDO voltage rc=%c\n", rc);
else
- lcdb->ldo.voltage_mv = min_uV / 1000;
+ lcdb->ldo.prev_voltage_mv = lcdb->ldo.voltage_mv;
return rc;
}
@@ -1276,6 +1384,9 @@
int rc = 0;
struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev);
+ if (lcdb->secure_mode)
+ return 0;
+
mutex_lock(&lcdb->lcdb_mutex);
rc = qpnp_lcdb_enable(lcdb);
if (rc < 0)
@@ -1290,6 +1401,9 @@
int rc = 0;
struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev);
+ if (lcdb->secure_mode)
+ return 0;
+
mutex_lock(&lcdb->lcdb_mutex);
rc = qpnp_lcdb_disable(lcdb);
if (rc < 0)
@@ -1312,11 +1426,20 @@
int rc = 0;
struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev);
- rc = qpnp_lcdb_set_voltage(lcdb, min_uV / 1000, NCP);
- if (rc < 0)
- pr_err("Failed to set LDO voltage rc=%c\n", rc);
+ if (lcdb->secure_mode)
+ return 0;
+
+ lcdb->ncp.voltage_mv = min_uV / 1000;
+ if (lcdb->voltage_step_ramp)
+ rc = qpnp_lcdb_set_voltage_step(lcdb,
+ lcdb->ncp.prev_voltage_mv + VOLTAGE_STEP_MV, NCP);
else
- lcdb->ncp.voltage_mv = min_uV / 1000;
+ rc = qpnp_lcdb_set_voltage(lcdb, lcdb->ncp.voltage_mv, NCP);
+
+ if (rc < 0)
+ pr_err("Failed to set NCP voltage rc=%c\n", rc);
+ else
+ lcdb->ncp.prev_voltage_mv = lcdb->ncp.voltage_mv;
return rc;
}
@@ -1678,6 +1801,8 @@
return rc;
}
+ lcdb->ldo.prev_voltage_mv = lcdb->ldo.voltage_mv;
+
rc = qpnp_lcdb_read(lcdb, lcdb->base +
LCDB_LDO_VREG_OK_CTL_REG, &val, 1);
if (rc < 0) {
@@ -1783,6 +1908,8 @@
return rc;
}
+ lcdb->ncp.prev_voltage_mv = lcdb->ncp.voltage_mv;
+
rc = qpnp_lcdb_read(lcdb, lcdb->base +
LCDB_NCP_VREG_OK_CTL_REG, &val, 1);
if (rc < 0) {
@@ -1959,6 +2086,8 @@
if (lcdb->sc_irq >= 0 && !(lcdb->wa_flags & NCP_SCP_DISABLE_WA)) {
lcdb->sc_count = 0;
+ irq_set_status_flags(lcdb->sc_irq,
+ IRQ_DISABLE_UNLAZY);
rc = devm_request_threaded_irq(lcdb->dev, lcdb->sc_irq,
NULL, qpnp_lcdb_sc_irq_handler, IRQF_ONESHOT,
"qpnp_lcdb_sc_irq", lcdb);
@@ -2017,6 +2146,7 @@
}
of_node_put(revid_dev_node);
+
for_each_available_child_of_node(node, temp) {
rc = of_property_read_string(temp, "label", &label);
if (rc < 0) {
@@ -2056,9 +2186,50 @@
if (lcdb->sc_irq < 0)
pr_debug("sc irq is not defined\n");
+ lcdb->voltage_step_ramp =
+ of_property_read_bool(node, "qcom,voltage-step-ramp");
+
return rc;
}
+static ssize_t qpnp_lcdb_irq_control(struct class *c,
+ struct class_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct qpnp_lcdb *lcdb = container_of(c, struct qpnp_lcdb,
+ lcdb_class);
+ int val, rc;
+
+ rc = kstrtouint(buf, 0, &val);
+
+ if (rc < 0)
+ return rc;
+
+ if (val != 0 && val != 1)
+ return count;
+
+ if (val == 1 && !lcdb->secure_mode) {
+ if (lcdb->sc_irq > 0)
+ disable_irq(lcdb->sc_irq);
+
+ lcdb->secure_mode = true;
+ } else if (val == 0 && lcdb->secure_mode) {
+
+ if (lcdb->sc_irq > 0)
+ enable_irq(lcdb->sc_irq);
+
+ lcdb->secure_mode = false;
+ }
+
+ return count;
+}
+
+static struct class_attribute lcdb_attributes[] = {
+ [0] = __ATTR(secure_mode, 0664, NULL,
+ qpnp_lcdb_irq_control),
+ __ATTR_NULL,
+};
+
static int qpnp_lcdb_regulator_probe(struct platform_device *pdev)
{
int rc;
@@ -2098,6 +2269,16 @@
return rc;
}
+ lcdb->lcdb_class.name = "lcd_bias";
+ lcdb->lcdb_class.owner = THIS_MODULE;
+ lcdb->lcdb_class.class_attrs = lcdb_attributes;
+
+ rc = class_register(&lcdb->lcdb_class);
+ if (rc < 0) {
+ pr_err("Failed to register lcdb class rc = %d\n", rc);
+ return rc;
+ }
+
rc = qpnp_lcdb_hw_init(lcdb);
if (rc < 0)
pr_err("Failed to initialize LCDB module rc=%d\n", rc);
diff --git a/drivers/regulator/qpnp-oledb-regulator.c b/drivers/regulator/qpnp-oledb-regulator.c
index bee9a3d..03f9ab1 100644
--- a/drivers/regulator/qpnp-oledb-regulator.c
+++ b/drivers/regulator/qpnp-oledb-regulator.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -155,6 +155,7 @@
struct platform_device *pdev;
struct device *dev;
struct regmap *regmap;
+ struct class oledb_class;
struct regulator_desc rdesc;
struct regulator_dev *rdev;
struct qpnp_oledb_psm_ctl psm_ctl;
@@ -185,6 +186,7 @@
bool force_pd_control;
bool handle_lab_sc_notification;
bool lab_sc_detected;
+ bool secure_mode;
};
static const u16 oledb_warmup_dly_ns[] = {6700, 13300, 26700, 53400};
@@ -279,6 +281,9 @@
struct qpnp_oledb *oledb = rdev_get_drvdata(rdev);
+ if (oledb->secure_mode)
+ return 0;
+
if (oledb->lab_sc_detected == true) {
pr_info("Short circuit detected: Disabled OLEDB rail\n");
return 0;
@@ -342,6 +347,8 @@
struct qpnp_oledb *oledb = rdev_get_drvdata(rdev);
+ if (oledb->secure_mode)
+ return 0;
/*
* Disable ext-pin-ctl after display-supply is turned off. This is to
* avoid glitches on the external pin.
@@ -416,7 +423,7 @@
struct qpnp_oledb *oledb = rdev_get_drvdata(rdev);
- if (oledb->swire_control)
+ if (oledb->swire_control || oledb->secure_mode)
return 0;
val = DIV_ROUND_UP(min_uV - OLEDB_VOUT_MIN_MV, OLEDB_VOUT_STEP_MV);
@@ -1260,6 +1267,9 @@
struct qpnp_oledb *oledb = container_of(nb, struct qpnp_oledb,
oledb_nb);
+ if (oledb->secure_mode)
+ return 0;
+
if (action == LAB_VREG_NOT_OK) {
/* short circuit detected. Disable OLEDB module */
val = 0;
@@ -1286,6 +1296,10 @@
return NOTIFY_OK;
}
+static struct class_attribute oledb_attributes[] = {
+ [0] = __ATTR(secure_mode, 0664, NULL, NULL),
+ __ATTR_NULL,
+};
static int qpnp_oledb_regulator_probe(struct platform_device *pdev)
{
int rc = 0;
@@ -1345,6 +1359,17 @@
pr_err("Failed to register regulator rc=%d\n", rc);
goto out;
}
+
+ oledb->oledb_class.name = "amoled_bias";
+ oledb->oledb_class.owner = THIS_MODULE;
+ oledb->oledb_class.class_attrs = oledb_attributes;
+
+ rc = class_register(&oledb->oledb_class);
+ if (rc < 0) {
+ pr_err("Failed to register oledb class rc = %d\n", rc);
+ return rc;
+ }
+
pr_info("OLEDB registered successfully, ext_pin_en=%d mod_en=%d current_voltage=%d mV\n",
oledb->ext_pin_control, oledb->mod_enable,
oledb->current_voltage);
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index 162afcc..d37960e 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -359,6 +359,11 @@
{
int err;
+ if (!rtc->ops)
+ return -ENODEV;
+ else if (!rtc->ops->set_alarm)
+ return -EINVAL;
+
err = rtc_valid_tm(&alarm->time);
if (err != 0)
return err;
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index a56a7b2..5466246 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -889,6 +889,11 @@
unsigned int minor_number;
int retval = TW_IOCTL_ERROR_OS_ENODEV;
+ if (!capable(CAP_SYS_ADMIN)) {
+ retval = -EACCES;
+ goto out;
+ }
+
minor_number = iminor(inode);
if (minor_number >= twa_device_extension_count)
goto out;
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index 25aba16..24ac19e 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -1034,6 +1034,9 @@
dprintk(KERN_WARNING "3w-xxxx: tw_ioctl_open()\n");
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
minor_number = iminor(inode);
if (minor_number >= tw_device_extension_count)
return -ENODEV;
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 9d05302..19bffe0b 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -4197,6 +4197,9 @@
int irq, i, j;
int error = -ENODEV;
+ if (hba_count >= MAX_CONTROLLERS)
+ goto out;
+
if (pci_enable_device(pdev))
goto out;
pci_set_master(pdev);
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index a156451..f722a0e 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -2031,6 +2031,9 @@
pRAID_Context->timeoutValue = cpu_to_le16(os_timeout_value);
pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
} else {
+ if (os_timeout_value)
+ os_timeout_value++;
+
/* system pd Fast Path */
io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
timeout_limit = (scmd->device->type == TYPE_DISK) ?
diff --git a/drivers/scsi/scsi_dh.c b/drivers/scsi/scsi_dh.c
index a5e30e9..375cede 100644
--- a/drivers/scsi/scsi_dh.c
+++ b/drivers/scsi/scsi_dh.c
@@ -58,7 +58,10 @@
{"IBM", "3526", "rdac", },
{"IBM", "3542", "rdac", },
{"IBM", "3552", "rdac", },
- {"SGI", "TP9", "rdac", },
+ {"SGI", "TP9300", "rdac", },
+ {"SGI", "TP9400", "rdac", },
+ {"SGI", "TP9500", "rdac", },
+ {"SGI", "TP9700", "rdac", },
{"SGI", "IS", "rdac", },
{"STK", "OPENstorage", "rdac", },
{"STK", "FLEXLINE 380", "rdac", },
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 6c97870..e3dca8b 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -3445,6 +3445,7 @@
int tag;
struct completion wait;
unsigned long flags;
+ bool has_read_lock = false;
/*
* May get invoked from shutdown and IOCTL contexts.
@@ -3452,8 +3453,10 @@
* In error recovery context, it may come with lock acquired.
*/
- if (!ufshcd_is_shutdown_ongoing(hba) && !ufshcd_eh_in_progress(hba))
+ if (!ufshcd_is_shutdown_ongoing(hba) && !ufshcd_eh_in_progress(hba)) {
down_read(&hba->lock);
+ has_read_lock = true;
+ }
/*
* Get free slot, sleep if slots are unavailable.
@@ -3486,7 +3489,7 @@
out_put_tag:
ufshcd_put_dev_cmd_tag(hba, tag);
wake_up(&hba->dev_cmd.tag_wq);
- if (!ufshcd_is_shutdown_ongoing(hba) && !ufshcd_eh_in_progress(hba))
+ if (has_read_lock)
up_read(&hba->lock);
return err;
}
diff --git a/drivers/soc/qcom/bgcom_spi.c b/drivers/soc/qcom/bgcom_spi.c
index 7f8382a..c6fc2db 100644
--- a/drivers/soc/qcom/bgcom_spi.c
+++ b/drivers/soc/qcom/bgcom_spi.c
@@ -565,9 +565,11 @@
memset(fxd_mem_buffer, 0, txn_len);
tx_buf = fxd_mem_buffer;
is_cma_used = true;
- } else
+ } else {
+ pr_info("DMA memory used for size[%d]\n", txn_len);
tx_buf = dma_zalloc_coherent(&spi->dev, txn_len,
&dma_hndl, GFP_KERNEL);
+ }
if (!tx_buf) {
mutex_unlock(&cma_buffer_lock);
@@ -923,8 +925,12 @@
static irqreturn_t bg_irq_tasklet_hndlr(int irq, void *device)
{
struct bg_spi_priv *bg_spi = device;
+
/* check if call-back exists */
- if (list_empty(&cb_head)) {
+ if (!atomic_read(&bg_is_spi_active)) {
+ pr_debug("Interrupt received in suspend state\n");
+ return IRQ_HANDLED;
+ } else if (list_empty(&cb_head)) {
pr_debug("No callback registered\n");
return IRQ_HANDLED;
} else if (spi_state == BGCOM_SPI_BUSY) {
@@ -1056,6 +1062,7 @@
if (ret == 0) {
bg_spi->bg_state = BGCOM_STATE_SUSPEND;
atomic_set(&bg_is_spi_active, 0);
+ disable_irq(bg_irq);
}
pr_info("suspended with : %d\n", ret);
return ret;
@@ -1072,7 +1079,8 @@
atomic_set(&bg_is_spi_active, 1);
ret = bgcom_resume(&clnt_handle);
if (ret == 0)
- pr_info("Bgcom resumed\n");
+ enable_irq(bg_irq);
+ pr_info("Bgcom resumed with : %d\n", ret);
return ret;
}
diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c
index 7a7cdda..a7d262b 100644
--- a/drivers/soc/qcom/icnss.c
+++ b/drivers/soc/qcom/icnss.c
@@ -1170,7 +1170,8 @@
return false;
return test_bit(ICNSS_FW_DOWN, &penv->state) ||
- test_bit(ICNSS_PD_RESTART, &penv->state);
+ test_bit(ICNSS_PD_RESTART, &penv->state) ||
+ test_bit(ICNSS_REJUVENATE, &penv->state);
}
EXPORT_SYMBOL(icnss_is_fw_down);
@@ -3185,6 +3186,8 @@
int icnss_get_soc_info(struct device *dev, struct icnss_soc_info *info)
{
+ char *fw_build_timestamp = NULL;
+
if (!penv || !dev) {
icnss_pr_err("Platform driver not initialized\n");
return -EINVAL;
@@ -3197,6 +3200,8 @@
info->board_id = penv->board_info.board_id;
info->soc_id = penv->soc_info.soc_id;
info->fw_version = penv->fw_version_info.fw_version;
+ fw_build_timestamp = penv->fw_version_info.fw_build_timestamp;
+ fw_build_timestamp[QMI_WLFW_MAX_TIMESTAMP_LEN_V01] = '\0';
strlcpy(info->fw_build_timestamp,
penv->fw_version_info.fw_build_timestamp,
QMI_WLFW_MAX_TIMESTAMP_LEN_V01 + 1);
diff --git a/drivers/soc/qcom/memory_dump_v2.c b/drivers/soc/qcom/memory_dump_v2.c
index 5912ff2..5459f35 100644
--- a/drivers/soc/qcom/memory_dump_v2.c
+++ b/drivers/soc/qcom/memory_dump_v2.c
@@ -140,7 +140,7 @@
dmac_flush_range(table, (void *)table + sizeof(struct msm_dump_table));
- if (msm_dump_data_add_minidump(entry))
+ if (msm_dump_data_add_minidump(entry) < 0)
pr_err("Failed to add entry in Minidump table\n");
return 0;
diff --git a/drivers/soc/qcom/minidump_log.c b/drivers/soc/qcom/minidump_log.c
index 87e1700..ff4a79c 100644
--- a/drivers/soc/qcom/minidump_log.c
+++ b/drivers/soc/qcom/minidump_log.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -37,7 +37,7 @@
md_entry.virt_addr = (uintptr_t) (*log_bufp);
md_entry.phys_addr = virt_to_phys(*log_bufp);
md_entry.size = *log_buf_lenp;
- if (msm_minidump_add_region(&md_entry))
+ if (msm_minidump_add_region(&md_entry) < 0)
pr_err("Failed to add logbuf in Minidump\n");
}
@@ -53,7 +53,7 @@
ksec_entry.virt_addr = (uintptr_t)_sdata;
ksec_entry.phys_addr = virt_to_phys(_sdata);
ksec_entry.size = roundup((__bss_stop - _sdata), 4);
- if (msm_minidump_add_region(&ksec_entry))
+ if (msm_minidump_add_region(&ksec_entry) < 0)
pr_err("Failed to add data section in Minidump\n");
/* Add percpu static sections */
@@ -66,7 +66,7 @@
ksec_entry.virt_addr = (uintptr_t)start;
ksec_entry.phys_addr = per_cpu_ptr_to_phys(start);
ksec_entry.size = static_size;
- if (msm_minidump_add_region(&ksec_entry))
+ if (msm_minidump_add_region(&ksec_entry) < 0)
pr_err("Failed to add percpu sections in Minidump\n");
}
}
@@ -87,14 +87,14 @@
ksp_entry.virt_addr = sp;
ksp_entry.phys_addr = virt_to_phys((uintptr_t *)sp);
ksp_entry.size = THREAD_SIZE;
- if (msm_minidump_add_region(&ksp_entry))
+ if (msm_minidump_add_region(&ksp_entry) < 0)
pr_err("Failed to add stack of cpu %d in Minidump\n", cpu);
scnprintf(ktsk_entry.name, sizeof(ktsk_entry.name), "KTASK%d", cpu);
ktsk_entry.virt_addr = (u64)current;
ktsk_entry.phys_addr = virt_to_phys((uintptr_t *)current);
ktsk_entry.size = sizeof(struct task_struct);
- if (msm_minidump_add_region(&ktsk_entry))
+ if (msm_minidump_add_region(&ktsk_entry) < 0)
pr_err("Failed to add current task %d in Minidump\n", cpu);
}
diff --git a/drivers/soc/qcom/msm_minidump.c b/drivers/soc/qcom/msm_minidump.c
index 3644dd6..309af6c 100644
--- a/drivers/soc/qcom/msm_minidump.c
+++ b/drivers/soc/qcom/msm_minidump.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -40,7 +40,7 @@
struct md_ss_toc *md_ss_toc;
struct md_global_toc *md_gbl_toc;
struct md_ss_region *md_regions;
- struct md_region entry[MAX_NUM_ENTRIES];
+ struct md_region entry[MAX_NUM_ENTRIES];
};
/**
@@ -169,17 +169,10 @@
}
EXPORT_SYMBOL(msm_minidump_enabled);
-int msm_minidump_add_region(const struct md_region *entry)
+static inline int validate_region(const struct md_region *entry)
{
- u32 entries;
- struct md_region *mdr;
- int ret = 0;
-
- if (!entry)
- return -EINVAL;
-
- if ((strlen(entry->name) > MAX_NAME_LENGTH) ||
- md_check_name(entry->name) || !entry->virt_addr) {
+ if (!entry || (strlen(entry->name) > MAX_NAME_LENGTH) ||
+ !entry->virt_addr) {
pr_err("Invalid entry details\n");
return -EINVAL;
}
@@ -188,6 +181,55 @@
pr_err("size should be 4 byte aligned\n");
return -EINVAL;
}
+ return 0;
+}
+
+int msm_minidump_update_region(int regno, const struct md_region *entry)
+{
+ struct md_region *mdr;
+ struct md_ss_region *mdssr;
+ struct elfhdr *hdr = minidump_elfheader.ehdr;
+ struct elf_shdr *shdr;
+ struct elf_phdr *phdr;
+
+ if (validate_region(entry) || (regno >= MAX_NUM_ENTRIES))
+ return -EINVAL;
+
+ if (!md_check_name(entry->name)) {
+ pr_err("Region:[%s] does not exist to update.\n", entry->name);
+ return -ENOMEM;
+ }
+
+ mdr = &minidump_table.entry[regno];
+ mdr->virt_addr = entry->virt_addr;
+ mdr->phys_addr = entry->phys_addr;
+
+ mdssr = &minidump_table.md_regions[regno + 1];
+ mdssr->region_base_address = entry->phys_addr;
+
+ shdr = elf_section(hdr, regno + 4);
+ phdr = elf_program(hdr, regno + 1);
+
+ shdr->sh_addr = (elf_addr_t)entry->virt_addr;
+ phdr->p_vaddr = entry->virt_addr;
+ phdr->p_paddr = entry->phys_addr;
+
+ return 0;
+}
+EXPORT_SYMBOL(msm_minidump_update_region);
+
+int msm_minidump_add_region(const struct md_region *entry)
+{
+ u32 entries;
+ struct md_region *mdr;
+
+ if (validate_region(entry))
+ return -EINVAL;
+
+ if (md_check_name(entry->name)) {
+ pr_err("Region name [%s] already registered\n", entry->name);
+ return -EEXIST;
+ }
spin_lock(&mdt_lock);
entries = minidump_table.num_regions;
@@ -215,7 +257,7 @@
spin_unlock(&mdt_lock);
- return ret;
+ return entries;
}
EXPORT_SYMBOL(msm_minidump_add_region);
diff --git a/drivers/soc/qcom/service-locator.c b/drivers/soc/qcom/service-locator.c
index 5abc093..1c2be3f 100644
--- a/drivers/soc/qcom/service-locator.c
+++ b/drivers/soc/qcom/service-locator.c
@@ -252,7 +252,6 @@
req->domain_offset_valid = true;
req->domain_offset = 0;
- pd->domain_list = NULL;
do {
req->domain_offset += domains_read;
rc = servreg_loc_send_msg(&req_desc, &resp_desc, req, resp,
@@ -282,6 +281,7 @@
pr_err("Service Locator DB updated for client %s\n",
pd->client_name);
kfree(pd->domain_list);
+ pd->domain_list = NULL;
rc = -EAGAIN;
goto out;
}
@@ -381,7 +381,7 @@
goto err;
}
- pqcd = kmalloc(sizeof(struct pd_qmi_client_data), GFP_KERNEL);
+ pqcd = kzalloc(sizeof(struct pd_qmi_client_data), GFP_KERNEL);
if (!pqcd) {
rc = -ENOMEM;
pr_err("Allocation failed\n");
@@ -422,7 +422,7 @@
pr_err("Unable to connect to service locator!, rc = %d\n", rc);
pdqw->notifier->notifier_call(pdqw->notifier,
LOCATOR_DOWN, NULL);
- goto err;
+ goto err_init_servloc;
}
rc = service_locator_send_msg(data);
if (rc) {
@@ -430,11 +430,13 @@
data->service_name, data->client_name, rc);
pdqw->notifier->notifier_call(pdqw->notifier,
LOCATOR_DOWN, NULL);
- goto err;
+ goto err_servloc_send_msg;
}
pdqw->notifier->notifier_call(pdqw->notifier, LOCATOR_UP, data);
-err:
+err_servloc_send_msg:
+ kfree(data->domain_list);
+err_init_servloc:
kfree(data);
kfree(pdqw);
}
diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c
index f6a28c0..e78a49a 100644
--- a/drivers/soc/qcom/socinfo.c
+++ b/drivers/soc/qcom/socinfo.c
@@ -602,6 +602,9 @@
/* SDM710 ID */
[360] = {MSM_CPU_SDM710, "SDM710"},
+ /* SDMNOBELIUM ID */
+ [393] = {MSM_CPU_SDMNOBELIUM, "SDMNOBELIUM"},
+
/* SXR1120 ID */
[370] = {MSM_CPU_SXR1120, "SXR1120"},
@@ -627,6 +630,9 @@
[308] = {MSM_CPU_8917, "MSM8217"},
[309] = {MSM_CPU_8917, "MSM8617"},
+ /* MSM8940 IDs */
+ [313] = {MSM_CPU_8940, "MSM8940"},
+
/* SDM429 and SDM439 ID*/
[353] = {MSM_CPU_SDM439, "SDM439"},
[354] = {MSM_CPU_SDM429, "SDM429"},
@@ -1554,6 +1560,10 @@
dummy_socinfo.id = 360;
strlcpy(dummy_socinfo.build_id, "sdm710 - ",
sizeof(dummy_socinfo.build_id));
+ } else if (early_machine_is_sdmnobelium()) {
+ dummy_socinfo.id = 393;
+ strlcpy(dummy_socinfo.build_id, "sdmnobelium - ",
+ sizeof(dummy_socinfo.build_id));
} else if (early_machine_is_sda670()) {
dummy_socinfo.id = 337;
strlcpy(dummy_socinfo.build_id, "sda670 - ",
@@ -1586,10 +1596,18 @@
dummy_socinfo.id = 303;
strlcpy(dummy_socinfo.build_id, "msm8917 - ",
sizeof(dummy_socinfo.build_id));
+ } else if (early_machine_is_msm8940()) {
+ dummy_socinfo.id = 313;
+ strlcpy(dummy_socinfo.build_id, "msm8940 - ",
+ sizeof(dummy_socinfo.build_id));
} else if (early_machine_is_sdm450()) {
dummy_socinfo.id = 338;
strlcpy(dummy_socinfo.build_id, "sdm450 - ",
sizeof(dummy_socinfo.build_id));
+ } else if (early_machine_is_sda450()) {
+ dummy_socinfo.id = 351;
+ strlcpy(dummy_socinfo.build_id, "sda450 - ",
+ sizeof(dummy_socinfo.build_id));
} else if (early_machine_is_sdm632()) {
dummy_socinfo.id = 349;
strlcpy(dummy_socinfo.build_id, "sdm632 - ",
diff --git a/drivers/soc/qcom/subsys-pil-bg.c b/drivers/soc/qcom/subsys-pil-bg.c
index 818e91e..4f5e4d4 100644
--- a/drivers/soc/qcom/subsys-pil-bg.c
+++ b/drivers/soc/qcom/subsys-pil-bg.c
@@ -193,6 +193,9 @@
struct tzapp_bg_req *bg_tz_req;
struct tzapp_bg_rsp *bg_tz_rsp;
int rc, req_len, rsp_len;
+ unsigned char *ascii;
+ char fiwmare_version[100] = {'\0'};
+ char ascii_string[5];
/* Fill command structure */
req_len = sizeof(struct tzapp_bg_req);
@@ -218,10 +221,16 @@
if (req->tzapp_bg_cmd == BGPIL_GET_BG_VERSION) {
int i;
- pr_info("BG FW ver ");
- for (i = 0; i < bg_tz_rsp->bg_info_len; i++)
+ pr_info("BG FW version ");
+ for (i = 0; i < bg_tz_rsp->bg_info_len; i++) {
pr_info("0x%08x ", bg_tz_rsp->bg_info[i]);
- pr_info("\n");
+ ascii = (unsigned char *)&bg_tz_rsp->bg_info[i];
+ snprintf(ascii_string, PAGE_SIZE, "%c%c%c%c", ascii[0],
+ ascii[1], ascii[2], ascii[3]);
+ strlcat(fiwmare_version, ascii_string,
+ PAGE_SIZE);
+ }
+ pr_info("%s\n", fiwmare_version);
}
end:
return rc;
diff --git a/drivers/soc/qcom/subsystem_restart.c b/drivers/soc/qcom/subsystem_restart.c
index f20eda2..4aac534 100644
--- a/drivers/soc/qcom/subsystem_restart.c
+++ b/drivers/soc/qcom/subsystem_restart.c
@@ -61,7 +61,7 @@
#define setup_timeout(dest_ss, source_ss, comm_type) \
_setup_timeout(dest_ss, source_ss, comm_type)
-#define cancel_timeout(subsys) del_timer(&subsys->timeout_data.timer)
+#define cancel_timeout(subsys) del_timer_sync(&subsys->timeout_data.timer)
#define init_subsys_timer(subsys) _init_subsys_timer(subsys)
/* Timeout values */
diff --git a/drivers/soc/qcom/watchdog_v2.c b/drivers/soc/qcom/watchdog_v2.c
index b924bc8..30672a37 100644
--- a/drivers/soc/qcom/watchdog_v2.c
+++ b/drivers/soc/qcom/watchdog_v2.c
@@ -885,7 +885,7 @@
md_entry.virt_addr = (uintptr_t)wdog_dd;
md_entry.phys_addr = virt_to_phys(wdog_dd);
md_entry.size = sizeof(*wdog_dd);
- if (msm_minidump_add_region(&md_entry))
+ if (msm_minidump_add_region(&md_entry) < 0)
pr_info("Failed to add Watchdog data in Minidump\n");
return 0;
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 0f0b7ba..a26b289 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -685,19 +685,26 @@
if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
type.type |= bit_mask_irq;
if (flow_type & IRQF_TRIGGER_RISING)
- type.polarity_high |= bit_mask_irq;
+ type.polarity_high |= bit_mask_irq;
+ else
+ type.polarity_high &= ~bit_mask_irq;
if (flow_type & IRQF_TRIGGER_FALLING)
- type.polarity_low |= bit_mask_irq;
+ type.polarity_low |= bit_mask_irq;
+ else
+ type.polarity_low &= ~bit_mask_irq;
} else {
if ((flow_type & (IRQF_TRIGGER_HIGH)) &&
(flow_type & (IRQF_TRIGGER_LOW)))
return -EINVAL;
type.type &= ~bit_mask_irq; /* level trig */
- if (flow_type & IRQF_TRIGGER_HIGH)
- type.polarity_high |= bit_mask_irq;
- else
- type.polarity_low |= bit_mask_irq;
+ if (flow_type & IRQF_TRIGGER_HIGH) {
+ type.polarity_high |= bit_mask_irq;
+ type.polarity_low &= ~bit_mask_irq;
+ } else {
+ type.polarity_low |= bit_mask_irq;
+ type.polarity_high &= ~bit_mask_irq;
+ }
}
qpnpint_spmi_write(d, QPNPINT_REG_SET_TYPE, &type, sizeof(type));
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index 9995a84..eb73b8b 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -3,7 +3,7 @@
* drivers/staging/android/ion/ion.c
*
* Copyright (C) 2011 Google, Inc.
- * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -603,10 +603,12 @@
if (!((1 << heap->id) & heap_id_mask))
continue;
trace_ion_alloc_buffer_start(client->name, heap->name, len,
- heap_id_mask, flags);
+ heap_id_mask, flags, client->pid, current->comm,
+ current->pid, (void *)buffer);
buffer = ion_buffer_create(heap, dev, len, align, flags);
trace_ion_alloc_buffer_end(client->name, heap->name, len,
- heap_id_mask, flags);
+ heap_id_mask, flags, client->pid, current->comm,
+ current->pid, (void *)buffer);
if (!IS_ERR(buffer))
break;
@@ -713,6 +715,9 @@
WARN(1, "%s: User does not have access!\n", __func__);
return;
}
+ trace_ion_free_buffer(client->name, client->pid, current->comm,
+ current->pid, (void *)handle->buffer,
+ handle->buffer->size);
user_ion_handle_put_nolock(handle);
}
diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c
index d991b02..831c334 100644
--- a/drivers/staging/android/ion/ion_cma_heap.c
+++ b/drivers/staging/android/ion/ion_cma_heap.c
@@ -4,7 +4,7 @@
* Copyright (C) Linaro 2012
* Author: <benjamin.gaignard@linaro.org> for ST-Ericsson.
*
- * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -386,14 +386,37 @@
return ret;
}
+static void *ion_secure_cma_map_kernel(struct ion_heap *heap,
+ struct ion_buffer *buffer)
+{
+ if (!is_buffer_hlos_assigned(buffer)) {
+ pr_info("%s: Mapping non-HLOS accessible buffer disallowed\n",
+ __func__);
+ return NULL;
+ }
+ return ion_cma_map_kernel(heap, buffer);
+}
+
+static int ion_secure_cma_map_user(struct ion_heap *mapper,
+ struct ion_buffer *buffer,
+ struct vm_area_struct *vma)
+{
+ if (!is_buffer_hlos_assigned(buffer)) {
+ pr_info("%s: Mapping non-HLOS accessible buffer disallowed\n",
+ __func__);
+ return -EINVAL;
+ }
+ return ion_cma_mmap(mapper, buffer, vma);
+}
+
static struct ion_heap_ops ion_secure_cma_ops = {
.allocate = ion_secure_cma_allocate,
.free = ion_secure_cma_free,
.map_dma = ion_cma_heap_map_dma,
.unmap_dma = ion_cma_heap_unmap_dma,
.phys = ion_cma_phys,
- .map_user = ion_cma_mmap,
- .map_kernel = ion_cma_map_kernel,
+ .map_user = ion_secure_cma_map_user,
+ .map_kernel = ion_secure_cma_map_kernel,
.unmap_kernel = ion_cma_unmap_kernel,
.print_debug = ion_cma_print_debug,
};
diff --git a/drivers/staging/android/ion/ion_page_pool.c b/drivers/staging/android/ion/ion_page_pool.c
index 38d4175..5709434 100644
--- a/drivers/staging/android/ion/ion_page_pool.c
+++ b/drivers/staging/android/ion/ion_page_pool.c
@@ -2,7 +2,7 @@
* drivers/staging/android/ion/ion_page_pool.c
*
* Copyright (C) 2011 Google, Inc.
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016, 2018 The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -65,6 +65,9 @@
list_add_tail(&page->lru, &pool->low_items);
pool->low_count++;
}
+
+ mod_node_page_state(page_pgdat(page), NR_INDIRECTLY_RECLAIMABLE_BYTES,
+ (1 << (PAGE_SHIFT + pool->order)));
mutex_unlock(&pool->mutex);
return 0;
}
@@ -84,6 +87,8 @@
}
list_del(&page->lru);
+ mod_node_page_state(page_pgdat(page), NR_INDIRECTLY_RECLAIMABLE_BYTES,
+ -(1 << (PAGE_SHIFT + pool->order)));
return page;
}
diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c
index 3b27252..5c71628 100644
--- a/drivers/staging/android/ion/ion_system_heap.c
+++ b/drivers/staging/android/ion/ion_system_heap.c
@@ -102,6 +102,11 @@
return total << PAGE_SHIFT;
}
+static int ion_heap_is_system_heap_type(enum ion_heap_type type)
+{
+ return type == ((enum ion_heap_type)ION_HEAP_TYPE_SYSTEM);
+}
+
static struct page *alloc_buffer_page(struct ion_system_heap *heap,
struct ion_buffer *buffer,
unsigned long order,
@@ -357,6 +362,13 @@
int vmid = get_secure_vmid(buffer->flags);
struct device *dev = heap->priv;
+ if (ion_heap_is_system_heap_type(buffer->heap->type) &&
+ is_secure_vmid_valid(vmid)) {
+ pr_info("%s: System heap doesn't support secure allocations\n",
+ __func__);
+ return -EINVAL;
+ }
+
if (align > PAGE_SIZE)
return -EINVAL;
@@ -469,7 +481,7 @@
err_free_sg2:
/* We failed to zero buffers. Bypass pool */
- buffer->flags |= ION_PRIV_FLAG_SHRINKER_FREE;
+ buffer->private_flags |= ION_PRIV_FLAG_SHRINKER_FREE;
if (vmid > 0)
ion_system_secure_heap_unassign_sg(table, vmid);
diff --git a/drivers/staging/android/ion/ion_system_secure_heap.c b/drivers/staging/android/ion/ion_system_secure_heap.c
index 5bf484b..cf86ea2 100644
--- a/drivers/staging/android/ion/ion_system_secure_heap.c
+++ b/drivers/staging/android/ion/ion_system_secure_heap.c
@@ -1,6 +1,6 @@
/*
*
- * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2016,2018 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -171,14 +171,15 @@
sys_heap->ops->free(&buffer);
}
-static void process_one_shrink(struct ion_heap *sys_heap,
+static void process_one_shrink(struct ion_system_secure_heap *secure_heap,
+ struct ion_heap *sys_heap,
struct prefetch_info *info)
{
struct ion_buffer buffer;
size_t pool_size, size;
int ret;
- buffer.heap = sys_heap;
+ buffer.heap = &secure_heap->heap;
buffer.flags = info->vmid;
pool_size = ion_system_heap_secure_page_pool_total(sys_heap,
@@ -193,6 +194,7 @@
}
buffer.private_flags = ION_PRIV_FLAG_SHRINKER_FREE;
+ buffer.heap = sys_heap;
sys_heap->ops->free(&buffer);
}
@@ -212,7 +214,7 @@
spin_unlock_irqrestore(&secure_heap->work_lock, flags);
if (info->shrink)
- process_one_shrink(sys_heap, info);
+ process_one_shrink(secure_heap, sys_heap, info);
else
process_one_prefetch(sys_heap, info);
diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
index ea9a0c2..4ff2931 100644
--- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
+++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
@@ -1299,11 +1299,6 @@
goto failed2;
}
- LASSERT(cmid->device);
- CDEBUG(D_NET, "%s: connection bound to %s:%pI4h:%s\n",
- libcfs_nid2str(peer->ibp_nid), dev->ibd_ifname,
- &dev->ibd_ifip, cmid->device->name);
-
return;
failed2:
@@ -3005,8 +3000,19 @@
} else {
rc = rdma_resolve_route(
cmid, *kiblnd_tunables.kib_timeout * 1000);
- if (!rc)
+ if (!rc) {
+ struct kib_net *net = peer->ibp_ni->ni_data;
+ struct kib_dev *dev = net->ibn_dev;
+
+ CDEBUG(D_NET, "%s: connection bound to "\
+ "%s:%pI4h:%s\n",
+ libcfs_nid2str(peer->ibp_nid),
+ dev->ibd_ifname,
+ &dev->ibd_ifip, cmid->device->name);
+
return 0;
+ }
+
/* Can't initiate route resolution */
CERROR("Can't resolve route for %s: %d\n",
libcfs_nid2str(peer->ibp_nid), rc);
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
index d18ab3f..9addcdb 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
@@ -1489,8 +1489,10 @@
return ERR_CAST(res);
lock = ldlm_lock_new(res);
- if (!lock)
+ if (!lock) {
+ ldlm_resource_putref(res);
return ERR_PTR(-ENOMEM);
+ }
lock->l_req_mode = mode;
lock->l_ast_data = data;
@@ -1533,6 +1535,8 @@
return ERR_PTR(rc);
}
+
+
/**
* Enqueue (request) a lock.
* On the client this is called from ldlm_cli_enqueue_fini
diff --git a/drivers/staging/lustre/lustre/llite/xattr.c b/drivers/staging/lustre/lustre/llite/xattr.c
index e070adb..57121fd 100644
--- a/drivers/staging/lustre/lustre/llite/xattr.c
+++ b/drivers/staging/lustre/lustre/llite/xattr.c
@@ -103,7 +103,11 @@
__u64 valid;
int rc;
- if (flags == XATTR_REPLACE) {
+ /* When setxattr() is called with a size of 0 the value is
+ * unconditionally replaced by "". When removexattr() is
+ * called we get a NULL value and XATTR_REPLACE for flags.
+ */
+ if (!value && flags == XATTR_REPLACE) {
ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_REMOVEXATTR, 1);
valid = OBD_MD_FLXATTRRM;
} else {
diff --git a/drivers/thermal/qcom/qti_virtual_sensor.c b/drivers/thermal/qcom/qti_virtual_sensor.c
index f01658d..1fa8ca4 100644
--- a/drivers/thermal/qcom/qti_virtual_sensor.c
+++ b/drivers/thermal/qcom/qti_virtual_sensor.c
@@ -102,6 +102,16 @@
"cpuss1-usr"},
.logic = VIRT_MAXIMUM,
},
+ {
+ .virt_zone_name = "penta-cpu-max-step",
+ .num_sensors = 5,
+ .sensor_names = {"apc1-cpu0-usr",
+ "apc1-cpu1-usr",
+ "apc1-cpu2-usr",
+ "apc1-cpu3-usr",
+ "cpuss-usr"},
+ .logic = VIRT_MAXIMUM,
+ },
};
int qti_virtual_sensor_register(struct device *dev)
diff --git a/drivers/thermal/qpnp-adc-tm.c b/drivers/thermal/qpnp-adc-tm.c
index 5d345cc..fbab52f 100644
--- a/drivers/thermal/qpnp-adc-tm.c
+++ b/drivers/thermal/qpnp-adc-tm.c
@@ -361,6 +361,7 @@
[SCALE_R_ABSOLUTE] = {qpnp_adc_absolute_rthr},
[SCALE_QRD_SKUH_RBATT_THERM] = {qpnp_adc_qrd_skuh_btm_scaler},
[SCALE_QRD_SKUT1_RBATT_THERM] = {qpnp_adc_qrd_skut1_btm_scaler},
+ [SCALE_QRD_215_RBATT_THERM] = {qpnp_adc_qrd_215_btm_scaler},
};
static int32_t qpnp_adc_tm_read_reg(struct qpnp_adc_tm_chip *chip,
diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index a45810b..c974cb5 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -598,6 +598,7 @@
threshold_code = temp_to_code(data, temp);
rising_threshold = readl(data->base + rising_reg_offset);
+ rising_threshold &= ~(0xff << j * 8);
rising_threshold |= (threshold_code << j * 8);
writel(rising_threshold, data->base + rising_reg_offset);
diff --git a/drivers/tty/hvc/hvc_opal.c b/drivers/tty/hvc/hvc_opal.c
index 5107993..1fc5d5b 100644
--- a/drivers/tty/hvc/hvc_opal.c
+++ b/drivers/tty/hvc/hvc_opal.c
@@ -332,7 +332,6 @@
udbg_putc = udbg_opal_putc;
udbg_getc = udbg_opal_getc;
udbg_getc_poll = udbg_opal_getc_poll;
- tb_ticks_per_usec = 0x200; /* Make udelay not suck */
}
void __init hvc_opal_init_early(void)
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c
index 2b90738..171130a 100644
--- a/drivers/tty/pty.c
+++ b/drivers/tty/pty.c
@@ -106,16 +106,19 @@
static int pty_write(struct tty_struct *tty, const unsigned char *buf, int c)
{
struct tty_struct *to = tty->link;
+ unsigned long flags;
if (tty->stopped)
return 0;
if (c > 0) {
+ spin_lock_irqsave(&to->port->lock, flags);
/* Stuff the data into the input queue of the other end */
c = tty_insert_flip_string(to->port, buf, c);
/* And shovel */
if (c)
tty_flip_buffer_push(to->port);
+ spin_unlock_irqrestore(&to->port->lock, flags);
}
return c;
}
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 08bef18..a9c950d 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -1785,6 +1785,9 @@
{ USB_DEVICE(0x09d8, 0x0320), /* Elatec GmbH TWN3 */
.driver_info = NO_UNION_NORMAL, /* has misplaced union descriptor */
},
+ { USB_DEVICE(0x0ca6, 0xa050), /* Castles VEGA3000 */
+ .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
+ },
{ USB_DEVICE(0x2912, 0x0001), /* ATOL FPrint */
.driver_info = CLEAR_HALT_CONDITIONS,
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 771efc9..7f0811f 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1150,10 +1150,14 @@
if (!udev || udev->state == USB_STATE_NOTATTACHED) {
/* Tell hub_wq to disconnect the device or
- * check for a new connection
+ * check for a new connection or over current condition.
+ * Based on USB2.0 Spec Section 11.12.5,
+ * C_PORT_OVER_CURRENT could be set while
+ * PORT_OVER_CURRENT is not. So check for any of them.
*/
if (udev || (portstatus & USB_PORT_STAT_CONNECTION) ||
- (portstatus & USB_PORT_STAT_OVERCURRENT))
+ (portstatus & USB_PORT_STAT_OVERCURRENT) ||
+ (portchange & USB_PORT_STAT_C_OVERCURRENT))
set_bit(port1, hub->change_bits);
} else if (portstatus & USB_PORT_STAT_ENABLE) {
@@ -3370,6 +3374,10 @@
while (delay_ms < 2000) {
if (status || *portstatus & USB_PORT_STAT_CONNECTION)
break;
+ if (!port_is_power_on(hub, *portstatus)) {
+ status = -ENODEV;
+ break;
+ }
msleep(20);
delay_ms += 20;
status = hub_port_status(hub, *port1, portstatus, portchange);
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 40ce175..99f6776 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -231,6 +231,10 @@
/* Corsair K70 RGB */
{ USB_DEVICE(0x1b1c, 0x1b13), .driver_info = USB_QUIRK_DELAY_INIT },
+ /* Corsair Strafe */
+ { USB_DEVICE(0x1b1c, 0x1b15), .driver_info = USB_QUIRK_DELAY_INIT |
+ USB_QUIRK_DELAY_CTRL_MSG },
+
/* Corsair Strafe RGB */
{ USB_DEVICE(0x1b1c, 0x1b20), .driver_info = USB_QUIRK_DELAY_INIT |
USB_QUIRK_DELAY_CTRL_MSG },
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 0a0cf15..984d6aa 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -2544,34 +2544,29 @@
#define DWC2_USB_DMA_ALIGN 4
-struct dma_aligned_buffer {
- void *kmalloc_ptr;
- void *old_xfer_buffer;
- u8 data[0];
-};
-
static void dwc2_free_dma_aligned_buffer(struct urb *urb)
{
- struct dma_aligned_buffer *temp;
+ void *stored_xfer_buffer;
if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER))
return;
- temp = container_of(urb->transfer_buffer,
- struct dma_aligned_buffer, data);
+ /* Restore urb->transfer_buffer from the end of the allocated area */
+ memcpy(&stored_xfer_buffer, urb->transfer_buffer +
+ urb->transfer_buffer_length, sizeof(urb->transfer_buffer));
if (usb_urb_dir_in(urb))
- memcpy(temp->old_xfer_buffer, temp->data,
+ memcpy(stored_xfer_buffer, urb->transfer_buffer,
urb->transfer_buffer_length);
- urb->transfer_buffer = temp->old_xfer_buffer;
- kfree(temp->kmalloc_ptr);
+ kfree(urb->transfer_buffer);
+ urb->transfer_buffer = stored_xfer_buffer;
urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER;
}
static int dwc2_alloc_dma_aligned_buffer(struct urb *urb, gfp_t mem_flags)
{
- struct dma_aligned_buffer *temp, *kmalloc_ptr;
+ void *kmalloc_ptr;
size_t kmalloc_size;
if (urb->num_sgs || urb->sg ||
@@ -2579,22 +2574,29 @@
!((uintptr_t)urb->transfer_buffer & (DWC2_USB_DMA_ALIGN - 1)))
return 0;
- /* Allocate a buffer with enough padding for alignment */
+ /*
+ * Allocate a buffer with enough padding for original transfer_buffer
+ * pointer. This allocation is guaranteed to be aligned properly for
+ * DMA
+ */
kmalloc_size = urb->transfer_buffer_length +
- sizeof(struct dma_aligned_buffer) + DWC2_USB_DMA_ALIGN - 1;
+ sizeof(urb->transfer_buffer);
kmalloc_ptr = kmalloc(kmalloc_size, mem_flags);
if (!kmalloc_ptr)
return -ENOMEM;
- /* Position our struct dma_aligned_buffer such that data is aligned */
- temp = PTR_ALIGN(kmalloc_ptr + 1, DWC2_USB_DMA_ALIGN) - 1;
- temp->kmalloc_ptr = kmalloc_ptr;
- temp->old_xfer_buffer = urb->transfer_buffer;
+ /*
+ * Position value of original urb->transfer_buffer pointer to the end
+ * of allocation for later referencing
+ */
+ memcpy(kmalloc_ptr + urb->transfer_buffer_length,
+ &urb->transfer_buffer, sizeof(urb->transfer_buffer));
+
if (usb_urb_dir_out(urb))
- memcpy(temp->data, urb->transfer_buffer,
+ memcpy(kmalloc_ptr, urb->transfer_buffer,
urb->transfer_buffer_length);
- urb->transfer_buffer = temp->data;
+ urb->transfer_buffer = kmalloc_ptr;
urb->transfer_flags |= URB_ALIGNED_TEMP_BUFFER;
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index d53dc92..dcc183d 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -2329,7 +2329,14 @@
return -EBUSY;
}
- if (!mdwc->in_host_mode && (mdwc->vbus_active && !mdwc->suspend)) {
+ /*
+ * Check if remote wakeup is received and pending before going
+ * ahead with suspend routine as part of device bus suspend.
+ */
+
+ if (!mdwc->in_host_mode && (mdwc->vbus_active &&
+ (mdwc->otg_state == OTG_STATE_B_SUSPEND ||
+ mdwc->otg_state == OTG_STATE_B_PERIPHERAL) && !mdwc->suspend)) {
dev_dbg(mdwc->dev,
"Received wakeup event before the core suspend\n");
mutex_unlock(&mdwc->suspend_resume_mutex);
@@ -3862,6 +3869,11 @@
mdwc->core_clk_rate_hs);
mdwc->max_rh_port_speed = USB_SPEED_HIGH;
} else {
+ clk_set_rate(mdwc->core_clk,
+ mdwc->core_clk_rate);
+ dev_dbg(mdwc->dev,
+ "set ss core clk rate %ld\n",
+ mdwc->core_clk_rate);
mdwc->max_rh_port_speed = USB_SPEED_SUPER;
}
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 703fb24..2e300a3 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -3541,6 +3541,9 @@
hw_device_state(udc->ep0out.qh.dma);
} else {
hw_device_state(0);
+ spin_unlock_irqrestore(udc->lock, flags);
+ _gadget_stop_activity(&udc->gadget);
+ spin_lock_irqsave(udc->lock, flags);
}
spin_unlock_irqrestore(udc->lock, flags);
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 8bdbf5f..5306eff 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -2511,7 +2511,13 @@
f->func_wakeup_pending = 0;
}
- if (gadget->speed != USB_SPEED_SUPER && f->resume)
+ /*
+ * Call function resume irrespective of the speed.
+ * Individual function needs to retain the USB3 Function
+ * suspend state through out the Device suspend entry
+ * and exit process.
+ */
+ if (f->resume)
f->resume(f);
}
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index 6fe4fc5..15c67c1 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -3733,7 +3733,7 @@
ffs_log("exit");
- return USB_GADGET_DELAYED_STATUS;
+ return creq->wLength == 0 ? USB_GADGET_DELAYED_STATUS : 0;
}
static bool ffs_func_req_match(struct usb_function *f,
diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c
index 0065c06..726b1aa 100644
--- a/drivers/usb/gadget/function/f_gsi.c
+++ b/drivers/usb/gadget/function/f_gsi.c
@@ -1083,9 +1083,11 @@
ipa_resume_work_handler(d_port);
d_port->sm_state = STATE_CONNECTED;
} else if (event == EVT_DISCONNECTED) {
+ usb_gadget_autopm_get(d_port->gadget);
ipa_disconnect_work_handler(d_port);
d_port->sm_state = STATE_INITIALIZED;
log_event_dbg("%s: ST_SUS_EVT_DIS", __func__);
+ usb_gadget_autopm_put_async(d_port->gadget);
}
break;
default:
@@ -1393,7 +1395,7 @@
ctrl_device);
struct f_gsi *gsi;
struct gsi_ctrl_pkt *cpkt;
- struct ep_info info;
+ struct ep_info info = { {0} };
int val, ret = 0;
unsigned long flags;
diff --git a/drivers/usb/gadget/function/f_gsi.h b/drivers/usb/gadget/function/f_gsi.h
index 5231213..683d6c5 100644
--- a/drivers/usb/gadget/function/f_gsi.h
+++ b/drivers/usb/gadget/function/f_gsi.h
@@ -39,7 +39,7 @@
#define GSI_GPS_CTRL_NAME "gps"
#define GSI_CTRL_NAME_LEN (sizeof(GSI_MBIM_CTRL_NAME)+2)
-#define GSI_MAX_CTRL_PKT_SIZE 4096
+#define GSI_MAX_CTRL_PKT_SIZE 8192
#define GSI_CTRL_DTR (1 << 0)
#define GSI_NUM_IN_RNDIS_BUFFERS 50
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 040feda..6b71b45 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -650,7 +650,7 @@
if (!ep->stream_info)
return NULL;
- if (stream_id > ep->stream_info->num_streams)
+ if (stream_id >= ep->stream_info->num_streams)
return NULL;
return ep->stream_info->stream_rings[stream_id];
}
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index ccad0be..3d05a44 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -934,6 +934,41 @@
spin_unlock_irqrestore(&xhci->lock, flags);
}
+static bool xhci_pending_portevent(struct xhci_hcd *xhci)
+{
+ __le32 __iomem **port_array;
+ int port_index;
+ u32 status;
+ u32 portsc;
+
+ status = readl(&xhci->op_regs->status);
+ if (status & STS_EINT)
+ return true;
+ /*
+ * Checking STS_EINT is not enough as there is a lag between a change
+ * bit being set and the Port Status Change Event that it generated
+ * being written to the Event Ring. See note in xhci 1.1 section 4.19.2.
+ */
+
+ port_index = xhci->num_usb2_ports;
+ port_array = xhci->usb2_ports;
+ while (port_index--) {
+ portsc = readl(port_array[port_index]);
+ if (portsc & PORT_CHANGE_MASK ||
+ (portsc & PORT_PLS_MASK) == XDEV_RESUME)
+ return true;
+ }
+ port_index = xhci->num_usb3_ports;
+ port_array = xhci->usb3_ports;
+ while (port_index--) {
+ portsc = readl(port_array[port_index]);
+ if (portsc & PORT_CHANGE_MASK ||
+ (portsc & PORT_PLS_MASK) == XDEV_RESUME)
+ return true;
+ }
+ return false;
+}
+
/*
* Stop HC (not bus-specific)
*
@@ -1031,7 +1066,7 @@
*/
int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
{
- u32 command, temp = 0, status;
+ u32 command, temp = 0;
struct usb_hcd *hcd = xhci_to_hcd(xhci);
struct usb_hcd *secondary_hcd;
int retval = 0;
@@ -1153,8 +1188,7 @@
done:
if (retval == 0) {
/* Resume root hubs only when have pending events. */
- status = readl(&xhci->op_regs->status);
- if (status & STS_EINT) {
+ if (xhci_pending_portevent(xhci)) {
usb_hcd_resume_root_hub(xhci->shared_hcd);
usb_hcd_resume_root_hub(hcd);
}
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index a5153ca..39068a7 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -385,6 +385,10 @@
#define PORT_PLC (1 << 22)
/* port configure error change - port failed to configure its link partner */
#define PORT_CEC (1 << 23)
+#define PORT_CHANGE_MASK (PORT_CSC | PORT_PEC | PORT_WRC | PORT_OCC | \
+ PORT_RC | PORT_PLC | PORT_CEC)
+
+
/* Cold Attach Status - xHC can set this bit to report device attached during
* Sx state. Warm port reset should be perfomed to clear this bit and move port
* to connected state.
diff --git a/drivers/usb/misc/yurex.c b/drivers/usb/misc/yurex.c
index 54e53ac..f36968e 100644
--- a/drivers/usb/misc/yurex.c
+++ b/drivers/usb/misc/yurex.c
@@ -406,8 +406,7 @@
loff_t *ppos)
{
struct usb_yurex *dev;
- int retval = 0;
- int bytes_read = 0;
+ int len = 0;
char in_buffer[20];
unsigned long flags;
@@ -415,26 +414,16 @@
mutex_lock(&dev->io_mutex);
if (!dev->interface) { /* already disconnected */
- retval = -ENODEV;
- goto exit;
+ mutex_unlock(&dev->io_mutex);
+ return -ENODEV;
}
spin_lock_irqsave(&dev->lock, flags);
- bytes_read = snprintf(in_buffer, 20, "%lld\n", dev->bbu);
+ len = snprintf(in_buffer, 20, "%lld\n", dev->bbu);
spin_unlock_irqrestore(&dev->lock, flags);
-
- if (*ppos < bytes_read) {
- if (copy_to_user(buffer, in_buffer + *ppos, bytes_read - *ppos))
- retval = -EFAULT;
- else {
- retval = bytes_read - *ppos;
- *ppos += bytes_read;
- }
- }
-
-exit:
mutex_unlock(&dev->io_mutex);
- return retval;
+
+ return simple_read_from_buffer(buffer, count, ppos, in_buffer, len);
}
static ssize_t yurex_write(struct file *file, const char __user *user_buffer,
diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c
index 10d11ac..1a95910 100644
--- a/drivers/usb/pd/policy_engine.c
+++ b/drivers/usb/pd/policy_engine.c
@@ -2101,7 +2101,8 @@
/* Disconnect? */
if (pd->current_pr == PR_NONE) {
- if (pd->current_state == PE_UNKNOWN)
+ if (pd->current_state == PE_UNKNOWN &&
+ pd->current_dr == DR_NONE)
goto sm_done;
if (pd->vconn_enabled) {
diff --git a/drivers/usb/phy/phy-msm-ssusb-qmp.c b/drivers/usb/phy/phy-msm-ssusb-qmp.c
index 5b734be..4360e89 100644
--- a/drivers/usb/phy/phy-msm-ssusb-qmp.c
+++ b/drivers/usb/phy/phy-msm-ssusb-qmp.c
@@ -23,6 +23,7 @@
#include <linux/regulator/consumer.h>
#include <linux/usb/phy.h>
#include <linux/clk.h>
+#include <linux/extcon.h>
#include <linux/reset.h>
enum ldo_levels {
@@ -133,6 +134,8 @@
struct reset_control *phy_reset;
struct reset_control *phy_phy_reset;
struct reset_control *global_phy_reset;
+ struct extcon_dev *extcon_dp;
+ struct notifier_block dp_nb;
bool power_enabled;
bool clk_enabled;
bool cable_connected;
@@ -377,9 +380,12 @@
switch (phy->phy.type) {
case USB_PHY_TYPE_USB3_AND_DP:
/* override hardware control for reset of qmp phy */
- writel_relaxed(SW_DPPHY_RESET_MUX | SW_DPPHY_RESET |
- SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET,
- phy->base + phy->phy_reg[USB3_DP_COM_RESET_OVRD_CTRL]);
+ if (!(phy->phy.flags & PHY_USB_DP_CONCURRENT_MODE)) {
+ writel_relaxed(SW_DPPHY_RESET_MUX | SW_DPPHY_RESET |
+ SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET,
+ phy->base +
+ phy->phy_reg[USB3_DP_COM_RESET_OVRD_CTRL]);
+ }
/* update port select */
if (val > 0) {
@@ -389,12 +395,16 @@
phy->phy_reg[USB3_DP_COM_TYPEC_CTRL]);
}
- writel_relaxed(USB3_MODE | DP_MODE,
- phy->base + phy->phy_reg[USB3_DP_COM_PHY_MODE_CTRL]);
+ if (!(phy->phy.flags & PHY_USB_DP_CONCURRENT_MODE)) {
+ writel_relaxed(USB3_MODE | DP_MODE,
+ phy->base +
+ phy->phy_reg[USB3_DP_COM_PHY_MODE_CTRL]);
- /* bring both QMP USB and QMP DP PHYs PCS block out of reset */
- writel_relaxed(0x00,
- phy->base + phy->phy_reg[USB3_DP_COM_RESET_OVRD_CTRL]);
+ /* bring both USB and DP PHYs PCS block out of reset */
+ writel_relaxed(0x00,
+ phy->base +
+ phy->phy_reg[USB3_DP_COM_RESET_OVRD_CTRL]);
+ }
break;
case USB_PHY_TYPE_USB3_OR_DP:
if (val > 0) {
@@ -485,7 +495,8 @@
}
/* perform software reset of PHY common logic */
- if (phy->phy.type == USB_PHY_TYPE_USB3_AND_DP)
+ if (phy->phy.type == USB_PHY_TYPE_USB3_AND_DP &&
+ !(phy->phy.flags & PHY_USB_DP_CONCURRENT_MODE))
writel_relaxed(0x00,
phy->base + phy->phy_reg[USB3_DP_COM_SW_RESET]);
@@ -523,6 +534,25 @@
phy);
int ret = 0;
+ if (phy->phy.flags & PHY_USB_DP_CONCURRENT_MODE) {
+ dev_dbg(uphy->dev, "Resetting USB part of QMP phy\n");
+
+ /* Assert USB3 PHY CSR reset */
+ ret = reset_control_assert(phy->phy_reset);
+ if (ret) {
+ dev_err(uphy->dev, "phy_reset assert failed\n");
+ goto exit;
+ }
+
+ /* Deassert USB3 PHY CSR reset */
+ ret = reset_control_deassert(phy->phy_reset);
+ if (ret) {
+ dev_err(uphy->dev, "phy_reset deassert failed\n");
+ goto exit;
+ }
+ return 0;
+ }
+
dev_dbg(uphy->dev, "Global reset of QMP DP combo phy\n");
/* Assert global PHY reset */
ret = reset_control_assert(phy->global_phy_reset);
@@ -716,6 +746,49 @@
return 0;
}
+static int msm_ssphy_qmp_dp_notifier(struct notifier_block *nb,
+ unsigned long dp_lane, void *ptr)
+{
+ struct msm_ssphy_qmp *phy = container_of(nb,
+ struct msm_ssphy_qmp, dp_nb);
+
+ if (dp_lane == 2 || dp_lane == 4)
+ phy->phy.flags |= PHY_USB_DP_CONCURRENT_MODE;
+ else
+ phy->phy.flags &= ~PHY_USB_DP_CONCURRENT_MODE;
+
+ return 0;
+
+}
+
+static int msm_ssphy_qmp_extcon_register(struct msm_ssphy_qmp *phy,
+ struct device *dev)
+{
+ struct device_node *node = dev->of_node;
+ struct extcon_dev *edev;
+ int ret = 0;
+
+ if (!of_property_read_bool(node, "extcon"))
+ return 0;
+
+ edev = extcon_get_edev_by_phandle(dev, 0);
+ if (IS_ERR(edev)) {
+ dev_err(dev, "failed to get phandle for msm_ssphy_qmp\n");
+ return PTR_ERR(edev);
+ }
+
+ phy->extcon_dp = edev;
+ phy->dp_nb.notifier_call = msm_ssphy_qmp_dp_notifier;
+ ret = extcon_register_blocking_notifier(edev, EXTCON_DISP_DP,
+ &phy->dp_nb);
+ if (ret < 0) {
+ dev_err(dev, "failed to register blocking notifier\n");
+ return ret;
+ }
+
+ return 0;
+}
+
static int msm_ssphy_qmp_get_clks(struct msm_ssphy_qmp *phy, struct device *dev)
{
int ret = 0;
@@ -1065,6 +1138,10 @@
else
phy->phy.reset = msm_ssphy_qmp_reset;
+ ret = msm_ssphy_qmp_extcon_register(phy, dev);
+ if (ret)
+ goto err;
+
ret = usb_add_phy_dev(&phy->phy);
err:
diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c
index 44c917d..43e558b 100644
--- a/drivers/usb/phy/phy-msm-usb.c
+++ b/drivers/usb/phy/phy-msm-usb.c
@@ -3676,6 +3676,11 @@
struct extcon_dev *edev;
int ret = 0;
+ if (motg->extcon_registered) {
+ dev_info(&motg->pdev->dev, "extcon_nb already registered\n");
+ return 0;
+ }
+
if (!of_property_read_bool(node, "extcon"))
return 0;
@@ -3712,6 +3717,7 @@
goto err;
}
}
+ motg->extcon_registered = true;
return 0;
err:
@@ -4312,7 +4318,7 @@
INIT_DELAYED_WORK(&motg->sdp_check, check_for_sdp_connection);
INIT_WORK(&motg->notify_charger_work, msm_otg_notify_charger_work);
INIT_WORK(&motg->extcon_register_work, msm_otg_extcon_register_work);
- motg->otg_wq = alloc_ordered_workqueue("k_otg", 0);
+ motg->otg_wq = alloc_ordered_workqueue("k_otg", WQ_FREEZABLE);
if (!motg->otg_wq) {
pr_err("%s: Unable to create workqueue otg_wq\n",
__func__);
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c
index e98590a..9a2c0c7 100644
--- a/drivers/usb/serial/ch341.c
+++ b/drivers/usb/serial/ch341.c
@@ -118,7 +118,7 @@
r = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), request,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
value, index, buf, bufsize, DEFAULT_TIMEOUT);
- if (r < bufsize) {
+ if (r < (int)bufsize) {
if (r >= 0) {
dev_err(&dev->dev,
"short control message received (%d < %u)\n",
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 71a8ede..39709fe 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -146,6 +146,7 @@
{ USB_DEVICE(0x10C4, 0x8977) }, /* CEL MeshWorks DevKit Device */
{ USB_DEVICE(0x10C4, 0x8998) }, /* KCF Technologies PRN */
{ USB_DEVICE(0x10C4, 0x89A4) }, /* CESINEL FTBC Flexible Thyristor Bridge Controller */
+ { USB_DEVICE(0x10C4, 0x89FB) }, /* Qivicon ZigBee USB Radio Stick */
{ USB_DEVICE(0x10C4, 0x8A2A) }, /* HubZ dual ZigBee and Z-Wave dongle */
{ USB_DEVICE(0x10C4, 0x8A5E) }, /* CEL EM3588 ZigBee USB Stick Long Range */
{ USB_DEVICE(0x10C4, 0x8B34) }, /* Qivicon ZigBee USB Radio Stick */
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index d2dab2a..d17f787 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -373,8 +373,10 @@
3, /* get pins */
USB_TYPE_VENDOR|USB_RECIP_INTERFACE|USB_DIR_IN,
0, 0, data, 1, 2000);
- if (rc >= 0)
+ if (rc == 1)
*value = *data;
+ else if (rc >= 0)
+ rc = -EIO;
kfree(data);
return rc;
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index 6baacf6..03d63ba 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -482,6 +482,9 @@
}
dev_dbg(dev, "%s urb buffer size is %d\n", __func__, urb->actual_length);
+ if (urb->actual_length < 1)
+ goto out;
+
dev_dbg(dev, "%s mos7840_port->MsrLsr is %d port %d\n", __func__,
mos7840_port->MsrLsr, mos7840_port->port_num);
data = urb->transfer_buffer;
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index 43559be..7338e43 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -28,6 +28,7 @@
#include <linux/uaccess.h>
#include <linux/vfio.h>
#include <linux/vgaarb.h>
+#include <linux/nospec.h>
#include "vfio_pci_private.h"
@@ -755,6 +756,9 @@
if (info.index >=
VFIO_PCI_NUM_REGIONS + vdev->num_regions)
return -EINVAL;
+ info.index = array_index_nospec(info.index,
+ VFIO_PCI_NUM_REGIONS +
+ vdev->num_regions);
i = info.index - VFIO_PCI_NUM_REGIONS;
diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c
index d781428..d143d08 100644
--- a/drivers/vfio/platform/vfio_platform_common.c
+++ b/drivers/vfio/platform/vfio_platform_common.c
@@ -696,18 +696,23 @@
group = vfio_iommu_group_get(dev);
if (!group) {
pr_err("VFIO: No IOMMU group for device %s\n", vdev->name);
- return -EINVAL;
+ ret = -EINVAL;
+ goto put_reset;
}
ret = vfio_add_group_dev(dev, &vfio_platform_ops, vdev);
- if (ret) {
- vfio_iommu_group_put(group, dev);
- return ret;
- }
+ if (ret)
+ goto put_iommu;
mutex_init(&vdev->igate);
return 0;
+
+put_iommu:
+ vfio_iommu_group_put(group, dev);
+put_reset:
+ vfio_platform_put_reset(vdev);
+ return ret;
}
EXPORT_SYMBOL_GPL(vfio_platform_probe_common);
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 487586e..353c93b 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -1052,7 +1052,8 @@
if (ubufs)
vhost_net_ubuf_put_wait_and_free(ubufs);
err_ubufs:
- sockfd_put(sock);
+ if (sock)
+ sockfd_put(sock);
err_vq:
mutex_unlock(&vq->mutex);
err:
diff --git a/drivers/video/fbdev/msm/mdp3.c b/drivers/video/fbdev/msm/mdp3.c
index 5e9e49c..903a083 100644
--- a/drivers/video/fbdev/msm/mdp3.c
+++ b/drivers/video/fbdev/msm/mdp3.c
@@ -1812,7 +1812,8 @@
pr_err("invalid bus handle %d\n", bus_handle->handle);
return -EINVAL;
}
- mdp3_calc_dma_res(panel_info, &mdp_clk_rate, &ab, &ib, panel_info->bpp);
+ mdp3_calc_dma_res(panel_info, &mdp_clk_rate, &ab,
+ &ib, MAX_BPP_SUPPORTED);
mdp3_clk_set_rate(MDP3_CLK_VSYNC, MDP_VSYNC_CLK_RATE,
MDP3_CLIENT_DMA_P);
@@ -1968,6 +1969,8 @@
int rc;
struct mdss_data_type *mdata;
struct mdss_debug_data *mdd;
+ struct mdss_debug_base *mdp_dbg_blk = NULL;
+ struct mdss_debug_base *vbif_dbg_blk = NULL;
mdata = devm_kzalloc(&pdev->dev, sizeof(*mdata), GFP_KERNEL);
if (!mdata)
@@ -1996,8 +1999,27 @@
debugfs_create_file("stat", 0644, mdd->root, mdp3_res,
&mdp3_debug_dump_stats_fops);
- rc = mdss_debug_register_base(NULL, mdp3_res->mdp_base,
- mdp3_res->mdp_reg_size, NULL);
+ /* MDP Debug base registration */
+ rc = mdss_debug_register_base("mdp", mdp3_res->mdp_base,
+ mdp3_res->mdp_reg_size, &mdp_dbg_blk);
+ if (rc)
+ return rc;
+
+ mdss_debug_register_dump_range(pdev, mdp_dbg_blk, "qcom,regs-dump-mdp",
+ "qcom,regs-dump-names-mdp", "qcom,regs-dump-xin-id-mdp");
+
+
+ /* VBIF Debug base registration */
+ if (mdp3_res->vbif_base) {
+ rc = mdss_debug_register_base("vbif", mdp3_res->vbif_base,
+ mdp3_res->vbif_reg_size, &vbif_dbg_blk);
+ if (rc)
+ return rc;
+
+ mdss_debug_register_dump_range(pdev, vbif_dbg_blk,
+ "qcom,regs-dump-vbif", "qcom,regs-dump-names-vbif",
+ "qcom,regs-dump-xin-id-vbif");
+ }
return rc;
}
diff --git a/drivers/video/fbdev/msm/mdp3_ctrl.c b/drivers/video/fbdev/msm/mdp3_ctrl.c
index c976c0e..defec0b 100644
--- a/drivers/video/fbdev/msm/mdp3_ctrl.c
+++ b/drivers/video/fbdev/msm/mdp3_ctrl.c
@@ -32,8 +32,6 @@
#include "mdss_spi_panel.h"
#include "mdss_sync.h"
-#define VSYNC_EXPIRE_TICK 4
-
static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd);
static int mdp3_overlay_unset(struct msm_fb_data_type *mfd, int ndx);
static int mdp3_histogram_stop(struct mdp3_session_data *session,
@@ -188,7 +186,8 @@
return;
mutex_lock(&session->lock);
- MDSS_XLOG(0x111);
+ MDSS_XLOG(0x111, atomic_read(&session->vsync_countdown),
+ session->dma->vsync_period);
if (session->vsync_enabled ||
atomic_read(&session->vsync_countdown) > 0) {
mutex_unlock(&session->lock);
@@ -206,14 +205,14 @@
if (session->intf->active) {
retry_dma_done:
rc = wait_for_completion_timeout(&session->dma_completion,
- WAIT_DMA_TIMEOUT);
- MDSS_XLOG(0x222);
+ dma_timeout_value(session->dma));
if (rc <= 0) {
struct mdss_panel_data *panel;
panel = session->panel;
pr_debug("cmd kickoff timed out (%d)\n", rc);
dmap_busy = session->dma->busy();
+ MDSS_XLOG(0x222, dmap_busy);
if (dmap_busy) {
if (--retry_count) {
pr_err("dmap is busy, retry %d\n",
@@ -222,7 +221,7 @@
goto retry_dma_done;
}
pr_err("dmap is still busy, bug_on\n");
- WARN_ON(1);
+ BUG_ON(1);
} else {
pr_debug("dmap is not busy, continue\n");
}
@@ -303,10 +302,13 @@
struct mdp3_session_data *session = (struct mdp3_session_data *)arg;
/* We are counting down to turn off clocks */
- if (atomic_read(&session->vsync_countdown) > 0)
+ if (atomic_read(&session->vsync_countdown) > 0) {
atomic_dec(&session->vsync_countdown);
- if (atomic_read(&session->vsync_countdown) == 0)
- schedule_work(&session->clk_off_work);
+ MDSS_XLOG(atomic_read(&session->vsync_countdown),
+ session->dma->vsync_period);
+ if (atomic_read(&session->vsync_countdown) == 0)
+ schedule_work(&session->clk_off_work);
+ }
}
void mdp3_ctrl_reset_countdown(struct mdp3_session_data *session,
@@ -314,6 +316,8 @@
{
if (mdp3_ctrl_get_intf_type(mfd) == MDP3_DMA_OUTPUT_SEL_DSI_CMD)
atomic_set(&session->vsync_countdown, VSYNC_EXPIRE_TICK);
+
+ MDSS_XLOG(atomic_read(&session->vsync_countdown));
}
static int mdp3_ctrl_vsync_enable(struct msm_fb_data_type *mfd, int enable)
@@ -378,7 +382,7 @@
*/
if (mod_vsync_timer && (intf_type != MDP3_DMA_OUTPUT_SEL_SPI_CMD)) {
mod_timer(&mdp3_session->vsync_timer,
- jiffies + msecs_to_jiffies(mdp3_session->vsync_period));
+ jiffies + msecs_to_jiffies(mdp3_session->dma->vsync_period));
} else if (enable && !mdp3_session->clk_on) {
mdp3_ctrl_reset_countdown(mdp3_session, mfd);
mdp3_ctrl_clk_enable(mfd, 1);
@@ -398,7 +402,7 @@
pr_debug("mdp3_vsync_timer_func trigger\n");
vsync_notify_handler(session);
mod_timer(&session->vsync_timer,
- jiffies + msecs_to_jiffies(session->vsync_period));
+ jiffies + msecs_to_jiffies(session->dma->vsync_period));
}
}
@@ -905,6 +909,7 @@
int rc = 0;
struct mdp3_session_data *mdp3_session;
struct mdss_panel_data *panel;
+ u32 framerate = 0;
pr_debug("mdp3_ctrl_on\n");
mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1;
@@ -1027,7 +1032,7 @@
mdp3_session->status = 1;
mdp3_ctrl_pp_resume(mfd);
- MDSS_XLOG(XLOG_FUNC_EXIT, __LINE__, mfd->panel_power_state);
+
on_error:
if (rc || (mdp3_res->idle_pc_enabled &&
(mfd->panel_info->type == MIPI_CMD_PANEL))) {
@@ -1038,6 +1043,12 @@
pm_runtime_put(&mdp3_res->pdev->dev);
}
end:
+ framerate = mdss_panel_get_framerate(mfd->panel_info,
+ FPS_RESOLUTION_HZ);
+ if (framerate != 0)
+ mdp3_session->dma->vsync_period = DIV_ROUND_UP(1000, framerate);
+
+ MDSS_XLOG(XLOG_FUNC_EXIT, __LINE__, mfd->panel_power_state, framerate);
mutex_unlock(&mdp3_session->lock);
return rc;
}
@@ -1054,6 +1065,7 @@
bool intf_stopped = true;
struct mdp3_session_data *mdp3_session;
struct mdss_panel_data *panel;
+ u32 framerate = 0;
pr_debug("mdp3_ctrl_off\n");
mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1;
@@ -1242,7 +1254,13 @@
mdp3_session->overlay.id = MSMFB_NEW_REQUEST;
mdp3_bufq_deinit(&mdp3_session->bufq_in, client);
}
- MDSS_XLOG(XLOG_FUNC_EXIT, __LINE__);
+
+ framerate = mdss_panel_get_framerate(mfd->panel_info,
+ FPS_RESOLUTION_HZ);
+ if (framerate != 0)
+ mdp3_session->dma->vsync_period = DIV_ROUND_UP(1000, framerate);
+
+ MDSS_XLOG(XLOG_FUNC_EXIT, __LINE__, framerate);
mutex_unlock(&mdp3_session->lock);
/* Release the last reference to the runtime device */
pm_runtime_put(&mdp3_res->pdev->dev);
@@ -1511,6 +1529,7 @@
struct mdss_panel_data *panel;
int frame_rate = DEFAULT_FRAME_RATE;
int stride;
+ int prev_bl;
if (!mfd || !mfd->mdp.private1)
return -EINVAL;
@@ -1528,22 +1547,6 @@
return -EPERM;
}
- if (panel_info->partial_update_enabled &&
- is_roi_valid(mdp3_session->dma->source_config,
- cmt_data->l_roi) &&
- update_roi(mdp3_session->dma->roi, cmt_data->l_roi)) {
- mdp3_session->dma->roi.x = cmt_data->l_roi.x;
- mdp3_session->dma->roi.y = cmt_data->l_roi.y;
- mdp3_session->dma->roi.w = cmt_data->l_roi.w;
- mdp3_session->dma->roi.h = cmt_data->l_roi.h;
- mdp3_session->dma->update_src_cfg = true;
- pr_debug("%s: ROI: x=%d y=%d w=%d h=%d\n", __func__,
- mdp3_session->dma->roi.x,
- mdp3_session->dma->roi.y,
- mdp3_session->dma->roi.w,
- mdp3_session->dma->roi.h);
- }
-
panel = mdp3_session->panel;
mutex_lock(&mdp3_res->fs_idle_pc_lock);
if (mdp3_session->in_splash_screen ||
@@ -1556,6 +1559,9 @@
mutex_unlock(&mdp3_res->fs_idle_pc_lock);
return -EINVAL;
}
+ if ((mdp3_session->dma->roi.x || mdp3_session->dma->roi.y) &&
+ panel_info->partial_update_enabled)
+ mdp3_session->dma->update_src_cfg = true;
}
mutex_unlock(&mdp3_res->fs_idle_pc_lock);
@@ -1567,7 +1573,8 @@
mutex_unlock(&mdp3_session->lock);
return -EPERM;
}
- MDSS_XLOG(0x111);
+ MDSS_XLOG(0x111, mdp3_session->dma->vsync_period);
+
mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_BEGIN);
data = mdp3_bufq_pop(&mdp3_session->bufq_in);
if (data) {
@@ -1637,9 +1644,15 @@
}
mdp3_session->vsync_before_commit = 0;
+ prev_bl = mfd->bl_level;
if (!splash_done || mdp3_session->esd_recovery == true) {
- if (panel && panel->set_backlight)
- panel->set_backlight(panel, panel->panel_info.bl_max);
+ if (panel && panel->set_backlight) {
+ if (mdp3_session->esd_recovery == true && prev_bl > 0)
+ panel->set_backlight(panel, prev_bl);
+ else
+ panel->set_backlight(panel,
+ panel->panel_info.bl_max);
+ }
splash_done = true;
mdp3_session->esd_recovery = false;
}
@@ -2894,7 +2907,7 @@
if (session->dma_active) {
rc = wait_for_completion_timeout(&session->dma_completion,
- KOFF_TIMEOUT);
+ dma_timeout_value(session->dma));
if (rc > 0) {
session->dma_active = 0;
rc = 0;
@@ -2963,14 +2976,17 @@
return -ENOMEM;
}
- /* Add retire vsync handler */
- retire_client.handler = mdp3_vsync_retire_handle_vsync;
- retire_client.arg = mdp3_session;
+ if (mfd->panel_info->type == MIPI_CMD_PANEL) {
+ /* Add retire vsync handler */
+ retire_client.handler = mdp3_vsync_retire_handle_vsync;
+ retire_client.arg = mdp3_session;
- if (mdp3_session->dma)
- mdp3_session->dma->retire_client = retire_client;
+ if (mdp3_session->dma)
+ mdp3_session->dma->retire_client = retire_client;
- INIT_WORK(&mdp3_session->retire_work, mdp3_vsync_retire_work_handler);
+ INIT_WORK(&mdp3_session->retire_work,
+ mdp3_vsync_retire_work_handler);
+ }
return 0;
}
@@ -3071,7 +3087,11 @@
init_timer(&mdp3_session->vsync_timer);
mdp3_session->vsync_timer.function = mdp3_vsync_timer_func;
mdp3_session->vsync_timer.data = (u32)mdp3_session;
- mdp3_session->vsync_period = 1000 / frame_rate;
+
+ if (frame_rate != 0)
+ mdp3_session->dma->vsync_period =
+ DIV_ROUND_UP(1000, frame_rate);
+
mfd->mdp.private1 = mdp3_session;
init_completion(&mdp3_session->dma_completion);
if (intf_type != MDP3_DMA_OUTPUT_SEL_DSI_VIDEO ||
@@ -3145,13 +3165,10 @@
mdp3_session->vsync_before_commit = true;
mdp3_session->dyn_pu_state = mfd->panel_info->partial_update_enabled;
- if (mfd->panel_info->mipi.dms_mode ||
- mfd->panel_info->type == MIPI_CMD_PANEL) {
- rc = mdp3_vsync_retire_setup(mfd);
- if (IS_ERR_VALUE(rc)) {
- pr_err("unable to create vsync timeline\n");
- goto init_done;
- }
+ rc = mdp3_vsync_retire_setup(mfd);
+ if (IS_ERR_VALUE(rc)) {
+ pr_err("unable to create vsync timeline\n");
+ goto init_done;
}
init_done:
if (IS_ERR_VALUE(rc))
diff --git a/drivers/video/fbdev/msm/mdp3_ctrl.h b/drivers/video/fbdev/msm/mdp3_ctrl.h
index 5193af1..64be356 100644
--- a/drivers/video/fbdev/msm/mdp3_ctrl.h
+++ b/drivers/video/fbdev/msm/mdp3_ctrl.h
@@ -45,7 +45,6 @@
struct msm_fb_data_type *mfd;
ktime_t vsync_time;
struct timer_list vsync_timer;
- int vsync_period;
struct kernfs_node *vsync_event_sd;
struct kernfs_node *bl_event_sd;
struct mdp_overlay overlay;
diff --git a/drivers/video/fbdev/msm/mdp3_dma.c b/drivers/video/fbdev/msm/mdp3_dma.c
index b223c87..c9356bd 100644
--- a/drivers/video/fbdev/msm/mdp3_dma.c
+++ b/drivers/video/fbdev/msm/mdp3_dma.c
@@ -36,7 +36,13 @@
struct mdp3_notification retire_client;
unsigned int wait_for_next_vs;
+ if (!dma) {
+ pr_err("dma is null\n");
+ return;
+ }
+
pr_debug("mdp3_vsync_intr_handler\n");
+ MDSS_XLOG(0x111, dma->vsync_period);
spin_lock(&dma->dma_lock);
vsync_client = dma->vsync_client;
retire_client = dma->retire_client;
@@ -61,6 +67,11 @@
struct mdp3_dma *dma = (struct mdp3_dma *)arg;
struct mdp3_notification dma_client;
+ if (!dma) {
+ pr_err("dma is null\n");
+ return;
+ }
+
pr_debug("mdp3_dma_done_intr_handler\n");
spin_lock(&dma->dma_lock);
dma_client = dma->dma_notifier_client;
@@ -76,6 +87,11 @@
struct mdp3_dma *dma = (struct mdp3_dma *)arg;
u32 isr, mask;
+ if (!dma) {
+ pr_err("dma is null\n");
+ return;
+ }
+
isr = MDP3_REG_READ(MDP3_REG_DMA_P_HIST_INTR_STATUS);
mask = MDP3_REG_READ(MDP3_REG_DMA_P_HIST_INTR_ENABLE);
MDP3_REG_WRITE(MDP3_REG_DMA_P_HIST_INTR_CLEAR, isr);
@@ -674,7 +690,7 @@
ATRACE_BEGIN("mdp3_wait_for_dma_comp");
retry_dma_done:
rc = wait_for_completion_timeout(&dma->dma_comp,
- KOFF_TIMEOUT);
+ dma_timeout_value(dma));
if (rc <= 0 && --retry_count) {
int vsync_status;
@@ -735,7 +751,7 @@
ATRACE_BEGIN("mdp3_wait_for_vsync_comp");
retry_vsync:
rc = wait_for_completion_timeout(&dma->vsync_comp,
- KOFF_TIMEOUT);
+ dma_timeout_value(dma));
if (rc <= 0 && --retry_count) {
int vsync = MDP3_REG_READ(MDP3_REG_INTR_STATUS) &
(1 << MDP3_INTR_LCDC_START_OF_FRAME);
diff --git a/drivers/video/fbdev/msm/mdp3_dma.h b/drivers/video/fbdev/msm/mdp3_dma.h
index ec327b6..e0458f8 100644
--- a/drivers/video/fbdev/msm/mdp3_dma.h
+++ b/drivers/video/fbdev/msm/mdp3_dma.h
@@ -25,6 +25,7 @@
#define MDP_HISTOGRAM_CSC_VECTOR_MAX 0x200
#define MDP_HISTOGRAM_BIN_NUM 32
#define MDP_LUT_SIZE 256
+#define VSYNC_EXPIRE_TICK 4
enum {
MDP3_DMA_P,
@@ -255,6 +256,7 @@
u32 capability;
int in_use;
int available;
+ int vsync_period;
spinlock_t dma_lock;
spinlock_t histo_lock;
@@ -384,6 +386,14 @@
int (*stop)(struct mdp3_intf *intf);
};
+static inline unsigned long dma_timeout_value(struct mdp3_dma *dma)
+{
+ if (dma->vsync_period)
+ return msecs_to_jiffies(VSYNC_EXPIRE_TICK * dma->vsync_period);
+ else
+ return msecs_to_jiffies(84);
+}
+
int mdp3_dma_init(struct mdp3_dma *dma);
int mdp3_intf_init(struct mdp3_intf *intf);
diff --git a/drivers/video/fbdev/msm/mdss_debug.c b/drivers/video/fbdev/msm/mdss_debug.c
index 86f3bce..bdf3b7a 100644
--- a/drivers/video/fbdev/msm/mdss_debug.c
+++ b/drivers/video/fbdev/msm/mdss_debug.c
@@ -456,6 +456,39 @@
return 0;
}
+/**
+ * mdss_debug_base_is_valid_range - verify if requested memory range is valid
+ * @off: address offset in bytes
+ * @cnt: memory size in bytes
+ * Return: true if valid; false otherwise
+ */
+static bool mdss_debug_base_is_valid_range(u32 off, u32 cnt)
+{
+ struct mdss_data_type *mdata = mdss_mdp_get_mdata();
+ struct mdss_debug_data *mdd = mdata->debug_inf.debug_data;
+ struct range_dump_node *node;
+ struct mdss_debug_base *base;
+
+ pr_debug("check offset=0x%x cnt=0x%x\n", off, cnt);
+
+ list_for_each_entry(base, &mdd->base_list, head) {
+ list_for_each_entry(node, &base->dump_list, head) {
+ pr_debug("%s: start=0x%x end=0x%x\n", node->range_name,
+ node->offset.start, node->offset.end);
+
+ if (node->offset.start <= off
+ && off <= node->offset.end
+ && off + cnt <= node->offset.end) {
+ pr_debug("valid range requested\n");
+ return true;
+ }
+ }
+ }
+
+ pr_err("invalid range requested\n");
+ return false;
+}
+
static ssize_t mdss_debug_base_offset_write(struct file *file,
const char __user *user_buf, size_t count, loff_t *ppos)
{
@@ -487,6 +520,9 @@
if (cnt > (dbg->max_offset - off))
cnt = dbg->max_offset - off;
+ if (!mdss_debug_base_is_valid_range(off, cnt))
+ return -EINVAL;
+
mutex_lock(&mdss_debug_lock);
dbg->off = off;
dbg->cnt = cnt;
diff --git a/drivers/video/fbdev/msm/mdss_debug_xlog.c b/drivers/video/fbdev/msm/mdss_debug_xlog.c
index ed00fc5..fbc46674 100644
--- a/drivers/video/fbdev/msm/mdss_debug_xlog.c
+++ b/drivers/video/fbdev/msm/mdss_debug_xlog.c
@@ -486,8 +486,8 @@
}
}
- if (!from_isr)
- mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);
+ if (!from_isr && mdata->debug_inf.debug_enable_clock)
+ mdata->debug_inf.debug_enable_clock(MDP_BLOCK_POWER_ON);
for (i = 0; i < len; i++) {
u32 x0, x4, x8, xc;
@@ -511,8 +511,8 @@
addr += 16;
}
- if (!from_isr)
- mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF);
+ if (!from_isr && mdata->debug_inf.debug_enable_clock)
+ mdata->debug_inf.debug_enable_clock(MDP_BLOCK_POWER_OFF);
}
static void mdss_dump_reg_by_ranges(struct mdss_debug_base *dbg,
diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c
index b4e4bdd..5d8398e 100644
--- a/drivers/video/fbdev/msm/mdss_dsi.c
+++ b/drivers/video/fbdev/msm/mdss_dsi.c
@@ -1951,6 +1951,9 @@
return;
}
+ if (ctrl_pdata->timing_db_mode)
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x1e8, 0x1);
+
vsync_period =
mdss_panel_get_vtotal(&pdata->panel_info);
hsync_period =
@@ -1960,23 +1963,13 @@
new_dsi_v_total =
((vsync_period - 1) << 16) | (hsync_period - 1);
- MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x2C,
- (current_dsi_v_total | 0x8000000));
- if (new_dsi_v_total & 0x8000000) {
- MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x2C,
- new_dsi_v_total);
- } else {
- MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x2C,
- (new_dsi_v_total | 0x8000000));
- MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x2C,
- (new_dsi_v_total & 0x7ffffff));
- }
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x2C, new_dsi_v_total);
if (ctrl_pdata->timing_db_mode)
MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x1e4, 0x1);
- pr_debug("%s new_fps:%d vsync:%d hsync:%d frame_rate:%d\n",
- __func__, new_fps, vsync_period, hsync_period,
+ pr_debug("%s new_fps:%d new_vtotal:0x%X cur_vtotal:0x%X frame_rate:%d\n",
+ __func__, new_fps, new_dsi_v_total, current_dsi_v_total,
ctrl_pdata->panel_data.panel_info.mipi.frame_rate);
ctrl_pdata->panel_data.panel_info.current_fps = new_fps;
diff --git a/drivers/video/fbdev/msm/mdss_dsi_panel.c b/drivers/video/fbdev/msm/mdss_dsi_panel.c
index cde2bc3..7eb8c70 100644
--- a/drivers/video/fbdev/msm/mdss_dsi_panel.c
+++ b/drivers/video/fbdev/msm/mdss_dsi_panel.c
@@ -1769,17 +1769,13 @@
for (i = 0; i < ctrl->status_cmds.cmd_cnt; i++)
len += lenp[i];
- for (i = 0; i < len; i++) {
- pr_debug("[%i] return:0x%x status:0x%x\n",
- i, (unsigned int)ctrl->return_buf[i],
- (unsigned int)ctrl->status_value[j + i]);
- MDSS_XLOG(ctrl->ndx, ctrl->return_buf[i],
- ctrl->status_value[j + i]);
- j += len;
- }
-
for (j = 0; j < ctrl->groups; ++j) {
for (i = 0; i < len; ++i) {
+ pr_debug("[%i] return:0x%x status:0x%x\n",
+ i, ctrl->return_buf[i],
+ (unsigned int)ctrl->status_value[group + i]);
+ MDSS_XLOG(ctrl->ndx, ctrl->return_buf[i],
+ ctrl->status_value[group + i]);
if (ctrl->return_buf[i] !=
ctrl->status_value[group + i])
break;
diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c
index 72adb17..63f8553 100644
--- a/drivers/video/fbdev/msm/mdss_fb.c
+++ b/drivers/video/fbdev/msm/mdss_fb.c
@@ -2032,6 +2032,14 @@
* supported for command mode panels. For all other panel, treat lp
* mode as full unblank and ulp mode as full blank.
*/
+ if ((mfd->panel_info->type == SPI_PANEL) &&
+ ((blank_mode == BLANK_FLAG_LP) ||
+ (blank_mode == BLANK_FLAG_ULP))) {
+ pr_debug("lp/ulp mode are not supported for SPI panels\n");
+ if (mdss_fb_is_power_on_interactive(mfd))
+ return 0;
+ }
+
if (mfd->panel_info->type != MIPI_CMD_PANEL) {
if (blank_mode == BLANK_FLAG_LP) {
pr_debug("lp mode only valid for cmd mode panels\n");
@@ -2100,7 +2108,10 @@
int ret;
struct mdss_panel_data *pdata;
struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+ ktime_t start, end;
+ s64 actual_time;
+ start = ktime_get();
ret = mdss_fb_pan_idle(mfd);
if (ret) {
pr_warn("mdss_fb_pan_idle for fb%d failed. ret=%d\n",
@@ -2133,7 +2144,12 @@
}
ret = mdss_fb_blank_sub(blank_mode, info, mfd->op_enable);
- MDSS_XLOG(blank_mode);
+ end = ktime_get();
+ actual_time = ktime_ms_delta(end, start);
+
+ MDSS_XLOG(blank_mode, actual_time);
+ pr_debug("blank_mode: %d and transition time: %lldms\n",
+ blank_mode, actual_time);
end:
mutex_unlock(&mfd->mdss_sysfs_lock);
diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c
index 7837559..ed98df6 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c
@@ -1204,16 +1204,7 @@
new_vsync_period_f0 = (vsync_period * hsync_period);
mdp_video_write(ctx, MDSS_MDP_REG_INTF_VSYNC_PERIOD_F0,
- current_vsync_period_f0 | 0x800000);
- if (new_vsync_period_f0 & 0x800000) {
- mdp_video_write(ctx, MDSS_MDP_REG_INTF_VSYNC_PERIOD_F0,
new_vsync_period_f0);
- } else {
- mdp_video_write(ctx, MDSS_MDP_REG_INTF_VSYNC_PERIOD_F0,
- new_vsync_period_f0 | 0x800000);
- mdp_video_write(ctx, MDSS_MDP_REG_INTF_VSYNC_PERIOD_F0,
- new_vsync_period_f0 & 0x7fffff);
- }
pr_debug("if:%d vtotal:%d htotal:%d f0:0x%x nw_f0:0x%x\n",
ctx->intf_num, vsync_period, hsync_period,
@@ -1432,6 +1423,11 @@
}
/*
+ * Make sure controller setting committed
+ */
+ wmb();
+
+ /*
* MDP INTF registers support DB on targets
* starting from MDP v1.5.
*/
@@ -1743,7 +1739,9 @@
h_total = mdss_panel_get_htotal(pinfo, true);
fetch_start = (v_total - pinfo->prg_fet) * h_total + 1;
- fetch_enable = BIT(31);
+
+ fetch_enable = mdp_video_read(ctx, MDSS_MDP_REG_INTF_CONFIG);
+ fetch_enable |= BIT(31);
if (pinfo->dynamic_fps && (pinfo->dfps_update ==
DFPS_IMMEDIATE_CLK_UPDATE_MODE))
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 1fdf4e5..a4fabf6 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1217,9 +1217,8 @@
goto out_free_ph;
}
- len = ELF_PAGESTART(eppnt->p_filesz + eppnt->p_vaddr +
- ELF_MIN_ALIGN - 1);
- bss = eppnt->p_memsz + eppnt->p_vaddr;
+ len = ELF_PAGEALIGN(eppnt->p_filesz + eppnt->p_vaddr);
+ bss = ELF_PAGEALIGN(eppnt->p_memsz + eppnt->p_vaddr);
if (bss > len) {
error = vm_brk(len, bss - len);
if (error)
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 03ac3ab..2bf83f9 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -3830,8 +3830,8 @@
if (wbc->sync_mode == WB_SYNC_ALL)
tag_pages_for_writeback(mapping, index, end);
while (!done && !nr_to_write_done && (index <= end) &&
- (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, tag,
- min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1))) {
+ (nr_pages = pagevec_lookup_range_tag(&pvec, mapping, &index, end,
+ tag))) {
unsigned i;
scanned = 1;
@@ -3841,11 +3841,6 @@
if (!PagePrivate(page))
continue;
- if (!wbc->range_cyclic && page->index > end) {
- done = 1;
- break;
- }
-
spin_lock(&mapping->private_lock);
if (!PagePrivate(page)) {
spin_unlock(&mapping->private_lock);
@@ -3978,8 +3973,8 @@
tag_pages_for_writeback(mapping, index, end);
done_index = index;
while (!done && !nr_to_write_done && (index <= end) &&
- (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, tag,
- min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1))) {
+ (nr_pages = pagevec_lookup_range_tag(&pvec, mapping,
+ &index, end, tag))) {
unsigned i;
scanned = 1;
@@ -4004,12 +3999,6 @@
continue;
}
- if (!wbc->range_cyclic && page->index > end) {
- done = 1;
- unlock_page(page);
- continue;
- }
-
if (wbc->sync_mode != WB_SYNC_NONE) {
if (PageWriteback(page))
flush_fn(data);
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index dfd9986..9afad8c 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -2237,6 +2237,21 @@
}
/*
+ * Check if the leaf is the last leaf. Which means all node pointers
+ * are at their last position.
+ */
+static bool is_last_leaf(struct btrfs_path *path)
+{
+ int i;
+
+ for (i = 1; i < BTRFS_MAX_LEVEL && path->nodes[i]; i++) {
+ if (path->slots[i] != btrfs_header_nritems(path->nodes[i]) - 1)
+ return false;
+ }
+ return true;
+}
+
+/*
* returns < 0 on error, 0 when more leafs are to be scanned.
* returns 1 when done.
*/
@@ -2249,6 +2264,7 @@
struct ulist *roots = NULL;
struct seq_list tree_mod_seq_elem = SEQ_LIST_INIT(tree_mod_seq_elem);
u64 num_bytes;
+ bool done;
int slot;
int ret;
@@ -2277,6 +2293,7 @@
mutex_unlock(&fs_info->qgroup_rescan_lock);
return ret;
}
+ done = is_last_leaf(path);
btrfs_item_key_to_cpu(path->nodes[0], &found,
btrfs_header_nritems(path->nodes[0]) - 1);
@@ -2323,6 +2340,8 @@
}
btrfs_put_tree_mod_seq(fs_info, &tree_mod_seq_elem);
+ if (done && !ret)
+ ret = 1;
return ret;
}
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 44d3492..44966fd 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -2979,8 +2979,11 @@
mutex_unlock(&log_root_tree->log_mutex);
/*
- * The barrier before waitqueue_active is implied by mutex_unlock
+ * The barrier before waitqueue_active is needed so all the updates
+ * above are seen by the woken threads. It might not be necessary, but
+ * proving that seems to be hard.
*/
+ smp_mb();
if (waitqueue_active(&log_root_tree->log_commit_wait[index2]))
wake_up(&log_root_tree->log_commit_wait[index2]);
out:
@@ -2991,8 +2994,11 @@
mutex_unlock(&root->log_mutex);
/*
- * The barrier before waitqueue_active is implied by mutex_unlock
+ * The barrier before waitqueue_active is needed so all the updates
+ * above are seen by the woken threads. It might not be necessary, but
+ * proving that seems to be hard.
*/
+ smp_mb();
if (waitqueue_active(&root->log_commit_wait[index1]))
wake_up(&root->log_commit_wait[index1]);
return ret;
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index 7b79a54..546d643 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -838,21 +838,15 @@
struct page **pages = NULL, **data_pages;
mempool_t *pool = NULL; /* Becomes non-null if mempool used */
struct page *page;
- int want;
u64 offset = 0, len = 0;
max_pages = max_pages_ever;
get_more_pages:
first = -1;
- want = min(end - index,
- min((pgoff_t)PAGEVEC_SIZE,
- max_pages - (pgoff_t)locked_pages) - 1)
- + 1;
- pvec_pages = pagevec_lookup_tag(&pvec, mapping, &index,
- PAGECACHE_TAG_DIRTY,
- want);
- dout("pagevec_lookup_tag got %d\n", pvec_pages);
+ pvec_pages = pagevec_lookup_range_tag(&pvec, mapping, &index,
+ end, PAGECACHE_TAG_DIRTY);
+ dout("pagevec_lookup_range_tag got %d\n", pvec_pages);
if (!pvec_pages && !locked_pages)
break;
for (i = 0; i < pvec_pages && locked_pages < max_pages; i++) {
@@ -870,12 +864,6 @@
unlock_page(page);
break;
}
- if (!wbc->range_cyclic && page->index > end) {
- dout("end of range %p\n", page);
- done = 1;
- unlock_page(page);
- break;
- }
if (strip_unit_end && (page->index > strip_unit_end)) {
dout("end of strip unit %p\n", page);
unlock_page(page);
diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c
index 0758d32..0f46cf5 100644
--- a/fs/crypto/crypto.c
+++ b/fs/crypto/crypto.c
@@ -162,12 +162,8 @@
}
req = skcipher_request_alloc(tfm, gfp_flags);
- if (!req) {
- printk_ratelimited(KERN_ERR
- "%s: crypto_request_alloc() failed\n",
- __func__);
+ if (!req)
return -ENOMEM;
- }
skcipher_request_set_callback(
req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
@@ -184,9 +180,10 @@
res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
skcipher_request_free(req);
if (res) {
- printk_ratelimited(KERN_ERR
- "%s: crypto_skcipher_encrypt() returned %d\n",
- __func__, res);
+ fscrypt_err(inode->i_sb,
+ "%scryption failed for inode %lu, block %llu: %d",
+ (rw == FS_DECRYPT ? "de" : "en"),
+ inode->i_ino, lblk_num, res);
return res;
}
return 0;
@@ -332,7 +329,6 @@
return 0;
}
- /* this should eventually be an flag in d_flags */
spin_lock(&dentry->d_lock);
cached_with_key = dentry->d_flags & DCACHE_ENCRYPTED_WITH_KEY;
spin_unlock(&dentry->d_lock);
@@ -359,7 +355,6 @@
const struct dentry_operations fscrypt_d_ops = {
.d_revalidate = fscrypt_d_revalidate,
};
-EXPORT_SYMBOL(fscrypt_d_ops);
void fscrypt_restore_control_page(struct page *page)
{
@@ -428,13 +423,43 @@
return res;
}
+void fscrypt_msg(struct super_block *sb, const char *level,
+ const char *fmt, ...)
+{
+ static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL,
+ DEFAULT_RATELIMIT_BURST);
+ struct va_format vaf;
+ va_list args;
+
+ if (!__ratelimit(&rs))
+ return;
+
+ va_start(args, fmt);
+ vaf.fmt = fmt;
+ vaf.va = &args;
+ if (sb)
+ printk("%sfscrypt (%s): %pV\n", level, sb->s_id, &vaf);
+ else
+ printk("%sfscrypt: %pV\n", level, &vaf);
+ va_end(args);
+}
+
/**
* fscrypt_init() - Set up for fs encryption.
*/
static int __init fscrypt_init(void)
{
+ /*
+ * Use an unbound workqueue to allow bios to be decrypted in parallel
+ * even when they happen to complete on the same CPU. This sacrifices
+ * locality, but it's worthwhile since decryption is CPU-intensive.
+ *
+ * Also use a high-priority workqueue to prioritize decryption work,
+ * which blocks reads from completing, over regular application tasks.
+ */
fscrypt_read_workqueue = alloc_workqueue("fscrypt_read_queue",
- WQ_HIGHPRI, 0);
+ WQ_UNBOUND | WQ_HIGHPRI,
+ num_online_cpus());
if (!fscrypt_read_workqueue)
goto fail;
diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c
index b18fa32..1bdb9f2 100644
--- a/fs/crypto/fname.c
+++ b/fs/crypto/fname.c
@@ -58,11 +58,8 @@
/* Set up the encryption request */
req = skcipher_request_alloc(tfm, GFP_NOFS);
- if (!req) {
- printk_ratelimited(KERN_ERR
- "%s: skcipher_request_alloc() failed\n", __func__);
+ if (!req)
return -ENOMEM;
- }
skcipher_request_set_callback(req,
CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
crypto_req_done, &wait);
@@ -73,8 +70,9 @@
res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
skcipher_request_free(req);
if (res < 0) {
- printk_ratelimited(KERN_ERR
- "%s: Error (error code %d)\n", __func__, res);
+ fscrypt_err(inode->i_sb,
+ "Filename encryption failed for inode %lu: %d",
+ inode->i_ino, res);
return res;
}
@@ -95,23 +93,14 @@
struct skcipher_request *req = NULL;
DECLARE_CRYPTO_WAIT(wait);
struct scatterlist src_sg, dst_sg;
- struct fscrypt_info *ci = inode->i_crypt_info;
- struct crypto_skcipher *tfm = ci->ci_ctfm;
+ struct crypto_skcipher *tfm = inode->i_crypt_info->ci_ctfm;
int res = 0;
char iv[FS_CRYPTO_BLOCK_SIZE];
- unsigned lim;
-
- lim = inode->i_sb->s_cop->max_namelen(inode);
- if (iname->len <= 0 || iname->len > lim)
- return -EIO;
/* Allocate request */
req = skcipher_request_alloc(tfm, GFP_NOFS);
- if (!req) {
- printk_ratelimited(KERN_ERR
- "%s: crypto_request_alloc() failed\n", __func__);
+ if (!req)
return -ENOMEM;
- }
skcipher_request_set_callback(req,
CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
crypto_req_done, &wait);
@@ -126,8 +115,9 @@
res = crypto_wait_req(crypto_skcipher_decrypt(req), &wait);
skcipher_request_free(req);
if (res < 0) {
- printk_ratelimited(KERN_ERR
- "%s: Error (error code %d)\n", __func__, res);
+ fscrypt_err(inode->i_sb,
+ "Filename decryption failed for inode %lu: %d",
+ inode->i_ino, res);
return res;
}
@@ -340,12 +330,12 @@
return 0;
}
ret = fscrypt_get_encryption_info(dir);
- if (ret && ret != -EOPNOTSUPP)
+ if (ret)
return ret;
if (dir->i_crypt_info) {
if (!fscrypt_fname_encrypted_size(dir, iname->len,
- dir->i_sb->s_cop->max_namelen(dir),
+ dir->i_sb->s_cop->max_namelen,
&fname->crypto_buf.len))
return -ENAMETOOLONG;
fname->crypto_buf.name = kmalloc(fname->crypto_buf.len,
diff --git a/fs/crypto/fscrypt_ice.c b/fs/crypto/fscrypt_ice.c
index 62dae83..cd84469 100644
--- a/fs/crypto/fscrypt_ice.c
+++ b/fs/crypto/fscrypt_ice.c
@@ -12,6 +12,8 @@
#include "fscrypt_ice.h"
+extern int fscrypt_get_mode_key_size(int mode);
+
int fscrypt_using_hardware_encryption(const struct inode *inode)
{
struct fscrypt_info *ci = inode->i_crypt_info;
@@ -21,6 +23,30 @@
}
EXPORT_SYMBOL(fscrypt_using_hardware_encryption);
+size_t fscrypt_get_ice_encryption_key_size(const struct inode *inode)
+{
+ struct fscrypt_info *ci = NULL;
+
+ if (inode)
+ ci = inode->i_crypt_info;
+ if (!ci)
+ return 0;
+
+ return fscrypt_get_mode_key_size(ci->ci_data_mode) / 2;
+}
+
+size_t fscrypt_get_ice_encryption_salt_size(const struct inode *inode)
+{
+ struct fscrypt_info *ci = NULL;
+
+ if (inode)
+ ci = inode->i_crypt_info;
+ if (!ci)
+ return 0;
+
+ return fscrypt_get_mode_key_size(ci->ci_data_mode) / 2;
+}
+
/*
* Retrieves encryption key from the inode
*/
@@ -44,6 +70,7 @@
char *fscrypt_get_ice_encryption_salt(const struct inode *inode)
{
struct fscrypt_info *ci = NULL;
+ int size = 0;
if (!inode)
return NULL;
@@ -52,7 +79,11 @@
if (!ci)
return NULL;
- return &(ci->ci_raw_key[fscrypt_get_ice_encryption_key_size(inode)]);
+ size = fscrypt_get_ice_encryption_key_size(inode);
+ if (!size)
+ return NULL;
+
+ return &(ci->ci_raw_key[size]);
}
/*
@@ -126,16 +157,29 @@
}
EXPORT_SYMBOL(fscrypt_set_ice_dun);
+void fscrypt_set_ice_skip(struct bio *bio, int bi_crypt_skip)
+{
+#ifdef CONFIG_DM_DEFAULT_KEY
+ bio->bi_crypt_skip = bi_crypt_skip;
+#endif
+}
+EXPORT_SYMBOL(fscrypt_set_ice_skip);
+
/*
* This function will be used for filesystem when deciding to merge bios.
* Basic assumption is, if inline_encryption is set, single bio has to
* guarantee consecutive LBAs as well as ino|pg->index.
*/
-bool fscrypt_mergeable_bio(struct bio *bio, u64 dun, bool bio_encrypted)
+bool fscrypt_mergeable_bio(struct bio *bio, u64 dun, bool bio_encrypted,
+ int bi_crypt_skip)
{
if (!bio)
return true;
+#ifdef CONFIG_DM_DEFAULT_KEY
+ if (bi_crypt_skip != bio->bi_crypt_skip)
+ return false;
+#endif
/* if both of them are not encrypted, no further check is needed */
if (!bio_dun(bio) && !bio_encrypted)
return true;
diff --git a/fs/crypto/fscrypt_ice.h b/fs/crypto/fscrypt_ice.h
index d448eae..3115cd0 100644
--- a/fs/crypto/fscrypt_ice.h
+++ b/fs/crypto/fscrypt_ice.h
@@ -40,17 +40,10 @@
bool fscrypt_is_ice_encryption_info_equal(const struct inode *inode1,
const struct inode *inode2);
-static inline size_t fscrypt_get_ice_encryption_key_size(
- const struct inode *inode)
-{
- return FS_AES_256_XTS_KEY_SIZE / 2;
-}
+size_t fscrypt_get_ice_encryption_key_size(const struct inode *inode);
-static inline size_t fscrypt_get_ice_encryption_salt_size(
- const struct inode *inode)
-{
- return FS_AES_256_XTS_KEY_SIZE / 2;
-}
+size_t fscrypt_get_ice_encryption_salt_size(const struct inode *inode);
+
#else
static inline bool fscrypt_should_be_processed_by_ice(const struct inode *inode)
{
diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h
index 6563f88..f2251a8 100644
--- a/fs/crypto/fscrypt_private.h
+++ b/fs/crypto/fscrypt_private.h
@@ -20,15 +20,7 @@
/* Encryption parameters */
#define FS_IV_SIZE 16
-#define FS_AES_128_ECB_KEY_SIZE 16
-#define FS_AES_128_CBC_KEY_SIZE 16
-#define FS_AES_128_CTS_KEY_SIZE 16
-#define FS_AES_256_GCM_KEY_SIZE 32
-#define FS_AES_256_CBC_KEY_SIZE 32
-#define FS_AES_256_CTS_KEY_SIZE 32
-#define FS_AES_256_XTS_KEY_SIZE 64
-
-#define FS_KEY_DERIVATION_NONCE_SIZE 16
+#define FS_KEY_DERIVATION_NONCE_SIZE 16
/**
* Encryption context for inode
@@ -129,6 +121,15 @@
gfp_t gfp_flags);
extern struct page *fscrypt_alloc_bounce_page(struct fscrypt_ctx *ctx,
gfp_t gfp_flags);
+extern const struct dentry_operations fscrypt_d_ops;
+
+extern void __printf(3, 4) __cold
+fscrypt_msg(struct super_block *sb, const char *level, const char *fmt, ...);
+
+#define fscrypt_warn(sb, fmt, ...) \
+ fscrypt_msg(sb, KERN_WARNING, fmt, ##__VA_ARGS__)
+#define fscrypt_err(sb, fmt, ...) \
+ fscrypt_msg(sb, KERN_ERR, fmt, ##__VA_ARGS__)
/* fname.c */
extern int fname_encrypt(struct inode *inode, const struct qstr *iname,
diff --git a/fs/crypto/hooks.c b/fs/crypto/hooks.c
index bec0649..926e5df 100644
--- a/fs/crypto/hooks.c
+++ b/fs/crypto/hooks.c
@@ -39,8 +39,9 @@
dir = dget_parent(file_dentry(filp));
if (IS_ENCRYPTED(d_inode(dir)) &&
!fscrypt_has_permitted_context(d_inode(dir), inode)) {
- pr_warn_ratelimited("fscrypt: inconsistent encryption contexts: %lu/%lu",
- d_inode(dir)->i_ino, inode->i_ino);
+ fscrypt_warn(inode->i_sb,
+ "inconsistent encryption contexts: %lu/%lu",
+ d_inode(dir)->i_ino, inode->i_ino);
err = -EPERM;
}
dput(dir);
diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c
index 1866733..6219c91 100644
--- a/fs/crypto/keyinfo.c
+++ b/fs/crypto/keyinfo.c
@@ -19,17 +19,16 @@
static struct crypto_shash *essiv_hash_tfm;
-/**
- * derive_key_aes() - Derive a key using AES-128-ECB
- * @deriving_key: Encryption key used for derivation.
- * @source_key: Source key to which to apply derivation.
- * @derived_raw_key: Derived raw key.
+/*
+ * Key derivation function. This generates the derived key by encrypting the
+ * master key with AES-128-ECB using the inode's nonce as the AES key.
*
- * Return: Zero on success; non-zero otherwise.
+ * The master key must be at least as long as the derived key. If the master
+ * key is longer, then only the first 'derived_keysize' bytes are used.
*/
-static int derive_key_aes(u8 deriving_key[FS_AES_128_ECB_KEY_SIZE],
- const struct fscrypt_key *source_key,
- u8 derived_raw_key[FS_MAX_KEY_SIZE])
+static int derive_key_aes(const u8 *master_key,
+ const struct fscrypt_context *ctx,
+ u8 *derived_key, unsigned int derived_keysize)
{
int res = 0;
struct skcipher_request *req = NULL;
@@ -51,14 +50,13 @@
skcipher_request_set_callback(req,
CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
crypto_req_done, &wait);
- res = crypto_skcipher_setkey(tfm, deriving_key,
- FS_AES_128_ECB_KEY_SIZE);
+ res = crypto_skcipher_setkey(tfm, ctx->nonce, sizeof(ctx->nonce));
if (res < 0)
goto out;
- sg_init_one(&src_sg, source_key->raw, source_key->size);
- sg_init_one(&dst_sg, derived_raw_key, source_key->size);
- skcipher_request_set_crypt(req, &src_sg, &dst_sg, source_key->size,
+ sg_init_one(&src_sg, master_key, derived_keysize);
+ sg_init_one(&dst_sg, derived_key, derived_keysize);
+ skcipher_request_set_crypt(req, &src_sg, &dst_sg, derived_keysize,
NULL);
res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
out:
@@ -67,125 +65,156 @@
return res;
}
-static int validate_user_key(struct fscrypt_info *crypt_info,
- struct fscrypt_context *ctx,
- const char *prefix, int min_keysize)
+/*
+ * Search the current task's subscribed keyrings for a "logon" key with
+ * description prefix:descriptor, and if found acquire a read lock on it and
+ * return a pointer to its validated payload in *payload_ret.
+ */
+static struct key *
+find_and_lock_process_key(const char *prefix,
+ const u8 descriptor[FS_KEY_DESCRIPTOR_SIZE],
+ unsigned int min_keysize,
+ const struct fscrypt_key **payload_ret)
{
char *description;
- struct key *keyring_key;
- struct fscrypt_key *master_key;
+ struct key *key;
const struct user_key_payload *ukp;
- int res;
+ const struct fscrypt_key *payload;
description = kasprintf(GFP_NOFS, "%s%*phN", prefix,
- FS_KEY_DESCRIPTOR_SIZE,
- ctx->master_key_descriptor);
+ FS_KEY_DESCRIPTOR_SIZE, descriptor);
if (!description)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
- keyring_key = request_key(&key_type_logon, description, NULL);
+ key = request_key(&key_type_logon, description, NULL);
kfree(description);
- if (IS_ERR(keyring_key))
- return PTR_ERR(keyring_key);
- down_read(&keyring_key->sem);
+ if (IS_ERR(key))
+ return key;
- if (keyring_key->type != &key_type_logon) {
- printk_once(KERN_WARNING
- "%s: key type must be logon\n", __func__);
- res = -ENOKEY;
- goto out;
- }
- ukp = user_key_payload_locked(keyring_key);
- if (!ukp) {
- /* key was revoked before we acquired its semaphore */
- res = -EKEYREVOKED;
- goto out;
- }
- if (ukp->datalen != sizeof(struct fscrypt_key)) {
- res = -EINVAL;
- goto out;
- }
- master_key = (struct fscrypt_key *)ukp->data;
- BUILD_BUG_ON(FS_AES_128_ECB_KEY_SIZE != FS_KEY_DERIVATION_NONCE_SIZE);
+ down_read(&key->sem);
+ ukp = user_key_payload_locked(key);
- if (master_key->size < min_keysize || master_key->size > FS_MAX_KEY_SIZE
- || master_key->size % AES_BLOCK_SIZE != 0) {
- printk_once(KERN_WARNING
- "%s: key size incorrect: %d\n",
- __func__, master_key->size);
- res = -ENOKEY;
- goto out;
- }
- res = derive_key_aes(ctx->nonce, master_key, crypt_info->ci_raw_key);
- /* If we don't need to derive, we still want to do everything
- * up until now to validate the key. It's cleaner to fail now
- * than to fail in block I/O.
- if (!is_private_data_mode(crypt_info)) {
- res = derive_key_aes(ctx->nonce, master_key,
- crypt_info->ci_raw_key);
- } else {
- * Inline encryption: no key derivation required because IVs are
- * assigned based on iv_sector.
+ if (!ukp) /* was the key revoked before we acquired its semaphore? */
+ goto invalid;
- BUILD_BUG_ON(sizeof(crypt_info->ci_raw_key) !=
- sizeof(master_key->raw));
- memcpy(crypt_info->ci_raw_key,
- master_key->raw, sizeof(crypt_info->ci_raw_key));
- res = 0;
+ payload = (const struct fscrypt_key *)ukp->data;
+
+ if (ukp->datalen != sizeof(struct fscrypt_key) ||
+ payload->size < 1 || payload->size > FS_MAX_KEY_SIZE) {
+ fscrypt_warn(NULL,
+ "key with description '%s' has invalid payload",
+ key->description);
+ goto invalid;
}
- */
-out:
- up_read(&keyring_key->sem);
- key_put(keyring_key);
- return res;
+
+ if (payload->size < min_keysize) {
+ fscrypt_warn(NULL,
+ "key with description '%s' is too short (got %u bytes, need %u+ bytes)",
+ key->description, payload->size, min_keysize);
+ goto invalid;
+ }
+
+ *payload_ret = payload;
+ return key;
+
+invalid:
+ up_read(&key->sem);
+ key_put(key);
+ return ERR_PTR(-ENOKEY);
}
-static const struct {
+/* Find the master key, then derive the inode's actual encryption key */
+static int find_and_derive_key(const struct inode *inode,
+ const struct fscrypt_context *ctx,
+ u8 *derived_key, unsigned int derived_keysize)
+{
+ struct key *key;
+ const struct fscrypt_key *payload;
+ int err;
+
+ key = find_and_lock_process_key(FS_KEY_DESC_PREFIX,
+ ctx->master_key_descriptor,
+ derived_keysize, &payload);
+ if (key == ERR_PTR(-ENOKEY) && inode->i_sb->s_cop->key_prefix) {
+ key = find_and_lock_process_key(inode->i_sb->s_cop->key_prefix,
+ ctx->master_key_descriptor,
+ derived_keysize, &payload);
+ }
+ if (IS_ERR(key))
+ return PTR_ERR(key);
+ err = derive_key_aes(payload->raw, ctx, derived_key, derived_keysize);
+ /* If we don't need to derive, we still want to do everything
+ * up until now to validate the key. It's cleaner to fail now
+ * than to fail in block I/O.
+ */
+ up_read(&key->sem);
+ key_put(key);
+ return err;
+}
+
+static struct fscrypt_mode {
+ const char *friendly_name;
const char *cipher_str;
int keysize;
+ bool logged_impl_name;
} available_modes[] = {
- [FS_ENCRYPTION_MODE_AES_256_XTS] = { "xts(aes)",
- FS_AES_256_XTS_KEY_SIZE },
- [FS_ENCRYPTION_MODE_AES_256_CTS] = { "cts(cbc(aes))",
- FS_AES_256_CTS_KEY_SIZE },
- [FS_ENCRYPTION_MODE_AES_128_CBC] = { "cbc(aes)",
- FS_AES_128_CBC_KEY_SIZE },
- [FS_ENCRYPTION_MODE_AES_128_CTS] = { "cts(cbc(aes))",
- FS_AES_128_CTS_KEY_SIZE },
- [FS_ENCRYPTION_MODE_SPECK128_256_XTS] = { "xts(speck128)", 64 },
- [FS_ENCRYPTION_MODE_SPECK128_256_CTS] = { "cts(cbc(speck128))", 32 },
- [FS_ENCRYPTION_MODE_PRIVATE] = { "bugon",
- FS_AES_256_XTS_KEY_SIZE },
+ [FS_ENCRYPTION_MODE_AES_256_XTS] = {
+ .friendly_name = "AES-256-XTS",
+ .cipher_str = "xts(aes)",
+ .keysize = 64,
+ },
+ [FS_ENCRYPTION_MODE_AES_256_CTS] = {
+ .friendly_name = "AES-256-CTS-CBC",
+ .cipher_str = "cts(cbc(aes))",
+ .keysize = 32,
+ },
+ [FS_ENCRYPTION_MODE_AES_128_CBC] = {
+ .friendly_name = "AES-128-CBC",
+ .cipher_str = "cbc(aes)",
+ .keysize = 16,
+ },
+ [FS_ENCRYPTION_MODE_AES_128_CTS] = {
+ .friendly_name = "AES-128-CTS-CBC",
+ .cipher_str = "cts(cbc(aes))",
+ .keysize = 16,
+ },
+ [FS_ENCRYPTION_MODE_SPECK128_256_XTS] = {
+ .friendly_name = "Speck128/256-XTS",
+ .cipher_str = "xts(speck128)",
+ .keysize = 64,
+ },
+ [FS_ENCRYPTION_MODE_SPECK128_256_CTS] = {
+ .friendly_name = "Speck128/256-CTS-CBC",
+ .cipher_str = "cts(cbc(speck128))",
+ .keysize = 32,
+ },
+ [FS_ENCRYPTION_MODE_PRIVATE] = {
+ .friendly_name = "ICE",
+ .cipher_str = "bugon",
+ .keysize = 64,
+ },
};
-static int determine_cipher_type(struct fscrypt_info *ci, struct inode *inode,
- const char **cipher_str_ret, int *keysize_ret, int *fname)
+static struct fscrypt_mode *
+select_encryption_mode(const struct fscrypt_info *ci, const struct inode *inode)
{
- u32 mode;
-
if (!fscrypt_valid_enc_modes(ci->ci_data_mode, ci->ci_filename_mode)) {
- pr_warn_ratelimited("fscrypt: inode %lu uses unsupported encryption modes (contents mode %d, filenames mode %d)\n",
- inode->i_ino,
- ci->ci_data_mode, ci->ci_filename_mode);
- return -EINVAL;
+ fscrypt_warn(inode->i_sb,
+ "inode %lu uses unsupported encryption modes (contents mode %d, filenames mode %d)",
+ inode->i_ino, ci->ci_data_mode,
+ ci->ci_filename_mode);
+ return ERR_PTR(-EINVAL);
}
- if (S_ISREG(inode->i_mode)) {
- ci->ci_mode = CI_DATA_MODE;
- mode = ci->ci_data_mode;
- } else if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) {
- ci->ci_mode = CI_FNAME_MODE;
- mode = ci->ci_filename_mode;
- *fname = 1;
- } else {
- WARN_ONCE(1, "fscrypt: filesystem tried to load encryption info for inode %lu, which is not encryptable (file type %d)\n",
- inode->i_ino, (inode->i_mode & S_IFMT));
- return -EINVAL;
- }
+ if (S_ISREG(inode->i_mode))
+ return &available_modes[ci->ci_data_mode];
- *cipher_str_ret = available_modes[mode].cipher_str;
- *keysize_ret = available_modes[mode].keysize;
- return 0;
+ if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
+ return &available_modes[ci->ci_filename_mode];
+
+ WARN_ONCE(1, "fscrypt: filesystem tried to load encryption info for inode %lu, which is not encryptable (file type %d)\n",
+ inode->i_ino, (inode->i_mode & S_IFMT));
+ return ERR_PTR(-EINVAL);
}
static void put_crypt_info(struct fscrypt_info *ci)
@@ -209,8 +238,9 @@
tfm = crypto_alloc_shash("sha256", 0, 0);
if (IS_ERR(tfm)) {
- pr_warn_ratelimited("fscrypt: error allocating SHA-256 transform: %ld\n",
- PTR_ERR(tfm));
+ fscrypt_warn(NULL,
+ "error allocating SHA-256 transform: %ld",
+ PTR_ERR(tfm));
return PTR_ERR(tfm);
}
prev_tfm = cmpxchg(&essiv_hash_tfm, NULL, tfm);
@@ -271,15 +301,20 @@
FS_ENCRYPTION_MODE_PRIVATE : FS_ENCRYPTION_MODE_AES_256_XTS;
}
+int fscrypt_get_mode_key_size(int mode)
+{
+ return available_modes[mode].keysize;
+}
+EXPORT_SYMBOL(fscrypt_get_mode_key_size);
+
int fscrypt_get_encryption_info(struct inode *inode)
{
struct fscrypt_info *crypt_info;
struct fscrypt_context ctx;
struct crypto_skcipher *ctfm;
- const char *cipher_str;
- int keysize;
+ struct fscrypt_mode *mode;
+ u8 *raw_key = NULL;
int res;
- int fname = 0;
if (inode->i_crypt_info)
return 0;
@@ -322,70 +357,71 @@
memcpy(crypt_info->ci_master_key, ctx.master_key_descriptor,
sizeof(crypt_info->ci_master_key));
- res = determine_cipher_type(crypt_info, inode, &cipher_str, &keysize,
- &fname);
- if (res)
+ mode = select_encryption_mode(crypt_info, inode);
+ if (IS_ERR(mode)) {
+ res = PTR_ERR(mode);
goto out;
+ }
/*
* This cannot be a stack buffer because it is passed to the scatterlist
* crypto API as part of key derivation.
*/
res = -ENOMEM;
-
- res = validate_user_key(crypt_info, &ctx, FS_KEY_DESC_PREFIX,
- keysize);
- if (res && inode->i_sb->s_cop->key_prefix) {
- int res2 = validate_user_key(crypt_info, &ctx,
- inode->i_sb->s_cop->key_prefix,
- keysize);
- if (res2) {
- if (res2 == -ENOKEY)
- res = -ENOKEY;
- goto out;
- }
- res = 0;
- } else if (res) {
+ raw_key = kmalloc(mode->keysize, GFP_NOFS);
+ if (!raw_key)
goto out;
- }
+
+ res = find_and_derive_key(inode, &ctx, raw_key, mode->keysize);
+ if (res)
+ goto out;
if (is_private_data_mode(crypt_info)) {
if (!fscrypt_is_ice_capable(inode->i_sb)) {
pr_warn("%s: ICE support not available\n",
- __func__);
+ __func__);
res = -EINVAL;
goto out;
}
/* Let's encrypt/decrypt by ICE */
+ memcpy(crypt_info->ci_raw_key, raw_key, mode->keysize);
goto do_ice;
}
-
- ctfm = crypto_alloc_skcipher(cipher_str, 0, 0);
- if (!ctfm || IS_ERR(ctfm)) {
- res = ctfm ? PTR_ERR(ctfm) : -ENOMEM;
- pr_debug("%s: error %d (inode %lu) allocating crypto tfm\n",
- __func__, res, inode->i_ino);
+ ctfm = crypto_alloc_skcipher(mode->cipher_str, 0, 0);
+ if (IS_ERR(ctfm)) {
+ res = PTR_ERR(ctfm);
+ fscrypt_warn(inode->i_sb,
+ "error allocating '%s' transform for inode %lu: %d",
+ mode->cipher_str, inode->i_ino, res);
goto out;
}
+ if (unlikely(!mode->logged_impl_name)) {
+ /*
+ * fscrypt performance can vary greatly depending on which
+ * crypto algorithm implementation is used. Help people debug
+ * performance problems by logging the ->cra_driver_name the
+ * first time a mode is used. Note that multiple threads can
+ * race here, but it doesn't really matter.
+ */
+ mode->logged_impl_name = true;
+ pr_info("fscrypt: %s using implementation \"%s\"\n",
+ mode->friendly_name,
+ crypto_skcipher_alg(ctfm)->base.cra_driver_name);
+ }
crypt_info->ci_ctfm = ctfm;
- crypto_skcipher_clear_flags(ctfm, ~0);
crypto_skcipher_set_flags(ctfm, CRYPTO_TFM_REQ_WEAK_KEY);
- /*
- * if the provided key is longer than keysize, we use the first
- * keysize bytes of the derived key only
- */
- res = crypto_skcipher_setkey(ctfm, crypt_info->ci_raw_key, keysize);
+ res = crypto_skcipher_setkey(ctfm, raw_key, mode->keysize);
if (res)
goto out;
if (S_ISREG(inode->i_mode) &&
crypt_info->ci_data_mode == FS_ENCRYPTION_MODE_AES_128_CBC) {
- res = init_essiv_generator(crypt_info, crypt_info->ci_raw_key,
- keysize);
+ res = init_essiv_generator(crypt_info, raw_key, mode->keysize);
if (res) {
- pr_debug("%s: error %d (inode %lu) allocating essiv tfm\n",
- __func__, res, inode->i_ino);
+ fscrypt_warn(inode->i_sb,
+ "error initializing ESSIV generator for inode %lu: %d",
+ inode->i_ino, res);
goto out;
}
}
diff --git a/fs/exec.c b/fs/exec.c
index d27f5e9..70110a6 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1228,15 +1228,14 @@
return -EAGAIN;
}
-char *get_task_comm(char *buf, struct task_struct *tsk)
+char *__get_task_comm(char *buf, size_t buf_size, struct task_struct *tsk)
{
- /* buf must be at least sizeof(tsk->comm) in size */
task_lock(tsk);
- strncpy(buf, tsk->comm, sizeof(tsk->comm));
+ strncpy(buf, tsk->comm, buf_size);
task_unlock(tsk);
return buf;
}
-EXPORT_SYMBOL_GPL(get_task_comm);
+EXPORT_SYMBOL_GPL(__get_task_comm);
/*
* These functions flushes out all traces of the currently running executable
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index ad13f07..2455fe1 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -378,6 +378,8 @@
return -EFSCORRUPTED;
ext4_lock_group(sb, block_group);
+ if (buffer_verified(bh))
+ goto verified;
if (unlikely(!ext4_block_bitmap_csum_verify(sb, block_group,
desc, bh))) {
ext4_unlock_group(sb, block_group);
@@ -400,6 +402,7 @@
return -EFSCORRUPTED;
}
set_buffer_verified(bh);
+verified:
ext4_unlock_group(sb, block_group);
return 0;
}
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 6941365..004c088 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -88,6 +88,8 @@
return -EFSCORRUPTED;
ext4_lock_group(sb, block_group);
+ if (buffer_verified(bh))
+ goto verified;
blk = ext4_inode_bitmap(sb, desc);
if (!ext4_inode_bitmap_csum_verify(sb, block_group, desc, bh,
EXT4_INODES_PER_GROUP(sb) / 8)) {
@@ -105,6 +107,7 @@
return -EFSBADCRC;
}
set_buffer_verified(bh);
+verified:
ext4_unlock_group(sb, block_group);
return 0;
}
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
index 6fde321..74e831f 100644
--- a/fs/ext4/inline.c
+++ b/fs/ext4/inline.c
@@ -693,6 +693,10 @@
goto convert;
}
+ ret = ext4_journal_get_write_access(handle, iloc.bh);
+ if (ret)
+ goto out;
+
flags |= AOP_FLAG_NOFS;
page = grab_cache_page_write_begin(mapping, 0, flags);
@@ -721,7 +725,7 @@
out_up_read:
up_read(&EXT4_I(inode)->xattr_sem);
out:
- if (handle)
+ if (handle && (ret != 1))
ext4_journal_stop(handle);
brelse(iloc.bh);
return ret;
@@ -763,6 +767,7 @@
ext4_write_unlock_xattr(inode, &no_expand);
brelse(iloc.bh);
+ mark_inode_dirty(inode);
out:
return copied;
}
@@ -909,7 +914,6 @@
goto out;
}
-
page = grab_cache_page_write_begin(mapping, 0, flags);
if (!page) {
ret = -ENOMEM;
@@ -927,6 +931,9 @@
if (ret < 0)
goto out_release_page;
}
+ ret = ext4_journal_get_write_access(handle, iloc.bh);
+ if (ret)
+ goto out_release_page;
up_read(&EXT4_I(inode)->xattr_sem);
*pagep = page;
@@ -947,7 +954,6 @@
unsigned len, unsigned copied,
struct page *page)
{
- int i_size_changed = 0;
int ret;
ret = ext4_write_inline_data_end(inode, pos, len, copied, page);
@@ -965,10 +971,8 @@
* But it's important to update i_size while still holding page lock:
* page writeout could otherwise come in and zero beyond i_size.
*/
- if (pos+copied > inode->i_size) {
+ if (pos+copied > inode->i_size)
i_size_write(inode, pos+copied);
- i_size_changed = 1;
- }
unlock_page(page);
put_page(page);
@@ -978,8 +982,7 @@
* ordering of page lock and transaction start for journaling
* filesystems.
*/
- if (i_size_changed)
- mark_inode_dirty(inode);
+ mark_inode_dirty(inode);
return copied;
}
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index af9b5f6..c38245d 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1332,10 +1332,11 @@
loff_t old_size = inode->i_size;
int ret = 0, ret2;
int i_size_changed = 0;
+ int inline_data = ext4_has_inline_data(inode);
trace_android_fs_datawrite_end(inode, pos, len);
trace_ext4_write_end(inode, pos, len, copied);
- if (ext4_has_inline_data(inode)) {
+ if (inline_data) {
ret = ext4_write_inline_data_end(inode, pos, len,
copied, page);
if (ret < 0) {
@@ -1363,7 +1364,7 @@
* ordering of page lock and transaction start for journaling
* filesystems.
*/
- if (i_size_changed)
+ if (i_size_changed || inline_data)
ext4_mark_inode_dirty(handle, inode);
if (pos + len > inode->i_size && ext4_can_truncate(inode))
@@ -1437,6 +1438,7 @@
int partial = 0;
unsigned from, to;
int size_changed = 0;
+ int inline_data = ext4_has_inline_data(inode);
trace_android_fs_datawrite_end(inode, pos, len);
trace_ext4_journalled_write_end(inode, pos, len, copied);
@@ -1445,7 +1447,7 @@
BUG_ON(!ext4_handle_valid(handle));
- if (ext4_has_inline_data(inode)) {
+ if (inline_data) {
ret = ext4_write_inline_data_end(inode, pos, len,
copied, page);
if (ret < 0) {
@@ -1476,7 +1478,7 @@
if (old_size < pos)
pagecache_isize_extended(inode, old_size, pos);
- if (size_changed) {
+ if (size_changed || inline_data) {
ret2 = ext4_mark_inode_dirty(handle, inode);
if (!ret)
ret = ret2;
@@ -1974,11 +1976,7 @@
}
if (inline_data) {
- BUFFER_TRACE(inode_bh, "get write access");
- ret = ext4_journal_get_write_access(handle, inode_bh);
-
- err = ext4_handle_dirty_metadata(handle, inode, inode_bh);
-
+ ret = ext4_mark_inode_dirty(handle, inode);
} else {
ret = ext4_walk_page_buffers(handle, page_bufs, 0, len, NULL,
do_journal_get_write_access);
@@ -2571,8 +2569,8 @@
mpd->map.m_len = 0;
mpd->next_page = index;
while (index <= end) {
- nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, tag,
- min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1);
+ nr_pages = pagevec_lookup_range_tag(&pvec, mapping, &index, end,
+ tag);
if (nr_pages == 0)
goto out;
@@ -2580,16 +2578,6 @@
struct page *page = pvec.pages[i];
/*
- * At this point, the page may be truncated or
- * invalidated (changing page->mapping to NULL), or
- * even swizzled back from swapper_space to tmpfs file
- * mapping. However, page->index will not change
- * because we have a reference on the page.
- */
- if (page->index > end)
- goto out;
-
- /*
* Accumulated enough dirty pages? This doesn't apply
* to WB_SYNC_ALL mode. For integrity sync we have to
* keep going because someone may be concurrently
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index d536e0a..ac0b633 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -1545,24 +1545,14 @@
struct inode *inode;
struct ext4_dir_entry_2 *de;
struct buffer_head *bh;
+ int err;
- if (ext4_encrypted_inode(dir)) {
- int res = fscrypt_get_encryption_info(dir);
+ err = fscrypt_prepare_lookup(dir, dentry, flags);
+ if (err)
+ return ERR_PTR(err);
- /*
- * DCACHE_ENCRYPTED_WITH_KEY is set if the dentry is
- * created while the directory was encrypted and we
- * have access to the key.
- */
- if (fscrypt_has_encryption_key(dir))
- fscrypt_set_encrypted_dentry(dentry);
- fscrypt_set_d_op(dentry);
- if (res && res != -ENOKEY)
- return ERR_PTR(res);
- }
-
- if (dentry->d_name.len > EXT4_NAME_LEN)
- return ERR_PTR(-ENAMETOOLONG);
+ if (dentry->d_name.len > EXT4_NAME_LEN)
+ return ERR_PTR(-ENAMETOOLONG);
bh = ext4_find_entry(dir, &dentry->d_name, &de, NULL);
if (IS_ERR(bh))
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index ab72207..c7fdf50 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1174,19 +1174,13 @@
return DUMMY_ENCRYPTION_ENABLED(EXT4_SB(inode->i_sb));
}
-static unsigned ext4_max_namelen(struct inode *inode)
-{
- return S_ISLNK(inode->i_mode) ? inode->i_sb->s_blocksize :
- EXT4_NAME_LEN;
-}
-
static const struct fscrypt_operations ext4_cryptops = {
.key_prefix = "ext4:",
.get_context = ext4_get_context,
.set_context = ext4_set_context,
.dummy_context = ext4_dummy_context,
.empty_dir = ext4_empty_dir,
- .max_namelen = ext4_max_namelen,
+ .max_namelen = EXT4_NAME_LEN,
};
#endif
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 91b2d00..d7a53c6 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -24,7 +24,7 @@
#include <trace/events/f2fs.h>
static struct kmem_cache *ino_entry_slab;
-struct kmem_cache *inode_entry_slab;
+struct kmem_cache *f2fs_inode_entry_slab;
void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io)
{
@@ -36,7 +36,7 @@
/*
* We guarantee no failure on the returned page.
*/
-struct page *grab_meta_page(struct f2fs_sb_info *sbi, pgoff_t index)
+struct page *f2fs_grab_meta_page(struct f2fs_sb_info *sbi, pgoff_t index)
{
struct address_space *mapping = META_MAPPING(sbi);
struct page *page = NULL;
@@ -100,24 +100,27 @@
* readonly and make sure do not write checkpoint with non-uptodate
* meta page.
*/
- if (unlikely(!PageUptodate(page)))
+ if (unlikely(!PageUptodate(page))) {
+ memset(page_address(page), 0, PAGE_SIZE);
f2fs_stop_checkpoint(sbi, false);
+ }
out:
return page;
}
-struct page *get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index)
+struct page *f2fs_get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index)
{
return __get_meta_page(sbi, index, true);
}
/* for POR only */
-struct page *get_tmp_page(struct f2fs_sb_info *sbi, pgoff_t index)
+struct page *f2fs_get_tmp_page(struct f2fs_sb_info *sbi, pgoff_t index)
{
return __get_meta_page(sbi, index, false);
}
-bool is_valid_blkaddr(struct f2fs_sb_info *sbi, block_t blkaddr, int type)
+bool f2fs_is_valid_meta_blkaddr(struct f2fs_sb_info *sbi,
+ block_t blkaddr, int type)
{
switch (type) {
case META_NAT:
@@ -151,7 +154,7 @@
/*
* Readahead CP/NAT/SIT/SSA pages
*/
-int ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
+int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
int type, bool sync)
{
struct page *page;
@@ -173,7 +176,7 @@
blk_start_plug(&plug);
for (; nrpages-- > 0; blkno++) {
- if (!is_valid_blkaddr(sbi, blkno, type))
+ if (!f2fs_is_valid_meta_blkaddr(sbi, blkno, type))
goto out;
switch (type) {
@@ -217,7 +220,7 @@
return blkno - start;
}
-void ra_meta_pages_cond(struct f2fs_sb_info *sbi, pgoff_t index)
+void f2fs_ra_meta_pages_cond(struct f2fs_sb_info *sbi, pgoff_t index)
{
struct page *page;
bool readahead = false;
@@ -228,7 +231,7 @@
f2fs_put_page(page, 0);
if (readahead)
- ra_meta_pages(sbi, index, BIO_MAX_PAGES, META_POR, true);
+ f2fs_ra_meta_pages(sbi, index, BIO_MAX_PAGES, META_POR, true);
}
static int __f2fs_write_meta_page(struct page *page,
@@ -249,7 +252,7 @@
if (wbc->for_reclaim && page->index < GET_SUM_BLOCK(sbi, 0))
goto redirty_out;
- write_meta_page(sbi, page, io_type);
+ f2fs_do_write_meta_page(sbi, page, io_type);
dec_page_count(sbi, F2FS_DIRTY_META);
if (wbc->for_reclaim)
@@ -294,7 +297,7 @@
trace_f2fs_writepages(mapping->host, wbc, META);
diff = nr_pages_to_write(sbi, META, wbc);
- written = sync_meta_pages(sbi, META, wbc->nr_to_write, FS_META_IO);
+ written = f2fs_sync_meta_pages(sbi, META, wbc->nr_to_write, FS_META_IO);
mutex_unlock(&sbi->cp_mutex);
wbc->nr_to_write = max((long)0, wbc->nr_to_write - written - diff);
return 0;
@@ -305,13 +308,14 @@
return 0;
}
-long sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type,
+long f2fs_sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type,
long nr_to_write, enum iostat_type io_type)
{
struct address_space *mapping = META_MAPPING(sbi);
- pgoff_t index = 0, end = ULONG_MAX, prev = ULONG_MAX;
+ pgoff_t index = 0, prev = ULONG_MAX;
struct pagevec pvec;
long nwritten = 0;
+ int nr_pages;
struct writeback_control wbc = {
.for_reclaim = 0,
};
@@ -321,13 +325,9 @@
blk_start_plug(&plug);
- while (index <= end) {
- int i, nr_pages;
- nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
- PAGECACHE_TAG_DIRTY,
- min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1);
- if (unlikely(nr_pages == 0))
- break;
+ while ((nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
+ PAGECACHE_TAG_DIRTY))) {
+ int i;
for (i = 0; i < nr_pages; i++) {
struct page *page = pvec.pages[i];
@@ -458,20 +458,20 @@
spin_unlock(&im->ino_lock);
}
-void add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type)
+void f2fs_add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type)
{
/* add new dirty ino entry into list */
__add_ino_entry(sbi, ino, 0, type);
}
-void remove_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type)
+void f2fs_remove_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type)
{
/* remove dirty ino entry from list */
__remove_ino_entry(sbi, ino, type);
}
/* mode should be APPEND_INO or UPDATE_INO */
-bool exist_written_data(struct f2fs_sb_info *sbi, nid_t ino, int mode)
+bool f2fs_exist_written_data(struct f2fs_sb_info *sbi, nid_t ino, int mode)
{
struct inode_management *im = &sbi->im[mode];
struct ino_entry *e;
@@ -482,7 +482,7 @@
return e ? true : false;
}
-void release_ino_entry(struct f2fs_sb_info *sbi, bool all)
+void f2fs_release_ino_entry(struct f2fs_sb_info *sbi, bool all)
{
struct ino_entry *e, *tmp;
int i;
@@ -501,13 +501,13 @@
}
}
-void set_dirty_device(struct f2fs_sb_info *sbi, nid_t ino,
+void f2fs_set_dirty_device(struct f2fs_sb_info *sbi, nid_t ino,
unsigned int devidx, int type)
{
__add_ino_entry(sbi, ino, devidx, type);
}
-bool is_dirty_device(struct f2fs_sb_info *sbi, nid_t ino,
+bool f2fs_is_dirty_device(struct f2fs_sb_info *sbi, nid_t ino,
unsigned int devidx, int type)
{
struct inode_management *im = &sbi->im[type];
@@ -522,7 +522,7 @@
return is_dirty;
}
-int acquire_orphan_inode(struct f2fs_sb_info *sbi)
+int f2fs_acquire_orphan_inode(struct f2fs_sb_info *sbi)
{
struct inode_management *im = &sbi->im[ORPHAN_INO];
int err = 0;
@@ -545,7 +545,7 @@
return err;
}
-void release_orphan_inode(struct f2fs_sb_info *sbi)
+void f2fs_release_orphan_inode(struct f2fs_sb_info *sbi)
{
struct inode_management *im = &sbi->im[ORPHAN_INO];
@@ -555,14 +555,14 @@
spin_unlock(&im->ino_lock);
}
-void add_orphan_inode(struct inode *inode)
+void f2fs_add_orphan_inode(struct inode *inode)
{
/* add new orphan ino entry into list */
__add_ino_entry(F2FS_I_SB(inode), inode->i_ino, 0, ORPHAN_INO);
- update_inode_page(inode);
+ f2fs_update_inode_page(inode);
}
-void remove_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
+void f2fs_remove_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
{
/* remove orphan entry from orphan list */
__remove_ino_entry(sbi, ino, ORPHAN_INO);
@@ -572,7 +572,7 @@
{
struct inode *inode;
struct node_info ni;
- int err = acquire_orphan_inode(sbi);
+ int err = f2fs_acquire_orphan_inode(sbi);
if (err)
goto err_out;
@@ -590,16 +590,17 @@
}
err = dquot_initialize(inode);
- if (err)
+ if (err) {
+ iput(inode);
goto err_out;
+ }
- dquot_initialize(inode);
clear_nlink(inode);
/* truncate all the data during iput */
iput(inode);
- get_node_info(sbi, ino, &ni);
+ f2fs_get_node_info(sbi, ino, &ni);
/* ENOMEM was fully retried in f2fs_evict_inode. */
if (ni.blk_addr != NULL_ADDR) {
@@ -617,7 +618,7 @@
return err;
}
-int recover_orphan_inodes(struct f2fs_sb_info *sbi)
+int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi)
{
block_t start_blk, orphan_blocks, i, j;
unsigned int s_flags = sbi->sb->s_flags;
@@ -645,10 +646,10 @@
start_blk = __start_cp_addr(sbi) + 1 + __cp_payload(sbi);
orphan_blocks = __start_sum_addr(sbi) - 1 - __cp_payload(sbi);
- ra_meta_pages(sbi, start_blk, orphan_blocks, META_CP, true);
+ f2fs_ra_meta_pages(sbi, start_blk, orphan_blocks, META_CP, true);
for (i = 0; i < orphan_blocks; i++) {
- struct page *page = get_meta_page(sbi, start_blk + i);
+ struct page *page = f2fs_get_meta_page(sbi, start_blk + i);
struct f2fs_orphan_block *orphan_blk;
orphan_blk = (struct f2fs_orphan_block *)page_address(page);
@@ -698,7 +699,7 @@
/* loop for each orphan inode entry and write them in Jornal block */
list_for_each_entry(orphan, head, list) {
if (!page) {
- page = grab_meta_page(sbi, start_blk++);
+ page = f2fs_grab_meta_page(sbi, start_blk++);
orphan_blk =
(struct f2fs_orphan_block *)page_address(page);
memset(orphan_blk, 0, sizeof(*orphan_blk));
@@ -740,7 +741,7 @@
size_t crc_offset = 0;
__u32 crc = 0;
- *cp_page = get_meta_page(sbi, cp_addr);
+ *cp_page = f2fs_get_meta_page(sbi, cp_addr);
*cp_block = (struct f2fs_checkpoint *)page_address(*cp_page);
crc_offset = le32_to_cpu((*cp_block)->checksum_offset);
@@ -793,7 +794,7 @@
return NULL;
}
-int get_valid_checkpoint(struct f2fs_sb_info *sbi)
+int f2fs_get_valid_checkpoint(struct f2fs_sb_info *sbi)
{
struct f2fs_checkpoint *cp_block;
struct f2fs_super_block *fsb = sbi->raw_super;
@@ -805,7 +806,8 @@
block_t cp_blk_no;
int i;
- sbi->ckpt = f2fs_kzalloc(sbi, cp_blks * blk_size, GFP_KERNEL);
+ sbi->ckpt = f2fs_kzalloc(sbi, array_size(blk_size, cp_blks),
+ GFP_KERNEL);
if (!sbi->ckpt)
return -ENOMEM;
/*
@@ -837,7 +839,7 @@
memcpy(sbi->ckpt, cp_block, blk_size);
/* Sanity checking of checkpoint */
- if (sanity_check_ckpt(sbi))
+ if (f2fs_sanity_check_ckpt(sbi))
goto free_fail_no_cp;
if (cur_page == cp1)
@@ -856,7 +858,7 @@
void *sit_bitmap_ptr;
unsigned char *ckpt = (unsigned char *)sbi->ckpt;
- cur_page = get_meta_page(sbi, cp_blk_no + i);
+ cur_page = f2fs_get_meta_page(sbi, cp_blk_no + i);
sit_bitmap_ptr = page_address(cur_page);
memcpy(ckpt + i * blk_size, sit_bitmap_ptr, blk_size);
f2fs_put_page(cur_page, 1);
@@ -901,7 +903,7 @@
stat_dec_dirty_inode(F2FS_I_SB(inode), type);
}
-void update_dirty_page(struct inode *inode, struct page *page)
+void f2fs_update_dirty_page(struct inode *inode, struct page *page)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
enum inode_type type = S_ISDIR(inode->i_mode) ? DIR_INODE : FILE_INODE;
@@ -920,7 +922,7 @@
f2fs_trace_pid(page);
}
-void remove_dirty_inode(struct inode *inode)
+void f2fs_remove_dirty_inode(struct inode *inode)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
enum inode_type type = S_ISDIR(inode->i_mode) ? DIR_INODE : FILE_INODE;
@@ -937,7 +939,7 @@
spin_unlock(&sbi->inode_lock[type]);
}
-int sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type)
+int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type)
{
struct list_head *head;
struct inode *inode;
@@ -1020,7 +1022,7 @@
/* it's on eviction */
if (is_inode_flag_set(inode, FI_DIRTY_INODE))
- update_inode_page(inode);
+ f2fs_update_inode_page(inode);
iput(inode);
}
}
@@ -1060,7 +1062,7 @@
/* write all the dirty dentry pages */
if (get_pages(sbi, F2FS_DIRTY_DENTS)) {
f2fs_unlock_all(sbi);
- err = sync_dirty_inodes(sbi, DIR_INODE);
+ err = f2fs_sync_dirty_inodes(sbi, DIR_INODE);
if (err)
goto out;
cond_resched();
@@ -1088,7 +1090,9 @@
if (get_pages(sbi, F2FS_DIRTY_NODES)) {
up_write(&sbi->node_write);
- err = sync_node_pages(sbi, &wbc, false, FS_CP_NODE_IO);
+ atomic_inc(&sbi->wb_sync_req[NODE]);
+ err = f2fs_sync_node_pages(sbi, &wbc, false, FS_CP_NODE_IO);
+ atomic_dec(&sbi->wb_sync_req[NODE]);
if (err) {
up_write(&sbi->node_change);
f2fs_unlock_all(sbi);
@@ -1182,10 +1186,10 @@
/*
* pagevec_lookup_tag and lock_page again will take
- * some extra time. Therefore, update_meta_pages and
- * sync_meta_pages are combined in this function.
+ * some extra time. Therefore, f2fs_update_meta_pages and
+ * f2fs_sync_meta_pages are combined in this function.
*/
- struct page *page = grab_meta_page(sbi, blk_addr);
+ struct page *page = f2fs_grab_meta_page(sbi, blk_addr);
int err;
memcpy(page_address(page), src, PAGE_SIZE);
@@ -1223,7 +1227,7 @@
/* Flush all the NAT/SIT pages */
while (get_pages(sbi, F2FS_DIRTY_META)) {
- sync_meta_pages(sbi, META, LONG_MAX, FS_CP_META_IO);
+ f2fs_sync_meta_pages(sbi, META, LONG_MAX, FS_CP_META_IO);
if (unlikely(f2fs_cp_error(sbi)))
return -EIO;
}
@@ -1232,7 +1236,7 @@
* modify checkpoint
* version number is already updated
*/
- ckpt->elapsed_time = cpu_to_le64(get_mtime(sbi));
+ ckpt->elapsed_time = cpu_to_le64(get_mtime(sbi, true));
ckpt->free_segment_count = cpu_to_le32(free_segments(sbi));
for (i = 0; i < NR_CURSEG_NODE_TYPE; i++) {
ckpt->cur_node_segno[i] =
@@ -1252,7 +1256,7 @@
}
/* 2 cp + n data seg summary + orphan inode blocks */
- data_sum_blocks = npages_for_summary_flush(sbi, false);
+ data_sum_blocks = f2fs_npages_for_summary_flush(sbi, false);
spin_lock_irqsave(&sbi->cp_lock, flags);
if (data_sum_blocks < NR_CURSEG_DATA_TYPE)
__set_ckpt_flags(ckpt, CP_COMPACT_SUM_FLAG);
@@ -1297,22 +1301,23 @@
blk = start_blk + sbi->blocks_per_seg - nm_i->nat_bits_blocks;
for (i = 0; i < nm_i->nat_bits_blocks; i++)
- update_meta_page(sbi, nm_i->nat_bits +
+ f2fs_update_meta_page(sbi, nm_i->nat_bits +
(i << F2FS_BLKSIZE_BITS), blk + i);
/* Flush all the NAT BITS pages */
while (get_pages(sbi, F2FS_DIRTY_META)) {
- sync_meta_pages(sbi, META, LONG_MAX, FS_CP_META_IO);
+ f2fs_sync_meta_pages(sbi, META, LONG_MAX,
+ FS_CP_META_IO);
if (unlikely(f2fs_cp_error(sbi)))
return -EIO;
}
}
/* write out checkpoint buffer at block 0 */
- update_meta_page(sbi, ckpt, start_blk++);
+ f2fs_update_meta_page(sbi, ckpt, start_blk++);
for (i = 1; i < 1 + cp_payload_blks; i++)
- update_meta_page(sbi, (char *)ckpt + i * F2FS_BLKSIZE,
+ f2fs_update_meta_page(sbi, (char *)ckpt + i * F2FS_BLKSIZE,
start_blk++);
if (orphan_num) {
@@ -1320,7 +1325,7 @@
start_blk += orphan_blocks;
}
- write_data_summaries(sbi, start_blk);
+ f2fs_write_data_summaries(sbi, start_blk);
start_blk += data_sum_blocks;
/* Record write statistics in the hot node summary */
@@ -1331,7 +1336,7 @@
seg_i->journal->info.kbytes_written = cpu_to_le64(kbytes_written);
if (__remain_node_summaries(cpc->reason)) {
- write_node_summaries(sbi, start_blk);
+ f2fs_write_node_summaries(sbi, start_blk);
start_blk += NR_CURSEG_NODE_TYPE;
}
@@ -1340,7 +1345,7 @@
percpu_counter_set(&sbi->alloc_valid_block_count, 0);
/* Here, we have one bio having CP pack except cp pack 2 page */
- sync_meta_pages(sbi, META, LONG_MAX, FS_CP_META_IO);
+ f2fs_sync_meta_pages(sbi, META, LONG_MAX, FS_CP_META_IO);
/* wait for previous submitted meta pages writeback */
wait_on_all_pages_writeback(sbi);
@@ -1357,7 +1362,7 @@
commit_checkpoint(sbi, ckpt, start_blk);
wait_on_all_pages_writeback(sbi);
- release_ino_entry(sbi, false);
+ f2fs_release_ino_entry(sbi, false);
if (unlikely(f2fs_cp_error(sbi)))
return -EIO;
@@ -1382,7 +1387,7 @@
/*
* We guarantee that this checkpoint procedure will not fail.
*/
-int write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
+int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
{
struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
unsigned long long ckpt_ver;
@@ -1415,7 +1420,7 @@
/* this is the case of multiple fstrims without any changes */
if (cpc->reason & CP_DISCARD) {
- if (!exist_trim_candidates(sbi, cpc)) {
+ if (!f2fs_exist_trim_candidates(sbi, cpc)) {
unblock_operations(sbi);
goto out;
}
@@ -1423,8 +1428,8 @@
if (NM_I(sbi)->dirty_nat_cnt == 0 &&
SIT_I(sbi)->dirty_sentries == 0 &&
prefree_segments(sbi) == 0) {
- flush_sit_entries(sbi, cpc);
- clear_prefree_segments(sbi, cpc);
+ f2fs_flush_sit_entries(sbi, cpc);
+ f2fs_clear_prefree_segments(sbi, cpc);
unblock_operations(sbi);
goto out;
}
@@ -1439,15 +1444,15 @@
ckpt->checkpoint_ver = cpu_to_le64(++ckpt_ver);
/* write cached NAT/SIT entries to NAT/SIT area */
- flush_nat_entries(sbi, cpc);
- flush_sit_entries(sbi, cpc);
+ f2fs_flush_nat_entries(sbi, cpc);
+ f2fs_flush_sit_entries(sbi, cpc);
/* unlock all the fs_lock[] in do_checkpoint() */
err = do_checkpoint(sbi, cpc);
if (err)
- release_discard_addrs(sbi);
+ f2fs_release_discard_addrs(sbi);
else
- clear_prefree_segments(sbi, cpc);
+ f2fs_clear_prefree_segments(sbi, cpc);
unblock_operations(sbi);
stat_inc_cp_count(sbi->stat_info);
@@ -1464,7 +1469,7 @@
return err;
}
-void init_ino_entry_info(struct f2fs_sb_info *sbi)
+void f2fs_init_ino_entry_info(struct f2fs_sb_info *sbi)
{
int i;
@@ -1482,23 +1487,23 @@
F2FS_ORPHANS_PER_BLOCK;
}
-int __init create_checkpoint_caches(void)
+int __init f2fs_create_checkpoint_caches(void)
{
ino_entry_slab = f2fs_kmem_cache_create("f2fs_ino_entry",
sizeof(struct ino_entry));
if (!ino_entry_slab)
return -ENOMEM;
- inode_entry_slab = f2fs_kmem_cache_create("f2fs_inode_entry",
+ f2fs_inode_entry_slab = f2fs_kmem_cache_create("f2fs_inode_entry",
sizeof(struct inode_entry));
- if (!inode_entry_slab) {
+ if (!f2fs_inode_entry_slab) {
kmem_cache_destroy(ino_entry_slab);
return -ENOMEM;
}
return 0;
}
-void destroy_checkpoint_caches(void)
+void f2fs_destroy_checkpoint_caches(void)
{
kmem_cache_destroy(ino_entry_slab);
- kmem_cache_destroy(inode_entry_slab);
+ kmem_cache_destroy(f2fs_inode_entry_slab);
}
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 30c5ec0..f7f2c13 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -48,6 +48,8 @@
if (inode->i_ino == F2FS_META_INO(sbi) ||
inode->i_ino == F2FS_NODE_INO(sbi) ||
S_ISDIR(inode->i_mode) ||
+ (S_ISREG(inode->i_mode) &&
+ is_inode_flag_set(inode, FI_ATOMIC_FILE)) ||
is_cold_data(page))
return true;
return false;
@@ -244,7 +246,7 @@
} else {
bio->bi_end_io = f2fs_write_end_io;
bio->bi_private = sbi;
- bio->bi_write_hint = io_type_to_rw_hint(sbi, type, temp);
+ bio->bi_write_hint = f2fs_io_type_to_rw_hint(sbi, type, temp);
}
if (wbc)
wbc_init_bio(wbc, bio);
@@ -448,7 +450,8 @@
1, is_read_io(fio->op), fio->type, fio->temp);
if (f2fs_may_encrypt_bio(inode, fio))
- fscrypt_set_ice_dun(inode, bio, PG_DUN(inode, fio->page));
+ fscrypt_set_ice_dun(inode, bio, PG_DUN(inode, fio->page));
+ fscrypt_set_ice_skip(bio, fio->encrypted_page ? 1 : 0);
if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) {
bio_put(bio);
@@ -463,7 +466,7 @@
return 0;
}
-int f2fs_submit_page_write(struct f2fs_io_info *fio)
+void f2fs_submit_page_write(struct f2fs_io_info *fio)
{
struct f2fs_sb_info *sbi = fio->sbi;
enum page_type btype = PAGE_TYPE_OF_BIO(fio->type);
@@ -471,8 +474,8 @@
struct page *bio_page;
struct inode *inode;
bool bio_encrypted;
+ int bi_crypt_skip;
u64 dun;
- int err = 0;
f2fs_bug_on(sbi, is_read_io(fio->op));
@@ -482,7 +485,7 @@
spin_lock(&io->io_lock);
if (list_empty(&io->io_list)) {
spin_unlock(&io->io_lock);
- goto out_fail;
+ goto out;
}
fio = list_first_entry(&io->io_list,
struct f2fs_io_info, list);
@@ -490,13 +493,14 @@
spin_unlock(&io->io_lock);
}
- if (fio->old_blkaddr != NEW_ADDR)
+ if (is_valid_blkaddr(fio->old_blkaddr))
verify_block_addr(fio, fio->old_blkaddr);
verify_block_addr(fio, fio->new_blkaddr);
bio_page = fio->encrypted_page ? fio->encrypted_page : fio->page;
inode = fio->page->mapping->host;
dun = PG_DUN(inode, fio->page);
+ bi_crypt_skip = fio->encrypted_page ? 1 : 0;
bio_encrypted = f2fs_may_encrypt_bio(inode, fio);
/* set submitted = true as a return value */
@@ -510,23 +514,23 @@
__submit_merged_bio(io);
/* ICE support */
- if (!fscrypt_mergeable_bio(io->bio, dun, bio_encrypted))
+ if (!fscrypt_mergeable_bio(io->bio, dun, bio_encrypted, bi_crypt_skip))
__submit_merged_bio(io);
alloc_new:
if (io->bio == NULL) {
if ((fio->type == DATA || fio->type == NODE) &&
fio->new_blkaddr & F2FS_IO_SIZE_MASK(sbi)) {
- err = -EAGAIN;
dec_page_count(sbi, WB_DATA_TYPE(bio_page));
- goto out_fail;
+ fio->retry = true;
+ goto skip;
}
io->bio = __bio_alloc(sbi, fio->new_blkaddr, fio->io_wbc,
BIO_MAX_PAGES, false,
fio->type, fio->temp);
if (bio_encrypted)
fscrypt_set_ice_dun(inode, io->bio, dun);
-
+ fscrypt_set_ice_skip(io->bio, bi_crypt_skip);
io->fio = *fio;
}
@@ -542,12 +546,11 @@
f2fs_trace_ios(fio, 0);
trace_f2fs_submit_page_write(fio->page, fio);
-
+skip:
if (fio->in_list)
goto next;
-out_fail:
+out:
up_write(&io->io_rwsem);
- return err;
}
static struct bio *f2fs_grab_read_bio(struct inode *inode, block_t blkaddr,
@@ -625,7 +628,7 @@
* ->node_page
* update block addresses in the node page
*/
-void set_data_blkaddr(struct dnode_of_data *dn)
+void f2fs_set_data_blkaddr(struct dnode_of_data *dn)
{
f2fs_wait_on_page_writeback(dn->node_page, NODE, true);
__set_data_blkaddr(dn);
@@ -636,12 +639,12 @@
void f2fs_update_data_blkaddr(struct dnode_of_data *dn, block_t blkaddr)
{
dn->data_blkaddr = blkaddr;
- set_data_blkaddr(dn);
+ f2fs_set_data_blkaddr(dn);
f2fs_update_extent_cache(dn);
}
/* dn->ofs_in_node will be returned with up-to-date last block pointer */
-int reserve_new_blocks(struct dnode_of_data *dn, blkcnt_t count)
+int f2fs_reserve_new_blocks(struct dnode_of_data *dn, blkcnt_t count)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
int err;
@@ -675,12 +678,12 @@
}
/* Should keep dn->ofs_in_node unchanged */
-int reserve_new_block(struct dnode_of_data *dn)
+int f2fs_reserve_new_block(struct dnode_of_data *dn)
{
unsigned int ofs_in_node = dn->ofs_in_node;
int ret;
- ret = reserve_new_blocks(dn, 1);
+ ret = f2fs_reserve_new_blocks(dn, 1);
dn->ofs_in_node = ofs_in_node;
return ret;
}
@@ -690,12 +693,12 @@
bool need_put = dn->inode_page ? false : true;
int err;
- err = get_dnode_of_data(dn, index, ALLOC_NODE);
+ err = f2fs_get_dnode_of_data(dn, index, ALLOC_NODE);
if (err)
return err;
if (dn->data_blkaddr == NULL_ADDR)
- err = reserve_new_block(dn);
+ err = f2fs_reserve_new_block(dn);
if (err || need_put)
f2fs_put_dnode(dn);
return err;
@@ -714,7 +717,7 @@
return f2fs_reserve_block(dn, index);
}
-struct page *get_read_data_page(struct inode *inode, pgoff_t index,
+struct page *f2fs_get_read_data_page(struct inode *inode, pgoff_t index,
int op_flags, bool for_write)
{
struct address_space *mapping = inode->i_mapping;
@@ -733,7 +736,7 @@
}
set_new_dnode(&dn, inode, NULL, NULL, 0);
- err = get_dnode_of_data(&dn, index, LOOKUP_NODE);
+ err = f2fs_get_dnode_of_data(&dn, index, LOOKUP_NODE);
if (err)
goto put_err;
f2fs_put_dnode(&dn);
@@ -752,7 +755,8 @@
* A new dentry page is allocated but not able to be written, since its
* new inode page couldn't be allocated due to -ENOSPC.
* In such the case, its blkaddr can be remained as NEW_ADDR.
- * see, f2fs_add_link -> get_new_data_page -> init_inode_metadata.
+ * see, f2fs_add_link -> f2fs_get_new_data_page ->
+ * f2fs_init_inode_metadata.
*/
if (dn.data_blkaddr == NEW_ADDR) {
zero_user_segment(page, 0, PAGE_SIZE);
@@ -772,7 +776,7 @@
return ERR_PTR(err);
}
-struct page *find_data_page(struct inode *inode, pgoff_t index)
+struct page *f2fs_find_data_page(struct inode *inode, pgoff_t index)
{
struct address_space *mapping = inode->i_mapping;
struct page *page;
@@ -782,7 +786,7 @@
return page;
f2fs_put_page(page, 0);
- page = get_read_data_page(inode, index, 0, false);
+ page = f2fs_get_read_data_page(inode, index, 0, false);
if (IS_ERR(page))
return page;
@@ -802,13 +806,13 @@
* Because, the callers, functions in dir.c and GC, should be able to know
* whether this page exists or not.
*/
-struct page *get_lock_data_page(struct inode *inode, pgoff_t index,
+struct page *f2fs_get_lock_data_page(struct inode *inode, pgoff_t index,
bool for_write)
{
struct address_space *mapping = inode->i_mapping;
struct page *page;
repeat:
- page = get_read_data_page(inode, index, 0, for_write);
+ page = f2fs_get_read_data_page(inode, index, 0, for_write);
if (IS_ERR(page))
return page;
@@ -834,7 +838,7 @@
* Note that, ipage is set only by make_empty_dir, and if any error occur,
* ipage should be released by this function.
*/
-struct page *get_new_data_page(struct inode *inode,
+struct page *f2fs_get_new_data_page(struct inode *inode,
struct page *ipage, pgoff_t index, bool new_i_size)
{
struct address_space *mapping = inode->i_mapping;
@@ -873,7 +877,7 @@
/* if ipage exists, blkaddr should be NEW_ADDR */
f2fs_bug_on(F2FS_I_SB(inode), ipage);
- page = get_lock_data_page(inode, index, true);
+ page = f2fs_get_lock_data_page(inode, index, true);
if (IS_ERR(page))
return page;
}
@@ -905,15 +909,15 @@
return err;
alloc:
- get_node_info(sbi, dn->nid, &ni);
+ f2fs_get_node_info(sbi, dn->nid, &ni);
set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version);
- allocate_data_block(sbi, NULL, dn->data_blkaddr, &dn->data_blkaddr,
+ f2fs_allocate_data_block(sbi, NULL, dn->data_blkaddr, &dn->data_blkaddr,
&sum, seg_type, NULL, false);
- set_data_blkaddr(dn);
+ f2fs_set_data_blkaddr(dn);
/* update i_size */
- fofs = start_bidx_of_node(ofs_of_node(dn->node_page), dn->inode) +
+ fofs = f2fs_start_bidx_of_node(ofs_of_node(dn->node_page), dn->inode) +
dn->ofs_in_node;
if (i_size_read(dn->inode) < ((loff_t)(fofs + 1) << PAGE_SHIFT))
f2fs_i_size_write(dn->inode,
@@ -951,7 +955,7 @@
map.m_seg_type = NO_CHECK_TYPE;
if (direct_io) {
- map.m_seg_type = rw_hint_to_seg_type(iocb->ki_hint);
+ map.m_seg_type = f2fs_rw_hint_to_seg_type(iocb->ki_hint);
flag = f2fs_force_buffered_io(inode, WRITE) ?
F2FS_GET_BLOCK_PRE_AIO :
F2FS_GET_BLOCK_PRE_DIO;
@@ -1041,7 +1045,7 @@
/* When reading holes, we need its node page */
set_new_dnode(&dn, inode, NULL, NULL, 0);
- err = get_dnode_of_data(&dn, pgofs, mode);
+ err = f2fs_get_dnode_of_data(&dn, pgofs, mode);
if (err) {
if (flag == F2FS_GET_BLOCK_BMAP)
map->m_pblk = 0;
@@ -1049,10 +1053,10 @@
err = 0;
if (map->m_next_pgofs)
*map->m_next_pgofs =
- get_next_page_offset(&dn, pgofs);
+ f2fs_get_next_page_offset(&dn, pgofs);
if (map->m_next_extent)
*map->m_next_extent =
- get_next_page_offset(&dn, pgofs);
+ f2fs_get_next_page_offset(&dn, pgofs);
}
goto unlock_out;
}
@@ -1065,7 +1069,7 @@
next_block:
blkaddr = datablock_addr(dn.inode, dn.node_page, dn.ofs_in_node);
- if (blkaddr == NEW_ADDR || blkaddr == NULL_ADDR) {
+ if (!is_valid_blkaddr(blkaddr)) {
if (create) {
if (unlikely(f2fs_cp_error(sbi))) {
err = -EIO;
@@ -1138,7 +1142,7 @@
(pgofs == end || dn.ofs_in_node == end_offset)) {
dn.ofs_in_node = ofs_in_node;
- err = reserve_new_blocks(&dn, prealloc);
+ err = f2fs_reserve_new_blocks(&dn, prealloc);
if (err)
goto sync_out;
@@ -1257,7 +1261,7 @@
{
return __get_data_block(inode, iblock, bh_result, create,
F2FS_GET_BLOCK_DEFAULT, NULL,
- rw_hint_to_seg_type(
+ f2fs_rw_hint_to_seg_type(
inode->i_write_hint));
}
@@ -1302,7 +1306,7 @@
if (!page)
return -ENOMEM;
- get_node_info(sbi, inode->i_ino, &ni);
+ f2fs_get_node_info(sbi, inode->i_ino, &ni);
phys = (__u64)blk_to_logical(inode, ni.blk_addr);
offset = offsetof(struct f2fs_inode, i_addr) +
@@ -1329,7 +1333,7 @@
if (!page)
return -ENOMEM;
- get_node_info(sbi, xnid, &ni);
+ f2fs_get_node_info(sbi, xnid, &ni);
phys = (__u64)blk_to_logical(inode, ni.blk_addr);
len = inode->i_sb->s_blocksize;
@@ -1538,7 +1542,7 @@
dun = PG_DUN(inode, page);
bio_encrypted = f2fs_may_encrypt_bio(inode, NULL);
- if (!fscrypt_mergeable_bio(bio, dun, bio_encrypted)) {
+ if (!fscrypt_mergeable_bio(bio, dun, bio_encrypted, 0)) {
__submit_bio(F2FS_I_SB(inode), bio, DATA);
bio = NULL;
}
@@ -1647,12 +1651,12 @@
if (policy & (0x1 << F2FS_IPU_FORCE))
return true;
- if (policy & (0x1 << F2FS_IPU_SSR) && need_SSR(sbi))
+ if (policy & (0x1 << F2FS_IPU_SSR) && f2fs_need_SSR(sbi))
return true;
if (policy & (0x1 << F2FS_IPU_UTIL) &&
utilization(sbi) > SM_I(sbi)->min_ipu_util)
return true;
- if (policy & (0x1 << F2FS_IPU_SSR_UTIL) && need_SSR(sbi) &&
+ if (policy & (0x1 << F2FS_IPU_SSR_UTIL) && f2fs_need_SSR(sbi) &&
utilization(sbi) > SM_I(sbi)->min_ipu_util)
return true;
@@ -1673,7 +1677,7 @@
return false;
}
-bool should_update_inplace(struct inode *inode, struct f2fs_io_info *fio)
+bool f2fs_should_update_inplace(struct inode *inode, struct f2fs_io_info *fio)
{
if (f2fs_is_pinned_file(inode))
return true;
@@ -1685,7 +1689,7 @@
return check_inplace_update_policy(inode, fio);
}
-bool should_update_outplace(struct inode *inode, struct f2fs_io_info *fio)
+bool f2fs_should_update_outplace(struct inode *inode, struct f2fs_io_info *fio)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
@@ -1708,22 +1712,13 @@
{
struct inode *inode = fio->page->mapping->host;
- if (should_update_outplace(inode, fio))
+ if (f2fs_should_update_outplace(inode, fio))
return false;
- return should_update_inplace(inode, fio);
+ return f2fs_should_update_inplace(inode, fio);
}
-static inline bool valid_ipu_blkaddr(struct f2fs_io_info *fio)
-{
- if (fio->old_blkaddr == NEW_ADDR)
- return false;
- if (fio->old_blkaddr == NULL_ADDR)
- return false;
- return true;
-}
-
-int do_write_data_page(struct f2fs_io_info *fio)
+int f2fs_do_write_data_page(struct f2fs_io_info *fio)
{
struct page *page = fio->page;
struct inode *inode = page->mapping->host;
@@ -1737,7 +1732,7 @@
f2fs_lookup_extent_cache(inode, page->index, &ei)) {
fio->old_blkaddr = ei.blk + page->index - ei.fofs;
- if (valid_ipu_blkaddr(fio)) {
+ if (is_valid_blkaddr(fio->old_blkaddr)) {
ipu_force = true;
fio->need_lock = LOCK_DONE;
goto got_it;
@@ -1748,7 +1743,7 @@
if (fio->need_lock == LOCK_REQ && !f2fs_trylock_op(fio->sbi))
return -EAGAIN;
- err = get_dnode_of_data(&dn, page->index, LOOKUP_NODE);
+ err = f2fs_get_dnode_of_data(&dn, page->index, LOOKUP_NODE);
if (err)
goto out;
@@ -1764,7 +1759,8 @@
* If current allocation needs SSR,
* it had better in-place writes for updated data.
*/
- if (ipu_force || (valid_ipu_blkaddr(fio) && need_inplace_update(fio))) {
+ if (ipu_force || (is_valid_blkaddr(fio->old_blkaddr) &&
+ need_inplace_update(fio))) {
err = encrypt_one_page(fio);
if (err)
goto out_writepage;
@@ -1774,7 +1770,7 @@
f2fs_put_dnode(&dn);
if (fio->need_lock == LOCK_REQ)
f2fs_unlock_op(fio->sbi);
- err = rewrite_data_page(fio);
+ err = f2fs_inplace_write_data(fio);
trace_f2fs_do_write_data_page(fio->page, IPU);
set_inode_flag(inode, FI_UPDATE_WRITE);
return err;
@@ -1796,7 +1792,7 @@
ClearPageError(page);
/* LFS mode write path */
- write_data_page(&dn, fio);
+ f2fs_outplace_write_data(&dn, fio);
trace_f2fs_do_write_data_page(page, OPU);
set_inode_flag(inode, FI_APPEND_WRITE);
if (page->index == 0)
@@ -1842,6 +1838,12 @@
/* we should bypass data pages to proceed the kworkder jobs */
if (unlikely(f2fs_cp_error(sbi))) {
mapping_set_error(page->mapping, -EIO);
+ /*
+ * don't drop any dirty dentry pages for keeping lastest
+ * directory structure.
+ */
+ if (S_ISDIR(inode->i_mode))
+ goto redirty_out;
goto out;
}
@@ -1866,13 +1868,13 @@
/* we should not write 0'th page having journal header */
if (f2fs_is_volatile_file(inode) && (!page->index ||
(!wbc->for_reclaim &&
- available_free_memory(sbi, BASE_CHECK))))
+ f2fs_available_free_memory(sbi, BASE_CHECK))))
goto redirty_out;
/* Dentry blocks are controlled by checkpoint */
if (S_ISDIR(inode->i_mode)) {
fio.need_lock = LOCK_DONE;
- err = do_write_data_page(&fio);
+ err = f2fs_do_write_data_page(&fio);
goto done;
}
@@ -1891,10 +1893,10 @@
}
if (err == -EAGAIN) {
- err = do_write_data_page(&fio);
+ err = f2fs_do_write_data_page(&fio);
if (err == -EAGAIN) {
fio.need_lock = LOCK_REQ;
- err = do_write_data_page(&fio);
+ err = f2fs_do_write_data_page(&fio);
}
}
@@ -1919,7 +1921,7 @@
if (wbc->for_reclaim) {
f2fs_submit_merged_write_cond(sbi, inode, 0, page->index, DATA);
clear_inode_flag(inode, FI_HOT_DATA);
- remove_dirty_inode(inode);
+ f2fs_remove_dirty_inode(inode);
submitted = NULL;
}
@@ -1969,6 +1971,7 @@
int ret = 0;
int done = 0;
struct pagevec pvec;
+ struct f2fs_sb_info *sbi = F2FS_M_SB(mapping);
int nr_pages;
pgoff_t uninitialized_var(writeback_index);
pgoff_t index;
@@ -2013,8 +2016,8 @@
while (!done && (index <= end)) {
int i;
- nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, tag,
- min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1);
+ nr_pages = pagevec_lookup_range_tag(&pvec, mapping, &index, end,
+ tag);
if (nr_pages == 0)
break;
@@ -2022,7 +2025,9 @@
struct page *page = pvec.pages[i];
bool submitted = false;
- if (page->index > end) {
+ /* give a priority to WB_SYNC threads */
+ if (atomic_read(&sbi->wb_sync_req[DATA]) &&
+ wbc->sync_mode == WB_SYNC_NONE) {
done = 1;
break;
}
@@ -2081,9 +2086,7 @@
last_idx = page->index;
}
- /* give a priority to WB_SYNC threads */
- if ((atomic_read(&F2FS_M_SB(mapping)->wb_sync_req) ||
- --wbc->nr_to_write <= 0) &&
+ if (--wbc->nr_to_write <= 0 &&
wbc->sync_mode == WB_SYNC_NONE) {
done = 1;
break;
@@ -2121,7 +2124,7 @@
return false;
}
-int __f2fs_write_data_pages(struct address_space *mapping,
+static int __f2fs_write_data_pages(struct address_space *mapping,
struct writeback_control *wbc,
enum iostat_type io_type)
{
@@ -2145,7 +2148,7 @@
if (S_ISDIR(inode->i_mode) && wbc->sync_mode == WB_SYNC_NONE &&
get_dirty_pages(inode) < nr_pages_to_skip(sbi, DATA) &&
- available_free_memory(sbi, DIRTY_DENTS))
+ f2fs_available_free_memory(sbi, DIRTY_DENTS))
goto skip_write;
/* skip writing during file defragment */
@@ -2156,8 +2159,8 @@
/* to avoid spliting IOs due to mixed WB_SYNC_ALL and WB_SYNC_NONE */
if (wbc->sync_mode == WB_SYNC_ALL)
- atomic_inc(&sbi->wb_sync_req);
- else if (atomic_read(&sbi->wb_sync_req))
+ atomic_inc(&sbi->wb_sync_req[DATA]);
+ else if (atomic_read(&sbi->wb_sync_req[DATA]))
goto skip_write;
if (__should_serialize_io(inode, wbc)) {
@@ -2173,13 +2176,13 @@
mutex_unlock(&sbi->writepages);
if (wbc->sync_mode == WB_SYNC_ALL)
- atomic_dec(&sbi->wb_sync_req);
+ atomic_dec(&sbi->wb_sync_req[DATA]);
/*
* if some pages were truncated, we cannot guarantee its mapping->host
* to detect pending bios.
*/
- remove_dirty_inode(inode);
+ f2fs_remove_dirty_inode(inode);
return ret;
skip_write:
@@ -2206,7 +2209,7 @@
if (to > i_size) {
down_write(&F2FS_I(inode)->i_mmap_sem);
truncate_pagecache(inode, i_size);
- truncate_blocks(inode, i_size, true);
+ f2fs_truncate_blocks(inode, i_size, true);
up_write(&F2FS_I(inode)->i_mmap_sem);
}
}
@@ -2238,7 +2241,7 @@
}
restart:
/* check inline_data */
- ipage = get_node_page(sbi, inode->i_ino);
+ ipage = f2fs_get_node_page(sbi, inode->i_ino);
if (IS_ERR(ipage)) {
err = PTR_ERR(ipage);
goto unlock_out;
@@ -2248,7 +2251,7 @@
if (f2fs_has_inline_data(inode)) {
if (pos + len <= MAX_INLINE_DATA(inode)) {
- read_inline_data(page, ipage);
+ f2fs_do_read_inline_data(page, ipage);
set_inode_flag(inode, FI_DATA_EXIST);
if (inode->i_nlink)
set_inline_node(ipage);
@@ -2266,7 +2269,7 @@
dn.data_blkaddr = ei.blk + index - ei.fofs;
} else {
/* hole case */
- err = get_dnode_of_data(&dn, index, LOOKUP_NODE);
+ err = f2fs_get_dnode_of_data(&dn, index, LOOKUP_NODE);
if (err || dn.data_blkaddr == NULL_ADDR) {
f2fs_put_dnode(&dn);
__do_map_lock(sbi, F2FS_GET_BLOCK_PRE_AIO,
@@ -2313,7 +2316,7 @@
trace_f2fs_write_begin(inode, pos, len, flags);
if (f2fs_is_atomic_file(inode) &&
- !available_free_memory(sbi, INMEM_PAGES)) {
+ !f2fs_available_free_memory(sbi, INMEM_PAGES)) {
err = -ENOMEM;
drop_atomic = true;
goto fail;
@@ -2397,7 +2400,7 @@
f2fs_put_page(page, 1);
f2fs_write_failed(mapping, pos + len);
if (drop_atomic)
- drop_inmem_pages_all(sbi);
+ f2fs_drop_inmem_pages_all(sbi, false);
return err;
}
@@ -2495,17 +2498,17 @@
if (rw == WRITE && whint_mode == WHINT_MODE_OFF)
iocb->ki_hint = WRITE_LIFE_NOT_SET;
- if (!down_read_trylock(&F2FS_I(inode)->dio_rwsem[rw])) {
+ if (!down_read_trylock(&F2FS_I(inode)->i_gc_rwsem[rw])) {
if (iocb->ki_flags & IOCB_NOWAIT) {
iocb->ki_hint = hint;
err = -EAGAIN;
goto out;
}
- down_read(&F2FS_I(inode)->dio_rwsem[rw]);
+ down_read(&F2FS_I(inode)->i_gc_rwsem[rw]);
}
err = blockdev_direct_IO(iocb, inode, iter, get_data_block_dio);
- up_read(&F2FS_I(inode)->dio_rwsem[rw]);
+ up_read(&F2FS_I(inode)->i_gc_rwsem[rw]);
if (rw == WRITE) {
if (whint_mode == WHINT_MODE_OFF)
@@ -2548,13 +2551,13 @@
dec_page_count(sbi, F2FS_DIRTY_NODES);
} else {
inode_dec_dirty_pages(inode);
- remove_dirty_inode(inode);
+ f2fs_remove_dirty_inode(inode);
}
}
/* This is atomic written page, keep Private */
if (IS_ATOMIC_WRITTEN_PAGE(page))
- return drop_inmem_page(inode, page);
+ return f2fs_drop_inmem_page(inode, page);
set_page_private(page, 0);
ClearPagePrivate(page);
@@ -2587,7 +2590,7 @@
if (f2fs_is_atomic_file(inode) && !f2fs_is_commit_atomic_write(inode)) {
if (!IS_ATOMIC_WRITTEN_PAGE(page)) {
- register_inmem_page(inode, page);
+ f2fs_register_inmem_page(inode, page);
return 1;
}
/*
@@ -2599,7 +2602,7 @@
if (!PageDirty(page)) {
__set_page_dirty_nobuffers(page);
- update_dirty_page(inode, page);
+ f2fs_update_dirty_page(inode, page);
return 1;
}
return 0;
@@ -2692,6 +2695,17 @@
#endif
};
+void f2fs_clear_radix_tree_dirty_tag(struct page *page)
+{
+ struct address_space *mapping = page_mapping(page);
+ unsigned long flags;
+
+ spin_lock_irqsave(&mapping->tree_lock, flags);
+ radix_tree_tag_clear(&mapping->page_tree, page_index(page),
+ PAGECACHE_TAG_DIRTY);
+ spin_unlock_irqrestore(&mapping->tree_lock, flags);
+}
+
int __init f2fs_init_post_read_processing(void)
{
bio_post_read_ctx_cache = KMEM_CACHE(bio_post_read_ctx, 0);
diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
index a66107b..2d65e77 100644
--- a/fs/f2fs/debug.c
+++ b/fs/f2fs/debug.c
@@ -104,6 +104,8 @@
si->avail_nids = NM_I(sbi)->available_nids;
si->alloc_nids = NM_I(sbi)->nid_cnt[PREALLOC_NID];
si->bg_gc = sbi->bg_gc;
+ si->skipped_atomic_files[BG_GC] = sbi->skipped_atomic_files[BG_GC];
+ si->skipped_atomic_files[FG_GC] = sbi->skipped_atomic_files[FG_GC];
si->util_free = (int)(free_user_blocks(sbi) >> sbi->log_blocks_per_seg)
* 100 / (int)(sbi->user_block_count >> sbi->log_blocks_per_seg)
/ 2;
@@ -342,6 +344,10 @@
si->bg_data_blks);
seq_printf(s, " - node blocks : %d (%d)\n", si->node_blks,
si->bg_node_blks);
+ seq_printf(s, "Skipped : atomic write %llu (%llu)\n",
+ si->skipped_atomic_files[BG_GC] +
+ si->skipped_atomic_files[FG_GC],
+ si->skipped_atomic_files[BG_GC]);
seq_puts(s, "\nExtent Cache:\n");
seq_printf(s, " - Hit Count: L1-1:%llu L1-2:%llu L2:%llu\n",
si->hit_largest, si->hit_cached,
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index f9a1e18..63c0732 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -60,12 +60,12 @@
[S_IFLNK >> S_SHIFT] = F2FS_FT_SYMLINK,
};
-void set_de_type(struct f2fs_dir_entry *de, umode_t mode)
+static void set_de_type(struct f2fs_dir_entry *de, umode_t mode)
{
de->file_type = f2fs_type_by_mode[(mode & S_IFMT) >> S_SHIFT];
}
-unsigned char get_de_type(struct f2fs_dir_entry *de)
+unsigned char f2fs_get_de_type(struct f2fs_dir_entry *de)
{
if (de->file_type < F2FS_FT_MAX)
return f2fs_filetype_table[de->file_type];
@@ -97,14 +97,14 @@
dentry_blk = (struct f2fs_dentry_block *)page_address(dentry_page);
make_dentry_ptr_block(NULL, &d, dentry_blk);
- de = find_target_dentry(fname, namehash, max_slots, &d);
+ de = f2fs_find_target_dentry(fname, namehash, max_slots, &d);
if (de)
*res_page = dentry_page;
return de;
}
-struct f2fs_dir_entry *find_target_dentry(struct fscrypt_name *fname,
+struct f2fs_dir_entry *f2fs_find_target_dentry(struct fscrypt_name *fname,
f2fs_hash_t namehash, int *max_slots,
struct f2fs_dentry_ptr *d)
{
@@ -171,7 +171,7 @@
for (; bidx < end_block; bidx++) {
/* no need to allocate new dentry pages to all the indices */
- dentry_page = find_data_page(dir, bidx);
+ dentry_page = f2fs_find_data_page(dir, bidx);
if (IS_ERR(dentry_page)) {
if (PTR_ERR(dentry_page) == -ENOENT) {
room = true;
@@ -210,7 +210,7 @@
if (f2fs_has_inline_dentry(dir)) {
*res_page = NULL;
- de = find_in_inline_dir(dir, fname, res_page);
+ de = f2fs_find_in_inline_dir(dir, fname, res_page);
goto out;
}
@@ -319,7 +319,7 @@
set_page_dirty(ipage);
}
-void do_make_empty_dir(struct inode *inode, struct inode *parent,
+void f2fs_do_make_empty_dir(struct inode *inode, struct inode *parent,
struct f2fs_dentry_ptr *d)
{
struct qstr dot = QSTR_INIT(".", 1);
@@ -340,23 +340,23 @@
struct f2fs_dentry_ptr d;
if (f2fs_has_inline_dentry(inode))
- return make_empty_inline_dir(inode, parent, page);
+ return f2fs_make_empty_inline_dir(inode, parent, page);
- dentry_page = get_new_data_page(inode, page, 0, true);
+ dentry_page = f2fs_get_new_data_page(inode, page, 0, true);
if (IS_ERR(dentry_page))
return PTR_ERR(dentry_page);
dentry_blk = page_address(dentry_page);
make_dentry_ptr_block(NULL, &d, dentry_blk);
- do_make_empty_dir(inode, parent, &d);
+ f2fs_do_make_empty_dir(inode, parent, &d);
set_page_dirty(dentry_page);
f2fs_put_page(dentry_page, 1);
return 0;
}
-struct page *init_inode_metadata(struct inode *inode, struct inode *dir,
+struct page *f2fs_init_inode_metadata(struct inode *inode, struct inode *dir,
const struct qstr *new_name, const struct qstr *orig_name,
struct page *dpage)
{
@@ -365,7 +365,7 @@
int err;
if (is_inode_flag_set(inode, FI_NEW_INODE)) {
- page = new_inode_page(inode);
+ page = f2fs_new_inode_page(inode);
if (IS_ERR(page))
return page;
@@ -395,7 +395,7 @@
goto put_error;
}
} else {
- page = get_node_page(F2FS_I_SB(dir), inode->i_ino);
+ page = f2fs_get_node_page(F2FS_I_SB(dir), inode->i_ino);
if (IS_ERR(page))
return page;
}
@@ -418,19 +418,19 @@
* we should remove this inode from orphan list.
*/
if (inode->i_nlink == 0)
- remove_orphan_inode(F2FS_I_SB(dir), inode->i_ino);
+ f2fs_remove_orphan_inode(F2FS_I_SB(dir), inode->i_ino);
f2fs_i_links_write(inode, true);
}
return page;
put_error:
clear_nlink(inode);
- update_inode(inode, page);
+ f2fs_update_inode(inode, page);
f2fs_put_page(page, 1);
return ERR_PTR(err);
}
-void update_parent_metadata(struct inode *dir, struct inode *inode,
+void f2fs_update_parent_metadata(struct inode *dir, struct inode *inode,
unsigned int current_depth)
{
if (inode && is_inode_flag_set(inode, FI_NEW_INODE)) {
@@ -448,7 +448,7 @@
clear_inode_flag(inode, FI_INC_LINK);
}
-int room_for_filename(const void *bitmap, int slots, int max_slots)
+int f2fs_room_for_filename(const void *bitmap, int slots, int max_slots)
{
int bit_start = 0;
int zero_start, zero_end;
@@ -537,12 +537,12 @@
(le32_to_cpu(dentry_hash) % nbucket));
for (block = bidx; block <= (bidx + nblock - 1); block++) {
- dentry_page = get_new_data_page(dir, NULL, block, true);
+ dentry_page = f2fs_get_new_data_page(dir, NULL, block, true);
if (IS_ERR(dentry_page))
return PTR_ERR(dentry_page);
dentry_blk = page_address(dentry_page);
- bit_pos = room_for_filename(&dentry_blk->dentry_bitmap,
+ bit_pos = f2fs_room_for_filename(&dentry_blk->dentry_bitmap,
slots, NR_DENTRY_IN_BLOCK);
if (bit_pos < NR_DENTRY_IN_BLOCK)
goto add_dentry;
@@ -558,7 +558,7 @@
if (inode) {
down_write(&F2FS_I(inode)->i_sem);
- page = init_inode_metadata(inode, dir, new_name,
+ page = f2fs_init_inode_metadata(inode, dir, new_name,
orig_name, NULL);
if (IS_ERR(page)) {
err = PTR_ERR(page);
@@ -576,7 +576,7 @@
f2fs_put_page(page, 1);
}
- update_parent_metadata(dir, inode, current_depth);
+ f2fs_update_parent_metadata(dir, inode, current_depth);
fail:
if (inode)
up_write(&F2FS_I(inode)->i_sem);
@@ -586,7 +586,7 @@
return err;
}
-int __f2fs_do_add_link(struct inode *dir, struct fscrypt_name *fname,
+int f2fs_add_dentry(struct inode *dir, struct fscrypt_name *fname,
struct inode *inode, nid_t ino, umode_t mode)
{
struct qstr new_name;
@@ -610,7 +610,7 @@
* Caller should grab and release a rwsem by calling f2fs_lock_op() and
* f2fs_unlock_op().
*/
-int __f2fs_add_link(struct inode *dir, const struct qstr *name,
+int f2fs_do_add_link(struct inode *dir, const struct qstr *name,
struct inode *inode, nid_t ino, umode_t mode)
{
struct fscrypt_name fname;
@@ -639,7 +639,7 @@
} else if (IS_ERR(page)) {
err = PTR_ERR(page);
} else {
- err = __f2fs_do_add_link(dir, &fname, inode, ino, mode);
+ err = f2fs_add_dentry(dir, &fname, inode, ino, mode);
}
fscrypt_free_filename(&fname);
return err;
@@ -651,7 +651,7 @@
int err = 0;
down_write(&F2FS_I(inode)->i_sem);
- page = init_inode_metadata(inode, dir, NULL, NULL, NULL);
+ page = f2fs_init_inode_metadata(inode, dir, NULL, NULL, NULL);
if (IS_ERR(page)) {
err = PTR_ERR(page);
goto fail;
@@ -683,9 +683,9 @@
up_write(&F2FS_I(inode)->i_sem);
if (inode->i_nlink == 0)
- add_orphan_inode(inode);
+ f2fs_add_orphan_inode(inode);
else
- release_orphan_inode(sbi);
+ f2fs_release_orphan_inode(sbi);
}
/*
@@ -698,14 +698,12 @@
struct f2fs_dentry_block *dentry_blk;
unsigned int bit_pos;
int slots = GET_DENTRY_SLOTS(le16_to_cpu(dentry->name_len));
- struct address_space *mapping = page_mapping(page);
- unsigned long flags;
int i;
f2fs_update_time(F2FS_I_SB(dir), REQ_TIME);
if (F2FS_OPTION(F2FS_I_SB(dir)).fsync_mode == FSYNC_MODE_STRICT)
- add_ino_entry(F2FS_I_SB(dir), dir->i_ino, TRANS_DIR_INO);
+ f2fs_add_ino_entry(F2FS_I_SB(dir), dir->i_ino, TRANS_DIR_INO);
if (f2fs_has_inline_dentry(dir))
return f2fs_delete_inline_entry(dentry, page, dir, inode);
@@ -731,17 +729,13 @@
f2fs_drop_nlink(dir, inode);
if (bit_pos == NR_DENTRY_IN_BLOCK &&
- !truncate_hole(dir, page->index, page->index + 1)) {
- spin_lock_irqsave(&mapping->tree_lock, flags);
- radix_tree_tag_clear(&mapping->page_tree, page_index(page),
- PAGECACHE_TAG_DIRTY);
- spin_unlock_irqrestore(&mapping->tree_lock, flags);
-
+ !f2fs_truncate_hole(dir, page->index, page->index + 1)) {
+ f2fs_clear_radix_tree_dirty_tag(page);
clear_page_dirty_for_io(page);
ClearPagePrivate(page);
ClearPageUptodate(page);
inode_dec_dirty_pages(dir);
- remove_dirty_inode(dir);
+ f2fs_remove_dirty_inode(dir);
}
f2fs_put_page(page, 1);
}
@@ -758,7 +752,7 @@
return f2fs_empty_inline_dir(dir);
for (bidx = 0; bidx < nblock; bidx++) {
- dentry_page = get_lock_data_page(dir, bidx, false);
+ dentry_page = f2fs_get_lock_data_page(dir, bidx, false);
if (IS_ERR(dentry_page)) {
if (PTR_ERR(dentry_page) == -ENOENT)
continue;
@@ -806,7 +800,7 @@
continue;
}
- d_type = get_de_type(de);
+ d_type = f2fs_get_de_type(de);
de_name.name = d->filename[bit_pos];
de_name.len = le16_to_cpu(de->name_len);
@@ -830,7 +824,7 @@
return 1;
if (sbi->readdir_ra == 1)
- ra_node_page(sbi, le32_to_cpu(de->ino));
+ f2fs_ra_node_page(sbi, le32_to_cpu(de->ino));
bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len));
ctx->pos = start_pos + bit_pos;
@@ -880,7 +874,7 @@
page_cache_sync_readahead(inode->i_mapping, ra, file, n,
min(npages - n, (pgoff_t)MAX_DIR_RA_PAGES));
- dentry_page = get_lock_data_page(inode, n, false);
+ dentry_page = f2fs_get_lock_data_page(inode, n, false);
if (IS_ERR(dentry_page)) {
err = PTR_ERR(dentry_page);
if (err == -ENOENT) {
diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c
index d5a861b..231b77e 100644
--- a/fs/f2fs/extent_cache.c
+++ b/fs/f2fs/extent_cache.c
@@ -49,7 +49,7 @@
return NULL;
}
-struct rb_entry *__lookup_rb_tree(struct rb_root *root,
+struct rb_entry *f2fs_lookup_rb_tree(struct rb_root *root,
struct rb_entry *cached_re, unsigned int ofs)
{
struct rb_entry *re;
@@ -61,7 +61,7 @@
return re;
}
-struct rb_node **__lookup_rb_tree_for_insert(struct f2fs_sb_info *sbi,
+struct rb_node **f2fs_lookup_rb_tree_for_insert(struct f2fs_sb_info *sbi,
struct rb_root *root, struct rb_node **parent,
unsigned int ofs)
{
@@ -92,7 +92,7 @@
* in order to simpfy the insertion after.
* tree must stay unchanged between lookup and insertion.
*/
-struct rb_entry *__lookup_rb_tree_ret(struct rb_root *root,
+struct rb_entry *f2fs_lookup_rb_tree_ret(struct rb_root *root,
struct rb_entry *cached_re,
unsigned int ofs,
struct rb_entry **prev_entry,
@@ -159,7 +159,7 @@
return re;
}
-bool __check_rb_tree_consistence(struct f2fs_sb_info *sbi,
+bool f2fs_check_rb_tree_consistence(struct f2fs_sb_info *sbi,
struct rb_root *root)
{
#ifdef CONFIG_F2FS_CHECK_FS
@@ -390,7 +390,7 @@
goto out;
}
- en = (struct extent_node *)__lookup_rb_tree(&et->root,
+ en = (struct extent_node *)f2fs_lookup_rb_tree(&et->root,
(struct rb_entry *)et->cached_en, pgofs);
if (!en)
goto out;
@@ -470,7 +470,7 @@
goto do_insert;
}
- p = __lookup_rb_tree_for_insert(sbi, &et->root, &parent, ei->fofs);
+ p = f2fs_lookup_rb_tree_for_insert(sbi, &et->root, &parent, ei->fofs);
do_insert:
en = __attach_extent_node(sbi, et, ei, parent, p);
if (!en)
@@ -520,7 +520,7 @@
__drop_largest_extent(inode, fofs, len);
/* 1. lookup first extent node in range [fofs, fofs + len - 1] */
- en = (struct extent_node *)__lookup_rb_tree_ret(&et->root,
+ en = (struct extent_node *)f2fs_lookup_rb_tree_ret(&et->root,
(struct rb_entry *)et->cached_en, fofs,
(struct rb_entry **)&prev_en,
(struct rb_entry **)&next_en,
@@ -773,7 +773,7 @@
else
blkaddr = dn->data_blkaddr;
- fofs = start_bidx_of_node(ofs_of_node(dn->node_page), dn->inode) +
+ fofs = f2fs_start_bidx_of_node(ofs_of_node(dn->node_page), dn->inode) +
dn->ofs_in_node;
f2fs_update_extent_tree_range(dn->inode, fofs, blkaddr, 1);
}
@@ -788,7 +788,7 @@
f2fs_update_extent_tree_range(dn->inode, fofs, blkaddr, len);
}
-void init_extent_cache_info(struct f2fs_sb_info *sbi)
+void f2fs_init_extent_cache_info(struct f2fs_sb_info *sbi)
{
INIT_RADIX_TREE(&sbi->extent_tree_root, GFP_NOIO);
mutex_init(&sbi->extent_tree_lock);
@@ -800,7 +800,7 @@
atomic_set(&sbi->total_ext_node, 0);
}
-int __init create_extent_cache(void)
+int __init f2fs_create_extent_cache(void)
{
extent_tree_slab = f2fs_kmem_cache_create("f2fs_extent_tree",
sizeof(struct extent_tree));
@@ -815,7 +815,7 @@
return 0;
}
-void destroy_extent_cache(void)
+void f2fs_destroy_extent_cache(void)
{
kmem_cache_destroy(extent_node_slab);
kmem_cache_destroy(extent_tree_slab);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 4c4b51a..b696bc8 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -26,6 +26,7 @@
#include <linux/blkdev.h>
#include <linux/quotaops.h>
#include <crypto/hash.h>
+#include <linux/overflow.h>
#define __FS_HAS_ENCRYPTION IS_ENABLED(CONFIG_F2FS_FS_ENCRYPTION)
#include <linux/fscrypt.h>
@@ -181,6 +182,7 @@
#define DEF_MAX_DISCARD_REQUEST 8 /* issue 8 discards per round */
#define DEF_MAX_DISCARD_LEN 512 /* Max. 2MB per discard */
#define DEF_MIN_DISCARD_ISSUE_TIME 50 /* 50 ms, if exists */
+#define DEF_MID_DISCARD_ISSUE_TIME 500 /* 500 ms, if device busy */
#define DEF_MAX_DISCARD_ISSUE_TIME 60000 /* 60 s, if no candidates */
#define DEF_DISCARD_URGENT_UTIL 80 /* do more discard over 80% */
#define DEF_CP_INTERVAL 60 /* 60 secs */
@@ -283,6 +285,7 @@
struct discard_policy {
int type; /* type of discard */
unsigned int min_interval; /* used for candidates exist */
+ unsigned int mid_interval; /* used for device busy */
unsigned int max_interval; /* used for candidates not exist */
unsigned int max_requests; /* # of discards issued per round */
unsigned int io_aware_gran; /* minimum granularity discard not be aware of I/O */
@@ -615,15 +618,20 @@
#define DEF_DIR_LEVEL 0
+enum {
+ GC_FAILURE_PIN,
+ GC_FAILURE_ATOMIC,
+ MAX_GC_FAILURE
+};
+
struct f2fs_inode_info {
struct inode vfs_inode; /* serve a vfs inode */
unsigned long i_flags; /* keep an inode flags for ioctl */
unsigned char i_advise; /* use to give file attribute hints */
unsigned char i_dir_level; /* use for dentry level for large dir */
- union {
- unsigned int i_current_depth; /* only for directory depth */
- unsigned short i_gc_failures; /* only for regular file */
- };
+ unsigned int i_current_depth; /* only for directory depth */
+ /* for gc failure statistic */
+ unsigned int i_gc_failures[MAX_GC_FAILURE];
unsigned int i_pino; /* parent inode number */
umode_t i_acl_mode; /* keep file acl mode temporarily */
@@ -651,7 +659,9 @@
struct task_struct *inmem_task; /* store inmemory task */
struct mutex inmem_lock; /* lock for inmemory pages */
struct extent_tree *extent_tree; /* cached extent_tree entry */
- struct rw_semaphore dio_rwsem[2];/* avoid racing between dio and gc */
+
+ /* avoid racing between foreground op and gc */
+ struct rw_semaphore i_gc_rwsem[2];
struct rw_semaphore i_mmap_sem;
struct rw_semaphore i_xattr_sem; /* avoid racing between reading and changing EAs */
@@ -1002,6 +1012,7 @@
int need_lock; /* indicate we need to lock cp_rwsem */
bool in_list; /* indicate fio is in io_list */
bool is_meta; /* indicate borrow meta inode mapping or not */
+ bool retry; /* need to reallocate block address */
enum iostat_type io_type; /* io type */
struct writeback_control *io_wbc; /* writeback control */
};
@@ -1064,6 +1075,13 @@
};
enum {
+ GC_NORMAL,
+ GC_IDLE_CB,
+ GC_IDLE_GREEDY,
+ GC_URGENT,
+};
+
+enum {
WHINT_MODE_OFF, /* not pass down write hints */
WHINT_MODE_USER, /* try to pass down hints given by users */
WHINT_MODE_FS, /* pass down hints with F2FS policy */
@@ -1112,6 +1130,8 @@
struct f2fs_bio_info *write_io[NR_PAGE_TYPE]; /* for write bios */
struct mutex wio_mutex[NR_PAGE_TYPE - 1][NR_TEMP_TYPE];
/* bio ordering for NODE/DATA */
+ /* keep migration IO order for LFS mode */
+ struct rw_semaphore io_order_lock;
mempool_t *write_io_dummy; /* Dummy pages */
/* for checkpoint */
@@ -1182,7 +1202,7 @@
struct percpu_counter alloc_valid_block_count;
/* writeback control */
- atomic_t wb_sync_req; /* count # of WB_SYNC threads */
+ atomic_t wb_sync_req[META]; /* count # of WB_SYNC threads */
/* valid inode count */
struct percpu_counter total_valid_inode_count;
@@ -1193,9 +1213,9 @@
struct mutex gc_mutex; /* mutex for GC */
struct f2fs_gc_kthread *gc_thread; /* GC thread */
unsigned int cur_victim_sec; /* current victim section num */
-
- /* threshold for converting bg victims for fg */
- u64 fggc_threshold;
+ unsigned int gc_mode; /* current GC state */
+ /* for skip statistic */
+ unsigned long long skipped_atomic_files[2]; /* FG_GC and BG_GC */
/* threshold for gc trials on pinned files */
u64 gc_pin_file_threshold;
@@ -1586,18 +1606,6 @@
}
/*
- * Check whether the given nid is within node id range.
- */
-static inline int check_nid_range(struct f2fs_sb_info *sbi, nid_t nid)
-{
- if (unlikely(nid < F2FS_ROOT_INO(sbi)))
- return -EINVAL;
- if (unlikely(nid >= NM_I(sbi)->max_nid))
- return -EINVAL;
- return 0;
-}
-
-/*
* Check whether the inode has blocks or not
*/
static inline int F2FS_HAS_BLOCKS(struct inode *inode)
@@ -2155,9 +2163,60 @@
*addr ^= mask;
}
-#define F2FS_REG_FLMASK (~(FS_DIRSYNC_FL | FS_TOPDIR_FL))
-#define F2FS_OTHER_FLMASK (FS_NODUMP_FL | FS_NOATIME_FL)
-#define F2FS_FL_INHERITED (FS_PROJINHERIT_FL)
+/*
+ * Inode flags
+ */
+#define F2FS_SECRM_FL 0x00000001 /* Secure deletion */
+#define F2FS_UNRM_FL 0x00000002 /* Undelete */
+#define F2FS_COMPR_FL 0x00000004 /* Compress file */
+#define F2FS_SYNC_FL 0x00000008 /* Synchronous updates */
+#define F2FS_IMMUTABLE_FL 0x00000010 /* Immutable file */
+#define F2FS_APPEND_FL 0x00000020 /* writes to file may only append */
+#define F2FS_NODUMP_FL 0x00000040 /* do not dump file */
+#define F2FS_NOATIME_FL 0x00000080 /* do not update atime */
+/* Reserved for compression usage... */
+#define F2FS_DIRTY_FL 0x00000100
+#define F2FS_COMPRBLK_FL 0x00000200 /* One or more compressed clusters */
+#define F2FS_NOCOMPR_FL 0x00000400 /* Don't compress */
+#define F2FS_ENCRYPT_FL 0x00000800 /* encrypted file */
+/* End compression flags --- maybe not all used */
+#define F2FS_INDEX_FL 0x00001000 /* hash-indexed directory */
+#define F2FS_IMAGIC_FL 0x00002000 /* AFS directory */
+#define F2FS_JOURNAL_DATA_FL 0x00004000 /* file data should be journaled */
+#define F2FS_NOTAIL_FL 0x00008000 /* file tail should not be merged */
+#define F2FS_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */
+#define F2FS_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/
+#define F2FS_HUGE_FILE_FL 0x00040000 /* Set to each huge file */
+#define F2FS_EXTENTS_FL 0x00080000 /* Inode uses extents */
+#define F2FS_EA_INODE_FL 0x00200000 /* Inode used for large EA */
+#define F2FS_EOFBLOCKS_FL 0x00400000 /* Blocks allocated beyond EOF */
+#define F2FS_INLINE_DATA_FL 0x10000000 /* Inode has inline data. */
+#define F2FS_PROJINHERIT_FL 0x20000000 /* Create with parents projid */
+#define F2FS_RESERVED_FL 0x80000000 /* reserved for ext4 lib */
+
+#define F2FS_FL_USER_VISIBLE 0x304BDFFF /* User visible flags */
+#define F2FS_FL_USER_MODIFIABLE 0x204BC0FF /* User modifiable flags */
+
+/* Flags we can manipulate with through F2FS_IOC_FSSETXATTR */
+#define F2FS_FL_XFLAG_VISIBLE (F2FS_SYNC_FL | \
+ F2FS_IMMUTABLE_FL | \
+ F2FS_APPEND_FL | \
+ F2FS_NODUMP_FL | \
+ F2FS_NOATIME_FL | \
+ F2FS_PROJINHERIT_FL)
+
+/* Flags that should be inherited by new inodes from their parent. */
+#define F2FS_FL_INHERITED (F2FS_SECRM_FL | F2FS_UNRM_FL | F2FS_COMPR_FL |\
+ F2FS_SYNC_FL | F2FS_NODUMP_FL | F2FS_NOATIME_FL |\
+ F2FS_NOCOMPR_FL | F2FS_JOURNAL_DATA_FL |\
+ F2FS_NOTAIL_FL | F2FS_DIRSYNC_FL |\
+ F2FS_PROJINHERIT_FL)
+
+/* Flags that are appropriate for regular files (all but dir-specific ones). */
+#define F2FS_REG_FLMASK (~(F2FS_DIRSYNC_FL | F2FS_TOPDIR_FL))
+
+/* Flags that are appropriate for non-directories/regular files. */
+#define F2FS_OTHER_FLMASK (F2FS_NODUMP_FL | F2FS_NOATIME_FL)
static inline __u32 f2fs_mask_flags(umode_t mode, __u32 flags)
{
@@ -2200,6 +2259,7 @@
FI_EXTRA_ATTR, /* indicate file has extra attribute */
FI_PROJ_INHERIT, /* indicate file inherits projectid */
FI_PIN_FILE, /* indicate file should not be gced */
+ FI_ATOMIC_REVOKE_REQUEST, /* request to drop atomic data */
};
static inline void __mark_inode_dirty_flag(struct inode *inode,
@@ -2298,7 +2358,7 @@
static inline void f2fs_i_gc_failures_write(struct inode *inode,
unsigned int count)
{
- F2FS_I(inode)->i_gc_failures = count;
+ F2FS_I(inode)->i_gc_failures[GC_FAILURE_PIN] = count;
f2fs_mark_inode_dirty_sync(inode, true);
}
@@ -2597,7 +2657,7 @@
return F2FS_I(inode)->i_inline_xattr_size;
}
-#define get_inode_mode(i) \
+#define f2fs_get_inode_mode(i) \
((is_inode_flag_set(i, FI_ACL_MODE)) ? \
(F2FS_I(i)->i_acl_mode) : ((i)->i_mode))
@@ -2636,18 +2696,25 @@
spin_unlock(&sbi->iostat_lock);
}
+static inline bool is_valid_blkaddr(block_t blkaddr)
+{
+ if (blkaddr == NEW_ADDR || blkaddr == NULL_ADDR)
+ return false;
+ return true;
+}
+
/*
* file.c
*/
int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync);
-void truncate_data_blocks(struct dnode_of_data *dn);
-int truncate_blocks(struct inode *inode, u64 from, bool lock);
+void f2fs_truncate_data_blocks(struct dnode_of_data *dn);
+int f2fs_truncate_blocks(struct inode *inode, u64 from, bool lock);
int f2fs_truncate(struct inode *inode);
int f2fs_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat);
int f2fs_setattr(struct dentry *dentry, struct iattr *attr);
-int truncate_hole(struct inode *inode, pgoff_t pg_start, pgoff_t pg_end);
-void truncate_data_blocks_range(struct dnode_of_data *dn, int count);
+int f2fs_truncate_hole(struct inode *inode, pgoff_t pg_start, pgoff_t pg_end);
+void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count);
int f2fs_precache_extents(struct inode *inode);
long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
@@ -2661,38 +2728,37 @@
void f2fs_inode_chksum_set(struct f2fs_sb_info *sbi, struct page *page);
struct inode *f2fs_iget(struct super_block *sb, unsigned long ino);
struct inode *f2fs_iget_retry(struct super_block *sb, unsigned long ino);
-int try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink);
-void update_inode(struct inode *inode, struct page *node_page);
-void update_inode_page(struct inode *inode);
+int f2fs_try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink);
+void f2fs_update_inode(struct inode *inode, struct page *node_page);
+void f2fs_update_inode_page(struct inode *inode);
int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc);
void f2fs_evict_inode(struct inode *inode);
-void handle_failed_inode(struct inode *inode);
+void f2fs_handle_failed_inode(struct inode *inode);
/*
* namei.c
*/
-int update_extension_list(struct f2fs_sb_info *sbi, const char *name,
+int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name,
bool hot, bool set);
struct dentry *f2fs_get_parent(struct dentry *child);
/*
* dir.c
*/
-void set_de_type(struct f2fs_dir_entry *de, umode_t mode);
-unsigned char get_de_type(struct f2fs_dir_entry *de);
-struct f2fs_dir_entry *find_target_dentry(struct fscrypt_name *fname,
+unsigned char f2fs_get_de_type(struct f2fs_dir_entry *de);
+struct f2fs_dir_entry *f2fs_find_target_dentry(struct fscrypt_name *fname,
f2fs_hash_t namehash, int *max_slots,
struct f2fs_dentry_ptr *d);
int f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d,
unsigned int start_pos, struct fscrypt_str *fstr);
-void do_make_empty_dir(struct inode *inode, struct inode *parent,
+void f2fs_do_make_empty_dir(struct inode *inode, struct inode *parent,
struct f2fs_dentry_ptr *d);
-struct page *init_inode_metadata(struct inode *inode, struct inode *dir,
+struct page *f2fs_init_inode_metadata(struct inode *inode, struct inode *dir,
const struct qstr *new_name,
const struct qstr *orig_name, struct page *dpage);
-void update_parent_metadata(struct inode *dir, struct inode *inode,
+void f2fs_update_parent_metadata(struct inode *dir, struct inode *inode,
unsigned int current_depth);
-int room_for_filename(const void *bitmap, int slots, int max_slots);
+int f2fs_room_for_filename(const void *bitmap, int slots, int max_slots);
void f2fs_drop_nlink(struct inode *dir, struct inode *inode);
struct f2fs_dir_entry *__f2fs_find_entry(struct inode *dir,
struct fscrypt_name *fname, struct page **res_page);
@@ -2709,9 +2775,9 @@
int f2fs_add_regular_entry(struct inode *dir, const struct qstr *new_name,
const struct qstr *orig_name,
struct inode *inode, nid_t ino, umode_t mode);
-int __f2fs_do_add_link(struct inode *dir, struct fscrypt_name *fname,
+int f2fs_add_dentry(struct inode *dir, struct fscrypt_name *fname,
struct inode *inode, nid_t ino, umode_t mode);
-int __f2fs_add_link(struct inode *dir, const struct qstr *name,
+int f2fs_do_add_link(struct inode *dir, const struct qstr *name,
struct inode *inode, nid_t ino, umode_t mode);
void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
struct inode *dir, struct inode *inode);
@@ -2720,7 +2786,7 @@
static inline int f2fs_add_link(struct dentry *dentry, struct inode *inode)
{
- return __f2fs_add_link(d_inode(dentry->d_parent), &dentry->d_name,
+ return f2fs_do_add_link(d_inode(dentry->d_parent), &dentry->d_name,
inode, inode->i_ino, inode->i_mode);
}
@@ -2735,7 +2801,7 @@
int f2fs_sync_fs(struct super_block *sb, int sync);
extern __printf(3, 4)
void f2fs_msg(struct super_block *sb, const char *level, const char *fmt, ...);
-int sanity_check_ckpt(struct f2fs_sb_info *sbi);
+int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi);
/*
* hash.c
@@ -2749,138 +2815,146 @@
struct dnode_of_data;
struct node_info;
-bool available_free_memory(struct f2fs_sb_info *sbi, int type);
-int need_dentry_mark(struct f2fs_sb_info *sbi, nid_t nid);
-bool is_checkpointed_node(struct f2fs_sb_info *sbi, nid_t nid);
-bool need_inode_block_update(struct f2fs_sb_info *sbi, nid_t ino);
-void get_node_info(struct f2fs_sb_info *sbi, nid_t nid, struct node_info *ni);
-pgoff_t get_next_page_offset(struct dnode_of_data *dn, pgoff_t pgofs);
-int get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode);
-int truncate_inode_blocks(struct inode *inode, pgoff_t from);
-int truncate_xattr_node(struct inode *inode);
-int wait_on_node_pages_writeback(struct f2fs_sb_info *sbi, nid_t ino);
-int remove_inode_page(struct inode *inode);
-struct page *new_inode_page(struct inode *inode);
-struct page *new_node_page(struct dnode_of_data *dn, unsigned int ofs);
-void ra_node_page(struct f2fs_sb_info *sbi, nid_t nid);
-struct page *get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid);
-struct page *get_node_page_ra(struct page *parent, int start);
-void move_node_page(struct page *node_page, int gc_type);
-int fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
+int f2fs_check_nid_range(struct f2fs_sb_info *sbi, nid_t nid);
+bool f2fs_available_free_memory(struct f2fs_sb_info *sbi, int type);
+int f2fs_need_dentry_mark(struct f2fs_sb_info *sbi, nid_t nid);
+bool f2fs_is_checkpointed_node(struct f2fs_sb_info *sbi, nid_t nid);
+bool f2fs_need_inode_block_update(struct f2fs_sb_info *sbi, nid_t ino);
+void f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid,
+ struct node_info *ni);
+pgoff_t f2fs_get_next_page_offset(struct dnode_of_data *dn, pgoff_t pgofs);
+int f2fs_get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode);
+int f2fs_truncate_inode_blocks(struct inode *inode, pgoff_t from);
+int f2fs_truncate_xattr_node(struct inode *inode);
+int f2fs_wait_on_node_pages_writeback(struct f2fs_sb_info *sbi, nid_t ino);
+int f2fs_remove_inode_page(struct inode *inode);
+struct page *f2fs_new_inode_page(struct inode *inode);
+struct page *f2fs_new_node_page(struct dnode_of_data *dn, unsigned int ofs);
+void f2fs_ra_node_page(struct f2fs_sb_info *sbi, nid_t nid);
+struct page *f2fs_get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid);
+struct page *f2fs_get_node_page_ra(struct page *parent, int start);
+void f2fs_move_node_page(struct page *node_page, int gc_type);
+int f2fs_fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
struct writeback_control *wbc, bool atomic);
-int sync_node_pages(struct f2fs_sb_info *sbi, struct writeback_control *wbc,
+int f2fs_sync_node_pages(struct f2fs_sb_info *sbi,
+ struct writeback_control *wbc,
bool do_balance, enum iostat_type io_type);
-void build_free_nids(struct f2fs_sb_info *sbi, bool sync, bool mount);
-bool alloc_nid(struct f2fs_sb_info *sbi, nid_t *nid);
-void alloc_nid_done(struct f2fs_sb_info *sbi, nid_t nid);
-void alloc_nid_failed(struct f2fs_sb_info *sbi, nid_t nid);
-int try_to_free_nids(struct f2fs_sb_info *sbi, int nr_shrink);
-void recover_inline_xattr(struct inode *inode, struct page *page);
-int recover_xattr_data(struct inode *inode, struct page *page);
-int recover_inode_page(struct f2fs_sb_info *sbi, struct page *page);
-void restore_node_summary(struct f2fs_sb_info *sbi,
+void f2fs_build_free_nids(struct f2fs_sb_info *sbi, bool sync, bool mount);
+bool f2fs_alloc_nid(struct f2fs_sb_info *sbi, nid_t *nid);
+void f2fs_alloc_nid_done(struct f2fs_sb_info *sbi, nid_t nid);
+void f2fs_alloc_nid_failed(struct f2fs_sb_info *sbi, nid_t nid);
+int f2fs_try_to_free_nids(struct f2fs_sb_info *sbi, int nr_shrink);
+void f2fs_recover_inline_xattr(struct inode *inode, struct page *page);
+int f2fs_recover_xattr_data(struct inode *inode, struct page *page);
+int f2fs_recover_inode_page(struct f2fs_sb_info *sbi, struct page *page);
+void f2fs_restore_node_summary(struct f2fs_sb_info *sbi,
unsigned int segno, struct f2fs_summary_block *sum);
-void flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc);
-int build_node_manager(struct f2fs_sb_info *sbi);
-void destroy_node_manager(struct f2fs_sb_info *sbi);
-int __init create_node_manager_caches(void);
-void destroy_node_manager_caches(void);
+void f2fs_flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc);
+int f2fs_build_node_manager(struct f2fs_sb_info *sbi);
+void f2fs_destroy_node_manager(struct f2fs_sb_info *sbi);
+int __init f2fs_create_node_manager_caches(void);
+void f2fs_destroy_node_manager_caches(void);
/*
* segment.c
*/
-bool need_SSR(struct f2fs_sb_info *sbi);
-void register_inmem_page(struct inode *inode, struct page *page);
-void drop_inmem_pages_all(struct f2fs_sb_info *sbi);
-void drop_inmem_pages(struct inode *inode);
-void drop_inmem_page(struct inode *inode, struct page *page);
-int commit_inmem_pages(struct inode *inode);
+bool f2fs_need_SSR(struct f2fs_sb_info *sbi);
+void f2fs_register_inmem_page(struct inode *inode, struct page *page);
+void f2fs_drop_inmem_pages_all(struct f2fs_sb_info *sbi, bool gc_failure);
+void f2fs_drop_inmem_pages(struct inode *inode);
+void f2fs_drop_inmem_page(struct inode *inode, struct page *page);
+int f2fs_commit_inmem_pages(struct inode *inode);
void f2fs_balance_fs(struct f2fs_sb_info *sbi, bool need);
void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi);
int f2fs_issue_flush(struct f2fs_sb_info *sbi, nid_t ino);
-int create_flush_cmd_control(struct f2fs_sb_info *sbi);
+int f2fs_create_flush_cmd_control(struct f2fs_sb_info *sbi);
int f2fs_flush_device_cache(struct f2fs_sb_info *sbi);
-void destroy_flush_cmd_control(struct f2fs_sb_info *sbi, bool free);
-void invalidate_blocks(struct f2fs_sb_info *sbi, block_t addr);
-bool is_checkpointed_data(struct f2fs_sb_info *sbi, block_t blkaddr);
-void drop_discard_cmd(struct f2fs_sb_info *sbi);
-void stop_discard_thread(struct f2fs_sb_info *sbi);
+void f2fs_destroy_flush_cmd_control(struct f2fs_sb_info *sbi, bool free);
+void f2fs_invalidate_blocks(struct f2fs_sb_info *sbi, block_t addr);
+bool f2fs_is_checkpointed_data(struct f2fs_sb_info *sbi, block_t blkaddr);
+void f2fs_drop_discard_cmd(struct f2fs_sb_info *sbi);
+void f2fs_stop_discard_thread(struct f2fs_sb_info *sbi);
bool f2fs_wait_discard_bios(struct f2fs_sb_info *sbi);
-void clear_prefree_segments(struct f2fs_sb_info *sbi, struct cp_control *cpc);
-void release_discard_addrs(struct f2fs_sb_info *sbi);
-int npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra);
-void allocate_new_segments(struct f2fs_sb_info *sbi);
+void f2fs_clear_prefree_segments(struct f2fs_sb_info *sbi,
+ struct cp_control *cpc);
+void f2fs_release_discard_addrs(struct f2fs_sb_info *sbi);
+int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra);
+void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi);
int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range);
-bool exist_trim_candidates(struct f2fs_sb_info *sbi, struct cp_control *cpc);
-struct page *get_sum_page(struct f2fs_sb_info *sbi, unsigned int segno);
-void update_meta_page(struct f2fs_sb_info *sbi, void *src, block_t blk_addr);
-void write_meta_page(struct f2fs_sb_info *sbi, struct page *page,
+bool f2fs_exist_trim_candidates(struct f2fs_sb_info *sbi,
+ struct cp_control *cpc);
+struct page *f2fs_get_sum_page(struct f2fs_sb_info *sbi, unsigned int segno);
+void f2fs_update_meta_page(struct f2fs_sb_info *sbi, void *src,
+ block_t blk_addr);
+void f2fs_do_write_meta_page(struct f2fs_sb_info *sbi, struct page *page,
enum iostat_type io_type);
-void write_node_page(unsigned int nid, struct f2fs_io_info *fio);
-void write_data_page(struct dnode_of_data *dn, struct f2fs_io_info *fio);
-int rewrite_data_page(struct f2fs_io_info *fio);
-void __f2fs_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
+void f2fs_do_write_node_page(unsigned int nid, struct f2fs_io_info *fio);
+void f2fs_outplace_write_data(struct dnode_of_data *dn,
+ struct f2fs_io_info *fio);
+int f2fs_inplace_write_data(struct f2fs_io_info *fio);
+void f2fs_do_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
block_t old_blkaddr, block_t new_blkaddr,
bool recover_curseg, bool recover_newaddr);
void f2fs_replace_block(struct f2fs_sb_info *sbi, struct dnode_of_data *dn,
block_t old_addr, block_t new_addr,
unsigned char version, bool recover_curseg,
bool recover_newaddr);
-void allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
+void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
block_t old_blkaddr, block_t *new_blkaddr,
struct f2fs_summary *sum, int type,
struct f2fs_io_info *fio, bool add_list);
void f2fs_wait_on_page_writeback(struct page *page,
enum page_type type, bool ordered);
void f2fs_wait_on_block_writeback(struct f2fs_sb_info *sbi, block_t blkaddr);
-void write_data_summaries(struct f2fs_sb_info *sbi, block_t start_blk);
-void write_node_summaries(struct f2fs_sb_info *sbi, block_t start_blk);
-int lookup_journal_in_cursum(struct f2fs_journal *journal, int type,
+void f2fs_write_data_summaries(struct f2fs_sb_info *sbi, block_t start_blk);
+void f2fs_write_node_summaries(struct f2fs_sb_info *sbi, block_t start_blk);
+int f2fs_lookup_journal_in_cursum(struct f2fs_journal *journal, int type,
unsigned int val, int alloc);
-void flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc);
-int build_segment_manager(struct f2fs_sb_info *sbi);
-void destroy_segment_manager(struct f2fs_sb_info *sbi);
-int __init create_segment_manager_caches(void);
-void destroy_segment_manager_caches(void);
-int rw_hint_to_seg_type(enum rw_hint hint);
-enum rw_hint io_type_to_rw_hint(struct f2fs_sb_info *sbi, enum page_type type,
- enum temp_type temp);
+void f2fs_flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc);
+int f2fs_build_segment_manager(struct f2fs_sb_info *sbi);
+void f2fs_destroy_segment_manager(struct f2fs_sb_info *sbi);
+int __init f2fs_create_segment_manager_caches(void);
+void f2fs_destroy_segment_manager_caches(void);
+int f2fs_rw_hint_to_seg_type(enum rw_hint hint);
+enum rw_hint f2fs_io_type_to_rw_hint(struct f2fs_sb_info *sbi,
+ enum page_type type, enum temp_type temp);
/*
* checkpoint.c
*/
void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io);
-struct page *grab_meta_page(struct f2fs_sb_info *sbi, pgoff_t index);
-struct page *get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index);
-struct page *get_tmp_page(struct f2fs_sb_info *sbi, pgoff_t index);
-bool is_valid_blkaddr(struct f2fs_sb_info *sbi, block_t blkaddr, int type);
-int ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
+struct page *f2fs_grab_meta_page(struct f2fs_sb_info *sbi, pgoff_t index);
+struct page *f2fs_get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index);
+struct page *f2fs_get_tmp_page(struct f2fs_sb_info *sbi, pgoff_t index);
+bool f2fs_is_valid_meta_blkaddr(struct f2fs_sb_info *sbi,
+ block_t blkaddr, int type);
+int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
int type, bool sync);
-void ra_meta_pages_cond(struct f2fs_sb_info *sbi, pgoff_t index);
-long sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type,
+void f2fs_ra_meta_pages_cond(struct f2fs_sb_info *sbi, pgoff_t index);
+long f2fs_sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type,
long nr_to_write, enum iostat_type io_type);
-void add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type);
-void remove_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type);
-void release_ino_entry(struct f2fs_sb_info *sbi, bool all);
-bool exist_written_data(struct f2fs_sb_info *sbi, nid_t ino, int mode);
-void set_dirty_device(struct f2fs_sb_info *sbi, nid_t ino,
+void f2fs_add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type);
+void f2fs_remove_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type);
+void f2fs_release_ino_entry(struct f2fs_sb_info *sbi, bool all);
+bool f2fs_exist_written_data(struct f2fs_sb_info *sbi, nid_t ino, int mode);
+void f2fs_set_dirty_device(struct f2fs_sb_info *sbi, nid_t ino,
unsigned int devidx, int type);
-bool is_dirty_device(struct f2fs_sb_info *sbi, nid_t ino,
+bool f2fs_is_dirty_device(struct f2fs_sb_info *sbi, nid_t ino,
unsigned int devidx, int type);
int f2fs_sync_inode_meta(struct f2fs_sb_info *sbi);
-int acquire_orphan_inode(struct f2fs_sb_info *sbi);
-void release_orphan_inode(struct f2fs_sb_info *sbi);
-void add_orphan_inode(struct inode *inode);
-void remove_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino);
-int recover_orphan_inodes(struct f2fs_sb_info *sbi);
-int get_valid_checkpoint(struct f2fs_sb_info *sbi);
-void update_dirty_page(struct inode *inode, struct page *page);
-void remove_dirty_inode(struct inode *inode);
-int sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type);
-int write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc);
-void init_ino_entry_info(struct f2fs_sb_info *sbi);
-int __init create_checkpoint_caches(void);
-void destroy_checkpoint_caches(void);
+int f2fs_acquire_orphan_inode(struct f2fs_sb_info *sbi);
+void f2fs_release_orphan_inode(struct f2fs_sb_info *sbi);
+void f2fs_add_orphan_inode(struct inode *inode);
+void f2fs_remove_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino);
+int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi);
+int f2fs_get_valid_checkpoint(struct f2fs_sb_info *sbi);
+void f2fs_update_dirty_page(struct inode *inode, struct page *page);
+void f2fs_remove_dirty_inode(struct inode *inode);
+int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type);
+int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc);
+void f2fs_init_ino_entry_info(struct f2fs_sb_info *sbi);
+int __init f2fs_create_checkpoint_caches(void);
+void f2fs_destroy_checkpoint_caches(void);
/*
* data.c
@@ -2893,34 +2967,31 @@
enum page_type type);
void f2fs_flush_merged_writes(struct f2fs_sb_info *sbi);
int f2fs_submit_page_bio(struct f2fs_io_info *fio);
-int f2fs_submit_page_write(struct f2fs_io_info *fio);
+void f2fs_submit_page_write(struct f2fs_io_info *fio);
struct block_device *f2fs_target_device(struct f2fs_sb_info *sbi,
block_t blk_addr, struct bio *bio);
int f2fs_target_device_index(struct f2fs_sb_info *sbi, block_t blkaddr);
-void set_data_blkaddr(struct dnode_of_data *dn);
+void f2fs_set_data_blkaddr(struct dnode_of_data *dn);
void f2fs_update_data_blkaddr(struct dnode_of_data *dn, block_t blkaddr);
-int reserve_new_blocks(struct dnode_of_data *dn, blkcnt_t count);
-int reserve_new_block(struct dnode_of_data *dn);
+int f2fs_reserve_new_blocks(struct dnode_of_data *dn, blkcnt_t count);
+int f2fs_reserve_new_block(struct dnode_of_data *dn);
int f2fs_get_block(struct dnode_of_data *dn, pgoff_t index);
int f2fs_preallocate_blocks(struct kiocb *iocb, struct iov_iter *from);
int f2fs_reserve_block(struct dnode_of_data *dn, pgoff_t index);
-struct page *get_read_data_page(struct inode *inode, pgoff_t index,
+struct page *f2fs_get_read_data_page(struct inode *inode, pgoff_t index,
int op_flags, bool for_write);
-struct page *find_data_page(struct inode *inode, pgoff_t index);
-struct page *get_lock_data_page(struct inode *inode, pgoff_t index,
+struct page *f2fs_find_data_page(struct inode *inode, pgoff_t index);
+struct page *f2fs_get_lock_data_page(struct inode *inode, pgoff_t index,
bool for_write);
-struct page *get_new_data_page(struct inode *inode,
+struct page *f2fs_get_new_data_page(struct inode *inode,
struct page *ipage, pgoff_t index, bool new_i_size);
-int do_write_data_page(struct f2fs_io_info *fio);
+int f2fs_do_write_data_page(struct f2fs_io_info *fio);
int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
int create, int flag);
int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
u64 start, u64 len);
-bool should_update_inplace(struct inode *inode, struct f2fs_io_info *fio);
-bool should_update_outplace(struct inode *inode, struct f2fs_io_info *fio);
-int __f2fs_write_data_pages(struct address_space *mapping,
- struct writeback_control *wbc,
- enum iostat_type io_type);
+bool f2fs_should_update_inplace(struct inode *inode, struct f2fs_io_info *fio);
+bool f2fs_should_update_outplace(struct inode *inode, struct f2fs_io_info *fio);
void f2fs_invalidate_page(struct page *page, unsigned int offset,
unsigned int length);
int f2fs_release_page(struct page *page, gfp_t wait);
@@ -2929,22 +3000,23 @@
struct page *page, enum migrate_mode mode);
#endif
bool f2fs_overwrite_io(struct inode *inode, loff_t pos, size_t len);
+void f2fs_clear_radix_tree_dirty_tag(struct page *page);
/*
* gc.c
*/
-int start_gc_thread(struct f2fs_sb_info *sbi);
-void stop_gc_thread(struct f2fs_sb_info *sbi);
-block_t start_bidx_of_node(unsigned int node_ofs, struct inode *inode);
+int f2fs_start_gc_thread(struct f2fs_sb_info *sbi);
+void f2fs_stop_gc_thread(struct f2fs_sb_info *sbi);
+block_t f2fs_start_bidx_of_node(unsigned int node_ofs, struct inode *inode);
int f2fs_gc(struct f2fs_sb_info *sbi, bool sync, bool background,
unsigned int segno);
-void build_gc_manager(struct f2fs_sb_info *sbi);
+void f2fs_build_gc_manager(struct f2fs_sb_info *sbi);
/*
* recovery.c
*/
-int recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only);
-bool space_for_roll_forward(struct f2fs_sb_info *sbi);
+int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only);
+bool f2fs_space_for_roll_forward(struct f2fs_sb_info *sbi);
/*
* debug.c
@@ -2982,6 +3054,7 @@
int bg_node_segs, bg_data_segs;
int tot_blks, data_blks, node_blks;
int bg_data_blks, bg_node_blks;
+ unsigned long long skipped_atomic_files[2];
int curseg[NR_CURSEG_TYPE];
int cursec[NR_CURSEG_TYPE];
int curzone[NR_CURSEG_TYPE];
@@ -3148,29 +3221,31 @@
extern const struct inode_operations f2fs_symlink_inode_operations;
extern const struct inode_operations f2fs_encrypted_symlink_inode_operations;
extern const struct inode_operations f2fs_special_inode_operations;
-extern struct kmem_cache *inode_entry_slab;
+extern struct kmem_cache *f2fs_inode_entry_slab;
/*
* inline.c
*/
bool f2fs_may_inline_data(struct inode *inode);
bool f2fs_may_inline_dentry(struct inode *inode);
-void read_inline_data(struct page *page, struct page *ipage);
-void truncate_inline_inode(struct inode *inode, struct page *ipage, u64 from);
+void f2fs_do_read_inline_data(struct page *page, struct page *ipage);
+void f2fs_truncate_inline_inode(struct inode *inode,
+ struct page *ipage, u64 from);
int f2fs_read_inline_data(struct inode *inode, struct page *page);
int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page);
int f2fs_convert_inline_inode(struct inode *inode);
int f2fs_write_inline_data(struct inode *inode, struct page *page);
-bool recover_inline_data(struct inode *inode, struct page *npage);
-struct f2fs_dir_entry *find_in_inline_dir(struct inode *dir,
+bool f2fs_recover_inline_data(struct inode *inode, struct page *npage);
+struct f2fs_dir_entry *f2fs_find_in_inline_dir(struct inode *dir,
struct fscrypt_name *fname, struct page **res_page);
-int make_empty_inline_dir(struct inode *inode, struct inode *parent,
+int f2fs_make_empty_inline_dir(struct inode *inode, struct inode *parent,
struct page *ipage);
int f2fs_add_inline_entry(struct inode *dir, const struct qstr *new_name,
const struct qstr *orig_name,
struct inode *inode, nid_t ino, umode_t mode);
-void f2fs_delete_inline_entry(struct f2fs_dir_entry *dentry, struct page *page,
- struct inode *dir, struct inode *inode);
+void f2fs_delete_inline_entry(struct f2fs_dir_entry *dentry,
+ struct page *page, struct inode *dir,
+ struct inode *inode);
bool f2fs_empty_inline_dir(struct inode *dir);
int f2fs_read_inline_dir(struct file *file, struct dir_context *ctx,
struct fscrypt_str *fstr);
@@ -3191,17 +3266,17 @@
/*
* extent_cache.c
*/
-struct rb_entry *__lookup_rb_tree(struct rb_root *root,
+struct rb_entry *f2fs_lookup_rb_tree(struct rb_root *root,
struct rb_entry *cached_re, unsigned int ofs);
-struct rb_node **__lookup_rb_tree_for_insert(struct f2fs_sb_info *sbi,
+struct rb_node **f2fs_lookup_rb_tree_for_insert(struct f2fs_sb_info *sbi,
struct rb_root *root, struct rb_node **parent,
unsigned int ofs);
-struct rb_entry *__lookup_rb_tree_ret(struct rb_root *root,
+struct rb_entry *f2fs_lookup_rb_tree_ret(struct rb_root *root,
struct rb_entry *cached_re, unsigned int ofs,
struct rb_entry **prev_entry, struct rb_entry **next_entry,
struct rb_node ***insert_p, struct rb_node **insert_parent,
bool force);
-bool __check_rb_tree_consistence(struct f2fs_sb_info *sbi,
+bool f2fs_check_rb_tree_consistence(struct f2fs_sb_info *sbi,
struct rb_root *root);
unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink);
bool f2fs_init_extent_tree(struct inode *inode, struct f2fs_extent *i_ext);
@@ -3213,9 +3288,9 @@
void f2fs_update_extent_cache(struct dnode_of_data *dn);
void f2fs_update_extent_cache_range(struct dnode_of_data *dn,
pgoff_t fofs, block_t blkaddr, unsigned int len);
-void init_extent_cache_info(struct f2fs_sb_info *sbi);
-int __init create_extent_cache(void);
-void destroy_extent_cache(void);
+void f2fs_init_extent_cache_info(struct f2fs_sb_info *sbi);
+int __init f2fs_create_extent_cache(void);
+void f2fs_destroy_extent_cache(void);
/*
* sysfs.c
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 44a2e32..1ac5f4d 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -97,7 +97,8 @@
/* page is wholly or partially inside EOF */
if (((loff_t)(page->index + 1) << PAGE_SHIFT) >
i_size_read(inode)) {
- unsigned offset;
+ loff_t offset;
+
offset = i_size_read(inode) & ~PAGE_MASK;
zero_user_segment(page, offset, PAGE_SIZE);
}
@@ -159,17 +160,18 @@
cp_reason = CP_SB_NEED_CP;
else if (file_wrong_pino(inode))
cp_reason = CP_WRONG_PINO;
- else if (!space_for_roll_forward(sbi))
+ else if (!f2fs_space_for_roll_forward(sbi))
cp_reason = CP_NO_SPC_ROLL;
- else if (!is_checkpointed_node(sbi, F2FS_I(inode)->i_pino))
+ else if (!f2fs_is_checkpointed_node(sbi, F2FS_I(inode)->i_pino))
cp_reason = CP_NODE_NEED_CP;
else if (test_opt(sbi, FASTBOOT))
cp_reason = CP_FASTBOOT_MODE;
else if (F2FS_OPTION(sbi).active_logs == 2)
cp_reason = CP_SPEC_LOG_NUM;
else if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_STRICT &&
- need_dentry_mark(sbi, inode->i_ino) &&
- exist_written_data(sbi, F2FS_I(inode)->i_pino, TRANS_DIR_INO))
+ f2fs_need_dentry_mark(sbi, inode->i_ino) &&
+ f2fs_exist_written_data(sbi, F2FS_I(inode)->i_pino,
+ TRANS_DIR_INO))
cp_reason = CP_RECOVER_DIR;
return cp_reason;
@@ -180,7 +182,7 @@
struct page *i = find_get_page(NODE_MAPPING(sbi), ino);
bool ret = false;
/* But we need to avoid that there are some inode updates */
- if ((i && PageDirty(i)) || need_inode_block_update(sbi, ino))
+ if ((i && PageDirty(i)) || f2fs_need_inode_block_update(sbi, ino))
ret = true;
f2fs_put_page(i, 0);
return ret;
@@ -240,14 +242,14 @@
* if there is no written data, don't waste time to write recovery info.
*/
if (!is_inode_flag_set(inode, FI_APPEND_WRITE) &&
- !exist_written_data(sbi, ino, APPEND_INO)) {
+ !f2fs_exist_written_data(sbi, ino, APPEND_INO)) {
/* it may call write_inode just prior to fsync */
if (need_inode_page_update(sbi, ino))
goto go_write;
if (is_inode_flag_set(inode, FI_UPDATE_WRITE) ||
- exist_written_data(sbi, ino, UPDATE_INO))
+ f2fs_exist_written_data(sbi, ino, UPDATE_INO))
goto flush_out;
goto out;
}
@@ -274,7 +276,9 @@
goto out;
}
sync_nodes:
- ret = fsync_node_pages(sbi, inode, &wbc, atomic);
+ atomic_inc(&sbi->wb_sync_req[NODE]);
+ ret = f2fs_fsync_node_pages(sbi, inode, &wbc, atomic);
+ atomic_dec(&sbi->wb_sync_req[NODE]);
if (ret)
goto out;
@@ -284,7 +288,7 @@
goto out;
}
- if (need_inode_block_update(sbi, ino)) {
+ if (f2fs_need_inode_block_update(sbi, ino)) {
f2fs_mark_inode_dirty_sync(inode, true);
f2fs_write_inode(inode, NULL);
goto sync_nodes;
@@ -299,21 +303,21 @@
* given fsync mark.
*/
if (!atomic) {
- ret = wait_on_node_pages_writeback(sbi, ino);
+ ret = f2fs_wait_on_node_pages_writeback(sbi, ino);
if (ret)
goto out;
}
/* once recovery info is written, don't need to tack this */
- remove_ino_entry(sbi, ino, APPEND_INO);
+ f2fs_remove_ino_entry(sbi, ino, APPEND_INO);
clear_inode_flag(inode, FI_APPEND_WRITE);
flush_out:
if (!atomic && F2FS_OPTION(sbi).fsync_mode != FSYNC_MODE_NOBARRIER)
ret = f2fs_issue_flush(sbi, inode->i_ino);
if (!ret) {
- remove_ino_entry(sbi, ino, UPDATE_INO);
+ f2fs_remove_ino_entry(sbi, ino, UPDATE_INO);
clear_inode_flag(inode, FI_UPDATE_WRITE);
- remove_ino_entry(sbi, ino, FLUSH_INO);
+ f2fs_remove_ino_entry(sbi, ino, FLUSH_INO);
}
f2fs_update_time(sbi, REQ_TIME);
out:
@@ -332,18 +336,19 @@
static pgoff_t __get_first_dirty_index(struct address_space *mapping,
pgoff_t pgofs, int whence)
{
- struct pagevec pvec;
+ struct page *page;
int nr_pages;
if (whence != SEEK_DATA)
return 0;
/* find first dirty page index */
- pagevec_init(&pvec, 0);
- nr_pages = pagevec_lookup_tag(&pvec, mapping, &pgofs,
- PAGECACHE_TAG_DIRTY, 1);
- pgofs = nr_pages ? pvec.pages[0]->index : ULONG_MAX;
- pagevec_release(&pvec);
+ nr_pages = find_get_pages_tag(mapping, &pgofs, PAGECACHE_TAG_DIRTY,
+ 1, &page);
+ if (!nr_pages)
+ return ULONG_MAX;
+ pgofs = page->index;
+ put_page(page);
return pgofs;
}
@@ -353,7 +358,7 @@
switch (whence) {
case SEEK_DATA:
if ((blkaddr == NEW_ADDR && dirty == pgofs) ||
- (blkaddr != NEW_ADDR && blkaddr != NULL_ADDR))
+ is_valid_blkaddr(blkaddr))
return true;
break;
case SEEK_HOLE:
@@ -393,13 +398,13 @@
for (; data_ofs < isize; data_ofs = (loff_t)pgofs << PAGE_SHIFT) {
set_new_dnode(&dn, inode, NULL, NULL, 0);
- err = get_dnode_of_data(&dn, pgofs, LOOKUP_NODE);
+ err = f2fs_get_dnode_of_data(&dn, pgofs, LOOKUP_NODE);
if (err && err != -ENOENT) {
goto fail;
} else if (err == -ENOENT) {
/* direct node does not exists */
if (whence == SEEK_DATA) {
- pgofs = get_next_page_offset(&dn, pgofs);
+ pgofs = f2fs_get_next_page_offset(&dn, pgofs);
continue;
} else {
goto found;
@@ -413,6 +418,7 @@
dn.ofs_in_node++, pgofs++,
data_ofs = (loff_t)pgofs << PAGE_SHIFT) {
block_t blkaddr;
+
blkaddr = datablock_addr(dn.inode,
dn.node_page, dn.ofs_in_node);
@@ -487,7 +493,7 @@
return dquot_file_open(inode, filp);
}
-void truncate_data_blocks_range(struct dnode_of_data *dn, int count)
+void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
struct f2fs_node *raw_node;
@@ -503,12 +509,13 @@
for (; count > 0; count--, addr++, dn->ofs_in_node++) {
block_t blkaddr = le32_to_cpu(*addr);
+
if (blkaddr == NULL_ADDR)
continue;
dn->data_blkaddr = NULL_ADDR;
- set_data_blkaddr(dn);
- invalidate_blocks(sbi, blkaddr);
+ f2fs_set_data_blkaddr(dn);
+ f2fs_invalidate_blocks(sbi, blkaddr);
if (dn->ofs_in_node == 0 && IS_INODE(dn->node_page))
clear_inode_flag(dn->inode, FI_FIRST_BLOCK_WRITTEN);
nr_free++;
@@ -520,7 +527,7 @@
* once we invalidate valid blkaddr in range [ofs, ofs + count],
* we will invalidate all blkaddr in the whole range.
*/
- fofs = start_bidx_of_node(ofs_of_node(dn->node_page),
+ fofs = f2fs_start_bidx_of_node(ofs_of_node(dn->node_page),
dn->inode) + ofs;
f2fs_update_extent_cache_range(dn, fofs, 0, len);
dec_valid_block_count(sbi, dn->inode, nr_free);
@@ -532,15 +539,15 @@
dn->ofs_in_node, nr_free);
}
-void truncate_data_blocks(struct dnode_of_data *dn)
+void f2fs_truncate_data_blocks(struct dnode_of_data *dn)
{
- truncate_data_blocks_range(dn, ADDRS_PER_BLOCK);
+ f2fs_truncate_data_blocks_range(dn, ADDRS_PER_BLOCK);
}
static int truncate_partial_data_page(struct inode *inode, u64 from,
bool cache_only)
{
- unsigned offset = from & (PAGE_SIZE - 1);
+ loff_t offset = from & (PAGE_SIZE - 1);
pgoff_t index = from >> PAGE_SHIFT;
struct address_space *mapping = inode->i_mapping;
struct page *page;
@@ -556,7 +563,7 @@
return 0;
}
- page = get_lock_data_page(inode, index, true);
+ page = f2fs_get_lock_data_page(inode, index, true);
if (IS_ERR(page))
return PTR_ERR(page) == -ENOENT ? 0 : PTR_ERR(page);
truncate_out:
@@ -571,7 +578,7 @@
return 0;
}
-int truncate_blocks(struct inode *inode, u64 from, bool lock)
+int f2fs_truncate_blocks(struct inode *inode, u64 from, bool lock)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
struct dnode_of_data dn;
@@ -590,21 +597,21 @@
if (lock)
f2fs_lock_op(sbi);
- ipage = get_node_page(sbi, inode->i_ino);
+ ipage = f2fs_get_node_page(sbi, inode->i_ino);
if (IS_ERR(ipage)) {
err = PTR_ERR(ipage);
goto out;
}
if (f2fs_has_inline_data(inode)) {
- truncate_inline_inode(inode, ipage, from);
+ f2fs_truncate_inline_inode(inode, ipage, from);
f2fs_put_page(ipage, 1);
truncate_page = true;
goto out;
}
set_new_dnode(&dn, inode, ipage, NULL, 0);
- err = get_dnode_of_data(&dn, free_from, LOOKUP_NODE_RA);
+ err = f2fs_get_dnode_of_data(&dn, free_from, LOOKUP_NODE_RA);
if (err) {
if (err == -ENOENT)
goto free_next;
@@ -617,13 +624,13 @@
f2fs_bug_on(sbi, count < 0);
if (dn.ofs_in_node || IS_INODE(dn.node_page)) {
- truncate_data_blocks_range(&dn, count);
+ f2fs_truncate_data_blocks_range(&dn, count);
free_from += count;
}
f2fs_put_dnode(&dn);
free_next:
- err = truncate_inode_blocks(inode, free_from);
+ err = f2fs_truncate_inode_blocks(inode, free_from);
out:
if (lock)
f2fs_unlock_op(sbi);
@@ -662,7 +669,7 @@
return err;
}
- err = truncate_blocks(inode, i_size_read(inode), true);
+ err = f2fs_truncate_blocks(inode, i_size_read(inode), true);
if (err)
return err;
@@ -688,16 +695,16 @@
stat->btime.tv_nsec = fi->i_crtime.tv_nsec;
}
- flags = fi->i_flags & (FS_FL_USER_VISIBLE | FS_PROJINHERIT_FL);
- if (flags & FS_APPEND_FL)
+ flags = fi->i_flags & F2FS_FL_USER_VISIBLE;
+ if (flags & F2FS_APPEND_FL)
stat->attributes |= STATX_ATTR_APPEND;
- if (flags & FS_COMPR_FL)
+ if (flags & F2FS_COMPR_FL)
stat->attributes |= STATX_ATTR_COMPRESSED;
if (f2fs_encrypted_inode(inode))
stat->attributes |= STATX_ATTR_ENCRYPTED;
- if (flags & FS_IMMUTABLE_FL)
+ if (flags & F2FS_IMMUTABLE_FL)
stat->attributes |= STATX_ATTR_IMMUTABLE;
- if (flags & FS_NODUMP_FL)
+ if (flags & F2FS_NODUMP_FL)
stat->attributes |= STATX_ATTR_NODUMP;
stat->attributes_mask |= (STATX_ATTR_APPEND |
@@ -813,7 +820,7 @@
__setattr_copy(inode, attr);
if (attr->ia_valid & ATTR_MODE) {
- err = posix_acl_chmod(inode, get_inode_mode(inode));
+ err = posix_acl_chmod(inode, f2fs_get_inode_mode(inode));
if (err || is_inode_flag_set(inode, FI_ACL_MODE)) {
inode->i_mode = F2FS_I(inode)->i_acl_mode;
clear_inode_flag(inode, FI_ACL_MODE);
@@ -852,7 +859,7 @@
f2fs_balance_fs(sbi, true);
f2fs_lock_op(sbi);
- page = get_new_data_page(inode, NULL, index, false);
+ page = f2fs_get_new_data_page(inode, NULL, index, false);
f2fs_unlock_op(sbi);
if (IS_ERR(page))
@@ -865,7 +872,7 @@
return 0;
}
-int truncate_hole(struct inode *inode, pgoff_t pg_start, pgoff_t pg_end)
+int f2fs_truncate_hole(struct inode *inode, pgoff_t pg_start, pgoff_t pg_end)
{
int err;
@@ -874,10 +881,11 @@
pgoff_t end_offset, count;
set_new_dnode(&dn, inode, NULL, NULL, 0);
- err = get_dnode_of_data(&dn, pg_start, LOOKUP_NODE);
+ err = f2fs_get_dnode_of_data(&dn, pg_start, LOOKUP_NODE);
if (err) {
if (err == -ENOENT) {
- pg_start = get_next_page_offset(&dn, pg_start);
+ pg_start = f2fs_get_next_page_offset(&dn,
+ pg_start);
continue;
}
return err;
@@ -888,7 +896,7 @@
f2fs_bug_on(F2FS_I_SB(inode), count == 0 || count > end_offset);
- truncate_data_blocks_range(&dn, count);
+ f2fs_truncate_data_blocks_range(&dn, count);
f2fs_put_dnode(&dn);
pg_start += count;
@@ -944,7 +952,7 @@
blk_end - 1);
f2fs_lock_op(sbi);
- ret = truncate_hole(inode, pg_start, pg_end);
+ ret = f2fs_truncate_hole(inode, pg_start, pg_end);
f2fs_unlock_op(sbi);
up_write(&F2FS_I(inode)->i_mmap_sem);
}
@@ -962,7 +970,7 @@
next_dnode:
set_new_dnode(&dn, inode, NULL, NULL, 0);
- ret = get_dnode_of_data(&dn, off, LOOKUP_NODE_RA);
+ ret = f2fs_get_dnode_of_data(&dn, off, LOOKUP_NODE_RA);
if (ret && ret != -ENOENT) {
return ret;
} else if (ret == -ENOENT) {
@@ -979,7 +987,7 @@
for (i = 0; i < done; i++, blkaddr++, do_replace++, dn.ofs_in_node++) {
*blkaddr = datablock_addr(dn.inode,
dn.node_page, dn.ofs_in_node);
- if (!is_checkpointed_data(sbi, *blkaddr)) {
+ if (!f2fs_is_checkpointed_data(sbi, *blkaddr)) {
if (test_opt(sbi, LFS)) {
f2fs_put_dnode(&dn);
@@ -1012,10 +1020,10 @@
continue;
set_new_dnode(&dn, inode, NULL, NULL, 0);
- ret = get_dnode_of_data(&dn, off + i, LOOKUP_NODE_RA);
+ ret = f2fs_get_dnode_of_data(&dn, off + i, LOOKUP_NODE_RA);
if (ret) {
dec_valid_block_count(sbi, inode, 1);
- invalidate_blocks(sbi, *blkaddr);
+ f2fs_invalidate_blocks(sbi, *blkaddr);
} else {
f2fs_update_data_blkaddr(&dn, *blkaddr);
}
@@ -1045,18 +1053,18 @@
pgoff_t ilen;
set_new_dnode(&dn, dst_inode, NULL, NULL, 0);
- ret = get_dnode_of_data(&dn, dst + i, ALLOC_NODE);
+ ret = f2fs_get_dnode_of_data(&dn, dst + i, ALLOC_NODE);
if (ret)
return ret;
- get_node_info(sbi, dn.nid, &ni);
+ f2fs_get_node_info(sbi, dn.nid, &ni);
ilen = min((pgoff_t)
ADDRS_PER_PAGE(dn.node_page, dst_inode) -
dn.ofs_in_node, len - i);
do {
dn.data_blkaddr = datablock_addr(dn.inode,
dn.node_page, dn.ofs_in_node);
- truncate_data_blocks_range(&dn, 1);
+ f2fs_truncate_data_blocks_range(&dn, 1);
if (do_replace[i]) {
f2fs_i_blocks_write(src_inode,
@@ -1079,10 +1087,11 @@
} else {
struct page *psrc, *pdst;
- psrc = get_lock_data_page(src_inode, src + i, true);
+ psrc = f2fs_get_lock_data_page(src_inode,
+ src + i, true);
if (IS_ERR(psrc))
return PTR_ERR(psrc);
- pdst = get_new_data_page(dst_inode, NULL, dst + i,
+ pdst = f2fs_get_new_data_page(dst_inode, NULL, dst + i,
true);
if (IS_ERR(pdst)) {
f2fs_put_page(psrc, 1);
@@ -1093,7 +1102,8 @@
f2fs_put_page(pdst, 1);
f2fs_put_page(psrc, 1);
- ret = truncate_hole(src_inode, src + i, src + i + 1);
+ ret = f2fs_truncate_hole(src_inode,
+ src + i, src + i + 1);
if (ret)
return ret;
i++;
@@ -1115,12 +1125,14 @@
olen = min((pgoff_t)4 * ADDRS_PER_BLOCK, len);
src_blkaddr = f2fs_kvzalloc(F2FS_I_SB(src_inode),
- sizeof(block_t) * olen, GFP_KERNEL);
+ array_size(olen, sizeof(block_t)),
+ GFP_KERNEL);
if (!src_blkaddr)
return -ENOMEM;
do_replace = f2fs_kvzalloc(F2FS_I_SB(src_inode),
- sizeof(int) * olen, GFP_KERNEL);
+ array_size(olen, sizeof(int)),
+ GFP_KERNEL);
if (!do_replace) {
kvfree(src_blkaddr);
return -ENOMEM;
@@ -1146,7 +1158,7 @@
return 0;
roll_back:
- __roll_back_blkaddrs(src_inode, src_blkaddr, do_replace, src, len);
+ __roll_back_blkaddrs(src_inode, src_blkaddr, do_replace, src, olen);
kvfree(src_blkaddr);
kvfree(do_replace);
return ret;
@@ -1189,7 +1201,7 @@
pg_end = (offset + len) >> PAGE_SHIFT;
/* avoid gc operation during block exchange */
- down_write(&F2FS_I(inode)->dio_rwsem[WRITE]);
+ down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
down_write(&F2FS_I(inode)->i_mmap_sem);
/* write out all dirty pages from offset */
@@ -1210,12 +1222,12 @@
new_size = i_size_read(inode) - len;
truncate_pagecache(inode, new_size);
- ret = truncate_blocks(inode, new_size, true);
+ ret = f2fs_truncate_blocks(inode, new_size, true);
if (!ret)
f2fs_i_size_write(inode, new_size);
out_unlock:
up_write(&F2FS_I(inode)->i_mmap_sem);
- up_write(&F2FS_I(inode)->dio_rwsem[WRITE]);
+ up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
return ret;
}
@@ -1235,7 +1247,7 @@
}
dn->ofs_in_node = ofs_in_node;
- ret = reserve_new_blocks(dn, count);
+ ret = f2fs_reserve_new_blocks(dn, count);
if (ret)
return ret;
@@ -1244,7 +1256,7 @@
dn->data_blkaddr = datablock_addr(dn->inode,
dn->node_page, dn->ofs_in_node);
/*
- * reserve_new_blocks will not guarantee entire block
+ * f2fs_reserve_new_blocks will not guarantee entire block
* allocation.
*/
if (dn->data_blkaddr == NULL_ADDR) {
@@ -1252,9 +1264,9 @@
break;
}
if (dn->data_blkaddr != NEW_ADDR) {
- invalidate_blocks(sbi, dn->data_blkaddr);
+ f2fs_invalidate_blocks(sbi, dn->data_blkaddr);
dn->data_blkaddr = NEW_ADDR;
- set_data_blkaddr(dn);
+ f2fs_set_data_blkaddr(dn);
}
}
@@ -1320,7 +1332,7 @@
f2fs_lock_op(sbi);
set_new_dnode(&dn, inode, NULL, NULL, 0);
- ret = get_dnode_of_data(&dn, index, ALLOC_NODE);
+ ret = f2fs_get_dnode_of_data(&dn, index, ALLOC_NODE);
if (ret) {
f2fs_unlock_op(sbi);
goto out;
@@ -1391,10 +1403,10 @@
f2fs_balance_fs(sbi, true);
/* avoid gc operation during block exchange */
- down_write(&F2FS_I(inode)->dio_rwsem[WRITE]);
+ down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
down_write(&F2FS_I(inode)->i_mmap_sem);
- ret = truncate_blocks(inode, i_size_read(inode), true);
+ ret = f2fs_truncate_blocks(inode, i_size_read(inode), true);
if (ret)
goto out;
@@ -1432,7 +1444,7 @@
f2fs_i_size_write(inode, new_size);
out:
up_write(&F2FS_I(inode)->i_mmap_sem);
- up_write(&F2FS_I(inode)->dio_rwsem[WRITE]);
+ up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
return ret;
}
@@ -1475,7 +1487,7 @@
last_off = map.m_lblk + map.m_len - 1;
/* update new size to the failed position */
- new_size = (last_off == pg_end) ? offset + len:
+ new_size = (last_off == pg_end) ? offset + len :
(loff_t)(last_off + 1) << PAGE_SHIFT;
} else {
new_size = ((loff_t)pg_end << PAGE_SHIFT) + off_end;
@@ -1555,13 +1567,13 @@
/* some remained atomic pages should discarded */
if (f2fs_is_atomic_file(inode))
- drop_inmem_pages(inode);
+ f2fs_drop_inmem_pages(inode);
if (f2fs_is_volatile_file(inode)) {
- clear_inode_flag(inode, FI_VOLATILE_FILE);
- stat_dec_volatile_write(inode);
set_inode_flag(inode, FI_DROP_CACHE);
filemap_fdatawrite(inode->i_mapping);
clear_inode_flag(inode, FI_DROP_CACHE);
+ clear_inode_flag(inode, FI_VOLATILE_FILE);
+ stat_dec_volatile_write(inode);
}
return 0;
}
@@ -1578,7 +1590,7 @@
*/
if (f2fs_is_atomic_file(inode) &&
F2FS_I(inode)->inmem_task == current)
- drop_inmem_pages(inode);
+ f2fs_drop_inmem_pages(inode);
return 0;
}
@@ -1586,7 +1598,15 @@
{
struct inode *inode = file_inode(filp);
struct f2fs_inode_info *fi = F2FS_I(inode);
- unsigned int flags = fi->i_flags & FS_FL_USER_VISIBLE;
+ unsigned int flags = fi->i_flags;
+
+ if (file_is_encrypt(inode))
+ flags |= F2FS_ENCRYPT_FL;
+ if (f2fs_has_inline_data(inode) || f2fs_has_inline_dentry(inode))
+ flags |= F2FS_INLINE_DATA_FL;
+
+ flags &= F2FS_FL_USER_VISIBLE;
+
return put_user(flags, (int __user *)arg);
}
@@ -1620,15 +1640,15 @@
oldflags = fi->i_flags;
- if ((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL)) {
+ if ((flags ^ oldflags) & (F2FS_APPEND_FL | F2FS_IMMUTABLE_FL)) {
if (!capable(CAP_LINUX_IMMUTABLE)) {
ret = -EPERM;
goto unlock_out;
}
}
- flags = flags & FS_FL_USER_MODIFIABLE;
- flags |= oldflags & ~FS_FL_USER_MODIFIABLE;
+ flags = flags & (F2FS_FL_USER_MODIFIABLE);
+ flags |= oldflags & ~(F2FS_FL_USER_MODIFIABLE);
fi->i_flags = flags;
inode->i_ctime = current_time(inode);
@@ -1664,6 +1684,8 @@
inode_lock(inode);
+ down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
+
if (f2fs_is_atomic_file(inode))
goto out;
@@ -1671,28 +1693,25 @@
if (ret)
goto out;
- set_inode_flag(inode, FI_ATOMIC_FILE);
- set_inode_flag(inode, FI_HOT_DATA);
- f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
-
if (!get_dirty_pages(inode))
- goto inc_stat;
+ goto skip_flush;
f2fs_msg(F2FS_I_SB(inode)->sb, KERN_WARNING,
"Unexpected flush for atomic writes: ino=%lu, npages=%u",
inode->i_ino, get_dirty_pages(inode));
ret = filemap_write_and_wait_range(inode->i_mapping, 0, LLONG_MAX);
- if (ret) {
- clear_inode_flag(inode, FI_ATOMIC_FILE);
- clear_inode_flag(inode, FI_HOT_DATA);
+ if (ret)
goto out;
- }
+skip_flush:
+ set_inode_flag(inode, FI_ATOMIC_FILE);
+ clear_inode_flag(inode, FI_ATOMIC_REVOKE_REQUEST);
+ f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
-inc_stat:
F2FS_I(inode)->inmem_task = current;
stat_inc_atomic_write(inode);
stat_update_max_atomic_write(inode);
out:
+ up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
inode_unlock(inode);
mnt_drop_write_file(filp);
return ret;
@@ -1712,27 +1731,33 @@
inode_lock(inode);
- down_write(&F2FS_I(inode)->dio_rwsem[WRITE]);
+ down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
- if (f2fs_is_volatile_file(inode))
+ if (f2fs_is_volatile_file(inode)) {
+ ret = -EINVAL;
goto err_out;
+ }
if (f2fs_is_atomic_file(inode)) {
- ret = commit_inmem_pages(inode);
+ ret = f2fs_commit_inmem_pages(inode);
if (ret)
goto err_out;
ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 0, true);
if (!ret) {
clear_inode_flag(inode, FI_ATOMIC_FILE);
- clear_inode_flag(inode, FI_HOT_DATA);
+ F2FS_I(inode)->i_gc_failures[GC_FAILURE_ATOMIC] = 0;
stat_dec_atomic_write(inode);
}
} else {
ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 1, false);
}
err_out:
- up_write(&F2FS_I(inode)->dio_rwsem[WRITE]);
+ if (is_inode_flag_set(inode, FI_ATOMIC_REVOKE_REQUEST)) {
+ clear_inode_flag(inode, FI_ATOMIC_REVOKE_REQUEST);
+ ret = -EINVAL;
+ }
+ up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
inode_unlock(inode);
mnt_drop_write_file(filp);
return ret;
@@ -1817,7 +1842,7 @@
inode_lock(inode);
if (f2fs_is_atomic_file(inode))
- drop_inmem_pages(inode);
+ f2fs_drop_inmem_pages(inode);
if (f2fs_is_volatile_file(inode)) {
clear_inode_flag(inode, FI_VOLATILE_FILE);
stat_dec_volatile_write(inode);
@@ -1845,9 +1870,11 @@
if (get_user(in, (__u32 __user *)arg))
return -EFAULT;
- ret = mnt_want_write_file(filp);
- if (ret)
- return ret;
+ if (in != F2FS_GOING_DOWN_FULLSYNC) {
+ ret = mnt_want_write_file(filp);
+ if (ret)
+ return ret;
+ }
switch (in) {
case F2FS_GOING_DOWN_FULLSYNC:
@@ -1872,7 +1899,7 @@
f2fs_stop_checkpoint(sbi, false);
break;
case F2FS_GOING_DOWN_METAFLUSH:
- sync_meta_pages(sbi, META, LONG_MAX, FS_META_IO);
+ f2fs_sync_meta_pages(sbi, META, LONG_MAX, FS_META_IO);
f2fs_stop_checkpoint(sbi, false);
break;
default:
@@ -1880,15 +1907,16 @@
goto out;
}
- stop_gc_thread(sbi);
- stop_discard_thread(sbi);
+ f2fs_stop_gc_thread(sbi);
+ f2fs_stop_discard_thread(sbi);
- drop_discard_cmd(sbi);
+ f2fs_drop_discard_cmd(sbi);
clear_opt(sbi, DISCARD);
f2fs_update_time(sbi, REQ_TIME);
out:
- mnt_drop_write_file(filp);
+ if (in != F2FS_GOING_DOWN_FULLSYNC)
+ mnt_drop_write_file(filp);
return ret;
}
@@ -2047,15 +2075,15 @@
if (f2fs_readonly(sbi->sb))
return -EROFS;
+ end = range.start + range.len;
+ if (range.start < MAIN_BLKADDR(sbi) || end >= MAX_BLKADDR(sbi)) {
+ return -EINVAL;
+ }
+
ret = mnt_want_write_file(filp);
if (ret)
return ret;
- end = range.start + range.len;
- if (range.start < MAIN_BLKADDR(sbi) || end >= MAX_BLKADDR(sbi)) {
- ret = -EINVAL;
- goto out;
- }
do_more:
if (!range.sync) {
if (!mutex_trylock(&sbi->gc_mutex)) {
@@ -2075,7 +2103,7 @@
return ret;
}
-static int f2fs_ioc_write_checkpoint(struct file *filp, unsigned long arg)
+static int f2fs_ioc_f2fs_write_checkpoint(struct file *filp, unsigned long arg)
{
struct inode *inode = file_inode(filp);
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
@@ -2104,7 +2132,7 @@
struct inode *inode = file_inode(filp);
struct f2fs_map_blocks map = { .m_next_extent = NULL,
.m_seg_type = NO_CHECK_TYPE };
- struct extent_info ei = {0,0,0};
+ struct extent_info ei = {0, 0, 0};
pgoff_t pg_start, pg_end, next_pgofs;
unsigned int blk_per_seg = sbi->blocks_per_seg;
unsigned int total = 0, sec_num;
@@ -2113,7 +2141,7 @@
int err;
/* if in-place-update policy is enabled, don't waste time here */
- if (should_update_inplace(inode, NULL))
+ if (f2fs_should_update_inplace(inode, NULL))
return -EINVAL;
pg_start = range->start >> PAGE_SHIFT;
@@ -2208,7 +2236,7 @@
while (idx < map.m_lblk + map.m_len && cnt < blk_per_seg) {
struct page *page;
- page = get_lock_data_page(inode, idx, true);
+ page = f2fs_get_lock_data_page(inode, idx, true);
if (IS_ERR(page)) {
err = PTR_ERR(page);
goto clear_out;
@@ -2319,12 +2347,12 @@
}
inode_lock(src);
- down_write(&F2FS_I(src)->dio_rwsem[WRITE]);
+ down_write(&F2FS_I(src)->i_gc_rwsem[WRITE]);
if (src != dst) {
ret = -EBUSY;
if (!inode_trylock(dst))
goto out;
- if (!down_write_trylock(&F2FS_I(dst)->dio_rwsem[WRITE])) {
+ if (!down_write_trylock(&F2FS_I(dst)->i_gc_rwsem[WRITE])) {
inode_unlock(dst);
goto out;
}
@@ -2386,11 +2414,11 @@
f2fs_unlock_op(sbi);
out_unlock:
if (src != dst) {
- up_write(&F2FS_I(dst)->dio_rwsem[WRITE]);
+ up_write(&F2FS_I(dst)->i_gc_rwsem[WRITE]);
inode_unlock(dst);
}
out:
- up_write(&F2FS_I(src)->dio_rwsem[WRITE]);
+ up_write(&F2FS_I(src)->i_gc_rwsem[WRITE]);
inode_unlock(src);
return ret;
}
@@ -2517,12 +2545,14 @@
/* Use i_gc_failures for normal file as a risk signal. */
if (inc)
- f2fs_i_gc_failures_write(inode, fi->i_gc_failures + 1);
+ f2fs_i_gc_failures_write(inode,
+ fi->i_gc_failures[GC_FAILURE_PIN] + 1);
- if (fi->i_gc_failures > sbi->gc_pin_file_threshold) {
+ if (fi->i_gc_failures[GC_FAILURE_PIN] > sbi->gc_pin_file_threshold) {
f2fs_msg(sbi->sb, KERN_WARNING,
"%s: Enable GC = ino %lx after %x GC trials\n",
- __func__, inode->i_ino, fi->i_gc_failures);
+ __func__, inode->i_ino,
+ fi->i_gc_failures[GC_FAILURE_PIN]);
clear_inode_flag(inode, FI_PIN_FILE);
return -EAGAIN;
}
@@ -2553,14 +2583,14 @@
inode_lock(inode);
- if (should_update_outplace(inode, NULL)) {
+ if (f2fs_should_update_outplace(inode, NULL)) {
ret = -EINVAL;
goto out;
}
if (!pin) {
clear_inode_flag(inode, FI_PIN_FILE);
- F2FS_I(inode)->i_gc_failures = 1;
+ F2FS_I(inode)->i_gc_failures[GC_FAILURE_PIN] = 1;
goto done;
}
@@ -2573,7 +2603,7 @@
goto out;
set_inode_flag(inode, FI_PIN_FILE);
- ret = F2FS_I(inode)->i_gc_failures;
+ ret = F2FS_I(inode)->i_gc_failures[GC_FAILURE_PIN];
done:
f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
out:
@@ -2588,7 +2618,7 @@
__u32 pin = 0;
if (is_inode_flag_set(inode, FI_PIN_FILE))
- pin = F2FS_I(inode)->i_gc_failures;
+ pin = F2FS_I(inode)->i_gc_failures[GC_FAILURE_PIN];
return put_user(pin, (u32 __user *)arg);
}
@@ -2612,9 +2642,9 @@
while (map.m_lblk < end) {
map.m_len = end - map.m_lblk;
- down_write(&fi->dio_rwsem[WRITE]);
+ down_write(&fi->i_gc_rwsem[WRITE]);
err = f2fs_map_blocks(inode, &map, 0, F2FS_GET_BLOCK_PRECACHE);
- up_write(&fi->dio_rwsem[WRITE]);
+ up_write(&fi->i_gc_rwsem[WRITE]);
if (err)
return err;
@@ -2666,7 +2696,7 @@
case F2FS_IOC_GARBAGE_COLLECT_RANGE:
return f2fs_ioc_gc_range(filp, arg);
case F2FS_IOC_WRITE_CHECKPOINT:
- return f2fs_ioc_write_checkpoint(filp, arg);
+ return f2fs_ioc_f2fs_write_checkpoint(filp, arg);
case F2FS_IOC_DEFRAGMENT:
return f2fs_ioc_defragment(filp, arg);
case F2FS_IOC_MOVE_RANGE:
@@ -2690,7 +2720,6 @@
{
struct file *file = iocb->ki_filp;
struct inode *inode = file_inode(file);
- struct blk_plug plug;
ssize_t ret;
if (unlikely(f2fs_cp_error(F2FS_I_SB(inode))))
@@ -2720,6 +2749,8 @@
iov_iter_count(from)) ||
f2fs_has_inline_data(inode) ||
f2fs_force_buffered_io(inode, WRITE)) {
+ clear_inode_flag(inode,
+ FI_NO_PREALLOC);
inode_unlock(inode);
return -EAGAIN;
}
@@ -2735,9 +2766,7 @@
return err;
}
}
- blk_start_plug(&plug);
ret = __generic_file_write_iter(iocb, from);
- blk_finish_plug(&plug);
clear_inode_flag(inode, FI_NO_PREALLOC);
/* if we couldn't write data, we should deallocate blocks. */
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 66044fa..857dcc0 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -76,7 +76,7 @@
* invalidated soon after by user update or deletion.
* So, I'd like to wait some time to collect dirty segments.
*/
- if (gc_th->gc_urgent) {
+ if (sbi->gc_mode == GC_URGENT) {
wait_ms = gc_th->urgent_sleep_time;
mutex_lock(&sbi->gc_mutex);
goto do_gc;
@@ -114,7 +114,7 @@
return 0;
}
-int start_gc_thread(struct f2fs_sb_info *sbi)
+int f2fs_start_gc_thread(struct f2fs_sb_info *sbi)
{
struct f2fs_gc_kthread *gc_th;
dev_t dev = sbi->sb->s_bdev->bd_dev;
@@ -131,8 +131,6 @@
gc_th->max_sleep_time = DEF_GC_THREAD_MAX_SLEEP_TIME;
gc_th->no_gc_sleep_time = DEF_GC_THREAD_NOGC_SLEEP_TIME;
- gc_th->gc_idle = 0;
- gc_th->gc_urgent = 0;
gc_th->gc_wake= 0;
sbi->gc_thread = gc_th;
@@ -148,7 +146,7 @@
return err;
}
-void stop_gc_thread(struct f2fs_sb_info *sbi)
+void f2fs_stop_gc_thread(struct f2fs_sb_info *sbi)
{
struct f2fs_gc_kthread *gc_th = sbi->gc_thread;
if (!gc_th)
@@ -158,21 +156,19 @@
sbi->gc_thread = NULL;
}
-static int select_gc_type(struct f2fs_gc_kthread *gc_th, int gc_type)
+static int select_gc_type(struct f2fs_sb_info *sbi, int gc_type)
{
int gc_mode = (gc_type == BG_GC) ? GC_CB : GC_GREEDY;
- if (!gc_th)
- return gc_mode;
-
- if (gc_th->gc_idle) {
- if (gc_th->gc_idle == 1)
- gc_mode = GC_CB;
- else if (gc_th->gc_idle == 2)
- gc_mode = GC_GREEDY;
- }
- if (gc_th->gc_urgent)
+ switch (sbi->gc_mode) {
+ case GC_IDLE_CB:
+ gc_mode = GC_CB;
+ break;
+ case GC_IDLE_GREEDY:
+ case GC_URGENT:
gc_mode = GC_GREEDY;
+ break;
+ }
return gc_mode;
}
@@ -187,7 +183,7 @@
p->max_search = dirty_i->nr_dirty[type];
p->ofs_unit = 1;
} else {
- p->gc_mode = select_gc_type(sbi->gc_thread, gc_type);
+ p->gc_mode = select_gc_type(sbi, gc_type);
p->dirty_segmap = dirty_i->dirty_segmap[DIRTY];
p->max_search = dirty_i->nr_dirty[DIRTY];
p->ofs_unit = sbi->segs_per_sec;
@@ -195,7 +191,7 @@
/* we need to check every dirty segments in the FG_GC case */
if (gc_type != FG_GC &&
- (sbi->gc_thread && !sbi->gc_thread->gc_urgent) &&
+ (sbi->gc_mode != GC_URGENT) &&
p->max_search > sbi->max_victim_search)
p->max_search = sbi->max_victim_search;
@@ -234,10 +230,6 @@
for_each_set_bit(secno, dirty_i->victim_secmap, MAIN_SECS(sbi)) {
if (sec_usage_check(sbi, secno))
continue;
-
- if (no_fggc_candidate(sbi, secno))
- continue;
-
clear_bit(secno, dirty_i->victim_secmap);
return GET_SEG_FROM_SEC(sbi, secno);
}
@@ -377,9 +369,6 @@
goto next;
if (gc_type == BG_GC && test_bit(secno, dirty_i->victim_secmap))
goto next;
- if (gc_type == FG_GC && p.alloc_mode == LFS &&
- no_fggc_candidate(sbi, secno))
- goto next;
cost = get_gc_cost(sbi, segno, &p);
@@ -440,7 +429,7 @@
iput(inode);
return;
}
- new_ie = f2fs_kmem_cache_alloc(inode_entry_slab, GFP_NOFS);
+ new_ie = f2fs_kmem_cache_alloc(f2fs_inode_entry_slab, GFP_NOFS);
new_ie->inode = inode;
f2fs_radix_tree_insert(&gc_list->iroot, inode->i_ino, new_ie);
@@ -454,7 +443,7 @@
radix_tree_delete(&gc_list->iroot, ie->inode->i_ino);
iput(ie->inode);
list_del(&ie->list);
- kmem_cache_free(inode_entry_slab, ie);
+ kmem_cache_free(f2fs_inode_entry_slab, ie);
}
}
@@ -484,12 +473,16 @@
block_t start_addr;
int off;
int phase = 0;
+ bool fggc = (gc_type == FG_GC);
start_addr = START_BLOCK(sbi, segno);
next_step:
entry = sum;
+ if (fggc && phase == 2)
+ atomic_inc(&sbi->wb_sync_req[NODE]);
+
for (off = 0; off < sbi->blocks_per_seg; off++, entry++) {
nid_t nid = le32_to_cpu(entry->nid);
struct page *node_page;
@@ -503,39 +496,42 @@
continue;
if (phase == 0) {
- ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), 1,
+ f2fs_ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), 1,
META_NAT, true);
continue;
}
if (phase == 1) {
- ra_node_page(sbi, nid);
+ f2fs_ra_node_page(sbi, nid);
continue;
}
/* phase == 2 */
- node_page = get_node_page(sbi, nid);
+ node_page = f2fs_get_node_page(sbi, nid);
if (IS_ERR(node_page))
continue;
- /* block may become invalid during get_node_page */
+ /* block may become invalid during f2fs_get_node_page */
if (check_valid_map(sbi, segno, off) == 0) {
f2fs_put_page(node_page, 1);
continue;
}
- get_node_info(sbi, nid, &ni);
+ f2fs_get_node_info(sbi, nid, &ni);
if (ni.blk_addr != start_addr + off) {
f2fs_put_page(node_page, 1);
continue;
}
- move_node_page(node_page, gc_type);
+ f2fs_move_node_page(node_page, gc_type);
stat_inc_node_blk_count(sbi, 1, gc_type);
}
if (++phase < 3)
goto next_step;
+
+ if (fggc)
+ atomic_dec(&sbi->wb_sync_req[NODE]);
}
/*
@@ -545,7 +541,7 @@
* as indirect or double indirect node blocks, are given, it must be a caller's
* bug.
*/
-block_t start_bidx_of_node(unsigned int node_ofs, struct inode *inode)
+block_t f2fs_start_bidx_of_node(unsigned int node_ofs, struct inode *inode)
{
unsigned int indirect_blks = 2 * NIDS_PER_BLOCK + 4;
unsigned int bidx;
@@ -576,11 +572,11 @@
nid = le32_to_cpu(sum->nid);
ofs_in_node = le16_to_cpu(sum->ofs_in_node);
- node_page = get_node_page(sbi, nid);
+ node_page = f2fs_get_node_page(sbi, nid);
if (IS_ERR(node_page))
return false;
- get_node_info(sbi, nid, dni);
+ f2fs_get_node_info(sbi, nid, dni);
if (sum->version != dni->version) {
f2fs_msg(sbi->sb, KERN_WARNING,
@@ -603,7 +599,7 @@
* This can be used to move blocks, aka LBAs, directly on disk.
*/
static void move_data_block(struct inode *inode, block_t bidx,
- unsigned int segno, int off)
+ int gc_type, unsigned int segno, int off)
{
struct f2fs_io_info fio = {
.sbi = F2FS_I_SB(inode),
@@ -614,6 +610,7 @@
.op_flags = 0,
.encrypted_page = NULL,
.in_list = false,
+ .retry = false,
};
struct dnode_of_data dn;
struct f2fs_summary sum;
@@ -621,6 +618,7 @@
struct page *page;
block_t newaddr;
int err;
+ bool lfs_mode = test_opt(fio.sbi, LFS);
/* do not read out */
page = f2fs_grab_cache_page(inode->i_mapping, bidx, false);
@@ -630,8 +628,11 @@
if (!check_valid_map(F2FS_I_SB(inode), segno, off))
goto out;
- if (f2fs_is_atomic_file(inode))
+ if (f2fs_is_atomic_file(inode)) {
+ F2FS_I(inode)->i_gc_failures[GC_FAILURE_ATOMIC]++;
+ F2FS_I_SB(inode)->skipped_atomic_files[gc_type]++;
goto out;
+ }
if (f2fs_is_pinned_file(inode)) {
f2fs_pin_file_control(inode, true);
@@ -639,7 +640,7 @@
}
set_new_dnode(&dn, inode, NULL, NULL, 0);
- err = get_dnode_of_data(&dn, bidx, LOOKUP_NODE);
+ err = f2fs_get_dnode_of_data(&dn, bidx, LOOKUP_NODE);
if (err)
goto out;
@@ -654,14 +655,17 @@
*/
f2fs_wait_on_page_writeback(page, DATA, true);
- get_node_info(fio.sbi, dn.nid, &ni);
+ f2fs_get_node_info(fio.sbi, dn.nid, &ni);
set_summary(&sum, dn.nid, dn.ofs_in_node, ni.version);
/* read page */
fio.page = page;
fio.new_blkaddr = fio.old_blkaddr = dn.data_blkaddr;
- allocate_data_block(fio.sbi, NULL, fio.old_blkaddr, &newaddr,
+ if (lfs_mode)
+ down_write(&fio.sbi->io_order_lock);
+
+ f2fs_allocate_data_block(fio.sbi, NULL, fio.old_blkaddr, &newaddr,
&sum, CURSEG_COLD_DATA, NULL, false);
fio.encrypted_page = f2fs_pagecache_get_page(META_MAPPING(fio.sbi),
@@ -701,8 +705,8 @@
fio.op = REQ_OP_WRITE;
fio.op_flags = REQ_SYNC;
fio.new_blkaddr = newaddr;
- err = f2fs_submit_page_write(&fio);
- if (err) {
+ f2fs_submit_page_write(&fio);
+ if (fio.retry) {
if (PageWriteback(fio.encrypted_page))
end_page_writeback(fio.encrypted_page);
goto put_page_out;
@@ -717,8 +721,10 @@
put_page_out:
f2fs_put_page(fio.encrypted_page, 1);
recover_block:
+ if (lfs_mode)
+ up_write(&fio.sbi->io_order_lock);
if (err)
- __f2fs_replace_block(fio.sbi, &sum, newaddr, fio.old_blkaddr,
+ f2fs_do_replace_block(fio.sbi, &sum, newaddr, fio.old_blkaddr,
true, true);
put_out:
f2fs_put_dnode(&dn);
@@ -731,15 +737,18 @@
{
struct page *page;
- page = get_lock_data_page(inode, bidx, true);
+ page = f2fs_get_lock_data_page(inode, bidx, true);
if (IS_ERR(page))
return;
if (!check_valid_map(F2FS_I_SB(inode), segno, off))
goto out;
- if (f2fs_is_atomic_file(inode))
+ if (f2fs_is_atomic_file(inode)) {
+ F2FS_I(inode)->i_gc_failures[GC_FAILURE_ATOMIC]++;
+ F2FS_I_SB(inode)->skipped_atomic_files[gc_type]++;
goto out;
+ }
if (f2fs_is_pinned_file(inode)) {
if (gc_type == FG_GC)
f2fs_pin_file_control(inode, true);
@@ -773,15 +782,20 @@
f2fs_wait_on_page_writeback(page, DATA, true);
if (clear_page_dirty_for_io(page)) {
inode_dec_dirty_pages(inode);
- remove_dirty_inode(inode);
+ f2fs_remove_dirty_inode(inode);
}
set_cold_data(page);
- err = do_write_data_page(&fio);
- if (err == -ENOMEM && is_dirty) {
- congestion_wait(BLK_RW_ASYNC, HZ/50);
- goto retry;
+ err = f2fs_do_write_data_page(&fio);
+ if (err) {
+ clear_cold_data(page);
+ if (err == -ENOMEM) {
+ congestion_wait(BLK_RW_ASYNC, HZ/50);
+ goto retry;
+ }
+ if (is_dirty)
+ set_page_dirty(page);
}
}
out:
@@ -825,13 +839,13 @@
continue;
if (phase == 0) {
- ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), 1,
+ f2fs_ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), 1,
META_NAT, true);
continue;
}
if (phase == 1) {
- ra_node_page(sbi, nid);
+ f2fs_ra_node_page(sbi, nid);
continue;
}
@@ -840,7 +854,7 @@
continue;
if (phase == 2) {
- ra_node_page(sbi, dni.ino);
+ f2fs_ra_node_page(sbi, dni.ino);
continue;
}
@@ -858,16 +872,16 @@
}
if (!down_write_trylock(
- &F2FS_I(inode)->dio_rwsem[WRITE])) {
+ &F2FS_I(inode)->i_gc_rwsem[WRITE])) {
iput(inode);
continue;
}
- start_bidx = start_bidx_of_node(nofs, inode);
- data_page = get_read_data_page(inode,
+ start_bidx = f2fs_start_bidx_of_node(nofs, inode);
+ data_page = f2fs_get_read_data_page(inode,
start_bidx + ofs_in_node, REQ_RAHEAD,
true);
- up_write(&F2FS_I(inode)->dio_rwsem[WRITE]);
+ up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
if (IS_ERR(data_page)) {
iput(inode);
continue;
@@ -885,11 +899,11 @@
bool locked = false;
if (S_ISREG(inode->i_mode)) {
- if (!down_write_trylock(&fi->dio_rwsem[READ]))
+ if (!down_write_trylock(&fi->i_gc_rwsem[READ]))
continue;
if (!down_write_trylock(
- &fi->dio_rwsem[WRITE])) {
- up_write(&fi->dio_rwsem[READ]);
+ &fi->i_gc_rwsem[WRITE])) {
+ up_write(&fi->i_gc_rwsem[READ]);
continue;
}
locked = true;
@@ -898,17 +912,18 @@
inode_dio_wait(inode);
}
- start_bidx = start_bidx_of_node(nofs, inode)
+ start_bidx = f2fs_start_bidx_of_node(nofs, inode)
+ ofs_in_node;
if (f2fs_post_read_required(inode))
- move_data_block(inode, start_bidx, segno, off);
+ move_data_block(inode, start_bidx, gc_type,
+ segno, off);
else
move_data_page(inode, start_bidx, gc_type,
segno, off);
if (locked) {
- up_write(&fi->dio_rwsem[WRITE]);
- up_write(&fi->dio_rwsem[READ]);
+ up_write(&fi->i_gc_rwsem[WRITE]);
+ up_write(&fi->i_gc_rwsem[READ]);
}
stat_inc_data_blk_count(sbi, 1, gc_type);
@@ -947,12 +962,12 @@
/* readahead multi ssa blocks those have contiguous address */
if (sbi->segs_per_sec > 1)
- ra_meta_pages(sbi, GET_SUM_BLOCK(sbi, segno),
+ f2fs_ra_meta_pages(sbi, GET_SUM_BLOCK(sbi, segno),
sbi->segs_per_sec, META_SSA, true);
/* reference all summary page */
while (segno < end_segno) {
- sum_page = get_sum_page(sbi, segno++);
+ sum_page = f2fs_get_sum_page(sbi, segno++);
unlock_page(sum_page);
}
@@ -1018,6 +1033,8 @@
.ilist = LIST_HEAD_INIT(gc_list.ilist),
.iroot = RADIX_TREE_INIT(GFP_NOFS),
};
+ unsigned long long last_skipped = sbi->skipped_atomic_files[FG_GC];
+ unsigned int skipped_round = 0, round = 0;
trace_f2fs_gc_begin(sbi->sb, sync, background,
get_pages(sbi, F2FS_DIRTY_NODES),
@@ -1046,7 +1063,7 @@
* secure free segments which doesn't need fggc any more.
*/
if (prefree_segments(sbi)) {
- ret = write_checkpoint(sbi, &cpc);
+ ret = f2fs_write_checkpoint(sbi, &cpc);
if (ret)
goto stop;
}
@@ -1069,17 +1086,27 @@
sec_freed++;
total_freed += seg_freed;
+ if (gc_type == FG_GC) {
+ if (sbi->skipped_atomic_files[FG_GC] > last_skipped)
+ skipped_round++;
+ last_skipped = sbi->skipped_atomic_files[FG_GC];
+ round++;
+ }
+
if (gc_type == FG_GC)
sbi->cur_victim_sec = NULL_SEGNO;
if (!sync) {
if (has_not_enough_free_secs(sbi, sec_freed, 0)) {
+ if (skipped_round > MAX_SKIP_ATOMIC_COUNT &&
+ skipped_round * 2 >= round)
+ f2fs_drop_inmem_pages_all(sbi, true);
segno = NULL_SEGNO;
goto gc_more;
}
if (gc_type == FG_GC)
- ret = write_checkpoint(sbi, &cpc);
+ ret = f2fs_write_checkpoint(sbi, &cpc);
}
stop:
SIT_I(sbi)->last_victim[ALLOC_NEXT] = 0;
@@ -1103,19 +1130,10 @@
return ret;
}
-void build_gc_manager(struct f2fs_sb_info *sbi)
+void f2fs_build_gc_manager(struct f2fs_sb_info *sbi)
{
- u64 main_count, resv_count, ovp_count;
-
DIRTY_I(sbi)->v_ops = &default_v_ops;
- /* threshold of # of valid blocks in a section for victims of FG_GC */
- main_count = SM_I(sbi)->main_segments << sbi->log_blocks_per_seg;
- resv_count = SM_I(sbi)->reserved_segments << sbi->log_blocks_per_seg;
- ovp_count = SM_I(sbi)->ovp_segments << sbi->log_blocks_per_seg;
-
- sbi->fggc_threshold = div64_u64((main_count - ovp_count) *
- BLKS_PER_SEC(sbi), (main_count - resv_count));
sbi->gc_pin_file_threshold = DEF_GC_FAILED_PINNED_FILES;
/* give warm/cold data area from slower device */
diff --git a/fs/f2fs/gc.h b/fs/f2fs/gc.h
index b0045d4..c8619e4 100644
--- a/fs/f2fs/gc.h
+++ b/fs/f2fs/gc.h
@@ -36,8 +36,6 @@
unsigned int no_gc_sleep_time;
/* for changing gc mode */
- unsigned int gc_idle;
- unsigned int gc_urgent;
unsigned int gc_wake;
};
diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c
index 156ac4f..3f0c74d 100644
--- a/fs/f2fs/inline.c
+++ b/fs/f2fs/inline.c
@@ -43,7 +43,7 @@
return true;
}
-void read_inline_data(struct page *page, struct page *ipage)
+void f2fs_do_read_inline_data(struct page *page, struct page *ipage)
{
struct inode *inode = page->mapping->host;
void *src_addr, *dst_addr;
@@ -65,7 +65,8 @@
SetPageUptodate(page);
}
-void truncate_inline_inode(struct inode *inode, struct page *ipage, u64 from)
+void f2fs_truncate_inline_inode(struct inode *inode,
+ struct page *ipage, u64 from)
{
void *addr;
@@ -97,7 +98,7 @@
path, current->comm);
}
- ipage = get_node_page(F2FS_I_SB(inode), inode->i_ino);
+ ipage = f2fs_get_node_page(F2FS_I_SB(inode), inode->i_ino);
if (IS_ERR(ipage)) {
trace_android_fs_dataread_end(inode, page_offset(page),
PAGE_SIZE);
@@ -115,7 +116,7 @@
if (page->index)
zero_user_segment(page, 0, PAGE_SIZE);
else
- read_inline_data(page, ipage);
+ f2fs_do_read_inline_data(page, ipage);
if (!PageUptodate(page))
SetPageUptodate(page);
@@ -149,7 +150,7 @@
f2fs_bug_on(F2FS_P_SB(page), PageWriteback(page));
- read_inline_data(page, dn->inode_page);
+ f2fs_do_read_inline_data(page, dn->inode_page);
set_page_dirty(page);
/* clear dirty state */
@@ -160,18 +161,18 @@
ClearPageError(page);
fio.old_blkaddr = dn->data_blkaddr;
set_inode_flag(dn->inode, FI_HOT_DATA);
- write_data_page(dn, &fio);
+ f2fs_outplace_write_data(dn, &fio);
f2fs_wait_on_page_writeback(page, DATA, true);
if (dirty) {
inode_dec_dirty_pages(dn->inode);
- remove_dirty_inode(dn->inode);
+ f2fs_remove_dirty_inode(dn->inode);
}
/* this converted inline_data should be recovered. */
set_inode_flag(dn->inode, FI_APPEND_WRITE);
/* clear inline data and flag after data writeback */
- truncate_inline_inode(dn->inode, dn->inode_page, 0);
+ f2fs_truncate_inline_inode(dn->inode, dn->inode_page, 0);
clear_inline_node(dn->inode_page);
clear_out:
stat_dec_inline_inode(dn->inode);
@@ -196,7 +197,7 @@
f2fs_lock_op(sbi);
- ipage = get_node_page(sbi, inode->i_ino);
+ ipage = f2fs_get_node_page(sbi, inode->i_ino);
if (IS_ERR(ipage)) {
err = PTR_ERR(ipage);
goto out;
@@ -222,12 +223,10 @@
{
void *src_addr, *dst_addr;
struct dnode_of_data dn;
- struct address_space *mapping = page_mapping(page);
- unsigned long flags;
int err;
set_new_dnode(&dn, inode, NULL, NULL, 0);
- err = get_dnode_of_data(&dn, 0, LOOKUP_NODE);
+ err = f2fs_get_dnode_of_data(&dn, 0, LOOKUP_NODE);
if (err)
return err;
@@ -245,10 +244,7 @@
kunmap_atomic(src_addr);
set_page_dirty(dn.inode_page);
- spin_lock_irqsave(&mapping->tree_lock, flags);
- radix_tree_tag_clear(&mapping->page_tree, page_index(page),
- PAGECACHE_TAG_DIRTY);
- spin_unlock_irqrestore(&mapping->tree_lock, flags);
+ f2fs_clear_radix_tree_dirty_tag(page);
set_inode_flag(inode, FI_APPEND_WRITE);
set_inode_flag(inode, FI_DATA_EXIST);
@@ -258,7 +254,7 @@
return 0;
}
-bool recover_inline_data(struct inode *inode, struct page *npage)
+bool f2fs_recover_inline_data(struct inode *inode, struct page *npage)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
struct f2fs_inode *ri = NULL;
@@ -279,7 +275,7 @@
if (f2fs_has_inline_data(inode) &&
ri && (ri->i_inline & F2FS_INLINE_DATA)) {
process_inline:
- ipage = get_node_page(sbi, inode->i_ino);
+ ipage = f2fs_get_node_page(sbi, inode->i_ino);
f2fs_bug_on(sbi, IS_ERR(ipage));
f2fs_wait_on_page_writeback(ipage, NODE, true);
@@ -297,20 +293,20 @@
}
if (f2fs_has_inline_data(inode)) {
- ipage = get_node_page(sbi, inode->i_ino);
+ ipage = f2fs_get_node_page(sbi, inode->i_ino);
f2fs_bug_on(sbi, IS_ERR(ipage));
- truncate_inline_inode(inode, ipage, 0);
+ f2fs_truncate_inline_inode(inode, ipage, 0);
clear_inode_flag(inode, FI_INLINE_DATA);
f2fs_put_page(ipage, 1);
} else if (ri && (ri->i_inline & F2FS_INLINE_DATA)) {
- if (truncate_blocks(inode, 0, false))
+ if (f2fs_truncate_blocks(inode, 0, false))
return false;
goto process_inline;
}
return false;
}
-struct f2fs_dir_entry *find_in_inline_dir(struct inode *dir,
+struct f2fs_dir_entry *f2fs_find_in_inline_dir(struct inode *dir,
struct fscrypt_name *fname, struct page **res_page)
{
struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb);
@@ -321,7 +317,7 @@
void *inline_dentry;
f2fs_hash_t namehash;
- ipage = get_node_page(sbi, dir->i_ino);
+ ipage = f2fs_get_node_page(sbi, dir->i_ino);
if (IS_ERR(ipage)) {
*res_page = ipage;
return NULL;
@@ -332,7 +328,7 @@
inline_dentry = inline_data_addr(dir, ipage);
make_dentry_ptr_inline(dir, &d, inline_dentry);
- de = find_target_dentry(fname, namehash, NULL, &d);
+ de = f2fs_find_target_dentry(fname, namehash, NULL, &d);
unlock_page(ipage);
if (de)
*res_page = ipage;
@@ -342,7 +338,7 @@
return de;
}
-int make_empty_inline_dir(struct inode *inode, struct inode *parent,
+int f2fs_make_empty_inline_dir(struct inode *inode, struct inode *parent,
struct page *ipage)
{
struct f2fs_dentry_ptr d;
@@ -351,7 +347,7 @@
inline_dentry = inline_data_addr(inode, ipage);
make_dentry_ptr_inline(inode, &d, inline_dentry);
- do_make_empty_dir(inode, parent, &d);
+ f2fs_do_make_empty_dir(inode, parent, &d);
set_page_dirty(ipage);
@@ -386,7 +382,6 @@
goto out;
f2fs_wait_on_page_writeback(page, DATA, true);
- zero_user_segment(page, MAX_INLINE_DATA(dir), PAGE_SIZE);
dentry_blk = page_address(page);
@@ -410,7 +405,7 @@
set_page_dirty(page);
/* clear inline dir and flag after data writeback */
- truncate_inline_inode(dir, ipage, 0);
+ f2fs_truncate_inline_inode(dir, ipage, 0);
stat_dec_inline_dir(dir);
clear_inode_flag(dir, FI_INLINE_DENTRY);
@@ -453,7 +448,7 @@
new_name.len = le16_to_cpu(de->name_len);
ino = le32_to_cpu(de->ino);
- fake_mode = get_de_type(de) << S_SHIFT;
+ fake_mode = f2fs_get_de_type(de) << S_SHIFT;
err = f2fs_add_regular_entry(dir, &new_name, NULL, NULL,
ino, fake_mode);
@@ -465,8 +460,8 @@
return 0;
punch_dentry_pages:
truncate_inode_pages(&dir->i_data, 0);
- truncate_blocks(dir, 0, false);
- remove_dirty_inode(dir);
+ f2fs_truncate_blocks(dir, 0, false);
+ f2fs_remove_dirty_inode(dir);
return err;
}
@@ -484,7 +479,7 @@
}
memcpy(backup_dentry, inline_dentry, MAX_INLINE_DATA(dir));
- truncate_inline_inode(dir, ipage, 0);
+ f2fs_truncate_inline_inode(dir, ipage, 0);
unlock_page(ipage);
@@ -533,14 +528,14 @@
struct page *page = NULL;
int err = 0;
- ipage = get_node_page(sbi, dir->i_ino);
+ ipage = f2fs_get_node_page(sbi, dir->i_ino);
if (IS_ERR(ipage))
return PTR_ERR(ipage);
inline_dentry = inline_data_addr(dir, ipage);
make_dentry_ptr_inline(dir, &d, inline_dentry);
- bit_pos = room_for_filename(d.bitmap, slots, d.max);
+ bit_pos = f2fs_room_for_filename(d.bitmap, slots, d.max);
if (bit_pos >= d.max) {
err = f2fs_convert_inline_dir(dir, ipage, inline_dentry);
if (err)
@@ -551,7 +546,7 @@
if (inode) {
down_write(&F2FS_I(inode)->i_sem);
- page = init_inode_metadata(inode, dir, new_name,
+ page = f2fs_init_inode_metadata(inode, dir, new_name,
orig_name, ipage);
if (IS_ERR(page)) {
err = PTR_ERR(page);
@@ -572,7 +567,7 @@
f2fs_put_page(page, 1);
}
- update_parent_metadata(dir, inode, 0);
+ f2fs_update_parent_metadata(dir, inode, 0);
fail:
if (inode)
up_write(&F2FS_I(inode)->i_sem);
@@ -618,7 +613,7 @@
void *inline_dentry;
struct f2fs_dentry_ptr d;
- ipage = get_node_page(sbi, dir->i_ino);
+ ipage = f2fs_get_node_page(sbi, dir->i_ino);
if (IS_ERR(ipage))
return false;
@@ -649,7 +644,7 @@
if (ctx->pos == d.max)
return 0;
- ipage = get_node_page(F2FS_I_SB(inode), inode->i_ino);
+ ipage = f2fs_get_node_page(F2FS_I_SB(inode), inode->i_ino);
if (IS_ERR(ipage))
return PTR_ERR(ipage);
@@ -675,7 +670,7 @@
struct page *ipage;
int err = 0;
- ipage = get_node_page(F2FS_I_SB(inode), inode->i_ino);
+ ipage = f2fs_get_node_page(F2FS_I_SB(inode), inode->i_ino);
if (IS_ERR(ipage))
return PTR_ERR(ipage);
@@ -691,7 +686,7 @@
ilen = start + len;
ilen -= start;
- get_node_info(F2FS_I_SB(inode), inode->i_ino, &ni);
+ f2fs_get_node_info(F2FS_I_SB(inode), inode->i_ino, &ni);
byteaddr = (__u64)ni.blk_addr << inode->i_sb->s_blocksize_bits;
byteaddr += (char *)inline_data_addr(inode, ipage) -
(char *)F2FS_INODE(ipage);
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
index e0d9e8f..30a7773 100644
--- a/fs/f2fs/inode.c
+++ b/fs/f2fs/inode.c
@@ -36,15 +36,15 @@
unsigned int flags = F2FS_I(inode)->i_flags;
unsigned int new_fl = 0;
- if (flags & FS_SYNC_FL)
+ if (flags & F2FS_SYNC_FL)
new_fl |= S_SYNC;
- if (flags & FS_APPEND_FL)
+ if (flags & F2FS_APPEND_FL)
new_fl |= S_APPEND;
- if (flags & FS_IMMUTABLE_FL)
+ if (flags & F2FS_IMMUTABLE_FL)
new_fl |= S_IMMUTABLE;
- if (flags & FS_NOATIME_FL)
+ if (flags & F2FS_NOATIME_FL)
new_fl |= S_NOATIME;
- if (flags & FS_DIRSYNC_FL)
+ if (flags & F2FS_DIRSYNC_FL)
new_fl |= S_DIRSYNC;
if (f2fs_encrypted_inode(inode))
new_fl |= S_ENCRYPTED;
@@ -72,7 +72,7 @@
{
block_t addr = le32_to_cpu(ri->i_addr[offset_in_addr(ri)]);
- if (addr != NEW_ADDR && addr != NULL_ADDR)
+ if (is_valid_blkaddr(addr))
return true;
return false;
}
@@ -117,7 +117,6 @@
static bool f2fs_enable_inode_chksum(struct f2fs_sb_info *sbi, struct page *page)
{
struct f2fs_inode *ri = &F2FS_NODE(page)->i;
- int extra_isize = le32_to_cpu(ri->i_extra_isize);
if (!f2fs_sb_has_inode_chksum(sbi->sb))
return false;
@@ -125,7 +124,8 @@
if (!RAW_IS_INODE(F2FS_NODE(page)) || !(ri->i_inline & F2FS_EXTRA_ATTR))
return false;
- if (!F2FS_FITS_IN_INODE(ri, extra_isize, i_inode_checksum))
+ if (!F2FS_FITS_IN_INODE(ri, le16_to_cpu(ri->i_extra_isize),
+ i_inode_checksum))
return false;
return true;
@@ -185,6 +185,21 @@
ri->i_inode_checksum = cpu_to_le32(f2fs_inode_chksum(sbi, page));
}
+static bool sanity_check_inode(struct inode *inode)
+{
+ struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+
+ if (f2fs_sb_has_flexible_inline_xattr(sbi->sb)
+ && !f2fs_has_extra_attr(inode)) {
+ set_sbi_flag(sbi, SBI_NEED_FSCK);
+ f2fs_msg(sbi->sb, KERN_WARNING,
+ "%s: corrupted inode ino=%lx, run fsck to fix.",
+ __func__, inode->i_ino);
+ return false;
+ }
+ return true;
+}
+
static int do_read_inode(struct inode *inode)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
@@ -194,14 +209,10 @@
projid_t i_projid;
/* Check if ino is within scope */
- if (check_nid_range(sbi, inode->i_ino)) {
- f2fs_msg(inode->i_sb, KERN_ERR, "bad inode number: %lu",
- (unsigned long) inode->i_ino);
- WARN_ON(1);
+ if (f2fs_check_nid_range(sbi, inode->i_ino))
return -EINVAL;
- }
- node_page = get_node_page(sbi, inode->i_ino);
+ node_page = f2fs_get_node_page(sbi, inode->i_ino);
if (IS_ERR(node_page))
return PTR_ERR(node_page);
@@ -221,8 +232,11 @@
inode->i_ctime.tv_nsec = le32_to_cpu(ri->i_ctime_nsec);
inode->i_mtime.tv_nsec = le32_to_cpu(ri->i_mtime_nsec);
inode->i_generation = le32_to_cpu(ri->i_generation);
-
- fi->i_current_depth = le32_to_cpu(ri->i_current_depth);
+ if (S_ISDIR(inode->i_mode))
+ fi->i_current_depth = le32_to_cpu(ri->i_current_depth);
+ else if (S_ISREG(inode->i_mode))
+ fi->i_gc_failures[GC_FAILURE_PIN] =
+ le16_to_cpu(ri->i_gc_failures);
fi->i_xattr_nid = le32_to_cpu(ri->i_xattr_nid);
fi->i_flags = le32_to_cpu(ri->i_flags);
fi->flags = 0;
@@ -239,7 +253,6 @@
le16_to_cpu(ri->i_extra_isize) : 0;
if (f2fs_sb_has_flexible_inline_xattr(sbi->sb)) {
- f2fs_bug_on(sbi, !f2fs_has_extra_attr(inode));
fi->i_inline_xattr_size = le16_to_cpu(ri->i_inline_xattr_size);
} else if (f2fs_has_inline_xattr(inode) ||
f2fs_has_inline_dentry(inode)) {
@@ -265,10 +278,10 @@
if (__written_first_block(ri))
set_inode_flag(inode, FI_FIRST_BLOCK_WRITTEN);
- if (!need_inode_block_update(sbi, inode->i_ino))
+ if (!f2fs_need_inode_block_update(sbi, inode->i_ino))
fi->last_disk_size = inode->i_size;
- if (fi->i_flags & FS_PROJINHERIT_FL)
+ if (fi->i_flags & F2FS_PROJINHERIT_FL)
set_inode_flag(inode, FI_PROJ_INHERIT);
if (f2fs_has_extra_attr(inode) && f2fs_sb_has_project_quota(sbi->sb) &&
@@ -317,13 +330,17 @@
ret = do_read_inode(inode);
if (ret)
goto bad_inode;
+ if (!sanity_check_inode(inode)) {
+ ret = -EINVAL;
+ goto bad_inode;
+ }
make_now:
if (ino == F2FS_NODE_INO(sbi)) {
inode->i_mapping->a_ops = &f2fs_node_aops;
- mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_ZERO);
+ mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
} else if (ino == F2FS_META_INO(sbi)) {
inode->i_mapping->a_ops = &f2fs_meta_aops;
- mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_ZERO);
+ mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
} else if (S_ISREG(inode->i_mode)) {
inode->i_op = &f2fs_file_inode_operations;
inode->i_fop = &f2fs_file_operations;
@@ -373,7 +390,7 @@
return inode;
}
-void update_inode(struct inode *inode, struct page *node_page)
+void f2fs_update_inode(struct inode *inode, struct page *node_page)
{
struct f2fs_inode *ri;
struct extent_tree *et = F2FS_I(inode)->extent_tree;
@@ -408,7 +425,12 @@
ri->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec);
ri->i_ctime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec);
ri->i_mtime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec);
- ri->i_current_depth = cpu_to_le32(F2FS_I(inode)->i_current_depth);
+ if (S_ISDIR(inode->i_mode))
+ ri->i_current_depth =
+ cpu_to_le32(F2FS_I(inode)->i_current_depth);
+ else if (S_ISREG(inode->i_mode))
+ ri->i_gc_failures =
+ cpu_to_le16(F2FS_I(inode)->i_gc_failures[GC_FAILURE_PIN]);
ri->i_xattr_nid = cpu_to_le32(F2FS_I(inode)->i_xattr_nid);
ri->i_flags = cpu_to_le32(F2FS_I(inode)->i_flags);
ri->i_pino = cpu_to_le32(F2FS_I(inode)->i_pino);
@@ -454,12 +476,12 @@
F2FS_I(inode)->i_disk_time[3] = F2FS_I(inode)->i_crtime;
}
-void update_inode_page(struct inode *inode)
+void f2fs_update_inode_page(struct inode *inode)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
struct page *node_page;
retry:
- node_page = get_node_page(sbi, inode->i_ino);
+ node_page = f2fs_get_node_page(sbi, inode->i_ino);
if (IS_ERR(node_page)) {
int err = PTR_ERR(node_page);
if (err == -ENOMEM) {
@@ -470,7 +492,7 @@
}
return;
}
- update_inode(inode, node_page);
+ f2fs_update_inode(inode, node_page);
f2fs_put_page(node_page, 1);
}
@@ -489,7 +511,7 @@
* We need to balance fs here to prevent from producing dirty node pages
* during the urgent cleaning time when runing out of free sections.
*/
- update_inode_page(inode);
+ f2fs_update_inode_page(inode);
if (wbc && wbc->nr_to_write)
f2fs_balance_fs(sbi, true);
return 0;
@@ -506,7 +528,7 @@
/* some remained atomic pages should discarded */
if (f2fs_is_atomic_file(inode))
- drop_inmem_pages(inode);
+ f2fs_drop_inmem_pages(inode);
trace_f2fs_evict_inode(inode);
truncate_inode_pages_final(&inode->i_data);
@@ -516,7 +538,7 @@
goto out_clear;
f2fs_bug_on(sbi, get_dirty_pages(inode));
- remove_dirty_inode(inode);
+ f2fs_remove_dirty_inode(inode);
f2fs_destroy_extent_tree(inode);
@@ -525,9 +547,9 @@
dquot_initialize(inode);
- remove_ino_entry(sbi, inode->i_ino, APPEND_INO);
- remove_ino_entry(sbi, inode->i_ino, UPDATE_INO);
- remove_ino_entry(sbi, inode->i_ino, FLUSH_INO);
+ f2fs_remove_ino_entry(sbi, inode->i_ino, APPEND_INO);
+ f2fs_remove_ino_entry(sbi, inode->i_ino, UPDATE_INO);
+ f2fs_remove_ino_entry(sbi, inode->i_ino, FLUSH_INO);
sb_start_intwrite(inode->i_sb);
set_inode_flag(inode, FI_NO_ALLOC);
@@ -544,7 +566,7 @@
#endif
if (!err) {
f2fs_lock_op(sbi);
- err = remove_inode_page(inode);
+ err = f2fs_remove_inode_page(inode);
f2fs_unlock_op(sbi);
if (err == -ENOENT)
err = 0;
@@ -557,7 +579,7 @@
}
if (err)
- update_inode_page(inode);
+ f2fs_update_inode_page(inode);
dquot_free_inode(inode);
sb_end_intwrite(inode->i_sb);
no_delete:
@@ -580,16 +602,19 @@
invalidate_mapping_pages(NODE_MAPPING(sbi), xnid, xnid);
if (inode->i_nlink) {
if (is_inode_flag_set(inode, FI_APPEND_WRITE))
- add_ino_entry(sbi, inode->i_ino, APPEND_INO);
+ f2fs_add_ino_entry(sbi, inode->i_ino, APPEND_INO);
if (is_inode_flag_set(inode, FI_UPDATE_WRITE))
- add_ino_entry(sbi, inode->i_ino, UPDATE_INO);
+ f2fs_add_ino_entry(sbi, inode->i_ino, UPDATE_INO);
}
if (is_inode_flag_set(inode, FI_FREE_NID)) {
- alloc_nid_failed(sbi, inode->i_ino);
+ f2fs_alloc_nid_failed(sbi, inode->i_ino);
clear_inode_flag(inode, FI_FREE_NID);
} else {
- f2fs_bug_on(sbi, err &&
- !exist_written_data(sbi, inode->i_ino, ORPHAN_INO));
+ /*
+ * If xattr nid is corrupted, we can reach out error condition,
+ * err & !f2fs_exist_written_data(sbi, inode->i_ino, ORPHAN_INO)).
+ * In that case, f2fs_check_nid_range() is enough to give a clue.
+ */
}
out_clear:
fscrypt_put_encryption_info(inode);
@@ -597,7 +622,7 @@
}
/* caller should call f2fs_lock_op() */
-void handle_failed_inode(struct inode *inode)
+void f2fs_handle_failed_inode(struct inode *inode)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
struct node_info ni;
@@ -612,7 +637,7 @@
* we must call this to avoid inode being remained as dirty, resulting
* in a panic when flushing dirty inodes in gdirty_list.
*/
- update_inode_page(inode);
+ f2fs_update_inode_page(inode);
f2fs_inode_synced(inode);
/* don't make bad inode, since it becomes a regular file. */
@@ -623,18 +648,18 @@
* so we can prevent losing this orphan when encoutering checkpoint
* and following suddenly power-off.
*/
- get_node_info(sbi, inode->i_ino, &ni);
+ f2fs_get_node_info(sbi, inode->i_ino, &ni);
if (ni.blk_addr != NULL_ADDR) {
- int err = acquire_orphan_inode(sbi);
+ int err = f2fs_acquire_orphan_inode(sbi);
if (err) {
set_sbi_flag(sbi, SBI_NEED_FSCK);
f2fs_msg(sbi->sb, KERN_WARNING,
"Too many orphan inodes, run fsck to fix.");
} else {
- add_orphan_inode(inode);
+ f2fs_add_orphan_inode(inode);
}
- alloc_nid_done(sbi, inode->i_ino);
+ f2fs_alloc_nid_done(sbi, inode->i_ino);
} else {
set_inode_flag(inode, FI_FREE_NID);
}
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
index f1e1ff1..c53760e 100644
--- a/fs/f2fs/namei.c
+++ b/fs/f2fs/namei.c
@@ -37,7 +37,7 @@
return ERR_PTR(-ENOMEM);
f2fs_lock_op(sbi);
- if (!alloc_nid(sbi, &ino)) {
+ if (!f2fs_alloc_nid(sbi, &ino)) {
f2fs_unlock_op(sbi);
err = -ENOSPC;
goto fail;
@@ -54,6 +54,9 @@
F2FS_I(inode)->i_crtime = current_time(inode);
inode->i_generation = sbi->s_next_generation++;
+ if (S_ISDIR(inode->i_mode))
+ F2FS_I(inode)->i_current_depth = 1;
+
err = insert_inode_locked(inode);
if (err) {
err = -EINVAL;
@@ -61,7 +64,7 @@
}
if (f2fs_sb_has_project_quota(sbi->sb) &&
- (F2FS_I(dir)->i_flags & FS_PROJINHERIT_FL))
+ (F2FS_I(dir)->i_flags & F2FS_PROJINHERIT_FL))
F2FS_I(inode)->i_projid = F2FS_I(dir)->i_projid;
else
F2FS_I(inode)->i_projid = make_kprojid(&init_user_ns,
@@ -116,9 +119,9 @@
f2fs_mask_flags(mode, F2FS_I(dir)->i_flags & F2FS_FL_INHERITED);
if (S_ISDIR(inode->i_mode))
- F2FS_I(inode)->i_flags |= FS_INDEX_FL;
+ F2FS_I(inode)->i_flags |= F2FS_INDEX_FL;
- if (F2FS_I(inode)->i_flags & FS_PROJINHERIT_FL)
+ if (F2FS_I(inode)->i_flags & F2FS_PROJINHERIT_FL)
set_inode_flag(inode, FI_PROJ_INHERIT);
trace_f2fs_new_inode(inode, 0);
@@ -193,7 +196,7 @@
up_read(&sbi->sb_lock);
}
-int update_extension_list(struct f2fs_sb_info *sbi, const char *name,
+int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name,
bool hot, bool set)
{
__u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list;
@@ -292,7 +295,7 @@
goto out;
f2fs_unlock_op(sbi);
- alloc_nid_done(sbi, ino);
+ f2fs_alloc_nid_done(sbi, ino);
d_instantiate_new(dentry, inode);
@@ -302,7 +305,7 @@
f2fs_balance_fs(sbi, true);
return 0;
out:
- handle_failed_inode(inode);
+ f2fs_handle_failed_inode(inode);
return err;
}
@@ -397,7 +400,7 @@
err = PTR_ERR(page);
goto out;
} else {
- err = __f2fs_add_link(dir, &dot, NULL, dir->i_ino, S_IFDIR);
+ err = f2fs_do_add_link(dir, &dot, NULL, dir->i_ino, S_IFDIR);
if (err)
goto out;
}
@@ -408,7 +411,7 @@
else if (IS_ERR(page))
err = PTR_ERR(page);
else
- err = __f2fs_add_link(dir, &dotdot, NULL, pino, S_IFDIR);
+ err = f2fs_do_add_link(dir, &dotdot, NULL, pino, S_IFDIR);
out:
if (!err)
clear_inode_flag(dir, FI_INLINE_DOTS);
@@ -520,7 +523,7 @@
f2fs_balance_fs(sbi, true);
f2fs_lock_op(sbi);
- err = acquire_orphan_inode(sbi);
+ err = f2fs_acquire_orphan_inode(sbi);
if (err) {
f2fs_unlock_op(sbi);
f2fs_put_page(page, 0);
@@ -585,9 +588,9 @@
f2fs_lock_op(sbi);
err = f2fs_add_link(dentry, inode);
if (err)
- goto out_handle_failed_inode;
+ goto out_f2fs_handle_failed_inode;
f2fs_unlock_op(sbi);
- alloc_nid_done(sbi, inode->i_ino);
+ f2fs_alloc_nid_done(sbi, inode->i_ino);
err = fscrypt_encrypt_symlink(inode, symname, len, &disk_link);
if (err)
@@ -620,8 +623,8 @@
f2fs_balance_fs(sbi, true);
goto out_free_encrypted_link;
-out_handle_failed_inode:
- handle_failed_inode(inode);
+out_f2fs_handle_failed_inode:
+ f2fs_handle_failed_inode(inode);
out_free_encrypted_link:
if (disk_link.name != (unsigned char *)symname)
kfree(disk_link.name);
@@ -657,7 +660,7 @@
goto out_fail;
f2fs_unlock_op(sbi);
- alloc_nid_done(sbi, inode->i_ino);
+ f2fs_alloc_nid_done(sbi, inode->i_ino);
d_instantiate_new(dentry, inode);
@@ -669,7 +672,7 @@
out_fail:
clear_inode_flag(inode, FI_INC_LINK);
- handle_failed_inode(inode);
+ f2fs_handle_failed_inode(inode);
return err;
}
@@ -708,7 +711,7 @@
goto out;
f2fs_unlock_op(sbi);
- alloc_nid_done(sbi, inode->i_ino);
+ f2fs_alloc_nid_done(sbi, inode->i_ino);
d_instantiate_new(dentry, inode);
@@ -718,7 +721,7 @@
f2fs_balance_fs(sbi, true);
return 0;
out:
- handle_failed_inode(inode);
+ f2fs_handle_failed_inode(inode);
return err;
}
@@ -747,7 +750,7 @@
}
f2fs_lock_op(sbi);
- err = acquire_orphan_inode(sbi);
+ err = f2fs_acquire_orphan_inode(sbi);
if (err)
goto out;
@@ -759,8 +762,8 @@
* add this non-linked tmpfile to orphan list, in this way we could
* remove all unused data of tmpfile after abnormal power-off.
*/
- add_orphan_inode(inode);
- alloc_nid_done(sbi, inode->i_ino);
+ f2fs_add_orphan_inode(inode);
+ f2fs_alloc_nid_done(sbi, inode->i_ino);
if (whiteout) {
f2fs_i_links_write(inode, false);
@@ -776,9 +779,9 @@
return 0;
release_out:
- release_orphan_inode(sbi);
+ f2fs_release_orphan_inode(sbi);
out:
- handle_failed_inode(inode);
+ f2fs_handle_failed_inode(inode);
return err;
}
@@ -885,7 +888,7 @@
f2fs_lock_op(sbi);
- err = acquire_orphan_inode(sbi);
+ err = f2fs_acquire_orphan_inode(sbi);
if (err)
goto put_out_dir;
@@ -899,9 +902,9 @@
up_write(&F2FS_I(new_inode)->i_sem);
if (!new_inode->i_nlink)
- add_orphan_inode(new_inode);
+ f2fs_add_orphan_inode(new_inode);
else
- release_orphan_inode(sbi);
+ f2fs_release_orphan_inode(sbi);
} else {
f2fs_balance_fs(sbi, true);
@@ -969,8 +972,12 @@
f2fs_put_page(old_dir_page, 0);
f2fs_i_links_write(old_dir, false);
}
- if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_STRICT)
- add_ino_entry(sbi, new_dir->i_ino, TRANS_DIR_INO);
+ if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_STRICT) {
+ f2fs_add_ino_entry(sbi, new_dir->i_ino, TRANS_DIR_INO);
+ if (S_ISDIR(old_inode->i_mode))
+ f2fs_add_ino_entry(sbi, old_inode->i_ino,
+ TRANS_DIR_INO);
+ }
f2fs_unlock_op(sbi);
@@ -1121,8 +1128,8 @@
f2fs_mark_inode_dirty_sync(new_dir, false);
if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_STRICT) {
- add_ino_entry(sbi, old_dir->i_ino, TRANS_DIR_INO);
- add_ino_entry(sbi, new_dir->i_ino, TRANS_DIR_INO);
+ f2fs_add_ino_entry(sbi, old_dir->i_ino, TRANS_DIR_INO);
+ f2fs_add_ino_entry(sbi, new_dir->i_ino, TRANS_DIR_INO);
}
f2fs_unlock_op(sbi);
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 803a010..874b0a1 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -23,13 +23,28 @@
#include "trace.h"
#include <trace/events/f2fs.h>
-#define on_build_free_nids(nmi) mutex_is_locked(&(nm_i)->build_lock)
+#define on_f2fs_build_free_nids(nmi) mutex_is_locked(&(nm_i)->build_lock)
static struct kmem_cache *nat_entry_slab;
static struct kmem_cache *free_nid_slab;
static struct kmem_cache *nat_entry_set_slab;
-bool available_free_memory(struct f2fs_sb_info *sbi, int type)
+/*
+ * Check whether the given nid is within node id range.
+ */
+int f2fs_check_nid_range(struct f2fs_sb_info *sbi, nid_t nid)
+{
+ if (unlikely(nid < F2FS_ROOT_INO(sbi) || nid >= NM_I(sbi)->max_nid)) {
+ set_sbi_flag(sbi, SBI_NEED_FSCK);
+ f2fs_msg(sbi->sb, KERN_WARNING,
+ "%s: out-of-range nid=%x, run fsck to fix.",
+ __func__, nid);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+bool f2fs_available_free_memory(struct f2fs_sb_info *sbi, int type)
{
struct f2fs_nm_info *nm_i = NM_I(sbi);
struct sysinfo val;
@@ -87,18 +102,10 @@
static void clear_node_page_dirty(struct page *page)
{
- struct address_space *mapping = page->mapping;
- unsigned int long flags;
-
if (PageDirty(page)) {
- spin_lock_irqsave(&mapping->tree_lock, flags);
- radix_tree_tag_clear(&mapping->page_tree,
- page_index(page),
- PAGECACHE_TAG_DIRTY);
- spin_unlock_irqrestore(&mapping->tree_lock, flags);
-
+ f2fs_clear_radix_tree_dirty_tag(page);
clear_page_dirty_for_io(page);
- dec_page_count(F2FS_M_SB(mapping), F2FS_DIRTY_NODES);
+ dec_page_count(F2FS_P_SB(page), F2FS_DIRTY_NODES);
}
ClearPageUptodate(page);
}
@@ -106,7 +113,7 @@
static struct page *get_current_nat_page(struct f2fs_sb_info *sbi, nid_t nid)
{
pgoff_t index = current_nat_addr(sbi, nid);
- return get_meta_page(sbi, index);
+ return f2fs_get_meta_page(sbi, index);
}
static struct page *get_next_nat_page(struct f2fs_sb_info *sbi, nid_t nid)
@@ -123,8 +130,8 @@
dst_off = next_nat_addr(sbi, src_off);
/* get current nat block page with lock */
- src_page = get_meta_page(sbi, src_off);
- dst_page = grab_meta_page(sbi, dst_off);
+ src_page = f2fs_get_meta_page(sbi, src_off);
+ dst_page = f2fs_grab_meta_page(sbi, dst_off);
f2fs_bug_on(sbi, PageDirty(src_page));
src_addr = page_address(src_page);
@@ -260,7 +267,7 @@
start, nr);
}
-int need_dentry_mark(struct f2fs_sb_info *sbi, nid_t nid)
+int f2fs_need_dentry_mark(struct f2fs_sb_info *sbi, nid_t nid)
{
struct f2fs_nm_info *nm_i = NM_I(sbi);
struct nat_entry *e;
@@ -277,7 +284,7 @@
return need;
}
-bool is_checkpointed_node(struct f2fs_sb_info *sbi, nid_t nid)
+bool f2fs_is_checkpointed_node(struct f2fs_sb_info *sbi, nid_t nid)
{
struct f2fs_nm_info *nm_i = NM_I(sbi);
struct nat_entry *e;
@@ -291,7 +298,7 @@
return is_cp;
}
-bool need_inode_block_update(struct f2fs_sb_info *sbi, nid_t ino)
+bool f2fs_need_inode_block_update(struct f2fs_sb_info *sbi, nid_t ino)
{
struct f2fs_nm_info *nm_i = NM_I(sbi);
struct nat_entry *e;
@@ -364,8 +371,7 @@
new_blkaddr == NULL_ADDR);
f2fs_bug_on(sbi, nat_get_blkaddr(e) == NEW_ADDR &&
new_blkaddr == NEW_ADDR);
- f2fs_bug_on(sbi, nat_get_blkaddr(e) != NEW_ADDR &&
- nat_get_blkaddr(e) != NULL_ADDR &&
+ f2fs_bug_on(sbi, is_valid_blkaddr(nat_get_blkaddr(e)) &&
new_blkaddr == NEW_ADDR);
/* increment version no as node is removed */
@@ -376,7 +382,7 @@
/* change address */
nat_set_blkaddr(e, new_blkaddr);
- if (new_blkaddr == NEW_ADDR || new_blkaddr == NULL_ADDR)
+ if (!is_valid_blkaddr(new_blkaddr))
set_nat_flag(e, IS_CHECKPOINTED, false);
__set_nat_cache_dirty(nm_i, e);
@@ -391,7 +397,7 @@
up_write(&nm_i->nat_tree_lock);
}
-int try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink)
+int f2fs_try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink)
{
struct f2fs_nm_info *nm_i = NM_I(sbi);
int nr = nr_shrink;
@@ -413,7 +419,8 @@
/*
* This function always returns success
*/
-void get_node_info(struct f2fs_sb_info *sbi, nid_t nid, struct node_info *ni)
+void f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid,
+ struct node_info *ni)
{
struct f2fs_nm_info *nm_i = NM_I(sbi);
struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA);
@@ -443,7 +450,7 @@
/* Check current segment summary */
down_read(&curseg->journal_rwsem);
- i = lookup_journal_in_cursum(journal, NAT_JOURNAL, nid, 0);
+ i = f2fs_lookup_journal_in_cursum(journal, NAT_JOURNAL, nid, 0);
if (i >= 0) {
ne = nat_in_journal(journal, i);
node_info_from_raw_nat(ni, &ne);
@@ -458,7 +465,7 @@
index = current_nat_addr(sbi, nid);
up_read(&nm_i->nat_tree_lock);
- page = get_meta_page(sbi, index);
+ page = f2fs_get_meta_page(sbi, index);
nat_blk = (struct f2fs_nat_block *)page_address(page);
ne = nat_blk->entries[nid - start_nid];
node_info_from_raw_nat(ni, &ne);
@@ -471,7 +478,7 @@
/*
* readahead MAX_RA_NODE number of node pages.
*/
-static void ra_node_pages(struct page *parent, int start, int n)
+static void f2fs_ra_node_pages(struct page *parent, int start, int n)
{
struct f2fs_sb_info *sbi = F2FS_P_SB(parent);
struct blk_plug plug;
@@ -485,13 +492,13 @@
end = min(end, NIDS_PER_BLOCK);
for (i = start; i < end; i++) {
nid = get_nid(parent, i, false);
- ra_node_page(sbi, nid);
+ f2fs_ra_node_page(sbi, nid);
}
blk_finish_plug(&plug);
}
-pgoff_t get_next_page_offset(struct dnode_of_data *dn, pgoff_t pgofs)
+pgoff_t f2fs_get_next_page_offset(struct dnode_of_data *dn, pgoff_t pgofs)
{
const long direct_index = ADDRS_PER_INODE(dn->inode);
const long direct_blks = ADDRS_PER_BLOCK;
@@ -606,7 +613,7 @@
* f2fs_unlock_op() only if ro is not set RDONLY_NODE.
* In the case of RDONLY_NODE, we don't need to care about mutex.
*/
-int get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode)
+int f2fs_get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
struct page *npage[4];
@@ -625,7 +632,7 @@
npage[0] = dn->inode_page;
if (!npage[0]) {
- npage[0] = get_node_page(sbi, nids[0]);
+ npage[0] = f2fs_get_node_page(sbi, nids[0]);
if (IS_ERR(npage[0]))
return PTR_ERR(npage[0]);
}
@@ -649,24 +656,24 @@
if (!nids[i] && mode == ALLOC_NODE) {
/* alloc new node */
- if (!alloc_nid(sbi, &(nids[i]))) {
+ if (!f2fs_alloc_nid(sbi, &(nids[i]))) {
err = -ENOSPC;
goto release_pages;
}
dn->nid = nids[i];
- npage[i] = new_node_page(dn, noffset[i]);
+ npage[i] = f2fs_new_node_page(dn, noffset[i]);
if (IS_ERR(npage[i])) {
- alloc_nid_failed(sbi, nids[i]);
+ f2fs_alloc_nid_failed(sbi, nids[i]);
err = PTR_ERR(npage[i]);
goto release_pages;
}
set_nid(parent, offset[i - 1], nids[i], i == 1);
- alloc_nid_done(sbi, nids[i]);
+ f2fs_alloc_nid_done(sbi, nids[i]);
done = true;
} else if (mode == LOOKUP_NODE_RA && i == level && level > 1) {
- npage[i] = get_node_page_ra(parent, offset[i - 1]);
+ npage[i] = f2fs_get_node_page_ra(parent, offset[i - 1]);
if (IS_ERR(npage[i])) {
err = PTR_ERR(npage[i]);
goto release_pages;
@@ -681,7 +688,7 @@
}
if (!done) {
- npage[i] = get_node_page(sbi, nids[i]);
+ npage[i] = f2fs_get_node_page(sbi, nids[i]);
if (IS_ERR(npage[i])) {
err = PTR_ERR(npage[i]);
f2fs_put_page(npage[0], 0);
@@ -720,15 +727,15 @@
struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
struct node_info ni;
- get_node_info(sbi, dn->nid, &ni);
+ f2fs_get_node_info(sbi, dn->nid, &ni);
/* Deallocate node address */
- invalidate_blocks(sbi, ni.blk_addr);
+ f2fs_invalidate_blocks(sbi, ni.blk_addr);
dec_valid_node_count(sbi, dn->inode, dn->nid == dn->inode->i_ino);
set_node_addr(sbi, &ni, NULL_ADDR, false);
if (dn->nid == dn->inode->i_ino) {
- remove_orphan_inode(sbi, dn->nid);
+ f2fs_remove_orphan_inode(sbi, dn->nid);
dec_valid_inode_count(sbi);
f2fs_inode_synced(dn->inode);
}
@@ -753,7 +760,7 @@
return 1;
/* get direct node */
- page = get_node_page(F2FS_I_SB(dn->inode), dn->nid);
+ page = f2fs_get_node_page(F2FS_I_SB(dn->inode), dn->nid);
if (IS_ERR(page) && PTR_ERR(page) == -ENOENT)
return 1;
else if (IS_ERR(page))
@@ -762,7 +769,7 @@
/* Make dnode_of_data for parameter */
dn->node_page = page;
dn->ofs_in_node = 0;
- truncate_data_blocks(dn);
+ f2fs_truncate_data_blocks(dn);
truncate_node(dn);
return 1;
}
@@ -783,13 +790,13 @@
trace_f2fs_truncate_nodes_enter(dn->inode, dn->nid, dn->data_blkaddr);
- page = get_node_page(F2FS_I_SB(dn->inode), dn->nid);
+ page = f2fs_get_node_page(F2FS_I_SB(dn->inode), dn->nid);
if (IS_ERR(page)) {
trace_f2fs_truncate_nodes_exit(dn->inode, PTR_ERR(page));
return PTR_ERR(page);
}
- ra_node_pages(page, ofs, NIDS_PER_BLOCK);
+ f2fs_ra_node_pages(page, ofs, NIDS_PER_BLOCK);
rn = F2FS_NODE(page);
if (depth < 3) {
@@ -859,7 +866,7 @@
/* get indirect nodes in the path */
for (i = 0; i < idx + 1; i++) {
/* reference count'll be increased */
- pages[i] = get_node_page(F2FS_I_SB(dn->inode), nid[i]);
+ pages[i] = f2fs_get_node_page(F2FS_I_SB(dn->inode), nid[i]);
if (IS_ERR(pages[i])) {
err = PTR_ERR(pages[i]);
idx = i - 1;
@@ -868,7 +875,7 @@
nid[i + 1] = get_nid(pages[i], offset[i + 1], false);
}
- ra_node_pages(pages[idx], offset[idx + 1], NIDS_PER_BLOCK);
+ f2fs_ra_node_pages(pages[idx], offset[idx + 1], NIDS_PER_BLOCK);
/* free direct nodes linked to a partial indirect node */
for (i = offset[idx + 1]; i < NIDS_PER_BLOCK; i++) {
@@ -905,7 +912,7 @@
/*
* All the block addresses of data and nodes should be nullified.
*/
-int truncate_inode_blocks(struct inode *inode, pgoff_t from)
+int f2fs_truncate_inode_blocks(struct inode *inode, pgoff_t from)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
int err = 0, cont = 1;
@@ -921,7 +928,7 @@
if (level < 0)
return level;
- page = get_node_page(sbi, inode->i_ino);
+ page = f2fs_get_node_page(sbi, inode->i_ino);
if (IS_ERR(page)) {
trace_f2fs_truncate_inode_blocks_exit(inode, PTR_ERR(page));
return PTR_ERR(page);
@@ -1001,7 +1008,7 @@
}
/* caller must lock inode page */
-int truncate_xattr_node(struct inode *inode)
+int f2fs_truncate_xattr_node(struct inode *inode)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
nid_t nid = F2FS_I(inode)->i_xattr_nid;
@@ -1011,7 +1018,7 @@
if (!nid)
return 0;
- npage = get_node_page(sbi, nid);
+ npage = f2fs_get_node_page(sbi, nid);
if (IS_ERR(npage))
return PTR_ERR(npage);
@@ -1026,17 +1033,17 @@
* Caller should grab and release a rwsem by calling f2fs_lock_op() and
* f2fs_unlock_op().
*/
-int remove_inode_page(struct inode *inode)
+int f2fs_remove_inode_page(struct inode *inode)
{
struct dnode_of_data dn;
int err;
set_new_dnode(&dn, inode, NULL, NULL, inode->i_ino);
- err = get_dnode_of_data(&dn, 0, LOOKUP_NODE);
+ err = f2fs_get_dnode_of_data(&dn, 0, LOOKUP_NODE);
if (err)
return err;
- err = truncate_xattr_node(inode);
+ err = f2fs_truncate_xattr_node(inode);
if (err) {
f2fs_put_dnode(&dn);
return err;
@@ -1045,7 +1052,7 @@
/* remove potential inline_data blocks */
if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
S_ISLNK(inode->i_mode))
- truncate_data_blocks_range(&dn, 1);
+ f2fs_truncate_data_blocks_range(&dn, 1);
/* 0 is possible, after f2fs_new_inode() has failed */
f2fs_bug_on(F2FS_I_SB(inode),
@@ -1056,7 +1063,7 @@
return 0;
}
-struct page *new_inode_page(struct inode *inode)
+struct page *f2fs_new_inode_page(struct inode *inode)
{
struct dnode_of_data dn;
@@ -1064,10 +1071,10 @@
set_new_dnode(&dn, inode, NULL, NULL, inode->i_ino);
/* caller should f2fs_put_page(page, 1); */
- return new_node_page(&dn, 0);
+ return f2fs_new_node_page(&dn, 0);
}
-struct page *new_node_page(struct dnode_of_data *dn, unsigned int ofs)
+struct page *f2fs_new_node_page(struct dnode_of_data *dn, unsigned int ofs)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
struct node_info new_ni;
@@ -1085,7 +1092,7 @@
goto fail;
#ifdef CONFIG_F2FS_CHECK_FS
- get_node_info(sbi, dn->nid, &new_ni);
+ f2fs_get_node_info(sbi, dn->nid, &new_ni);
f2fs_bug_on(sbi, new_ni.blk_addr != NULL_ADDR);
#endif
new_ni.nid = dn->nid;
@@ -1137,7 +1144,7 @@
if (PageUptodate(page))
return LOCKED_PAGE;
- get_node_info(sbi, page->index, &ni);
+ f2fs_get_node_info(sbi, page->index, &ni);
if (unlikely(ni.blk_addr == NULL_ADDR)) {
ClearPageUptodate(page);
@@ -1151,14 +1158,15 @@
/*
* Readahead a node page
*/
-void ra_node_page(struct f2fs_sb_info *sbi, nid_t nid)
+void f2fs_ra_node_page(struct f2fs_sb_info *sbi, nid_t nid)
{
struct page *apage;
int err;
if (!nid)
return;
- f2fs_bug_on(sbi, check_nid_range(sbi, nid));
+ if (f2fs_check_nid_range(sbi, nid))
+ return;
rcu_read_lock();
apage = radix_tree_lookup(&NODE_MAPPING(sbi)->page_tree, nid);
@@ -1182,7 +1190,8 @@
if (!nid)
return ERR_PTR(-ENOENT);
- f2fs_bug_on(sbi, check_nid_range(sbi, nid));
+ if (f2fs_check_nid_range(sbi, nid))
+ return ERR_PTR(-EINVAL);
repeat:
page = f2fs_grab_cache_page(NODE_MAPPING(sbi), nid, false);
if (!page)
@@ -1198,7 +1207,7 @@
}
if (parent)
- ra_node_pages(parent, start + 1, MAX_RA_NODE);
+ f2fs_ra_node_pages(parent, start + 1, MAX_RA_NODE);
lock_page(page);
@@ -1232,12 +1241,12 @@
return page;
}
-struct page *get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid)
+struct page *f2fs_get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid)
{
return __get_node_page(sbi, nid, NULL, 0);
}
-struct page *get_node_page_ra(struct page *parent, int start)
+struct page *f2fs_get_node_page_ra(struct page *parent, int start)
{
struct f2fs_sb_info *sbi = F2FS_P_SB(parent);
nid_t nid = get_nid(parent, start, false);
@@ -1272,7 +1281,7 @@
ret = f2fs_write_inline_data(inode, page);
inode_dec_dirty_pages(inode);
- remove_dirty_inode(inode);
+ f2fs_remove_dirty_inode(inode);
if (ret)
set_page_dirty(page);
page_out:
@@ -1283,21 +1292,17 @@
static struct page *last_fsync_dnode(struct f2fs_sb_info *sbi, nid_t ino)
{
- pgoff_t index, end;
+ pgoff_t index;
struct pagevec pvec;
struct page *last_page = NULL;
+ int nr_pages;
pagevec_init(&pvec, 0);
index = 0;
- end = ULONG_MAX;
- while (index <= end) {
- int i, nr_pages;
- nr_pages = pagevec_lookup_tag(&pvec, NODE_MAPPING(sbi), &index,
- PAGECACHE_TAG_DIRTY,
- min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1);
- if (nr_pages == 0)
- break;
+ while ((nr_pages = pagevec_lookup_tag(&pvec, NODE_MAPPING(sbi), &index,
+ PAGECACHE_TAG_DIRTY))) {
+ int i;
for (i = 0; i < nr_pages; i++) {
struct page *page = pvec.pages[i];
@@ -1363,11 +1368,8 @@
trace_f2fs_writepage(page, NODE);
- if (unlikely(f2fs_cp_error(sbi))) {
- dec_page_count(sbi, F2FS_DIRTY_NODES);
- unlock_page(page);
- return 0;
- }
+ if (unlikely(f2fs_cp_error(sbi)))
+ goto redirty_out;
if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING)))
goto redirty_out;
@@ -1383,7 +1385,7 @@
down_read(&sbi->node_write);
}
- get_node_info(sbi, nid, &ni);
+ f2fs_get_node_info(sbi, nid, &ni);
/* This page is already truncated */
if (unlikely(ni.blk_addr == NULL_ADDR)) {
@@ -1400,7 +1402,7 @@
set_page_writeback(page);
ClearPageError(page);
fio.old_blkaddr = ni.blk_addr;
- write_node_page(nid, &fio);
+ f2fs_do_write_node_page(nid, &fio);
set_node_addr(sbi, &ni, fio.new_blkaddr, is_fsync_dnode(page));
dec_page_count(sbi, F2FS_DIRTY_NODES);
up_read(&sbi->node_write);
@@ -1429,7 +1431,7 @@
return AOP_WRITEPAGE_ACTIVATE;
}
-void move_node_page(struct page *node_page, int gc_type)
+void f2fs_move_node_page(struct page *node_page, int gc_type)
{
if (gc_type == FG_GC) {
struct writeback_control wbc = {
@@ -1466,16 +1468,17 @@
return __write_node_page(page, false, NULL, wbc, false, FS_NODE_IO);
}
-int fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
+int f2fs_fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
struct writeback_control *wbc, bool atomic)
{
- pgoff_t index, end;
+ pgoff_t index;
pgoff_t last_idx = ULONG_MAX;
struct pagevec pvec;
int ret = 0;
struct page *last_page = NULL;
bool marked = false;
nid_t ino = inode->i_ino;
+ int nr_pages;
if (atomic) {
last_page = last_fsync_dnode(sbi, ino);
@@ -1485,15 +1488,10 @@
retry:
pagevec_init(&pvec, 0);
index = 0;
- end = ULONG_MAX;
- while (index <= end) {
- int i, nr_pages;
- nr_pages = pagevec_lookup_tag(&pvec, NODE_MAPPING(sbi), &index,
- PAGECACHE_TAG_DIRTY,
- min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1);
- if (nr_pages == 0)
- break;
+ while ((nr_pages = pagevec_lookup_tag(&pvec, NODE_MAPPING(sbi), &index,
+ PAGECACHE_TAG_DIRTY))) {
+ int i;
for (i = 0; i < nr_pages; i++) {
struct page *page = pvec.pages[i];
@@ -1537,9 +1535,9 @@
if (IS_INODE(page)) {
if (is_inode_flag_set(inode,
FI_DIRTY_INODE))
- update_inode(inode, page);
+ f2fs_update_inode(inode, page);
set_dentry_mark(page,
- need_dentry_mark(sbi, ino));
+ f2fs_need_dentry_mark(sbi, ino));
}
/* may be written by other thread */
if (!PageDirty(page))
@@ -1589,33 +1587,37 @@
return ret ? -EIO: 0;
}
-int sync_node_pages(struct f2fs_sb_info *sbi, struct writeback_control *wbc,
+int f2fs_sync_node_pages(struct f2fs_sb_info *sbi,
+ struct writeback_control *wbc,
bool do_balance, enum iostat_type io_type)
{
- pgoff_t index, end;
+ pgoff_t index;
struct pagevec pvec;
int step = 0;
int nwritten = 0;
int ret = 0;
+ int nr_pages, done = 0;
pagevec_init(&pvec, 0);
next_step:
index = 0;
- end = ULONG_MAX;
- while (index <= end) {
- int i, nr_pages;
- nr_pages = pagevec_lookup_tag(&pvec, NODE_MAPPING(sbi), &index,
- PAGECACHE_TAG_DIRTY,
- min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1);
- if (nr_pages == 0)
- break;
+ while (!done && (nr_pages = pagevec_lookup_tag(&pvec,
+ NODE_MAPPING(sbi), &index, PAGECACHE_TAG_DIRTY))) {
+ int i;
for (i = 0; i < nr_pages; i++) {
struct page *page = pvec.pages[i];
bool submitted = false;
+ /* give a priority to WB_SYNC threads */
+ if (atomic_read(&sbi->wb_sync_req[NODE]) &&
+ wbc->sync_mode == WB_SYNC_NONE) {
+ done = 1;
+ break;
+ }
+
/*
* flushing sequence with step:
* 0. indirect nodes
@@ -1694,29 +1696,22 @@
return ret;
}
-int wait_on_node_pages_writeback(struct f2fs_sb_info *sbi, nid_t ino)
+int f2fs_wait_on_node_pages_writeback(struct f2fs_sb_info *sbi, nid_t ino)
{
- pgoff_t index = 0, end = ULONG_MAX;
+ pgoff_t index = 0;
struct pagevec pvec;
int ret2, ret = 0;
+ int nr_pages;
pagevec_init(&pvec, 0);
- while (index <= end) {
- int i, nr_pages;
- nr_pages = pagevec_lookup_tag(&pvec, NODE_MAPPING(sbi), &index,
- PAGECACHE_TAG_WRITEBACK,
- min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1);
- if (nr_pages == 0)
- break;
+ while ((nr_pages = pagevec_lookup_tag(&pvec, NODE_MAPPING(sbi), &index,
+ PAGECACHE_TAG_WRITEBACK))) {
+ int i;
for (i = 0; i < nr_pages; i++) {
struct page *page = pvec.pages[i];
- /* until radix tree lookup accepts end_index */
- if (unlikely(page->index > end))
- continue;
-
if (ino && ino_of_node(page) == ino) {
f2fs_wait_on_page_writeback(page, NODE, true);
if (TestClearPageError(page))
@@ -1750,14 +1745,21 @@
if (get_pages(sbi, F2FS_DIRTY_NODES) < nr_pages_to_skip(sbi, NODE))
goto skip_write;
+ if (wbc->sync_mode == WB_SYNC_ALL)
+ atomic_inc(&sbi->wb_sync_req[NODE]);
+ else if (atomic_read(&sbi->wb_sync_req[NODE]))
+ goto skip_write;
+
trace_f2fs_writepages(mapping->host, wbc, NODE);
diff = nr_pages_to_write(sbi, NODE, wbc);
- wbc->sync_mode = WB_SYNC_NONE;
blk_start_plug(&plug);
- sync_node_pages(sbi, wbc, true, FS_NODE_IO);
+ f2fs_sync_node_pages(sbi, wbc, true, FS_NODE_IO);
blk_finish_plug(&plug);
wbc->nr_to_write = max((long)0, wbc->nr_to_write - diff);
+
+ if (wbc->sync_mode == WB_SYNC_ALL)
+ atomic_dec(&sbi->wb_sync_req[NODE]);
return 0;
skip_write:
@@ -1903,20 +1905,20 @@
* Thread A Thread B
* - f2fs_create
* - f2fs_new_inode
- * - alloc_nid
+ * - f2fs_alloc_nid
* - __insert_nid_to_list(PREALLOC_NID)
* - f2fs_balance_fs_bg
- * - build_free_nids
- * - __build_free_nids
+ * - f2fs_build_free_nids
+ * - __f2fs_build_free_nids
* - scan_nat_page
* - add_free_nid
* - __lookup_nat_cache
* - f2fs_add_link
- * - init_inode_metadata
- * - new_inode_page
- * - new_node_page
+ * - f2fs_init_inode_metadata
+ * - f2fs_new_inode_page
+ * - f2fs_new_node_page
* - set_node_addr
- * - alloc_nid_done
+ * - f2fs_alloc_nid_done
* - __remove_nid_from_list(PREALLOC_NID)
* - __insert_nid_to_list(FREE_NID)
*/
@@ -2048,7 +2050,8 @@
up_read(&nm_i->nat_tree_lock);
}
-static void __build_free_nids(struct f2fs_sb_info *sbi, bool sync, bool mount)
+static void __f2fs_build_free_nids(struct f2fs_sb_info *sbi,
+ bool sync, bool mount)
{
struct f2fs_nm_info *nm_i = NM_I(sbi);
int i = 0;
@@ -2061,7 +2064,7 @@
if (nm_i->nid_cnt[FREE_NID] >= NAT_ENTRY_PER_BLOCK)
return;
- if (!sync && !available_free_memory(sbi, FREE_NIDS))
+ if (!sync && !f2fs_available_free_memory(sbi, FREE_NIDS))
return;
if (!mount) {
@@ -2073,7 +2076,7 @@
}
/* readahead nat pages to be scanned */
- ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), FREE_NID_PAGES,
+ f2fs_ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), FREE_NID_PAGES,
META_NAT, true);
down_read(&nm_i->nat_tree_lock);
@@ -2103,14 +2106,14 @@
up_read(&nm_i->nat_tree_lock);
- ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nm_i->next_scan_nid),
+ f2fs_ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nm_i->next_scan_nid),
nm_i->ra_nid_pages, META_NAT, false);
}
-void build_free_nids(struct f2fs_sb_info *sbi, bool sync, bool mount)
+void f2fs_build_free_nids(struct f2fs_sb_info *sbi, bool sync, bool mount)
{
mutex_lock(&NM_I(sbi)->build_lock);
- __build_free_nids(sbi, sync, mount);
+ __f2fs_build_free_nids(sbi, sync, mount);
mutex_unlock(&NM_I(sbi)->build_lock);
}
@@ -2119,7 +2122,7 @@
* from second parameter of this function.
* The returned nid could be used ino as well as nid when inode is created.
*/
-bool alloc_nid(struct f2fs_sb_info *sbi, nid_t *nid)
+bool f2fs_alloc_nid(struct f2fs_sb_info *sbi, nid_t *nid)
{
struct f2fs_nm_info *nm_i = NM_I(sbi);
struct free_nid *i = NULL;
@@ -2137,8 +2140,8 @@
return false;
}
- /* We should not use stale free nids created by build_free_nids */
- if (nm_i->nid_cnt[FREE_NID] && !on_build_free_nids(nm_i)) {
+ /* We should not use stale free nids created by f2fs_build_free_nids */
+ if (nm_i->nid_cnt[FREE_NID] && !on_f2fs_build_free_nids(nm_i)) {
f2fs_bug_on(sbi, list_empty(&nm_i->free_nid_list));
i = list_first_entry(&nm_i->free_nid_list,
struct free_nid, list);
@@ -2155,14 +2158,14 @@
spin_unlock(&nm_i->nid_list_lock);
/* Let's scan nat pages and its caches to get free nids */
- build_free_nids(sbi, true, false);
+ f2fs_build_free_nids(sbi, true, false);
goto retry;
}
/*
- * alloc_nid() should be called prior to this function.
+ * f2fs_alloc_nid() should be called prior to this function.
*/
-void alloc_nid_done(struct f2fs_sb_info *sbi, nid_t nid)
+void f2fs_alloc_nid_done(struct f2fs_sb_info *sbi, nid_t nid)
{
struct f2fs_nm_info *nm_i = NM_I(sbi);
struct free_nid *i;
@@ -2177,9 +2180,9 @@
}
/*
- * alloc_nid() should be called prior to this function.
+ * f2fs_alloc_nid() should be called prior to this function.
*/
-void alloc_nid_failed(struct f2fs_sb_info *sbi, nid_t nid)
+void f2fs_alloc_nid_failed(struct f2fs_sb_info *sbi, nid_t nid)
{
struct f2fs_nm_info *nm_i = NM_I(sbi);
struct free_nid *i;
@@ -2192,7 +2195,7 @@
i = __lookup_free_nid_list(nm_i, nid);
f2fs_bug_on(sbi, !i);
- if (!available_free_memory(sbi, FREE_NIDS)) {
+ if (!f2fs_available_free_memory(sbi, FREE_NIDS)) {
__remove_free_nid(sbi, i, PREALLOC_NID);
need_free = true;
} else {
@@ -2209,7 +2212,7 @@
kmem_cache_free(free_nid_slab, i);
}
-int try_to_free_nids(struct f2fs_sb_info *sbi, int nr_shrink)
+int f2fs_try_to_free_nids(struct f2fs_sb_info *sbi, int nr_shrink)
{
struct f2fs_nm_info *nm_i = NM_I(sbi);
struct free_nid *i, *next;
@@ -2237,14 +2240,14 @@
return nr - nr_shrink;
}
-void recover_inline_xattr(struct inode *inode, struct page *page)
+void f2fs_recover_inline_xattr(struct inode *inode, struct page *page)
{
void *src_addr, *dst_addr;
size_t inline_size;
struct page *ipage;
struct f2fs_inode *ri;
- ipage = get_node_page(F2FS_I_SB(inode), inode->i_ino);
+ ipage = f2fs_get_node_page(F2FS_I_SB(inode), inode->i_ino);
f2fs_bug_on(F2FS_I_SB(inode), IS_ERR(ipage));
ri = F2FS_INODE(page);
@@ -2262,11 +2265,11 @@
f2fs_wait_on_page_writeback(ipage, NODE, true);
memcpy(dst_addr, src_addr, inline_size);
update_inode:
- update_inode(inode, ipage);
+ f2fs_update_inode(inode, ipage);
f2fs_put_page(ipage, 1);
}
-int recover_xattr_data(struct inode *inode, struct page *page)
+int f2fs_recover_xattr_data(struct inode *inode, struct page *page)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
nid_t prev_xnid = F2FS_I(inode)->i_xattr_nid;
@@ -2279,25 +2282,25 @@
goto recover_xnid;
/* 1: invalidate the previous xattr nid */
- get_node_info(sbi, prev_xnid, &ni);
- invalidate_blocks(sbi, ni.blk_addr);
+ f2fs_get_node_info(sbi, prev_xnid, &ni);
+ f2fs_invalidate_blocks(sbi, ni.blk_addr);
dec_valid_node_count(sbi, inode, false);
set_node_addr(sbi, &ni, NULL_ADDR, false);
recover_xnid:
/* 2: update xattr nid in inode */
- if (!alloc_nid(sbi, &new_xnid))
+ if (!f2fs_alloc_nid(sbi, &new_xnid))
return -ENOSPC;
set_new_dnode(&dn, inode, NULL, NULL, new_xnid);
- xpage = new_node_page(&dn, XATTR_NODE_OFFSET);
+ xpage = f2fs_new_node_page(&dn, XATTR_NODE_OFFSET);
if (IS_ERR(xpage)) {
- alloc_nid_failed(sbi, new_xnid);
+ f2fs_alloc_nid_failed(sbi, new_xnid);
return PTR_ERR(xpage);
}
- alloc_nid_done(sbi, new_xnid);
- update_inode_page(inode);
+ f2fs_alloc_nid_done(sbi, new_xnid);
+ f2fs_update_inode_page(inode);
/* 3: update and set xattr node page dirty */
memcpy(F2FS_NODE(xpage), F2FS_NODE(page), VALID_XATTR_BLOCK_SIZE);
@@ -2308,14 +2311,14 @@
return 0;
}
-int recover_inode_page(struct f2fs_sb_info *sbi, struct page *page)
+int f2fs_recover_inode_page(struct f2fs_sb_info *sbi, struct page *page)
{
struct f2fs_inode *src, *dst;
nid_t ino = ino_of_node(page);
struct node_info old_ni, new_ni;
struct page *ipage;
- get_node_info(sbi, ino, &old_ni);
+ f2fs_get_node_info(sbi, ino, &old_ni);
if (unlikely(old_ni.blk_addr != NULL_ADDR))
return -EINVAL;
@@ -2369,7 +2372,7 @@
return 0;
}
-void restore_node_summary(struct f2fs_sb_info *sbi,
+void f2fs_restore_node_summary(struct f2fs_sb_info *sbi,
unsigned int segno, struct f2fs_summary_block *sum)
{
struct f2fs_node *rn;
@@ -2386,10 +2389,10 @@
nrpages = min(last_offset - i, BIO_MAX_PAGES);
/* readahead node pages */
- ra_meta_pages(sbi, addr, nrpages, META_POR, true);
+ f2fs_ra_meta_pages(sbi, addr, nrpages, META_POR, true);
for (idx = addr; idx < addr + nrpages; idx++) {
- struct page *page = get_tmp_page(sbi, idx);
+ struct page *page = f2fs_get_tmp_page(sbi, idx);
rn = F2FS_NODE(page);
sum_entry->nid = rn->footer.nid;
@@ -2531,7 +2534,7 @@
f2fs_bug_on(sbi, nat_get_blkaddr(ne) == NEW_ADDR);
if (to_journal) {
- offset = lookup_journal_in_cursum(journal,
+ offset = f2fs_lookup_journal_in_cursum(journal,
NAT_JOURNAL, nid, 1);
f2fs_bug_on(sbi, offset < 0);
raw_ne = &nat_in_journal(journal, offset);
@@ -2568,7 +2571,7 @@
/*
* This function is called during the checkpointing process.
*/
-void flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc)
+void f2fs_flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc)
{
struct f2fs_nm_info *nm_i = NM_I(sbi);
struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA);
@@ -2631,7 +2634,7 @@
nat_bits_addr = __start_cp_addr(sbi) + sbi->blocks_per_seg -
nm_i->nat_bits_blocks;
for (i = 0; i < nm_i->nat_bits_blocks; i++) {
- struct page *page = get_meta_page(sbi, nat_bits_addr++);
+ struct page *page = f2fs_get_meta_page(sbi, nat_bits_addr++);
memcpy(nm_i->nat_bits + (i << F2FS_BLKSIZE_BITS),
page_address(page), F2FS_BLKSIZE);
@@ -2750,8 +2753,10 @@
struct f2fs_nm_info *nm_i = NM_I(sbi);
int i;
- nm_i->free_nid_bitmap = f2fs_kzalloc(sbi, nm_i->nat_blocks *
- sizeof(unsigned char *), GFP_KERNEL);
+ nm_i->free_nid_bitmap =
+ f2fs_kzalloc(sbi, array_size(sizeof(unsigned char *),
+ nm_i->nat_blocks),
+ GFP_KERNEL);
if (!nm_i->free_nid_bitmap)
return -ENOMEM;
@@ -2767,14 +2772,16 @@
if (!nm_i->nat_block_bitmap)
return -ENOMEM;
- nm_i->free_nid_count = f2fs_kvzalloc(sbi, nm_i->nat_blocks *
- sizeof(unsigned short), GFP_KERNEL);
+ nm_i->free_nid_count =
+ f2fs_kvzalloc(sbi, array_size(sizeof(unsigned short),
+ nm_i->nat_blocks),
+ GFP_KERNEL);
if (!nm_i->free_nid_count)
return -ENOMEM;
return 0;
}
-int build_node_manager(struct f2fs_sb_info *sbi)
+int f2fs_build_node_manager(struct f2fs_sb_info *sbi)
{
int err;
@@ -2794,11 +2801,11 @@
/* load free nid status from nat_bits table */
load_free_nid_bitmap(sbi);
- build_free_nids(sbi, true, true);
+ f2fs_build_free_nids(sbi, true, true);
return 0;
}
-void destroy_node_manager(struct f2fs_sb_info *sbi)
+void f2fs_destroy_node_manager(struct f2fs_sb_info *sbi)
{
struct f2fs_nm_info *nm_i = NM_I(sbi);
struct free_nid *i, *next_i;
@@ -2870,7 +2877,7 @@
kfree(nm_i);
}
-int __init create_node_manager_caches(void)
+int __init f2fs_create_node_manager_caches(void)
{
nat_entry_slab = f2fs_kmem_cache_create("nat_entry",
sizeof(struct nat_entry));
@@ -2896,7 +2903,7 @@
return -ENOMEM;
}
-void destroy_node_manager_caches(void)
+void f2fs_destroy_node_manager_caches(void)
{
kmem_cache_destroy(nat_entry_set_slab);
kmem_cache_destroy(free_nid_slab);
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index 4ddc226..daf81d4 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -47,7 +47,7 @@
static struct kmem_cache *fsync_entry_slab;
-bool space_for_roll_forward(struct f2fs_sb_info *sbi)
+bool f2fs_space_for_roll_forward(struct f2fs_sb_info *sbi)
{
s64 nalloc = percpu_counter_sum_positive(&sbi->alloc_valid_block_count);
@@ -162,7 +162,7 @@
goto out_put;
}
- err = acquire_orphan_inode(F2FS_I_SB(inode));
+ err = f2fs_acquire_orphan_inode(F2FS_I_SB(inode));
if (err) {
iput(einode);
goto out_put;
@@ -173,7 +173,7 @@
} else if (IS_ERR(page)) {
err = PTR_ERR(page);
} else {
- err = __f2fs_do_add_link(dir, &fname, inode,
+ err = f2fs_add_dentry(dir, &fname, inode,
inode->i_ino, inode->i_mode);
}
if (err == -ENOMEM)
@@ -204,8 +204,6 @@
set_inode_flag(inode, FI_DATA_EXIST);
else
clear_inode_flag(inode, FI_DATA_EXIST);
- if (!(ri->i_inline & F2FS_INLINE_DOTS))
- clear_inode_flag(inode, FI_INLINE_DOTS);
}
static void recover_inode(struct inode *inode, struct page *page)
@@ -254,10 +252,10 @@
while (1) {
struct fsync_inode_entry *entry;
- if (!is_valid_blkaddr(sbi, blkaddr, META_POR))
+ if (!f2fs_is_valid_meta_blkaddr(sbi, blkaddr, META_POR))
return 0;
- page = get_tmp_page(sbi, blkaddr);
+ page = f2fs_get_tmp_page(sbi, blkaddr);
if (!is_recoverable_dnode(page))
break;
@@ -271,7 +269,7 @@
if (!check_only &&
IS_INODE(page) && is_dent_dnode(page)) {
- err = recover_inode_page(sbi, page);
+ err = f2fs_recover_inode_page(sbi, page);
if (err)
break;
quota_inode = true;
@@ -312,7 +310,7 @@
blkaddr = next_blkaddr_of_node(page);
f2fs_put_page(page, 1);
- ra_meta_pages_cond(sbi, blkaddr);
+ f2fs_ra_meta_pages_cond(sbi, blkaddr);
}
f2fs_put_page(page, 1);
return err;
@@ -355,7 +353,7 @@
}
}
- sum_page = get_sum_page(sbi, segno);
+ sum_page = f2fs_get_sum_page(sbi, segno);
sum_node = (struct f2fs_summary_block *)page_address(sum_page);
sum = sum_node->entries[blkoff];
f2fs_put_page(sum_page, 1);
@@ -375,7 +373,7 @@
}
/* Get the node page */
- node_page = get_node_page(sbi, nid);
+ node_page = f2fs_get_node_page(sbi, nid);
if (IS_ERR(node_page))
return PTR_ERR(node_page);
@@ -400,7 +398,8 @@
inode = dn->inode;
}
- bidx = start_bidx_of_node(offset, inode) + le16_to_cpu(sum.ofs_in_node);
+ bidx = f2fs_start_bidx_of_node(offset, inode) +
+ le16_to_cpu(sum.ofs_in_node);
/*
* if inode page is locked, unlock temporarily, but its reference
@@ -410,11 +409,11 @@
unlock_page(dn->inode_page);
set_new_dnode(&tdn, inode, NULL, NULL, 0);
- if (get_dnode_of_data(&tdn, bidx, LOOKUP_NODE))
+ if (f2fs_get_dnode_of_data(&tdn, bidx, LOOKUP_NODE))
goto out;
if (tdn.data_blkaddr == blkaddr)
- truncate_data_blocks_range(&tdn, 1);
+ f2fs_truncate_data_blocks_range(&tdn, 1);
f2fs_put_dnode(&tdn);
out:
@@ -427,7 +426,7 @@
truncate_out:
if (datablock_addr(tdn.inode, tdn.node_page,
tdn.ofs_in_node) == blkaddr)
- truncate_data_blocks_range(&tdn, 1);
+ f2fs_truncate_data_blocks_range(&tdn, 1);
if (dn->inode->i_ino == nid && !dn->inode_page_locked)
unlock_page(dn->inode_page);
return 0;
@@ -443,25 +442,25 @@
/* step 1: recover xattr */
if (IS_INODE(page)) {
- recover_inline_xattr(inode, page);
+ f2fs_recover_inline_xattr(inode, page);
} else if (f2fs_has_xattr_block(ofs_of_node(page))) {
- err = recover_xattr_data(inode, page);
+ err = f2fs_recover_xattr_data(inode, page);
if (!err)
recovered++;
goto out;
}
/* step 2: recover inline data */
- if (recover_inline_data(inode, page))
+ if (f2fs_recover_inline_data(inode, page))
goto out;
/* step 3: recover data indices */
- start = start_bidx_of_node(ofs_of_node(page), inode);
+ start = f2fs_start_bidx_of_node(ofs_of_node(page), inode);
end = start + ADDRS_PER_PAGE(page, inode);
set_new_dnode(&dn, inode, NULL, NULL, 0);
retry_dn:
- err = get_dnode_of_data(&dn, start, ALLOC_NODE);
+ err = f2fs_get_dnode_of_data(&dn, start, ALLOC_NODE);
if (err) {
if (err == -ENOMEM) {
congestion_wait(BLK_RW_ASYNC, HZ/50);
@@ -472,7 +471,7 @@
f2fs_wait_on_page_writeback(dn.node_page, NODE, true);
- get_node_info(sbi, dn.nid, &ni);
+ f2fs_get_node_info(sbi, dn.nid, &ni);
f2fs_bug_on(sbi, ni.ino != ino_of_node(page));
f2fs_bug_on(sbi, ofs_of_node(dn.node_page) != ofs_of_node(page));
@@ -488,7 +487,7 @@
/* dest is invalid, just invalidate src block */
if (dest == NULL_ADDR) {
- truncate_data_blocks_range(&dn, 1);
+ f2fs_truncate_data_blocks_range(&dn, 1);
continue;
}
@@ -502,19 +501,19 @@
* and then reserve one new block in dnode page.
*/
if (dest == NEW_ADDR) {
- truncate_data_blocks_range(&dn, 1);
- reserve_new_block(&dn);
+ f2fs_truncate_data_blocks_range(&dn, 1);
+ f2fs_reserve_new_block(&dn);
continue;
}
/* dest is valid block, try to recover from src to dest */
- if (is_valid_blkaddr(sbi, dest, META_POR)) {
+ if (f2fs_is_valid_meta_blkaddr(sbi, dest, META_POR)) {
if (src == NULL_ADDR) {
- err = reserve_new_block(&dn);
+ err = f2fs_reserve_new_block(&dn);
#ifdef CONFIG_F2FS_FAULT_INJECTION
while (err)
- err = reserve_new_block(&dn);
+ err = f2fs_reserve_new_block(&dn);
#endif
/* We should not get -ENOSPC */
f2fs_bug_on(sbi, err);
@@ -569,12 +568,12 @@
while (1) {
struct fsync_inode_entry *entry;
- if (!is_valid_blkaddr(sbi, blkaddr, META_POR))
+ if (!f2fs_is_valid_meta_blkaddr(sbi, blkaddr, META_POR))
break;
- ra_meta_pages_cond(sbi, blkaddr);
+ f2fs_ra_meta_pages_cond(sbi, blkaddr);
- page = get_tmp_page(sbi, blkaddr);
+ page = f2fs_get_tmp_page(sbi, blkaddr);
if (!is_recoverable_dnode(page)) {
f2fs_put_page(page, 1);
@@ -612,11 +611,11 @@
f2fs_put_page(page, 1);
}
if (!err)
- allocate_new_segments(sbi);
+ f2fs_allocate_new_segments(sbi);
return err;
}
-int recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only)
+int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only)
{
struct list_head inode_list;
struct list_head dir_list;
@@ -691,7 +690,7 @@
struct cp_control cpc = {
.reason = CP_RECOVERY,
};
- err = write_checkpoint(sbi, &cpc);
+ err = f2fs_write_checkpoint(sbi, &cpc);
}
kmem_cache_destroy(fsync_entry_slab);
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 284faa5..52e85a0 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -169,7 +169,7 @@
return result - size + __reverse_ffz(tmp);
}
-bool need_SSR(struct f2fs_sb_info *sbi)
+bool f2fs_need_SSR(struct f2fs_sb_info *sbi)
{
int node_secs = get_blocktype_secs(sbi, F2FS_DIRTY_NODES);
int dent_secs = get_blocktype_secs(sbi, F2FS_DIRTY_DENTS);
@@ -177,14 +177,14 @@
if (test_opt(sbi, LFS))
return false;
- if (sbi->gc_thread && sbi->gc_thread->gc_urgent)
+ if (sbi->gc_mode == GC_URGENT)
return true;
return free_sections(sbi) <= (node_secs + 2 * dent_secs + imeta_secs +
SM_I(sbi)->min_ssr_sections + reserved_sections(sbi));
}
-void register_inmem_page(struct inode *inode, struct page *page)
+void f2fs_register_inmem_page(struct inode *inode, struct page *page)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
struct f2fs_inode_info *fi = F2FS_I(inode);
@@ -230,6 +230,8 @@
lock_page(page);
+ f2fs_wait_on_page_writeback(page, DATA, true);
+
if (recover) {
struct dnode_of_data dn;
struct node_info ni;
@@ -237,7 +239,8 @@
trace_f2fs_commit_inmem_page(page, INMEM_REVOKE);
retry:
set_new_dnode(&dn, inode, NULL, NULL, 0);
- err = get_dnode_of_data(&dn, page->index, LOOKUP_NODE);
+ err = f2fs_get_dnode_of_data(&dn, page->index,
+ LOOKUP_NODE);
if (err) {
if (err == -ENOMEM) {
congestion_wait(BLK_RW_ASYNC, HZ/50);
@@ -247,9 +250,9 @@
err = -EAGAIN;
goto next;
}
- get_node_info(sbi, dn.nid, &ni);
+ f2fs_get_node_info(sbi, dn.nid, &ni);
if (cur->old_addr == NEW_ADDR) {
- invalidate_blocks(sbi, dn.data_blkaddr);
+ f2fs_invalidate_blocks(sbi, dn.data_blkaddr);
f2fs_update_data_blkaddr(&dn, NEW_ADDR);
} else
f2fs_replace_block(sbi, &dn, dn.data_blkaddr,
@@ -271,7 +274,7 @@
return err;
}
-void drop_inmem_pages_all(struct f2fs_sb_info *sbi)
+void f2fs_drop_inmem_pages_all(struct f2fs_sb_info *sbi, bool gc_failure)
{
struct list_head *head = &sbi->inode_list[ATOMIC_FILE];
struct inode *inode;
@@ -287,15 +290,23 @@
spin_unlock(&sbi->inode_lock[ATOMIC_FILE]);
if (inode) {
- drop_inmem_pages(inode);
+ if (gc_failure) {
+ if (fi->i_gc_failures[GC_FAILURE_ATOMIC])
+ goto drop;
+ goto skip;
+ }
+drop:
+ set_inode_flag(inode, FI_ATOMIC_REVOKE_REQUEST);
+ f2fs_drop_inmem_pages(inode);
iput(inode);
}
+skip:
congestion_wait(BLK_RW_ASYNC, HZ/50);
cond_resched();
goto next;
}
-void drop_inmem_pages(struct inode *inode)
+void f2fs_drop_inmem_pages(struct inode *inode)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
struct f2fs_inode_info *fi = F2FS_I(inode);
@@ -309,11 +320,11 @@
mutex_unlock(&fi->inmem_lock);
clear_inode_flag(inode, FI_ATOMIC_FILE);
- clear_inode_flag(inode, FI_HOT_DATA);
+ fi->i_gc_failures[GC_FAILURE_ATOMIC] = 0;
stat_dec_atomic_write(inode);
}
-void drop_inmem_page(struct inode *inode, struct page *page)
+void f2fs_drop_inmem_page(struct inode *inode, struct page *page)
{
struct f2fs_inode_info *fi = F2FS_I(inode);
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
@@ -328,7 +339,7 @@
break;
}
- f2fs_bug_on(sbi, !cur || cur->page != page);
+ f2fs_bug_on(sbi, list_empty(head) || cur->page != page);
list_del(&cur->list);
mutex_unlock(&fi->inmem_lock);
@@ -343,8 +354,7 @@
trace_f2fs_commit_inmem_page(page, INMEM_INVALIDATE);
}
-static int __commit_inmem_pages(struct inode *inode,
- struct list_head *revoke_list)
+static int __f2fs_commit_inmem_pages(struct inode *inode)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
struct f2fs_inode_info *fi = F2FS_I(inode);
@@ -357,9 +367,12 @@
.op_flags = REQ_SYNC | REQ_PRIO,
.io_type = FS_DATA_IO,
};
+ struct list_head revoke_list;
pgoff_t last_idx = ULONG_MAX;
int err = 0;
+ INIT_LIST_HEAD(&revoke_list);
+
list_for_each_entry_safe(cur, tmp, &fi->inmem_pages, list) {
struct page *page = cur->page;
@@ -371,14 +384,14 @@
f2fs_wait_on_page_writeback(page, DATA, true);
if (clear_page_dirty_for_io(page)) {
inode_dec_dirty_pages(inode);
- remove_dirty_inode(inode);
+ f2fs_remove_dirty_inode(inode);
}
retry:
fio.page = page;
fio.old_blkaddr = NULL_ADDR;
fio.encrypted_page = NULL;
fio.need_lock = LOCK_DONE;
- err = do_write_data_page(&fio);
+ err = f2fs_do_write_data_page(&fio);
if (err) {
if (err == -ENOMEM) {
congestion_wait(BLK_RW_ASYNC, HZ/50);
@@ -393,35 +406,13 @@
last_idx = page->index;
}
unlock_page(page);
- list_move_tail(&cur->list, revoke_list);
+ list_move_tail(&cur->list, &revoke_list);
}
if (last_idx != ULONG_MAX)
f2fs_submit_merged_write_cond(sbi, inode, 0, last_idx, DATA);
- if (!err)
- __revoke_inmem_pages(inode, revoke_list, false, false);
-
- return err;
-}
-
-int commit_inmem_pages(struct inode *inode)
-{
- struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
- struct f2fs_inode_info *fi = F2FS_I(inode);
- struct list_head revoke_list;
- int err;
-
- INIT_LIST_HEAD(&revoke_list);
- f2fs_balance_fs(sbi, true);
- f2fs_lock_op(sbi);
-
- set_inode_flag(inode, FI_ATOMIC_COMMIT);
-
- mutex_lock(&fi->inmem_lock);
- err = __commit_inmem_pages(inode, &revoke_list);
if (err) {
- int ret;
/*
* try to revoke all committed pages, but still we could fail
* due to no memory or other reason, if that happened, EAGAIN
@@ -430,13 +421,31 @@
* recovery or rewrite & commit last transaction. For other
* error number, revoking was done by filesystem itself.
*/
- ret = __revoke_inmem_pages(inode, &revoke_list, false, true);
- if (ret)
- err = ret;
+ err = __revoke_inmem_pages(inode, &revoke_list, false, true);
/* drop all uncommitted pages */
__revoke_inmem_pages(inode, &fi->inmem_pages, true, false);
+ } else {
+ __revoke_inmem_pages(inode, &revoke_list, false, false);
}
+
+ return err;
+}
+
+int f2fs_commit_inmem_pages(struct inode *inode)
+{
+ struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+ struct f2fs_inode_info *fi = F2FS_I(inode);
+ int err;
+
+ f2fs_balance_fs(sbi, true);
+ f2fs_lock_op(sbi);
+
+ set_inode_flag(inode, FI_ATOMIC_COMMIT);
+
+ mutex_lock(&fi->inmem_lock);
+ err = __f2fs_commit_inmem_pages(inode);
+
spin_lock(&sbi->inode_lock[ATOMIC_FILE]);
if (!list_empty(&fi->inmem_ilist))
list_del_init(&fi->inmem_ilist);
@@ -478,25 +487,28 @@
void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi)
{
+ if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING)))
+ return;
+
/* try to shrink extent cache when there is no enough memory */
- if (!available_free_memory(sbi, EXTENT_CACHE))
+ if (!f2fs_available_free_memory(sbi, EXTENT_CACHE))
f2fs_shrink_extent_tree(sbi, EXTENT_CACHE_SHRINK_NUMBER);
/* check the # of cached NAT entries */
- if (!available_free_memory(sbi, NAT_ENTRIES))
- try_to_free_nats(sbi, NAT_ENTRY_PER_BLOCK);
+ if (!f2fs_available_free_memory(sbi, NAT_ENTRIES))
+ f2fs_try_to_free_nats(sbi, NAT_ENTRY_PER_BLOCK);
- if (!available_free_memory(sbi, FREE_NIDS))
- try_to_free_nids(sbi, MAX_FREE_NIDS);
+ if (!f2fs_available_free_memory(sbi, FREE_NIDS))
+ f2fs_try_to_free_nids(sbi, MAX_FREE_NIDS);
else
- build_free_nids(sbi, false, false);
+ f2fs_build_free_nids(sbi, false, false);
if (!is_idle(sbi) && !excess_dirty_nats(sbi))
return;
/* checkpoint is the only way to shrink partial cached entries */
- if (!available_free_memory(sbi, NAT_ENTRIES) ||
- !available_free_memory(sbi, INO_ENTRIES) ||
+ if (!f2fs_available_free_memory(sbi, NAT_ENTRIES) ||
+ !f2fs_available_free_memory(sbi, INO_ENTRIES) ||
excess_prefree_segs(sbi) ||
excess_dirty_nats(sbi) ||
f2fs_time_over(sbi, CP_TIME)) {
@@ -504,7 +516,7 @@
struct blk_plug plug;
blk_start_plug(&plug);
- sync_dirty_inodes(sbi, FILE_INODE);
+ f2fs_sync_dirty_inodes(sbi, FILE_INODE);
blk_finish_plug(&plug);
}
f2fs_sync_fs(sbi->sb, true);
@@ -537,7 +549,7 @@
return __submit_flush_wait(sbi, sbi->sb->s_bdev);
for (i = 0; i < sbi->s_ndevs; i++) {
- if (!is_dirty_device(sbi, ino, i, FLUSH_INO))
+ if (!f2fs_is_dirty_device(sbi, ino, i, FLUSH_INO))
continue;
ret = __submit_flush_wait(sbi, FDEV(i).bdev);
if (ret)
@@ -648,7 +660,7 @@
return cmd.ret;
}
-int create_flush_cmd_control(struct f2fs_sb_info *sbi)
+int f2fs_create_flush_cmd_control(struct f2fs_sb_info *sbi)
{
dev_t dev = sbi->sb->s_bdev->bd_dev;
struct flush_cmd_control *fcc;
@@ -685,7 +697,7 @@
return err;
}
-void destroy_flush_cmd_control(struct f2fs_sb_info *sbi, bool free)
+void f2fs_destroy_flush_cmd_control(struct f2fs_sb_info *sbi, bool free)
{
struct flush_cmd_control *fcc = SM_I(sbi)->fcc_info;
@@ -929,6 +941,7 @@
if (discard_type == DPOLICY_BG) {
dpolicy->min_interval = DEF_MIN_DISCARD_ISSUE_TIME;
+ dpolicy->mid_interval = DEF_MID_DISCARD_ISSUE_TIME;
dpolicy->max_interval = DEF_MAX_DISCARD_ISSUE_TIME;
dpolicy->io_aware = true;
dpolicy->sync = false;
@@ -938,11 +951,13 @@
}
} else if (discard_type == DPOLICY_FORCE) {
dpolicy->min_interval = DEF_MIN_DISCARD_ISSUE_TIME;
+ dpolicy->mid_interval = DEF_MID_DISCARD_ISSUE_TIME;
dpolicy->max_interval = DEF_MAX_DISCARD_ISSUE_TIME;
dpolicy->io_aware = false;
} else if (discard_type == DPOLICY_FSTRIM) {
dpolicy->io_aware = false;
} else if (discard_type == DPOLICY_UMOUNT) {
+ dpolicy->max_requests = UINT_MAX;
dpolicy->io_aware = false;
}
}
@@ -962,6 +977,9 @@
if (dc->state != D_PREP)
return;
+ if (is_sbi_flag_set(sbi, SBI_NEED_FSCK))
+ return;
+
trace_f2fs_issue_discard(dc->bdev, dc->start, dc->len);
dc->error = __blkdev_issue_discard(dc->bdev,
@@ -1005,7 +1023,7 @@
goto do_insert;
}
- p = __lookup_rb_tree_for_insert(sbi, &dcc->root, &parent, lstart);
+ p = f2fs_lookup_rb_tree_for_insert(sbi, &dcc->root, &parent, lstart);
do_insert:
dc = __attach_discard_cmd(sbi, bdev, lstart, start, len, parent, p);
if (!dc)
@@ -1070,7 +1088,7 @@
mutex_lock(&dcc->cmd_lock);
- dc = (struct discard_cmd *)__lookup_rb_tree_ret(&dcc->root,
+ dc = (struct discard_cmd *)f2fs_lookup_rb_tree_ret(&dcc->root,
NULL, lstart,
(struct rb_entry **)&prev_dc,
(struct rb_entry **)&next_dc,
@@ -1181,7 +1199,8 @@
mutex_lock(&dcc->cmd_lock);
if (list_empty(pend_list))
goto next;
- f2fs_bug_on(sbi, !__check_rb_tree_consistence(sbi, &dcc->root));
+ f2fs_bug_on(sbi,
+ !f2fs_check_rb_tree_consistence(sbi, &dcc->root));
blk_start_plug(&plug);
list_for_each_entry_safe(dc, tmp, pend_list, list) {
f2fs_bug_on(sbi, dc->state != D_PREP);
@@ -1234,7 +1253,7 @@
return dropped;
}
-void drop_discard_cmd(struct f2fs_sb_info *sbi)
+void f2fs_drop_discard_cmd(struct f2fs_sb_info *sbi)
{
__drop_discard_cmd(sbi);
}
@@ -1325,7 +1344,8 @@
bool need_wait = false;
mutex_lock(&dcc->cmd_lock);
- dc = (struct discard_cmd *)__lookup_rb_tree(&dcc->root, NULL, blkaddr);
+ dc = (struct discard_cmd *)f2fs_lookup_rb_tree(&dcc->root,
+ NULL, blkaddr);
if (dc) {
if (dc->state == D_PREP) {
__punch_discard_cmd(sbi, dc, blkaddr);
@@ -1340,7 +1360,7 @@
__wait_one_discard_bio(sbi, dc);
}
-void stop_discard_thread(struct f2fs_sb_info *sbi)
+void f2fs_stop_discard_thread(struct f2fs_sb_info *sbi)
{
struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
@@ -1377,6 +1397,8 @@
struct discard_policy dpolicy;
unsigned int wait_ms = DEF_MIN_DISCARD_ISSUE_TIME;
int issued;
+ unsigned long interval = sbi->interval_time[REQ_TIME] * HZ;
+ long delta;
set_freezable();
@@ -1388,25 +1410,36 @@
kthread_should_stop() || freezing(current) ||
dcc->discard_wake,
msecs_to_jiffies(wait_ms));
+
+ if (dcc->discard_wake)
+ dcc->discard_wake = 0;
+
if (try_to_freeze())
continue;
if (f2fs_readonly(sbi->sb))
continue;
if (kthread_should_stop())
return 0;
+ if (is_sbi_flag_set(sbi, SBI_NEED_FSCK)) {
+ wait_ms = dpolicy.max_interval;
+ continue;
+ }
- if (dcc->discard_wake)
- dcc->discard_wake = 0;
-
- if (sbi->gc_thread && sbi->gc_thread->gc_urgent)
+ if (sbi->gc_mode == GC_URGENT)
__init_discard_policy(sbi, &dpolicy, DPOLICY_FORCE, 1);
sb_start_intwrite(sbi->sb);
issued = __issue_discard_cmd(sbi, &dpolicy);
- if (issued) {
+ if (issued > 0) {
__wait_all_discard_cmd(sbi, &dpolicy);
wait_ms = dpolicy.min_interval;
+ } else if (issued == -1){
+ delta = (sbi->last_time[REQ_TIME] + interval) - jiffies;
+ if (delta > 0)
+ wait_ms = jiffies_to_msecs(delta);
+ else
+ wait_ms = dpolicy.mid_interval;
} else {
wait_ms = dpolicy.max_interval;
}
@@ -1575,20 +1608,24 @@
return false;
}
-void release_discard_addrs(struct f2fs_sb_info *sbi)
+static void release_discard_addr(struct discard_entry *entry)
+{
+ list_del(&entry->list);
+ kmem_cache_free(discard_entry_slab, entry);
+}
+
+void f2fs_release_discard_addrs(struct f2fs_sb_info *sbi)
{
struct list_head *head = &(SM_I(sbi)->dcc_info->entry_list);
struct discard_entry *entry, *this;
/* drop caches */
- list_for_each_entry_safe(entry, this, head, list) {
- list_del(&entry->list);
- kmem_cache_free(discard_entry_slab, entry);
- }
+ list_for_each_entry_safe(entry, this, head, list)
+ release_discard_addr(entry);
}
/*
- * Should call clear_prefree_segments after checkpoint is done.
+ * Should call f2fs_clear_prefree_segments after checkpoint is done.
*/
static void set_prefree_as_free_segments(struct f2fs_sb_info *sbi)
{
@@ -1601,7 +1638,8 @@
mutex_unlock(&dirty_i->seglist_lock);
}
-void clear_prefree_segments(struct f2fs_sb_info *sbi, struct cp_control *cpc)
+void f2fs_clear_prefree_segments(struct f2fs_sb_info *sbi,
+ struct cp_control *cpc)
{
struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
struct list_head *head = &dcc->entry_list;
@@ -1684,9 +1722,8 @@
if (cur_pos < sbi->blocks_per_seg)
goto find_next;
- list_del(&entry->list);
+ release_discard_addr(entry);
dcc->nr_discards -= total_len;
- kmem_cache_free(discard_entry_slab, entry);
}
wake_up_discard_thread(sbi, false);
@@ -1744,7 +1781,7 @@
if (!dcc)
return;
- stop_discard_thread(sbi);
+ f2fs_stop_discard_thread(sbi);
kfree(dcc);
SM_I(sbi)->dcc_info = NULL;
@@ -1791,8 +1828,9 @@
(new_vblocks > sbi->blocks_per_seg)));
se->valid_blocks = new_vblocks;
- se->mtime = get_mtime(sbi);
- SIT_I(sbi)->max_mtime = se->mtime;
+ se->mtime = get_mtime(sbi, false);
+ if (se->mtime > SIT_I(sbi)->max_mtime)
+ SIT_I(sbi)->max_mtime = se->mtime;
/* Update valid block bitmap */
if (del > 0) {
@@ -1860,7 +1898,7 @@
get_sec_entry(sbi, segno)->valid_blocks += del;
}
-void invalidate_blocks(struct f2fs_sb_info *sbi, block_t addr)
+void f2fs_invalidate_blocks(struct f2fs_sb_info *sbi, block_t addr)
{
unsigned int segno = GET_SEGNO(sbi, addr);
struct sit_info *sit_i = SIT_I(sbi);
@@ -1880,14 +1918,14 @@
up_write(&sit_i->sentry_lock);
}
-bool is_checkpointed_data(struct f2fs_sb_info *sbi, block_t blkaddr)
+bool f2fs_is_checkpointed_data(struct f2fs_sb_info *sbi, block_t blkaddr)
{
struct sit_info *sit_i = SIT_I(sbi);
unsigned int segno, offset;
struct seg_entry *se;
bool is_cp = false;
- if (blkaddr == NEW_ADDR || blkaddr == NULL_ADDR)
+ if (!is_valid_blkaddr(blkaddr))
return true;
down_read(&sit_i->sentry_lock);
@@ -1919,7 +1957,7 @@
/*
* Calculate the number of current summary pages for writing
*/
-int npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra)
+int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra)
{
int valid_sum_count = 0;
int i, sum_in_page;
@@ -1949,14 +1987,15 @@
/*
* Caller should put this summary page
*/
-struct page *get_sum_page(struct f2fs_sb_info *sbi, unsigned int segno)
+struct page *f2fs_get_sum_page(struct f2fs_sb_info *sbi, unsigned int segno)
{
- return get_meta_page(sbi, GET_SUM_BLOCK(sbi, segno));
+ return f2fs_get_meta_page(sbi, GET_SUM_BLOCK(sbi, segno));
}
-void update_meta_page(struct f2fs_sb_info *sbi, void *src, block_t blk_addr)
+void f2fs_update_meta_page(struct f2fs_sb_info *sbi,
+ void *src, block_t blk_addr)
{
- struct page *page = grab_meta_page(sbi, blk_addr);
+ struct page *page = f2fs_grab_meta_page(sbi, blk_addr);
memcpy(page_address(page), src, PAGE_SIZE);
set_page_dirty(page);
@@ -1966,18 +2005,19 @@
static void write_sum_page(struct f2fs_sb_info *sbi,
struct f2fs_summary_block *sum_blk, block_t blk_addr)
{
- update_meta_page(sbi, (void *)sum_blk, blk_addr);
+ f2fs_update_meta_page(sbi, (void *)sum_blk, blk_addr);
}
static void write_current_sum_page(struct f2fs_sb_info *sbi,
int type, block_t blk_addr)
{
struct curseg_info *curseg = CURSEG_I(sbi, type);
- struct page *page = grab_meta_page(sbi, blk_addr);
+ struct page *page = f2fs_grab_meta_page(sbi, blk_addr);
struct f2fs_summary_block *src = curseg->sum_blk;
struct f2fs_summary_block *dst;
dst = (struct f2fs_summary_block *)page_address(page);
+ memset(dst, 0, PAGE_SIZE);
mutex_lock(&curseg->curseg_mutex);
@@ -2217,7 +2257,7 @@
curseg->alloc_type = SSR;
__next_free_blkoff(sbi, curseg, 0);
- sum_page = get_sum_page(sbi, new_segno);
+ sum_page = f2fs_get_sum_page(sbi, new_segno);
sum_node = (struct f2fs_summary_block *)page_address(sum_page);
memcpy(curseg->sum_blk, sum_node, SUM_ENTRY_SIZE);
f2fs_put_page(sum_page, 1);
@@ -2231,7 +2271,7 @@
int i, cnt;
bool reversed = false;
- /* need_SSR() already forces to do this */
+ /* f2fs_need_SSR() already forces to do this */
if (v_ops->get_victim(sbi, &segno, BG_GC, type, SSR)) {
curseg->next_segno = segno;
return 1;
@@ -2283,7 +2323,7 @@
new_curseg(sbi, type, false);
else if (curseg->alloc_type == LFS && is_next_segment_free(sbi, type))
new_curseg(sbi, type, false);
- else if (need_SSR(sbi) && get_ssr_segment(sbi, type))
+ else if (f2fs_need_SSR(sbi) && get_ssr_segment(sbi, type))
change_curseg(sbi, type);
else
new_curseg(sbi, type, false);
@@ -2291,7 +2331,7 @@
stat_inc_seg_type(sbi, curseg);
}
-void allocate_new_segments(struct f2fs_sb_info *sbi)
+void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi)
{
struct curseg_info *curseg;
unsigned int old_segno;
@@ -2313,7 +2353,8 @@
.allocate_segment = allocate_segment_by_default,
};
-bool exist_trim_candidates(struct f2fs_sb_info *sbi, struct cp_control *cpc)
+bool f2fs_exist_trim_candidates(struct f2fs_sb_info *sbi,
+ struct cp_control *cpc)
{
__u64 trim_start = cpc->trim_start;
bool has_candidate = false;
@@ -2346,9 +2387,9 @@
issued = 0;
mutex_lock(&dcc->cmd_lock);
- f2fs_bug_on(sbi, !__check_rb_tree_consistence(sbi, &dcc->root));
+ f2fs_bug_on(sbi, !f2fs_check_rb_tree_consistence(sbi, &dcc->root));
- dc = (struct discard_cmd *)__lookup_rb_tree_ret(&dcc->root,
+ dc = (struct discard_cmd *)f2fs_lookup_rb_tree_ret(&dcc->root,
NULL, start,
(struct rb_entry **)&prev_dc,
(struct rb_entry **)&next_dc,
@@ -2407,12 +2448,12 @@
return -EINVAL;
if (end <= MAIN_BLKADDR(sbi))
- goto out;
+ return -EINVAL;
if (is_sbi_flag_set(sbi, SBI_NEED_FSCK)) {
f2fs_msg(sbi->sb, KERN_WARNING,
"Found FS corruption, run fsck to fix.");
- goto out;
+ return -EIO;
}
/* start/end segment number in main_area */
@@ -2429,7 +2470,7 @@
goto out;
mutex_lock(&sbi->gc_mutex);
- err = write_checkpoint(sbi, &cpc);
+ err = f2fs_write_checkpoint(sbi, &cpc);
mutex_unlock(&sbi->gc_mutex);
if (err)
goto out;
@@ -2463,7 +2504,7 @@
return false;
}
-int rw_hint_to_seg_type(enum rw_hint hint)
+int f2fs_rw_hint_to_seg_type(enum rw_hint hint)
{
switch (hint) {
case WRITE_LIFE_SHORT:
@@ -2536,7 +2577,7 @@
* WRITE_LIFE_LONG " WRITE_LIFE_LONG
*/
-enum rw_hint io_type_to_rw_hint(struct f2fs_sb_info *sbi,
+enum rw_hint f2fs_io_type_to_rw_hint(struct f2fs_sb_info *sbi,
enum page_type type, enum temp_type temp)
{
if (F2FS_OPTION(sbi).whint_mode == WHINT_MODE_USER) {
@@ -2603,9 +2644,11 @@
if (is_cold_data(fio->page) || file_is_cold(inode))
return CURSEG_COLD_DATA;
if (file_is_hot(inode) ||
- is_inode_flag_set(inode, FI_HOT_DATA))
+ is_inode_flag_set(inode, FI_HOT_DATA) ||
+ is_inode_flag_set(inode, FI_ATOMIC_FILE) ||
+ is_inode_flag_set(inode, FI_VOLATILE_FILE))
return CURSEG_HOT_DATA;
- /* rw_hint_to_seg_type(inode->i_write_hint); */
+ /* f2fs_rw_hint_to_seg_type(inode->i_write_hint); */
return CURSEG_WARM_DATA;
} else {
if (IS_DNODE(fio->page))
@@ -2642,7 +2685,7 @@
return type;
}
-void allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
+void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
block_t old_blkaddr, block_t *new_blkaddr,
struct f2fs_summary *sum, int type,
struct f2fs_io_info *fio, bool add_list)
@@ -2702,6 +2745,7 @@
INIT_LIST_HEAD(&fio->list);
fio->in_list = true;
+ fio->retry = false;
io = sbi->write_io[fio->type] + fio->temp;
spin_lock(&io->io_lock);
list_add_tail(&fio->list, &io->io_list);
@@ -2724,7 +2768,7 @@
devidx = f2fs_target_device_index(sbi, fio->new_blkaddr);
/* update device state for fsync */
- set_dirty_device(sbi, fio->ino, devidx, FLUSH_INO);
+ f2fs_set_dirty_device(sbi, fio->ino, devidx, FLUSH_INO);
/* update device state for checkpoint */
if (!f2fs_test_bit(devidx, (char *)&sbi->dirty_device)) {
@@ -2737,23 +2781,28 @@
static void do_write_page(struct f2fs_summary *sum, struct f2fs_io_info *fio)
{
int type = __get_segment_type(fio);
- int err;
+ bool keep_order = (test_opt(fio->sbi, LFS) && type == CURSEG_COLD_DATA);
+ if (keep_order)
+ down_read(&fio->sbi->io_order_lock);
reallocate:
- allocate_data_block(fio->sbi, fio->page, fio->old_blkaddr,
+ f2fs_allocate_data_block(fio->sbi, fio->page, fio->old_blkaddr,
&fio->new_blkaddr, sum, type, fio, true);
/* writeout dirty page into bdev */
- err = f2fs_submit_page_write(fio);
- if (err == -EAGAIN) {
+ f2fs_submit_page_write(fio);
+ if (fio->retry) {
fio->old_blkaddr = fio->new_blkaddr;
goto reallocate;
- } else if (!err) {
- update_device_state(fio);
}
+
+ update_device_state(fio);
+
+ if (keep_order)
+ up_read(&fio->sbi->io_order_lock);
}
-void write_meta_page(struct f2fs_sb_info *sbi, struct page *page,
+void f2fs_do_write_meta_page(struct f2fs_sb_info *sbi, struct page *page,
enum iostat_type io_type)
{
struct f2fs_io_info fio = {
@@ -2779,7 +2828,7 @@
f2fs_update_iostat(sbi, io_type, F2FS_BLKSIZE);
}
-void write_node_page(unsigned int nid, struct f2fs_io_info *fio)
+void f2fs_do_write_node_page(unsigned int nid, struct f2fs_io_info *fio)
{
struct f2fs_summary sum;
@@ -2789,14 +2838,15 @@
f2fs_update_iostat(fio->sbi, fio->io_type, F2FS_BLKSIZE);
}
-void write_data_page(struct dnode_of_data *dn, struct f2fs_io_info *fio)
+void f2fs_outplace_write_data(struct dnode_of_data *dn,
+ struct f2fs_io_info *fio)
{
struct f2fs_sb_info *sbi = fio->sbi;
struct f2fs_summary sum;
struct node_info ni;
f2fs_bug_on(sbi, dn->data_blkaddr == NULL_ADDR);
- get_node_info(sbi, dn->nid, &ni);
+ f2fs_get_node_info(sbi, dn->nid, &ni);
set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version);
do_write_page(&sum, fio);
f2fs_update_data_blkaddr(dn, fio->new_blkaddr);
@@ -2804,7 +2854,7 @@
f2fs_update_iostat(sbi, fio->io_type, F2FS_BLKSIZE);
}
-int rewrite_data_page(struct f2fs_io_info *fio)
+int f2fs_inplace_write_data(struct f2fs_io_info *fio)
{
int err;
struct f2fs_sb_info *sbi = fio->sbi;
@@ -2839,7 +2889,7 @@
return i;
}
-void __f2fs_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
+void f2fs_do_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
block_t old_blkaddr, block_t new_blkaddr,
bool recover_curseg, bool recover_newaddr)
{
@@ -2924,7 +2974,7 @@
set_summary(&sum, dn->nid, dn->ofs_in_node, version);
- __f2fs_replace_block(sbi, &sum, old_addr, new_addr,
+ f2fs_do_replace_block(sbi, &sum, old_addr, new_addr,
recover_curseg, recover_newaddr);
f2fs_update_data_blkaddr(dn, new_addr);
@@ -2949,7 +2999,7 @@
{
struct page *cpage;
- if (blkaddr == NEW_ADDR || blkaddr == NULL_ADDR)
+ if (!is_valid_blkaddr(blkaddr))
return;
cpage = find_lock_page(META_MAPPING(sbi), blkaddr);
@@ -2970,7 +3020,7 @@
start = start_sum_block(sbi);
- page = get_meta_page(sbi, start++);
+ page = f2fs_get_meta_page(sbi, start++);
kaddr = (unsigned char *)page_address(page);
/* Step 1: restore nat cache */
@@ -3010,7 +3060,7 @@
f2fs_put_page(page, 1);
page = NULL;
- page = get_meta_page(sbi, start++);
+ page = f2fs_get_meta_page(sbi, start++);
kaddr = (unsigned char *)page_address(page);
offset = 0;
}
@@ -3049,7 +3099,7 @@
blk_addr = GET_SUM_BLOCK(sbi, segno);
}
- new = get_meta_page(sbi, blk_addr);
+ new = f2fs_get_meta_page(sbi, blk_addr);
sum = (struct f2fs_summary_block *)page_address(new);
if (IS_NODESEG(type)) {
@@ -3061,7 +3111,7 @@
ns->ofs_in_node = 0;
}
} else {
- restore_node_summary(sbi, segno, sum);
+ f2fs_restore_node_summary(sbi, segno, sum);
}
}
@@ -3093,10 +3143,10 @@
int err;
if (is_set_ckpt_flags(sbi, CP_COMPACT_SUM_FLAG)) {
- int npages = npages_for_summary_flush(sbi, true);
+ int npages = f2fs_npages_for_summary_flush(sbi, true);
if (npages >= 2)
- ra_meta_pages(sbi, start_sum_block(sbi), npages,
+ f2fs_ra_meta_pages(sbi, start_sum_block(sbi), npages,
META_CP, true);
/* restore for compacted data summary */
@@ -3105,7 +3155,7 @@
}
if (__exist_node_summaries(sbi))
- ra_meta_pages(sbi, sum_blk_addr(sbi, NR_CURSEG_TYPE, type),
+ f2fs_ra_meta_pages(sbi, sum_blk_addr(sbi, NR_CURSEG_TYPE, type),
NR_CURSEG_TYPE - type, META_CP, true);
for (; type <= CURSEG_COLD_NODE; type++) {
@@ -3131,8 +3181,9 @@
int written_size = 0;
int i, j;
- page = grab_meta_page(sbi, blkaddr++);
+ page = f2fs_grab_meta_page(sbi, blkaddr++);
kaddr = (unsigned char *)page_address(page);
+ memset(kaddr, 0, PAGE_SIZE);
/* Step 1: write nat cache */
seg_i = CURSEG_I(sbi, CURSEG_HOT_DATA);
@@ -3155,8 +3206,9 @@
for (j = 0; j < blkoff; j++) {
if (!page) {
- page = grab_meta_page(sbi, blkaddr++);
+ page = f2fs_grab_meta_page(sbi, blkaddr++);
kaddr = (unsigned char *)page_address(page);
+ memset(kaddr, 0, PAGE_SIZE);
written_size = 0;
}
summary = (struct f2fs_summary *)(kaddr + written_size);
@@ -3191,7 +3243,7 @@
write_current_sum_page(sbi, i, blkaddr + (i - type));
}
-void write_data_summaries(struct f2fs_sb_info *sbi, block_t start_blk)
+void f2fs_write_data_summaries(struct f2fs_sb_info *sbi, block_t start_blk)
{
if (is_set_ckpt_flags(sbi, CP_COMPACT_SUM_FLAG))
write_compacted_summaries(sbi, start_blk);
@@ -3199,12 +3251,12 @@
write_normal_summaries(sbi, start_blk, CURSEG_HOT_DATA);
}
-void write_node_summaries(struct f2fs_sb_info *sbi, block_t start_blk)
+void f2fs_write_node_summaries(struct f2fs_sb_info *sbi, block_t start_blk)
{
write_normal_summaries(sbi, start_blk, CURSEG_HOT_NODE);
}
-int lookup_journal_in_cursum(struct f2fs_journal *journal, int type,
+int f2fs_lookup_journal_in_cursum(struct f2fs_journal *journal, int type,
unsigned int val, int alloc)
{
int i;
@@ -3229,7 +3281,7 @@
static struct page *get_current_sit_page(struct f2fs_sb_info *sbi,
unsigned int segno)
{
- return get_meta_page(sbi, current_sit_addr(sbi, segno));
+ return f2fs_get_meta_page(sbi, current_sit_addr(sbi, segno));
}
static struct page *get_next_sit_page(struct f2fs_sb_info *sbi,
@@ -3242,7 +3294,7 @@
src_off = current_sit_addr(sbi, start);
dst_off = next_sit_addr(sbi, src_off);
- page = grab_meta_page(sbi, dst_off);
+ page = f2fs_grab_meta_page(sbi, dst_off);
seg_info_to_sit_page(sbi, page, start);
set_page_dirty(page);
@@ -3338,7 +3390,7 @@
* CP calls this function, which flushes SIT entries including sit_journal,
* and moves prefree segs to free segs.
*/
-void flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc)
+void f2fs_flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc)
{
struct sit_info *sit_i = SIT_I(sbi);
unsigned long *bitmap = sit_i->dirty_sentries_bitmap;
@@ -3397,6 +3449,11 @@
int offset, sit_offset;
se = get_seg_entry(sbi, segno);
+#ifdef CONFIG_F2FS_CHECK_FS
+ if (memcmp(se->cur_valid_map, se->cur_valid_map_mir,
+ SIT_VBLOCK_MAP_SIZE))
+ f2fs_bug_on(sbi, 1);
+#endif
/* add discard candidates */
if (!(cpc->reason & CP_DISCARD)) {
@@ -3405,17 +3462,21 @@
}
if (to_journal) {
- offset = lookup_journal_in_cursum(journal,
+ offset = f2fs_lookup_journal_in_cursum(journal,
SIT_JOURNAL, segno, 1);
f2fs_bug_on(sbi, offset < 0);
segno_in_journal(journal, offset) =
cpu_to_le32(segno);
seg_info_to_raw_sit(se,
&sit_in_journal(journal, offset));
+ check_block_count(sbi, segno,
+ &sit_in_journal(journal, offset));
} else {
sit_offset = SIT_ENTRY_OFFSET(sit_i, segno);
seg_info_to_raw_sit(se,
&raw_sit->entries[sit_offset]);
+ check_block_count(sbi, segno,
+ &raw_sit->entries[sit_offset]);
}
__clear_bit(segno, bitmap);
@@ -3463,8 +3524,10 @@
SM_I(sbi)->sit_info = sit_i;
- sit_i->sentries = f2fs_kvzalloc(sbi, MAIN_SEGS(sbi) *
- sizeof(struct seg_entry), GFP_KERNEL);
+ sit_i->sentries =
+ f2fs_kvzalloc(sbi, array_size(sizeof(struct seg_entry),
+ MAIN_SEGS(sbi)),
+ GFP_KERNEL);
if (!sit_i->sentries)
return -ENOMEM;
@@ -3504,8 +3567,10 @@
return -ENOMEM;
if (sbi->segs_per_sec > 1) {
- sit_i->sec_entries = f2fs_kvzalloc(sbi, MAIN_SECS(sbi) *
- sizeof(struct sec_entry), GFP_KERNEL);
+ sit_i->sec_entries =
+ f2fs_kvzalloc(sbi, array_size(sizeof(struct sec_entry),
+ MAIN_SECS(sbi)),
+ GFP_KERNEL);
if (!sit_i->sec_entries)
return -ENOMEM;
}
@@ -3581,7 +3646,8 @@
struct curseg_info *array;
int i;
- array = f2fs_kzalloc(sbi, sizeof(*array) * NR_CURSEG_TYPE, GFP_KERNEL);
+ array = f2fs_kzalloc(sbi, array_size(NR_CURSEG_TYPE, sizeof(*array)),
+ GFP_KERNEL);
if (!array)
return -ENOMEM;
@@ -3614,9 +3680,10 @@
unsigned int i, start, end;
unsigned int readed, start_blk = 0;
int err = 0;
+ block_t total_node_blocks = 0;
do {
- readed = ra_meta_pages(sbi, start_blk, BIO_MAX_PAGES,
+ readed = f2fs_ra_meta_pages(sbi, start_blk, BIO_MAX_PAGES,
META_SIT, true);
start = start_blk * sit_i->sents_per_block;
@@ -3636,6 +3703,8 @@
if (err)
return err;
seg_info_from_raw_sit(se, &sit);
+ if (IS_NODESEG(se->type))
+ total_node_blocks += se->valid_blocks;
/* build discard map only one time */
if (f2fs_discard_en(sbi)) {
@@ -3664,15 +3733,28 @@
unsigned int old_valid_blocks;
start = le32_to_cpu(segno_in_journal(journal, i));
+ if (start >= MAIN_SEGS(sbi)) {
+ f2fs_msg(sbi->sb, KERN_ERR,
+ "Wrong journal entry on segno %u",
+ start);
+ set_sbi_flag(sbi, SBI_NEED_FSCK);
+ err = -EINVAL;
+ break;
+ }
+
se = &sit_i->sentries[start];
sit = sit_in_journal(journal, i);
old_valid_blocks = se->valid_blocks;
+ if (IS_NODESEG(se->type))
+ total_node_blocks -= old_valid_blocks;
err = check_block_count(sbi, start, &sit);
if (err)
break;
seg_info_from_raw_sit(se, &sit);
+ if (IS_NODESEG(se->type))
+ total_node_blocks += se->valid_blocks;
if (f2fs_discard_en(sbi)) {
if (is_set_ckpt_flags(sbi, CP_TRIMMED_FLAG)) {
@@ -3681,16 +3763,28 @@
} else {
memcpy(se->discard_map, se->cur_valid_map,
SIT_VBLOCK_MAP_SIZE);
- sbi->discard_blks += old_valid_blocks -
- se->valid_blocks;
+ sbi->discard_blks += old_valid_blocks;
+ sbi->discard_blks -= se->valid_blocks;
}
}
- if (sbi->segs_per_sec > 1)
+ if (sbi->segs_per_sec > 1) {
get_sec_entry(sbi, start)->valid_blocks +=
- se->valid_blocks - old_valid_blocks;
+ se->valid_blocks;
+ get_sec_entry(sbi, start)->valid_blocks -=
+ old_valid_blocks;
+ }
}
up_read(&curseg->journal_rwsem);
+
+ if (!err && total_node_blocks != valid_node_count(sbi)) {
+ f2fs_msg(sbi->sb, KERN_ERR,
+ "SIT is corrupted node# %u vs %u",
+ total_node_blocks, valid_node_count(sbi));
+ set_sbi_flag(sbi, SBI_NEED_FSCK);
+ err = -EINVAL;
+ }
+
return err;
}
@@ -3789,7 +3883,7 @@
down_write(&sit_i->sentry_lock);
- sit_i->min_mtime = LLONG_MAX;
+ sit_i->min_mtime = ULLONG_MAX;
for (segno = 0; segno < MAIN_SEGS(sbi); segno += sbi->segs_per_sec) {
unsigned int i;
@@ -3803,11 +3897,11 @@
if (sit_i->min_mtime > mtime)
sit_i->min_mtime = mtime;
}
- sit_i->max_mtime = get_mtime(sbi);
+ sit_i->max_mtime = get_mtime(sbi, false);
up_write(&sit_i->sentry_lock);
}
-int build_segment_manager(struct f2fs_sb_info *sbi)
+int f2fs_build_segment_manager(struct f2fs_sb_info *sbi)
{
struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
@@ -3845,7 +3939,7 @@
init_rwsem(&sm_info->curseg_lock);
if (!f2fs_readonly(sbi->sb)) {
- err = create_flush_cmd_control(sbi);
+ err = f2fs_create_flush_cmd_control(sbi);
if (err)
return err;
}
@@ -3970,13 +4064,13 @@
kfree(sit_i);
}
-void destroy_segment_manager(struct f2fs_sb_info *sbi)
+void f2fs_destroy_segment_manager(struct f2fs_sb_info *sbi)
{
struct f2fs_sm_info *sm_info = SM_I(sbi);
if (!sm_info)
return;
- destroy_flush_cmd_control(sbi, true);
+ f2fs_destroy_flush_cmd_control(sbi, true);
destroy_discard_cmd_control(sbi);
destroy_dirty_segmap(sbi);
destroy_curseg(sbi);
@@ -3986,7 +4080,7 @@
kfree(sm_info);
}
-int __init create_segment_manager_caches(void)
+int __init f2fs_create_segment_manager_caches(void)
{
discard_entry_slab = f2fs_kmem_cache_create("discard_entry",
sizeof(struct discard_entry));
@@ -4019,7 +4113,7 @@
return -ENOMEM;
}
-void destroy_segment_manager_caches(void)
+void f2fs_destroy_segment_manager_caches(void)
{
kmem_cache_destroy(sit_entry_set_slab);
kmem_cache_destroy(discard_cmd_slab);
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
index 3325d07..f18fc82 100644
--- a/fs/f2fs/segment.h
+++ b/fs/f2fs/segment.h
@@ -85,7 +85,7 @@
(GET_SEGOFF_FROM_SEG0(sbi, blk_addr) & ((sbi)->blocks_per_seg - 1))
#define GET_SEGNO(sbi, blk_addr) \
- ((((blk_addr) == NULL_ADDR) || ((blk_addr) == NEW_ADDR)) ? \
+ ((!is_valid_blkaddr(blk_addr)) ? \
NULL_SEGNO : GET_L2R_SEGNO(FREE_I(sbi), \
GET_SEGNO_FROM_SEG0(sbi, blk_addr)))
#define BLKS_PER_SEC(sbi) \
@@ -215,6 +215,8 @@
#define IS_DUMMY_WRITTEN_PAGE(page) \
(page_private(page) == (unsigned long)DUMMY_WRITTEN_PAGE)
+#define MAX_SKIP_ATOMIC_COUNT 16
+
struct inmem_pages {
struct list_head list;
struct page *page;
@@ -375,6 +377,7 @@
int i;
raw_sit = (struct f2fs_sit_block *)page_address(page);
+ memset(raw_sit, 0, PAGE_SIZE);
for (i = 0; i < end - start; i++) {
rs = &raw_sit->entries[i];
se = get_seg_entry(sbi, start + i);
@@ -742,12 +745,23 @@
#endif
}
-static inline unsigned long long get_mtime(struct f2fs_sb_info *sbi)
+static inline unsigned long long get_mtime(struct f2fs_sb_info *sbi,
+ bool base_time)
{
struct sit_info *sit_i = SIT_I(sbi);
- time64_t now = ktime_get_real_seconds();
+ time64_t diff, now = ktime_get_real_seconds();
- return sit_i->elapsed_time + now - sit_i->mounted_time;
+ if (now >= sit_i->mounted_time)
+ return sit_i->elapsed_time + now - sit_i->mounted_time;
+
+ /* system time is set to the past */
+ if (!base_time) {
+ diff = sit_i->mounted_time - now;
+ if (sit_i->elapsed_time >= diff)
+ return sit_i->elapsed_time - diff;
+ return 0;
+ }
+ return sit_i->elapsed_time;
}
static inline void set_summary(struct f2fs_summary *sum, nid_t nid,
@@ -771,15 +785,6 @@
- (base + 1) + type;
}
-static inline bool no_fggc_candidate(struct f2fs_sb_info *sbi,
- unsigned int secno)
-{
- if (get_valid_blocks(sbi, GET_SEG_FROM_SEC(sbi, secno), true) >
- sbi->fggc_threshold)
- return true;
- return false;
-}
-
static inline bool sec_usage_check(struct f2fs_sb_info *sbi, unsigned int secno)
{
if (IS_CURSEC(sbi, secno) || (sbi->cur_victim_sec == secno))
diff --git a/fs/f2fs/shrinker.c b/fs/f2fs/shrinker.c
index 0b5664a..36cfd81 100644
--- a/fs/f2fs/shrinker.c
+++ b/fs/f2fs/shrinker.c
@@ -109,11 +109,11 @@
/* shrink clean nat cache entries */
if (freed < nr)
- freed += try_to_free_nats(sbi, nr - freed);
+ freed += f2fs_try_to_free_nats(sbi, nr - freed);
/* shrink free nids cache entries */
if (freed < nr)
- freed += try_to_free_nids(sbi, nr - freed);
+ freed += f2fs_try_to_free_nids(sbi, nr - freed);
spin_lock(&f2fs_list_lock);
p = p->next;
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index ee2ebbf..fd5be5e 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -830,15 +830,14 @@
/* Initialize f2fs-specific inode info */
atomic_set(&fi->dirty_pages, 0);
- fi->i_current_depth = 1;
init_rwsem(&fi->i_sem);
INIT_LIST_HEAD(&fi->dirty_list);
INIT_LIST_HEAD(&fi->gdirty_list);
INIT_LIST_HEAD(&fi->inmem_ilist);
INIT_LIST_HEAD(&fi->inmem_pages);
mutex_init(&fi->inmem_lock);
- init_rwsem(&fi->dio_rwsem[READ]);
- init_rwsem(&fi->dio_rwsem[WRITE]);
+ init_rwsem(&fi->i_gc_rwsem[READ]);
+ init_rwsem(&fi->i_gc_rwsem[WRITE]);
init_rwsem(&fi->i_mmap_sem);
init_rwsem(&fi->i_xattr_sem);
@@ -866,7 +865,7 @@
/* some remained atomic pages should discarded */
if (f2fs_is_atomic_file(inode))
- drop_inmem_pages(inode);
+ f2fs_drop_inmem_pages(inode);
/* should remain fi->extent_tree for writepage */
f2fs_destroy_extent_node(inode);
@@ -1003,7 +1002,7 @@
struct cp_control cpc = {
.reason = CP_UMOUNT,
};
- write_checkpoint(sbi, &cpc);
+ f2fs_write_checkpoint(sbi, &cpc);
}
/* be sure to wait for any on-going discard commands */
@@ -1013,17 +1012,17 @@
struct cp_control cpc = {
.reason = CP_UMOUNT | CP_TRIMMED,
};
- write_checkpoint(sbi, &cpc);
+ f2fs_write_checkpoint(sbi, &cpc);
}
- /* write_checkpoint can update stat informaion */
+ /* f2fs_write_checkpoint can update stat informaion */
f2fs_destroy_stats(sbi);
/*
* normally superblock is clean, so we need to release this.
* In addition, EIO will skip do checkpoint, we need this as well.
*/
- release_ino_entry(sbi, true);
+ f2fs_release_ino_entry(sbi, true);
f2fs_leave_shrinker(sbi);
mutex_unlock(&sbi->umount_mutex);
@@ -1035,8 +1034,8 @@
iput(sbi->meta_inode);
/* destroy f2fs internal modules */
- destroy_node_manager(sbi);
- destroy_segment_manager(sbi);
+ f2fs_destroy_node_manager(sbi);
+ f2fs_destroy_segment_manager(sbi);
kfree(sbi->ckpt);
@@ -1078,7 +1077,7 @@
cpc.reason = __get_cp_reason(sbi);
mutex_lock(&sbi->gc_mutex);
- err = write_checkpoint(sbi, &cpc);
+ err = f2fs_write_checkpoint(sbi, &cpc);
mutex_unlock(&sbi->gc_mutex);
}
f2fs_trace_ios(NULL, 1);
@@ -1483,11 +1482,11 @@
*/
if ((*flags & MS_RDONLY) || !test_opt(sbi, BG_GC)) {
if (sbi->gc_thread) {
- stop_gc_thread(sbi);
+ f2fs_stop_gc_thread(sbi);
need_restart_gc = true;
}
} else if (!sbi->gc_thread) {
- err = start_gc_thread(sbi);
+ err = f2fs_start_gc_thread(sbi);
if (err)
goto restore_opts;
need_stop_gc = true;
@@ -1510,9 +1509,9 @@
*/
if ((*flags & MS_RDONLY) || !test_opt(sbi, FLUSH_MERGE)) {
clear_opt(sbi, FLUSH_MERGE);
- destroy_flush_cmd_control(sbi, false);
+ f2fs_destroy_flush_cmd_control(sbi, false);
} else {
- err = create_flush_cmd_control(sbi);
+ err = f2fs_create_flush_cmd_control(sbi);
if (err)
goto restore_gc;
}
@@ -1530,11 +1529,11 @@
return 0;
restore_gc:
if (need_restart_gc) {
- if (start_gc_thread(sbi))
+ if (f2fs_start_gc_thread(sbi))
f2fs_msg(sbi->sb, KERN_WARNING,
"background gc thread has stopped");
} else if (need_stop_gc) {
- stop_gc_thread(sbi);
+ f2fs_stop_gc_thread(sbi);
}
restore_opts:
#ifdef CONFIG_QUOTA
@@ -1806,7 +1805,7 @@
inode = d_inode(path->dentry);
inode_lock(inode);
- F2FS_I(inode)->i_flags |= FS_NOATIME_FL | FS_IMMUTABLE_FL;
+ F2FS_I(inode)->i_flags |= F2FS_NOATIME_FL | F2FS_IMMUTABLE_FL;
inode_set_flags(inode, S_NOATIME | S_IMMUTABLE,
S_NOATIME | S_IMMUTABLE);
inode_unlock(inode);
@@ -1830,7 +1829,7 @@
goto out_put;
inode_lock(inode);
- F2FS_I(inode)->i_flags &= ~(FS_NOATIME_FL | FS_IMMUTABLE_FL);
+ F2FS_I(inode)->i_flags &= ~(F2FS_NOATIME_FL | F2FS_IMMUTABLE_FL);
inode_set_flags(inode, 0, S_NOATIME | S_IMMUTABLE);
inode_unlock(inode);
f2fs_mark_inode_dirty_sync(inode, false);
@@ -1936,19 +1935,13 @@
return DUMMY_ENCRYPTION_ENABLED(F2FS_I_SB(inode));
}
-static unsigned f2fs_max_namelen(struct inode *inode)
-{
- return S_ISLNK(inode->i_mode) ?
- inode->i_sb->s_blocksize : F2FS_NAME_LEN;
-}
-
static const struct fscrypt_operations f2fs_cryptops = {
.key_prefix = "f2fs:",
.get_context = f2fs_get_context,
.set_context = f2fs_set_context,
.dummy_context = f2fs_dummy_context,
.empty_dir = f2fs_empty_dir,
- .max_namelen = f2fs_max_namelen,
+ .max_namelen = F2FS_NAME_LEN,
};
#endif
@@ -1958,7 +1951,7 @@
struct f2fs_sb_info *sbi = F2FS_SB(sb);
struct inode *inode;
- if (check_nid_range(sbi, ino))
+ if (f2fs_check_nid_range(sbi, ino))
return ERR_PTR(-ESTALE);
/*
@@ -2141,6 +2134,8 @@
static int sanity_check_raw_super(struct f2fs_sb_info *sbi,
struct buffer_head *bh)
{
+ block_t segment_count, segs_per_sec, secs_per_zone;
+ block_t total_sections, blocks_per_seg;
struct f2fs_super_block *raw_super = (struct f2fs_super_block *)
(bh->b_data + F2FS_SUPER_OFFSET);
struct super_block *sb = sbi->sb;
@@ -2197,6 +2192,72 @@
return 1;
}
+ segment_count = le32_to_cpu(raw_super->segment_count);
+ segs_per_sec = le32_to_cpu(raw_super->segs_per_sec);
+ secs_per_zone = le32_to_cpu(raw_super->secs_per_zone);
+ total_sections = le32_to_cpu(raw_super->section_count);
+
+ /* blocks_per_seg should be 512, given the above check */
+ blocks_per_seg = 1 << le32_to_cpu(raw_super->log_blocks_per_seg);
+
+ if (segment_count > F2FS_MAX_SEGMENT ||
+ segment_count < F2FS_MIN_SEGMENTS) {
+ f2fs_msg(sb, KERN_INFO,
+ "Invalid segment count (%u)",
+ segment_count);
+ return 1;
+ }
+
+ if (total_sections > segment_count ||
+ total_sections < F2FS_MIN_SEGMENTS ||
+ segs_per_sec > segment_count || !segs_per_sec) {
+ f2fs_msg(sb, KERN_INFO,
+ "Invalid segment/section count (%u, %u x %u)",
+ segment_count, total_sections, segs_per_sec);
+ return 1;
+ }
+
+ if ((segment_count / segs_per_sec) < total_sections) {
+ f2fs_msg(sb, KERN_INFO,
+ "Small segment_count (%u < %u * %u)",
+ segment_count, segs_per_sec, total_sections);
+ return 1;
+ }
+
+ if (segment_count > (le32_to_cpu(raw_super->block_count) >> 9)) {
+ f2fs_msg(sb, KERN_INFO,
+ "Wrong segment_count / block_count (%u > %u)",
+ segment_count, le32_to_cpu(raw_super->block_count));
+ return 1;
+ }
+
+ if (secs_per_zone > total_sections) {
+ f2fs_msg(sb, KERN_INFO,
+ "Wrong secs_per_zone (%u > %u)",
+ secs_per_zone, total_sections);
+ return 1;
+ }
+ if (le32_to_cpu(raw_super->extension_count) > F2FS_MAX_EXTENSION ||
+ raw_super->hot_ext_count > F2FS_MAX_EXTENSION ||
+ (le32_to_cpu(raw_super->extension_count) +
+ raw_super->hot_ext_count) > F2FS_MAX_EXTENSION) {
+ f2fs_msg(sb, KERN_INFO,
+ "Corrupted extension count (%u + %u > %u)",
+ le32_to_cpu(raw_super->extension_count),
+ raw_super->hot_ext_count,
+ F2FS_MAX_EXTENSION);
+ return 1;
+ }
+
+ if (le32_to_cpu(raw_super->cp_payload) >
+ (blocks_per_seg - F2FS_CP_PACKS)) {
+ f2fs_msg(sb, KERN_INFO,
+ "Insane cp_payload (%u > %u)",
+ le32_to_cpu(raw_super->cp_payload),
+ blocks_per_seg - F2FS_CP_PACKS);
+ return 1;
+ }
+
/* check reserved ino info */
if (le32_to_cpu(raw_super->node_ino) != 1 ||
le32_to_cpu(raw_super->meta_ino) != 2 ||
@@ -2209,13 +2270,6 @@
return 1;
}
- if (le32_to_cpu(raw_super->segment_count) > F2FS_MAX_SEGMENT) {
- f2fs_msg(sb, KERN_INFO,
- "Invalid segment count (%u)",
- le32_to_cpu(raw_super->segment_count));
- return 1;
- }
-
/* check CP/SIT/NAT/SSA/MAIN_AREA area boundary */
if (sanity_check_area_boundary(sbi, bh))
return 1;
@@ -2223,7 +2277,7 @@
return 0;
}
-int sanity_check_ckpt(struct f2fs_sb_info *sbi)
+int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi)
{
unsigned int total, fsmeta;
struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
@@ -2304,13 +2358,15 @@
for (i = 0; i < NR_COUNT_TYPE; i++)
atomic_set(&sbi->nr_pages[i], 0);
- atomic_set(&sbi->wb_sync_req, 0);
+ for (i = 0; i < META; i++)
+ atomic_set(&sbi->wb_sync_req[i], 0);
INIT_LIST_HEAD(&sbi->s_list);
mutex_init(&sbi->umount_mutex);
for (i = 0; i < NR_PAGE_TYPE - 1; i++)
for (j = HOT; j < NR_TEMP_TYPE; j++)
mutex_init(&sbi->wio_mutex[i][j]);
+ init_rwsem(&sbi->io_order_lock);
spin_lock_init(&sbi->cp_lock);
sbi->dirty_device = 0;
@@ -2365,8 +2421,10 @@
#define F2FS_REPORT_NR_ZONES 4096
- zones = f2fs_kzalloc(sbi, sizeof(struct blk_zone) *
- F2FS_REPORT_NR_ZONES, GFP_KERNEL);
+ zones = f2fs_kzalloc(sbi,
+ array_size(F2FS_REPORT_NR_ZONES,
+ sizeof(struct blk_zone)),
+ GFP_KERNEL);
if (!zones)
return -ENOMEM;
@@ -2510,8 +2568,10 @@
* Initialize multiple devices information, or single
* zoned block device information.
*/
- sbi->devs = f2fs_kzalloc(sbi, sizeof(struct f2fs_dev_info) *
- max_devices, GFP_KERNEL);
+ sbi->devs = f2fs_kzalloc(sbi,
+ array_size(max_devices,
+ sizeof(struct f2fs_dev_info)),
+ GFP_KERNEL);
if (!sbi->devs)
return -ENOMEM;
@@ -2734,9 +2794,11 @@
int n = (i == META) ? 1: NR_TEMP_TYPE;
int j;
- sbi->write_io[i] = f2fs_kmalloc(sbi,
- n * sizeof(struct f2fs_bio_info),
- GFP_KERNEL);
+ sbi->write_io[i] =
+ f2fs_kmalloc(sbi,
+ array_size(n,
+ sizeof(struct f2fs_bio_info)),
+ GFP_KERNEL);
if (!sbi->write_io[i]) {
err = -ENOMEM;
goto free_options;
@@ -2776,7 +2838,7 @@
goto free_io_dummy;
}
- err = get_valid_checkpoint(sbi);
+ err = f2fs_get_valid_checkpoint(sbi);
if (err) {
f2fs_msg(sb, KERN_ERR, "Failed to get valid F2FS checkpoint");
goto free_meta_inode;
@@ -2806,18 +2868,18 @@
spin_lock_init(&sbi->inode_lock[i]);
}
- init_extent_cache_info(sbi);
+ f2fs_init_extent_cache_info(sbi);
- init_ino_entry_info(sbi);
+ f2fs_init_ino_entry_info(sbi);
/* setup f2fs internal modules */
- err = build_segment_manager(sbi);
+ err = f2fs_build_segment_manager(sbi);
if (err) {
f2fs_msg(sb, KERN_ERR,
"Failed to initialize F2FS segment manager");
goto free_sm;
}
- err = build_node_manager(sbi);
+ err = f2fs_build_node_manager(sbi);
if (err) {
f2fs_msg(sb, KERN_ERR,
"Failed to initialize F2FS node manager");
@@ -2835,7 +2897,7 @@
sbi->kbytes_written =
le64_to_cpu(seg_i->journal->info.kbytes_written);
- build_gc_manager(sbi);
+ f2fs_build_gc_manager(sbi);
/* get an inode for node space */
sbi->node_inode = f2fs_iget(sb, F2FS_NODE_INO(sbi));
@@ -2887,7 +2949,7 @@
}
#endif
/* if there are nt orphan nodes free them */
- err = recover_orphan_inodes(sbi);
+ err = f2fs_recover_orphan_inodes(sbi);
if (err)
goto free_meta;
@@ -2909,7 +2971,7 @@
if (!retry)
goto skip_recovery;
- err = recover_fsync_data(sbi, false);
+ err = f2fs_recover_fsync_data(sbi, false);
if (err < 0) {
need_fsck = true;
f2fs_msg(sb, KERN_ERR,
@@ -2917,7 +2979,7 @@
goto free_meta;
}
} else {
- err = recover_fsync_data(sbi, true);
+ err = f2fs_recover_fsync_data(sbi, true);
if (!f2fs_readonly(sb) && err > 0) {
err = -EINVAL;
@@ -2927,7 +2989,7 @@
}
}
skip_recovery:
- /* recover_fsync_data() cleared this already */
+ /* f2fs_recover_fsync_data() cleared this already */
clear_sbi_flag(sbi, SBI_POR_DOING);
/*
@@ -2936,7 +2998,7 @@
*/
if (test_opt(sbi, BG_GC) && !f2fs_readonly(sb)) {
/* After POR, we can run background GC thread.*/
- err = start_gc_thread(sbi);
+ err = f2fs_start_gc_thread(sbi);
if (err)
goto free_meta;
}
@@ -2967,10 +3029,10 @@
#endif
f2fs_sync_inode_meta(sbi);
/*
- * Some dirty meta pages can be produced by recover_orphan_inodes()
+ * Some dirty meta pages can be produced by f2fs_recover_orphan_inodes()
* failed by EIO. Then, iput(node_inode) can trigger balance_fs_bg()
- * followed by write_checkpoint() through f2fs_write_node_pages(), which
- * falls into an infinite loop in sync_meta_pages().
+ * followed by f2fs_write_checkpoint() through f2fs_write_node_pages(), which
+ * falls into an infinite loop in f2fs_sync_meta_pages().
*/
truncate_inode_pages_final(META_MAPPING(sbi));
#ifdef CONFIG_QUOTA
@@ -2983,13 +3045,13 @@
free_stats:
f2fs_destroy_stats(sbi);
free_node_inode:
- release_ino_entry(sbi, true);
+ f2fs_release_ino_entry(sbi, true);
truncate_inode_pages_final(NODE_MAPPING(sbi));
iput(sbi->node_inode);
free_nm:
- destroy_node_manager(sbi);
+ f2fs_destroy_node_manager(sbi);
free_sm:
- destroy_segment_manager(sbi);
+ f2fs_destroy_segment_manager(sbi);
free_devices:
destroy_device_list(sbi);
kfree(sbi->ckpt);
@@ -3035,8 +3097,8 @@
{
if (sb->s_root) {
set_sbi_flag(F2FS_SB(sb), SBI_IS_CLOSE);
- stop_gc_thread(F2FS_SB(sb));
- stop_discard_thread(F2FS_SB(sb));
+ f2fs_stop_gc_thread(F2FS_SB(sb));
+ f2fs_stop_discard_thread(F2FS_SB(sb));
}
kill_block_super(sb);
}
@@ -3074,21 +3136,27 @@
{
int err;
+ if (PAGE_SIZE != F2FS_BLKSIZE) {
+ printk("F2FS not supported on PAGE_SIZE(%lu) != %d\n",
+ PAGE_SIZE, F2FS_BLKSIZE);
+ return -EINVAL;
+ }
+
f2fs_build_trace_ios();
err = init_inodecache();
if (err)
goto fail;
- err = create_node_manager_caches();
+ err = f2fs_create_node_manager_caches();
if (err)
goto free_inodecache;
- err = create_segment_manager_caches();
+ err = f2fs_create_segment_manager_caches();
if (err)
goto free_node_manager_caches;
- err = create_checkpoint_caches();
+ err = f2fs_create_checkpoint_caches();
if (err)
goto free_segment_manager_caches;
- err = create_extent_cache();
+ err = f2fs_create_extent_cache();
if (err)
goto free_checkpoint_caches;
err = f2fs_init_sysfs();
@@ -3117,13 +3185,13 @@
free_sysfs:
f2fs_exit_sysfs();
free_extent_cache:
- destroy_extent_cache();
+ f2fs_destroy_extent_cache();
free_checkpoint_caches:
- destroy_checkpoint_caches();
+ f2fs_destroy_checkpoint_caches();
free_segment_manager_caches:
- destroy_segment_manager_caches();
+ f2fs_destroy_segment_manager_caches();
free_node_manager_caches:
- destroy_node_manager_caches();
+ f2fs_destroy_node_manager_caches();
free_inodecache:
destroy_inodecache();
fail:
@@ -3137,10 +3205,10 @@
unregister_filesystem(&f2fs_fs_type);
unregister_shrinker(&f2fs_shrinker_info);
f2fs_exit_sysfs();
- destroy_extent_cache();
- destroy_checkpoint_caches();
- destroy_segment_manager_caches();
- destroy_node_manager_caches();
+ f2fs_destroy_extent_cache();
+ f2fs_destroy_checkpoint_caches();
+ f2fs_destroy_segment_manager_caches();
+ f2fs_destroy_node_manager_caches();
destroy_inodecache();
f2fs_destroy_trace_ios();
}
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 26cb855..e1b1b31 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -147,13 +147,13 @@
int len = 0, i;
len += snprintf(buf + len, PAGE_SIZE - len,
- "cold file extenstion:\n");
+ "cold file extension:\n");
for (i = 0; i < cold_count; i++)
len += snprintf(buf + len, PAGE_SIZE - len, "%s\n",
extlist[i]);
len += snprintf(buf + len, PAGE_SIZE - len,
- "hot file extenstion:\n");
+ "hot file extension:\n");
for (i = cold_count; i < cold_count + hot_count; i++)
len += snprintf(buf + len, PAGE_SIZE - len, "%s\n",
extlist[i]);
@@ -165,7 +165,7 @@
return snprintf(buf, PAGE_SIZE, "%u\n", *ui);
}
-static ssize_t f2fs_sbi_store(struct f2fs_attr *a,
+static ssize_t __sbi_store(struct f2fs_attr *a,
struct f2fs_sb_info *sbi,
const char *buf, size_t count)
{
@@ -201,13 +201,13 @@
down_write(&sbi->sb_lock);
- ret = update_extension_list(sbi, name, hot, set);
+ ret = f2fs_update_extension_list(sbi, name, hot, set);
if (ret)
goto out;
ret = f2fs_commit_super(sbi, false);
if (ret)
- update_extension_list(sbi, name, hot, !set);
+ f2fs_update_extension_list(sbi, name, hot, !set);
out:
up_write(&sbi->sb_lock);
return ret ? ret : count;
@@ -248,19 +248,53 @@
if (!strcmp(a->attr.name, "trim_sections"))
return -EINVAL;
+ if (!strcmp(a->attr.name, "gc_urgent")) {
+ if (t >= 1) {
+ sbi->gc_mode = GC_URGENT;
+ if (sbi->gc_thread) {
+ wake_up_interruptible_all(
+ &sbi->gc_thread->gc_wait_queue_head);
+ wake_up_discard_thread(sbi, true);
+ }
+ } else {
+ sbi->gc_mode = GC_NORMAL;
+ }
+ return count;
+ }
+ if (!strcmp(a->attr.name, "gc_idle")) {
+ if (t == GC_IDLE_CB)
+ sbi->gc_mode = GC_IDLE_CB;
+ else if (t == GC_IDLE_GREEDY)
+ sbi->gc_mode = GC_IDLE_GREEDY;
+ else
+ sbi->gc_mode = GC_NORMAL;
+ return count;
+ }
+
*ui = t;
if (!strcmp(a->attr.name, "iostat_enable") && *ui == 0)
f2fs_reset_iostat(sbi);
- if (!strcmp(a->attr.name, "gc_urgent") && t == 1 && sbi->gc_thread) {
- sbi->gc_thread->gc_wake = 1;
- wake_up_interruptible_all(&sbi->gc_thread->gc_wait_queue_head);
- wake_up_discard_thread(sbi, true);
- }
-
return count;
}
+static ssize_t f2fs_sbi_store(struct f2fs_attr *a,
+ struct f2fs_sb_info *sbi,
+ const char *buf, size_t count)
+{
+ ssize_t ret;
+ bool gc_entry = (!strcmp(a->attr.name, "gc_urgent") ||
+ a->struct_type == GC_THREAD);
+
+ if (gc_entry)
+ down_read(&sbi->sb->s_umount);
+ ret = __sbi_store(a, sbi, buf, count);
+ if (gc_entry)
+ up_read(&sbi->sb->s_umount);
+
+ return ret;
+}
+
static ssize_t f2fs_attr_show(struct kobject *kobj,
struct attribute *attr, char *buf)
{
@@ -349,8 +383,8 @@
F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_min_sleep_time, min_sleep_time);
F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_max_sleep_time, max_sleep_time);
F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time);
-F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_idle, gc_idle);
-F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_urgent, gc_urgent);
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_idle, gc_mode);
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_urgent, gc_mode);
F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments);
F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, max_small_discards, max_discards);
F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, discard_granularity, discard_granularity);
diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c
index ae2dfa7..7082718 100644
--- a/fs/f2fs/xattr.c
+++ b/fs/f2fs/xattr.c
@@ -252,7 +252,7 @@
if (ipage) {
inline_addr = inline_xattr_addr(inode, ipage);
} else {
- page = get_node_page(sbi, inode->i_ino);
+ page = f2fs_get_node_page(sbi, inode->i_ino);
if (IS_ERR(page))
return PTR_ERR(page);
@@ -273,7 +273,7 @@
void *xattr_addr;
/* The inode already has an extended attribute block. */
- xpage = get_node_page(sbi, xnid);
+ xpage = f2fs_get_node_page(sbi, xnid);
if (IS_ERR(xpage))
return PTR_ERR(xpage);
@@ -397,7 +397,7 @@
int err = 0;
if (hsize > inline_size && !F2FS_I(inode)->i_xattr_nid)
- if (!alloc_nid(sbi, &new_nid))
+ if (!f2fs_alloc_nid(sbi, &new_nid))
return -ENOSPC;
/* write to inline xattr */
@@ -405,9 +405,9 @@
if (ipage) {
inline_addr = inline_xattr_addr(inode, ipage);
} else {
- in_page = get_node_page(sbi, inode->i_ino);
+ in_page = f2fs_get_node_page(sbi, inode->i_ino);
if (IS_ERR(in_page)) {
- alloc_nid_failed(sbi, new_nid);
+ f2fs_alloc_nid_failed(sbi, new_nid);
return PTR_ERR(in_page);
}
inline_addr = inline_xattr_addr(inode, in_page);
@@ -417,8 +417,8 @@
NODE, true);
/* no need to use xattr node block */
if (hsize <= inline_size) {
- err = truncate_xattr_node(inode);
- alloc_nid_failed(sbi, new_nid);
+ err = f2fs_truncate_xattr_node(inode);
+ f2fs_alloc_nid_failed(sbi, new_nid);
if (err) {
f2fs_put_page(in_page, 1);
return err;
@@ -431,10 +431,10 @@
/* write to xattr node block */
if (F2FS_I(inode)->i_xattr_nid) {
- xpage = get_node_page(sbi, F2FS_I(inode)->i_xattr_nid);
+ xpage = f2fs_get_node_page(sbi, F2FS_I(inode)->i_xattr_nid);
if (IS_ERR(xpage)) {
err = PTR_ERR(xpage);
- alloc_nid_failed(sbi, new_nid);
+ f2fs_alloc_nid_failed(sbi, new_nid);
goto in_page_out;
}
f2fs_bug_on(sbi, new_nid);
@@ -442,13 +442,13 @@
} else {
struct dnode_of_data dn;
set_new_dnode(&dn, inode, NULL, NULL, new_nid);
- xpage = new_node_page(&dn, XATTR_NODE_OFFSET);
+ xpage = f2fs_new_node_page(&dn, XATTR_NODE_OFFSET);
if (IS_ERR(xpage)) {
err = PTR_ERR(xpage);
- alloc_nid_failed(sbi, new_nid);
+ f2fs_alloc_nid_failed(sbi, new_nid);
goto in_page_out;
}
- alloc_nid_done(sbi, new_nid);
+ f2fs_alloc_nid_done(sbi, new_nid);
}
xattr_addr = page_address(xpage);
@@ -693,7 +693,7 @@
if (err)
return err;
- /* this case is only from init_inode_metadata */
+ /* this case is only from f2fs_init_inode_metadata */
if (ipage)
return __f2fs_setxattr(inode, index, name, value,
size, ipage, flags);
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 0b6ba8c..eea5bc2 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -696,13 +696,21 @@
brelse(bh);
}
+static void fat_reset_iocharset(struct fat_mount_options *opts)
+{
+ if (opts->iocharset != fat_default_iocharset) {
+ /* Note: opts->iocharset can be NULL here */
+ kfree(opts->iocharset);
+ opts->iocharset = fat_default_iocharset;
+ }
+}
+
static void delayed_free(struct rcu_head *p)
{
struct msdos_sb_info *sbi = container_of(p, struct msdos_sb_info, rcu);
unload_nls(sbi->nls_disk);
unload_nls(sbi->nls_io);
- if (sbi->options.iocharset != fat_default_iocharset)
- kfree(sbi->options.iocharset);
+ fat_reset_iocharset(&sbi->options);
kfree(sbi);
}
@@ -1118,7 +1126,7 @@
opts->fs_fmask = opts->fs_dmask = current_umask();
opts->allow_utime = -1;
opts->codepage = fat_default_codepage;
- opts->iocharset = fat_default_iocharset;
+ fat_reset_iocharset(opts);
if (is_vfat) {
opts->shortname = VFAT_SFN_DISPLAY_WINNT|VFAT_SFN_CREATE_WIN95;
opts->rodir = 0;
@@ -1275,8 +1283,7 @@
/* vfat specific */
case Opt_charset:
- if (opts->iocharset != fat_default_iocharset)
- kfree(opts->iocharset);
+ fat_reset_iocharset(opts);
iocharset = match_strdup(&args[0]);
if (!iocharset)
return -ENOMEM;
@@ -1867,8 +1874,7 @@
iput(fat_inode);
unload_nls(sbi->nls_io);
unload_nls(sbi->nls_disk);
- if (sbi->options.iocharset != fat_default_iocharset)
- kfree(sbi->options.iocharset);
+ fat_reset_iocharset(&sbi->options);
sb->s_fs_info = NULL;
kfree(sbi);
return error;
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
index c6c507c..0283ee0 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
@@ -268,22 +268,6 @@
for(i = 0; i < nr_pages; i++) {
struct page *page = pvec->pages[i];
- /*
- * At this point, the page may be truncated or
- * invalidated (changing page->mapping to NULL), or
- * even swizzled back from swapper_space to tmpfs file
- * mapping. However, page->index will not change
- * because we have a reference on the page.
- */
- if (page->index > end) {
- /*
- * can't be range_cyclic (1st pass) because
- * end == -1 in that case.
- */
- ret = 1;
- break;
- }
-
*done_index = page->index;
lock_page(page);
@@ -401,8 +385,8 @@
tag_pages_for_writeback(mapping, index, end);
done_index = index;
while (!done && (index <= end)) {
- nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, tag,
- min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1);
+ nr_pages = pagevec_lookup_range_tag(&pvec, mapping, &index, end,
+ tag);
if (nr_pages == 0)
break;
diff --git a/fs/inode.c b/fs/inode.c
index 3844c31..1d1a957 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -2003,8 +2003,14 @@
inode->i_uid = current_fsuid();
if (dir && dir->i_mode & S_ISGID) {
inode->i_gid = dir->i_gid;
+
+ /* Directories are special, and always inherit S_ISGID */
if (S_ISDIR(mode))
mode |= S_ISGID;
+ else if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP) &&
+ !in_group_p(inode->i_gid) &&
+ !capable_wrt_inode_uidgid(dir, CAP_FSETID))
+ mode &= ~S_ISGID;
} else
inode->i_gid = current_fsgid();
inode->i_mode = mode;
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 91e017c..cf5fdc2 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2701,7 +2701,7 @@
if (ret != 0)
goto out;
- state = nfs4_opendata_to_nfs4_state(opendata);
+ state = _nfs4_opendata_to_nfs4_state(opendata);
ret = PTR_ERR(state);
if (IS_ERR(state))
goto out;
@@ -2737,6 +2737,7 @@
nfs4_schedule_stateid_recovery(server, state);
}
out:
+ nfs4_sequence_free_slot(&opendata->o_res.seq_res);
return ret;
}
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index bdbd9e6..b16a6c0 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1536,6 +1536,8 @@
gdev->gd_maxcount = be32_to_cpup(p++);
num = be32_to_cpup(p++);
if (num) {
+ if (num > 1000)
+ goto xdr_error;
READ_BUF(4 * num);
gdev->gd_notify_types = be32_to_cpup(p++);
for (i = 1; i < num; i++) {
diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
index 2e315f9..ac1ec8f 100644
--- a/fs/nilfs2/btree.c
+++ b/fs/nilfs2/btree.c
@@ -2158,8 +2158,8 @@
pagevec_init(&pvec, 0);
- while (pagevec_lookup_tag(&pvec, btcache, &index, PAGECACHE_TAG_DIRTY,
- PAGEVEC_SIZE)) {
+ while (pagevec_lookup_tag(&pvec, btcache, &index,
+ PAGECACHE_TAG_DIRTY)) {
for (i = 0; i < pagevec_count(&pvec); i++) {
bh = head = page_buffers(pvec.pages[i]);
do {
diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
index f11a3ad..454ee52 100644
--- a/fs/nilfs2/page.c
+++ b/fs/nilfs2/page.c
@@ -257,8 +257,7 @@
pagevec_init(&pvec, 0);
repeat:
- if (!pagevec_lookup_tag(&pvec, smap, &index, PAGECACHE_TAG_DIRTY,
- PAGEVEC_SIZE))
+ if (!pagevec_lookup_tag(&pvec, smap, &index, PAGECACHE_TAG_DIRTY))
return 0;
for (i = 0; i < pagevec_count(&pvec); i++) {
@@ -377,8 +376,8 @@
pagevec_init(&pvec, 0);
- while (pagevec_lookup_tag(&pvec, mapping, &index, PAGECACHE_TAG_DIRTY,
- PAGEVEC_SIZE)) {
+ while (pagevec_lookup_tag(&pvec, mapping, &index,
+ PAGECACHE_TAG_DIRTY)) {
for (i = 0; i < pagevec_count(&pvec); i++) {
struct page *page = pvec.pages[i];
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index 36362d4..b0eb58c 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -709,18 +709,14 @@
pagevec_init(&pvec, 0);
repeat:
if (unlikely(index > last) ||
- !pagevec_lookup_tag(&pvec, mapping, &index, PAGECACHE_TAG_DIRTY,
- min_t(pgoff_t, last - index,
- PAGEVEC_SIZE - 1) + 1))
+ !pagevec_lookup_range_tag(&pvec, mapping, &index, last,
+ PAGECACHE_TAG_DIRTY))
return ndirties;
for (i = 0; i < pagevec_count(&pvec); i++) {
struct buffer_head *bh, *head;
struct page *page = pvec.pages[i];
- if (unlikely(page->index > last))
- break;
-
lock_page(page);
if (!page_has_buffers(page))
create_empty_buffers(page, i_blocksize(inode), 0);
@@ -757,8 +753,8 @@
pagevec_init(&pvec, 0);
- while (pagevec_lookup_tag(&pvec, mapping, &index, PAGECACHE_TAG_DIRTY,
- PAGEVEC_SIZE)) {
+ while (pagevec_lookup_tag(&pvec, mapping, &index,
+ PAGECACHE_TAG_DIRTY)) {
for (i = 0; i < pagevec_count(&pvec); i++) {
bh = head = page_buffers(pvec.pages[i]);
do {
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index f2961b1..c26d046 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -134,6 +134,19 @@
return err;
}
+static int ocfs2_lock_get_block(struct inode *inode, sector_t iblock,
+ struct buffer_head *bh_result, int create)
+{
+ int ret = 0;
+ struct ocfs2_inode_info *oi = OCFS2_I(inode);
+
+ down_read(&oi->ip_alloc_sem);
+ ret = ocfs2_get_block(inode, iblock, bh_result, create);
+ up_read(&oi->ip_alloc_sem);
+
+ return ret;
+}
+
int ocfs2_get_block(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create)
{
@@ -2120,7 +2133,7 @@
* called like this: dio->get_blocks(dio->inode, fs_startblk,
* fs_count, map_bh, dio->rw == WRITE);
*/
-static int ocfs2_dio_get_block(struct inode *inode, sector_t iblock,
+static int ocfs2_dio_wr_get_block(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create)
{
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
@@ -2146,12 +2159,9 @@
* while file size will be changed.
*/
if (pos + total_len <= i_size_read(inode)) {
- down_read(&oi->ip_alloc_sem);
+
/* This is the fast path for re-write. */
- ret = ocfs2_get_block(inode, iblock, bh_result, create);
-
- up_read(&oi->ip_alloc_sem);
-
+ ret = ocfs2_lock_get_block(inode, iblock, bh_result, create);
if (buffer_mapped(bh_result) &&
!buffer_new(bh_result) &&
ret == 0)
@@ -2416,9 +2426,9 @@
return 0;
if (iov_iter_rw(iter) == READ)
- get_block = ocfs2_get_block;
+ get_block = ocfs2_lock_get_block;
else
- get_block = ocfs2_dio_get_block;
+ get_block = ocfs2_dio_wr_get_block;
return __blockdev_direct_IO(iocb, inode, inode->i_sb->s_bdev,
iter, get_block,
diff --git a/fs/ocfs2/cluster/nodemanager.c b/fs/ocfs2/cluster/nodemanager.c
index b17d180..c204ac9b 100644
--- a/fs/ocfs2/cluster/nodemanager.c
+++ b/fs/ocfs2/cluster/nodemanager.c
@@ -40,6 +40,9 @@
"panic", /* O2NM_FENCE_PANIC */
};
+static inline void o2nm_lock_subsystem(void);
+static inline void o2nm_unlock_subsystem(void);
+
struct o2nm_node *o2nm_get_node_by_num(u8 node_num)
{
struct o2nm_node *node = NULL;
@@ -181,7 +184,10 @@
{
/* through the first node_set .parent
* mycluster/nodes/mynode == o2nm_cluster->o2nm_node_group->o2nm_node */
- return to_o2nm_cluster(node->nd_item.ci_parent->ci_parent);
+ if (node->nd_item.ci_parent)
+ return to_o2nm_cluster(node->nd_item.ci_parent->ci_parent);
+ else
+ return NULL;
}
enum {
@@ -194,7 +200,7 @@
size_t count)
{
struct o2nm_node *node = to_o2nm_node(item);
- struct o2nm_cluster *cluster = to_o2nm_cluster_from_node(node);
+ struct o2nm_cluster *cluster;
unsigned long tmp;
char *p = (char *)page;
int ret = 0;
@@ -214,6 +220,13 @@
!test_bit(O2NM_NODE_ATTR_PORT, &node->nd_set_attributes))
return -EINVAL; /* XXX */
+ o2nm_lock_subsystem();
+ cluster = to_o2nm_cluster_from_node(node);
+ if (!cluster) {
+ o2nm_unlock_subsystem();
+ return -EINVAL;
+ }
+
write_lock(&cluster->cl_nodes_lock);
if (cluster->cl_nodes[tmp])
ret = -EEXIST;
@@ -226,6 +239,8 @@
set_bit(tmp, cluster->cl_nodes_bitmap);
}
write_unlock(&cluster->cl_nodes_lock);
+ o2nm_unlock_subsystem();
+
if (ret)
return ret;
@@ -269,7 +284,7 @@
size_t count)
{
struct o2nm_node *node = to_o2nm_node(item);
- struct o2nm_cluster *cluster = to_o2nm_cluster_from_node(node);
+ struct o2nm_cluster *cluster;
int ret, i;
struct rb_node **p, *parent;
unsigned int octets[4];
@@ -286,6 +301,13 @@
be32_add_cpu(&ipv4_addr, octets[i] << (i * 8));
}
+ o2nm_lock_subsystem();
+ cluster = to_o2nm_cluster_from_node(node);
+ if (!cluster) {
+ o2nm_unlock_subsystem();
+ return -EINVAL;
+ }
+
ret = 0;
write_lock(&cluster->cl_nodes_lock);
if (o2nm_node_ip_tree_lookup(cluster, ipv4_addr, &p, &parent))
@@ -298,6 +320,8 @@
rb_insert_color(&node->nd_ip_node, &cluster->cl_node_ip_tree);
}
write_unlock(&cluster->cl_nodes_lock);
+ o2nm_unlock_subsystem();
+
if (ret)
return ret;
@@ -315,7 +339,7 @@
size_t count)
{
struct o2nm_node *node = to_o2nm_node(item);
- struct o2nm_cluster *cluster = to_o2nm_cluster_from_node(node);
+ struct o2nm_cluster *cluster;
unsigned long tmp;
char *p = (char *)page;
ssize_t ret;
@@ -333,17 +357,26 @@
!test_bit(O2NM_NODE_ATTR_PORT, &node->nd_set_attributes))
return -EINVAL; /* XXX */
+ o2nm_lock_subsystem();
+ cluster = to_o2nm_cluster_from_node(node);
+ if (!cluster) {
+ ret = -EINVAL;
+ goto out;
+ }
+
/* the only failure case is trying to set a new local node
* when a different one is already set */
if (tmp && tmp == cluster->cl_has_local &&
- cluster->cl_local_node != node->nd_num)
- return -EBUSY;
+ cluster->cl_local_node != node->nd_num) {
+ ret = -EBUSY;
+ goto out;
+ }
/* bring up the rx thread if we're setting the new local node. */
if (tmp && !cluster->cl_has_local) {
ret = o2net_start_listening(node);
if (ret)
- return ret;
+ goto out;
}
if (!tmp && cluster->cl_has_local &&
@@ -358,7 +391,11 @@
cluster->cl_local_node = node->nd_num;
}
- return count;
+ ret = count;
+
+out:
+ o2nm_unlock_subsystem();
+ return ret;
}
CONFIGFS_ATTR(o2nm_node_, num);
@@ -738,6 +775,16 @@
},
};
+static inline void o2nm_lock_subsystem(void)
+{
+ mutex_lock(&o2nm_cluster_group.cs_subsys.su_mutex);
+}
+
+static inline void o2nm_unlock_subsystem(void)
+{
+ mutex_unlock(&o2nm_cluster_group.cs_subsys.su_mutex);
+}
+
int o2nm_depend_item(struct config_item *item)
{
return configfs_depend_item(&o2nm_cluster_group.cs_subsys, item);
diff --git a/fs/reiserfs/prints.c b/fs/reiserfs/prints.c
index 4f3f928..92470e5 100644
--- a/fs/reiserfs/prints.c
+++ b/fs/reiserfs/prints.c
@@ -76,83 +76,99 @@
}
/* %k */
-static void sprintf_le_key(char *buf, struct reiserfs_key *key)
+static int scnprintf_le_key(char *buf, size_t size, struct reiserfs_key *key)
{
if (key)
- sprintf(buf, "[%d %d %s %s]", le32_to_cpu(key->k_dir_id),
- le32_to_cpu(key->k_objectid), le_offset(key),
- le_type(key));
+ return scnprintf(buf, size, "[%d %d %s %s]",
+ le32_to_cpu(key->k_dir_id),
+ le32_to_cpu(key->k_objectid), le_offset(key),
+ le_type(key));
else
- sprintf(buf, "[NULL]");
+ return scnprintf(buf, size, "[NULL]");
}
/* %K */
-static void sprintf_cpu_key(char *buf, struct cpu_key *key)
+static int scnprintf_cpu_key(char *buf, size_t size, struct cpu_key *key)
{
if (key)
- sprintf(buf, "[%d %d %s %s]", key->on_disk_key.k_dir_id,
- key->on_disk_key.k_objectid, reiserfs_cpu_offset(key),
- cpu_type(key));
+ return scnprintf(buf, size, "[%d %d %s %s]",
+ key->on_disk_key.k_dir_id,
+ key->on_disk_key.k_objectid,
+ reiserfs_cpu_offset(key), cpu_type(key));
else
- sprintf(buf, "[NULL]");
+ return scnprintf(buf, size, "[NULL]");
}
-static void sprintf_de_head(char *buf, struct reiserfs_de_head *deh)
+static int scnprintf_de_head(char *buf, size_t size,
+ struct reiserfs_de_head *deh)
{
if (deh)
- sprintf(buf,
- "[offset=%d dir_id=%d objectid=%d location=%d state=%04x]",
- deh_offset(deh), deh_dir_id(deh), deh_objectid(deh),
- deh_location(deh), deh_state(deh));
+ return scnprintf(buf, size,
+ "[offset=%d dir_id=%d objectid=%d location=%d state=%04x]",
+ deh_offset(deh), deh_dir_id(deh),
+ deh_objectid(deh), deh_location(deh),
+ deh_state(deh));
else
- sprintf(buf, "[NULL]");
+ return scnprintf(buf, size, "[NULL]");
}
-static void sprintf_item_head(char *buf, struct item_head *ih)
+static int scnprintf_item_head(char *buf, size_t size, struct item_head *ih)
{
if (ih) {
- strcpy(buf,
- (ih_version(ih) == KEY_FORMAT_3_6) ? "*3.6* " : "*3.5*");
- sprintf_le_key(buf + strlen(buf), &(ih->ih_key));
- sprintf(buf + strlen(buf), ", item_len %d, item_location %d, "
- "free_space(entry_count) %d",
- ih_item_len(ih), ih_location(ih), ih_free_space(ih));
+ char *p = buf;
+ char * const end = buf + size;
+
+ p += scnprintf(p, end - p, "%s",
+ (ih_version(ih) == KEY_FORMAT_3_6) ?
+ "*3.6* " : "*3.5*");
+
+ p += scnprintf_le_key(p, end - p, &ih->ih_key);
+
+ p += scnprintf(p, end - p,
+ ", item_len %d, item_location %d, free_space(entry_count) %d",
+ ih_item_len(ih), ih_location(ih),
+ ih_free_space(ih));
+ return p - buf;
} else
- sprintf(buf, "[NULL]");
+ return scnprintf(buf, size, "[NULL]");
}
-static void sprintf_direntry(char *buf, struct reiserfs_dir_entry *de)
+static int scnprintf_direntry(char *buf, size_t size,
+ struct reiserfs_dir_entry *de)
{
char name[20];
memcpy(name, de->de_name, de->de_namelen > 19 ? 19 : de->de_namelen);
name[de->de_namelen > 19 ? 19 : de->de_namelen] = 0;
- sprintf(buf, "\"%s\"==>[%d %d]", name, de->de_dir_id, de->de_objectid);
+ return scnprintf(buf, size, "\"%s\"==>[%d %d]",
+ name, de->de_dir_id, de->de_objectid);
}
-static void sprintf_block_head(char *buf, struct buffer_head *bh)
+static int scnprintf_block_head(char *buf, size_t size, struct buffer_head *bh)
{
- sprintf(buf, "level=%d, nr_items=%d, free_space=%d rdkey ",
- B_LEVEL(bh), B_NR_ITEMS(bh), B_FREE_SPACE(bh));
+ return scnprintf(buf, size,
+ "level=%d, nr_items=%d, free_space=%d rdkey ",
+ B_LEVEL(bh), B_NR_ITEMS(bh), B_FREE_SPACE(bh));
}
-static void sprintf_buffer_head(char *buf, struct buffer_head *bh)
+static int scnprintf_buffer_head(char *buf, size_t size, struct buffer_head *bh)
{
- sprintf(buf,
- "dev %pg, size %zd, blocknr %llu, count %d, state 0x%lx, page %p, (%s, %s, %s)",
- bh->b_bdev, bh->b_size,
- (unsigned long long)bh->b_blocknr, atomic_read(&(bh->b_count)),
- bh->b_state, bh->b_page,
- buffer_uptodate(bh) ? "UPTODATE" : "!UPTODATE",
- buffer_dirty(bh) ? "DIRTY" : "CLEAN",
- buffer_locked(bh) ? "LOCKED" : "UNLOCKED");
+ return scnprintf(buf, size,
+ "dev %pg, size %zd, blocknr %llu, count %d, state 0x%lx, page %p, (%s, %s, %s)",
+ bh->b_bdev, bh->b_size,
+ (unsigned long long)bh->b_blocknr,
+ atomic_read(&(bh->b_count)),
+ bh->b_state, bh->b_page,
+ buffer_uptodate(bh) ? "UPTODATE" : "!UPTODATE",
+ buffer_dirty(bh) ? "DIRTY" : "CLEAN",
+ buffer_locked(bh) ? "LOCKED" : "UNLOCKED");
}
-static void sprintf_disk_child(char *buf, struct disk_child *dc)
+static int scnprintf_disk_child(char *buf, size_t size, struct disk_child *dc)
{
- sprintf(buf, "[dc_number=%d, dc_size=%u]", dc_block_number(dc),
- dc_size(dc));
+ return scnprintf(buf, size, "[dc_number=%d, dc_size=%u]",
+ dc_block_number(dc), dc_size(dc));
}
static char *is_there_reiserfs_struct(char *fmt, int *what)
@@ -189,55 +205,60 @@
char *fmt1 = fmt_buf;
char *k;
char *p = error_buf;
+ char * const end = &error_buf[sizeof(error_buf)];
int what;
spin_lock(&error_lock);
- strcpy(fmt1, fmt);
+ if (WARN_ON(strscpy(fmt_buf, fmt, sizeof(fmt_buf)) < 0)) {
+ strscpy(error_buf, "format string too long", end - error_buf);
+ goto out_unlock;
+ }
while ((k = is_there_reiserfs_struct(fmt1, &what)) != NULL) {
*k = 0;
- p += vsprintf(p, fmt1, args);
+ p += vscnprintf(p, end - p, fmt1, args);
switch (what) {
case 'k':
- sprintf_le_key(p, va_arg(args, struct reiserfs_key *));
+ p += scnprintf_le_key(p, end - p,
+ va_arg(args, struct reiserfs_key *));
break;
case 'K':
- sprintf_cpu_key(p, va_arg(args, struct cpu_key *));
+ p += scnprintf_cpu_key(p, end - p,
+ va_arg(args, struct cpu_key *));
break;
case 'h':
- sprintf_item_head(p, va_arg(args, struct item_head *));
+ p += scnprintf_item_head(p, end - p,
+ va_arg(args, struct item_head *));
break;
case 't':
- sprintf_direntry(p,
- va_arg(args,
- struct reiserfs_dir_entry *));
+ p += scnprintf_direntry(p, end - p,
+ va_arg(args, struct reiserfs_dir_entry *));
break;
case 'y':
- sprintf_disk_child(p,
- va_arg(args, struct disk_child *));
+ p += scnprintf_disk_child(p, end - p,
+ va_arg(args, struct disk_child *));
break;
case 'z':
- sprintf_block_head(p,
- va_arg(args, struct buffer_head *));
+ p += scnprintf_block_head(p, end - p,
+ va_arg(args, struct buffer_head *));
break;
case 'b':
- sprintf_buffer_head(p,
- va_arg(args, struct buffer_head *));
+ p += scnprintf_buffer_head(p, end - p,
+ va_arg(args, struct buffer_head *));
break;
case 'a':
- sprintf_de_head(p,
- va_arg(args,
- struct reiserfs_de_head *));
+ p += scnprintf_de_head(p, end - p,
+ va_arg(args, struct reiserfs_de_head *));
break;
}
- p += strlen(p);
fmt1 = k + 2;
}
- vsprintf(p, fmt1, args);
+ p += vscnprintf(p, end - p, fmt1, args);
+out_unlock:
spin_unlock(&error_lock);
}
diff --git a/fs/sdcardfs/main.c b/fs/sdcardfs/main.c
index d5701dd..1ad7718 100644
--- a/fs/sdcardfs/main.c
+++ b/fs/sdcardfs/main.c
@@ -295,6 +295,13 @@
atomic_inc(&lower_sb->s_active);
sdcardfs_set_lower_super(sb, lower_sb);
+ sb->s_stack_depth = lower_sb->s_stack_depth + 1;
+ if (sb->s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) {
+ pr_err("sdcardfs: maximum fs stacking depth exceeded\n");
+ err = -EINVAL;
+ goto out_sput;
+ }
+
/* inherit maxbytes from lower file system */
sb->s_maxbytes = lower_sb->s_maxbytes;
diff --git a/fs/squashfs/cache.c b/fs/squashfs/cache.c
index 05e4244..9d9d4aa 100644
--- a/fs/squashfs/cache.c
+++ b/fs/squashfs/cache.c
@@ -340,6 +340,9 @@
TRACE("Entered squashfs_read_metadata [%llx:%x]\n", *block, *offset);
+ if (unlikely(length < 0))
+ return -EIO;
+
while (length) {
entry = squashfs_cache_get(sb, msblk->block_cache, *block, 0);
if (entry->error) {
diff --git a/fs/squashfs/file.c b/fs/squashfs/file.c
index bb2e77e..cd3c5c8 100644
--- a/fs/squashfs/file.c
+++ b/fs/squashfs/file.c
@@ -195,7 +195,11 @@
}
for (i = 0; i < blocks; i++) {
- int size = le32_to_cpu(blist[i]);
+ int size = squashfs_block_size(blist[i]);
+ if (size < 0) {
+ err = size;
+ goto failure;
+ }
block += SQUASHFS_COMPRESSED_SIZE_BLOCK(size);
}
n -= blocks;
@@ -368,7 +372,7 @@
sizeof(size));
if (res < 0)
return res;
- return le32_to_cpu(size);
+ return squashfs_block_size(size);
}
/* Copy data into page cache */
diff --git a/fs/squashfs/fragment.c b/fs/squashfs/fragment.c
index 0ed6edb..86ad9a4 100644
--- a/fs/squashfs/fragment.c
+++ b/fs/squashfs/fragment.c
@@ -61,9 +61,7 @@
return size;
*fragment_block = le64_to_cpu(fragment_entry.start_block);
- size = le32_to_cpu(fragment_entry.size);
-
- return size;
+ return squashfs_block_size(fragment_entry.size);
}
diff --git a/fs/squashfs/squashfs_fs.h b/fs/squashfs/squashfs_fs.h
index 506f4ba..e664863 100644
--- a/fs/squashfs/squashfs_fs.h
+++ b/fs/squashfs/squashfs_fs.h
@@ -129,6 +129,12 @@
#define SQUASHFS_COMPRESSED_BLOCK(B) (!((B) & SQUASHFS_COMPRESSED_BIT_BLOCK))
+static inline int squashfs_block_size(__le32 raw)
+{
+ u32 size = le32_to_cpu(raw);
+ return (size >> 25) ? -EIO : size;
+}
+
/*
* Inode number ops. Inodes consist of a compressed block number, and an
* uncompressed offset within that block
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 50810be..1daeacb 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -346,6 +346,7 @@
# define DP_PSR_FRAME_CAPTURE (1 << 3)
# define DP_PSR_SELECTIVE_UPDATE (1 << 4)
# define DP_PSR_IRQ_HPD_WITH_CRC_ERRORS (1 << 5)
+# define DP_PSR_ENABLE_PSR2 (1 << 6) /* eDP 1.4a */
#define DP_ADAPTER_CTRL 0x1a0
# define DP_ADAPTER_CTRL_FORCE_LOAD_SENSE (1 << 0)
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
index 43690f5..43072b1 100644
--- a/include/linux/arm-smccc.h
+++ b/include/linux/arm-smccc.h
@@ -80,6 +80,11 @@
ARM_SMCCC_SMC_32, \
0, 0x8000)
+#define ARM_SMCCC_ARCH_WORKAROUND_2 \
+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
+ ARM_SMCCC_SMC_32, \
+ 0, 0x7fff)
+
#ifndef __ASSEMBLY__
#include <linux/linkage.h>
@@ -293,5 +298,10 @@
*/
#define arm_smccc_1_1_hvc(...) __arm_smccc_1_1(SMCCC_HVC_INST, __VA_ARGS__)
+/* Return codes defined in ARM DEN 0070A */
+#define SMCCC_RET_SUCCESS 0
+#define SMCCC_RET_NOT_SUPPORTED -1
+#define SMCCC_RET_NOT_REQUIRED -2
+
#endif /*__ASSEMBLY__*/
#endif /*__LINUX_ARM_SMCCC_H*/
diff --git a/include/linux/batterydata-lib.h b/include/linux/batterydata-lib.h
index 39517f8..d4cbff4 100644
--- a/include/linux/batterydata-lib.h
+++ b/include/linux/batterydata-lib.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015, 2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -160,55 +160,55 @@
extern struct bms_battery_data QRD_4v35_2000mAh_data;
extern struct bms_battery_data qrd_4v2_1300mah_data;
-int interpolate_fcc(struct single_row_lut *fcc_temp_lut, int batt_temp);
-int interpolate_scalingfactor(struct sf_lut *sf_lut, int row_entry, int pc);
-int interpolate_scalingfactor_fcc(struct single_row_lut *fcc_sf_lut,
+int interpolate_fcc_bms(struct single_row_lut *fcc_temp_lut, int batt_temp);
+int interpolate_scalingfactor_bms(struct sf_lut *sf_lut, int row_entry, int pc);
+int interpolate_scalingfactor_fcc_bms(struct single_row_lut *fcc_sf_lut,
int cycles);
-int interpolate_pc(struct pc_temp_ocv_lut *pc_temp_ocv,
+int interpolate_pc_bms(struct pc_temp_ocv_lut *pc_temp_ocv,
int batt_temp_degc, int ocv);
-int interpolate_ocv(struct pc_temp_ocv_lut *pc_temp_ocv,
+int interpolate_ocv_bms(struct pc_temp_ocv_lut *pc_temp_ocv,
int batt_temp_degc, int pc);
-int interpolate_slope(struct pc_temp_ocv_lut *pc_temp_ocv,
+int interpolate_slope_bms(struct pc_temp_ocv_lut *pc_temp_ocv,
int batt_temp, int pc);
-int interpolate_acc(struct ibat_temp_acc_lut *ibat_acc_lut,
+int interpolate_acc_bms(struct ibat_temp_acc_lut *ibat_acc_lut,
int batt_temp, int ibat);
-int linear_interpolate(int y0, int x0, int y1, int x1, int x);
+int linear_interpolate_bms(int y0, int x0, int y1, int x1, int x);
#else
-static inline int interpolate_fcc(struct single_row_lut *fcc_temp_lut,
+static inline int interpolate_fcc_bms(struct single_row_lut *fcc_temp_lut,
int batt_temp)
{
return -EINVAL;
}
-static inline int interpolate_scalingfactor(struct sf_lut *sf_lut,
+static inline int interpolate_scalingfactor_bms(struct sf_lut *sf_lut,
int row_entry, int pc)
{
return -EINVAL;
}
-static inline int interpolate_scalingfactor_fcc(
+static inline int interpolate_scalingfactor_fcc_bms(
struct single_row_lut *fcc_sf_lut, int cycles)
{
return -EINVAL;
}
-static inline int interpolate_pc(struct pc_temp_ocv_lut *pc_temp_ocv,
+static inline int interpolate_pc_bms(struct pc_temp_ocv_lut *pc_temp_ocv,
int batt_temp_degc, int ocv)
{
return -EINVAL;
}
-static inline int interpolate_ocv(struct pc_temp_ocv_lut *pc_temp_ocv,
+static inline int interpolate_ocv_bms(struct pc_temp_ocv_lut *pc_temp_ocv,
int batt_temp_degc, int pc)
{
return -EINVAL;
}
-static inline int interpolate_slope(struct pc_temp_ocv_lut *pc_temp_ocv,
+static inline int interpolate_slope_bms(struct pc_temp_ocv_lut *pc_temp_ocv,
int batt_temp, int pc)
{
return -EINVAL;
}
-static inline int linear_interpolate(int y0, int x0, int y1, int x1, int x)
+static inline int linear_interpolate_bms(int y0, int x0, int y1, int x1, int x)
{
return -EINVAL;
}
-static inline int interpolate_acc(struct ibat_temp_acc_lut *ibat_acc_lut,
+static inline int interpolate_acc_bms(struct ibat_temp_acc_lut *ibat_acc_lut,
int batt_temp, int ibat)
{
return -EINVAL;
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 42ad6b5..a149671 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -78,6 +78,9 @@
*/
struct inode *bi_dio_inode;
#endif
+#ifdef CONFIG_DM_DEFAULT_KEY
+ int bi_crypt_skip;
+#endif
unsigned short bi_vcnt; /* how many bio_vec's */
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index a6d1bf2..8e82e33 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -65,25 +65,40 @@
#endif
/*
+ * Feature detection for gnu_inline (gnu89 extern inline semantics). Either
+ * __GNUC_STDC_INLINE__ is defined (not using gnu89 extern inline semantics,
+ * and we opt in to the gnu89 semantics), or __GNUC_STDC_INLINE__ is not
+ * defined so the gnu89 semantics are the default.
+ */
+#ifdef __GNUC_STDC_INLINE__
+# define __gnu_inline __attribute__((gnu_inline))
+#else
+# define __gnu_inline
+#endif
+
+/*
* Force always-inline if the user requests it so via the .config,
* or if gcc is too old.
* GCC does not warn about unused static inline functions for
* -Wunused-function. This turns out to avoid the need for complex #ifdef
* directives. Suppress the warning in clang as well by using "unused"
* function attribute, which is redundant but not harmful for gcc.
+ * Prefer gnu_inline, so that extern inline functions do not emit an
+ * externally visible function. This makes extern inline behave as per gnu89
+ * semantics rather than c99. This prevents multiple symbol definition errors
+ * of extern inline functions at link time.
+ * A lot of inline functions can cause havoc with function tracing.
*/
#if !defined(CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING) || \
!defined(CONFIG_OPTIMIZE_INLINING) || (__GNUC__ < 4)
-#define inline inline __attribute__((always_inline,unused)) notrace
-#define __inline__ __inline__ __attribute__((always_inline,unused)) notrace
-#define __inline __inline __attribute__((always_inline,unused)) notrace
+#define inline \
+ inline __attribute__((always_inline, unused)) notrace __gnu_inline
#else
-/* A lot of inline functions can cause havoc with function tracing */
-#define inline inline __attribute__((unused)) notrace
-#define __inline__ __inline__ __attribute__((unused)) notrace
-#define __inline __inline __attribute__((unused)) notrace
+#define inline inline __attribute__((unused)) notrace __gnu_inline
#endif
+#define __inline__ inline
+#define __inline inline
#define __always_inline inline __attribute__((always_inline))
#define noinline __attribute__((noinline))
diff --git a/include/linux/cpufreq_times.h b/include/linux/cpufreq_times.h
index 3fb3875..356a3fa 100644
--- a/include/linux/cpufreq_times.h
+++ b/include/linux/cpufreq_times.h
@@ -22,6 +22,7 @@
#ifdef CONFIG_CPU_FREQ_TIMES
void cpufreq_task_times_init(struct task_struct *p);
+void cpufreq_task_times_alloc(struct task_struct *p);
void cpufreq_task_times_exit(struct task_struct *p);
int proc_time_in_state_show(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *p);
@@ -31,6 +32,11 @@
void cpufreq_task_times_remove_uids(uid_t uid_start, uid_t uid_end);
int single_uid_time_in_state_open(struct inode *inode, struct file *file);
#else
+static inline void cpufreq_task_times_init(struct task_struct *p) {}
+static inline void cpufreq_task_times_alloc(struct task_struct *p) {}
+static inline void cpufreq_task_times_exit(struct task_struct *p) {}
+static inline void cpufreq_acct_update_power(struct task_struct *p,
+ u64 cputime) {}
static inline void cpufreq_times_create_policy(struct cpufreq_policy *policy) {}
static inline void cpufreq_times_record_transition(
struct cpufreq_freqs *freq) {}
diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h
index 8dce6fd..f17e1f2 100644
--- a/include/linux/dma-iommu.h
+++ b/include/linux/dma-iommu.h
@@ -17,6 +17,7 @@
#define __DMA_IOMMU_H
#ifdef __KERNEL__
+#include <linux/types.h>
#include <asm/errno.h>
#ifdef CONFIG_IOMMU_DMA
diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
index 1e03614..f5371c2 100644
--- a/include/linux/fscrypt.h
+++ b/include/linux/fscrypt.h
@@ -257,7 +257,9 @@
extern int fscrypt_using_hardware_encryption(const struct inode *inode);
extern void fscrypt_set_ice_dun(const struct inode *inode,
struct bio *bio, u64 dun);
-extern bool fscrypt_mergeable_bio(struct bio *bio, u64 dun, bool bio_encrypted);
+extern bool fscrypt_mergeable_bio(struct bio *bio, u64 dun, bool bio_encrypted,
+ int bi_crypt_skip);
+extern void fscrypt_set_ice_skip(struct bio *bio, int bi_crypt_skip);
#else
static inline int fscrypt_using_hardware_encryption(const struct inode *inode)
{
@@ -270,8 +272,12 @@
return;
}
+static inline void fscrypt_set_ice_skip(struct bio *bio, int bi_crypt_skip)
+{
+}
+
static inline bool fscrypt_mergeable_bio(struct bio *bio,
- u64 dun, bool bio_encrypted)
+ u64 dun, bool bio_encrypted, int bi_crypt_skip)
{
return true;
}
diff --git a/include/linux/fscrypt_notsupp.h b/include/linux/fscrypt_notsupp.h
index 172d418..5017122 100644
--- a/include/linux/fscrypt_notsupp.h
+++ b/include/linux/fscrypt_notsupp.h
@@ -67,16 +67,6 @@
return;
}
-static inline void fscrypt_set_d_op(struct dentry *dentry)
-{
- return;
-}
-
-static inline void fscrypt_set_encrypted_dentry(struct dentry *dentry)
-{
- return;
-}
-
/* policy.c */
static inline int fscrypt_ioctl_set_policy(struct file *filp,
const void __user *arg)
diff --git a/include/linux/fscrypt_supp.h b/include/linux/fscrypt_supp.h
index 1ed79ee..99b6c52 100644
--- a/include/linux/fscrypt_supp.h
+++ b/include/linux/fscrypt_supp.h
@@ -28,7 +28,7 @@
int (*set_context)(struct inode *, const void *, size_t, void *);
bool (*dummy_context)(struct inode *);
bool (*empty_dir)(struct inode *);
- unsigned (*max_namelen)(struct inode *);
+ unsigned int max_namelen;
};
struct fscrypt_ctx {
@@ -74,20 +74,6 @@
extern void fscrypt_restore_control_page(struct page *);
-extern const struct dentry_operations fscrypt_d_ops;
-
-static inline void fscrypt_set_d_op(struct dentry *dentry)
-{
- d_set_d_op(dentry, &fscrypt_d_ops);
-}
-
-static inline void fscrypt_set_encrypted_dentry(struct dentry *dentry)
-{
- spin_lock(&dentry->d_lock);
- dentry->d_flags |= DCACHE_ENCRYPTED_WITH_KEY;
- spin_unlock(&dentry->d_lock);
-}
-
/* policy.c */
extern int fscrypt_ioctl_set_policy(struct file *, const void __user *);
extern int fscrypt_ioctl_get_policy(struct file *, void __user *);
diff --git a/include/linux/iio/imu/mpu.h b/include/linux/iio/imu/mpu.h
new file mode 100644
index 0000000..4dbb86c
--- /dev/null
+++ b/include/linux/iio/imu/mpu.h
@@ -0,0 +1,124 @@
+/*
+* Copyright (C) 2012-2017 InvenSense, Inc.
+*
+* This software is licensed under the terms of the GNU General Public
+* License version 2, as published by the Free Software Foundation, and
+* may be copied, distributed, and modified under those terms.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*/
+
+#ifndef __MPU_H_
+#define __MPU_H_
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#endif
+
+enum secondary_slave_type {
+ SECONDARY_SLAVE_TYPE_NONE,
+ SECONDARY_SLAVE_TYPE_ACCEL,
+ SECONDARY_SLAVE_TYPE_COMPASS,
+ SECONDARY_SLAVE_TYPE_PRESSURE,
+ SECONDARY_SLAVE_TYPE_ALS,
+
+ SECONDARY_SLAVE_TYPE_TYPES
+};
+
+enum ext_slave_id {
+ ID_INVALID = 0,
+ GYRO_ID_MPU3050,
+ GYRO_ID_MPU6050A2,
+ GYRO_ID_MPU6050B1,
+ GYRO_ID_MPU6050B1_NO_ACCEL,
+ GYRO_ID_ITG3500,
+
+ ACCEL_ID_LIS331,
+ ACCEL_ID_LSM303DLX,
+ ACCEL_ID_LIS3DH,
+ ACCEL_ID_KXSD9,
+ ACCEL_ID_KXTF9,
+ ACCEL_ID_BMA150,
+ ACCEL_ID_BMA222,
+ ACCEL_ID_BMA250,
+ ACCEL_ID_ADXL34X,
+ ACCEL_ID_MMA8450,
+ ACCEL_ID_MMA845X,
+ ACCEL_ID_MPU6050,
+
+ COMPASS_ID_AK8963,
+ COMPASS_ID_AK8975,
+ COMPASS_ID_AK8972,
+ COMPASS_ID_AMI30X,
+ COMPASS_ID_AMI306,
+ COMPASS_ID_YAS529,
+ COMPASS_ID_YAS530,
+ COMPASS_ID_HMC5883,
+ COMPASS_ID_LSM303DLH,
+ COMPASS_ID_LSM303DLM,
+ COMPASS_ID_MMC314X,
+ COMPASS_ID_HSCDTD002B,
+ COMPASS_ID_HSCDTD004A,
+ COMPASS_ID_MLX90399,
+ COMPASS_ID_AK09911,
+ COMPASS_ID_AK09912,
+ COMPASS_ID_AK09916,
+
+ PRESSURE_ID_BMP085,
+ PRESSURE_ID_BMP280,
+
+ ALS_ID_APDS_9900,
+ ALS_ID_APDS_9930,
+ ALS_ID_TSL_2772,
+};
+
+#define INV_PROD_KEY(ver, rev) (ver * 100 + rev)
+/**
+ * struct mpu_platform_data - Platform data for the mpu driver
+ * @int_config: Bits [7:3] of the int config register.
+ * @level_shifter: 0: VLogic, 1: VDD
+ * @orientation: Orientation matrix of the gyroscope
+ * @sec_slave_type: secondary slave device type, can be compass, accel, etc
+ * @sec_slave_id: id of the secondary slave device
+ * @secondary_i2c_address: secondary device's i2c address
+ * @secondary_orientation: secondary device's orientation matrix
+ * @aux_slave_type: auxiliary slave. Another slave device type
+ * @aux_slave_id: auxiliary slave ID.
+ * @aux_i2c_addr: auxiliary device I2C address.
+ * @read_only_slave_type: read only slave type.
+ * @read_only_slave_id: read only slave device ID.
+ * @read_only_i2c_addr: read only slave device address.
+ *
+ * Contains platform specific information on how to configure the MPU3050 to
+ * work on this platform. The orientation matricies are 3x3 rotation matricies
+ * that are applied to the data to rotate from the mounting orientation to the
+ * platform orientation. The values must be one of 0, 1, or -1 and each row and
+ * column should have exactly 1 non-zero value.
+ */
+struct mpu_platform_data {
+ __u8 int_config;
+ __u8 level_shifter;
+ __s8 orientation[9];
+ enum secondary_slave_type sec_slave_type;
+ enum ext_slave_id sec_slave_id;
+ __u16 secondary_i2c_addr;
+ __s8 secondary_orientation[9];
+ enum secondary_slave_type aux_slave_type;
+ enum ext_slave_id aux_slave_id;
+ __u16 aux_i2c_addr;
+ enum secondary_slave_type read_only_slave_type;
+ enum ext_slave_id read_only_slave_id;
+ __u16 read_only_i2c_addr;
+#ifdef CONFIG_OF
+ int (*power_on)(struct mpu_platform_data *);
+ int (*power_off)(struct mpu_platform_data *);
+ struct regulator *vdd_ana;
+ struct regulator *vdd_i2c;
+#endif
+};
+
+#endif /* __MPU_H_ */
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 616eef4..df58b01 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -208,6 +208,7 @@
ATA_FLAG_SLAVE_POSS = (1 << 0), /* host supports slave dev */
/* (doesn't imply presence) */
ATA_FLAG_SATA = (1 << 1),
+ ATA_FLAG_NO_LPM = (1 << 2), /* host not happy with LPM */
ATA_FLAG_NO_LOG_PAGE = (1 << 5), /* do not issue log page read */
ATA_FLAG_NO_ATAPI = (1 << 6), /* No ATAPI support */
ATA_FLAG_PIO_DMA = (1 << 7), /* PIO cmds via DMA */
diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h
index d43ef96..3e4d4f4 100644
--- a/include/linux/mmc/sdio_ids.h
+++ b/include/linux/mmc/sdio_ids.h
@@ -34,6 +34,7 @@
#define SDIO_DEVICE_ID_BROADCOM_4335_4339 0x4335
#define SDIO_DEVICE_ID_BROADCOM_4339 0x4339
#define SDIO_DEVICE_ID_BROADCOM_43362 0xa962
+#define SDIO_DEVICE_ID_BROADCOM_43364 0xa9a4
#define SDIO_DEVICE_ID_BROADCOM_43430 0xa9a6
#define SDIO_DEVICE_ID_BROADCOM_4345 0x4345
#define SDIO_DEVICE_ID_BROADCOM_4354 0x4354
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 815d0f4..57203c7 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -178,6 +178,7 @@
NR_VMSCAN_IMMEDIATE, /* Prioritise for reclaim when writeback ends */
NR_DIRTIED, /* page dirtyings since bootup */
NR_WRITTEN, /* page writings since bootup */
+ NR_INDIRECTLY_RECLAIMABLE_BYTES, /* measured in bytes */
NR_VM_NODE_STAT_ITEMS
};
diff --git a/include/linux/msm_mhi_dev.h b/include/linux/msm_mhi_dev.h
index b96591b..00cde22 100644
--- a/include/linux/msm_mhi_dev.h
+++ b/include/linux/msm_mhi_dev.h
@@ -67,7 +67,7 @@
u32 snd_cmpl;
void *context;
size_t len;
- size_t actual_len;
+ size_t transfer_len;
uint32_t rd_offset;
struct mhi_dev_client *client;
struct list_head list;
diff --git a/include/linux/netfilter/ipset/ip_set_timeout.h b/include/linux/netfilter/ipset/ip_set_timeout.h
index 1d6a935..8793f5a 100644
--- a/include/linux/netfilter/ipset/ip_set_timeout.h
+++ b/include/linux/netfilter/ipset/ip_set_timeout.h
@@ -65,8 +65,14 @@
static inline u32
ip_set_timeout_get(unsigned long *timeout)
{
- return *timeout == IPSET_ELEM_PERMANENT ? 0 :
- jiffies_to_msecs(*timeout - jiffies)/MSEC_PER_SEC;
+ u32 t;
+
+ if (*timeout == IPSET_ELEM_PERMANENT)
+ return 0;
+
+ t = jiffies_to_msecs(*timeout - jiffies)/MSEC_PER_SEC;
+ /* Zero value in userspace means no timeout */
+ return t == 0 ? 1 : t;
}
#endif /* __KERNEL__ */
diff --git a/include/linux/overflow.h b/include/linux/overflow.h
new file mode 100644
index 0000000..8712ff7
--- /dev/null
+++ b/include/linux/overflow.h
@@ -0,0 +1,278 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+#ifndef __LINUX_OVERFLOW_H
+#define __LINUX_OVERFLOW_H
+
+#include <linux/compiler.h>
+
+/*
+ * In the fallback code below, we need to compute the minimum and
+ * maximum values representable in a given type. These macros may also
+ * be useful elsewhere, so we provide them outside the
+ * COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW block.
+ *
+ * It would seem more obvious to do something like
+ *
+ * #define type_min(T) (T)(is_signed_type(T) ? (T)1 << (8*sizeof(T)-1) : 0)
+ * #define type_max(T) (T)(is_signed_type(T) ? ((T)1 << (8*sizeof(T)-1)) - 1 : ~(T)0)
+ *
+ * Unfortunately, the middle expressions, strictly speaking, have
+ * undefined behaviour, and at least some versions of gcc warn about
+ * the type_max expression (but not if -fsanitize=undefined is in
+ * effect; in that case, the warning is deferred to runtime...).
+ *
+ * The slightly excessive casting in type_min is to make sure the
+ * macros also produce sensible values for the exotic type _Bool. [The
+ * overflow checkers only almost work for _Bool, but that's
+ * a-feature-not-a-bug, since people shouldn't be doing arithmetic on
+ * _Bools. Besides, the gcc builtins don't allow _Bool* as third
+ * argument.]
+ *
+ * Idea stolen from
+ * https://mail-index.netbsd.org/tech-misc/2007/02/05/0000.html -
+ * credit to Christian Biere.
+ */
+#define is_signed_type(type) (((type)(-1)) < (type)1)
+#define __type_half_max(type) ((type)1 << (8*sizeof(type) - 1 - is_signed_type(type)))
+#define type_max(T) ((T)((__type_half_max(T) - 1) + __type_half_max(T)))
+#define type_min(T) ((T)((T)-type_max(T)-(T)1))
+
+
+#ifdef COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW
+/*
+ * For simplicity and code hygiene, the fallback code below insists on
+ * a, b and *d having the same type (similar to the min() and max()
+ * macros), whereas gcc's type-generic overflow checkers accept
+ * different types. Hence we don't just make check_add_overflow an
+ * alias for __builtin_add_overflow, but add type checks similar to
+ * below.
+ */
+#define check_add_overflow(a, b, d) ({ \
+ typeof(a) __a = (a); \
+ typeof(b) __b = (b); \
+ typeof(d) __d = (d); \
+ (void) (&__a == &__b); \
+ (void) (&__a == __d); \
+ __builtin_add_overflow(__a, __b, __d); \
+})
+
+#define check_sub_overflow(a, b, d) ({ \
+ typeof(a) __a = (a); \
+ typeof(b) __b = (b); \
+ typeof(d) __d = (d); \
+ (void) (&__a == &__b); \
+ (void) (&__a == __d); \
+ __builtin_sub_overflow(__a, __b, __d); \
+})
+
+#define check_mul_overflow(a, b, d) ({ \
+ typeof(a) __a = (a); \
+ typeof(b) __b = (b); \
+ typeof(d) __d = (d); \
+ (void) (&__a == &__b); \
+ (void) (&__a == __d); \
+ __builtin_mul_overflow(__a, __b, __d); \
+})
+
+#else
+
+
+/* Checking for unsigned overflow is relatively easy without causing UB. */
+#define __unsigned_add_overflow(a, b, d) ({ \
+ typeof(a) __a = (a); \
+ typeof(b) __b = (b); \
+ typeof(d) __d = (d); \
+ (void) (&__a == &__b); \
+ (void) (&__a == __d); \
+ *__d = __a + __b; \
+ *__d < __a; \
+})
+#define __unsigned_sub_overflow(a, b, d) ({ \
+ typeof(a) __a = (a); \
+ typeof(b) __b = (b); \
+ typeof(d) __d = (d); \
+ (void) (&__a == &__b); \
+ (void) (&__a == __d); \
+ *__d = __a - __b; \
+ __a < __b; \
+})
+/*
+ * If one of a or b is a compile-time constant, this avoids a division.
+ */
+#define __unsigned_mul_overflow(a, b, d) ({ \
+ typeof(a) __a = (a); \
+ typeof(b) __b = (b); \
+ typeof(d) __d = (d); \
+ (void) (&__a == &__b); \
+ (void) (&__a == __d); \
+ *__d = __a * __b; \
+ __builtin_constant_p(__b) ? \
+ __b > 0 && __a > type_max(typeof(__a)) / __b : \
+ __a > 0 && __b > type_max(typeof(__b)) / __a; \
+})
+
+/*
+ * For signed types, detecting overflow is much harder, especially if
+ * we want to avoid UB. But the interface of these macros is such that
+ * we must provide a result in *d, and in fact we must produce the
+ * result promised by gcc's builtins, which is simply the possibly
+ * wrapped-around value. Fortunately, we can just formally do the
+ * operations in the widest relevant unsigned type (u64) and then
+ * truncate the result - gcc is smart enough to generate the same code
+ * with and without the (u64) casts.
+ */
+
+/*
+ * Adding two signed integers can overflow only if they have the same
+ * sign, and overflow has happened iff the result has the opposite
+ * sign.
+ */
+#define __signed_add_overflow(a, b, d) ({ \
+ typeof(a) __a = (a); \
+ typeof(b) __b = (b); \
+ typeof(d) __d = (d); \
+ (void) (&__a == &__b); \
+ (void) (&__a == __d); \
+ *__d = (u64)__a + (u64)__b; \
+ (((~(__a ^ __b)) & (*__d ^ __a)) \
+ & type_min(typeof(__a))) != 0; \
+})
+
+/*
+ * Subtraction is similar, except that overflow can now happen only
+ * when the signs are opposite. In this case, overflow has happened if
+ * the result has the opposite sign of a.
+ */
+#define __signed_sub_overflow(a, b, d) ({ \
+ typeof(a) __a = (a); \
+ typeof(b) __b = (b); \
+ typeof(d) __d = (d); \
+ (void) (&__a == &__b); \
+ (void) (&__a == __d); \
+ *__d = (u64)__a - (u64)__b; \
+ ((((__a ^ __b)) & (*__d ^ __a)) \
+ & type_min(typeof(__a))) != 0; \
+})
+
+/*
+ * Signed multiplication is rather hard. gcc always follows C99, so
+ * division is truncated towards 0. This means that we can write the
+ * overflow check like this:
+ *
+ * (a > 0 && (b > MAX/a || b < MIN/a)) ||
+ * (a < -1 && (b > MIN/a || b < MAX/a) ||
+ * (a == -1 && b == MIN)
+ *
+ * The redundant casts of -1 are to silence an annoying -Wtype-limits
+ * (included in -Wextra) warning: When the type is u8 or u16, the
+ * __b_c_e in check_mul_overflow obviously selects
+ * __unsigned_mul_overflow, but unfortunately gcc still parses this
+ * code and warns about the limited range of __b.
+ */
+
+#define __signed_mul_overflow(a, b, d) ({ \
+ typeof(a) __a = (a); \
+ typeof(b) __b = (b); \
+ typeof(d) __d = (d); \
+ typeof(a) __tmax = type_max(typeof(a)); \
+ typeof(a) __tmin = type_min(typeof(a)); \
+ (void) (&__a == &__b); \
+ (void) (&__a == __d); \
+ *__d = (u64)__a * (u64)__b; \
+ (__b > 0 && (__a > __tmax/__b || __a < __tmin/__b)) || \
+ (__b < (typeof(__b))-1 && (__a > __tmin/__b || __a < __tmax/__b)) || \
+ (__b == (typeof(__b))-1 && __a == __tmin); \
+})
+
+
+#define check_add_overflow(a, b, d) \
+ __builtin_choose_expr(is_signed_type(typeof(a)), \
+ __signed_add_overflow(a, b, d), \
+ __unsigned_add_overflow(a, b, d))
+
+#define check_sub_overflow(a, b, d) \
+ __builtin_choose_expr(is_signed_type(typeof(a)), \
+ __signed_sub_overflow(a, b, d), \
+ __unsigned_sub_overflow(a, b, d))
+
+#define check_mul_overflow(a, b, d) \
+ __builtin_choose_expr(is_signed_type(typeof(a)), \
+ __signed_mul_overflow(a, b, d), \
+ __unsigned_mul_overflow(a, b, d))
+
+
+#endif /* COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW */
+
+/**
+ * array_size() - Calculate size of 2-dimensional array.
+ *
+ * @a: dimension one
+ * @b: dimension two
+ *
+ * Calculates size of 2-dimensional array: @a * @b.
+ *
+ * Returns: number of bytes needed to represent the array or SIZE_MAX on
+ * overflow.
+ */
+static inline __must_check size_t array_size(size_t a, size_t b)
+{
+ size_t bytes;
+
+ if (check_mul_overflow(a, b, &bytes))
+ return SIZE_MAX;
+
+ return bytes;
+}
+
+/**
+ * array3_size() - Calculate size of 3-dimensional array.
+ *
+ * @a: dimension one
+ * @b: dimension two
+ * @c: dimension three
+ *
+ * Calculates size of 3-dimensional array: @a * @b * @c.
+ *
+ * Returns: number of bytes needed to represent the array or SIZE_MAX on
+ * overflow.
+ */
+static inline __must_check size_t array3_size(size_t a, size_t b, size_t c)
+{
+ size_t bytes;
+
+ if (check_mul_overflow(a, b, &bytes))
+ return SIZE_MAX;
+ if (check_mul_overflow(bytes, c, &bytes))
+ return SIZE_MAX;
+
+ return bytes;
+}
+
+static inline __must_check size_t __ab_c_size(size_t n, size_t size, size_t c)
+{
+ size_t bytes;
+
+ if (check_mul_overflow(n, size, &bytes))
+ return SIZE_MAX;
+ if (check_add_overflow(bytes, c, &bytes))
+ return SIZE_MAX;
+
+ return bytes;
+}
+
+/**
+ * struct_size() - Calculate size of structure with trailing array.
+ * @p: Pointer to the structure.
+ * @member: Name of the array member.
+ * @n: Number of elements in the array.
+ *
+ * Calculates size of memory needed for structure @p followed by an
+ * array of @n @member elements.
+ *
+ * Return: number of bytes needed or SIZE_MAX on overflow.
+ */
+#define struct_size(p, member, n) \
+ __ab_c_size(n, \
+ sizeof(*(p)->member) + __must_be_array((p)->member),\
+ sizeof(*(p)))
+
+#endif /* __LINUX_OVERFLOW_H */
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 9dbf9c3..c890724a 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -341,8 +341,16 @@
unsigned int nr_pages, struct page **pages);
unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t start,
unsigned int nr_pages, struct page **pages);
-unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index,
- int tag, unsigned int nr_pages, struct page **pages);
+unsigned find_get_pages_range_tag(struct address_space *mapping, pgoff_t *index,
+ pgoff_t end, int tag, unsigned int nr_pages,
+ struct page **pages);
+static inline unsigned find_get_pages_tag(struct address_space *mapping,
+ pgoff_t *index, int tag, unsigned int nr_pages,
+ struct page **pages)
+{
+ return find_get_pages_range_tag(mapping, index, (pgoff_t)-1, tag,
+ nr_pages, pages);
+}
unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t start,
int tag, unsigned int nr_entries,
struct page **entries, pgoff_t *indices);
diff --git a/include/linux/pagevec.h b/include/linux/pagevec.h
index b45d391..cead441 100644
--- a/include/linux/pagevec.h
+++ b/include/linux/pagevec.h
@@ -29,9 +29,17 @@
void pagevec_remove_exceptionals(struct pagevec *pvec);
unsigned pagevec_lookup(struct pagevec *pvec, struct address_space *mapping,
pgoff_t start, unsigned nr_pages);
-unsigned pagevec_lookup_tag(struct pagevec *pvec,
- struct address_space *mapping, pgoff_t *index, int tag,
- unsigned nr_pages);
+unsigned pagevec_lookup_range_tag(struct pagevec *pvec,
+ struct address_space *mapping, pgoff_t *index, pgoff_t end,
+ int tag);
+unsigned pagevec_lookup_range_nr_tag(struct pagevec *pvec,
+ struct address_space *mapping, pgoff_t *index, pgoff_t end,
+ int tag, unsigned max_pages);
+static inline unsigned pagevec_lookup_tag(struct pagevec *pvec,
+ struct address_space *mapping, pgoff_t *index, int tag)
+{
+ return pagevec_lookup_range_tag(pvec, mapping, index, (pgoff_t)-1, tag);
+}
static inline void pagevec_init(struct pagevec *pvec, int cold)
{
diff --git a/include/linux/qpnp/qpnp-adc.h b/include/linux/qpnp/qpnp-adc.h
index 48fe2e9..770cd64 100644
--- a/include/linux/qpnp/qpnp-adc.h
+++ b/include/linux/qpnp/qpnp-adc.h
@@ -455,6 +455,7 @@
SCALE_R_ABSOLUTE,
SCALE_QRD_SKUH_RBATT_THERM,
SCALE_QRD_SKUT1_RBATT_THERM,
+ SCALE_QRD_215_RBATT_THERM,
SCALE_RSCALE_NONE,
};
@@ -1888,6 +1889,22 @@
struct qpnp_adc_tm_btm_param *param,
uint32_t *low_threshold, uint32_t *high_threshold);
/**
+ * qpnp_adc_qrd_215_btm_scaler() - Performs reverse calibration on the
+ * low/high temperature threshold values passed by the client.
+ * The function maps the temperature to voltage and applies
+ * ratiometric calibration on the voltage values for SKUT1 board.
+ * @dev: Structure device for qpnp vadc
+ * @param: The input parameters that contain the low/high temperature
+ * values.
+ * @low_threshold: The low threshold value that needs to be updated with
+ * the above calibrated voltage value.
+ * @high_threshold: The low threshold value that needs to be updated with
+ * the above calibrated voltage value.
+ */
+int32_t qpnp_adc_qrd_215_btm_scaler(struct qpnp_vadc_chip *dev,
+ struct qpnp_adc_tm_btm_param *param,
+ uint32_t *low_threshold, uint32_t *high_threshold);
+/**
* qpnp_adc_tm_scale_therm_voltage_pu2() - Performs reverse calibration
* and convert given temperature to voltage on supported
* thermistor channels using 100k pull-up.
@@ -2279,6 +2296,10 @@
struct qpnp_adc_tm_btm_param *param,
uint32_t *low_threshold, uint32_t *high_threshold)
{ return -ENXIO; }
+static inline int32_t qpnp_adc_qrd_215_btm_scaler(struct qpnp_vadc_chip *dev,
+ struct qpnp_adc_tm_btm_param *param,
+ uint32_t *low_threshold, uint32_t *high_threshold)
+{ return -ENXIO; }
static inline int32_t qpnp_adc_scale_millidegc_pmic_voltage_thr(
struct qpnp_vadc_chip *dev,
struct qpnp_adc_tm_btm_param *param,
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 6b03b08..e8d74c0 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -392,7 +392,7 @@
extern void sched_init(void);
extern void sched_init_smp(void);
extern asmlinkage void schedule_tail(struct task_struct *prev);
-extern void init_idle(struct task_struct *idle, int cpu, bool hotplug);
+extern void init_idle(struct task_struct *idle, int cpu);
extern void init_idle_bootup_task(struct task_struct *idle);
extern cpumask_var_t cpu_isolated_map;
@@ -3349,7 +3349,11 @@
{
__set_task_comm(tsk, from, false);
}
-extern char *get_task_comm(char *to, struct task_struct *tsk);
+extern char *__get_task_comm(char *to, size_t len, struct task_struct *tsk);
+#define get_task_comm(buf, tsk) ({ \
+ BUILD_BUG_ON(sizeof(buf) != TASK_COMM_LEN); \
+ __get_task_comm(buf, sizeof(buf), tsk); \
+})
#ifdef CONFIG_SMP
void scheduler_ipi(void);
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 42e3f06..c7dff69 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -345,7 +345,8 @@
};
struct earlycon_id {
- char name[16];
+ char name[15];
+ char name_term; /* In case compiler didn't '\0' term name */
char compatible[128];
int (*setup)(struct earlycon_device *, const char *options);
};
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 6b20f91..9b8e0ed 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -602,6 +602,7 @@
* @hash: the packet hash
* @queue_mapping: Queue mapping for multiqueue devices
* @xmit_more: More SKBs are pending for this queue
+ * @pfmemalloc: skbuff was allocated from PFMEMALLOC reserves
* @ndisc_nodetype: router type (from link layer)
* @ooo_okay: allow the mapping of a socket to a queue to be changed
* @l4_hash: indicate hash is a canonical 4-tuple hash over transport
@@ -692,7 +693,7 @@
peeked:1,
head_frag:1,
xmit_more:1,
- __unused:1; /* one bit hole */
+ pfmemalloc:1;
kmemcheck_bitfield_end(flags1);
/* fields enclosed in headers_start/headers_end are copied
@@ -712,19 +713,18 @@
__u8 __pkt_type_offset[0];
__u8 pkt_type:3;
- __u8 pfmemalloc:1;
__u8 ignore_df:1;
__u8 nfctinfo:3;
-
__u8 nf_trace:1;
+
__u8 ip_summed:2;
__u8 ooo_okay:1;
__u8 l4_hash:1;
__u8 sw_hash:1;
__u8 wifi_acked_valid:1;
__u8 wifi_acked:1;
-
__u8 no_fcs:1;
+
/* Indicates the inner headers are valid in the skbuff. */
__u8 encapsulation:1;
__u8 encap_hdr_csum:1;
@@ -732,11 +732,11 @@
__u8 csum_complete_sw:1;
__u8 csum_level:2;
__u8 csum_bad:1;
-
#ifdef CONFIG_IPV6_NDISC_NODETYPE
__u8 ndisc_nodetype:2;
#endif
__u8 ipvs_property:1;
+
__u8 inner_protocol_type:1;
__u8 fast_forwarded:1;
__u8 remcsum_offload:1;
diff --git a/include/linux/string.h b/include/linux/string.h
index b7e8f42..d55f6ee 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -27,7 +27,7 @@
size_t strlcpy(char *, const char *, size_t);
#endif
#ifndef __HAVE_ARCH_STRSCPY
-ssize_t __must_check strscpy(char *, const char *, size_t);
+ssize_t strscpy(char *, const char *, size_t);
#endif
#ifndef __HAVE_ARCH_STRCAT
extern char * strcat(char *, const char *);
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 2393c13..0e7f7c5 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -171,6 +171,7 @@
* @extcon_id: Used for ID notification registration.
* @vbus_nb: Notification callback for VBUS event.
* @id_nb: Notification callback for ID event.
+ * @extcon_registered: indicates if extcon notifier registered or not.
* @dpdm_desc: Regulator descriptor for D+ and D- voting.
* @dpdm_rdev: Regulator class device for dpdm regulator.
* @dbg_idx: Dynamic debug buffer Index.
@@ -297,6 +298,7 @@
struct extcon_dev *extcon_id;
struct notifier_block vbus_nb;
struct notifier_block id_nb;
+ bool extcon_registered;
struct regulator_desc dpdm_rdesc;
struct regulator_dev *dpdm_rdev;
/* Maximum debug message length */
diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h
index d999b3c..4caac13 100644
--- a/include/linux/usb/phy.h
+++ b/include/linux/usb/phy.h
@@ -22,6 +22,7 @@
#define PHY_LANE_B BIT(7)
#define PHY_HSFS_MODE BIT(8)
#define PHY_LS_MODE BIT(9)
+#define PHY_USB_DP_CONCURRENT_MODE BIT(10)
enum usb_phy_interface {
USBPHY_INTERFACE_MODE_UNKNOWN,
diff --git a/include/linux/verification.h b/include/linux/verification.h
index a10549a..5a088da 100644
--- a/include/linux/verification.h
+++ b/include/linux/verification.h
@@ -26,9 +26,13 @@
};
extern const char *const key_being_used_for[NR__KEY_BEING_USED_FOR];
-#ifdef CONFIG_SYSTEM_DATA_VERIFICATION
-
struct key;
+struct public_key_signature;
+
+extern int verify_signature_one(const struct public_key_signature *sig,
+ struct key *trusted_keys, const char *keyid);
+
+#ifdef CONFIG_SYSTEM_DATA_VERIFICATION
extern int verify_pkcs7_signature(const void *data, size_t len,
const void *raw_pkcs7, size_t pkcs7_len,
diff --git a/include/net/cnss2.h b/include/net/cnss2.h
index e95ef8b..4e86755 100644
--- a/include/net/cnss2.h
+++ b/include/net/cnss2.h
@@ -115,6 +115,11 @@
u32 addr;
};
+struct cnss_rri_over_ddr_cfg {
+ u32 base_addr_low;
+ u32 base_addr_high;
+};
+
struct cnss_wlan_enable_cfg {
u32 num_ce_tgt_cfg;
struct cnss_ce_tgt_pipe_cfg *ce_tgt_cfg;
@@ -124,6 +129,8 @@
struct cnss_shadow_reg_cfg *shadow_reg_cfg;
u32 num_shadow_reg_v2_cfg;
struct cnss_shadow_reg_v2_cfg *shadow_reg_v2_cfg;
+ bool rri_over_ddr_cfg_valid;
+ struct cnss_rri_over_ddr_cfg rri_over_ddr_cfg;
};
enum cnss_driver_mode {
@@ -174,6 +181,9 @@
extern int cnss_wlan_pm_control(struct device *dev, bool vote);
extern int cnss_auto_suspend(struct device *dev);
extern int cnss_auto_resume(struct device *dev);
+extern int cnss_pci_force_wake_request(struct device *dev);
+extern int cnss_pci_is_device_awake(struct device *dev);
+extern int cnss_pci_force_wake_release(struct device *dev);
extern int cnss_get_user_msi_assignment(struct device *dev, char *user_name,
int *num_vectors,
uint32_t *user_base_data,
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index e64210c..407087d 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -794,7 +794,7 @@
* to minimize possbility that any useful information to an
* attacker is leaked. Only lower 20 bits are relevant.
*/
- rol32(hash, 16);
+ hash = rol32(hash, 16);
flowlabel = (__force __be32)hash & IPV6_FLOWLABEL_MASK;
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 76d7c97..6f439a5 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -379,6 +379,7 @@
extern int tcp_proc_delayed_ack_control(struct ctl_table *table, int write,
void __user *buffer, size_t *length,
loff_t *ppos);
+void tcp_enter_quickack_mode(struct sock *sk);
static inline void tcp_dec_quickack_mode(struct sock *sk,
const unsigned int pkts)
{
@@ -569,6 +570,7 @@
void tcp_send_active_reset(struct sock *sk, gfp_t priority);
int tcp_send_synack(struct sock *);
void tcp_push_one(struct sock *, unsigned int mss_now);
+void __tcp_send_ack(struct sock *sk, u32 rcv_nxt);
void tcp_send_ack(struct sock *sk);
void tcp_send_delayed_ack(struct sock *sk);
void tcp_send_loss_probe(struct sock *sk);
diff --git a/include/soc/qcom/minidump.h b/include/soc/qcom/minidump.h
index 5c751e8..0d43e14 100644
--- a/include/soc/qcom/minidump.h
+++ b/include/soc/qcom/minidump.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-18 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -30,13 +30,22 @@
u64 size;
};
-/* Register an entry in Minidump table
- * Returns:
- * Zero: on successful addition
- * Negetive error number on failures
- */
#ifdef CONFIG_QCOM_MINIDUMP
+/*
+ * Register an entry in Minidump table
+ * Returns:
+ * region number: entry position in minidump table.
+ * Negetive error number on failures.
+ */
extern int msm_minidump_add_region(const struct md_region *entry);
+/*
+ * Update registered region address in Minidump table.
+ * It does not hold any locks, so strictly serialize the region updates.
+ * Returns:
+ * Zero: on successfully update
+ * Negetive error number on failures.
+ */
+extern int msm_minidump_update_region(int regno, const struct md_region *entry);
extern bool msm_minidump_enabled(void);
extern void dump_stack_minidump(u64 sp);
#else
diff --git a/include/soc/qcom/socinfo.h b/include/soc/qcom/socinfo.h
index 2eaaaa5..c7dcf36 100644
--- a/include/soc/qcom/socinfo.h
+++ b/include/soc/qcom/socinfo.h
@@ -114,14 +114,20 @@
of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,sxr1120")
#define early_machine_is_msm8953() \
of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,msm8953")
+#define early_machine_is_sdmnobelium() \
+ of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,sdm670")
#define early_machine_is_msm8937() \
of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,msm8937")
#define early_machine_is_msm8917() \
of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,msm8917")
+#define early_machine_is_msm8940() \
+ of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,msm8940")
#define early_machine_is_mdm9607() \
of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,mdm9607")
#define early_machine_is_sdm450() \
of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,sdm450")
+#define early_machine_is_sda450() \
+ of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,sda450")
#define early_machine_is_sdm632() \
of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,sdm632")
#define early_machine_is_sdm439() \
@@ -185,7 +191,9 @@
#define early_machine_is_msm8953() 0
#define early_machine_is_msm8937() 0
#define early_machine_is_msm8917() 0
+#define early_machine_is_msm8940() 0
#define early_machine_is_sdm450() 0
+#define early_machine_is_sda450() 0
#define early_machine_is_sdm632() 0
#define early_machine_is_sdm439() 0
#define early_machine_is_sdm429() 0
@@ -193,6 +201,7 @@
#define early_machine_is_sda429() 0
#define early_machine_is_mdm9650() 0
#define early_machine_is_qm215() 0
+#define early_machine_is_sdmnobelium() 0
#endif
#define PLATFORM_SUBTYPE_MDM 1
@@ -262,12 +271,15 @@
MSM_CPU_SXR1120,
MSM_CPU_8953,
MSM_CPU_SDM450,
+ MSM_CPU_SDA450,
MSM_CPU_SDM632,
MSM_CPU_SDA632,
MSM_CPU_8937,
MSM_CPU_8917,
+ MSM_CPU_8940,
MSM_CPU_9607,
MSM_CPU_SDM439,
+ MSM_CPU_SDMNOBELIUM,
MSM_CPU_SDM429,
MSM_CPU_SDA439,
MSM_CPU_SDA429,
diff --git a/include/soc/tegra/mc.h b/include/soc/tegra/mc.h
index 44202ff..f759e09 100644
--- a/include/soc/tegra/mc.h
+++ b/include/soc/tegra/mc.h
@@ -99,6 +99,8 @@
u8 client_id_mask;
const struct tegra_smmu_soc *smmu;
+
+ u32 intmask;
};
struct tegra_mc {
diff --git a/include/trace/events/kmem.h b/include/trace/events/kmem.h
index 5b8c6f8..f5b46a4 100644
--- a/include/trace/events/kmem.h
+++ b/include/trace/events/kmem.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016, 2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -336,9 +336,14 @@
const char *heap_name,
size_t len,
unsigned int mask,
- unsigned int flags),
+ unsigned int flags,
+ pid_t client_pid,
+ char *current_comm,
+ pid_t current_pid,
+ void *buffer),
- TP_ARGS(client_name, heap_name, len, mask, flags),
+ TP_ARGS(client_name, heap_name, len, mask, flags, client_pid,
+ current_comm, current_pid, buffer),
TP_STRUCT__entry(
__array(char, client_name, 64)
@@ -346,6 +351,10 @@
__field(size_t, len)
__field(unsigned int, mask)
__field(unsigned int, flags)
+ __field(pid_t, client_pid)
+ __array(char, current_comm, 16)
+ __field(pid_t, current_pid)
+ __field(void *, buffer)
),
TP_fast_assign(
@@ -354,14 +363,24 @@
__entry->len = len;
__entry->mask = mask;
__entry->flags = flags;
+ __entry->client_pid = client_pid;
+ strlcpy(__entry->current_comm, current_comm, 16);
+ __entry->current_pid = current_pid;
+ __entry->buffer = buffer;
),
- TP_printk("client_name=%s heap_name=%s len=%zu mask=0x%x flags=0x%x",
+ TP_printk("client_name=%s heap_name=%s len=%zu mask=0x%x flags=0x%x "
+ "client_pid=%d current_comm=%s current_pid=%d "
+ "buffer=%pK",
__entry->client_name,
__entry->heap_name,
__entry->len,
__entry->mask,
- __entry->flags)
+ __entry->flags,
+ __entry->client_pid,
+ __entry->current_comm,
+ __entry->current_pid,
+ __entry->buffer)
);
DEFINE_EVENT(ion_alloc, ion_alloc_buffer_start,
@@ -370,9 +389,14 @@
const char *heap_name,
size_t len,
unsigned int mask,
- unsigned int flags),
+ unsigned int flags,
+ pid_t client_pid,
+ char *current_comm,
+ pid_t current_pid,
+ void *buffer),
- TP_ARGS(client_name, heap_name, len, mask, flags)
+ TP_ARGS(client_name, heap_name, len, mask, flags, client_pid,
+ current_comm, current_pid, buffer)
);
DEFINE_EVENT(ion_alloc, ion_alloc_buffer_end,
@@ -381,9 +405,67 @@
const char *heap_name,
size_t len,
unsigned int mask,
- unsigned int flags),
+ unsigned int flags,
+ pid_t client_pid,
+ char *current_comm,
+ pid_t current_pid,
+ void *buffer),
- TP_ARGS(client_name, heap_name, len, mask, flags)
+ TP_ARGS(client_name, heap_name, len, mask, flags, client_pid,
+ current_comm, current_pid, buffer)
+);
+
+DECLARE_EVENT_CLASS(ion_free,
+
+ TP_PROTO(const char *client_name,
+ pid_t client_pid,
+ char *current_comm,
+ pid_t current_pid,
+ void *buffer,
+ size_t size),
+
+ TP_ARGS(client_name, client_pid, current_comm, current_pid,
+ buffer, size),
+
+ TP_STRUCT__entry(
+ __array(char, client_name, 64)
+ __field(pid_t, client_pid)
+ __array(char, current_comm, 16)
+ __field(pid_t, current_pid)
+ __field(void *, buffer)
+ __field(size_t, size)
+ ),
+
+ TP_fast_assign(
+ strlcpy(__entry->client_name, client_name, 64);
+ __entry->client_pid = client_pid;
+ strlcpy(__entry->current_comm, current_comm, 16);
+ __entry->current_pid = current_pid;
+ __entry->buffer = buffer;
+ __entry->size = size;
+ ),
+
+ TP_printk("client_name=%s client_pid=%d current_comm=%s "
+ "current_pid=%d buffer=%pK size=%zu",
+ __entry->client_name,
+ __entry->client_pid,
+ __entry->current_comm,
+ __entry->current_pid,
+ __entry->buffer,
+ __entry->size)
+);
+
+DEFINE_EVENT(ion_free, ion_free_buffer,
+
+ TP_PROTO(const char *client_name,
+ pid_t client_pid,
+ char *current_comm,
+ pid_t current_pid,
+ void *buffer,
+ size_t size),
+
+ TP_ARGS(client_name, client_pid, current_comm, current_pid,
+ buffer, size)
);
DECLARE_EVENT_CLASS(ion_alloc_error,
diff --git a/include/uapi/linux/msm_ipa.h b/include/uapi/linux/msm_ipa.h
index bd9836c..11d277f 100644
--- a/include/uapi/linux/msm_ipa.h
+++ b/include/uapi/linux/msm_ipa.h
@@ -100,6 +100,10 @@
#define IPA_IOCTL_GET_VLAN_MODE 58
#define IPA_IOCTL_ADD_BRIDGE_VLAN_MAPPING 59
#define IPA_IOCTL_DEL_BRIDGE_VLAN_MAPPING 60
+#define IPA_IOCTL_GSB_CONNECT 61
+#define IPA_IOCTL_GSB_DISCONNECT 62
+
+
/**
* max size of the header to be inserted
@@ -172,6 +176,7 @@
#define IPA_FLT_TCP_SYN_L2TP (1ul << 24)
#define IPA_FLT_L2TP_INNER_IP_TYPE (1ul << 25)
#define IPA_FLT_L2TP_INNER_IPV4_DST_ADDR (1ul << 26)
+#define IPA_FLT_IS_PURE_ACK (1ul << 27)
/**
* maximal number of NAT PDNs in the PDN config table
@@ -526,7 +531,14 @@
#define IPA_WLAN_FW_SSR_EVENT_MAX IPA_WLAN_FW_SSR_EVENT_MAX
};
-#define IPA_EVENT_MAX_NUM (IPA_WLAN_FW_SSR_EVENT_MAX)
+enum ipa_gsb_event {
+ IPA_GSB_CONNECT = IPA_WLAN_FW_SSR_EVENT_MAX,
+ IPA_GSB_DISCONNECT,
+ IPA_GSB_EVENT_MAX,
+#define IPA_GSB_EVENT_MAX IPA_GSB_EVENT_MAX
+};
+
+#define IPA_EVENT_MAX_NUM (IPA_GSB_EVENT_MAX)
#define IPA_EVENT_MAX ((int)IPA_EVENT_MAX_NUM)
/**
@@ -1691,6 +1703,14 @@
};
/**
+ * struct ipa_ioc_gsb_info - connect/disconnect
+ * @name: interface name
+ */
+struct ipa_ioc_gsb_info {
+ char name[IPA_RESOURCE_NAME_MAX];
+};
+
+/**
* struct ipa_msg_meta - Format of the message meta-data.
* @msg_type: the type of the message
* @rsvd: reserved bits for future use.
@@ -1826,16 +1846,20 @@
IPACM_CLIENT_MAX
};
+#define IPACM_SUPPORT_OF_LAN_STATS_FOR_ODU_CLIENTS
+
enum ipacm_per_client_device_type {
IPACM_CLIENT_DEVICE_TYPE_USB = 0,
IPACM_CLIENT_DEVICE_TYPE_WLAN = 1,
- IPACM_CLIENT_DEVICE_TYPE_ETH = 2
+ IPACM_CLIENT_DEVICE_TYPE_ETH = 2,
+ IPACM_CLIENT_DEVICE_TYPE_ODU = 3,
+ IPACM_CLIENT_DEVICE_MAX
};
/**
* max number of device types supported.
*/
-#define IPACM_MAX_CLIENT_DEVICE_TYPES 3
+#define IPACM_MAX_CLIENT_DEVICE_TYPES IPACM_CLIENT_DEVICE_MAX
/**
* @lanIface - Name of the lan interface
@@ -2102,6 +2126,14 @@
IPA_IOCTL_DEL_BRIDGE_VLAN_MAPPING, \
struct ipa_ioc_bridge_vlan_mapping_info)
+#define IPA_IOC_GSB_CONNECT _IOWR(IPA_IOC_MAGIC, \
+ IPA_IOCTL_GSB_CONNECT, \
+ struct ipa_ioc_gsb_info)
+
+#define IPA_IOC_GSB_DISCONNECT _IOWR(IPA_IOC_MAGIC, \
+ IPA_IOCTL_GSB_DISCONNECT, \
+ struct ipa_ioc_gsb_info)
+
/*
* unique magic number of the Tethering bridge ioctls
*/
diff --git a/include/uapi/linux/msm_kgsl.h b/include/uapi/linux/msm_kgsl.h
index 8ffef59..96053c6 100644
--- a/include/uapi/linux/msm_kgsl.h
+++ b/include/uapi/linux/msm_kgsl.h
@@ -65,6 +65,7 @@
#define KGSL_CONTEXT_TYPE_CL 2
#define KGSL_CONTEXT_TYPE_C2D 3
#define KGSL_CONTEXT_TYPE_RS 4
+#define KGSL_CONTEXT_TYPE_VK 5
#define KGSL_CONTEXT_TYPE_UNKNOWN 0x1E
#define KGSL_CONTEXT_INVALIDATE_ON_FAULT 0x10000000
diff --git a/include/uapi/media/cam_req_mgr.h b/include/uapi/media/cam_req_mgr.h
index 841c40a..ae65649 100644
--- a/include/uapi/media/cam_req_mgr.h
+++ b/include/uapi/media/cam_req_mgr.h
@@ -262,6 +262,9 @@
((idx & CAM_MEM_MGR_HDL_IDX_MASK) | \
(fd << (CAM_MEM_MGR_HDL_FD_END_POS - CAM_MEM_MGR_HDL_FD_SIZE))) \
+#define GET_FD_FROM_HANDLE(hdl) \
+ (hdl >> (CAM_MEM_MGR_HDL_FD_END_POS - CAM_MEM_MGR_HDL_FD_SIZE)) \
+
#define CAM_MEM_MGR_GET_HDL_IDX(hdl) (hdl & CAM_MEM_MGR_HDL_IDX_MASK)
#define CAM_MEM_MGR_SET_SECURE_HDL(hdl, flag) \
diff --git a/include/uapi/media/msmb_isp.h b/include/uapi/media/msmb_isp.h
index 74a8d93..271a731 100644
--- a/include/uapi/media/msmb_isp.h
+++ b/include/uapi/media/msmb_isp.h
@@ -26,9 +26,16 @@
#define ISP_STATS_STREAM_BIT 0x80000000
#define VFE_HW_LIMIT 1
+#define ISP_KERNEL_STATE 1
struct msm_vfe_cfg_cmd_list;
+struct isp_kstate {
+ uint32_t kernel_sofid;
+ uint32_t drop_reconfig;
+ uint32_t vfeid;
+};
+
enum ISP_START_PIXEL_PATTERN {
ISP_BAYER_RGRGRG,
ISP_BAYER_GRGRGR,
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 85d9cac..cd4f413 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -406,7 +406,7 @@
return -EINVAL;
break;
case AUDIT_EXE:
- if (f->op != Audit_equal)
+ if (f->op != Audit_not_equal && f->op != Audit_equal)
return -EINVAL;
if (entry->rule.listnr != AUDIT_FILTER_EXIT)
return -EINVAL;
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 93648f6..6039aa77 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -469,6 +469,8 @@
break;
case AUDIT_EXE:
result = audit_exe_compare(tsk, rule->exe);
+ if (f->op == Audit_not_equal)
+ result = !result;
break;
case AUDIT_UID:
result = audit_uid_comparator(cred->uid, f->op, f->uid);
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 076e4a0..dafa270 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -3225,7 +3225,7 @@
/* hold the map. If the program is rejected by verifier,
* the map will be released by release_maps() or it
* will be used by the valid program until it's unloaded
- * and all maps are released in free_bpf_prog_info()
+ * and all maps are released in free_used_maps()
*/
map = bpf_map_inc(map, false);
if (IS_ERR(map)) {
@@ -3629,7 +3629,7 @@
vfree(log_buf);
if (!env->prog->aux->used_maps)
/* if we didn't copy map pointers into bpf_prog_info, release
- * them now. Otherwise free_bpf_prog_info() will release them.
+ * them now. Otherwise free_used_maps() will release them.
*/
release_maps(env);
*prog = env->prog;
diff --git a/kernel/exit.c b/kernel/exit.c
index ee8c601..f5a7cbf 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -54,7 +54,6 @@
#include <linux/writeback.h>
#include <linux/shm.h>
#include <linux/kcov.h>
-#include <linux/cpufreq_times.h>
#include "sched/tune.h"
@@ -172,9 +171,6 @@
{
struct task_struct *leader;
int zap_leader;
-#ifdef CONFIG_CPU_FREQ_TIMES
- cpufreq_task_times_exit(p);
-#endif
repeat:
/* don't need to get the RCU readlock here - the process is dead and
* can't be modifying its own credentials. But shut RCU-lockdep up */
diff --git a/kernel/fork.c b/kernel/fork.c
index 965c091..36cf1da 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -77,6 +77,7 @@
#include <linux/compiler.h>
#include <linux/sysctl.h>
#include <linux/kcov.h>
+#include <linux/cpufreq_times.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
@@ -339,6 +340,8 @@
void free_task(struct task_struct *tsk)
{
+ cpufreq_task_times_exit(tsk);
+
#ifndef CONFIG_THREAD_INFO_IN_TASK
/*
* The task is finally done with both the stack and thread_info,
@@ -1546,6 +1549,8 @@
*/
p->clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) ? child_tidptr : NULL;
+ cpufreq_task_times_init(p);
+
ftrace_graph_init_task(p);
rt_mutex_init_task(p);
@@ -1926,7 +1931,7 @@
cpu_to_node(cpu));
if (!IS_ERR(task)) {
init_idle_pids(task->pids);
- init_idle(task, cpu, false);
+ init_idle(task, cpu);
}
return task;
@@ -1978,6 +1983,8 @@
struct completion vfork;
struct pid *pid;
+ cpufreq_task_times_alloc(p);
+
trace_sched_process_fork(current, p);
pid = get_task_pid(p, PIDTYPE_PID);
diff --git a/kernel/kcov.c b/kernel/kcov.c
index 154a80d..fad5144 100644
--- a/kernel/kcov.c
+++ b/kernel/kcov.c
@@ -240,7 +240,8 @@
void kcov_task_init(struct task_struct *t)
{
- t->kcov_mode = KCOV_MODE_DISABLED;
+ WRITE_ONCE(t->kcov_mode, KCOV_MODE_DISABLED);
+ barrier();
t->kcov_size = 0;
t->kcov_area = NULL;
t->kcov = NULL;
diff --git a/kernel/kthread.c b/kernel/kthread.c
index b65854c..981ebe9 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -290,8 +290,14 @@
task = create->result;
if (!IS_ERR(task)) {
static const struct sched_param param = { .sched_priority = 0 };
+ char name[TASK_COMM_LEN];
- vsnprintf(task->comm, sizeof(task->comm), namefmt, args);
+ /*
+ * task is already visible to other tasks, so updating
+ * COMM must be protected.
+ */
+ vsnprintf(name, sizeof(name), namefmt, args);
+ set_task_comm(task, name);
/*
* root may have changed our (kthreadd's) priority or CPU mask.
* The kernel thread should not inherit these properties.
diff --git a/kernel/locking/spinlock_debug.c b/kernel/locking/spinlock_debug.c
index e99d860..d381f55 100644
--- a/kernel/locking/spinlock_debug.c
+++ b/kernel/locking/spinlock_debug.c
@@ -174,6 +174,11 @@
printk(KERN_EMERG "BUG: rwlock %s on CPU#%d, %s/%d, %p\n",
msg, raw_smp_processor_id(), current->comm,
task_pid_nr(current), lock);
+#ifdef CONFIG_DEBUG_SPINLOCK_BITE_ON_BUG
+ msm_trigger_wdog_bite();
+#elif defined(CONFIG_DEBUG_SPINLOCK_PANIC_ON_BUG)
+ BUG();
+#endif
dump_stack();
}
diff --git a/kernel/power/user.c b/kernel/power/user.c
index 35310b6..bc6dde1 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -186,6 +186,11 @@
res = PAGE_SIZE - pg_offp;
}
+ if (!data_of(data->handle)) {
+ res = -EINVAL;
+ goto unlock;
+ }
+
res = simple_write_to_buffer(data_of(data->handle), res, &pg_offp,
buf, count);
if (res > 0)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index b755eb8..8f29103 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -2344,10 +2344,6 @@
memset(&p->se.statistics, 0, sizeof(p->se.statistics));
#endif
-#ifdef CONFIG_CPU_FREQ_TIMES
- cpufreq_task_times_init(p);
-#endif
-
RB_CLEAR_NODE(&p->dl.rb_node);
init_dl_task_timer(&p->dl);
__dl_clear_params(p);
@@ -2505,7 +2501,7 @@
unsigned long flags;
int cpu;
- init_new_task_load(p, false);
+ init_new_task_load(p);
cpu = get_cpu();
__sched_fork(clone_flags, p);
@@ -5529,21 +5525,17 @@
* init_idle - set up an idle thread for a given CPU
* @idle: task in question
* @cpu: cpu the idle task belongs to
- * @cpu_up: differentiate between initial boot vs hotplug
*
* NOTE: this function does not set the idle thread's NEED_RESCHED
* flag, to make booting more robust.
*/
-void init_idle(struct task_struct *idle, int cpu, bool cpu_up)
+void init_idle(struct task_struct *idle, int cpu)
{
struct rq *rq = cpu_rq(cpu);
unsigned long flags;
__sched_fork(0, idle);
- if (!cpu_up)
- init_new_task_load(idle, true);
-
raw_spin_lock_irqsave(&idle->pi_lock, flags);
raw_spin_lock(&rq->lock);
@@ -8368,7 +8360,8 @@
* but because we are the idle thread, we just pick up running again
* when this runqueue becomes "idle".
*/
- init_idle(current, smp_processor_id(), false);
+ init_idle(current, smp_processor_id());
+ init_new_task_load(current);
calc_load_update = jiffies + LOAD_FREQ;
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
index a7c4b4c..7cabd8c 100644
--- a/kernel/sched/cputime.c
+++ b/kernel/sched/cputime.c
@@ -166,10 +166,8 @@
/* Account for user time used */
acct_account_cputime(p);
-#ifdef CONFIG_CPU_FREQ_TIMES
/* Account power usage for user time */
cpufreq_acct_update_power(p, cputime);
-#endif
}
/*
@@ -220,10 +218,9 @@
/* Account for system time used */
acct_account_cputime(p);
-#ifdef CONFIG_CPU_FREQ_TIMES
+
/* Account power usage for system time */
cpufreq_acct_update_power(p, cputime);
-#endif
}
/*
diff --git a/kernel/sched/walt.c b/kernel/sched/walt.c
index 269f687..6144dee 100644
--- a/kernel/sched/walt.c
+++ b/kernel/sched/walt.c
@@ -2001,7 +2001,7 @@
return 0;
}
-void init_new_task_load(struct task_struct *p, bool idle_task)
+void init_new_task_load(struct task_struct *p)
{
int i;
u32 init_load_windows;
@@ -2019,9 +2019,6 @@
/* Don't have much choice. CPU frequency would be bogus */
BUG_ON(!p->ravg.curr_window_cpu || !p->ravg.prev_window_cpu);
- if (idle_task)
- return;
-
if (current->init_load_pct)
init_load_pct = current->init_load_pct;
else
diff --git a/kernel/sched/walt.h b/kernel/sched/walt.h
index cac925c..7d505c3 100644
--- a/kernel/sched/walt.h
+++ b/kernel/sched/walt.h
@@ -150,7 +150,7 @@
extern void inc_rq_walt_stats(struct rq *rq, struct task_struct *p);
extern void dec_rq_walt_stats(struct rq *rq, struct task_struct *p);
extern void fixup_busy_time(struct task_struct *p, int new_cpu);
-extern void init_new_task_load(struct task_struct *p, bool idle_task);
+extern void init_new_task_load(struct task_struct *p);
extern void mark_task_starting(struct task_struct *p);
extern void set_window_start(struct rq *rq);
void account_irqtime(int cpu, struct task_struct *curr, u64 delta,
@@ -337,7 +337,7 @@
}
static inline void fixup_busy_time(struct task_struct *p, int new_cpu) { }
-static inline void init_new_task_load(struct task_struct *p, bool idle_task)
+static inline void init_new_task_load(struct task_struct *p)
{
}
diff --git a/kernel/smpboot.c b/kernel/smpboot.c
index 653cf6d..a4719ee 100644
--- a/kernel/smpboot.c
+++ b/kernel/smpboot.c
@@ -31,7 +31,7 @@
if (!tsk)
return ERR_PTR(-ENOMEM);
- init_idle(tsk, cpu, true);
+ init_idle(tsk, cpu);
return tsk;
}
diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c
index ec9ab2f..9b8cd7e 100644
--- a/kernel/stop_machine.c
+++ b/kernel/stop_machine.c
@@ -36,7 +36,7 @@
struct cpu_stopper {
struct task_struct *thread;
- spinlock_t lock;
+ raw_spinlock_t lock;
bool enabled; /* is this stopper enabled? */
struct list_head works; /* list of pending works */
@@ -78,13 +78,13 @@
unsigned long flags;
bool enabled;
- spin_lock_irqsave(&stopper->lock, flags);
+ raw_spin_lock_irqsave(&stopper->lock, flags);
enabled = stopper->enabled;
if (enabled)
__cpu_stop_queue_work(stopper, work);
else if (work->done)
cpu_stop_signal_done(work->done);
- spin_unlock_irqrestore(&stopper->lock, flags);
+ raw_spin_unlock_irqrestore(&stopper->lock, flags);
return enabled;
}
@@ -231,8 +231,8 @@
struct cpu_stopper *stopper2 = per_cpu_ptr(&cpu_stopper, cpu2);
int err;
retry:
- spin_lock_irq(&stopper1->lock);
- spin_lock_nested(&stopper2->lock, SINGLE_DEPTH_NESTING);
+ raw_spin_lock_irq(&stopper1->lock);
+ raw_spin_lock_nested(&stopper2->lock, SINGLE_DEPTH_NESTING);
err = -ENOENT;
if (!stopper1->enabled || !stopper2->enabled)
@@ -255,8 +255,8 @@
__cpu_stop_queue_work(stopper1, work1);
__cpu_stop_queue_work(stopper2, work2);
unlock:
- spin_unlock(&stopper2->lock);
- spin_unlock_irq(&stopper1->lock);
+ raw_spin_unlock(&stopper2->lock);
+ raw_spin_unlock_irq(&stopper1->lock);
if (unlikely(err == -EDEADLK)) {
while (stop_cpus_in_progress)
@@ -448,9 +448,9 @@
unsigned long flags;
int run;
- spin_lock_irqsave(&stopper->lock, flags);
+ raw_spin_lock_irqsave(&stopper->lock, flags);
run = !list_empty(&stopper->works);
- spin_unlock_irqrestore(&stopper->lock, flags);
+ raw_spin_unlock_irqrestore(&stopper->lock, flags);
return run;
}
@@ -461,13 +461,13 @@
repeat:
work = NULL;
- spin_lock_irq(&stopper->lock);
+ raw_spin_lock_irq(&stopper->lock);
if (!list_empty(&stopper->works)) {
work = list_first_entry(&stopper->works,
struct cpu_stop_work, list);
list_del_init(&work->list);
}
- spin_unlock_irq(&stopper->lock);
+ raw_spin_unlock_irq(&stopper->lock);
if (work) {
cpu_stop_fn_t fn = work->fn;
@@ -541,7 +541,7 @@
for_each_possible_cpu(cpu) {
struct cpu_stopper *stopper = &per_cpu(cpu_stopper, cpu);
- spin_lock_init(&stopper->lock);
+ raw_spin_lock_init(&stopper->lock);
INIT_LIST_HEAD(&stopper->works);
}
diff --git a/kernel/trace/ipc_logging.c b/kernel/trace/ipc_logging.c
index 68a9ad7..36d8edb 100644
--- a/kernel/trace/ipc_logging.c
+++ b/kernel/trace/ipc_logging.c
@@ -925,6 +925,7 @@
int ipc_log_context_destroy(void *ctxt)
{
struct ipc_log_context *ilctxt = (struct ipc_log_context *)ctxt;
+ struct dfunc_info *df_info = NULL, *tmp = NULL;
unsigned long flags;
if (!ilctxt)
@@ -935,6 +936,10 @@
spin_lock(&ilctxt->context_lock_lhb1);
ilctxt->destroyed = true;
complete_all(&ilctxt->read_avail);
+ list_for_each_entry_safe(df_info, tmp, &ilctxt->dfunc_info_list, list) {
+ list_del(&df_info->list);
+ kfree(df_info);
+ }
spin_unlock(&ilctxt->context_lock_lhb1);
write_lock_irqsave(&context_list_lock_lha1, flags);
diff --git a/kernel/trace/msm_rtb.c b/kernel/trace/msm_rtb.c
index d3bcd5c..6979bf0 100644
--- a/kernel/trace/msm_rtb.c
+++ b/kernel/trace/msm_rtb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -299,7 +299,7 @@
md_entry.virt_addr = (uintptr_t)msm_rtb.rtb;
md_entry.phys_addr = msm_rtb.phys;
md_entry.size = msm_rtb.size;
- if (msm_minidump_add_region(&md_entry))
+ if (msm_minidump_add_region(&md_entry) < 0)
pr_info("Failed to add RTB in Minidump\n");
#if defined(CONFIG_QCOM_RTB_SEPARATE_CPUS)
diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c
index 88f398a..8819944 100644
--- a/kernel/trace/trace_events_trigger.c
+++ b/kernel/trace/trace_events_trigger.c
@@ -678,6 +678,8 @@
goto out_free;
out_reg:
+ /* Up the trigger_data count to make sure reg doesn't free it on failure */
+ event_trigger_init(trigger_ops, trigger_data);
ret = cmd_ops->reg(glob, trigger_ops, trigger_data, file);
/*
* The above returns on success the # of functions enabled,
@@ -685,11 +687,13 @@
* Consider no functions a failure too.
*/
if (!ret) {
+ cmd_ops->unreg(glob, trigger_ops, trigger_data, file);
ret = -ENOENT;
- goto out_free;
- } else if (ret < 0)
- goto out_free;
- ret = 0;
+ } else if (ret > 0)
+ ret = 0;
+
+ /* Down the counter of trigger_data or free it if not used anymore */
+ event_trigger_free(trigger_ops, trigger_data);
out:
return ret;
@@ -1385,6 +1389,9 @@
goto out;
}
+ /* Up the trigger_data count to make sure nothing frees it on failure */
+ event_trigger_init(trigger_ops, trigger_data);
+
if (trigger) {
number = strsep(&trigger, ":");
@@ -1435,6 +1442,7 @@
goto out_disable;
/* Just return zero, not the number of enabled functions */
ret = 0;
+ event_trigger_free(trigger_ops, trigger_data);
out:
return ret;
@@ -1445,7 +1453,7 @@
out_free:
if (cmd_ops->set_filter)
cmd_ops->set_filter(NULL, trigger_data, NULL);
- kfree(trigger_data);
+ event_trigger_free(trigger_ops, trigger_data);
kfree(enable_data);
goto out;
}
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index ea3ed03..3b4cd44 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -359,11 +359,10 @@
static int
enable_trace_kprobe(struct trace_kprobe *tk, struct trace_event_file *file)
{
+ struct event_file_link *link = NULL;
int ret = 0;
if (file) {
- struct event_file_link *link;
-
link = kmalloc(sizeof(*link), GFP_KERNEL);
if (!link) {
ret = -ENOMEM;
@@ -383,6 +382,18 @@
else
ret = enable_kprobe(&tk->rp.kp);
}
+
+ if (ret) {
+ if (file) {
+ /* Notice the if is true on not WARN() */
+ if (!WARN_ON_ONCE(!link))
+ list_del_rcu(&link->list);
+ kfree(link);
+ tk->tp.flags &= ~TP_FLAG_TRACE;
+ } else {
+ tk->tp.flags &= ~TP_FLAG_PROFILE;
+ }
+ }
out:
return ret;
}
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index 895961c..101dac0 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -783,8 +783,16 @@
static size_t rounded_hashtable_size(const struct rhashtable_params *params)
{
- return max(roundup_pow_of_two(params->nelem_hint * 4 / 3),
- (unsigned long)params->min_size);
+ size_t retsize;
+
+ if (params->nelem_hint)
+ retsize = max(roundup_pow_of_two(params->nelem_hint * 4 / 3),
+ (unsigned long)params->min_size);
+ else
+ retsize = max(HASH_DEFAULT_SIZE,
+ (unsigned long)params->min_size);
+
+ return retsize;
}
static u32 rhashtable_jhash2(const void *key, u32 length, u32 seed)
@@ -841,8 +849,6 @@
struct bucket_table *tbl;
size_t size;
- size = HASH_DEFAULT_SIZE;
-
if ((!params->key_len && !params->obj_hashfn) ||
(params->obj_hashfn && !params->obj_cmpfn))
return -EINVAL;
@@ -869,8 +875,7 @@
ht->p.min_size = max(ht->p.min_size, HASH_MIN_SIZE);
- if (params->nelem_hint)
- size = rounded_hashtable_size(&ht->p);
+ size = rounded_hashtable_size(&ht->p);
/* The maximum (not average) chain length grows with the
* size of the hash table, at a rate of (log N)/(log log N).
diff --git a/mm/filemap.c b/mm/filemap.c
index b27d2ca..4fcd8ee 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -441,19 +441,17 @@
goto out;
pagevec_init(&pvec, 0);
- while ((index <= end) &&
- (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
- PAGECACHE_TAG_WRITEBACK,
- min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1)) != 0) {
+ while (index <= end) {
unsigned i;
+ nr_pages = pagevec_lookup_range_tag(&pvec, mapping, &index,
+ end, PAGECACHE_TAG_WRITEBACK);
+ if (!nr_pages)
+ break;
+
for (i = 0; i < nr_pages; i++) {
struct page *page = pvec.pages[i];
- /* until radix tree lookup accepts end_index */
- if (page->index > end)
- continue;
-
wait_on_page_writeback(page);
if (TestClearPageError(page))
ret = -EIO;
@@ -1495,9 +1493,10 @@
EXPORT_SYMBOL(find_get_pages_contig);
/**
- * find_get_pages_tag - find and return pages that match @tag
+ * find_get_pages_range_tag - find and return pages in given range matching @tag
* @mapping: the address_space to search
* @index: the starting page index
+ * @end: The final page index (inclusive)
* @tag: the tag index
* @nr_pages: the maximum number of pages
* @pages: where the resulting pages are placed
@@ -1505,8 +1504,9 @@
* Like find_get_pages, except we only return pages which are tagged with
* @tag. We update @index to index the next page for the traversal.
*/
-unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index,
- int tag, unsigned int nr_pages, struct page **pages)
+unsigned find_get_pages_range_tag(struct address_space *mapping, pgoff_t *index,
+ pgoff_t end, int tag, unsigned int nr_pages,
+ struct page **pages)
{
struct radix_tree_iter iter;
void **slot;
@@ -1519,6 +1519,9 @@
radix_tree_for_each_tagged(slot, &mapping->page_tree,
&iter, *index, tag) {
struct page *head, *page;
+
+ if (iter.index > end)
+ break;
repeat:
page = radix_tree_deref_slot(slot);
if (unlikely(!page))
@@ -1560,18 +1563,28 @@
}
pages[ret] = page;
- if (++ret == nr_pages)
- break;
+ if (++ret == nr_pages) {
+ *index = pages[ret - 1]->index + 1;
+ goto out;
+ }
}
+ /*
+ * We come here when we got at @end. We take care to not overflow the
+ * index @index as it confuses some of the callers. This breaks the
+ * iteration when there is page at index -1 but that is already broken
+ * anyway.
+ */
+ if (end == (pgoff_t)-1)
+ *index = (pgoff_t)-1;
+ else
+ *index = end + 1;
+out:
rcu_read_unlock();
- if (ret)
- *index = pages[ret - 1]->index + 1;
-
return ret;
}
-EXPORT_SYMBOL(find_get_pages_tag);
+EXPORT_SYMBOL(find_get_pages_range_tag);
/**
* find_get_entries_tag - find and return entries that match @tag
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index a557862..b0c343f 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1642,6 +1642,8 @@
if (vma_is_dax(vma))
return;
page = pmd_page(_pmd);
+ if (!PageDirty(page) && pmd_dirty(_pmd))
+ set_page_dirty(page);
if (!PageReferenced(page) && pmd_young(_pmd))
SetPageReferenced(page);
page_remove_rmap(page, true);
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 34eec18..0929e1f 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -895,7 +895,7 @@
int nid;
int i;
- while ((memcg = parent_mem_cgroup(memcg))) {
+ for (; memcg; memcg = parent_mem_cgroup(memcg)) {
for_each_node(nid) {
mz = mem_cgroup_nodeinfo(memcg, nid);
for (i = 0; i <= DEF_PRIORITY; i++) {
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index ca18dc0..756c386 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -2185,30 +2185,14 @@
while (!done && (index <= end)) {
int i;
- nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, tag,
- min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1);
+ nr_pages = pagevec_lookup_range_tag(&pvec, mapping, &index, end,
+ tag);
if (nr_pages == 0)
break;
for (i = 0; i < nr_pages; i++) {
struct page *page = pvec.pages[i];
- /*
- * At this point, the page may be truncated or
- * invalidated (changing page->mapping to NULL), or
- * even swizzled back from swapper_space to tmpfs file
- * mapping. However, page->index will not change
- * because we have a reference on the page.
- */
- if (page->index > end) {
- /*
- * can't be range_cyclic (1st pass) because
- * end == -1 in that case.
- */
- done = 1;
- break;
- }
-
done_index = page->index;
lock_page(page);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index c9f73d6..0cbf275 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -4320,6 +4320,13 @@
available += global_page_state(NR_SLAB_RECLAIMABLE) -
min(global_page_state(NR_SLAB_RECLAIMABLE) / 2, wmark_low);
+ /*
+ * Part of the kernel memory, which can be released under memory
+ * pressure.
+ */
+ available += global_node_page_state(NR_INDIRECTLY_RECLAIMABLE_BYTES) >>
+ PAGE_SHIFT;
+
if (available < 0)
available = 0;
return available;
diff --git a/mm/slub.c b/mm/slub.c
index 7341005..61a49c0 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -683,7 +683,7 @@
slab_panic(reason);
}
-static void slab_err(struct kmem_cache *s, struct page *page,
+static __printf(3, 4) void slab_err(struct kmem_cache *s, struct page *page,
const char *fmt, ...)
{
va_list args;
diff --git a/mm/swap.c b/mm/swap.c
index 5827225..086d7fa 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -955,15 +955,25 @@
}
EXPORT_SYMBOL(pagevec_lookup);
-unsigned pagevec_lookup_tag(struct pagevec *pvec, struct address_space *mapping,
- pgoff_t *index, int tag, unsigned nr_pages)
+unsigned pagevec_lookup_range_tag(struct pagevec *pvec,
+ struct address_space *mapping, pgoff_t *index, pgoff_t end,
+ int tag)
{
- pvec->nr = find_get_pages_tag(mapping, index, tag,
- nr_pages, pvec->pages);
+ pvec->nr = find_get_pages_range_tag(mapping, index, end, tag,
+ PAGEVEC_SIZE, pvec->pages);
return pagevec_count(pvec);
}
-EXPORT_SYMBOL(pagevec_lookup_tag);
+EXPORT_SYMBOL(pagevec_lookup_range_tag);
+unsigned pagevec_lookup_range_nr_tag(struct pagevec *pvec,
+ struct address_space *mapping, pgoff_t *index, pgoff_t end,
+ int tag, unsigned max_pages)
+{
+ pvec->nr = find_get_pages_range_tag(mapping, index, end, tag,
+ min_t(unsigned int, max_pages, PAGEVEC_SIZE), pvec->pages);
+ return pagevec_count(pvec);
+}
+EXPORT_SYMBOL(pagevec_lookup_range_nr_tag);
/*
* Perform any setup for the swap system
*/
diff --git a/mm/swap_state.c b/mm/swap_state.c
index 35f882d..2fcc719 100644
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -17,6 +17,7 @@
#include <linux/blkdev.h>
#include <linux/pagevec.h>
#include <linux/migrate.h>
+#include <linux/delay.h>
#include <asm/pgtable.h>
@@ -350,8 +351,11 @@
* busy looping, we just conditionally invoke the
* scheduler here, if there are some more important
* tasks to run.
+ *
+ * cond_resched() may not work if the process is RT.
+ * We need a usleep_range() give up CPU to another task.
*/
- cond_resched();
+ usleep_range(500, 1000);
continue;
}
if (err) { /* swp entry is obsolete ? */
diff --git a/mm/util.c b/mm/util.c
index 8c755d0..6296de0 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -576,6 +576,13 @@
free += global_page_state(NR_SLAB_RECLAIMABLE);
/*
+ * Part of the kernel memory, which can be released
+ * under memory pressure.
+ */
+ free += global_node_page_state(
+ NR_INDIRECTLY_RECLAIMABLE_BYTES) >> PAGE_SHIFT;
+
+ /*
* Leave reserved pages. The pages are not for anonymous pages.
*/
if (free <= totalreserve_pages)
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 67ef013..0ffab05 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -1569,7 +1569,7 @@
addr))
return;
- area = remove_vm_area(addr);
+ area = find_vmap_area((unsigned long)addr)->vm;
if (unlikely(!area)) {
WARN(1, KERN_ERR "Trying to vfree() nonexistent vm area (%p)\n",
addr);
@@ -1579,6 +1579,7 @@
debug_check_no_locks_freed(addr, get_vm_area_size(area));
debug_check_no_obj_freed(addr, get_vm_area_size(area));
+ remove_vm_area(addr);
if (deallocate_pages) {
int i;
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 3d128da..fdd884a 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -973,6 +973,7 @@
"nr_vmscan_immediate_reclaim",
"nr_dirtied",
"nr_written",
+ "nr_indirectly_reclaimable",
/* enum writeback_stat_item counters */
"nr_dirty_threshold",
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index da3d373..18c1f07 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -406,6 +406,12 @@
watcher = xt_request_find_target(NFPROTO_BRIDGE, w->u.name, 0);
if (IS_ERR(watcher))
return PTR_ERR(watcher);
+
+ if (watcher->family != NFPROTO_BRIDGE) {
+ module_put(watcher->me);
+ return -ENOENT;
+ }
+
w->u.watcher = watcher;
par->target = watcher;
@@ -704,6 +710,8 @@
}
i = 0;
+ memset(&mtpar, 0, sizeof(mtpar));
+ memset(&tgpar, 0, sizeof(tgpar));
mtpar.net = tgpar.net = net;
mtpar.table = tgpar.table = name;
mtpar.entryinfo = tgpar.entryinfo = e;
@@ -725,6 +733,13 @@
goto cleanup_watchers;
}
+ /* Reject UNSPEC, xtables verdicts/return values are incompatible */
+ if (target->family != NFPROTO_BRIDGE) {
+ module_put(target->me);
+ ret = -ENOENT;
+ goto cleanup_watchers;
+ }
+
t->u.target = target;
if (t->u.target == &ebt_standard_target) {
if (gap < sizeof(struct ebt_standard_target)) {
diff --git a/net/core/dev.c b/net/core/dev.c
index c6a8932..8d5517c 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4201,7 +4201,8 @@
int (*gsb_nw_stack_recv)(struct sk_buff *skb) __rcu __read_mostly;
EXPORT_SYMBOL(gsb_nw_stack_recv);
-int (*athrs_fast_nat_recv)(struct sk_buff *skb) __rcu __read_mostly;
+int (*athrs_fast_nat_recv)(struct sk_buff *skb,
+ struct packet_type *pt_temp) __rcu __read_mostly;
EXPORT_SYMBOL(athrs_fast_nat_recv);
int (*embms_tm_multicast_recv)(struct sk_buff *skb) __rcu __read_mostly;
@@ -4216,7 +4217,7 @@
int ret = NET_RX_DROP;
__be16 type;
int (*gsb_ns_recv)(struct sk_buff *skb);
- int (*fast_recv)(struct sk_buff *skb);
+ int (*fast_recv)(struct sk_buff *skb, struct packet_type *pt_temp);
int (*embms_recv)(struct sk_buff *skb);
net_timestamp_check(!netdev_tstamp_prequeue, skb);
@@ -4286,7 +4287,7 @@
}
fast_recv = rcu_dereference(athrs_fast_nat_recv);
if (fast_recv) {
- if (fast_recv(skb)) {
+ if (fast_recv(skb, pt_prev)) {
ret = NET_RX_SUCCESS;
goto out;
}
diff --git a/net/core/dst.c b/net/core/dst.c
index b5de366..39cc119 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -349,15 +349,8 @@
new = ((unsigned long) &dst_default_metrics) | DST_METRICS_READ_ONLY;
prev = cmpxchg(&dst->_metrics, old, new);
- if (prev == old) {
- struct dst_metrics *old_p = (struct dst_metrics *)
- __DST_METRICS_PTR(old);
-
- if (prev & DST_METRICS_REFCOUNTED) {
- if (atomic_dec_and_test(&old_p->refcnt))
- kfree(old_p);
- }
- }
+ if (prev == old)
+ kfree(__DST_METRICS_PTR(old));
}
EXPORT_SYMBOL(__dst_destroy_metrics_generic);
diff --git a/net/core/gen_stats.c b/net/core/gen_stats.c
index 508e051..18f17e1 100644
--- a/net/core/gen_stats.c
+++ b/net/core/gen_stats.c
@@ -77,8 +77,20 @@
d->lock = lock;
spin_lock_bh(lock);
}
- if (d->tail)
- return gnet_stats_copy(d, type, NULL, 0, padattr);
+ if (d->tail) {
+ int ret = gnet_stats_copy(d, type, NULL, 0, padattr);
+
+ /* The initial attribute added in gnet_stats_copy() may be
+ * preceded by a padding attribute, in which case d->tail will
+ * end up pointing at the padding instead of the real attribute.
+ * Fix this so gnet_stats_finish_copy() adjusts the length of
+ * the right attribute.
+ */
+ if (ret == 0 && d->tail->nla_type == padattr)
+ d->tail = (struct nlattr *)((char *)d->tail +
+ NLA_ALIGN(d->tail->nla_len));
+ return ret;
+ }
return 0;
}
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index f3a0ad1..194e844 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2339,9 +2339,12 @@
return err;
}
- dev->rtnl_link_state = RTNL_LINK_INITIALIZED;
-
- __dev_notify_flags(dev, old_flags, ~0U);
+ if (dev->rtnl_link_state == RTNL_LINK_INITIALIZED) {
+ __dev_notify_flags(dev, old_flags, 0U);
+ } else {
+ dev->rtnl_link_state = RTNL_LINK_INITIALIZED;
+ __dev_notify_flags(dev, old_flags, ~0U);
+ }
return 0;
}
EXPORT_SYMBOL(rtnl_configure_link);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 89f0fbc..b6a319c 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -910,6 +910,7 @@
n->cloned = 1;
n->nohdr = 0;
n->peeked = 0;
+ C(pfmemalloc);
n->destructor = NULL;
C(tail);
C(end);
@@ -3258,6 +3259,7 @@
net_warn_ratelimited(
"skb_segment: too many frags: %u %u\n",
pos, mss);
+ err = -EINVAL;
goto err;
}
@@ -3294,11 +3296,10 @@
perform_csum_check:
if (!csum) {
- if (skb_has_shared_frag(nskb)) {
- err = __skb_linearize(nskb);
- if (err)
- goto err;
- }
+ if (skb_has_shared_frag(nskb) &&
+ __skb_linearize(nskb))
+ goto err;
+
if (!nskb->remcsum_offload)
nskb->ip_summed = CHECKSUM_NONE;
SKB_GSO_CB(nskb)->csum =
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index 119c043..03fcf3e 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -599,7 +599,7 @@
{
struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk);
struct dccp_sock *dp = dccp_sk(sk);
- ktime_t now = ktime_get_real();
+ ktime_t now = ktime_get();
s64 delta = 0;
switch (fbtype) {
@@ -624,15 +624,14 @@
case CCID3_FBACK_PERIODIC:
delta = ktime_us_delta(now, hc->rx_tstamp_last_feedback);
if (delta <= 0)
- DCCP_BUG("delta (%ld) <= 0", (long)delta);
- else
- hc->rx_x_recv = scaled_div32(hc->rx_bytes_recv, delta);
+ delta = 1;
+ hc->rx_x_recv = scaled_div32(hc->rx_bytes_recv, delta);
break;
default:
return;
}
- ccid3_pr_debug("Interval %ldusec, X_recv=%u, 1/p=%u\n", (long)delta,
+ ccid3_pr_debug("Interval %lldusec, X_recv=%u, 1/p=%u\n", delta,
hc->rx_x_recv, hc->rx_pinv);
hc->rx_tstamp_last_feedback = now;
@@ -679,7 +678,8 @@
static u32 ccid3_first_li(struct sock *sk)
{
struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk);
- u32 x_recv, p, delta;
+ u32 x_recv, p;
+ s64 delta;
u64 fval;
if (hc->rx_rtt == 0) {
@@ -687,7 +687,9 @@
hc->rx_rtt = DCCP_FALLBACK_RTT;
}
- delta = ktime_to_us(net_timedelta(hc->rx_tstamp_last_feedback));
+ delta = ktime_us_delta(ktime_get(), hc->rx_tstamp_last_feedback);
+ if (delta <= 0)
+ delta = 1;
x_recv = scaled_div32(hc->rx_bytes_recv, delta);
if (x_recv == 0) { /* would also trigger divide-by-zero */
DCCP_WARN("X_recv==0\n");
diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c
index f025276..5f5d9ea 100644
--- a/net/dns_resolver/dns_key.c
+++ b/net/dns_resolver/dns_key.c
@@ -87,35 +87,39 @@
opt++;
kdebug("options: '%s'", opt);
do {
+ int opt_len, opt_nlen;
const char *eq;
- int opt_len, opt_nlen, opt_vlen, tmp;
+ char optval[128];
next_opt = memchr(opt, '#', end - opt) ?: end;
opt_len = next_opt - opt;
- if (opt_len <= 0 || opt_len > 128) {
+ if (opt_len <= 0 || opt_len > sizeof(optval)) {
pr_warn_ratelimited("Invalid option length (%d) for dns_resolver key\n",
opt_len);
return -EINVAL;
}
- eq = memchr(opt, '=', opt_len) ?: end;
- opt_nlen = eq - opt;
- eq++;
- opt_vlen = next_opt - eq; /* will be -1 if no value */
+ eq = memchr(opt, '=', opt_len);
+ if (eq) {
+ opt_nlen = eq - opt;
+ eq++;
+ memcpy(optval, eq, next_opt - eq);
+ optval[next_opt - eq] = '\0';
+ } else {
+ opt_nlen = opt_len;
+ optval[0] = '\0';
+ }
- tmp = opt_vlen >= 0 ? opt_vlen : 0;
- kdebug("option '%*.*s' val '%*.*s'",
- opt_nlen, opt_nlen, opt, tmp, tmp, eq);
+ kdebug("option '%*.*s' val '%s'",
+ opt_nlen, opt_nlen, opt, optval);
/* see if it's an error number representing a DNS error
* that's to be recorded as the result in this key */
if (opt_nlen == sizeof(DNS_ERRORNO_OPTION) - 1 &&
memcmp(opt, DNS_ERRORNO_OPTION, opt_nlen) == 0) {
kdebug("dns error number option");
- if (opt_vlen <= 0)
- goto bad_option_value;
- ret = kstrtoul(eq, 10, &derrno);
+ ret = kstrtoul(optval, 10, &derrno);
if (ret < 0)
goto bad_option_value;
diff --git a/net/ipc_router/ipc_router_core.c b/net/ipc_router/ipc_router_core.c
index 7c12a16..d62b582 100644
--- a/net/ipc_router/ipc_router_core.c
+++ b/net/ipc_router/ipc_router_core.c
@@ -4298,6 +4298,8 @@
}
}
mutex_unlock(&xprt_info->rx_lock_lhb2);
+ if (rport_ptr)
+ kref_put(&rport_ptr->ref, ipc_router_release_rport);
kthread_queue_work(&xprt_info->kworker, &xprt_info->read_data);
}
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 08b7260..9be0312 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -290,6 +290,7 @@
if (!ipv4_is_zeronet(ip_hdr(skb)->saddr)) {
struct flowi4 fl4 = {
.flowi4_iif = LOOPBACK_IFINDEX,
+ .flowi4_oif = l3mdev_master_ifindex_rcu(dev),
.daddr = ip_hdr(skb)->saddr,
.flowi4_tos = RT_TOS(ip_hdr(skb)->tos),
.flowi4_scope = scope,
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 7f5fe07..f2e6e87 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -1193,8 +1193,7 @@
if (pmc) {
im->interface = pmc->interface;
im->crcount = in_dev->mr_qrv ?: net->ipv4.sysctl_igmp_qrv;
- im->sfmode = pmc->sfmode;
- if (pmc->sfmode == MCAST_INCLUDE) {
+ if (im->sfmode == MCAST_INCLUDE) {
im->tomb = pmc->tomb;
im->sources = pmc->sources;
for (psf = im->sources; psf; psf = psf->sf_next)
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index d0bd98f..5fcafc8 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -519,6 +519,8 @@
to->dev = from->dev;
to->mark = from->mark;
+ skb_copy_hash(to, from);
+
/* Copy the flags to each fragment. */
IPCB(to)->flags = IPCB(from)->flags;
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index dd80276..b21e435 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -135,15 +135,18 @@
{
struct sockaddr_in sin;
const struct iphdr *iph = ip_hdr(skb);
- __be16 *ports = (__be16 *)skb_transport_header(skb);
+ __be16 *ports;
+ int end;
- if (skb_transport_offset(skb) + 4 > (int)skb->len)
+ end = skb_transport_offset(skb) + 4;
+ if (end > 0 && !pskb_may_pull(skb, end))
return;
/* All current transport protocols have the port numbers in the
* first four bytes of the transport header and this function is
* written with this assumption in mind.
*/
+ ports = (__be16 *)skb_transport_header(skb);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = iph->daddr;
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index b23464d..d278b06 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -779,6 +779,11 @@
*/
static inline void __init ic_bootp_init(void)
{
+ /* Re-initialise all name servers to NONE, in case any were set via the
+ * "ip=" or "nfsaddrs=" kernel command line parameters: any IP addresses
+ * specified there will already have been decoded but are no longer
+ * needed
+ */
ic_nameservers_predef();
dev_add_pack(&bootp_packet_type);
@@ -1401,6 +1406,13 @@
int err;
unsigned int i;
+ /* Initialise all name servers to NONE (but only if the "ip=" or
+ * "nfsaddrs=" kernel command line parameters weren't decoded, otherwise
+ * we'll overwrite the IP addresses specified there)
+ */
+ if (ic_set_manually == 0)
+ ic_nameservers_predef();
+
#ifdef CONFIG_PROC_FS
proc_create("pnp", S_IRUGO, init_net.proc_net, &pnp_seq_fops);
#endif /* CONFIG_PROC_FS */
@@ -1621,6 +1633,7 @@
return 1;
}
+ /* Initialise all name servers to NONE */
ic_nameservers_predef();
/* Parse string for static IP assignment. */
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index e78f652..06aa494 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -554,6 +554,7 @@
return -ENOMEM;
j = 0;
+ memset(&mtpar, 0, sizeof(mtpar));
mtpar.net = net;
mtpar.table = name;
mtpar.entryinfo = &e->ip;
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index ccc484a..adc9ccc 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -144,8 +144,9 @@
if (write && ret == 0) {
low = make_kgid(user_ns, urange[0]);
high = make_kgid(user_ns, urange[1]);
- if (!gid_valid(low) || !gid_valid(high) ||
- (urange[1] < urange[0]) || gid_lt(high, low)) {
+ if (!gid_valid(low) || !gid_valid(high))
+ return -EINVAL;
+ if (urange[1] < urange[0] || gid_lt(high, low)) {
low = make_kgid(&init_user_ns, 1);
high = make_kgid(&init_user_ns, 0);
}
@@ -231,8 +232,9 @@
{
struct ctl_table tbl = { .maxlen = (TCP_FASTOPEN_KEY_LENGTH * 2 + 10) };
struct tcp_fastopen_context *ctxt;
- int ret;
u32 user_key[4]; /* 16 bytes, matching TCP_FASTOPEN_KEY_LENGTH */
+ __le32 key[4];
+ int ret, i;
tbl.data = kmalloc(tbl.maxlen, GFP_KERNEL);
if (!tbl.data)
@@ -241,11 +243,14 @@
rcu_read_lock();
ctxt = rcu_dereference(tcp_fastopen_ctx);
if (ctxt)
- memcpy(user_key, ctxt->key, TCP_FASTOPEN_KEY_LENGTH);
+ memcpy(key, ctxt->key, TCP_FASTOPEN_KEY_LENGTH);
else
- memset(user_key, 0, sizeof(user_key));
+ memset(key, 0, sizeof(key));
rcu_read_unlock();
+ for (i = 0; i < ARRAY_SIZE(key); i++)
+ user_key[i] = le32_to_cpu(key[i]);
+
snprintf(tbl.data, tbl.maxlen, "%08x-%08x-%08x-%08x",
user_key[0], user_key[1], user_key[2], user_key[3]);
ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
@@ -261,12 +266,16 @@
* first invocation of tcp_fastopen_cookie_gen
*/
tcp_fastopen_init_key_once(false);
- tcp_fastopen_reset_cipher(user_key, TCP_FASTOPEN_KEY_LENGTH);
+
+ for (i = 0; i < ARRAY_SIZE(user_key); i++)
+ key[i] = cpu_to_le32(user_key[i]);
+
+ tcp_fastopen_reset_cipher(key, TCP_FASTOPEN_KEY_LENGTH);
}
bad_key:
pr_debug("proc FO key set 0x%x-%x-%x-%x <- 0x%s: %u\n",
- user_key[0], user_key[1], user_key[2], user_key[3],
+ user_key[0], user_key[1], user_key[2], user_key[3],
(char *)tbl.data, ret);
kfree(tbl.data);
return ret;
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index fdfaaf0..5b4e5d6 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -3290,8 +3290,7 @@
struct request_sock *req = inet_reqsk(sk);
local_bh_disable();
- inet_csk_reqsk_queue_drop_and_put(req->rsk_listener,
- req);
+ inet_csk_reqsk_queue_drop(req->rsk_listener, req);
local_bh_enable();
return 0;
}
diff --git a/net/ipv4/tcp_dctcp.c b/net/ipv4/tcp_dctcp.c
index ab37c67..dd52ccb 100644
--- a/net/ipv4/tcp_dctcp.c
+++ b/net/ipv4/tcp_dctcp.c
@@ -131,23 +131,14 @@
struct dctcp *ca = inet_csk_ca(sk);
struct tcp_sock *tp = tcp_sk(sk);
- /* State has changed from CE=0 to CE=1 and delayed
- * ACK has not sent yet.
- */
- if (!ca->ce_state && ca->delayed_ack_reserved) {
- u32 tmp_rcv_nxt;
-
- /* Save current rcv_nxt. */
- tmp_rcv_nxt = tp->rcv_nxt;
-
- /* Generate previous ack with CE=0. */
- tp->ecn_flags &= ~TCP_ECN_DEMAND_CWR;
- tp->rcv_nxt = ca->prior_rcv_nxt;
-
- tcp_send_ack(sk);
-
- /* Recover current rcv_nxt. */
- tp->rcv_nxt = tmp_rcv_nxt;
+ if (!ca->ce_state) {
+ /* State has changed from CE=0 to CE=1, force an immediate
+ * ACK to reflect the new CE state. If an ACK was delayed,
+ * send that first to reflect the prior CE state.
+ */
+ if (inet_csk(sk)->icsk_ack.pending & ICSK_ACK_TIMER)
+ __tcp_send_ack(sk, ca->prior_rcv_nxt);
+ tcp_enter_quickack_mode(sk);
}
ca->prior_rcv_nxt = tp->rcv_nxt;
@@ -161,23 +152,14 @@
struct dctcp *ca = inet_csk_ca(sk);
struct tcp_sock *tp = tcp_sk(sk);
- /* State has changed from CE=1 to CE=0 and delayed
- * ACK has not sent yet.
- */
- if (ca->ce_state && ca->delayed_ack_reserved) {
- u32 tmp_rcv_nxt;
-
- /* Save current rcv_nxt. */
- tmp_rcv_nxt = tp->rcv_nxt;
-
- /* Generate previous ack with CE=1. */
- tp->ecn_flags |= TCP_ECN_DEMAND_CWR;
- tp->rcv_nxt = ca->prior_rcv_nxt;
-
- tcp_send_ack(sk);
-
- /* Recover current rcv_nxt. */
- tp->rcv_nxt = tmp_rcv_nxt;
+ if (ca->ce_state) {
+ /* State has changed from CE=1 to CE=0, force an immediate
+ * ACK to reflect the new CE state. If an ACK was delayed,
+ * send that first to reflect the prior CE state.
+ */
+ if (inet_csk(sk)->icsk_ack.pending & ICSK_ACK_TIMER)
+ __tcp_send_ack(sk, ca->prior_rcv_nxt);
+ tcp_enter_quickack_mode(sk);
}
ca->prior_rcv_nxt = tp->rcv_nxt;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index c244b72..28f31e2 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -210,13 +210,14 @@
icsk->icsk_ack.quick = min(quickacks, TCP_MAX_QUICKACKS);
}
-static void tcp_enter_quickack_mode(struct sock *sk)
+void tcp_enter_quickack_mode(struct sock *sk)
{
struct inet_connection_sock *icsk = inet_csk(sk);
tcp_incr_quickack(sk);
icsk->icsk_ack.pingpong = 0;
icsk->icsk_ack.ato = TCP_ATO_MIN;
}
+EXPORT_SYMBOL(tcp_enter_quickack_mode);
/* Send ACKs quickly, if "quick" count is not exhausted
* and the session is not interactive.
@@ -3237,6 +3238,15 @@
if (tcp_is_reno(tp)) {
tcp_remove_reno_sacks(sk, pkts_acked);
+
+ /* If any of the cumulatively ACKed segments was
+ * retransmitted, non-SACK case cannot confirm that
+ * progress was due to original transmission due to
+ * lack of TCPCB_SACKED_ACKED bits even if some of
+ * the packets may have been never retransmitted.
+ */
+ if (flag & FLAG_RETRANS_DATA_ACKED)
+ flag &= ~FLAG_ORIG_SACK_ACKED;
} else {
int delta;
@@ -4508,7 +4518,7 @@
/* All the bits are present. Drop. */
NET_INC_STATS(sock_net(sk),
LINUX_MIB_TCPOFOMERGE);
- __kfree_skb(skb);
+ tcp_drop(sk, skb);
skb = NULL;
tcp_dsack_set(sk, seq, end_seq);
goto add_sack;
@@ -4527,7 +4537,7 @@
TCP_SKB_CB(skb1)->end_seq);
NET_INC_STATS(sock_net(sk),
LINUX_MIB_TCPOFOMERGE);
- __kfree_skb(skb1);
+ tcp_drop(sk, skb1);
goto merge_right;
}
} else if (tcp_try_coalesce(sk, skb1, skb, &fragstolen)) {
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 70c7212..0afd75a 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -174,8 +174,13 @@
}
/* Account for an ACK we sent. */
-static inline void tcp_event_ack_sent(struct sock *sk, unsigned int pkts)
+static inline void tcp_event_ack_sent(struct sock *sk, unsigned int pkts,
+ u32 rcv_nxt)
{
+ struct tcp_sock *tp = tcp_sk(sk);
+
+ if (unlikely(rcv_nxt != tp->rcv_nxt))
+ return; /* Special ACK sent by DCTCP to reflect ECN */
tcp_dec_quickack_mode(sk, pkts);
inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK);
}
@@ -905,8 +910,8 @@
* We are working here with either a clone of the original
* SKB, or a fresh unique copy made by the retransmit engine.
*/
-static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
- gfp_t gfp_mask)
+static int __tcp_transmit_skb(struct sock *sk, struct sk_buff *skb,
+ int clone_it, gfp_t gfp_mask, u32 rcv_nxt)
{
const struct inet_connection_sock *icsk = inet_csk(sk);
struct inet_sock *inet;
@@ -969,7 +974,7 @@
th->source = inet->inet_sport;
th->dest = inet->inet_dport;
th->seq = htonl(tcb->seq);
- th->ack_seq = htonl(tp->rcv_nxt);
+ th->ack_seq = htonl(rcv_nxt);
*(((__be16 *)th) + 6) = htons(((tcp_header_size >> 2) << 12) |
tcb->tcp_flags);
@@ -1010,7 +1015,7 @@
icsk->icsk_af_ops->send_check(sk, skb);
if (likely(tcb->tcp_flags & TCPHDR_ACK))
- tcp_event_ack_sent(sk, tcp_skb_pcount(skb));
+ tcp_event_ack_sent(sk, tcp_skb_pcount(skb), rcv_nxt);
if (skb->len != tcp_header_size) {
tcp_event_data_sent(tp, sk);
@@ -1046,6 +1051,13 @@
return err;
}
+static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
+ gfp_t gfp_mask)
+{
+ return __tcp_transmit_skb(sk, skb, clone_it, gfp_mask,
+ tcp_sk(sk)->rcv_nxt);
+}
+
/* This routine just queues the buffer for sending.
*
* NOTE: probe0 timer is not checked, do not forget tcp_push_pending_frames,
@@ -3470,7 +3482,7 @@
}
/* This routine sends an ack and also updates the window. */
-void tcp_send_ack(struct sock *sk)
+void __tcp_send_ack(struct sock *sk, u32 rcv_nxt)
{
struct sk_buff *buff;
@@ -3508,9 +3520,14 @@
/* Send it off, this clears delayed acks for us. */
skb_mstamp_get(&buff->skb_mstamp);
- tcp_transmit_skb(sk, buff, 0, (__force gfp_t)0);
+ __tcp_transmit_skb(sk, buff, 0, (__force gfp_t)0, rcv_nxt);
}
-EXPORT_SYMBOL_GPL(tcp_send_ack);
+EXPORT_SYMBOL_GPL(__tcp_send_ack);
+
+void tcp_send_ack(struct sock *sk)
+{
+ __tcp_send_ack(sk, tcp_sk(sk)->rcv_nxt);
+}
/* This routine sends a packet with an out of date sequence
* number. It assumes the other end will try to ack it.
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 1778af9..83ce5ac 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -701,13 +701,16 @@
}
if (np->rxopt.bits.rxorigdstaddr) {
struct sockaddr_in6 sin6;
- __be16 *ports = (__be16 *) skb_transport_header(skb);
+ __be16 *ports;
+ int end;
- if (skb_transport_offset(skb) + 4 <= (int)skb->len) {
+ end = skb_transport_offset(skb) + 4;
+ if (end <= 0 || pskb_may_pull(skb, end)) {
/* All current transport protocols have the port numbers in the
* first four bytes of the transport header and this function is
* written with this assumption in mind.
*/
+ ports = (__be16 *)skb_transport_header(skb);
sin6.sin6_family = AF_INET6;
sin6.sin6_addr = ipv6_hdr(skb)->daddr;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index ae5e38b..def627f 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -585,6 +585,8 @@
to->dev = from->dev;
to->mark = from->mark;
+ skb_copy_hash(to, from);
+
#ifdef CONFIG_NET_SCHED
to->tc_index = from->tc_index;
#endif
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index ca8fac6..918c161 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -771,8 +771,7 @@
if (pmc) {
im->idev = pmc->idev;
im->mca_crcount = idev->mc_qrv;
- im->mca_sfmode = pmc->mca_sfmode;
- if (pmc->mca_sfmode == MCAST_INCLUDE) {
+ if (im->mca_sfmode == MCAST_INCLUDE) {
im->mca_tomb = pmc->mca_tomb;
im->mca_sources = pmc->mca_sources;
for (psf = im->mca_sources; psf; psf = psf->sf_next)
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index aa82858..6d96647 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -593,6 +593,7 @@
return -ENOMEM;
j = 0;
+ memset(&mtpar, 0, sizeof(mtpar));
mtpar.net = net;
mtpar.table = name;
mtpar.entryinfo = &e->ipv6;
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 64ec233..722a9db 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -618,6 +618,8 @@
fq->q.meat == fq->q.len &&
nf_ct_frag6_reasm(fq, skb, dev))
ret = 0;
+ else
+ skb_dst_drop(skb);
out_unlock:
spin_unlock_bh(&fq->q.lock);
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 3ba903f..58c045d 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -196,30 +196,22 @@
return 0;
}
-static int pfkey_broadcast_one(struct sk_buff *skb, struct sk_buff **skb2,
- gfp_t allocation, struct sock *sk)
+static int pfkey_broadcast_one(struct sk_buff *skb, gfp_t allocation,
+ struct sock *sk)
{
int err = -ENOBUFS;
- sock_hold(sk);
- if (*skb2 == NULL) {
- if (atomic_read(&skb->users) != 1) {
- *skb2 = skb_clone(skb, allocation);
- } else {
- *skb2 = skb;
- atomic_inc(&skb->users);
- }
+ if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf)
+ return err;
+
+ skb = skb_clone(skb, allocation);
+
+ if (skb) {
+ skb_set_owner_r(skb, sk);
+ skb_queue_tail(&sk->sk_receive_queue, skb);
+ sk->sk_data_ready(sk);
+ err = 0;
}
- if (*skb2 != NULL) {
- if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf) {
- skb_set_owner_r(*skb2, sk);
- skb_queue_tail(&sk->sk_receive_queue, *skb2);
- sk->sk_data_ready(sk);
- *skb2 = NULL;
- err = 0;
- }
- }
- sock_put(sk);
return err;
}
@@ -234,7 +226,6 @@
{
struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);
struct sock *sk;
- struct sk_buff *skb2 = NULL;
int err = -ESRCH;
/* XXX Do we need something like netlink_overrun? I think
@@ -253,7 +244,7 @@
* socket.
*/
if (pfk->promisc)
- pfkey_broadcast_one(skb, &skb2, GFP_ATOMIC, sk);
+ pfkey_broadcast_one(skb, GFP_ATOMIC, sk);
/* the exact target will be processed later */
if (sk == one_sk)
@@ -268,7 +259,7 @@
continue;
}
- err2 = pfkey_broadcast_one(skb, &skb2, GFP_ATOMIC, sk);
+ err2 = pfkey_broadcast_one(skb, GFP_ATOMIC, sk);
/* Error is cleared after successful sending to at least one
* registered KM */
@@ -278,9 +269,8 @@
rcu_read_unlock();
if (one_sk != NULL)
- err = pfkey_broadcast_one(skb, &skb2, allocation, one_sk);
+ err = pfkey_broadcast_one(skb, allocation, one_sk);
- kfree_skb(skb2);
kfree_skb(skb);
return err;
}
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 762f31f..a3fb30f 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -2476,12 +2476,13 @@
u32 id = ntohl(nla_get_be32(nla));
list_for_each_entry(trans, &net->nft.commit_list, list) {
- struct nft_set *set = nft_trans_set(trans);
+ if (trans->msg_type == NFT_MSG_NEWSET) {
+ struct nft_set *set = nft_trans_set(trans);
- if (trans->msg_type == NFT_MSG_NEWSET &&
- id == nft_trans_set_id(trans) &&
- nft_active_genmask(set, genmask))
- return set;
+ if (id == nft_trans_set_id(trans) &&
+ nft_active_genmask(set, genmask))
+ return set;
+ }
}
return ERR_PTR(-ENOENT);
}
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 5efb402..2a811b5 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -1210,6 +1210,9 @@
static const struct nla_policy nfqa_cfg_policy[NFQA_CFG_MAX+1] = {
[NFQA_CFG_CMD] = { .len = sizeof(struct nfqnl_msg_config_cmd) },
[NFQA_CFG_PARAMS] = { .len = sizeof(struct nfqnl_msg_config_params) },
+ [NFQA_CFG_QUEUE_MAXLEN] = { .type = NLA_U32 },
+ [NFQA_CFG_MASK] = { .type = NLA_U32 },
+ [NFQA_CFG_FLAGS] = { .type = NLA_U32 },
};
static const struct nf_queue_handler nfqh = {
diff --git a/net/nfc/llcp_commands.c b/net/nfc/llcp_commands.c
index 3f26611..04759a0 100644
--- a/net/nfc/llcp_commands.c
+++ b/net/nfc/llcp_commands.c
@@ -753,11 +753,14 @@
pr_debug("Fragment %zd bytes remaining %zd",
frag_len, remaining_len);
- pdu = nfc_alloc_send_skb(sock->dev, &sock->sk, MSG_DONTWAIT,
+ pdu = nfc_alloc_send_skb(sock->dev, &sock->sk, 0,
frag_len + LLCP_HEADER_SIZE, &err);
if (pdu == NULL) {
- pr_err("Could not allocate PDU\n");
- continue;
+ pr_err("Could not allocate PDU (error=%d)\n", err);
+ len -= remaining_len;
+ if (len == 0)
+ len = err;
+ break;
}
pdu = llcp_add_header(pdu, dsap, ssap, LLCP_PDU_UI);
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 8ab2b53..d4a438b 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -2265,6 +2265,12 @@
if (po->stats.stats1.tp_drops)
status |= TP_STATUS_LOSING;
}
+
+ if (do_vnet &&
+ __packet_rcv_vnet(skb, h.raw + macoff -
+ sizeof(struct virtio_net_hdr)))
+ goto drop_n_account;
+
po->stats.stats1.tp_packets++;
if (copy_skb) {
status |= TP_STATUS_COPY;
@@ -2272,14 +2278,6 @@
}
spin_unlock(&sk->sk_receive_queue.lock);
- if (do_vnet) {
- if (__packet_rcv_vnet(skb, h.raw + macoff -
- sizeof(struct virtio_net_hdr))) {
- spin_lock(&sk->sk_receive_queue.lock);
- goto drop_n_account;
- }
- }
-
skb_copy_bits(skb, 0, h.raw + macoff, snaplen);
if (!(ts_status = tpacket_get_timestamp(skb, &ts, po->tp_tstamp)))
diff --git a/net/rds/loop.c b/net/rds/loop.c
index f2bf78d..dac6218 100644
--- a/net/rds/loop.c
+++ b/net/rds/loop.c
@@ -193,4 +193,5 @@
.inc_copy_to_user = rds_message_inc_copy_to_user,
.inc_free = rds_loop_inc_free,
.t_name = "loopback",
+ .t_type = RDS_TRANS_LOOP,
};
diff --git a/net/rds/rds.h b/net/rds/rds.h
index 30a51fe..edfc339 100644
--- a/net/rds/rds.h
+++ b/net/rds/rds.h
@@ -440,6 +440,11 @@
int n_status;
};
+/* Available as part of RDS core, so doesn't need to participate
+ * in get_preferred transport etc
+ */
+#define RDS_TRANS_LOOP 3
+
/**
* struct rds_transport - transport specific behavioural hooks
*
diff --git a/net/rds/recv.c b/net/rds/recv.c
index cbfabdf..f16ee1b 100644
--- a/net/rds/recv.c
+++ b/net/rds/recv.c
@@ -94,6 +94,11 @@
return;
rs->rs_rcv_bytes += delta;
+
+ /* loop transport doesn't send/recv congestion updates */
+ if (rs->rs_transport->t_type == RDS_TRANS_LOOP)
+ return;
+
now_congested = rs->rs_rcv_bytes > rds_sk_rcvbuf(rs);
rdsdebug("rs %p (%pI4:%u) recv bytes %d buf %d "
diff --git a/net/sched/sch_blackhole.c b/net/sched/sch_blackhole.c
index c98a61e..9c4c2bb 100644
--- a/net/sched/sch_blackhole.c
+++ b/net/sched/sch_blackhole.c
@@ -21,7 +21,7 @@
struct sk_buff **to_free)
{
qdisc_drop(skb, sch, to_free);
- return NET_XMIT_SUCCESS;
+ return NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
}
static struct sk_buff *blackhole_dequeue(struct Qdisc *sch)
diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c
index f57c9f0..0287734 100644
--- a/net/sunrpc/xprtrdma/rpc_rdma.c
+++ b/net/sunrpc/xprtrdma/rpc_rdma.c
@@ -229,7 +229,7 @@
/* alloc the pagelist for receiving buffer */
ppages[p] = alloc_page(GFP_ATOMIC);
if (!ppages[p])
- return -EAGAIN;
+ return -ENOBUFS;
}
seg[n].mr_page = ppages[p];
seg[n].mr_offset = (void *)(unsigned long) page_base;
diff --git a/net/wireless/db.txt b/net/wireless/db.txt
index 38fbe09..29544de 100644
--- a/net/wireless/db.txt
+++ b/net/wireless/db.txt
@@ -755,6 +755,10 @@
(5490 - 5730 @ 160), (30), DFS
(5735 - 5875 @ 80), (14)
+country MM:
+ (2402 - 2482 @ 40), (20)
+ (5735 - 5835 @ 80), (30)
+
country MN: DFS-FCC
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (24), AUTO-BW
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 773c66b..272edad 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1406,6 +1406,9 @@
(ut[i].family != prev_family))
return -EINVAL;
+ if (ut[i].mode >= XFRM_MODE_MAX)
+ return -EINVAL;
+
prev_family = ut[i].family;
switch (ut[i].family) {
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index a71f906..9652541 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -379,6 +379,7 @@
static int read_idmap[READING_MAX_ID] = {
[READING_FIRMWARE] = FIRMWARE_CHECK,
+ [READING_FIRMWARE_PREALLOC_BUFFER] = FIRMWARE_CHECK,
[READING_MODULE] = MODULE_CHECK,
[READING_KEXEC_IMAGE] = KEXEC_KERNEL_CHECK,
[READING_KEXEC_INITRAMFS] = KEXEC_INITRAMFS_CHECK,
diff --git a/security/pfe/pfk.c b/security/pfe/pfk.c
index f9a6292..8b0b9ce 100644
--- a/security/pfe/pfk.c
+++ b/security/pfe/pfk.c
@@ -76,7 +76,6 @@
struct pfk_key_info *key_info,
enum ice_cryto_algo_mode *algo,
bool *is_pfe,
- unsigned int *data_unit,
const char *storage_type);
typedef bool (*pfk_allow_merge_bio_type)(const struct bio *bio1,
@@ -287,27 +286,33 @@
{
const struct inode *inode;
enum pfe_type which_pfe;
- const struct blk_encryption_key *key;
char *s_type = NULL;
+ const struct blk_encryption_key *key = NULL;
inode = pfk_bio_get_inode(bio);
which_pfe = pfk_get_pfe_type(inode);
s_type = (char *)pfk_kc_get_storage_type();
+ if (data_unit && (bio_dun(bio) ||
+ !memcmp(s_type, "ufs", strlen("ufs"))))
+ *data_unit = 1 << ICE_CRYPTO_DATA_UNIT_4_KB;
+
if (which_pfe != INVALID_PFE) {
/* Encrypted file; override ->bi_crypt_key */
pr_debug("parsing inode %lu with PFE type %d\n",
inode->i_ino, which_pfe);
return (*(pfk_parse_inode_ftable[which_pfe]))
(bio, inode, key_info, algo_mode, is_pfe,
- data_unit, (const char *)s_type);
+ (const char *)s_type);
}
/*
* bio is not for an encrypted file. Use ->bi_crypt_key if it was set.
* Otherwise, don't encrypt/decrypt the bio.
*/
+#ifdef CONFIG_DM_DEFAULT_KEY
key = bio->bi_crypt_key;
+#endif
if (!key) {
*is_pfe = false;
return -EINVAL;
@@ -469,13 +474,18 @@
*/
bool pfk_allow_merge_bio(const struct bio *bio1, const struct bio *bio2)
{
- const struct blk_encryption_key *key1;
- const struct blk_encryption_key *key2;
+ const struct blk_encryption_key *key1 = NULL;
+ const struct blk_encryption_key *key2 = NULL;
const struct inode *inode1;
const struct inode *inode2;
enum pfe_type which_pfe1;
enum pfe_type which_pfe2;
+#ifdef CONFIG_DM_DEFAULT_KEY
+ key1 = bio1->bi_crypt_key;
+ key2 = bio2->bi_crypt_key;
+#endif
+
if (!pfk_is_ready())
return false;
diff --git a/security/pfe/pfk_ext4.c b/security/pfe/pfk_ext4.c
index 7000b66..6d3cd4c 100644
--- a/security/pfe/pfk_ext4.c
+++ b/security/pfe/pfk_ext4.c
@@ -142,7 +142,6 @@
struct pfk_key_info *key_info,
enum ice_cryto_algo_mode *algo,
bool *is_pfe,
- unsigned int *data_unit,
const char *storage_type)
{
int ret = 0;
@@ -157,19 +156,6 @@
*/
*is_pfe = true;
- /* Update dun based upon storage type.
- * For ext4 FS UFS has 4k dun whereas eMMC
- * uses 512Byte dun.
- */
- if (storage_type && data_unit) {
- if (!memcmp(storage_type, "ufs", strlen("ufs")))
- *data_unit = 1 << ICE_CRYPTO_DATA_UNIT_4_KB;
- else if (!memcmp(storage_type, "sdcc", strlen("sdcc")))
- *data_unit = 1 << ICE_CRYPTO_DATA_UNIT_512_B;
- else
- return -EINVAL;
- }
-
if (!pfk_ext4_is_ready())
return -ENODEV;
diff --git a/security/pfe/pfk_ext4.h b/security/pfe/pfk_ext4.h
index e39d04d..346027b 100644
--- a/security/pfe/pfk_ext4.h
+++ b/security/pfe/pfk_ext4.h
@@ -25,7 +25,6 @@
struct pfk_key_info *key_info,
enum ice_cryto_algo_mode *algo,
bool *is_pfe,
- unsigned int *data_unit,
const char *storage_type);
bool pfk_ext4_allow_merge_bio(const struct bio *bio1,
diff --git a/security/pfe/pfk_f2fs.c b/security/pfe/pfk_f2fs.c
index 2076267..9523c35 100644
--- a/security/pfe/pfk_f2fs.c
+++ b/security/pfe/pfk_f2fs.c
@@ -117,7 +117,6 @@
struct pfk_key_info *key_info,
enum ice_cryto_algo_mode *algo,
bool *is_pfe,
- unsigned int *data_unit,
const char *storage_type)
{
int ret = 0;
@@ -132,18 +131,6 @@
*/
*is_pfe = true;
- /* Update the dun based upon storage type.
- * Right now both UFS and eMMC storage uses 4KB dun
- * for F2FS
- */
- if (storage_type && data_unit) {
- if (!memcmp(storage_type, "ufs", strlen("ufs")) ||
- !memcmp(storage_type, "sdcc", strlen("sdcc")))
- *data_unit = 1 << ICE_CRYPTO_DATA_UNIT_4_KB;
- else
- return -EINVAL;
- }
-
if (!pfk_f2fs_is_ready())
return -ENODEV;
diff --git a/security/pfe/pfk_f2fs.h b/security/pfe/pfk_f2fs.h
index 2e0c21d..1b00bd8 100644
--- a/security/pfe/pfk_f2fs.h
+++ b/security/pfe/pfk_f2fs.h
@@ -25,7 +25,6 @@
struct pfk_key_info *key_info,
enum ice_cryto_algo_mode *algo,
bool *is_pfe,
- unsigned int *data_unit,
const char *storage_type);
bool pfk_f2fs_allow_merge_bio(const struct bio *bio1,
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 180261d..f217a1d 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -636,10 +636,8 @@
int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream,
struct snd_rawmidi_params * params)
{
- char *newbuf;
- char *oldbuf;
+ char *newbuf, *oldbuf;
struct snd_rawmidi_runtime *runtime = substream->runtime;
- unsigned long flags;
if (substream->append && substream->use_count > 1)
return -EBUSY;
@@ -651,22 +649,17 @@
return -EINVAL;
}
if (params->buffer_size != runtime->buffer_size) {
- mutex_lock(&runtime->realloc_mutex);
- newbuf = __krealloc(runtime->buffer, params->buffer_size,
- GFP_KERNEL);
- if (!newbuf) {
- mutex_unlock(&runtime->realloc_mutex);
+ newbuf = kmalloc(params->buffer_size, GFP_KERNEL);
+ if (!newbuf)
return -ENOMEM;
- }
- spin_lock_irqsave(&runtime->lock, flags);
+ spin_lock_irq(&runtime->lock);
oldbuf = runtime->buffer;
runtime->buffer = newbuf;
runtime->buffer_size = params->buffer_size;
runtime->avail = runtime->buffer_size;
- spin_unlock_irqrestore(&runtime->lock, flags);
- if (oldbuf != newbuf)
- kfree(oldbuf);
- mutex_unlock(&runtime->realloc_mutex);
+ runtime->appl_ptr = runtime->hw_ptr = 0;
+ spin_unlock_irq(&runtime->lock);
+ kfree(oldbuf);
}
runtime->avail_min = params->avail_min;
substream->active_sensing = !params->no_active_sensing;
@@ -677,10 +670,8 @@
int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream,
struct snd_rawmidi_params * params)
{
- char *newbuf;
- char *oldbuf;
+ char *newbuf, *oldbuf;
struct snd_rawmidi_runtime *runtime = substream->runtime;
- unsigned long flags;
snd_rawmidi_drain_input(substream);
if (params->buffer_size < 32 || params->buffer_size > 1024L * 1024L) {
@@ -690,21 +681,16 @@
return -EINVAL;
}
if (params->buffer_size != runtime->buffer_size) {
- mutex_lock(&runtime->realloc_mutex);
- newbuf = __krealloc(runtime->buffer, params->buffer_size,
- GFP_KERNEL);
- if (!newbuf) {
- mutex_unlock(&runtime->realloc_mutex);
+ newbuf = kmalloc(params->buffer_size, GFP_KERNEL);
+ if (!newbuf)
return -ENOMEM;
- }
- spin_lock_irqsave(&runtime->lock, flags);
+ spin_lock_irq(&runtime->lock);
oldbuf = runtime->buffer;
runtime->buffer = newbuf;
runtime->buffer_size = params->buffer_size;
- spin_unlock_irqrestore(&runtime->lock, flags);
- if (oldbuf != newbuf)
- kfree(oldbuf);
- mutex_unlock(&runtime->realloc_mutex);
+ runtime->appl_ptr = runtime->hw_ptr = 0;
+ spin_unlock_irq(&runtime->lock);
+ kfree(oldbuf);
}
runtime->avail_min = params->avail_min;
return 0;
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index 37be1e1..0d2bb30 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -1850,7 +1850,9 @@
if (!kctl)
return -ENOMEM;
kctl->id.device = device;
- snd_ctl_add(emu->card, kctl);
+ err = snd_ctl_add(emu->card, kctl);
+ if (err < 0)
+ return err;
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 64*1024, 64*1024);
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
index 4f1f69b..8c778fa 100644
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -237,13 +237,13 @@
static int is_valid_page(struct snd_emu10k1 *emu, dma_addr_t addr)
{
if (addr & ~emu->dma_mask) {
- dev_err(emu->card->dev,
+ dev_err_ratelimited(emu->card->dev,
"max memory size is 0x%lx (addr = 0x%lx)!!\n",
emu->dma_mask, (unsigned long)addr);
return 0;
}
if (addr & (EMUPAGESIZE-1)) {
- dev_err(emu->card->dev, "page is not aligned\n");
+ dev_err_ratelimited(emu->card->dev, "page is not aligned\n");
return 0;
}
return 1;
@@ -334,7 +334,7 @@
else
addr = snd_pcm_sgbuf_get_addr(substream, ofs);
if (! is_valid_page(emu, addr)) {
- dev_err(emu->card->dev,
+ dev_err_ratelimited(emu->card->dev,
"emu: failure page = %d\n", idx);
mutex_unlock(&hdr->block_mutex);
return NULL;
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index a178e0d..8561f60 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -1068,11 +1068,19 @@
if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97_sec)) < 0)
return err;
}
- for (i = 0; i < FM801_CONTROLS; i++)
- snd_ctl_add(chip->card, snd_ctl_new1(&snd_fm801_controls[i], chip));
+ for (i = 0; i < FM801_CONTROLS; i++) {
+ err = snd_ctl_add(chip->card,
+ snd_ctl_new1(&snd_fm801_controls[i], chip));
+ if (err < 0)
+ return err;
+ }
if (chip->multichannel) {
- for (i = 0; i < FM801_CONTROLS_MULTI; i++)
- snd_ctl_add(chip->card, snd_ctl_new1(&snd_fm801_controls_multi[i], chip));
+ for (i = 0; i < FM801_CONTROLS_MULTI; i++) {
+ err = snd_ctl_add(chip->card,
+ snd_ctl_new1(&snd_fm801_controls_multi[i], chip));
+ if (err < 0)
+ return err;
+ }
}
return 0;
}
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 9ec4dba..2809999 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -38,6 +38,10 @@
/* Enable this to see controls for tuning purpose. */
/*#define ENABLE_TUNING_CONTROLS*/
+#ifdef ENABLE_TUNING_CONTROLS
+#include <sound/tlv.h>
+#endif
+
#define FLOAT_ZERO 0x00000000
#define FLOAT_ONE 0x3f800000
#define FLOAT_TWO 0x40000000
@@ -3067,8 +3071,8 @@
return 1;
}
-static const DECLARE_TLV_DB_SCALE(voice_focus_db_scale, 2000, 100, 0);
-static const DECLARE_TLV_DB_SCALE(eq_db_scale, -2400, 100, 0);
+static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(voice_focus_db_scale, 2000, 100, 0);
+static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(eq_db_scale, -2400, 100, 0);
static int add_tuning_control(struct hda_codec *codec,
hda_nid_t pnid, hda_nid_t nid,
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index bd65022..76ae627 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -33,6 +33,7 @@
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/module.h>
+#include <linux/pm_runtime.h>
#include <sound/core.h>
#include <sound/jack.h>
#include <sound/asoundef.h>
@@ -731,8 +732,10 @@
if (pin_idx < 0)
return;
+ mutex_lock(&spec->pcm_lock);
if (hdmi_present_sense(get_pin(spec, pin_idx), 1))
snd_hda_jack_report_sync(codec);
+ mutex_unlock(&spec->pcm_lock);
}
static void jack_callback(struct hda_codec *codec,
@@ -1521,21 +1524,23 @@
static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
{
struct hda_codec *codec = per_pin->codec;
- struct hdmi_spec *spec = codec->spec;
int ret;
/* no temporary power up/down needed for component notifier */
- if (!codec_has_acomp(codec))
- snd_hda_power_up_pm(codec);
+ if (!codec_has_acomp(codec)) {
+ ret = snd_hda_power_up_pm(codec);
+ if (ret < 0 && pm_runtime_suspended(hda_codec_dev(codec))) {
+ snd_hda_power_down_pm(codec);
+ return false;
+ }
+ }
- mutex_lock(&spec->pcm_lock);
if (codec_has_acomp(codec)) {
sync_eld_via_acomp(codec, per_pin);
ret = false; /* don't call snd_hda_jack_report_sync() */
} else {
ret = hdmi_present_sense_via_verbs(per_pin, repoll);
}
- mutex_unlock(&spec->pcm_lock);
if (!codec_has_acomp(codec))
snd_hda_power_down_pm(codec);
@@ -1547,12 +1552,16 @@
{
struct hdmi_spec_per_pin *per_pin =
container_of(to_delayed_work(work), struct hdmi_spec_per_pin, work);
+ struct hda_codec *codec = per_pin->codec;
+ struct hdmi_spec *spec = codec->spec;
if (per_pin->repoll_count++ > 6)
per_pin->repoll_count = 0;
+ mutex_lock(&spec->pcm_lock);
if (hdmi_present_sense(per_pin, per_pin->repoll_count))
snd_hda_jack_report_sync(per_pin->codec);
+ mutex_unlock(&spec->pcm_lock);
}
static void intel_haswell_fixup_connect_list(struct hda_codec *codec,
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index bd8f34a..a203275 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -1911,8 +1911,10 @@
continue;
if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) &&
- (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN))
- continue;
+ (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN)) {
+ soc_pcm_hw_free(be_substream);
+ be->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE;
+ }
dev_dbg(be->dev, "ASoC: close BE %s\n",
be->dai_link->name);
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index dc0a9ef..b57d1d4 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -1379,7 +1379,7 @@
if (bytes % (runtime->sample_bits >> 3) != 0) {
int oldbytes = bytes;
bytes = frames * stride;
- dev_warn(&subs->dev->dev,
+ dev_warn_ratelimited(&subs->dev->dev,
"Corrected urb data len. %d->%d\n",
oldbytes, bytes);
}
diff --git a/tools/build/Build.include b/tools/build/Build.include
index b816554..ab02f8d 100644
--- a/tools/build/Build.include
+++ b/tools/build/Build.include
@@ -63,8 +63,8 @@
$(fixdep) $(depfile) $@ '$(make-cmd)' > $(dot-target).tmp; \
rm -f $(depfile); \
mv -f $(dot-target).tmp $(dot-target).cmd, \
- printf '\# cannot find fixdep (%s)\n' $(fixdep) > $(dot-target).cmd; \
- printf '\# using basic dep data\n\n' >> $(dot-target).cmd; \
+ printf '$(pound) cannot find fixdep (%s)\n' $(fixdep) > $(dot-target).cmd; \
+ printf '$(pound) using basic dep data\n\n' >> $(dot-target).cmd; \
cat $(depfile) >> $(dot-target).cmd; \
printf '%s\n' 'cmd_$@ := $(make-cmd)' >> $(dot-target).cmd)
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index 879115f..98a4205 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -68,6 +68,7 @@
%type <num> value_sym
%type <head> event_config
%type <head> opt_event_config
+%type <head> opt_pmu_config
%type <term> event_term
%type <head> event_pmu
%type <head> event_legacy_symbol
@@ -219,7 +220,7 @@
event_bpf_file
event_pmu:
-PE_NAME opt_event_config
+PE_NAME opt_pmu_config
{
struct parse_events_evlist *data = _data;
struct list_head *list;
@@ -482,6 +483,17 @@
$$ = NULL;
}
+opt_pmu_config:
+'/' event_config '/'
+{
+ $$ = $2;
+}
+|
+'/' '/'
+{
+ $$ = NULL;
+}
+
start_terms: event_config
{
struct parse_events_terms *data = _data;
diff --git a/tools/testing/selftests/intel_pstate/run.sh b/tools/testing/selftests/intel_pstate/run.sh
index 7868c10..b62876f 100755
--- a/tools/testing/selftests/intel_pstate/run.sh
+++ b/tools/testing/selftests/intel_pstate/run.sh
@@ -48,11 +48,12 @@
echo "sleeping for 5 seconds"
sleep 5
- num_freqs=$(cat /proc/cpuinfo | grep MHz | sort -u | wc -l)
- if [ $num_freqs -le 2 ]; then
- cat /proc/cpuinfo | grep MHz | sort -u | tail -1 > /tmp/result.$1
+ grep MHz /proc/cpuinfo | sort -u > /tmp/result.freqs
+ num_freqs=$(wc -l /tmp/result.freqs | awk ' { print $1 } ')
+ if [ $num_freqs -ge 2 ]; then
+ tail -n 1 /tmp/result.freqs > /tmp/result.$1
else
- cat /proc/cpuinfo | grep MHz | sort -u > /tmp/result.$1
+ cp /tmp/result.freqs /tmp/result.$1
fi
./msr 0 >> /tmp/result.$1
@@ -82,21 +83,20 @@
max_freq=$(($_max_freq / 1000))
-for freq in `seq $max_freq -100 $min_freq`
+[ $EVALUATE_ONLY -eq 0 ] && for freq in `seq $max_freq -100 $min_freq`
do
echo "Setting maximum frequency to $freq"
cpupower frequency-set -g powersave --max=${freq}MHz >& /dev/null
- [ $EVALUATE_ONLY -eq 0 ] && run_test $freq
+ run_test $freq
done
-echo "=============================================================================="
+[ $EVALUATE_ONLY -eq 0 ] && cpupower frequency-set -g powersave --max=${max_freq}MHz >& /dev/null
+echo "=============================================================================="
echo "The marketing frequency of the cpu is $mkt_freq MHz"
echo "The maximum frequency of the cpu is $max_freq MHz"
echo "The minimum frequency of the cpu is $min_freq MHz"
-cpupower frequency-set -g powersave --max=${max_freq}MHz >& /dev/null
-
# make a pretty table
echo "Target Actual Difference MSR(0x199) max_perf_pct"
for freq in `seq $max_freq -100 $min_freq`
@@ -104,10 +104,6 @@
result_freq=$(cat /tmp/result.${freq} | grep "cpu MHz" | awk ' { print $4 } ' | awk -F "." ' { print $1 } ')
msr=$(cat /tmp/result.${freq} | grep "msr" | awk ' { print $3 } ')
max_perf_pct=$(cat /tmp/result.${freq} | grep "max_perf_pct" | awk ' { print $2 } ' )
- if [ $result_freq -eq $freq ]; then
- echo " $freq $result_freq 0 $msr $(($max_perf_pct*3300))"
- else
- echo " $freq $result_freq $(($result_freq-$freq)) $msr $(($max_perf_pct*$max_freq))"
- fi
+ echo " $freq $result_freq $(($result_freq-$freq)) $msr $(($max_perf_pct*$max_freq))"
done
exit 0
diff --git a/tools/usb/usbip/src/usbip_detach.c b/tools/usb/usbip/src/usbip_detach.c
index 9db9d21..6a8db85 100644
--- a/tools/usb/usbip/src/usbip_detach.c
+++ b/tools/usb/usbip/src/usbip_detach.c
@@ -43,7 +43,7 @@
static int detach_port(char *port)
{
- int ret;
+ int ret = 0;
uint8_t portnum;
char path[PATH_MAX+1];
@@ -73,9 +73,12 @@
}
ret = usbip_vhci_detach_device(portnum);
- if (ret < 0)
- return -1;
+ if (ret < 0) {
+ ret = -1;
+ goto call_driver_close;
+ }
+call_driver_close:
usbip_vhci_driver_close();
return ret;
diff --git a/verity_dev_keys.x509 b/verity_dev_keys.x509
new file mode 100644
index 0000000..86399c3
--- /dev/null
+++ b/verity_dev_keys.x509
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIID/TCCAuWgAwIBAgIJAJcPmDkJqolJMA0GCSqGSIb3DQEBBQUAMIGUMQswCQYD
+VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4g
+VmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEQMA4GA1UE
+AwwHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAe
+Fw0xNDExMDYxOTA3NDBaFw00MjAzMjQxOTA3NDBaMIGUMQswCQYDVQQGEwJVUzET
+MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4G
+A1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEQMA4GA1UEAwwHQW5kcm9p
+ZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAOjreE0vTVSRenuzO9vnaWfk0eQzYab0gqpi
+6xAzi6dmD+ugoEKJmbPiuE5Dwf21isZ9uhUUu0dQM46dK4ocKxMRrcnmGxydFn6o
+fs3ODJMXOkv2gKXL/FdbEPdDbxzdu8z3yk+W67udM/fW7WbaQ3DO0knu+izKak/3
+T41c5uoXmQ81UNtAzRGzGchNVXMmWuTGOkg6U+0I2Td7K8yvUMWhAWPPpKLtVH9r
+AL5TzjYNR92izdKcz3AjRsI3CTjtpiVABGeX0TcjRSuZB7K9EK56HV+OFNS6I1NP
+jdD7FIShyGlqqZdUOkAUZYanbpgeT5N7QL6uuqcGpoTOkalu6kkCAwEAAaNQME4w
+HQYDVR0OBBYEFH5DM/m7oArf4O3peeKO0ZIEkrQPMB8GA1UdIwQYMBaAFH5DM/m7
+oArf4O3peeKO0ZIEkrQPMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB
+AHO3NSvDE5jFvMehGGtS8BnFYdFKRIglDMc4niWSzhzOVYRH4WajxdtBWc5fx0ix
+NF/+hVKVhP6AIOQa+++sk+HIi7RvioPPbhjcsVlZe7cUEGrLSSveGouQyc+j0+m6
+JF84kszIl5GGNMTnx0XRPO+g8t6h5LWfnVydgZfpGRRg+WHewk1U2HlvTjIceb0N
+dcoJ8WKJAFWdcuE7VIm4w+vF/DYX/A2Oyzr2+QRhmYSv1cusgAeC1tvH4ap+J1Lg
+UnOu5Kh/FqPLLSwNVQp4Bu7b9QFfqK8Moj84bj88NqRGZgDyqzuTrFxn6FW7dmyA
+yttuAJAEAymk1mipd9+zp38=
+-----END CERTIFICATE-----
diff --git a/virt/kvm/arm/hyp/vgic-v2-sr.c b/virt/kvm/arm/hyp/vgic-v2-sr.c
index 9502124..3d6dbdf 100644
--- a/virt/kvm/arm/hyp/vgic-v2-sr.c
+++ b/virt/kvm/arm/hyp/vgic-v2-sr.c
@@ -203,7 +203,7 @@
return -1;
rd = kvm_vcpu_dabt_get_rd(vcpu);
- addr = kern_hyp_va((kern_hyp_va(&kvm_vgic_global_state))->vcpu_base_va);
+ addr = kern_hyp_va(hyp_symbol_addr(kvm_vgic_global_state)->vcpu_base_va);
addr += fault_ipa - vgic->vgic_cpu_base;
if (kvm_vcpu_dabt_iswrite(vcpu)) {
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index 4d28a9d..3f24eb1 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -119,8 +119,12 @@
{
struct kvm_kernel_irqfd *irqfd =
container_of(work, struct kvm_kernel_irqfd, shutdown);
+ struct kvm *kvm = irqfd->kvm;
u64 cnt;
+ /* Make sure irqfd has been initalized in assign path. */
+ synchronize_srcu(&kvm->irq_srcu);
+
/*
* Synchronize with the wait-queue and unhook ourselves to prevent
* further events.
@@ -387,7 +391,6 @@
idx = srcu_read_lock(&kvm->irq_srcu);
irqfd_update(kvm, irqfd);
- srcu_read_unlock(&kvm->irq_srcu, idx);
list_add_tail(&irqfd->list, &kvm->irqfds.items);
@@ -421,6 +424,7 @@
}
#endif
+ srcu_read_unlock(&kvm->irq_srcu, idx);
return 0;
fail: