diff --git a/Documentation/devicetree/bindings/fb/mdss-mdp.txt b/Documentation/devicetree/bindings/fb/mdss-mdp.txt index 7ad5888dd815b..c92d4e40f820a 100644 --- a/Documentation/devicetree/bindings/fb/mdss-mdp.txt +++ b/Documentation/devicetree/bindings/fb/mdss-mdp.txt @@ -402,8 +402,36 @@ Fudge Factors: Fudge factors are used to boost demand for applied in scenarios where panel interface can be more tolerant to memory latency such as command mode panels. -- qcom,max-bandwidth-per-pipe-kbps: This value indicates the max bandwidth in KB - that a single pipe can support without underflow. +- qcom,max-bandwidth-per-pipe-kbps: A two dimensional array indicating the max + bandwidth in KB that a single pipe can support + without underflow for various usecases. The + first parameter indicates the usecase and the + second parameter gives the max bw allowed for + the usecase. Following are the enum values for + modes in different cases: + For default case, mode = 1 + camera usecase, mode = 2 + hflip usecase, mode = 4 + vflip usecase, mode = 8 + First parameter/mode value need to match enum, + mdss_mdp_max_bw_mode, present in + include/uapi/linux/msm_mdp.h. +- qcom,max-bw-settings: This two dimension array indicates the max bandwidth + in KB that has to be supported when particular + scenarios are involved such as camera, flip. + The first parameter indicate the + scenario/usecase and second paramter indicate + the maximum bandwidth for that usecase. + Following are the enum values for modes in different + cases: + For default case, mode = 1 + camera usecase, mode = 2 + hflip usecase, mode = 4 + vflip usecase, mode = 8 + First parameter/mode value need to match enum, + mdss_mdp_max_bw_mode, present in + include/uapi/linux/msm_mdp.h. + - qcom,mdss-has-panic-ctrl: Boolean property to indicate if panic/robust signal control feature is available or not. - qcom,mdss-pipe-vig-panic-ctrl-offsets: Array of panic/robust signal offsets @@ -523,6 +551,13 @@ Example: qcom,max-bandwidth-low-kbps = <2300000>; qcom,max-bandwidth-high-kbps = <3000000>; + qcom,max-bandwidth-per-pipe-kbps = <4 2100000>, + <8 1800000>; + qcom,max-bw-settings = <1 2300000>, + <2 1700000>, + <4 2300000>, + <8 2000000>; + qcom,max-mixer-width = <2048>; qcom,max-clk-rate = <320000000>; qcom,vbif-settings = <0x0004 0x00000001>, diff --git a/Documentation/devicetree/bindings/input/misc/bmi160.txt b/Documentation/devicetree/bindings/input/misc/bmi160.txt new file mode 100644 index 0000000000000..7fe6eedb09b0f --- /dev/null +++ b/Documentation/devicetree/bindings/input/misc/bmi160.txt @@ -0,0 +1,49 @@ +BOSCH 6-axis accelerometer and gyroscope sensor driver. + +Required properties: + + - compatible : Should be "bosch,bmi160". + - reg : i2c slave address of the device. + - pinctrl-names : Pinctrl configuration names of this sensor driver. + Should be "default". + - pinctrl-0 : The pinctrl node corresponding to "default", + should be <&bmi160_int1_default &bmi160_int2_default>. + - interrupt-parent : Parent of interrupt. + - interrupts : Accelerometer interrupts to indicate new data ready or events. + - vdd-supply : Analog power supply needed to power device. + - vio-supply : Digital IO power supply needed for IO and I2C. + - bosch,init-interval : Initial data polling interval in millisecond. + - bosch,place : The placing of the accelerometer on board. There are 8 + patterns of placing described as below: + 0: 1st pin is right down + 1: 1st pin is left down + 2: 1st pin is left top + 3: 1st pin is right top + 4: 1st pin is left down (from top view) + 5: 1st pin is left top (from top view) + 6: 1st pin is right top (from top view) + 7: 1st pin is right down (from top view) + +Optional properties: + + - bosch,gpio-int1 : 1st irq gpio which is to provide interrupts + to host, interrupt events can be route to any of + these two irq pins according device configuration. + - bosch,gpio-int2 : 2nd irq gpio which is to provide interrupts + to host. +Example: +&i2c_0 { /* BLSP1 QUP2 */ + bosch@68 { /* Accelerometer and Gyroscope sensor */ + compatible = "bosch,bmi160"; + reg = <0x68>; + pinctrl-names = "default"; + pinctrl-0 = <&bmi160_int1_default>; + interrupt-parent = <&msm_gpio>; + interrupts = <96 0x2002>; + vdd-supply = <&pm8916_l17>; + vio-supply = <&pm8916_l6>; + bosch,init-interval = <200>; + bosch,place = <1>; + bosch,gpio-int1 = <&msm_gpio 96 0x2002>; + }; +}; diff --git a/Documentation/devicetree/bindings/input/misc/mmc3x30.txt b/Documentation/devicetree/bindings/input/misc/mmc3x30.txt new file mode 100644 index 0000000000000..f050cdc8cc918 --- /dev/null +++ b/Documentation/devicetree/bindings/input/misc/mmc3x30.txt @@ -0,0 +1,58 @@ +MEMSIC MMC3x30 3-axis magnetic sensor + +The MEMSIC 3-axis magnetic sensor is a complete 3-axis magnetic sensor with +on-chip signal processing and intergrated i2c bus. It can be connected to host +processor via i2c. It can measure magnetic fields within the full scale range +from -16 Gauss to +16 Gauss. + +Required properties: + + - compatible : Should be "memsic,mmc3x30". + - reg : i2c address of the device. + - vdd-supply : Analog power supply needed to power up the device. + - vio-supply : Digital IO power supply needed for IO and I2C. + - memsic,dir : String value of the direction of the ecompass sensor + chip. There are 8 patterns of direction: + + + x > 0 /___________o + / /| + / / |* 1st pin is here + /________/ /| + |_______/|/ |/ z > 0 + / + |/ y > 0 + + + The above graph shows the coordinate of the sensor chip. Specify the + following string to memsic,dir to convert it into Android coordinate. + Note the definition of sensor placement on target board is relative to + Android portrait mode. + + left right up down + obverse-x-axis-forward Y+ Y- X+ X- + obverse-x-axis-rightward X- X+ Y+ Y- + obverse-x-axis-backward Y- Y+ X- X+ + obverse-x-axis-leftward X+ X- Y- Y+ + reverse-x-axis-forward Y- Y+ X+ X- + reverse-x-axis-rightward X- X+ Y- Y+ + reverse-x-axis-backward Y+ Y- X- X+ + reverse-x-axis-leftward X+ X- Y+ Y- + +Optional properites: + + - memsic,auto-report : Boolean value to indicate if enable auto-report mode. + + Example: + A chip on 8916 platform with the pattern as the above graph: + &i2c_0 { /* BLSP1 QUP2 */ + memsic@30 { + compatible = "memsic,mmc3x30"; + reg = <0x30>; + vdd-supply = <&pm8916_l17>; + vio-supply = <&pm8916_l6>; + memsic,dir = "obverse-x-axis-forward"; + memsic,auto-report; + }; + }; + diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index fd22b040a2ac3..c1db21030e504 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -1276,6 +1276,13 @@ router_solicitations - INTEGER routers are present. Default: 3 +use_oif_addrs_only - BOOLEAN + When enabled, the candidate source addresses for destinations + routed via this interface are restricted to the set of addresses + configured on this interface (vis. RFC 6724, section 4). + + Default: false + use_tempaddr - INTEGER Preference for Privacy Extensions (RFC3041). <= 0 : disable Privacy Extensions @@ -1357,6 +1364,19 @@ ndisc_notify - BOOLEAN 1 - Generate unsolicited neighbour advertisements when device is brought up or hardware address changes. +optimistic_dad - BOOLEAN + Whether to perform Optimistic Duplicate Address Detection (RFC 4429). + 0: disabled (default) + 1: enabled + +use_optimistic - BOOLEAN + If enabled, do not classify optimistic addresses as deprecated during + source address selection. Preferred addresses will still be chosen + before optimistic addresses, subject to other ranking in the source + address selection algorithm. + 0: disabled (default) + 1: enabled + icmp/*: ratelimit - INTEGER Limit the maximal rates for sending ICMPv6 packets. diff --git a/Documentation/networking/key-mgmt-offload.txt b/Documentation/networking/key-mgmt-offload.txt deleted file mode 100644 index 9b18b0208cce6..0000000000000 --- a/Documentation/networking/key-mgmt-offload.txt +++ /dev/null @@ -1,147 +0,0 @@ -Key management offload is a mechanism where a station's device driver -or firmware/hardware does the exchange with the AP to establish the -temporal keys to be used for communications protection, rather than -having the supplicant do it. This exchange takes place in a Robust -Security Network during initial connection or after a roam between -APs occurs. It might also happen during after the device handles a -PTK rekeying operation. - -This design only supports key management offload in a station -(non-AP STA). - -There are a couple of possible advantages to offloading key -management. - - Connection time might be reduced (initial connection and after - roaming) since fewer software components will be involved and - there will not need to be a switch between kernel space (device - driver) and user space (wpa_supplicant). - - Power savings might be achieved since user space modules might - run on a processor separate from the device driver and/or - firmware and that processor could be kept in a power saving mode - since it need not be involved in key manaqgement. - -Key management can be offloaded in the following cases. - - WPA or WPA2 with PSK - - 802.11r (Fast Transition) with PSK - - Opportunistic Key Caching (OKC) - -For WPA/WPA2 or 802.11r with PSK, the PSK is supplied to the device -driver by the supplicant. For the OKC case, the supplicant will handle -the initial 802.1X authentication. It will pass the resulting PMK -(session key) to the driver. The driver can subsequently use this key -for connection to an AP that has cached the security association -(PMKSA), allowing the device to offload key management while not having -to do the full 802.1X authentication. - -The following topics will now be covered. - 1. Advertisement - The capabilities of the device with relation to - key management offloads are made known to the supplicant. - 2. Information Passing - The supplicant provides necessary - information to the device to allow it to accomplish the offload. - 3. Indication - Mechanism for the driver to update the supplicant - that key management has taken place. - 4. Example - An example of how the interface is used to allow key - management offload to take place. - -Advertisement -------------- - -The host driver's capability to offload key management is advertised by -the wiphy capability flag WIPHY_FLAG_HAS_KEY_MGMT_OFFLOAD. Individual -key management and key derivation capabilities are advertised as part -of the device attributes. - -The following key management offload capabilities can be advertised. - NL80211_KEY_MGMT_OFFLOAD_SUPPORT_PSK - NL80211_KEY_MGMT_OFFLOAD_SUPPORT_FT_PSK - NL80211_KEY_MGMT_OFFLOAD_SUPPORT_PMKSA - -The following key derivation capabilities can be advertised. - NL80211_KEY_DERIVE_OFFLOAD_SUPPORT_IGTK - -The decision to enable key management offload for a particular -connection is indicated to the driver by the flag -ASSOC_REQ_OFFLOAD_KEY_MGMT in cfg80211_assoc_req_flags which is passed -in a cfg80211_connect command. - -Information Passing -------------------- -The device will need information from the supplicant to handle the key -management offload. For each type of key management offload, the -following information is needed. - -NL80211_KEY_MGMT_OFFLOAD_SUPPORT_PSK - The PSK will be needed. The PSK will be included in the - cfg80211_connect_params that is passed as part of cfg80211_connect. - -NL80211_KEY_MGMT_OFFLOAD_SUPPORT_FT_PSK - The PSK will be needed. The PSK will be included in the - cfg80211_connect_params that is passed as part of cfg80211_connect. - -NL80211_KEY_MGMT_OFFLOAD_SUPPORT_PMKSA - The PMK (MSK) will be needed. It is not available at initial - association connect time because the 802.1X authentication must - first take place before the PMK is established. The PMK will be - passed to the driver using cfg80211_key_mgmt_set_pmk in this case - once it is known. - -Indication ----------- - -On a successful key management offload, the driver will invoke -cfg80211_authorization_event with status NL80211_AUTHORIZED. If the -key management offload is not successful, then NL80211_CONNECTED is -passed as the status in cfg80211_authorization_event and it is expected -the supplicant will take over key management. - -The last used EAPOL key reply counter value is passed to the supplicant -in cfg80211_authorization_event. - -In the case of key management offload after roaming, -cfg80211_authorization_event will always be called immediately after a -call to cfg80211_roamed. - -In the case of PTK rekeying, cfg80211_authorization_event is called -after the device has handled rekeying. This allows the supplicant -to recieve an updated EAPOL key reply counter value. - -Example -------- - -As an example of how this interface can be used, the case of key -management offloading for a WPA2 connection is examined. - - 1. The driver advertises general key management offload capability - with the wiphy flag WIPHY_FLAG_HAS_KEY_MGMT_OFFLOAD. Device - attributes NL80211_KEY_MGMT_OFFLOAD_SUPPORT_PSK and - NL80211_KEY_DERIVE_OFFLOAD_SUPPORT_IGTK are advertised. - - 2. Using existing mechanisms, the supplicant decides that a - connection should be made to a network. The network is an RSN - supporting WPA2 and Protected Management Frames. Seeing that the - device supports key management offload for WPA2 and key derivation - for IGTK, it signals to the driver that it wants to take advantage - of key management offload by specifying ASSOC_REQ_OFFLOAD_KEY_MGMT - in cfg80211_assoc_req_flags in the cfg80211_connect command. The - PSK for the connection is also included in cfg80211_connect. - - 3. The supplicant enters the "connected" state as it currently does, - waiting for the first EAPOL frame to arrive so that the security - exchange can be done. The EAPOL frame is presented to the - supplicant and it completes the security exchange. This is all - existing functionality. No key management offload took place - during this initial connection (but it could have). - - 4. Sometime later, the supplicant gets a cfg80211_roamed indication, - telling the supplicant that the device roamed to a different AP. - Again, the supplicant enters "connected" state, waiting for the - first EAPOL frame so that the security exchange can be done with - the new AP. - - 5. Immediately, the supplicant gets a cfg80211_authorization_event - with success status, indicating that the key management has been - done by the device. The supplicant enters "authorized" state for - the connection and allows transmission and reception of data - frames on the network. Here, during roaming, the key management - was offloaded to the device and did not need to be handled by the - supplicant. diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index 6c46487210833..d438fd2c21a6a 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt @@ -447,7 +447,6 @@ This file shows up if CONFIG_DEBUG_STACKOVERFLOW is enabled. 0: try to continue operation. -1: panic immediately. ============================================================== diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt index b81fca90f7fe4..c7539eced6263 100644 --- a/Documentation/sysctl/vm.txt +++ b/Documentation/sysctl/vm.txt @@ -42,6 +42,8 @@ Currently, these files are in /proc/sys/vm: - min_slab_ratio - min_unmapped_ratio - mmap_min_addr +- mmap_rnd_bits +- mmap_rnd_compat_bits - nr_hugepages - nr_overcommit_hugepages - nr_trim_pages (only if CONFIG_MMU=n) @@ -455,6 +457,33 @@ against future potential kernel bugs. ============================================================== +mmap_rnd_bits: + +This value can be used to select the number of bits to use to +determine the random offset to the base address of vma regions +resulting from mmap allocations on architectures which support +tuning address space randomization. This value will be bounded +by the architecture's minimum and maximum supported values. + +This value can be changed after boot using the +/proc/sys/vm/mmap_rnd_bits tunable + +============================================================== + +mmap_rnd_compat_bits: + +This value can be used to select the number of bits to use to +determine the random offset to the base address of vma regions +resulting from mmap allocations for applications run in +compatibility mode on architectures which support tuning address +space randomization. This value will be bounded by the +architecture's minimum and maximum supported values. + +This value can be changed after boot using the +/proc/sys/vm/mmap_rnd_compat_bits tunable + +============================================================== + nr_hugepages Change the minimum size of the hugepage pool. diff --git a/arch/Kconfig b/arch/Kconfig index 1ee888b66806b..69fcfae907781 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -455,6 +455,74 @@ config HAVE_UNDERSCORE_SYMBOL_PREFIX Some architectures generate an _ in front of C symbols; things like module loading and assembly files need to know about this. +config HAVE_ARCH_MMAP_RND_BITS + bool + help + An arch should select this symbol if it supports setting a variable + number of bits for use in establishing the base address for mmap + allocations, has MMU enabled and provides values for both: + - ARCH_MMAP_RND_BITS_MIN + - ARCH_MMAP_RND_BITS_MAX + +config ARCH_MMAP_RND_BITS_MIN + int + +config ARCH_MMAP_RND_BITS_MAX + int + +config ARCH_MMAP_RND_BITS_DEFAULT + int + +config ARCH_MMAP_RND_BITS + int "Number of bits to use for ASLR of mmap base address" if EXPERT + range ARCH_MMAP_RND_BITS_MIN ARCH_MMAP_RND_BITS_MAX + default ARCH_MMAP_RND_BITS_DEFAULT if ARCH_MMAP_RND_BITS_DEFAULT + default ARCH_MMAP_RND_BITS_MIN + depends on HAVE_ARCH_MMAP_RND_BITS + help + This value can be used to select the number of bits to use to + determine the random offset to the base address of vma regions + resulting from mmap allocations. This value will be bounded + by the architecture's minimum and maximum supported values. + + This value can be changed after boot using the + /proc/sys/vm/mmap_rnd_bits tunable + +config HAVE_ARCH_MMAP_RND_COMPAT_BITS + bool + help + An arch should select this symbol if it supports running applications + in compatibility mode, supports setting a variable number of bits for + use in establishing the base address for mmap allocations, has MMU + enabled and provides values for both: + - ARCH_MMAP_RND_COMPAT_BITS_MIN + - ARCH_MMAP_RND_COMPAT_BITS_MAX + +config ARCH_MMAP_RND_COMPAT_BITS_MIN + int + +config ARCH_MMAP_RND_COMPAT_BITS_MAX + int + +config ARCH_MMAP_RND_COMPAT_BITS_DEFAULT + int + +config ARCH_MMAP_RND_COMPAT_BITS + int "Number of bits to use for ASLR of mmap base address for compatible applications" if EXPERT + range ARCH_MMAP_RND_COMPAT_BITS_MIN ARCH_MMAP_RND_COMPAT_BITS_MAX + default ARCH_MMAP_RND_COMPAT_BITS_DEFAULT if ARCH_MMAP_RND_COMPAT_BITS_DEFAULT + default ARCH_MMAP_RND_COMPAT_BITS_MIN + depends on HAVE_ARCH_MMAP_RND_COMPAT_BITS + help + This value can be used to select the number of bits to use to + determine the random offset to the base address of vma regions + resulting from mmap allocations for compatible applications This + value will be bounded by the architecture's minimum and maximum + supported values. + + This value can be changed after boot using the + /proc/sys/vm/mmap_rnd_compat_bits tunable + # # ABI hall of shame # diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1250889b5978c..2a3c8a108b82a 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -23,6 +23,7 @@ config ARM select HARDIRQS_SW_RESEND select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL select HAVE_ARCH_KGDB + select HAVE_ARCH_MMAP_RND_BITS if MMU select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_TRACEHOOK select HAVE_BPF_JIT @@ -302,6 +303,14 @@ config MMU Select if you want MMU-based virtualised addressing space support by paged memory management. If unsure, say 'Y'. +config ARCH_MMAP_RND_BITS_MIN + default 8 + +config ARCH_MMAP_RND_BITS_MAX + default 14 if PAGE_OFFSET=0x40000000 + default 15 if PAGE_OFFSET=0x80000000 + default 16 + # # The "ARM system type" choice list is ordered alphabetically by option # text. Please add new entries in the option alphabetic order. diff --git a/arch/arm/boot/dts/qcom/Makefile b/arch/arm/boot/dts/qcom/Makefile index 525e888283cb4..43ad882a9acf9 100644 --- a/arch/arm/boot/dts/qcom/Makefile +++ b/arch/arm/boot/dts/qcom/Makefile @@ -53,6 +53,7 @@ dtb-$(CONFIG_ARCH_MSM8909) += msm8909-sim.dtb \ msm8909-pm8916-qhd-rcm.dtb \ msm8909-pm8916-qrd-skut-evt.dtb \ msm8909-pm8916-qrd-skut-dvt.dtb \ + msm8909-pm8916-qrd-skuq.dtb \ msm8208-cdp.dtb \ msm8208-mtp.dtb \ msm8208-1gb-cdp.dtb \ diff --git a/arch/arm/boot/dts/qcom/apq8016.dtsi b/arch/arm/boot/dts/qcom/apq8016.dtsi index 7fa77b43971f4..b12c41a738e24 100644 --- a/arch/arm/boot/dts/qcom/apq8016.dtsi +++ b/arch/arm/boot/dts/qcom/apq8016.dtsi @@ -27,7 +27,7 @@ }; peripheral_mem: pheripheral_region@0 { - reg = <0x0 0x89300000 0x0 0x0600000>; + reg = <0x0 0x89300000 0x0 0x0700000>; }; }; }; diff --git a/arch/arm/boot/dts/qcom/dsi-panel-hx8394f-720p-video.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-hx8394f-720p-video.dtsi new file mode 100644 index 0000000000000..2c6688fd4c87b --- /dev/null +++ b/arch/arm/boot/dts/qcom/dsi-panel-hx8394f-720p-video.dtsi @@ -0,0 +1,122 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_hx8394f_720p_video: qcom,mdss_dsi_hx8394f_720p_video { + qcom,mdss-dsi-panel-name = "hx8394f 720p 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 = <720>; + qcom,mdss-dsi-panel-height = <1280>; + qcom,mdss-dsi-h-front-porch = <16>; + qcom,mdss-dsi-h-back-porch = <16>; + qcom,mdss-dsi-h-pulse-width = <8>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <12>; + qcom,mdss-dsi-v-front-porch = <15>; + qcom,mdss-dsi-v-pulse-width = <4>; + 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-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-on-command = [39 01 00 00 00 00 04 b9 ff 83 94 + 39 01 00 00 00 00 0b + b1 50 14 74 09 31 24 71 31 55 + 2f + 39 01 00 00 00 00 07 + ba 63 03 68 6b b2 c0 + 39 01 00 00 00 00 02 + d2 77 + 39 01 00 00 00 00 06 + b2 00 80 64 10 07 + 39 01 00 00 00 00 16 + b4 01 74 01 74 01 74 01 0c 86 + 75 00 3f 01 74 01 74 01 74 01 + 0c 86 + 39 01 00 00 00 00 22 + d3 00 00 07 07 40 1e 08 00 32 + 10 08 00 08 54 15 10 05 04 02 + 12 10 05 07 23 23 0c 0c 27 10 + 07 07 10 40 + 39 01 00 00 00 00 2d + d5 19 19 18 18 1b 1b 1a 1a 04 + 05 06 07 00 01 02 03 20 21 18 + 18 22 23 18 18 18 18 18 18 18 + 18 18 18 18 18 18 18 18 18 18 + 18 18 18 18 18 + 39 01 00 00 00 00 2d + d6 18 18 19 19 1b 1b 1a 1a 03 + 02 01 00 07 06 05 04 23 22 18 + 18 21 20 18 18 18 18 18 18 18 + 18 18 18 18 18 18 18 18 18 18 + 18 18 18 18 18 + 39 01 00 00 00 00 3b + e0 00 03 09 11 11 14 18 16 2e + 3d 4d 4d 58 6c 72 78 88 8b 86 + a4 b2 58 55 59 5b 5d 60 64 7f + 00 03 09 0f 11 14 18 16 2e 3d + 4d 4d 58 6d 73 78 88 8b 87 a5 + b2 58 55 58 5b 5d 61 65 7f + 39 01 00 00 00 00 02 + cc 0b + 39 01 00 00 00 00 03 + c0 1f 31 + 39 01 00 00 00 00 03 + b6 92 92 + 39 01 00 00 00 00 02 + bd 01 + 39 01 00 00 00 00 02 + b1 00 + 39 01 00 00 00 00 02 + bd 00 + 39 01 00 00 00 00 08 + bf 40 81 50 00 1a fc 01 + 39 01 00 00 00 00 02 + c6 ef + 05 01 00 00 78 00 02 + 11 00 + 05 01 00 00 14 00 02 + 29 00]; + qcom,mdss-dsi-off-command = [05 01 00 00 14 00 02 28 00 + 05 01 00 00 78 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-lane-map = "lane_map_0123"; + 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-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-panel-timings + = [6a 16 0e 00 38 3c 12 1a 10 03 04 00]; + qcom,mdss-dsi-t-clk-post = <0x04>; + qcom,mdss-dsi-t-clk-pre = <0x17>; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <255>; + 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-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-reset-sequence = <1 20>, <0 2>, <1 20>; + }; +}; diff --git a/arch/arm/boot/dts/qcom/msm8909-camera-sensor-skuq.dtsi b/arch/arm/boot/dts/qcom/msm8909-camera-sensor-skuq.dtsi new file mode 100755 index 0000000000000..b8e6af402a38a --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm8909-camera-sensor-skuq.dtsi @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +&tlmm_pinmux { + GPIOFLASH_pins { + qcom,pins = <&gp 31>, <&gp 32>; + qcom,num-grp-pins = <2>; + qcom,pin-func = <0>; + label = "GPIOFLASH_pins"; + GPIOFLASH_default: en_default { + drive-strength = <2>; + bias-pull-down; + }; + }; + + cam_mipi_switch { + qcom,pins = <&gp 9>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <0>; + label = "cam-mipi-switch"; + /* active state */ + cam_mipi_switch_default: default { + drive-strength = <2>; /* 2 MA */ + bias-disable = <0>; /* No PULL */ + }; + }; + + cam_mipi_switch_sleep { + qcom,pins = <&gp 9>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <0>; + label = "cam-mipi-switch"; + /* suspend state */ + cam_mipi_switch_sleep: sleep { + drive-strength = <2>; /* 2 MA */ + bias-pull-down = <0>; /* PULL DOWN */ + }; + }; +}; + +&soc { + flash_GPIOFLASH:flashlight { + compatible = "qcom,leds-gpio-flash"; + status = "okay"; + pinctrl-names = "flash_default"; + pinctrl-0 = <&GPIOFLASH_default>; + qcom,flash-en = <&msm_gpio 31 0>; + qcom,flash-now = <&msm_gpio 32 0>; + qcom,op-seq = "flash_en", "flash_now"; + qcom,torch-seq-val = <1 0>; + qcom,flash-seq-val = <1 1>; + linux,name = "flashlight"; + linux,default-trigger = "flashlight-trigger"; + }; + led_flash0: qcom,camera-led-flash { + cell-index = <0>; + compatible = "qcom,camera-led-flash"; + qcom,flash-type = <3>; + qcom,flash-source = <&flash_GPIOFLASH>; + qcom,torch-source = <&flash_GPIOFLASH>; + }; +}; + +&i2c_3 { + + actuator0: qcom,actuator@0 { + cell-index = <0>; + reg = <0x3>; + compatible = "qcom,actuator"; + qcom,cci-master = <0>; + cam_vaf-supply = <&pm8916_l8>; + qcom,cam-vreg-name = "cam_vaf"; + qcom,cam-vreg-type = <0>; + qcom,cam-vreg-min-voltage = <2850000>; + qcom,cam-vreg-max-voltage = <2900000>; + qcom,cam-vreg-op-mode = <80000>; + }; + + eeprom0: qcom,eeprom@20{ + cell-index = <0>; + reg = <0x20>; + qcom,eeprom-name = "truly_ov8856"; + compatible = "qcom,eeprom"; + qcom,slave-addr = <0x20>; + qcom,cci-master = <0>; + + qcom,num-blocks = <10>; + qcom,page0 = <1 0x0100 2 0x01 1 1>; + qcom,poll0 = <0 0x0 2 0 1 1>; + qcom,mem0 = <0 0x0 2 0 1 0>; + qcom,page1 = <1 0x5002 2 0xa8 1 1>; + qcom,poll1 = <0 0x0 2 0 1 1>; + qcom,mem1 = <0 0x0 2 0 1 0>; + qcom,page2 = <1 0x3d84 2 0xc0 1 1>; + qcom,poll2 = <0 0x0 2 0 1 1>; + qcom,mem2 = <0 0x0 2 0 1 0>; + qcom,page3 = <1 0x3d88 2 0x7010 2 1>; + qcom,poll3 = <0 0x0 2 0 1 1>; + qcom,mem3 = <0 0x3d00 2 0 1 0>; + qcom,page4 = <1 0x3d8a 2 0x720a 2 1>; + qcom,poll4 = <0 0x0 2 0 1 1>; + qcom,mem4 = <0 0x3d00 2 0 1 0>; + qcom,page5 = <1 0x3d81 2 0x01 1 10>; + qcom,poll5 = <0 0x0 2 0 1 1>; + qcom,mem5 = <0 0x3d00 2 0 1 0>; + qcom,page6 = <0 0x0 2 0x0 1 1>; + qcom,poll6 = <0 0x0 2 0 1 1>; + qcom,mem6 = <507 0x7010 2 0 1 0>; + qcom,page7 = <0 0x0 2 0x0 1 1>; + qcom,poll7 = <0 0x0 2 0 1 1>; + qcom,mem7 = <1 0x5000 2 0 1 1>; + qcom,page8 = <1 0x5002 2 0xaa 1 1>; + qcom,poll8 = <0 0x0 2 0 1 1>; + qcom,mem8 = <0 0x0 2 0 1 0>; + qcom,page9 = <1 0x5002 2 0x00 1 1>; + qcom,poll9 = <0 0x0 2 0 1 1>; + qcom,mem9 = <0 0x0 2 0 1 0>; + + cam_vdig-supply = <&pm8916_l2>; + cam_vana-supply = <&pm8916_l17>; + cam_vio-supply = <&pm8916_l6>; + cam_vaf-supply = <&pm8916_l8>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", + "cam_vaf"; + qcom,cam-vreg-type = <0 1 0 0>; + qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-max-voltage = <1200000 0 2850000 2900000>; + qcom,cam-vreg-op-mode = <200000 0 80000 100000>; + 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_RESET1", + "CAM_STANDBY"; + + qcom,cam-power-seq-type = "sensor_vreg", + "sensor_vreg", "sensor_vreg", + "sensor_gpio", "sensor_gpio", + "sensor_clk"; + qcom,cam-power-seq-val = "cam_vio", + "cam_vana", "cam_vdig", + "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 = <10 10 10 10 10 5>; + + clocks = <&clock_gcc clk_mclk0_clk_src>, + <&clock_gcc clk_gcc_camss_mclk0_clk>; + clock-names = "cam_src_clk", "cam_clk"; + }; + + 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>; + qcom,actuator-src = <&actuator0>; + qcom,led-flash-src = <&led_flash0>; + qcom,eeprom-src = <&eeprom0>; + cam_vdig-supply = <&pm8916_l2>; + cam_vana-supply = <&pm8916_l17>; + cam_vio-supply = <&pm8916_l6>; + cam_vaf-supply = <&pm8916_l8>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", + "cam_vaf"; + qcom,cam-vreg-type = <0 1 0 0>; + qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-max-voltage = <1200000 0 2850000 2900000>; + qcom,cam-vreg-op-mode = <200000 0 80000 100000>; + 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>, + <&msm_gpio 9 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-custom1 = <3>; + qcom,gpio-req-tbl-num = <0 1 2 3>; + qcom,gpio-req-tbl-flags = <1 0 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK", + "CAM_RESET1", + "CAM_STANDBY", + "CAM_MIPI_SWITCH"; + qcom,sensor-position = <0>; + qcom,sensor-mode = <0>; + qcom,cci-master = <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,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_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-type = <0 1 0>; + qcom,cam-vreg-min-voltage = <1200000 0 2850000>; + qcom,cam-vreg-max-voltage = <1200000 0 2850000>; + qcom,cam-vreg-op-mode = <200000 0 80000>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_default &cam_sensor_front_default + &cam_mipi_switch_default>; + pinctrl-1 = <&cam_sensor_mclk1_sleep &cam_sensor_front_sleep + &cam_mipi_switch_sleep>; + gpios = <&msm_gpio 27 0>, + <&msm_gpio 28 0>, + <&msm_gpio 33 0>, + <&msm_gpio 9 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-custom1 = <3>; + qcom,gpio-req-tbl-num = <0 1 2 3>; + qcom,gpio-req-tbl-flags = <1 0 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK", + "CAM_RESET", + "CAM_STANDBY", + "CAM_MIPI_SWITCH"; + qcom,sensor-position = <1>; + qcom,cci-master = <0>; + status = "ok"; + clocks = <&clock_gcc clk_mclk1_clk_src>, + <&clock_gcc clk_gcc_camss_mclk1_clk>; + clock-names = "cam_src_clk", "cam_clk"; + }; +}; diff --git a/arch/arm/boot/dts/qcom/msm8909-camera.dtsi b/arch/arm/boot/dts/qcom/msm8909-camera.dtsi index 5e96cb1abaa6e..8c7a22c40e04f 100644 --- a/arch/arm/boot/dts/qcom/msm8909-camera.dtsi +++ b/arch/arm/boot/dts/qcom/msm8909-camera.dtsi @@ -98,6 +98,8 @@ interrupt-names = "ispif"; clocks = <&clock_gcc clk_gcc_camss_ispif_ahb_clk>, <&clock_gcc clk_gcc_camss_ahb_clk>, + <&clock_gcc clk_gcc_camss_top_ahb_clk>, + <&clock_gcc clk_camss_top_ahb_clk_src>, <&clock_gcc clk_csi0_clk_src>, <&clock_gcc clk_gcc_camss_csi0_clk>, <&clock_gcc clk_gcc_camss_csi0pix_clk>, @@ -110,12 +112,13 @@ <&clock_gcc clk_gcc_camss_vfe0_clk>, <&clock_gcc clk_gcc_camss_csi_vfe0_clk>; clock-names = "ispif_ahb_clk","camss_ahb_clk", + "camss_top_ahb_clk", "camss_ahb_src", "csi0_src_clk", "csi0_clk", "csi0_pix_clk","csi0_rdi_clk", "csi1_src_clk", "csi1_clk", "csi1_pix_clk", "csi1_rdi_clk", "vfe0_clk_src", "camss_vfe_vfe0_clk", "camss_csi_vfe0_clk"; - qcom,clock-rates = <40000000 0 0 0 0 0 0 0 0 0 0 0 0>; + qcom,clock-rates = <40000000 0 0 0 0 0 0 0 0 0 0 0 0 0 0>; }; qcom,vfe@1b10000 { diff --git a/arch/arm/boot/dts/qcom/msm8909-pinctrl.dtsi b/arch/arm/boot/dts/qcom/msm8909-pinctrl.dtsi index c33e6bda0f242..7787956b35e29 100644 --- a/arch/arm/boot/dts/qcom/msm8909-pinctrl.dtsi +++ b/arch/arm/boot/dts/qcom/msm8909-pinctrl.dtsi @@ -1206,6 +1206,17 @@ }; }; + gpio_led_pins { + qcom,pins = <&gp 91>, <&gp 92>; + qcom,num-grp-pins = <2>; + label = "gpio-led-pins"; + gpio_led_off: led_off { + drive-strength = <2>; + bias-disable; /* no pullup */ + output-low; + }; + }; + /* add pingrp for touchscreen */ pmx_ts_int_active { qcom,pins = <&gp 13>; diff --git a/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dts b/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dts new file mode 100644 index 0000000000000..b3e2128eed3ea --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dts @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "msm8909-pm8916-qrd-skuq.dtsi" + +/ { + qcom,board-id= <0x6040b 0x0>; +}; diff --git a/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi b/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi new file mode 100644 index 0000000000000..7a5bbf61f5879 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm8909-pm8916-qrd-skuq.dtsi @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "msm8909-pm8916-qrd.dtsi" +#include "msm8909-camera-sensor-skuq.dtsi" +/ { + model = "Qualcomm Technologies, Inc. MSM8909-PM8916 QSIP SKUQ"; + compatible = "qcom,msm8909-qrd", "qcom,msm8909", "qcom,qrd"; + qcom,msm-id = <245 0>, + <258 0>, + <275 0>, + <300 0>; +}; + +&tlmm_pinmux { + bmi160_int1_pin { + qcom,pins = <&gp 96>; + qcom,num-grp-pins = <1>; + label = "bmi160_int1_pin"; + bmi160_int1_default: int1_default { + drive-strength = <6>; + bias-pull-up; + }; + }; + +}; + +&pm8916_chg { + status = "ok"; +}; + +&pm8916_bms { + status = "ok"; +}; + +&soc { + sound { + compatible = "qcom,msm8x16-audio-codec"; + qcom,model = "msm8909-skuq-snd-card"; + qcom,msm-snd-card-id = <0>; + qcom,msm-codec-type = "internal"; + qcom,msm-ext-pa = "primary"; + qcom,msm-mclk-freq = <9600000>; + qcom,msm-mbhc-hphl-swh = <1>; + qcom,msm-mbhc-gnd-swh = <0>; + qcom,msm-hs-micbias-type = "internal"; + qcom,msm-micbias1-ext-cap; + qcom,audio-routing = + "RX_BIAS", "MCLK", + "SPK_RX_BIAS", "MCLK", + "INT_LDO_H", "MCLK", + "MIC BIAS External", "Handset Mic", + "MIC BIAS Internal2", "Headset Mic", + "MIC BIAS External", "Secondary Mic", + "AMIC1", "MIC BIAS External", + "AMIC2", "MIC BIAS Internal2", + "AMIC3", "MIC BIAS External"; + pinctrl-names = "cdc_lines_act", + "cdc_lines_sus"; + pinctrl-0 = <&cdc_pdm_lines_act>; + pinctrl-1 = <&cdc_pdm_lines_sus>; + asoc-platform = <&pcm0>, <&pcm1>, <&voip>, <&voice>, + <&loopback>, <&compress>, <&hostless>, + <&afe>, <&lsm>, <&routing>, <&lpa>, + <&voice_svc>; + asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1", + "msm-voip-dsp", "msm-pcm-voice", "msm-pcm-loopback", + "msm-compress-dsp", "msm-pcm-hostless", "msm-pcm-afe", + "msm-lsm-client", "msm-pcm-routing", "msm-pcm-lpa", + "msm-voice-svc"; + asoc-cpu = <&dai_pri_auxpcm>, <&dai_mi2s0>, <&dai_mi2s1>, <&dai_mi2s2>, + <&dai_mi2s3>, <&bt_sco_rx>, <&bt_sco_tx>, <&bt_a2dp_rx>, + <&int_fm_rx>, <&int_fm_tx>, <&afe_pcm_rx>, <&afe_pcm_tx>, + <&afe_proxy_rx>, <&afe_proxy_tx>, <&incall_record_rx>, + <&incall_record_tx>, <&incall_music_rx>, <&incall_music_2_rx>; + asoc-cpu-names = "msm-dai-q6-auxpcm.1", + "msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1", + "msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3", + "msm-dai-q6-dev.12288", "msm-dai-q6-dev.12289", + "msm-dai-q6-dev.12290", + "msm-dai-q6-dev.12292", "msm-dai-q6-dev.12293", + "msm-dai-q6-dev.224", "msm-dai-q6-dev.225", + "msm-dai-q6-dev.241", "msm-dai-q6-dev.240", + "msm-dai-q6-dev.32771", "msm-dai-q6-dev.32772", + "msm-dai-q6-dev.32773", "msm-dai-q6-dev.32770"; + asoc-codec = <&stub_codec>, <&pm8916_tombak_dig>; + asoc-codec-names = "msm-stub-codec.1", "tombak_codec"; + }; + + gpio-leds { + compatible = "gpio-leds"; + STAtus = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&gpio_led_off>; + + red { + gpios = <&msm_gpio 91 0>; + label = "red"; + linux,default-trigger = "none"; + default-state = "off"; + retain-state-suspended; + }; + + green { + gpios = <&msm_gpio 92 0>; + label = "green"; + linux,default-trigger = "none"; + default-state = "off"; + retain-state-suspended; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + input-name = "gpio-keys"; + pinctrl-names = "tlmm_gpio_key_active","tlmm_gpio_key_suspend"; + pinctrl-0 = <&gpio_key_active>; + pinctrl-1 = <&gpio_key_suspend>; + + vol_up { + label = "volume_up"; + gpios = <&msm_gpio 90 0x1>; + linux,input-type = <1>; + linux,code = <115>; + gpio-key,wakeup; + debounce-interval = <15>; + }; + + /delete-node/ vol_down; + }; + + i2c@78b5000 { + bosch@68 { /* Accelerometer and gyroscope sensor */ + compatible = "bosch,bmi160"; + reg = <0x68>; + pinctrl-names = "default"; + pinctrl-0 = <&bmi160_int1_default>; + interrupt-parent = <&msm_gpio>; + interrupts = <96 0x2002>; + vdd-supply = <&pm8916_l17>; + vio-supply = <&pm8916_l6>; + bosch,place = <5>; + bosch,gpio-int1 = <&msm_gpio 96 0x2002>; + }; + + memsic@30 { /* Magnetic field sensor */ + compatible = "memsic,mmc3x30"; + reg = <0x30>; + vdd-supply = <&pm8916_l17>; + vio-supply = <&pm8916_l6>; + memsic,dir = "obverse-x-axis-forward"; + memsic,auto-report; + }; + + stk@48 { + compatible = "stk,stk3x1x"; + reg = <0x48>; + interrupt-parent = <&msm_gpio>; + interrupts = <80 0x2>; + vdd-supply = <&pm8916_l17>; + vio-supply = <&pm8916_l6>; + stk,irq-gpio = <&msm_gpio 80 0x02>; + stk,transmittance = <340>; + stk,state-reg = <0x00>; + stk,psctrl-reg = <0x71>; + stk,alsctrl-reg = <0x38>; + stk,ledctrl-reg = <0xFF>; + stk,wait-reg = <0x07>; + stk,ps-thdh = <150>; + stk,ps-thdl = <100>; + stk,use-fir; + }; + }; +}; + +&pm8916_mpps { + mpp@a300 { /* MPP 4 */ + /* Backlight PWM */ + qcom,mode = <1>; /* Digital output */ + qcom,invert = <0>; /* Disable invert */ + qcom,src-sel = <4>; /* DTEST1 */ + qcom,vin-sel = <0>; /* VPH_PWR */ + qcom,master-en = <1>; /* Enable MPP */ + }; +}; + +#include "dsi-panel-hx8394f-720p-video.dtsi" + +&mdss_mdp { + qcom,mdss-pref-prim-intf = "dsi"; +}; + +&dsi_hx8394f_720p_video { + qcom,cont-splash-enabled; + qcom,mdss-dsi-pwm-gpio = <&pm8916_mpps 4 0>; +}; + +&pmx_mdss { + qcom,num-grp-pins = <3>; + qcom,pins = <&gp 25>, <&gp 11>, <&gp 10>; +}; + +&pmx_mdss_te { + qcom,num-grp-pins = <1>; + qcom,pins = <&gp 24>; +}; + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_hx8394f_720p_video>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + + qcom,platform-reset-gpio = <&msm_gpio 25 0>; +}; + +&sdc2_cd_on { + /delete-property/ bias-pull-up; + bias-pull-down; +}; + +&sdc2_cd_off { + /delete-property/ bias-disable; + bias-pull-down; +}; + +&sdhc_2 { + qcom,nonremovable; + + interrupts = <0 1>; + interrupt-map = <0 &intc 0 125 0 + 1 &intc 0 221 0>; + interrupt-names = "hc_irq", "pwr_irq"; + /delete-property/ cd-gpios; +}; diff --git a/arch/arm/boot/dts/qcom/msm8939-common.dtsi b/arch/arm/boot/dts/qcom/msm8939-common.dtsi index 91bafb56e4ecb..d641aa37d1e19 100644 --- a/arch/arm/boot/dts/qcom/msm8939-common.dtsi +++ b/arch/arm/boot/dts/qcom/msm8939-common.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -578,6 +578,7 @@ interrupt-names = "slimbus_irq", "slimbus_bam_irq"; qcom,apps-ch-pipes = <0x600000>; qcom,ea-pc = <0x140>; + qcom,subsys-name = "modem"; status = "disabled"; }; diff --git a/arch/arm/boot/dts/qcom/msm8939-mdss.dtsi b/arch/arm/boot/dts/qcom/msm8939-mdss.dtsi index 9332e6e49e625..4e8e8ec1dd33d 100644 --- a/arch/arm/boot/dts/qcom/msm8939-mdss.dtsi +++ b/arch/arm/boot/dts/qcom/msm8939-mdss.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -34,9 +34,16 @@ qcom,mdss-ib-factor = <2 1>; /* 2 times */ qcom,mdss-ib-factor-cmd = <10 6>; /* 1.6 times */ qcom,mdss-clk-factor = <105 100>; /* 1.05 times */ - qcom,max-bandwidth-low-kbps = <2000000>; - qcom,max-bandwidth-high-kbps = <2000000>; - qcom,max-bandwidth-per-pipe-kbps = <1500000>; + qcom,max-bandwidth-low-kbps = <2500000>; + qcom,max-bandwidth-high-kbps = <2500000>; + qcom,max-bandwidth-per-pipe-kbps = <1 2100000>, /* Default */ + <2 1500000>; /* Camera */ + + /* Bandwidth limit settings */ + qcom,max-bw-settings = <1 2500000>, /* Default */ + <2 2100000>, /* Camera */ + <4 1900000>, /* HFlip */ + <8 1900000>; /* VFlip */ /* VBIF QoS remapper settings*/ qcom,mdss-vbif-qos-rt-setting = <2 2 2 2>; diff --git a/arch/arm/configs/cyanogenmod_wt88047_defconfig b/arch/arm/configs/cyanogenmod_wt88047_defconfig index 8af4dbd912925..4f1062096b4e1 100644 --- a/arch/arm/configs/cyanogenmod_wt88047_defconfig +++ b/arch/arm/configs/cyanogenmod_wt88047_defconfig @@ -32,7 +32,7 @@ CONFIG_BUILDTIME_EXTABLE_SORT=y # CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_CROSS_COMPILE="" -CONFIG_LOCALVERSION="-blackhawk" +CONFIG_LOCALVERSION="-cyanogenmod" CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_LZMA=y @@ -666,6 +666,7 @@ CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_INET_UDP_DIAG is not set +# CONFIG_INET_DIAG_DESTROY is not set # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" @@ -845,7 +846,7 @@ CONFIG_NF_CONNTRACK_PROC_COMPAT=y CONFIG_IP_NF_IPTABLES=y CONFIG_IP_NF_MATCH_AH=y CONFIG_IP_NF_MATCH_ECN=y -# CONFIG_IP_NF_MATCH_RPFILTER is not set +CONFIG_IP_NF_MATCH_RPFILTER=y CONFIG_IP_NF_MATCH_TTL=y CONFIG_IP_NF_FILTER=y CONFIG_IP_NF_TARGET_REJECT=y @@ -882,7 +883,7 @@ CONFIG_IP6_NF_IPTABLES=y # CONFIG_IP6_NF_MATCH_HL is not set # CONFIG_IP6_NF_MATCH_IPV6HEADER is not set # CONFIG_IP6_NF_MATCH_MH is not set -# CONFIG_IP6_NF_MATCH_RPFILTER is not set +CONFIG_IP6_NF_MATCH_RPFILTER=y # CONFIG_IP6_NF_MATCH_RT is not set # CONFIG_IP6_NF_TARGET_HL is not set CONFIG_IP6_NF_FILTER=y diff --git a/arch/arm/configs/msm8909-1gb-LMT-perf_defconfig b/arch/arm/configs/msm8909-1gb-LMT-perf_defconfig index 6c67c525c083e..f755138ff7591 100644 --- a/arch/arm/configs/msm8909-1gb-LMT-perf_defconfig +++ b/arch/arm/configs/msm8909-1gb-LMT-perf_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_AUDIT=y diff --git a/arch/arm/configs/msm8909-1gb-perf_defconfig b/arch/arm/configs/msm8909-1gb-perf_defconfig index cf2a357fb7672..0200db769e7c2 100644 --- a/arch/arm/configs/msm8909-1gb-perf_defconfig +++ b/arch/arm/configs/msm8909-1gb-perf_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_AUDIT=y @@ -104,6 +104,7 @@ CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_IPCOMP=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set +CONFIG_INET_DIAG_DESTROY=y CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y @@ -278,6 +279,7 @@ CONFIG_DUMMY=y CONFIG_TUN=y CONFIG_KS8851=y CONFIG_MSM_RMNET_BAM=y +CONFIG_ARCH_MMAP_RND_BITS=16 CONFIG_PPP=y CONFIG_PPP_BSDCOMP=y CONFIG_PPP_DEFLATE=y @@ -319,10 +321,18 @@ CONFIG_APDS9930=y CONFIG_SENSORS_LTR553=y CONFIG_SENSORS_MPU6050=y CONFIG_SENSORS_MMC3416X=y +CONFIG_SENSORS_MMC3X30=y CONFIG_SENSORS_AKM8963=y CONFIG_SENSORS_AKM09911=y CONFIG_SENSORS_BMA2X2=y CONFIG_SENSORS_AP3426=y +CONFIG_SENSORS_STK3X1X=y +# CONFIG_LEGACY_PTYS is not set +CONFIG_SENSORS_BMI160=y +CONFIG_SENSORS_BMI160_I2C=y +# CONFIG_BMI160_MAG_INTERFACE_SUPPORT is not set +CONFIG_SENSORS_BMI160_ENABLE_INT1=y +# CONFIG_SENSORS_BMI160_ENABLE_INT2 is not set CONFIG_SENSORS_HALL=y #CONFIG_SERIAL_MSM_HSL is not set #CONFIG_SERIAL_MSM_HSL_CONSOLE is not set diff --git a/arch/arm/configs/msm8909-1gb_defconfig b/arch/arm/configs/msm8909-1gb_defconfig index 663eef5801bd9..021f7333cc76d 100644 --- a/arch/arm/configs/msm8909-1gb_defconfig +++ b/arch/arm/configs/msm8909-1gb_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_AUDIT=y @@ -110,6 +110,7 @@ CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set +CONFIG_INET_DIAG_DESTROY=y CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y @@ -285,6 +286,7 @@ CONFIG_DUMMY=y CONFIG_TUN=y CONFIG_KS8851=y CONFIG_MSM_RMNET_BAM=y +CONFIG_ARCH_MMAP_RND_BITS=16 CONFIG_PPP=y CONFIG_PPP_BSDCOMP=y CONFIG_PPP_DEFLATE=y @@ -326,10 +328,18 @@ CONFIG_APDS9930=y CONFIG_SENSORS_LTR553=y CONFIG_SENSORS_MPU6050=y CONFIG_SENSORS_MMC3416X=y +CONFIG_SENSORS_MMC3X30=y CONFIG_SENSORS_AKM8963=y CONFIG_SENSORS_AKM09911=y CONFIG_SENSORS_BMA2X2=y CONFIG_SENSORS_AP3426=y +CONFIG_SENSORS_STK3X1X=y +# CONFIG_LEGACY_PTYS is not set +CONFIG_SENSORS_BMI160=y +CONFIG_SENSORS_BMI160_I2C=y +# CONFIG_BMI160_MAG_INTERFACE_SUPPORT is not set +CONFIG_SENSORS_BMI160_ENABLE_INT1=y +# CONFIG_SENSORS_BMI160_ENABLE_INT2 is not set CONFIG_SENSORS_HALL=y CONFIG_SERIAL_MSM_HSL=y CONFIG_SERIAL_MSM_HSL_CONSOLE=y diff --git a/arch/arm/configs/msm8909-perf_defconfig b/arch/arm/configs/msm8909-perf_defconfig index 1551aa0421d41..ae028558e22ee 100644 --- a/arch/arm/configs/msm8909-perf_defconfig +++ b/arch/arm/configs/msm8909-perf_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_AUDIT=y @@ -98,6 +98,7 @@ CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set +CONFIG_INET_DIAG_DESTROY=y CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y diff --git a/arch/arm/configs/msm8909_defconfig b/arch/arm/configs/msm8909_defconfig index bcb15f2957918..18cb595bd88a0 100644 --- a/arch/arm/configs/msm8909_defconfig +++ b/arch/arm/configs/msm8909_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_AUDIT=y @@ -102,6 +102,7 @@ CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set +CONFIG_INET_DIAG_DESTROY=y CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y diff --git a/arch/arm/configs/msm8909w-perf_defconfig b/arch/arm/configs/msm8909w-perf_defconfig index 27d65d33b8498..018f1584e2579 100644 --- a/arch/arm/configs/msm8909w-perf_defconfig +++ b/arch/arm/configs/msm8909w-perf_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_AUDIT=y diff --git a/arch/arm/configs/msm8909w_defconfig b/arch/arm/configs/msm8909w_defconfig index 3ae54cb710105..86bb9a0330fd2 100644 --- a/arch/arm/configs/msm8909w_defconfig +++ b/arch/arm/configs/msm8909w_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_AUDIT=y diff --git a/arch/arm/configs/msm8916-512mb-perf_defconfig b/arch/arm/configs/msm8916-512mb-perf_defconfig index b69905e625dc7..dd53dd0386469 100755 --- a/arch/arm/configs/msm8916-512mb-perf_defconfig +++ b/arch/arm/configs/msm8916-512mb-perf_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_AUDIT=y @@ -85,6 +85,7 @@ CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set +CONFIG_INET_DIAG_DESTROY=y CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y diff --git a/arch/arm/configs/msm8916-512mb_defconfig b/arch/arm/configs/msm8916-512mb_defconfig index 4c6ec5adb4c00..77d5a053f549d 100644 --- a/arch/arm/configs/msm8916-512mb_defconfig +++ b/arch/arm/configs/msm8916-512mb_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_AUDIT=y @@ -88,6 +88,7 @@ CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set +CONFIG_INET_DIAG_DESTROY=y CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y diff --git a/arch/arm/configs/msm8916-LMT-perf_defconfig b/arch/arm/configs/msm8916-LMT-perf_defconfig index 337f283868697..abd29e9d6a56a 100644 --- a/arch/arm/configs/msm8916-LMT-perf_defconfig +++ b/arch/arm/configs/msm8916-LMT-perf_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y diff --git a/arch/arm/configs/msm8916-perf_defconfig b/arch/arm/configs/msm8916-perf_defconfig index 30ceb28fa270d..50bd944134cb7 100644 --- a/arch/arm/configs/msm8916-perf_defconfig +++ b/arch/arm/configs/msm8916-perf_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -82,6 +82,7 @@ CONFIG_UNIX=y CONFIG_XFRM=y CONFIG_XFRM_USER=y CONFIG_INET=y +CONFIG_INET_IPCOMP=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_VERBOSE=y @@ -94,6 +95,7 @@ CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set +CONFIG_INET_DIAG_DESTROY=y CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y @@ -122,6 +124,7 @@ CONFIG_NF_CONNTRACK_SANE=y CONFIG_NF_CONNTRACK_SIP=y CONFIG_NF_CONNTRACK_TFTP=y CONFIG_NF_CT_NETLINK=y +CONFIG_NET_KEY=y CONFIG_NETFILTER_TPROXY=y CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y CONFIG_NETFILTER_XT_TARGET_CONNMARK=y @@ -251,6 +254,7 @@ CONFIG_DUMMY=y CONFIG_TUN=y CONFIG_KS8851=y CONFIG_MSM_RMNET_BAM=y +CONFIG_ARCH_MMAP_RND_BITS=16 CONFIG_PPP=y CONFIG_PPP_BSDCOMP=y CONFIG_PPP_DEFLATE=y diff --git a/arch/arm/configs/msm8916_defconfig b/arch/arm/configs/msm8916_defconfig index 846b9eff1d71d..9367648788d31 100755 --- a/arch/arm/configs/msm8916_defconfig +++ b/arch/arm/configs/msm8916_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -85,6 +85,7 @@ CONFIG_UNIX=y CONFIG_XFRM=y CONFIG_XFRM_USER=y CONFIG_INET=y +CONFIG_INET_IPCOMP=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_VERBOSE=y @@ -97,6 +98,7 @@ CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set +CONFIG_INET_DIAG_DESTROY=y CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y @@ -125,6 +127,7 @@ CONFIG_NF_CONNTRACK_SANE=y CONFIG_NF_CONNTRACK_SIP=y CONFIG_NF_CONNTRACK_TFTP=y CONFIG_NF_CT_NETLINK=y +CONFIG_NET_KEY=y CONFIG_NETFILTER_TPROXY=y CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y CONFIG_NETFILTER_XT_TARGET_CONNMARK=y @@ -254,6 +257,7 @@ CONFIG_DUMMY=y CONFIG_TUN=y CONFIG_KS8851=y CONFIG_MSM_RMNET_BAM=y +CONFIG_ARCH_MMAP_RND_BITS=16 CONFIG_PPP=y CONFIG_PPP_BSDCOMP=y CONFIG_PPP_DEFLATE=y diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index a0c1e318a7905..2914c69f2fa09 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -272,21 +272,30 @@ armpmu_add(struct perf_event *event, int flags) } static int -validate_event(struct pmu_hw_events *hw_events, - struct perf_event *event) +validate_event(struct pmu *pmu, struct pmu_hw_events *hw_events, + struct perf_event *event) { - struct arm_pmu *armpmu = to_arm_pmu(event->pmu); + struct arm_pmu *armpmu; struct pmu *leader_pmu = event->group_leader->pmu; if (is_software_event(event)) return 1; - if (event->pmu != leader_pmu || event->state < PERF_EVENT_STATE_OFF) + /* + * Reject groups spanning multiple HW PMUs (e.g. CPU + CCI). The + * core perf code won't check that the pmu->ctx == leader->ctx + * until after pmu->event_init(event). + */ + if (event->pmu != pmu) + return 0; + + if (event->pmu != leader_pmu || event->state < PERF_EVENT_STATE_OFF) return 1; if (event->state == PERF_EVENT_STATE_OFF && !event->attr.enable_on_exec) return 1; + armpmu = to_arm_pmu(event->pmu); return armpmu->get_event_idx(hw_events, event) >= 0; } @@ -304,15 +313,15 @@ validate_group(struct perf_event *event) memset(fake_used_mask, 0, sizeof(fake_used_mask)); fake_pmu.used_mask = fake_used_mask; - if (!validate_event(&fake_pmu, leader)) + if (!validate_event(event->pmu, &fake_pmu, leader)) return -EINVAL; list_for_each_entry(sibling, &leader->sibling_list, group_entry) { - if (!validate_event(&fake_pmu, sibling)) + if (!validate_event(event->pmu, &fake_pmu, sibling)) return -EINVAL; } - if (!validate_event(&fake_pmu, event)) + if (!validate_event(event->pmu, &fake_pmu, event)) return -EINVAL; return 0; diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c index 5e85ed371364c..2d689d1f88fef 100644 --- a/arch/arm/mm/mmap.c +++ b/arch/arm/mm/mmap.c @@ -173,10 +173,9 @@ void arch_pick_mmap_layout(struct mm_struct *mm) { unsigned long random_factor = 0UL; - /* 8 bits of randomness in 20 address space bits */ if ((current->flags & PF_RANDOMIZE) && !(current->personality & ADDR_NO_RANDOMIZE)) - random_factor = (get_random_int() % (1 << 8)) << PAGE_SHIFT; + random_factor = (get_random_long() & ((1UL << mmap_rnd_bits) - 1)) << PAGE_SHIFT; if (mmap_is_legacy()) { mm->mmap_base = TASK_UNMAPPED_BASE + random_factor; diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 74addc244f713..b7e7a34662461 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -34,6 +34,8 @@ config ARM64 select HAVE_ARCH_AUDITSYSCALL select HAVE_ARCH_JUMP_LABEL select HAVE_ARCH_KGDB + select HAVE_ARCH_MMAP_RND_BITS + select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_TRACEHOOK select HAVE_C_RECORDMCOUNT @@ -83,6 +85,23 @@ config MMU config NO_IOPORT_MAP def_bool y +config ARCH_MMAP_RND_BITS_MIN + default 14 if ARM64_64K_PAGES + default 18 + +# max bits determined by the following formula: +# VA_BITS - PAGE_SHIFT - 3 +# VA_BITS is always 39 +config ARCH_MMAP_RND_BITS_MAX + default 20 if ARM64_64K_PAGES + default 24 + +config ARCH_MMAP_RND_COMPAT_BITS_MIN + default 11 + +config ARCH_MMAP_RND_COMPAT_BITS_MAX + default 16 + config STACKTRACE_SUPPORT def_bool y diff --git a/arch/arm64/configs/msm-LMT-perf_defconfig b/arch/arm64/configs/msm-LMT-perf_defconfig index 5ff85619c2714..cf878ca433e54 100644 --- a/arch/arm64/configs/msm-LMT-perf_defconfig +++ b/arch/arm64/configs/msm-LMT-perf_defconfig @@ -1,5 +1,5 @@ CONFIG_LOCALVERSION="-perf" -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_AUDIT=y diff --git a/arch/arm64/configs/msm-perf_defconfig b/arch/arm64/configs/msm-perf_defconfig index 60949ef47970a..bb010558c74be 100644 --- a/arch/arm64/configs/msm-perf_defconfig +++ b/arch/arm64/configs/msm-perf_defconfig @@ -1,5 +1,5 @@ CONFIG_LOCALVERSION="-perf" -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -64,6 +64,7 @@ CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y CONFIG_INET=y +CONFIG_INET_IPCOMP=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_VERBOSE=y @@ -73,6 +74,7 @@ CONFIG_INET_AH=y CONFIG_INET_ESP=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set +CONFIG_INET_DIAG_DESTROY=y CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y @@ -173,6 +175,7 @@ CONFIG_L2TP_V3=y CONFIG_L2TP_IP=y CONFIG_L2TP_ETH=y CONFIG_BRIDGE=y +CONFIG_NET_KEY=y CONFIG_NET_SCHED=y CONFIG_NET_SCH_HTB=y CONFIG_NET_SCH_PRIO=y @@ -231,6 +234,7 @@ CONFIG_DUMMY=y CONFIG_MII=y CONFIG_TUN=y CONFIG_MSM_RMNET_BAM=y +CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16 CONFIG_PHYLIB=y CONFIG_PPP=y CONFIG_PPP_BSDCOMP=y @@ -508,6 +512,7 @@ CONFIG_TIMER_STATS=y CONFIG_DEBUG_INFO=y CONFIG_IPC_LOGGING=y CONFIG_KEYS=y +CONFIG_DEBUG_SET_MODULE_RONX=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_LSM_MMAP_MIN_ADDR=4096 @@ -531,3 +536,4 @@ CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y CONFIG_QMI_ENCDEC=y CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y CONFIG_UID_CPUTIME=y +CONFIG_MSM_BOOT_STATS=y diff --git a/arch/arm64/configs/msm_defconfig b/arch/arm64/configs/msm_defconfig index 029e4637785e7..7442575a767b2 100644 --- a/arch/arm64/configs/msm_defconfig +++ b/arch/arm64/configs/msm_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYSVIPC=y +# CONFIG_SYSVIPC is not set CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -68,6 +68,7 @@ CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y CONFIG_INET=y +CONFIG_INET_IPCOMP=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_VERBOSE=y @@ -77,6 +78,7 @@ CONFIG_INET_AH=y CONFIG_INET_ESP=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set +CONFIG_INET_DIAG_DESTROY=y CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y @@ -177,6 +179,7 @@ CONFIG_L2TP_V3=y CONFIG_L2TP_IP=y CONFIG_L2TP_ETH=y CONFIG_BRIDGE=y +CONFIG_NET_KEY=y CONFIG_NET_SCHED=y CONFIG_NET_SCH_HTB=y CONFIG_NET_SCH_PRIO=y @@ -236,6 +239,7 @@ CONFIG_DUMMY=y CONFIG_MII=y CONFIG_TUN=y CONFIG_MSM_RMNET_BAM=y +CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16 CONFIG_PHYLIB=y CONFIG_PPP=y CONFIG_PPP_BSDCOMP=y @@ -556,8 +560,10 @@ CONFIG_MSM_RTB_SEPARATE_CPUS=y CONFIG_IPC_LOGGING=y CONFIG_DYNAMIC_DEBUG=y CONFIG_PANIC_ON_DATA_CORRUPTION=y +CONFIG_DEBUG_SET_MODULE_RONX=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y +CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_LSM_MMAP_MIN_ADDR=4096 CONFIG_SECURITY_SELINUX=y CONFIG_CRYPTO_NULL=y @@ -579,3 +585,4 @@ CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y CONFIG_QMI_ENCDEC=y CONFIG_STRICT_MEMORY_RWX=y CONFIG_UID_CPUTIME=y +CONFIG_MSM_BOOT_STATS=y diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c index 8ed6cb1a900f2..cdc2b985e4117 100644 --- a/arch/arm64/mm/mmap.c +++ b/arch/arm64/mm/mmap.c @@ -47,22 +47,19 @@ static int mmap_is_legacy(void) return sysctl_legacy_va_layout; } -/* - * Since get_random_int() returns the same value within a 1 jiffy window, we - * will almost always get the same randomisation for the stack and mmap - * region. This will mean the relative distance between stack and mmap will be - * the same. - * - * To avoid this we can shift the randomness by 1 bit. - */ static unsigned long mmap_rnd(void) { unsigned long rnd = 0; - if (current->flags & PF_RANDOMIZE) - rnd = (long)get_random_int() & (STACK_RND_MASK >> 1); - - return rnd << (PAGE_SHIFT + 1); + if (current->flags & PF_RANDOMIZE) { +#ifdef CONFIG_COMPAT + if (test_thread_flag(TIF_32BIT)) + rnd = get_random_long() & ((1UL << mmap_rnd_compat_bits) - 1); + else +#endif + rnd = get_random_long() & ((1UL << mmap_rnd_bits) - 1); + } + return rnd << PAGE_SHIFT; } static unsigned long mmap_base(void) diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c index f1baadd56e82e..5ab9e96d52252 100644 --- a/arch/mips/mm/mmap.c +++ b/arch/mips/mm/mmap.c @@ -147,7 +147,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm) unsigned long random_factor = 0UL; if (current->flags & PF_RANDOMIZE) { - random_factor = get_random_int(); + random_factor = get_random_long(); random_factor = random_factor << PAGE_SHIFT; if (TASK_IS_32BIT_ADDR) random_factor &= 0xfffffful; @@ -166,7 +166,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm) static inline unsigned long brk_rnd(void) { - unsigned long rnd = get_random_int(); + unsigned long rnd = get_random_long(); rnd = rnd << PAGE_SHIFT; /* 8MB for 32bit, 256MB for 64bit */ diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index d55357ee90283..bce0fe7acd445 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -1440,7 +1440,7 @@ void notrace __ppc64_runlatch_off(void) unsigned long arch_align_stack(unsigned long sp) { if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) - sp -= get_random_int() & ~PAGE_MASK; + sp -= get_random_long() & ~PAGE_MASK; return sp & ~0xf; } @@ -1450,9 +1450,9 @@ static inline unsigned long brk_rnd(void) /* 8MB for 32bit, 1GB for 64bit */ if (is_32bit_task()) - rnd = (long)(get_random_int() % (1<<(23-PAGE_SHIFT))); + rnd = (get_random_long() % (1UL<<(23-PAGE_SHIFT))); else - rnd = (long)(get_random_int() % (1<<(30-PAGE_SHIFT))); + rnd = (get_random_long() % (1UL<<(30-PAGE_SHIFT))); return rnd << PAGE_SHIFT; } diff --git a/arch/powerpc/mm/mmap_64.c b/arch/powerpc/mm/mmap_64.c index cb8bdbe4972fa..2575510873dd0 100644 --- a/arch/powerpc/mm/mmap_64.c +++ b/arch/powerpc/mm/mmap_64.c @@ -60,9 +60,9 @@ static unsigned long mmap_rnd(void) if (current->flags & PF_RANDOMIZE) { /* 8MB for 32bit, 1GB for 64bit */ if (is_32bit_task()) - rnd = (long)(get_random_int() % (1<<(23-PAGE_SHIFT))); + rnd = get_random_long() % (1UL<<(23-PAGE_SHIFT)); else - rnd = (long)(get_random_int() % (1<<(30-PAGE_SHIFT))); + rnd = get_random_long() % (1UL<<(30-PAGE_SHIFT)); } return rnd << PAGE_SHIFT; } diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index 51561b8b15baf..56b4959069c76 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c @@ -265,7 +265,7 @@ static unsigned long mmap_rnd(void) unsigned long rnd = 0UL; if (current->flags & PF_RANDOMIZE) { - unsigned long val = get_random_int(); + unsigned long val = get_random_long(); if (test_thread_flag(TIF_32BIT)) rnd = (val % (1UL << (23UL-PAGE_SHIFT))); else diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c index 25e7e1372bb26..65ba1a7d0c7c9 100644 --- a/arch/x86/mm/mmap.c +++ b/arch/x86/mm/mmap.c @@ -75,9 +75,9 @@ static unsigned long mmap_rnd(void) */ if (current->flags & PF_RANDOMIZE) { if (mmap_is_ia32()) - rnd = get_random_int() % (1<<8); + rnd = get_random_long() % (1UL<<8); else - rnd = get_random_int() % (1<<28); + rnd = get_random_long() % (1UL<<28); } return rnd << PAGE_SHIFT; } diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c index 8ae9f1ea2bb5e..3bbaa9828c09e 100644 --- a/drivers/bluetooth/hci_h4.c +++ b/drivers/bluetooth/hci_h4.c @@ -67,7 +67,7 @@ static int h4_open(struct hci_uart *hu) { struct h4_struct *h4; - BT_DBG("hu %p", hu); + BT_DBG("hu %pK", hu); h4 = kzalloc(sizeof(*h4), GFP_KERNEL); if (!h4) @@ -84,7 +84,7 @@ static int h4_flush(struct hci_uart *hu) { struct h4_struct *h4 = hu->priv; - BT_DBG("hu %p", hu); + BT_DBG("hu %pK", hu); skb_queue_purge(&h4->txq); @@ -98,7 +98,7 @@ static int h4_close(struct hci_uart *hu) hu->priv = NULL; - BT_DBG("hu %p", hu); + BT_DBG("hu %pK", hu); skb_queue_purge(&h4->txq); @@ -115,7 +115,7 @@ static int h4_enqueue(struct hci_uart *hu, struct sk_buff *skb) { struct h4_struct *h4 = hu->priv; - BT_DBG("hu %p skb %p", hu, skb); + BT_DBG("hu %pK skb %pK", hu, skb); /* Prepend skb with frame type */ memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); diff --git a/drivers/bluetooth/hci_ibs.c b/drivers/bluetooth/hci_ibs.c index 0d732184f274c..b97287058fbec 100644 --- a/drivers/bluetooth/hci_ibs.c +++ b/drivers/bluetooth/hci_ibs.c @@ -231,7 +231,7 @@ static int send_hci_ibs_cmd(u8 cmd, struct hci_uart *hu) struct ibs_struct *ibs = hu->priv; struct hci_ibs_cmd *hci_ibs_packet; - BT_DBG("hu %p cmd 0x%x", hu, cmd); + BT_DBG("hu %pK cmd 0x%x", hu, cmd); /* allocate packet */ skb = bt_skb_alloc(1, GFP_ATOMIC); @@ -259,7 +259,7 @@ static void ibs_wq_awake_device(struct work_struct *work) struct hci_uart *hu = (struct hci_uart *)ibs->ibs_hu; unsigned long flags; - BT_DBG(" %p ", hu); + BT_DBG(" %pK ", hu); /* Vote for serial clock */ ibs_msm_serial_clock_vote(HCI_IBS_TX_VOTE_CLOCK_ON, hu); @@ -286,7 +286,7 @@ static void ibs_wq_awake_rx(struct work_struct *work) struct hci_uart *hu = (struct hci_uart *)ibs->ibs_hu; unsigned long flags; - BT_DBG(" %p ", hu); + BT_DBG(" %pK ", hu); ibs_msm_serial_clock_vote(HCI_IBS_RX_VOTE_CLOCK_ON, hu); @@ -314,7 +314,7 @@ static void ibs_wq_serial_rx_clock_vote_off(struct work_struct *work) ws_rx_vote_off); struct hci_uart *hu = (struct hci_uart *)ibs->ibs_hu; - BT_DBG(" %p ", hu); + BT_DBG(" %pK ", hu); ibs_msm_serial_clock_vote(HCI_IBS_RX_VOTE_CLOCK_OFF, hu); @@ -326,7 +326,7 @@ static void ibs_wq_serial_tx_clock_vote_off(struct work_struct *work) ws_tx_vote_off); struct hci_uart *hu = (struct hci_uart *)ibs->ibs_hu; - BT_DBG(" %p ", hu); + BT_DBG(" %pK ", hu); hci_uart_tx_wakeup(hu); /* run HCI tx handling unlocked */ @@ -342,7 +342,7 @@ static void hci_ibs_tx_idle_timeout(unsigned long arg) struct ibs_struct *ibs = hu->priv; unsigned long flags; - BT_DBG("hu %p idle timeout in %lu state", hu, ibs->tx_ibs_state); + BT_DBG("hu %pK idle timeout in %lu state", hu, ibs->tx_ibs_state); spin_lock_irqsave_nested(&ibs->hci_ibs_lock, flags, SINGLE_DEPTH_NESTING); @@ -376,8 +376,8 @@ static void hci_ibs_wake_retrans_timeout(unsigned long arg) unsigned long flags; unsigned long retransmit = 0; - BT_DBG("hu %p wake retransmit timeout in %lu state", - hu, ibs->tx_ibs_state); + BT_DBG("hu %pK wake retransmit timeout in %lu state", + hu, ibs->tx_ibs_state); spin_lock_irqsave_nested(&ibs->hci_ibs_lock, flags, SINGLE_DEPTH_NESTING); @@ -409,7 +409,7 @@ static int ibs_open(struct hci_uart *hu) { struct ibs_struct *ibs; - BT_DBG("hu %p", hu); + BT_DBG("hu %pK", hu); ibs = kzalloc(sizeof(*ibs), GFP_ATOMIC); if (!ibs) @@ -505,7 +505,7 @@ static int ibs_flush(struct hci_uart *hu) { struct ibs_struct *ibs = hu->priv; - BT_DBG("hu %p", hu); + BT_DBG("hu %pK", hu); skb_queue_purge(&ibs->tx_wait_q); skb_queue_purge(&ibs->txq); @@ -518,7 +518,7 @@ static int ibs_close(struct hci_uart *hu) { struct ibs_struct *ibs = hu->priv; - BT_DBG("hu %p", hu); + BT_DBG("hu %pK", hu); ibs_msm_serial_clock_vote(HCI_IBS_VOTE_STATS_UPDATE, hu); ibs_log_local_stats(ibs); @@ -547,7 +547,7 @@ static void ibs_device_want_to_wakeup(struct hci_uart *hu) unsigned long flags; struct ibs_struct *ibs = hu->priv; - BT_DBG("hu %p", hu); + BT_DBG("hu %pK", hu); /* lock hci_ibs state */ spin_lock_irqsave(&ibs->hci_ibs_lock, flags); @@ -596,7 +596,7 @@ static void ibs_device_want_to_sleep(struct hci_uart *hu) unsigned long flags; struct ibs_struct *ibs = hu->priv; - BT_DBG("hu %p", hu); + BT_DBG("hu %pK", hu); /* lock hci_ibs state */ spin_lock_irqsave(&ibs->hci_ibs_lock, flags); @@ -632,7 +632,7 @@ static void ibs_device_woke_up(struct hci_uart *hu) struct ibs_struct *ibs = hu->priv; struct sk_buff *skb = NULL; - BT_DBG("hu %p", hu); + BT_DBG("hu %pK", hu); /* lock hci_ibs state */ spin_lock_irqsave(&ibs->hci_ibs_lock, flags); @@ -677,7 +677,7 @@ static int ibs_enqueue(struct hci_uart *hu, struct sk_buff *skb) unsigned long flags = 0; struct ibs_struct *ibs = hu->priv; - BT_DBG("hu %p skb %p", hu, skb); + BT_DBG("hu %pK skb %pK", hu, skb); /* Prepend skb with frame type */ memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); @@ -756,8 +756,8 @@ static int ibs_recv(struct hci_uart *hu, void *data, int count) struct hci_sco_hdr *sh; register int len, type, dlen; - BT_DBG("hu %p count %d rx_state %ld rx_count %ld", - hu, count, ibs->rx_state, ibs->rx_count); + BT_DBG("hu %pK count %d rx_state %ld rx_count %ld", + hu, count, ibs->rx_state, ibs->rx_count); ptr = data; while (count) { diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 8b49b56dc4d5e..c5975ca87ec14 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -200,7 +200,7 @@ int hci_uart_init_ready(struct hci_uart *hu) /* Initialize device */ static int hci_uart_open(struct hci_dev *hdev) { - BT_DBG("%s %p", hdev->name, hdev); + BT_DBG("%s %pK", hdev->name, hdev); /* Nothing to do for UART driver */ @@ -215,7 +215,7 @@ static int hci_uart_flush(struct hci_dev *hdev) struct hci_uart *hu = hci_get_drvdata(hdev); struct tty_struct *tty = hu->tty; - BT_DBG("hdev %p tty %p", hdev, tty); + BT_DBG("hdev %pK tty %pK", hdev, tty); if (hu->tx_skb) { kfree_skb(hu->tx_skb); hu->tx_skb = NULL; @@ -234,7 +234,7 @@ static int hci_uart_flush(struct hci_dev *hdev) /* Close device */ static int hci_uart_close(struct hci_dev *hdev) { - BT_DBG("hdev %p", hdev); + BT_DBG("hdev %pK", hdev); if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) return 0; @@ -283,7 +283,7 @@ static int hci_uart_tty_open(struct tty_struct *tty) { struct hci_uart *hu; - BT_DBG("tty %p", tty); + BT_DBG("tty %pK", tty); /* Error if the tty has no write op instead of leaving an exploitable hole */ @@ -326,7 +326,7 @@ static void hci_uart_tty_close(struct tty_struct *tty) struct hci_uart *hu = (void *)tty->disc_data; struct hci_dev *hdev; - BT_DBG("tty %p", tty); + BT_DBG("tty %pK", tty); /* Detach from the tty */ tty->disc_data = NULL; diff --git a/drivers/char/adsprpc_compat.c b/drivers/char/adsprpc_compat.c index 31c2897546eb6..ee324dcf91f0e 100644 --- a/drivers/char/adsprpc_compat.c +++ b/drivers/char/adsprpc_compat.c @@ -98,8 +98,9 @@ static int compat_get_fastrpc_ioctl_invoke( if (err) return -EFAULT; - inv->inv.pra = (union remote_arg *)(inv + 1); - err = put_user(sc, &inv->inv.sc); + pra = (union remote_arg *)(inv + 1); + err = put_user(pra, &inv->inv.pra); + err |= put_user(sc, &inv->inv.sc); err |= get_user(u, &inv32->inv.handle); err |= put_user(u, &inv->inv.handle); err |= get_user(p, &inv32->inv.pra); @@ -107,12 +108,11 @@ static int compat_get_fastrpc_ioctl_invoke( return err; pra32 = compat_ptr(p); - pra = inv->inv.pra; + pra = (union remote_arg *)(inv + 1); num = REMOTE_SCALARS_INBUFS(sc) + REMOTE_SCALARS_OUTBUFS(sc); for (j = 0; j < num; j++) { err |= get_user(p, &pra32[j].buf.pv); - pra[j].buf.pv = NULL; - err |= put_user(p, (compat_uptr_t *)&pra[j].buf.pv); + err |= put_user(p, (uintptr_t *)&pra[j].buf.pv); err |= get_user(s, &pra32[j].buf.len); err |= put_user(s, &pra[j].buf.len); } @@ -121,7 +121,7 @@ static int compat_get_fastrpc_ioctl_invoke( err |= put_user(u, &pra[num + j].h); } - inv->fds = NULL; + err |= put_user(NULL, &inv->fds); if (cmd == COMPAT_FASTRPC_IOCTL_INVOKE_FD) { err |= get_user(p, &inv32->fds); err |= put_user(p, (compat_uptr_t *)&inv->fds); @@ -173,8 +173,7 @@ static int compat_get_fastrpc_ioctl_mmap( err |= get_user(u, &map32->flags); err |= put_user(u, &map->flags); err |= get_user(p, &map32->vaddrin); - map->vaddrin = NULL; - err |= put_user(p, (compat_uptr_t *)&map->vaddrin); + err |= put_user(p, (uintptr_t *)&map->vaddrin); err |= get_user(s, &map32->size); err |= put_user(s, &map->size); diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c index 25b89dd9be3da..cb188b2f49601 100644 --- a/drivers/char/diag/diag_dci.c +++ b/drivers/char/diag/diag_dci.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -405,7 +405,7 @@ static int diag_process_single_dci_pkt(unsigned char *buf, int len, uint8_t cmd_code = 0; if (!buf || len < 0) { - pr_err("diag: Invalid input in %s, buf: %p, len: %d\n", + pr_err("diag: Invalid input in %s, buf: %pK, len: %d\n", __func__, buf, len); return -EIO; } @@ -749,7 +749,7 @@ static int diag_dci_remove_req_entry(unsigned char *buf, int len, { uint16_t rsp_count = 0, delayed_rsp_id = 0; if (!buf || len <= 0 || !entry) { - pr_err("diag: In %s, invalid input buf: %p, len: %d, entry: %p\n", + pr_err("diag: In %s, invalid input buf: %pK, len: %d, entry: %pK\n", __func__, buf, len, entry); return -EIO; } @@ -803,7 +803,7 @@ static void dci_process_ctrl_status(unsigned char *buf, int len, int token) int peripheral_mask, status; if (!buf || (len < sizeof(struct diag_ctrl_dci_status))) { - pr_err("diag: In %s, invalid buf %p or length: %d\n", + pr_err("diag: In %s, invalid buf %pK or length: %d\n", __func__, buf, len); return; } @@ -1937,7 +1937,7 @@ int diag_process_dci_transaction(unsigned char *buf, int len) __func__); return -ENOMEM; } - pr_debug("diag: head of dci log mask %p\n", head_log_mask_ptr); + pr_debug("diag: head of dci log mask %pK\n", head_log_mask_ptr); count = 0; /* iterator for extracting log codes */ while (count < num_codes) { @@ -1965,7 +1965,7 @@ int diag_process_dci_transaction(unsigned char *buf, int len) while (log_mask_ptr && (offset < DCI_LOG_MASK_SIZE)) { if (*log_mask_ptr == equip_id) { found = 1; - pr_debug("diag: find equip id = %x at %p\n", + pr_debug("diag: find equip id = %x at %pK\n", equip_id, log_mask_ptr); break; } else { @@ -2043,7 +2043,7 @@ int diag_process_dci_transaction(unsigned char *buf, int len) __func__); return -ENOMEM; } - pr_debug("diag: head of dci event mask %p\n", event_mask_ptr); + pr_debug("diag: head of dci event mask %pK\n", event_mask_ptr); count = 0; /* iterator for extracting log codes */ while (count < num_codes) { if (read_len >= USER_SPACE_DATA) { @@ -3096,7 +3096,7 @@ int diag_dci_write_proc(int peripheral, int pkt_type, char *buf, int len) if (!buf || (peripheral < 0 || peripheral >= NUM_SMD_DCI_CHANNELS) || !driver->rcvd_feature_mask[peripheral] || len < 0) { - pr_err("diag: In %s, invalid data 0x%p, peripheral: %d, len: %d\n", + pr_err("diag: In %s, invalid data 0x%pK, peripheral: %d, len: %d\n", __func__, buf, peripheral, len); return -EINVAL; } diff --git a/drivers/char/diag/diag_debugfs.c b/drivers/char/diag/diag_debugfs.c index 6916507ec2b15..0812576732321 100644 --- a/drivers/char/diag/diag_debugfs.c +++ b/drivers/char/diag/diag_debugfs.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014, 2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -50,26 +50,26 @@ static ssize_t diag_dbgfs_read_status(struct file *file, char __user *ubuf, } buf_size = ksize(buf); ret = scnprintf(buf, buf_size, - "modem ch: 0x%p\n" - "lpass ch: 0x%p\n" - "riva ch: 0x%p\n" - "sensors ch: 0x%p\n" - "modem dci ch: 0x%p\n" - "lpass dci ch: 0x%p\n" - "riva dci ch: 0x%p\n" - "sensors dci ch: 0x%p\n" - "modem cntl_ch: 0x%p\n" - "lpass cntl_ch: 0x%p\n" - "riva cntl_ch: 0x%p\n" - "sensors cntl_ch: 0x%p\n" - "modem cmd ch: 0x%p\n" - "adsp cmd ch: 0x%p\n" - "riva cmd ch: 0x%p\n" - "sensors cmd ch: 0x%p\n" - "modem dci cmd ch: 0x%p\n" - "lpass dci cmd ch: 0x%p\n" - "riva dci cmd ch: 0x%p\n" - "sensors dci cmd ch: 0x%p\n" + "modem ch: 0x%pK\n" + "lpass ch: 0x%pK\n" + "riva ch: 0x%pK\n" + "sensors ch: 0x%pK\n" + "modem dci ch: 0x%pK\n" + "lpass dci ch: 0x%pK\n" + "riva dci ch: 0x%pK\n" + "sensors dci ch: 0x%pK\n" + "modem cntl_ch: 0x%pK\n" + "lpass cntl_ch: 0x%pK\n" + "riva cntl_ch: 0x%pK\n" + "sensors cntl_ch: 0x%pK\n" + "modem cmd ch: 0x%pK\n" + "adsp cmd ch: 0x%pK\n" + "riva cmd ch: 0x%pK\n" + "sensors cmd ch: 0x%pK\n" + "modem dci cmd ch: 0x%pK\n" + "lpass dci cmd ch: 0x%pK\n" + "riva dci cmd ch: 0x%pK\n" + "sensors dci cmd ch: 0x%pK\n" "CPU Tools id: %d\n" "Apps only: %d\n" "Apps master: %d\n" @@ -723,7 +723,7 @@ static ssize_t diag_dbgfs_read_usbinfo(struct file *file, char __user *ubuf, bytes_written = scnprintf(buf+bytes_in_buffer, bytes_remaining, "id: %d\n" "name: %s\n" - "hdl: %p\n" + "hdl: %pK\n" "connected: %d\n" "enabled: %d\n" "mempool: %s\n" @@ -865,9 +865,9 @@ static ssize_t diag_dbgfs_read_mhiinfo(struct file *file, char __user *ubuf, "bridge index: %s\n" "mempool: %s\n" "read ch opened: %d\n" - "read ch hdl: %p\n" + "read ch hdl: %pK\n" "write ch opened: %d\n" - "write ch hdl: %p\n" + "write ch hdl: %pK\n" "read work pending: %d\n" "read done work pending: %d\n" "open work pending: %d\n" @@ -936,9 +936,9 @@ static ssize_t diag_dbgfs_read_bridge(struct file *file, char __user *ubuf, "type: %d\n" "inited: %d\n" "ctxt: %d\n" - "dev_ops: %p\n" - "dci_read_buf: %p\n" - "dci_read_ptr: %p\n" + "dev_ops: %pK\n" + "dci_read_buf: %pK\n" + "dci_read_ptr: %pK\n" "dci_read_len: %d\n\n", info->id, info->name, diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c index 7c0f103b2fbe9..ff75a950514b2 100644 --- a/drivers/char/diag/diag_masks.c +++ b/drivers/char/diag/diag_masks.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -386,7 +386,7 @@ static int diag_cmd_get_ssid_range(unsigned char *src_buf, int src_len, struct diag_ssid_range_t ssid_range; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -430,7 +430,7 @@ static int diag_cmd_get_build_mask(unsigned char *src_buf, int src_len, struct diag_msg_build_mask_t rsp; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -483,7 +483,7 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len, struct diag_msg_build_mask_t rsp; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -532,10 +532,11 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, struct diag_msg_mask_t *mask = NULL; struct diag_msg_build_mask_t *req = NULL; struct diag_msg_build_mask_t rsp; + struct diag_msg_mask_t *mask_next = NULL; uint32_t *temp = NULL; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -545,10 +546,18 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, mutex_lock(&msg_mask.lock); mask = (struct diag_msg_mask_t *)msg_mask.ptr; for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) { + if (i < (driver->msg_mask_tbl_count - 1)) { + mask_next = mask; + mask_next++; + } else + mask_next = NULL; + if ((req->ssid_first < mask->ssid_first) || - (req->ssid_first > mask->ssid_last_tools)) { + (req->ssid_first > mask->ssid_first + MAX_SSID_PER_RANGE) || + (mask_next && (req->ssid_first >= mask_next->ssid_first))) { continue; } + mask_next = NULL; found = 1; mask_size = req->ssid_last - req->ssid_first + 1; if (mask_size > MAX_SSID_PER_RANGE) { @@ -564,8 +573,10 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, pr_debug("diag: Msg SSID range mismatch\n"); if (mask_size != MAX_SSID_PER_RANGE) mask->ssid_last_tools = req->ssid_last; + mask->range_tools = + mask->ssid_last_tools - mask->ssid_first + 1; temp = krealloc(mask->ptr, - mask_size * sizeof(uint32_t), + mask->range_tools * sizeof(uint32_t), GFP_KERNEL); if (!temp) { pr_err_ratelimited("diag: In %s, unable to allocate memory for msg mask ptr, mask_size: %d\n", @@ -573,7 +584,6 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, return -ENOMEM; } mask->ptr = temp; - mask->range_tools = mask_size; } offset = req->ssid_first - mask->ssid_first; @@ -628,7 +638,7 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len, struct diag_msg_mask_t *mask = (struct diag_msg_mask_t *)msg_mask.ptr; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -674,7 +684,7 @@ static int diag_cmd_get_event_mask(unsigned char *src_buf, int src_len, struct diag_event_mask_config_t rsp; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -712,7 +722,7 @@ static int diag_cmd_update_event_mask(unsigned char *src_buf, int src_len, struct diag_event_mask_config_t *req; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -759,7 +769,7 @@ static int diag_cmd_toggle_events(unsigned char *src_buf, int src_len, struct diag_event_report_t header; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -805,7 +815,7 @@ static int diag_cmd_get_log_mask(unsigned char *src_buf, int src_len, struct diag_log_config_rsp_t rsp; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -875,7 +885,7 @@ static int diag_cmd_get_log_range(unsigned char *src_buf, int src_len, return 0; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -913,7 +923,7 @@ static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len, struct diag_log_config_set_rsp_t rsp; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -992,7 +1002,7 @@ static int diag_cmd_disable_log_mask(unsigned char *src_buf, int src_len, int i; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } diff --git a/drivers/char/diag/diag_memorydevice.c b/drivers/char/diag/diag_memorydevice.c index f00f2a9bc0103..53982079b90dd 100644 --- a/drivers/char/diag/diag_memorydevice.c +++ b/drivers/char/diag/diag_memorydevice.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -142,7 +142,7 @@ int diag_md_write(int id, unsigned char *buf, int len, int ctx) if (ch->tbl[i].buf != buf) continue; found = 1; - pr_err_ratelimited("diag: trying to write the same buffer buf: %p, ctxt: %d len: %d at i: %d back to the table, proc: %d, mode: %d\n", + pr_err_ratelimited("diag: trying to write the same buffer buf: %pK, ctxt: %d len: %d at i: %d back to the table, proc: %d, mode: %d\n", buf, ctx, ch->tbl[i].len, i, id, driver->logging_mode); } diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c index bb14523f2ec3a..ffb34fb54a6a7 100644 --- a/drivers/char/diag/diagchar_core.c +++ b/drivers/char/diag/diagchar_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -706,7 +706,7 @@ static int diag_process_userspace_remote(int proc, void *buf, int len) int bridge_index = proc - 1; if (!buf || len < 0) { - pr_err("diag: Invalid input in %s, buf: %p, len: %d\n", + pr_err("diag: Invalid input in %s, buf: %pK, len: %d\n", __func__, buf, len); return -EINVAL; } diff --git a/drivers/char/diag/diagchar_hdlc.c b/drivers/char/diag/diagchar_hdlc.c index 39f1f4487467c..4a6de7381793c 100644 --- a/drivers/char/diag/diagchar_hdlc.c +++ b/drivers/char/diag/diagchar_hdlc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2009, 2012-2013, The Linux Foundation. +/* Copyright (c) 2008-2009, 2012-2013, 2016, The Linux Foundation. * All rights reserved. * * This program is free software; you can redistribute it and/or modify @@ -242,7 +242,7 @@ int crc_check(uint8_t *buf, uint16_t len) * of data and 3 bytes for CRC */ if (!buf || len < 4) { - pr_err_ratelimited("diag: In %s, invalid packet or length, buf: 0x%p, len: %d", + pr_err_ratelimited("diag: In %s, invalid packet or length, buf: 0x%pK, len: %d", __func__, buf, len); return -EIO; } diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c index cbb9dbc2db1ae..19e38d4800a07 100644 --- a/drivers/char/diag/diagfwd.c +++ b/drivers/char/diag/diagfwd.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -810,7 +810,7 @@ void diag_update_pkt_buffer(unsigned char *buf, int type) } if (!ptr || length == 0) { - pr_err("diag: Invalid ptr %p and length %d in %s", + pr_err("diag: Invalid ptr %pK and length %d in %s", ptr, length, __func__); return; } @@ -923,7 +923,7 @@ int diag_process_stm_cmd(unsigned char *buf, unsigned char *dest_buf) int i; if (!buf || !dest_buf) { - pr_err("diag: Invalid pointers buf: %p, dest_buf %p in %s\n", + pr_err("diag: Invalid pointers buf: %pK, dest_buf %pK in %s\n", buf, dest_buf, __func__); return -EIO; } @@ -1011,7 +1011,7 @@ int diag_cmd_log_on_demand(unsigned char *src_buf, int src_len, return 0; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { - pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d", + pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; } @@ -2038,7 +2038,7 @@ int diag_smd_write(struct diag_smd_info *smd_info, void *buf, int len) int max_retries = 3; if (!smd_info || !buf || len <= 0) { - pr_err_ratelimited("diag: In %s, invalid params, smd_info: %p, buf: %p, len: %d\n", + pr_err_ratelimited("diag: In %s, invalid params, smd_info: %pK, buf: %pK, len: %d\n", __func__, smd_info, buf, len); return -EINVAL; } diff --git a/drivers/char/diag/diagfwd_bridge.c b/drivers/char/diag/diagfwd_bridge.c index f6aa7962d5167..633cd9983e018 100644 --- a/drivers/char/diag/diagfwd_bridge.c +++ b/drivers/char/diag/diagfwd_bridge.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -133,7 +133,7 @@ int diagfwd_bridge_register(int id, int ctxt, struct diag_remote_dev_ops *ops) char wq_name[DIAG_BRIDGE_NAME_SZ + 10]; if (!ops) { - pr_err("diag: Invalid pointers ops: %p ctxt: %d\n", ops, ctxt); + pr_err("diag: Invalid pointers ops: %pK ctxt: %d\n", ops, ctxt); return -EINVAL; } diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c index 55ce976da9876..cf7284401b6ba 100644 --- a/drivers/char/diag/diagfwd_cntl.c +++ b/drivers/char/diag/diagfwd_cntl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -836,7 +836,7 @@ int diag_send_diag_mode_update_by_smd(struct diag_smd_info *smd_info, int err = 0; if (!smd_info || smd_info->type != SMD_CNTL_TYPE) { - pr_err("diag: In %s, invalid channel info, smd_info: %p type: %d\n", + pr_err("diag: In %s, invalid channel info, smd_info: %pK type: %d\n", __func__, smd_info, ((smd_info) ? smd_info->type : -1)); return -EIO; diff --git a/drivers/char/diag/diagfwd_hsic.c b/drivers/char/diag/diagfwd_hsic.c index 987931fdc7626..df9b9a6e37d1d 100644 --- a/drivers/char/diag/diagfwd_hsic.c +++ b/drivers/char/diag/diagfwd_hsic.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2014, 2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -354,7 +354,7 @@ static int hsic_write(int id, unsigned char *buf, int len, int ctxt) return -EINVAL; } if (!buf || len <= 0) { - pr_err_ratelimited("diag: In %s, ch %d, invalid buf %p len %d\n", + pr_err_ratelimited("diag: In %s, ch %d, invalid buf %pK len %d\n", __func__, id, buf, len); return -EINVAL; } diff --git a/drivers/char/diag/diagfwd_mhi.c b/drivers/char/diag/diagfwd_mhi.c index a2bea81449161..0178153db8b6a 100644 --- a/drivers/char/diag/diagfwd_mhi.c +++ b/drivers/char/diag/diagfwd_mhi.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014, 2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -133,7 +133,7 @@ static int mhi_buf_tbl_add(struct diag_mhi_info *mhi_info, int type, item = kzalloc(sizeof(struct diag_mhi_buf_tbl_t), GFP_KERNEL); if (!item) { - pr_err_ratelimited("diag: In %s, unable to allocate new item for buf tbl, ch: %p, type: %d, buf: %p, len: %d\n", + pr_err_ratelimited("diag: In %s, unable to allocate new item for buf tbl, ch: %pK, type: %d, buf: %pK, len: %d\n", __func__, ch, ch->type, buf, len); return -ENOMEM; } @@ -187,7 +187,7 @@ static void mhi_buf_tbl_remove(struct diag_mhi_info *mhi_info, int type, spin_unlock_irqrestore(&ch->lock, flags); if (!found) { - pr_err_ratelimited("diag: In %s, unable to find buffer, ch: %p, type: %d, buf: %p\n", + pr_err_ratelimited("diag: In %s, unable to find buffer, ch: %pK, type: %d, buf: %pK\n", __func__, ch, ch->type, buf); } } @@ -443,7 +443,7 @@ static int mhi_write(int id, unsigned char *buf, int len, int ctxt) } if (!buf || len <= 0) { - pr_err("diag: In %s, ch %d, invalid buf %p len %d\n", + pr_err("diag: In %s, ch %d, invalid buf %pK len %d\n", __func__, id, buf, len); return -EINVAL; } @@ -473,7 +473,7 @@ static int mhi_write(int id, unsigned char *buf, int len, int ctxt) err = mhi_queue_xfer(ch->hdl, dma_addr, len, flags); if (err) { - pr_err_ratelimited("diag: In %s, cannot write to MHI channel %p, len %d, err: %d\n", + pr_err_ratelimited("diag: In %s, cannot write to MHI channel %pK, len %d, err: %d\n", __func__, diag_mhi[id].name, len, err); dma_unmap_single(NULL, (dma_addr_t)dma_addr, len, DMA_TO_DEVICE); diff --git a/drivers/char/msm_smd_pkt.c b/drivers/char/msm_smd_pkt.c index 8de52593d892b..7502d8cb769c0 100644 --- a/drivers/char/msm_smd_pkt.c +++ b/drivers/char/msm_smd_pkt.c @@ -359,6 +359,7 @@ static long smd_pkt_ioctl(struct file *file, unsigned int cmd, { int ret; struct smd_pkt_dev *smd_pkt_devp; + uint32_t val; smd_pkt_devp = file->private_data; if (!smd_pkt_devp) @@ -372,9 +373,15 @@ static long smd_pkt_ioctl(struct file *file, unsigned int cmd, ret = smd_tiocmget(smd_pkt_devp->ch); break; case TIOCMSET: - D_STATUS("%s TIOCSET command on smd_pkt_dev id:%d\n", - __func__, smd_pkt_devp->i); - ret = smd_tiocmset(smd_pkt_devp->ch, arg, ~arg); + ret = get_user(val, (uint32_t *)arg); + if (ret) { + pr_err("Error getting TIOCMSET value\n"); + mutex_unlock(&smd_pkt_devp->ch_lock); + return ret; + } + D_STATUS("%s TIOCSET command on smd_pkt_dev id:%d arg[0x%x]\n", + __func__, smd_pkt_devp->i, val); + ret = smd_tiocmset(smd_pkt_devp->ch, val, ~val); break; case SMD_PKT_IOCTL_BLOCKING_WRITE: ret = get_user(smd_pkt_devp->blocking_write, (int *)arg); diff --git a/drivers/char/random.c b/drivers/char/random.c index d9e24b59fcbfe..1c24ed59207d7 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1502,6 +1502,28 @@ unsigned int get_random_int(void) } EXPORT_SYMBOL(get_random_int); +/* + * Same as get_random_int(), but returns unsigned long. + */ +unsigned long get_random_long(void) +{ + __u32 *hash; + unsigned long ret; + + if (arch_get_random_long(&ret)) + return ret; + + hash = get_cpu_var(get_random_int_hash); + + hash[0] += current->pid + jiffies + get_cycles(); + md5_transform(hash, random_int_secret); + ret = *(unsigned long *)hash; + put_cpu_var(get_random_int_hash); + + return ret; +} +EXPORT_SYMBOL(get_random_long); + /* * randomize_range() returns a start address such that * diff --git a/drivers/coresight/coresight-csr.c b/drivers/coresight/coresight-csr.c index 19e44b9c5d3be..7ad40f16d303c 100644 --- a/drivers/coresight/coresight-csr.c +++ b/drivers/coresight/coresight-csr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2013,2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -195,8 +195,6 @@ static int csr_probe(struct platform_device *pdev) drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; - /* Store the driver data pointer for use in exported functions */ - csrdrvdata = drvdata; drvdata->dev = &pdev->dev; platform_set_drvdata(pdev, drvdata); @@ -227,6 +225,9 @@ static int csr_probe(struct platform_device *pdev) if (IS_ERR(drvdata->csdev)) return PTR_ERR(drvdata->csdev); + /* Store the driver data pointer for use in exported functions */ + csrdrvdata = drvdata; + dev_info(dev, "CSR initialized\n"); return 0; } diff --git a/drivers/coresight/coresight-fuse.c b/drivers/coresight/coresight-fuse.c index 94689285d8d86..cdbfc7a2ac13c 100644 --- a/drivers/coresight/coresight-fuse.c +++ b/drivers/coresight/coresight-fuse.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -252,8 +252,6 @@ static int fuse_probe(struct platform_device *pdev) drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; - /* Store the driver data pointer for use in exported functions */ - fusedrvdata = drvdata; drvdata->dev = &pdev->dev; platform_set_drvdata(pdev, drvdata); @@ -315,6 +313,9 @@ static int fuse_probe(struct platform_device *pdev) if (IS_ERR(drvdata->csdev)) return PTR_ERR(drvdata->csdev); + /* Store the driver data pointer for use in exported functions */ + fusedrvdata = drvdata; + dev_info(dev, "Fuse initialized\n"); return 0; } diff --git a/drivers/coresight/coresight-stm.c b/drivers/coresight/coresight-stm.c index 2cc1f9cd2394f..8833ee0b7c5d5 100644 --- a/drivers/coresight/coresight-stm.c +++ b/drivers/coresight/coresight-stm.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -868,8 +868,6 @@ static int stm_probe(struct platform_device *pdev) drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; - /* Store the driver data pointer for use in exported functions */ - stmdrvdata = drvdata; drvdata->dev = &pdev->dev; platform_set_drvdata(pdev, drvdata); @@ -948,6 +946,9 @@ static int stm_probe(struct platform_device *pdev) if (boot_enable) coresight_enable(drvdata->csdev); + /* Store the driver data pointer for use in exported functions */ + stmdrvdata = drvdata; + return 0; err: coresight_unregister(drvdata->csdev); diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c index 65077006c95dd..4a037f81f3813 100644 --- a/drivers/crypto/msm/qcedev.c +++ b/drivers/crypto/msm/qcedev.c @@ -42,7 +42,10 @@ #define CACHE_LINE_SIZE 32 #define CE_SHA_BLOCK_SIZE SHA256_BLOCK_SIZE -#define U32_MAX (~(__u32)0) + +#ifndef U32_MAX +#define U32_MAX ((u32)(~0U)) +#endif /* are FIPS integrity tests done ?? */ bool is_fips_qcedev_integritytest_done; @@ -829,11 +832,6 @@ static int qcedev_sha_final(struct qcedev_async_req *qcedev_areq, return -EINVAL; } - if (handle->sha_ctxt.trailing_buf_len == 0) { - pr_err("%s Incorrect trailng buffer %d\n", __func__, - handle->sha_ctxt.trailing_buf_len); - return -EINVAL; - } handle->sha_ctxt.last_blk = 1; total = handle->sha_ctxt.trailing_buf_len; @@ -1595,10 +1593,9 @@ static int qcedev_check_sha_params(struct qcedev_sha_op_req *req, pr_err("%s: CMAC not supported\n", __func__); goto sha_error; } - if ((req->entries == 0) || (req->data_len == 0) || - (req->entries > QCEDEV_MAX_BUFFERS)) { - pr_err("%s: Invalid data length (%d)/ num entries (%d)\n", - __func__, req->data_len, req->entries); + if ((!req->entries) || (req->entries > QCEDEV_MAX_BUFFERS)) { + pr_err("%s: Invalid num entries (%d)\n", + __func__, req->entries); goto sha_error; } diff --git a/drivers/crypto/msm/qcrypto.c b/drivers/crypto/msm/qcrypto.c index 2d833049ea921..9bc3086fa7566 100644 --- a/drivers/crypto/msm/qcrypto.c +++ b/drivers/crypto/msm/qcrypto.c @@ -1248,6 +1248,7 @@ static void _qcrypto_tfm_complete(struct crypto_priv *cp, u32 type, struct qcrypto_resp_ctx *arsp; struct list_head *plist; struct crypto_async_request *areq; + bool pending_list; switch (type) { case CRYPTO_ALG_TYPE_AHASH: @@ -1263,6 +1264,7 @@ static void _qcrypto_tfm_complete(struct crypto_priv *cp, u32 type, spin_lock_irqsave(&cp->lock, flags); if (list_empty(plist)) { arsp = NULL; /* nothing to do */ + pending_list = false; } else { arsp = list_first_entry(plist, struct qcrypto_resp_ctx, list); @@ -1270,12 +1272,17 @@ static void _qcrypto_tfm_complete(struct crypto_priv *cp, u32 type, arsp = NULL; /* still in progress */ else list_del(&arsp->list); /* request is complete */ + if (list_empty(plist)) + pending_list = false; + else + pending_list = true; } spin_unlock_irqrestore(&cp->lock, flags); if (arsp) { areq = arsp->async_req; areq->complete(areq, arsp->res); - goto again; + if (pending_list) + goto again; } } diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 35f36f80be16f..aaa8cdd5a790e 100755 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -1370,16 +1370,15 @@ kgsl_sharedmem_region_empty(struct kgsl_process_private *private, static inline struct kgsl_mem_entry * __must_check kgsl_sharedmem_find_id(struct kgsl_process_private *process, unsigned int id) { - int result = 0; + int result; struct kgsl_mem_entry *entry; spin_lock(&process->mem_lock); entry = idr_find(&process->mem_idr, id); - if (entry) - result = kgsl_mem_entry_get(entry); + result = kgsl_mem_entry_get(entry); spin_unlock(&process->mem_lock); - if (!result) + if (result == 0) return NULL; return entry; } @@ -1595,7 +1594,7 @@ void kgsl_dump_syncpoints(struct kgsl_device *device, } case KGSL_CMD_SYNCPOINT_TYPE_FENCE: if (event->handle) - dev_err(device->dev, " fence: [%p] %s\n", + dev_err(device->dev, " fence: [%pK] %s\n", event->handle->fence, event->handle->name); else @@ -2902,7 +2901,8 @@ static int kgsl_setup_useraddr(struct kgsl_mem_entry *entry, struct vm_area_struct *vma = NULL; int ret; - if (param->offset != 0 || param->hostptr == 0 + if (param->len == 0 || param->offset != 0 + || param->hostptr == 0 || !KGSL_IS_PAGE_ALIGNED(param->hostptr) || !KGSL_IS_PAGE_ALIGNED(param->len)) return -EINVAL; @@ -3936,7 +3936,8 @@ kgsl_mmap_memstore(struct kgsl_device *device, struct vm_area_struct *vma) static void kgsl_gpumem_vm_open(struct vm_area_struct *vma) { struct kgsl_mem_entry *entry = vma->vm_private_data; - if (!kgsl_mem_entry_get(entry)) + + if (kgsl_mem_entry_get(entry) == 0) vma->vm_private_data = NULL; } diff --git a/drivers/gpu/msm/kgsl.h b/drivers/gpu/msm/kgsl.h index 010f8fcb0ac9c..812f5bd40d043 100644 --- a/drivers/gpu/msm/kgsl.h +++ b/drivers/gpu/msm/kgsl.h @@ -397,13 +397,16 @@ static inline int timestamp_cmp(unsigned int a, unsigned int b) static inline int kgsl_mem_entry_get(struct kgsl_mem_entry *entry) { - return kref_get_unless_zero(&entry->refcount); + if (entry) + return kref_get_unless_zero(&entry->refcount); + return 0; } static inline void kgsl_mem_entry_put(struct kgsl_mem_entry *entry) { - kref_put(&entry->refcount, kgsl_mem_entry_destroy); + if (entry) + kref_put(&entry->refcount, kgsl_mem_entry_destroy); } /* diff --git a/drivers/gpu/msm/kgsl_cffdump.c b/drivers/gpu/msm/kgsl_cffdump.c index 431a30f45ddea..120d1a44a0d76 100644 --- a/drivers/gpu/msm/kgsl_cffdump.c +++ b/drivers/gpu/msm/kgsl_cffdump.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2014,2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c index 71a3ff34b7fdb..123edf426aad3 100644 --- a/drivers/gpu/msm/kgsl_iommu.c +++ b/drivers/gpu/msm/kgsl_iommu.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014,2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -333,7 +333,7 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain, iommu_dev = get_iommu_device(iommu_unit, dev); if (!iommu_dev) { - KGSL_CORE_ERR("Invalid IOMMU device %p\n", dev); + KGSL_CORE_ERR("Invalid IOMMU device %pK\n", dev); ret = -ENOSYS; goto done; } @@ -724,7 +724,7 @@ static void kgsl_detach_pagetable_iommu_domain(struct kgsl_mmu *mmu) iommu_unit->dev[j].dev); iommu_unit->dev[j].attached = false; KGSL_MEM_INFO(mmu->device, "iommu %pK detached " - "from user dev of MMU: %p\n", + "from user dev of MMU: %pK\n", iommu_pt->domain, mmu); } } @@ -1695,8 +1695,8 @@ kgsl_iommu_unmap(struct kgsl_pagetable *pt, } else ret = iommu_unmap_range(iommu_pt->domain, gpuaddr, range); if (ret) { - KGSL_CORE_ERR("iommu_unmap_range(%x, %d) failed " - "with err: %d\n", gpuaddr, + KGSL_CORE_ERR("iommu_unmap_range(%pK, %x, %d) failed " + "with err: %d\n", iommu_pt->domain, gpuaddr, range, ret); return ret; } @@ -1807,8 +1807,8 @@ kgsl_iommu_map(struct kgsl_pagetable *pt, sg_temp ? sg_temp : memdesc->sg, size, protflags); if (ret) { - KGSL_CORE_ERR("iommu_map_range(%x, %pK, %zd, %x) err: %d\n", - iommu_virt_addr, + KGSL_CORE_ERR("iommu_map_range(%pK, %x, %pK, %zd, %x) err: %d\n", + iommu_pt->domain, iommu_virt_addr, sg_temp ? sg_temp : memdesc->sg, size, protflags, ret); kgsl_free(sg_temp); @@ -1820,8 +1820,8 @@ kgsl_iommu_map(struct kgsl_pagetable *pt, page_to_phys(kgsl_guard_page), PAGE_SIZE, protflags & ~IOMMU_WRITE); if (ret) { - KGSL_CORE_ERR("iommu_map(%zx, guard, %x) err: %d\n", - iommu_virt_addr + size, + KGSL_CORE_ERR("iommu_map(%pK, %zx, guard, %x) err: %d\n", + iommu_pt->domain, iommu_virt_addr + size, protflags & ~IOMMU_WRITE, ret); /* cleanup the partial mapping */ diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c old mode 100755 new mode 100644 index 4c3eba50295a8..4915087256fbf --- a/drivers/gpu/msm/kgsl_pwrctrl.c +++ b/drivers/gpu/msm/kgsl_pwrctrl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1358,7 +1358,7 @@ int kgsl_pwrctrl_init(struct kgsl_device *device) if (!pwr->pcl) { KGSL_PWR_ERR(device, "msm_bus_scale_register_client failed: " - "id %d table %p %pK", device->id, + "id %d table %pK %pK", device->id, pdata->bus_scale_table, ocmem_scale_table); result = -EINVAL; diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c index 62813c1b4bc9b..5e4fdf3d4cbe4 100644 --- a/drivers/gpu/msm/kgsl_sharedmem.c +++ b/drivers/gpu/msm/kgsl_sharedmem.c @@ -621,6 +621,9 @@ _kgsl_sharedmem_page_alloc(struct kgsl_memdesc *memdesc, memdesc->pagetable = pagetable; memdesc->ops = &kgsl_page_alloc_ops; + /* Check for integer overflow */ + if (sglen_alloc && (sizeof(struct scatterlist) > INT_MAX / sglen_alloc)) + return -EINVAL; memdesc->sg = kgsl_malloc(sglen_alloc * sizeof(struct scatterlist)); if (memdesc->sg == NULL) { diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c index d3ae49770d219..2f3a7f305f523 100644 --- a/drivers/gpu/msm/kgsl_snapshot.c +++ b/drivers/gpu/msm/kgsl_snapshot.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2014,2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 81ddc901a65a9..b4c3bfe660ef3 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -793,11 +793,15 @@ config SENSORS_MMC3416X To compile this driver as a module, choose M here: the module will be called mmc3416x. -config SENSORS_MMC3416X_ALLOW_OVERFLOW - tristate "MMC3416X sensor overflow check" - depends on SENSORS_MMC3416X +config SENSORS_MMC3X30 + tristate "MMC3X30KJ 3-axis magnetic sensor driver" + depends on I2C help - Say Y here if you want to allow overflow in MMC3416X sensor. + Say Y here if you want to enable the MMC3X30KJ magnetic sensor + driver. + + To compile this driver as a module, choose M here: the + module will be called mmc3X30. config SENSORS_AKM09911 tristate "AKM09911 3-axis electronic compass sensor driver" @@ -933,53 +937,38 @@ config SENSORS_BMI058 If you say yes here, you get support for Bosch Sensortec's sensor driver of BMI058. -config INPUT_LSM6DX0 - tristate "STMicroelectronics LSM6DS0 and LSM6DL0" - depends on INPUT - depends on I2C +config SENSORS_BMI160 + tristate "BMI160 Sensor Support" + depends on I2C || SPI_MASTER help - Say Y here to enable STMicroelectronics LSM6DS0 or LSM6DL0inertial - module. - - To compile this driver as a module, choose M here: the - module will be called lsm6dx0. + If you say yes here, you get support for Bosch Sensortec's + sensor driver of BMI160. -config SENSORS_ST480 - tristate "Senodia ST480 magnetic sensor support" - depends on I2C - default n +config SENSORS_BMI160_I2C + tristate "support I2C bus communication" + depends on SENSORS_BMI160 && I2C help - If you say yes here you get support for Senodia - magnetic sensors ST480. + If you say yes here, you get support Bosch Sensortec's BMI160 sensor hooked to an I2C bus. -config SENSORS_MPU6880 - tristate "Invensense MPU6880 support" - depends on I2C - default n - select INPUT_POLLDEV +config BMI160_MAG_INTERFACE_SUPPORT + tristate "BMI160 Sensor mag interface support" + depends on SENSORS_BMI160 help - If you say yes here you get support for Invensense's MPU6880. + If you say yes here, you get support for Bosch Sensortec's + sensor driver of BMI160 with mag sensor support. -config SENSORS_PA12200001 - tristate "TXC_PA12200001 proximity/light sensor support" - depends on I2C - default n +config SENSORS_BMI160_ENABLE_INT1 + tristate "BMI160 sensor interrupt INT1 support" + depends on SENSORS_BMI160 help - If you say yes here you get support for TXC's PA12200001 proximity - and light sensor. - -config SENSORS_YL_HALL - tristate "Yulong/Coolpad Hall sensor support" - default n - help - If you say yes here you get support for Yulong/Coolpad's Hall sensor. + If you say yes here, you get INT1 support for Bosch Sensortec + sensors BMI160. -config SENSORS_YL_PARAMS - tristate "Yulong sensor parameter support" - default n +config SENSORS_BMI160_ENABLE_INT2 + tristate "BMI160 sensor interrupt INT2 support" + depends on SENSORS_BMI160 help - If you say yes here you get support for Yulong/Coolpad's sensor - calibration parameter driver. - + If you say yes here, you get INT2 support for Bosch Sensortec + sensors BMI160. endif diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 46298aba80f86..19be01e2ed2fb 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -69,6 +69,7 @@ obj-$(CONFIG_INPUT_YEALINK) += yealink.o obj-$(CONFIG_BMP18X) += bmp18x-core.o obj-$(CONFIG_BMP18X_I2C) += bmp18x-i2c.o obj-$(CONFIG_SENSORS_MMC3416X) += mmc3416x.o +obj-$(CONFIG_SENSORS_MMC3X30) += mmc3x30.o obj-$(CONFIG_SENSORS_MMA8X5X) += mma8x5x.o obj-$(CONFIG_SENSORS_STK3X1X) += stk3x1x.o obj-$(CONFIG_SENSORS_CAPELLA_CM36283) += cm36283.o @@ -102,14 +103,19 @@ ifeq ($(CONFIG_BOSCH_BMA2X2_ENABLE_INT2),y) EXTRA_CFLAGS += -DBMA2X2_ENABLE_INT2 endif - -ifeq ($(CONFIG_SENSORS_BMA2X2_ENABLE_IDENT),y) - EXTRA_CFLAGS += -DBMA2X2_SENSOR_IDENTIFICATION_ENABLE +obj-$(CONFIG_SENSORS_BMI160) += 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_BMG_FIFO),y) - EXTRA_CFLAGS += -DBMG_USE_FIFO -DBMG_USE_BASIC_I2C_FUNC +ifeq ($(CONFIG_SENSORS_BMI160_ENABLE_INT2),y) + EXTRA_CFLAGS += -DBMI160_ENABLE_INT2 endif -ifeq ($(CONFIG_SENSORS_BMM050),y) - EXTRA_CFLAGS += -DBMM_USE_BASIC_I2C_FUNC -DCONFIG_BMM_USE_PLATFORM_DATA + +obj-$(CONFIG_SENSORS_BMI160_I2C) += bmi160_i2c.o +ifeq ($(CONFIG_SENSORS_BMI160_I2C),y) + EXTRA_CFLAGS += -DBMI_USE_BASIC_I2C_FUNC endif diff --git a/drivers/input/misc/bmi160.c b/drivers/input/misc/bmi160.c new file mode 100644 index 0000000000000..286b975a2a1d2 --- /dev/null +++ b/drivers/input/misc/bmi160.c @@ -0,0 +1,18752 @@ +/* +* @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.c +* @Date: 2015/04/02 +* @id "2e89046" +* @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 + brief */ +#include "bmi160.h" +#include + +/* 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(s16 *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/misc/bmi160.h b/drivers/input/misc/bmi160.h new file mode 100644 index 0000000000000..fdfa5b7700140 --- /dev/null +++ b/drivers/input/misc/bmi160.h @@ -0,0 +1,11605 @@ +/* +**************************************************************************** +* Copyright (C) 2014 Bosch Sensortec GmbH +* +* bmi160.h +* Date : 2015/04/02 +* @id "2e89046" +* 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__ + + +#include + +/***************************************************************/ +/**\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;/** (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< 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(s16 *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/misc/bmi160_driver.c b/drivers/input/misc/bmi160_driver.c new file mode 100644 index 0000000000000..692203386af95 --- /dev/null +++ b/drivers/input/misc/bmi160_driver.c @@ -0,0 +1,5281 @@ +/*! + * @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 2015/08/17 14:40 + * @id "09afbe6" + * @version 1.4 + * + * @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_driver.h" +#include +#include +#include +#include + +#define I2C_BURST_READ_MAX_LEN (256) +#define BMI160_STORE_COUNT (6000) +#define LMADA (1) +uint64_t g_current_apts_us; +static unsigned char g_fifo_data_arr[2048];/*1024 + 12*4*/ + +/*BMI power supply VDD 1.71V-3.6V VIO 1.2-3.6V */ +#define BMI160_VDD_MIN_UV 1750000 +#define BMI160_VDD_MAX_UV 3600000 +#define BMI160_VIO_MIN_UV 1200000 +#define BMI160_VIO_MAX_UV 3600000 + +static struct sensors_classdev accel_cdev = { + .name = "bmi160-accel", + .vendor = "Bosch Corporation", + .version = 1, + .handle = SENSORS_ACCELERATION_HANDLE, + .type = SENSOR_TYPE_ACCELEROMETER, + .max_range = "156.8", + .resolution = "0.00781", + .sensor_power = "0.13", + .min_delay = 1000, + .fifo_reserved_event_count = 0, + .fifo_max_event_count = 0, + .enabled = 0, + .delay_msec = 200, + .sensors_enable = NULL, + .sensors_poll_delay = NULL, + .sensors_calibrate = NULL, + .sensors_write_cal_params = NULL, + .params = NULL, +}; + +static struct sensors_classdev gyro_cdev = { + .name = "bmi160-gyro", + .vendor = "Bosch Corporation", + .version = 1, + .handle = SENSORS_GYROSCOPE_HANDLE, + .type = SENSOR_TYPE_GYROSCOPE, + .max_range = "35", + .resolution = "0.06", + .sensor_power = "0.13", + .min_delay = 2000, + .fifo_reserved_event_count = 0, + .fifo_max_event_count = 0, + .enabled = 0, + .delay_msec = 200, + .sensors_enable = NULL, + .sensors_poll_delay = NULL, + .sensors_calibrate = NULL, + .sensors_write_cal_params = NULL, + .params = NULL, +}; + +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_value_t { + struct bmi160_axis_data_t acc; + struct bmi160_axis_data_t gyro; +#ifdef BMI160_MAG_INTERFACE_SUPPORT + struct bmi160_axis_data_t mag; +#endif + int64_t ts_intvl; +}; +struct bmi160_type_mapping_type { + + /*! bmi16x sensor chip id */ + uint16_t chip_id; + + /*! bmi16x chip revision code */ + uint16_t revision_id; + + /*! bmi160 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; +}; +static struct workqueue_struct *reportdata_wq; +#define FIFO_READ_LENGTH_RECOMMENDED (67) +#define FIFO_SENSORTIME_OVERFLOW_MASK (0x1000000) +#define FIFO_SENSORTIME_RESOLUTION (390625) + +static uint8_t s_fifo_data_buf[FIFO_DATA_BUFSIZE * 2] = {0}; +static uint64_t sensor_time_old = 0; +static uint64_t sensor_time_new = 0; +static uint64_t host_time_old = 0; +static uint64_t host_time_new = 0; + +#define BMI_RING_BUF_SIZE 100 + +static struct bmi160_value_t bmi_ring_buf[BMI_RING_BUF_SIZE]; +static int s_ring_buf_head = 0; +static int s_ring_buf_tail = 0; + + +uint64_t get_current_timestamp(void) +{ + uint64_t ts; + struct timeval tv; + + do_gettimeofday(&tv); + ts = (uint64_t)tv.tv_sec * 1000000 + tv.tv_usec; + + return ts; +} + + +/*! 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*/ + +}; + +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++) { + sprintf(dbg_buf_str0 + i * 3, "%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++) { + sprintf(dbg_buf_str1 + i * 3, "%02x%c", dbg_buf1[i], + (((i + 1) % BYTES_PER_LINE == 0) ? '\n' : ' ')); + } + dev_notice(client_data->dev, "\n%s\n", dbg_buf_str1); + +} + +/*! +* BMI160 sensor remapping function +* need to give some parameter in BSP files first. +*/ +static const struct bosch_sensor_axis_remap + bst_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 int bmi160_power_ctl(struct bmi_client_data *data, bool enable) +{ + int ret = 0; + int err = 0; + + if (!enable && data->power_enabled) { + ret = regulator_disable(data->vdd); + if (ret) { + dev_err(&data->i2c->dev, + "Regulator vdd disable failed ret=%d\n", ret); + return ret; + } + + ret = regulator_disable(data->vio); + if (ret) { + dev_err(&data->i2c->dev, + "Regulator vio disable failed ret=%d\n", ret); + err = regulator_enable(data->vdd); + return ret; + } + data->power_enabled = enable; + } else if (enable && !data->power_enabled) { + ret = regulator_enable(data->vdd); + if (ret) { + dev_err(&data->i2c->dev, + "Regulator vdd enable failed ret=%d\n", ret); + return ret; + } + + ret = regulator_enable(data->vio); + if (ret) { + dev_err(&data->i2c->dev, + "Regulator vio enable failed ret=%d\n", ret); + err = regulator_disable(data->vdd); + return ret; + } + data->power_enabled = enable; + } else { + dev_info(&data->i2c->dev, + "Power on=%d. enabled=%d\n", + enable, data->power_enabled); + } + + return ret; +} + +static int bmi160_power_init(struct bmi_client_data *data) +{ + int ret; + + data->vdd = regulator_get(&data->i2c->dev, "vdd"); + if (IS_ERR(data->vdd)) { + ret = PTR_ERR(data->vdd); + dev_err(&data->i2c->dev, + "Regulator get failed vdd ret=%d\n", ret); + return ret; + } + + if (regulator_count_voltages(data->vdd) > 0) { + ret = regulator_set_voltage(data->vdd, + BMI160_VDD_MIN_UV, + BMI160_VDD_MAX_UV); + if (ret) { + dev_err(&data->i2c->dev, + "Regulator set failed vdd ret=%d\n", + ret); + goto reg_vdd_put; + } + } + + data->vio = regulator_get(&data->i2c->dev, "vio"); + if (IS_ERR(data->vio)) { + ret = PTR_ERR(data->vio); + dev_err(&data->i2c->dev, + "Regulator get failed vio ret=%d\n", ret); + goto reg_vdd_set; + } + + if (regulator_count_voltages(data->vio) > 0) { + ret = regulator_set_voltage(data->vio, + BMI160_VIO_MIN_UV, + BMI160_VIO_MAX_UV); + if (ret) { + dev_err(&data->i2c->dev, + "Regulator set failed vio ret=%d\n", ret); + goto reg_vio_put; + } + } + + return 0; + +reg_vio_put: + regulator_put(data->vio); +reg_vdd_set: + if (regulator_count_voltages(data->vdd) > 0) + regulator_set_voltage(data->vdd, 0, BMI160_VDD_MAX_UV); +reg_vdd_put: + regulator_put(data->vdd); + return ret; +} + +static int bmi160_power_deinit(struct bmi_client_data *data) +{ + if (regulator_count_voltages(data->vdd) > 0) + regulator_set_voltage(data->vdd, + 0, BMI160_VDD_MAX_UV); + + regulator_put(data->vdd); + + if (regulator_count_voltages(data->vio) > 0) + regulator_set_voltage(data->vio, + 0, BMI160_VIO_MAX_UV); + + regulator_put(data->vio); + + return 0; +} + +static void bst_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 bst_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; + bst_remap_sensor_data(data, &bst_axis_remap_tab_dft[place]); +} + +static void bmi_remap_sensor_data(struct bmi160_axis_data_t *val, + struct bmi_client_data *client_data) +{ + struct bosch_sensor_data bsd; + + if ((NULL == client_data->bst_pd) || + (BOSCH_SENSOR_PLACE_UNKNOWN + == client_data->bst_pd->place)) + return; + + bsd.x = val->x; + bsd.y = val->y; + bsd.z = val->z; + + bst_remap_sensor_data_dft_tab(&bsd, + client_data->bst_pd->place); + + val->x = bsd.x; + val->y = bsd.y; + val->z = bsd.z; + +} + +static void bmi_remap_data_acc(struct bmi_client_data *client_data, + struct bmi160_accel_t *acc_frame) +{ + struct bosch_sensor_data bsd; + + if ((NULL == client_data->bst_pd) || + (BOSCH_SENSOR_PLACE_UNKNOWN + == client_data->bst_pd->place)) + return; + + bsd.x = acc_frame->x; + bsd.y = acc_frame->y; + bsd.z = acc_frame->z; + + bst_remap_sensor_data_dft_tab(&bsd, + client_data->bst_pd->place); + + acc_frame->x = bsd.x; + acc_frame->y = bsd.y; + acc_frame->z = bsd.z; + + +} + +static void bmi_remap_data_gyro(struct bmi_client_data *client_data, + struct bmi160_gyro_t *gyro_frame) +{ + struct bosch_sensor_data bsd; + + if ((NULL == client_data->bst_pd) || + (BOSCH_SENSOR_PLACE_UNKNOWN + == client_data->bst_pd->place)) + return; + + bsd.x = gyro_frame->x; + bsd.y = gyro_frame->y; + bsd.z = gyro_frame->z; + + bst_remap_sensor_data_dft_tab(&bsd, + client_data->bst_pd->place); + + gyro_frame->x = bsd.x; + gyro_frame->y = bsd.y; + gyro_frame->z = bsd.z; + + +} + +static 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 = devm_input_allocate_device(&client_data->i2c->dev); + if (NULL == dev) + return -ENOMEM; + + dev->name = BMI160_ACCEL_INPUT_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_drvdata(dev, client_data); + err = input_register_device(dev); + if (err < 0) { + input_free_device(dev); + dev_notice(client_data->dev, "bmi160 accel input free!\n"); + return err; + } + client_data->input_accel = dev; + dev_notice(client_data->dev, + "bmi160 accel input register successfully, %s!\n", + client_data->input_accel->name); + + dev = devm_input_allocate_device(&client_data->i2c->dev); + if (NULL == dev) + return -ENOMEM; + + dev->name = BMI160_GYRO_INPUT_NAME; + dev->id.bustype = BUS_I2C; + + + input_set_capability(dev, EV_ABS, ABS_MISC); + input_set_abs_params(dev, ABS_RX, GYRO_MAX_VALUE, GYRO_MIN_VALUE, 0, 0); + input_set_abs_params(dev, ABS_RY, GYRO_MAX_VALUE, GYRO_MIN_VALUE, 0, 0); + input_set_abs_params(dev, ABS_RZ, GYRO_MAX_VALUE, GYRO_MIN_VALUE, 0, 0); + input_set_drvdata(dev, client_data); + + err = input_register_device(dev); + if (err < 0) { + input_free_device(dev); + dev_notice(client_data->dev, "bmi160 accel input free!\n"); + return err; + } + client_data->input_gyro = dev; + dev_notice(client_data->dev, + "bmi160 gyro input register successfully, %s!\n", + client_data->input_gyro->name); + + return err; +} + + +static void bmi_input_destroy(struct bmi_client_data *client_data) +{ + struct input_dev *dev = client_data->input_accel; + + input_unregister_device(dev); + input_free_device(dev); + + dev = client_data->input_gyro; + 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; + } + } + mdelay(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 enum hrtimer_restart reportdata_timer_fun( + struct hrtimer *hrtimer) +{ + struct bmi_client_data *client_data = + container_of(hrtimer, struct bmi_client_data, timer); + int32_t delay = 0; + delay = atomic_read(&client_data->delay); + 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 bmi_show_enable_timer(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct bmi_client_data *client_data = dev_get_drvdata(dev); + + return snprintf(buf, 16, "%d\n", client_data->is_timer_running); +} + +static ssize_t bmi_store_enable_timer(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long data; + int error; + struct bmi_client_data *client_data = dev_get_drvdata(dev); + 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; + } + } else { + if (1 == client_data->is_timer_running) { + hrtimer_cancel(&client_data->timer); + client_data->is_timer_running = 0; + } + } + return count; +} + +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; + struct bmi160_axis_data_t bmi160_udata; + int err; + + err = BMI_CALL_API(read_accel_xyz)(&data); + if (err < 0) + return; + + bmi160_udata.x = data.x; + bmi160_udata.y = data.y; + bmi160_udata.z = data.z; + + bmi_remap_sensor_data(&bmi160_udata, client_data); + /*report current frame via input event*/ + input_event(client_data->input_accel, EV_ABS, ABS_X, bmi160_udata.x); + input_event(client_data->input_accel, EV_ABS, ABS_Y, bmi160_udata.y); + input_event(client_data->input_accel, EV_ABS, ABS_Z, bmi160_udata.z); + input_sync(client_data->input_accel); + + schedule_delayed_work(&client_data->work, delay); +} + +static void bmi_gyro_work_func(struct work_struct *work) +{ + struct bmi_client_data *client_data = container_of( + (struct delayed_work *)work, + struct bmi_client_data, gyro_work); + unsigned long delay = + msecs_to_jiffies(atomic_read(&client_data->delay)); + struct bmi160_gyro_t data; + struct bmi160_axis_data_t bmi160_udata; + int err; + + err = BMI_CALL_API(read_gyro_xyz)(&data); + if (err < 0) + return; + + bmi160_udata.x = data.x; + bmi160_udata.y = data.y; + bmi160_udata.z = data.z; + + bmi_remap_sensor_data(&bmi160_udata, client_data); + /*report current frame via input event*/ + input_event(client_data->input_gyro, EV_ABS, ABS_RX, bmi160_udata.x); + input_event(client_data->input_gyro, EV_ABS, ABS_RY, bmi160_udata.y); + input_event(client_data->input_gyro, EV_ABS, ABS_RZ, bmi160_udata.z); + input_sync(client_data->input_gyro); + + schedule_delayed_work(&client_data->gyro_work, delay); +} + +static uint8_t dbg_buf_str[2048] = ""; +static void bmi_hrtimer_work_func(struct work_struct *work) +{ + struct bmi_client_data *client_data = + container_of((struct delayed_work *)work, + struct bmi_client_data, work); + + unsigned int fifo_len0 = 0; + unsigned int fifo_frmbytes_ext = 0; + unsigned int fifo_read_len = 0; + int i, err; + + bmi_fifo_frame_bytes_extend_calc(client_data, &fifo_frmbytes_ext); + + err = BMI_CALL_API(fifo_length)(&fifo_len0); + client_data->fifo_bytecount = fifo_len0; + + if (client_data->fifo_bytecount == 0 || err) { + return ; + } + + fifo_read_len = client_data->fifo_bytecount + fifo_frmbytes_ext; + if (fifo_read_len > FIFO_DATA_BUFSIZE) { + fifo_read_len = FIFO_DATA_BUFSIZE; + } + + if (!err) { + err = bmi_burst_read_wrapper(client_data->device.dev_addr, + BMI160_USER_FIFO_DATA__REG, s_fifo_data_buf, + fifo_read_len); + } + + for (i = 0; i < fifo_read_len; i++) { + sprintf(dbg_buf_str + i * 3, "%02x%c", s_fifo_data_buf[i], + (((i + 1) % BYTES_PER_LINE == 0) ? '\n' : ' ')); + } + pr_info("%s\n", dbg_buf_str); + +} + +static ssize_t bmi160_chip_id_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct bmi_client_data *client_data = dev_get_drvdata(dev); + + return sprintf(buf, "0x%x\n", client_data->chip_id); +} + +static ssize_t bmi160_err_st_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct bmi_client_data *client_data = dev_get_drvdata(dev); + int err = 0; + err = bmi_get_err_status(client_data); + if (err) + return err; + else { + return sprintf(buf, "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 sprintf(buf, "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 bmi_client_data *client_data = dev_get_drvdata(dev); + + 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 = sprintf(buf, "%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 bmi_client_data *client_data = dev_get_drvdata(dev); + 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 bmi_client_data *client_data = dev_get_drvdata(dev); + err = bmi160_fifo_data_sel_get(client_data); + if (err) + return -EINVAL; + return sprintf(buf, "%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 bmi_client_data *client_data = dev_get_drvdata(dev); + 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 int bmi_fifo_analysis_handle(struct bmi_client_data *client_data, + u8 *fifo_data, u16 fifo_length, char *buf) +{ + u8 frame_head = 0;/* every frame head*/ + int len = 0; + + /*u8 skip_frame_cnt = 0;*/ + u8 acc_frm_cnt = 0;/*0~146*/ + u8 gyro_frm_cnt = 0; + u8 mag_frm_cnt = 0; + u8 tmp_frm_cnt = 0; + /*u8 tmp_odr = 0;*/ + /*uint64_t current_apts_us = 0;*/ + /*fifo data last frame start_index A G M*/ + u64 fifo_time = 0; + static uint32_t current_frm_ts; + u16 fifo_index = 0;/* fifo data buff index*/ + u16 fifo_index_tmp = 0; + u16 i = 0; + s8 last_return_st = 0; + int err = 0; + unsigned int frame_bytes = 0; + struct bmi160_mag_xyzr_t mag; + struct bmi160_mag_xyz_s32_t mag_comp_xyz; + struct bmi160_accel_t acc_frame_arr[FIFO_FRAME_CNT]; + struct bmi160_gyro_t gyro_frame_arr[FIFO_FRAME_CNT]; + struct bmi160_mag_xyzr_t mag_frame_arr[FIFO_FRAME_CNT]; + + struct odr_t odr; + + memset(&odr, 0, sizeof(odr)); + memset(&mag, 0, sizeof(mag)); + memset(&mag_comp_xyz, 0, sizeof(mag_comp_xyz)); + for (i = 0; i < FIFO_FRAME_CNT; i++) { + memset(&mag_frame_arr[i], 0, sizeof(struct bmi160_mag_xyzr_t)); + memset(&acc_frame_arr[i], 0, sizeof(struct bmi160_accel_t)); + memset(&gyro_frame_arr[i], 0, sizeof(struct bmi160_gyro_t)); + } + /*current_apts_us = get_current_timestamp();*/ + /* no fifo select for bmi sensor*/ + if (!client_data->fifo_data_sel) { + dev_err(client_data->dev, + "No select any sensor FIFO for BMI16x\n"); + return -EINVAL; + } + /*driver need read acc_odr/gyro_odr/mag_odr*/ + if ((client_data->fifo_data_sel) & (1 << BMI_ACC_SENSOR)) + odr.acc_odr = client_data->odr.acc_odr; + if ((client_data->fifo_data_sel) & (1 << BMI_GYRO_SENSOR)) + odr.gyro_odr = client_data->odr.gyro_odr; + if ((client_data->fifo_data_sel) & (1 << BMI_MAG_SENSOR)) + odr.mag_odr = client_data->odr.mag_odr; + bmi_fifo_frame_bytes_extend_calc(client_data, &frame_bytes); +/* search sensor time sub function firstly */ + for (fifo_index = 0; fifo_index < fifo_length;) { + /* conside limited HW i2c burst reading issue, + need to re-calc index 256 512 768 1024...*/ + if ((fifo_index_tmp >> 8) != (fifo_index >> 8)) { + if (fifo_data[fifo_index_tmp] == + fifo_data[(fifo_index >> 8)<<8]) { + fifo_index = (fifo_index >> 8) << 8; + fifo_length += + (fifo_index - fifo_index_tmp + 1); + } + } + fifo_index_tmp = fifo_index; + /* compare index with 256/512/ before doing parsing*/ + if (((fifo_index + frame_bytes) >> 8) != (fifo_index >> 8)) { + fifo_index = ((fifo_index + frame_bytes) >> 8) << 8; + continue; + } + + frame_head = fifo_data[fifo_index]; + + switch (frame_head) { + /*skip frame 0x40 22 0x84*/ + case FIFO_HEAD_SKIP_FRAME: + /*fifo data frame index + 1*/ + fifo_index = fifo_index + 1; + if (fifo_index + 1 > fifo_length) { + last_return_st = FIFO_SKIP_OVER_LEN; + break; + } + /*skip_frame_cnt = fifo_data[fifo_index];*/ + fifo_index = fifo_index + 1; + break; + + /*M & G & A*/ + case FIFO_HEAD_M_G_A: + {/*fifo data frame index + 1*/ + fifo_index = fifo_index + 1; + if (fifo_index + MGA_BYTES_FRM > fifo_length) { + last_return_st = FIFO_M_G_A_OVER_LEN; + break; + } + + /* mag frm index = gyro */ + mag_frm_cnt = gyro_frm_cnt; + mag_frame_arr[mag_frm_cnt].x = + fifo_data[fifo_index + 1] << 8 | + fifo_data[fifo_index + 0]; + mag_frame_arr[mag_frm_cnt].y = + fifo_data[fifo_index + 3] << 8 | + fifo_data[fifo_index + 2]; + mag_frame_arr[mag_frm_cnt].z = + fifo_data[fifo_index + 5] << 8 | + fifo_data[fifo_index + 4]; + mag_frame_arr[mag_frm_cnt].r = + fifo_data[fifo_index + 7] << 8 | + fifo_data[fifo_index + 6]; + + gyro_frame_arr[gyro_frm_cnt].x = + fifo_data[fifo_index + 9] << 8 | + fifo_data[fifo_index + 8]; + gyro_frame_arr[gyro_frm_cnt].y = + fifo_data[fifo_index + 11] << 8 | + fifo_data[fifo_index + 10]; + gyro_frame_arr[gyro_frm_cnt].z = + fifo_data[fifo_index + 13] << 8 | + fifo_data[fifo_index + 12]; + + acc_frame_arr[acc_frm_cnt].x = + fifo_data[fifo_index + 15] << 8 | + fifo_data[fifo_index + 14]; + acc_frame_arr[acc_frm_cnt].y = + fifo_data[fifo_index + 17] << 8 | + fifo_data[fifo_index + 16]; + acc_frame_arr[acc_frm_cnt].z = + fifo_data[fifo_index + 19] << 8 | + fifo_data[fifo_index + 18]; + + mag_frm_cnt++;/* M fram_cnt++ */ + gyro_frm_cnt++;/* G fram_cnt++ */ + acc_frm_cnt++;/* A fram_cnt++ */ + + fifo_index = fifo_index + MGA_BYTES_FRM; + break; + } + + case FIFO_HEAD_M_A: + {/*fifo data frame index + 1*/ + fifo_index = fifo_index + 1; + if (fifo_index + MA_BYTES_FRM > fifo_length) { + last_return_st = FIFO_M_A_OVER_LEN; + break; + } + + mag_frm_cnt = acc_frm_cnt; + + mag_frame_arr[mag_frm_cnt].x = + fifo_data[fifo_index + 1] << 8 | + fifo_data[fifo_index + 0]; + mag_frame_arr[mag_frm_cnt].y = + fifo_data[fifo_index + 3] << 8 | + fifo_data[fifo_index + 2]; + mag_frame_arr[mag_frm_cnt].z = + fifo_data[fifo_index + 5] << 8 | + fifo_data[fifo_index + 4]; + mag_frame_arr[mag_frm_cnt].r = + fifo_data[fifo_index + 7] << 8 | + fifo_data[fifo_index + 6]; + + acc_frame_arr[acc_frm_cnt].x = + fifo_data[fifo_index + 9] << 8 | + fifo_data[fifo_index + 8]; + acc_frame_arr[acc_frm_cnt].y = + fifo_data[fifo_index + 11] << 8 | + fifo_data[fifo_index + 10]; + acc_frame_arr[acc_frm_cnt].z = + fifo_data[fifo_index + 13] << 8 | + fifo_data[fifo_index + 12]; + + mag_frm_cnt++;/* M fram_cnt++ */ + acc_frm_cnt++;/* A fram_cnt++ */ + + fifo_index = fifo_index + MA_BYTES_FRM; + break; + } + + case FIFO_HEAD_M_G: + {/*fifo data frame index + 1*/ + fifo_index = fifo_index + 1; + if (fifo_index + MG_BYTES_FRM > fifo_length) { + last_return_st = FIFO_M_G_OVER_LEN; + break; + } + + mag_frm_cnt = gyro_frm_cnt; + mag_frame_arr[mag_frm_cnt].x = + fifo_data[fifo_index + 1] << 8 | + fifo_data[fifo_index + 0]; + mag_frame_arr[mag_frm_cnt].y = + fifo_data[fifo_index + 3] << 8 | + fifo_data[fifo_index + 2]; + mag_frame_arr[mag_frm_cnt].z = + fifo_data[fifo_index + 5] << 8 | + fifo_data[fifo_index + 4]; + mag_frame_arr[mag_frm_cnt].r = + fifo_data[fifo_index + 7] << 8 | + fifo_data[fifo_index + 6]; + + gyro_frame_arr[gyro_frm_cnt].x = + fifo_data[fifo_index + 9] << 8 | + fifo_data[fifo_index + 8]; + gyro_frame_arr[gyro_frm_cnt].y = + fifo_data[fifo_index + 11] << 8 | + fifo_data[fifo_index + 10]; + gyro_frame_arr[gyro_frm_cnt].z = + fifo_data[fifo_index + 13] << 8 | + fifo_data[fifo_index + 12]; + + mag_frm_cnt++;/* M fram_cnt++ */ + gyro_frm_cnt++;/* G fram_cnt++ */ + fifo_index = fifo_index + MG_BYTES_FRM; + break; + } + + case FIFO_HEAD_G_A: + { /*fifo data frame index + 1*/ + fifo_index = fifo_index + 1; + if (fifo_index + GA_BYTES_FRM > fifo_length) { + last_return_st = FIFO_G_A_OVER_LEN; + break; + } + gyro_frame_arr[gyro_frm_cnt].x = + fifo_data[fifo_index + 1] << 8 | + fifo_data[fifo_index + 0]; + gyro_frame_arr[gyro_frm_cnt].y = + fifo_data[fifo_index + 3] << 8 | + fifo_data[fifo_index + 2]; + gyro_frame_arr[gyro_frm_cnt].z = + fifo_data[fifo_index + 5] << 8 | + fifo_data[fifo_index + 4]; + + acc_frame_arr[acc_frm_cnt].x = + fifo_data[fifo_index + 7] << 8 | + fifo_data[fifo_index + 6]; + acc_frame_arr[acc_frm_cnt].y = + fifo_data[fifo_index + 9] << 8 | + fifo_data[fifo_index + 8]; + acc_frame_arr[acc_frm_cnt].z = + fifo_data[fifo_index + 11] << 8 | + fifo_data[fifo_index + 10]; + + bmi_remap_data_gyro(client_data, + &gyro_frame_arr[gyro_frm_cnt]); + bmi_remap_data_acc(client_data, + &acc_frame_arr[acc_frm_cnt]); + + gyro_frm_cnt++; + acc_frm_cnt++; + fifo_index = fifo_index + GA_BYTES_FRM; + + break; + } + case FIFO_HEAD_A: + { /*fifo data frame index + 1*/ + fifo_index = fifo_index + 1; + if (fifo_index + A_BYTES_FRM > fifo_length) { + last_return_st = FIFO_A_OVER_LEN; + break; + } + + acc_frame_arr[acc_frm_cnt].x = + fifo_data[fifo_index + 1] << 8 | + fifo_data[fifo_index + 0]; + acc_frame_arr[acc_frm_cnt].y = + fifo_data[fifo_index + 3] << 8 | + fifo_data[fifo_index + 2]; + acc_frame_arr[acc_frm_cnt].z = + fifo_data[fifo_index + 5] << 8 | + fifo_data[fifo_index + 4]; + + bmi_remap_data_acc(client_data, + &acc_frame_arr[acc_frm_cnt]); + + acc_frm_cnt++;/*acc_frm_cnt*/ + fifo_index = fifo_index + A_BYTES_FRM; + break; + } + case FIFO_HEAD_G: + { /*fifo data frame index + 1*/ + fifo_index = fifo_index + 1; + if (fifo_index + G_BYTES_FRM > fifo_length) { + last_return_st = FIFO_G_OVER_LEN; + break; + } + + gyro_frame_arr[gyro_frm_cnt].x = + fifo_data[fifo_index + 1] << 8 | + fifo_data[fifo_index + 0]; + gyro_frame_arr[gyro_frm_cnt].y = + fifo_data[fifo_index + 3] << 8 | + fifo_data[fifo_index + 2]; + gyro_frame_arr[gyro_frm_cnt].z = + fifo_data[fifo_index + 5] << 8 | + fifo_data[fifo_index + 4]; + + bmi_remap_data_gyro(client_data, + &gyro_frame_arr[gyro_frm_cnt]); + + gyro_frm_cnt++;/*gyro_frm_cnt*/ + + fifo_index = fifo_index + G_BYTES_FRM; + break; + } + case FIFO_HEAD_M: + { /*fifo data frame index + 1*/ + fifo_index = fifo_index + 1; + if (fifo_index + A_BYTES_FRM > fifo_length) { + last_return_st = FIFO_M_OVER_LEN; + break; + } + + mag_frame_arr[mag_frm_cnt].x = + fifo_data[fifo_index + 1] << 8 | + fifo_data[fifo_index + 0]; + mag_frame_arr[mag_frm_cnt].y = + fifo_data[fifo_index + 3] << 8 | + fifo_data[fifo_index + 2]; + mag_frame_arr[mag_frm_cnt].z = + fifo_data[fifo_index + 5] << 8 | + fifo_data[fifo_index + 4]; + mag_frame_arr[mag_frm_cnt].r = + fifo_data[fifo_index + 7] << 8 | + fifo_data[fifo_index + 6]; + + mag_frm_cnt++;/* M fram_cnt++ */ + + fifo_index = fifo_index + M_BYTES_FRM; + break; + } + + /* sensor time frame*/ + case FIFO_HEAD_SENSOR_TIME: + { + /*fifo data frame index + 1*/ + fifo_index = fifo_index + 1; + + if (fifo_index + 3 > fifo_length) { + last_return_st = FIFO_SENSORTIME_RETURN; + break; + } + fifo_time = + fifo_data[fifo_index + 2] << 16 | + fifo_data[fifo_index + 1] << 8 | + fifo_data[fifo_index + 0]; + + client_data->fifo_time = fifo_time; + /*fifo sensor time frame index + 3*/ + fifo_index = fifo_index + 3; + break; + } + case FIFO_HEAD_OVER_READ_LSB: + /*fifo data frame index + 1*/ + fifo_index = fifo_index + 1; + + if (fifo_index + 1 > fifo_length) { + last_return_st = FIFO_OVER_READ_RETURN; + break; + } + if (fifo_data[fifo_index] == + FIFO_HEAD_OVER_READ_MSB) { + /*fifo over read frame index + 1*/ + fifo_index = fifo_index + 1; + break; + } else { + last_return_st = FIFO_OVER_READ_RETURN; + break; + } + + default: + last_return_st = 1; + break; + + } + if (last_return_st) + break; + } + fifo_time = 0; +/*current_frm_ts = current_apts_us - +((fifo_time & (sensortime_duration_tbl[odr.acc_odr].ts_delat)) + +(sensortime_duration_tbl[odr.acc_odr].ts_duration_lsb +*(acc_frm_cnt - i - 1)))*625/16;*/ +/*Acc Only*/ + if (client_data->fifo_data_sel == BMI_FIFO_A_SEL) { + for (i = 0; i < acc_frm_cnt; i++) { + /*current_frm_ts += 256;*/ + current_frm_ts += + sensortime_duration_tbl[odr.acc_odr].ts_duration_us*LMADA; + + len = sprintf(buf, "%s %d %d %d %u ", + ACC_FIFO_HEAD, + acc_frame_arr[i].x, + acc_frame_arr[i].y, + acc_frame_arr[i].z, + current_frm_ts); + buf += len; + err += len; + } + } + + + /*only for G*/ + if (client_data->fifo_data_sel == BMI_FIFO_G_SEL) { + for (i = 0; i < gyro_frm_cnt; i++) { + /*current_frm_ts += 256;*/ + current_frm_ts += + sensortime_duration_tbl[odr.gyro_odr].ts_duration_us*LMADA; + + len = sprintf(buf, "%s %d %d %d %u ", + GYRO_FIFO_HEAD, + gyro_frame_arr[i].x, + gyro_frame_arr[i].y, + gyro_frame_arr[i].z, + current_frm_ts + ); + buf += len; + err += len; + } + } + + /*only for M*/ + if (client_data->fifo_data_sel == BMI_FIFO_M_SEL) { + for (i = 0; i < mag_frm_cnt; i++) { + /*current_frm_ts += 256;*/ + current_frm_ts += + sensortime_duration_tbl[odr.mag_odr].ts_duration_us*LMADA; +#ifdef BMI160_AKM09912_SUPPORT + mag_comp_xyz.x = mag_frame_arr[i].x; + mag_comp_xyz.y = mag_frame_arr[i].y; + mag_comp_xyz.z = mag_frame_arr[i].z; + bmi160_bst_akm09912_compensate_xyz_raw( + &mag_comp_xyz); +#else + mag.x = mag_frame_arr[i].x >> 3; + mag.y = mag_frame_arr[i].y >> 3; + mag.z = mag_frame_arr[i].z >> 1; + mag.r = mag_frame_arr[i].r >> 2; + bmi160_bmm150_mag_compensate_xyz_raw( + &mag_comp_xyz, mag); +#endif + len = sprintf(buf, "%s %d %d %d %u ", + MAG_FIFO_HEAD, + mag_comp_xyz.x, + mag_comp_xyz.y, + mag_comp_xyz.z, + current_frm_ts + ); + + buf += len; + err += len; + } + + } + +/*only for A M G*/ +if (client_data->fifo_data_sel == BMI_FIFO_M_G_A_SEL) { + + for (i = 0; i < gyro_frm_cnt; i++) { + /*sensor timeLSB*/ + /*dia(sensor_time) = fifo_time & (0xff), uint:LSB, 39.0625us*/ + /*AP tinmestamp 390625/10000 = 625 /16 */ + current_frm_ts += + sensortime_duration_tbl[odr.gyro_odr].ts_duration_us*LMADA; + + if (mag_frame_arr[i].x) { +#ifdef BMI160_AKM09912_SUPPORT + mag_comp_xyz.x = mag_frame_arr[i].x; + mag_comp_xyz.y = mag_frame_arr[i].y; + mag_comp_xyz.z = mag_frame_arr[i].z; + bmi160_bst_akm09912_compensate_xyz_raw( + &mag_comp_xyz); +#else + mag.x = mag_frame_arr[i].x >> 3; + mag.y = mag_frame_arr[i].y >> 3; + mag.z = mag_frame_arr[i].z >> 1; + mag.r = mag_frame_arr[i].r >> 2; + bmi160_bmm150_mag_compensate_xyz_raw( + &mag_comp_xyz, mag); +#endif + len = sprintf(buf, + "%s %d %d %d %u %s %d %d %d %u %s %d %d %d %u ", + GYRO_FIFO_HEAD, + gyro_frame_arr[i].x, + gyro_frame_arr[i].y, + gyro_frame_arr[i].z, + current_frm_ts, + ACC_FIFO_HEAD, + acc_frame_arr[i].x, + acc_frame_arr[i].y, + acc_frame_arr[i].z, + current_frm_ts, + MAG_FIFO_HEAD, + mag_comp_xyz.x, + mag_comp_xyz.y, + mag_comp_xyz.z, + current_frm_ts); + buf += len; + err += len; + } else { + len = sprintf(buf, + "%s %d %d %d %u %s %d %d %d %u ", + GYRO_FIFO_HEAD, + gyro_frame_arr[i].x, + gyro_frame_arr[i].y, + gyro_frame_arr[i].z, + current_frm_ts, + ACC_FIFO_HEAD, + acc_frame_arr[i].x, + acc_frame_arr[i].y, + acc_frame_arr[i].z, + current_frm_ts + ); + + buf += len; + err += len; + } + } + +} +/*only for A G*/ +if (client_data->fifo_data_sel == BMI_FIFO_G_A_SEL) { + + for (i = 0; i < gyro_frm_cnt; i++) { + /*sensor timeLSB*/ + /*dia(sensor_time) = fifo_time & (0xff), uint:LSB, 39.0625us*/ + /*AP tinmestamp 390625/10000 = 625 /16 */ + current_frm_ts += + sensortime_duration_tbl[odr.gyro_odr].ts_duration_us*LMADA; + len = sprintf(buf, + "%s %d %d %d %u %s %d %d %d %u ", + GYRO_FIFO_HEAD, + gyro_frame_arr[i].x, + gyro_frame_arr[i].y, + gyro_frame_arr[i].z, + current_frm_ts, + ACC_FIFO_HEAD, + acc_frame_arr[i].x, + acc_frame_arr[i].y, + acc_frame_arr[i].z, + current_frm_ts + ); + buf += len; + err += len; + } + } + +/*only for A M */ +if (client_data->fifo_data_sel == BMI_FIFO_M_A_SEL) { + for (i = 0; i < acc_frm_cnt; i++) { + /*sensor timeLSB*/ + /*dia(sensor_time) = fifo_time & (0xff), uint:LSB, 39.0625us*/ + /*AP tinmestamp 390625/10000 = 625 /16 */ + /*current_frm_ts += 256;*/ + current_frm_ts += + sensortime_duration_tbl[odr.acc_odr].ts_duration_us*LMADA; + + if (mag_frame_arr[i].x) { +#ifdef BMI160_AKM09912_SUPPORT + mag_comp_xyz.x = mag_frame_arr[i].x; + mag_comp_xyz.y = mag_frame_arr[i].y; + mag_comp_xyz.z = mag_frame_arr[i].z; + bmi160_bst_akm09912_compensate_xyz_raw( + &mag_comp_xyz); +#else + mag.x = mag_frame_arr[i].x >> 3; + mag.y = mag_frame_arr[i].y >> 3; + mag.z = mag_frame_arr[i].z >> 1; + mag.r = mag_frame_arr[i].r >> 2; + bmi160_bmm150_mag_compensate_xyz_raw( + &mag_comp_xyz, mag); +#endif + len = sprintf(buf, + "%s %d %d %d %u %s %d %d %d %u ", + ACC_FIFO_HEAD, + acc_frame_arr[i].x, + acc_frame_arr[i].y, + acc_frame_arr[i].z, + current_frm_ts, + MAG_FIFO_HEAD, + mag_comp_xyz.x, + mag_comp_xyz.y, + mag_comp_xyz.z, + current_frm_ts); + buf += len; + err += len; + } else { + len = sprintf(buf, "%s %d %d %d %u ", + ACC_FIFO_HEAD, + acc_frame_arr[i].x, + acc_frame_arr[i].y, + acc_frame_arr[i].z, + current_frm_ts + ); + + buf += len; + err += len; + } + } +} + +/*only forG M*/ +if (client_data->fifo_data_sel == BMI_FIFO_M_G_SEL) { + if (gyro_frm_cnt) { + tmp_frm_cnt = gyro_frm_cnt; + /*tmp_odr = odr.gyro_odr;*/ + } + + for (i = 0; i < tmp_frm_cnt; i++) { + current_frm_ts += + sensortime_duration_tbl[odr.gyro_odr].ts_duration_us*LMADA; + if (mag_frame_arr[i].x) { +#ifdef BMI160_AKM09912_SUPPORT + mag_comp_xyz.x = mag_frame_arr[i].x; + mag_comp_xyz.y = mag_frame_arr[i].y; + mag_comp_xyz.z = mag_frame_arr[i].z; + bmi160_bst_akm09912_compensate_xyz_raw( + &mag_comp_xyz); +#else + mag.x = mag_frame_arr[i].x >> 3; + mag.y = mag_frame_arr[i].y >> 3; + mag.z = mag_frame_arr[i].z >> 1; + mag.r = mag_frame_arr[i].r >> 2; + bmi160_bmm150_mag_compensate_xyz_raw( + &mag_comp_xyz, mag); +#endif + len = sprintf(buf, + "%s %d %d %d %u %s %d %d %d %u ", + GYRO_FIFO_HEAD, + gyro_frame_arr[i].x, + gyro_frame_arr[i].y, + gyro_frame_arr[i].z, + current_frm_ts, + MAG_FIFO_HEAD, + mag_comp_xyz.x, + mag_comp_xyz.y, + mag_comp_xyz.z, + current_frm_ts); + buf += len; + err += len; + } else { + len = sprintf(buf, "%s %d %d %d %u ", + GYRO_FIFO_HEAD, + gyro_frame_arr[i].x, + gyro_frame_arr[i].y, + gyro_frame_arr[i].z, + current_frm_ts + ); + + buf += len; + err += len; + } + } +} + + + return err; + + +} + + +static ssize_t bmi160_fifo_data_out_frame_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct bmi_client_data *client_data = dev_get_drvdata(dev); + int err = 0; + unsigned int fifo_bytecount_tmp; + + if (client_data->selftest > 0) { + dev_err(client_data->dev, + "in selftest no data available in fifo_data_frame\n"); + return -ENOMEM; + } + + if (NULL == g_fifo_data_arr) { + dev_err(client_data->dev, + "no memory available in fifo_data_frame\n"); + return -ENOMEM; + } + + if (client_data->pw.acc_pm == 2 && client_data->pw.gyro_pm == 2 + && client_data->pw.mag_pm == 2) { + dev_err(client_data->dev, "pw_acc: %d, pw_gyro: %d, pw_mag:%d\n", + client_data->pw.acc_pm, client_data->pw.gyro_pm, + client_data->pw.mag_pm); + return -EINVAL; + } + if (!client_data->fifo_data_sel) + return sprintf(buf, + "no selsect sensor fifo, fifo_data_sel:%d\n", + client_data->fifo_data_sel); + + if (client_data->fifo_bytecount == 0) + return -EINVAL; + + g_current_apts_us = get_current_timestamp(); + + BMI_CALL_API(fifo_length)(&fifo_bytecount_tmp); + if (fifo_bytecount_tmp > client_data->fifo_bytecount) + client_data->fifo_bytecount = fifo_bytecount_tmp; + if (client_data->fifo_bytecount > 210) { + /*err += BMI_CALL_API(set_command_register)( + CMD_CLR_FIFO_DATA);*/ + client_data->fifo_bytecount = 210; + } + if (!err) { + memset(g_fifo_data_arr, 0, 2048); + err = bmi_burst_read_wrapper(client_data->device.dev_addr, + BMI160_USER_FIFO_DATA__REG, g_fifo_data_arr, + client_data->fifo_bytecount); + } else + dev_err(client_data->dev, "read fifo leght err"); + if (err) { + dev_err(client_data->dev, "brust read fifo err\n"); + return err; + } + err = bmi_fifo_analysis_handle(client_data, g_fifo_data_arr, + client_data->fifo_bytecount, buf); + + + return err; +} + +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 sprintf(buf, "%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; + struct bmi_client_data *client_data = dev_get_drvdata(dev); + + 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; + + pr_info("fifo_watermark count %d", count); + + if (BMI_CALL_API(set_intr_enable_1) + (BMI160_FIFO_WM_ENABLE, 1) < 0) { + pr_info("set fifo wm enable failed"); + return -EIO; + } + mutex_lock(&client_data->mutex_ring_buf); + s_ring_buf_head = s_ring_buf_tail = 0; + mutex_unlock(&client_data->mutex_ring_buf); + + 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 sprintf(buf, "%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 bmi_client_data *client_data = dev_get_drvdata(dev); + 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 = sprintf(buf, "%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 = sprintf(buf, "%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 bmi_client_data *client_data = dev_get_drvdata(dev); + 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; + mdelay(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; + mdelay(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; + mdelay(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; + mdelay(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 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; + msleep(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; + msleep(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; + msleep(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 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 = sprintf(buf, "0x%x\n", temp); + + return err; +} + +static ssize_t bmi160_place_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct bmi_client_data *client_data = dev_get_drvdata(dev); + int place = BOSCH_SENSOR_PLACE_UNKNOWN; + + if (NULL != client_data->bst_pd) + place = client_data->bst_pd->place; + + return sprintf(buf, "%d\n", place); +} + +static ssize_t bmi160_delay_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct bmi_client_data *client_data = dev_get_drvdata(dev); + + return sprintf(buf, "%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 bmi_client_data *client_data = dev_get_drvdata(dev); + 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 bmi_client_data *client_data = dev_get_drvdata(dev); + + return sprintf(buf, "%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 bmi_client_data *client_data = dev_get_drvdata(dev); + 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) { + if (bmi160_power_ctl(client_data, true)) { + dev_err(dev, "power up sensor failed.\n"); + goto mutex_exit; + } + 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); + if (bmi160_power_ctl(client_data, false)) { + dev_err(dev, "power up sensor failed.\n"); + goto mutex_exit; + } + } + } + +mutex_exit: + mutex_unlock(&client_data->mutex_enable); + + mutex_lock(&client_data->mutex_ring_buf); + s_ring_buf_head = s_ring_buf_tail = 0; + mutex_unlock(&client_data->mutex_ring_buf); + + 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 sprintf(buf, "%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 sprintf(buf, "%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 bmi_client_data *client_data = dev_get_drvdata(dev); + 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 sprintf(buf, "%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 bmi_client_data *client_data = dev_get_drvdata(dev); + + 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 bmi_client_data *client_data = dev_get_drvdata(dev); + + 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; + 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; + 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 sprintf(buf, "%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) + pr_info("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 bmi_client_data *client_data = dev_get_drvdata(dev); + + err = BMI_CALL_API(get_accel_range)(&range); + if (err) + return err; + + client_data->range.acc_range = range; + return sprintf(buf, "%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 bmi_client_data *client_data = dev_get_drvdata(dev); + + 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 bmi_client_data *client_data = dev_get_drvdata(dev); + + err = BMI_CALL_API(get_accel_output_data_rate)(&acc_odr); + if (err) + return err; + + client_data->odr.acc_odr = acc_odr; + return sprintf(buf, "%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 bmi_client_data *client_data = dev_get_drvdata(dev); + + 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 bmi_client_data *client_data = dev_get_drvdata(dev); + 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 sprintf(buf, "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 bmi_client_data *client_data = dev_get_drvdata(dev); + 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 bmi_client_data *client_data = dev_get_drvdata(dev); + struct bmi160_accel_t data; + struct bmi160_axis_data_t bmi160_udata; + int err; + + err = BMI_CALL_API(read_accel_xyz)(&data); + if (err < 0) + return err; + + bmi160_udata.x = data.x; + bmi160_udata.y = data.y; + bmi160_udata.z = data.z; + + bmi_remap_sensor_data(&bmi160_udata, client_data); + return sprintf(buf, "%hd %hd %hd\n", + bmi160_udata.x, bmi160_udata.y, bmi160_udata.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 sprintf(buf, "%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 bmi_client_data *client_data = dev_get_drvdata(dev); + + 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 sprintf(buf, "%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 bmi_client_data *client_data = dev_get_drvdata(dev); + + 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 sprintf(buf, "%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 bmi_client_data *client_data = dev_get_drvdata(dev); + + 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) { + input_event(client_data->input_accel, EV_MSC, + INPUT_EVENT_FAST_ACC_CALIB_DONE, 1); + input_sync(client_data->input_accel); + 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 sprintf(buf, "%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 sprintf(buf, "%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 sprintf(buf, "%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 bmi_client_data *client_data = dev_get_drvdata(dev); + 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 sprintf(buf, "%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 bmi_client_data *client_data = dev_get_drvdata(dev); + + err = BMI_CALL_API(get_step_counter_enable)(&data); + + client_data->stc_enable = data; + + if (err < 0) + return err; + return sprintf(buf, "%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 bmi_client_data *client_data = dev_get_drvdata(dev); + + 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) +{ + s16 data; + int err; + static u16 last_stc_value; + struct bmi_client_data *client_data = dev_get_drvdata(dev); + + 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 sprintf(buf, "%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 bmi_client_data *client_data = dev_get_drvdata(dev); + 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 sprintf(buf, "%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 int bmi_ring_buf_get(struct bmi160_value_t *pData); +static ssize_t bmi160_ring_buf_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int err = 0; + int len; + struct bmi160_value_t data; + char *tmp = buf; + + struct bmi_client_data *client_data = dev_get_drvdata(dev); + + mutex_lock(&client_data->mutex_ring_buf); + while (bmi_ring_buf_get(&data) != 0) + { +#ifdef BMI160_MAG_INTERFACE_SUPPORT + len = snprintf(tmp, PAGE_SIZE, + "%d %d %d %d %d %d %d %d %d %lld", + data.acc.x, data.acc.y, data.acc.z, + data.gyro.x, data.gyro.y, data.gyro.z, + data.mag.x, data.mag.y, data.mag.z, + data.ts_intvl); + pr_info("%d %d %d %lld\n", + data.mag.x, + data.mag.y, + data.mag.z, + data.ts_intvl); +#else + len = snprintf(tmp, PAGE_SIZE, + "%d %d %d %d %d %d %lld", + data.acc.x, data.acc.y, data.acc.z, + data.gyro.x, data.gyro.y, data.gyro.z, + data.ts_intvl); +#endif + tmp += len; + err += len; + pr_info("%d %d %d %d %d %d %lld\n", + data.acc.x, data.acc.y, data.acc.z, + data.gyro.x, data.gyro.y, data.gyro.z, + data.ts_intvl); + + } + mutex_unlock(&client_data->mutex_ring_buf); + return err; + +} + +static ssize_t bmi160_selftest_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct bmi_client_data *client_data = dev_get_drvdata(dev); + + return sprintf(buf, "0x%x\n", + atomic_read(&client_data->selftest_result)); +} + +static int bmi_restore_hw_cfg(struct bmi_client_data *client); +static void bmi_delay(u32 msec); +/*! + * @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 bmi_client_data *client_data = dev_get_drvdata(dev); + 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; + +#ifdef BMI160_MAG_INTERFACE_SUPPORT + struct bmi160_mag_xyz_s32_t pos_data; + struct bmi160_mag_xyz_s32_t neg_data; +#endif + + dev_notice(client_data->dev, "Selftest for BMI16x starting.\n"); + + client_data->selftest = 1; + +#ifdef BMI160_MAG_INTERFACE_SUPPORT + /* Power mode value 0x06 */ + err += bmi160_set_mag_write_data(BMI160_BMM_POWER_MODE_REG); + bmi_delay(BMI160_GEN_READ_WRITE_DELAY); + /*write 0x4C register to write set power mode to normal*/ + err += bmi160_set_mag_write_addr(BMI160_BMM150_POWE_MODE_REG); + bmi_delay(BMI160_GEN_READ_WRITE_DELAY); + + /* 0x18 Sets the PMU mode for the Magnetometer to suspend */ + err += bmi160_set_mag_write_data(MAG_MODE_SUSPEND); + bmi_delay(BMI160_GEN_READ_WRITE_DELAY); + /* write 0x18 to register 0x4E */ + err += bmi160_set_mag_write_addr(BMI160_USER_MAG_IF_3_ADDR); + /* write the Z repetitions*/ + /* The v_data_u8 have to write for the register + It write the value in the register 0x4F*/ + err += bmi160_set_mag_write_data(BMI160_MAG_REGULAR_REPZ); + bmi_delay(BMI160_GEN_READ_WRITE_DELAY); + err += bmi160_set_mag_write_addr(BMI160_BMM150_Z_REP); + bmi_delay(BMI160_GEN_READ_WRITE_DELAY); + + /* 0xC2 */ + err += bmi160_set_mag_write_data(0xC2); + bmi_delay(BMI160_GEN_READ_WRITE_DELAY); + /* write register 0x4C */ + err += bmi160_set_mag_write_addr(BMI160_BMM150_POWE_MODE_REG); + bmi_delay(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + + err += bmi160_bmm150_mag_compensate_xyz(&pos_data); + bmi_delay(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + /* 0X82 */ + err += bmi160_set_mag_write_data(0x82); + bmi_delay(BMI160_GEN_READ_WRITE_DELAY); + /* write register 0x4C */ + err += bmi160_set_mag_write_addr(BMI160_BMM150_POWE_MODE_REG); + + bmi_delay(BMI160_SEC_INTERFACE_GEN_READ_WRITE_DELAY); + err += bmi160_bmm150_mag_compensate_xyz(&neg_data); + + diff_axis[2] = pos_data.z - neg_data.z; + dev_info(client_data->dev, + "pos_data.x:%d, pos_data.y:%d, pos_data.z:%d,\nneg_data.x:%d, neg_data.y:%d, neg_data.z:%d\n", + pos_data.x, pos_data.y, pos_data.z, neg_data.x, neg_data.y, neg_data.z); +#endif + + /*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 bmi_client_data *client_data = dev_get_drvdata(dev); + 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 sprintf(buf, "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 bmi_client_data *client_data = dev_get_drvdata(dev); + 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; + mdelay(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; + mdelay(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; + mdelay(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 bmi_client_data *client_data = dev_get_drvdata(dev); + struct bmi160_gyro_t data; + struct bmi160_axis_data_t bmi160_udata; + int err; + + err = BMI_CALL_API(read_gyro_xyz)(&data); + if (err < 0) + return err; + + bmi160_udata.x = data.x; + bmi160_udata.y = data.y; + bmi160_udata.z = data.z; + + bmi_remap_sensor_data(&bmi160_udata, client_data); + + return sprintf(buf, "%hd %hd %hd\n", bmi160_udata.x, + bmi160_udata.y, bmi160_udata.z); +} + +static ssize_t bmi160_gyro_range_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int err; + unsigned char range; + struct bmi_client_data *client_data = dev_get_drvdata(dev); + + err = BMI_CALL_API(get_gyro_range)(&range); + if (err) + return err; + + client_data->range.gyro_range = range; + return sprintf(buf, "%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 bmi_client_data *client_data = dev_get_drvdata(dev); + + 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 bmi_client_data *client_data = dev_get_drvdata(dev); + + err = BMI_CALL_API(get_gyro_output_data_rate)(&gyro_odr); + if (err) + return err; + + client_data->odr.gyro_odr = gyro_odr; + return sprintf(buf, "%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 bmi_client_data *client_data = dev_get_drvdata(dev); + + 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 sprintf(buf, "%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 bmi_client_data *client_data = dev_get_drvdata(dev); + + 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_gyro, EV_MSC, + INPUT_EVENT_FAST_GYRO_CALIB_DONE, 1); + input_sync(client_data->input_gyro); + } + 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 sprintf(buf, "%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 sprintf(buf, "%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 sprintf(buf, "%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 bmi_client_data *client_data = dev_get_drvdata(dev); + 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 sprintf(buf, "%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 bmi_client_data *client_data = dev_get_drvdata(dev); + 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 */ +#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 + client_data->pw.mag_pm = BMI_MAG_PM_NORMAL; + mdelay(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*/ +#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 + client_data->pw.mag_pm = BMI_MAG_PM_LP1; + mdelay(5); + break; + case BMI_MAG_PM_SUSPEND: + case BMI_MAG_PM_LP2: +#ifdef 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; + mdelay(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 bmi_client_data *client_data = dev_get_drvdata(dev); + + err = BMI_CALL_API(get_mag_output_data_rate)(&mag_odr); + if (err) + return err; + + client_data->odr.mag_odr = mag_odr; + return sprintf(buf, "%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 bmi_client_data *client_data = dev_get_drvdata(dev); + + 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 sprintf(buf, "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 bmi_client_data *client_data = dev_get_drvdata(dev); + struct bmi160_mag_xyz_s32_t data; + + struct bmi160_axis_data_t bmi160_udata; + int err; + /* raw data with compensation */ +#ifdef 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"); + } + bmi160_udata.x = data.x; + bmi160_udata.y = data.y; + bmi160_udata.z = data.z; + + bmi_remap_sensor_data(&bmi160_udata, client_data); + return sprintf(buf, "%hd %hd %hd\n", bmi160_udata.x, + bmi160_udata.y, bmi160_udata.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 sprintf(buf, "%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 */ +#ifdef 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 sprintf(buf, "chip_id:0x%x\n", mag_chipid); + +} + +#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 bmi_register_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct bmi_client_data *client_data = dev_get_drvdata(dev); + bmi_dump_reg(client_data); + + return sprintf(buf, "Dump OK\n"); +} + +static ssize_t bmi_register_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int err; + int reg_addr = 0; + int data; + u8 write_reg_add = 0; + u8 write_data = 0; + struct bmi_client_data *client_data = dev_get_drvdata(dev); + + err = sscanf(buf, "%3d %3d", ®_addr, &data); + if (err < 2) + return err; + + if (data > 0xff) + return -EINVAL; + + write_reg_add = (u8)reg_addr; + write_data = (u8)data; + err += BMI_CALL_API(write_reg)(write_reg_add, &write_data, 1); + + if (!err) { + dev_info(client_data->dev, "write reg 0x%2x, value= 0x%2x\n", + reg_addr, data); + } else { + dev_err(client_data->dev, "write reg fail\n"); + return err; + } + return count; +} + +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|S_IWGRP|S_IWOTH, + bmi160_selftest_show, bmi160_selftest_store); +static DEVICE_ATTR(fifo_flush, S_IWUSR|S_IWGRP|S_IWOTH, + NULL, bmi160_fifo_flush_store); +static DEVICE_ATTR(fifo_bytecount, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_fifo_bytecount_show, bmi160_fifo_bytecount_store); +static DEVICE_ATTR(fifo_data_sel, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + 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|S_IWGRP|S_IWOTH, + bmi160_fifo_watermark_show, bmi160_fifo_watermark_store); + +static DEVICE_ATTR(fifo_header_en, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_fifo_header_en_show, bmi160_fifo_header_en_store); +static DEVICE_ATTR(fifo_time_en, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_fifo_time_en_show, bmi160_fifo_time_en_store); +static DEVICE_ATTR(fifo_int_tag_en, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + 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|S_IWGRP|S_IWOTH, + bmi160_delay_show, bmi160_delay_store); +static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_enable_show, bmi160_enable_store); +static DEVICE_ATTR(acc_range, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_acc_range_show, bmi160_acc_range_store); +static DEVICE_ATTR(acc_odr, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_acc_odr_show, bmi160_acc_odr_store); +static DEVICE_ATTR(acc_op_mode, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + 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|S_IWGRP|S_IWOTH, + bmi160_acc_fast_calibration_x_show, + bmi160_acc_fast_calibration_x_store); +static DEVICE_ATTR(acc_fast_calibration_y, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_acc_fast_calibration_y_show, + bmi160_acc_fast_calibration_y_store); +static DEVICE_ATTR(acc_fast_calibration_z, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_acc_fast_calibration_z_show, + bmi160_acc_fast_calibration_z_store); +static DEVICE_ATTR(acc_offset_x, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_acc_offset_x_show, + bmi160_acc_offset_x_store); +static DEVICE_ATTR(acc_offset_y, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_acc_offset_y_show, + bmi160_acc_offset_y_store); +static DEVICE_ATTR(acc_offset_z, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + 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|S_IWGRP|S_IWOTH, + bmi160_step_counter_enable_show, + bmi160_step_counter_enable_store); +static DEVICE_ATTR(stc_mode, S_IWUSR|S_IWGRP|S_IWOTH, + NULL, bmi160_step_counter_mode_store); +static DEVICE_ATTR(stc_clc, S_IWUSR|S_IWGRP|S_IWOTH, + NULL, bmi160_step_counter_clc_store); +static DEVICE_ATTR(stc_value, S_IRUGO, + bmi160_step_counter_value_show, NULL); + + +/* gyro part */ +static DEVICE_ATTR(gyro_op_mode, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + 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|S_IWGRP|S_IWOTH, + bmi160_gyro_range_show, bmi160_gyro_range_store); +static DEVICE_ATTR(gyro_odr, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_gyro_odr_show, bmi160_gyro_odr_store); +static DEVICE_ATTR(gyro_fast_calibration_en, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, +bmi160_gyro_fast_calibration_en_show, bmi160_gyro_fast_calibration_en_store); +static DEVICE_ATTR(gyro_offset_x, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, +bmi160_gyro_offset_x_show, bmi160_gyro_offset_x_store); +static DEVICE_ATTR(gyro_offset_y, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, +bmi160_gyro_offset_y_show, bmi160_gyro_offset_y_store); +static DEVICE_ATTR(gyro_offset_z, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, +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|S_IWGRP|S_IWOTH, + bmi160_mag_op_mode_show, bmi160_mag_op_mode_store); +static DEVICE_ATTR(mag_odr, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_mag_odr_show, bmi160_mag_odr_store); +static DEVICE_ATTR(mag_i2c_addr, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + 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|S_IWGRP|S_IWOTH, + bmi160_mag_offset_show, bmi160_mag_offset_store); + +static DEVICE_ATTR(mag_chip_id, S_IRUGO, + bmi160_mag_chip_id_show, NULL); + +#endif + + +#if defined(BMI160_ENABLE_INT1) || defined(BMI160_ENABLE_INT2) +static DEVICE_ATTR(enable_int, S_IWUSR|S_IWGRP|S_IWOTH, + NULL, bmi_enable_int_store); +static DEVICE_ATTR(anymot_duration, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_anymot_duration_show, bmi160_anymot_duration_store); +static DEVICE_ATTR(anymot_threshold, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + 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|S_IWGRP|S_IWOTH, + bmi160_step_detector_enable_show, + bmi160_step_detector_enable_store); +static DEVICE_ATTR(sig_en, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi160_signification_motion_enable_show, + bmi160_signification_motion_enable_store); + +#endif +static DEVICE_ATTR(enable_timer, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi_show_enable_timer, bmi_store_enable_timer); + +static DEVICE_ATTR(register, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH, + bmi_register_show, bmi_register_store); + +static DEVICE_ATTR(bmi_value, S_IRUGO, + bmi160_bmi_value_show, NULL); + +static DEVICE_ATTR(bmi_ring_buf, S_IRUGO, + bmi160_ring_buf_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_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_value.attr, + &dev_attr_mag_offset.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_enable_timer.attr, + &dev_attr_register.attr, + &dev_attr_bmi_value.attr, + &dev_attr_bmi_ring_buf.attr, + NULL +}; + +static struct attribute_group bmi160_attribute_group = { + .attrs = bmi160_attributes +}; + +static void bmi_delay(u32 msec) +{ + mdelay(msec); +} + +#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 uint64_t bmi_get_alarm_timestamp_ns(void) +{ + uint64_t ts_ap; + struct timespec tmp_time; + get_monotonic_boottime(&tmp_time); + ts_ap = (uint64_t)tmp_time.tv_sec * 1000000000L + tmp_time.tv_nsec; + return ts_ap; +} + + +static int bmi_ring_buf_empty(void) +{ + return s_ring_buf_head == s_ring_buf_tail; +} + +static int bmi_ring_buf_full(void) +{ + return (s_ring_buf_tail + 1) % BMI_RING_BUF_SIZE == s_ring_buf_head; +} + +static int bmi_ring_buf_put(struct bmi160_value_t data) +{ + if (bmi_ring_buf_full()) + return 0; + + bmi_ring_buf[s_ring_buf_tail].acc.x = data.acc.x; + bmi_ring_buf[s_ring_buf_tail].acc.y = data.acc.y; + bmi_ring_buf[s_ring_buf_tail].acc.z = data.acc.z; + bmi_ring_buf[s_ring_buf_tail].gyro.x = data.gyro.x; + bmi_ring_buf[s_ring_buf_tail].gyro.y = data.gyro.y; + bmi_ring_buf[s_ring_buf_tail].gyro.z = data.gyro.z; +#ifdef BMI160_MAG_INTERFACE_SUPPORT + bmi_ring_buf[s_ring_buf_tail].mag.x = data.mag.x; + bmi_ring_buf[s_ring_buf_tail].mag.y = data.mag.y; + bmi_ring_buf[s_ring_buf_tail].mag.z = data.mag.z; +#endif + bmi_ring_buf[s_ring_buf_tail].ts_intvl= data.ts_intvl; + s_ring_buf_tail = (s_ring_buf_tail + 1) % BMI_RING_BUF_SIZE; + + return 1; +} + +static int bmi_ring_buf_get(struct bmi160_value_t *pData) +{ + if (bmi_ring_buf_empty()) + return 0; + + pData->acc.x = bmi_ring_buf[s_ring_buf_head].acc.x; + pData->acc.y = bmi_ring_buf[s_ring_buf_head].acc.y; + pData->acc.z = bmi_ring_buf[s_ring_buf_head].acc.z; + pData->gyro.x = bmi_ring_buf[s_ring_buf_head].gyro.x; + pData->gyro.y = bmi_ring_buf[s_ring_buf_head].gyro.y; + pData->gyro.z = bmi_ring_buf[s_ring_buf_head].gyro.z; +#ifdef BMI160_MAG_INTERFACE_SUPPORT + pData->mag.x = bmi_ring_buf[s_ring_buf_head].mag.x; + pData->mag.y = bmi_ring_buf[s_ring_buf_head].mag.y; + pData->mag.z = bmi_ring_buf[s_ring_buf_head].mag.z; +#endif + pData->ts_intvl = bmi_ring_buf[s_ring_buf_head].ts_intvl; + + s_ring_buf_head = (s_ring_buf_head + 1) % BMI_RING_BUF_SIZE; + + return 1; +} + + +static int bmi_fifo_get_decode_data(struct bmi160_axis_data_t *acc, + struct bmi160_axis_data_t *gyro, + struct bmi160_axis_data_t *mag, + u8 *fifo_data, + u16 fifo_index) +{ + /* array index to get elements from fifo data*/ + u16 array_index = 0; + + /* get xyzr axis mag data */ + if (mag != NULL) + { + struct bmi160_mag_xyzr_t mag_valid; + struct bmi160_mag_xyzr_t mag_data; + struct bmi160_mag_xyz_s32_t mag_comp_xyz; + mag_data.x = fifo_data[fifo_index + 0] + | fifo_data[fifo_index + 1] << 8; + mag_data.y = fifo_data[fifo_index + 2] + | fifo_data[fifo_index + 3] << 8; + mag_data.z = fifo_data[fifo_index + 4] + | fifo_data[fifo_index + 5] << 8; + mag_data.r = fifo_data[fifo_index + 6] + | fifo_data[fifo_index + 7] << 8; + fifo_index += 8; + mag_valid.x = mag_data.x >> 3; + mag_valid.y = mag_data.y >> 3; + mag_valid.z = mag_data.z >> 1; + mag_valid.r = mag_data.r >> 2; + bmi160_bmm150_mag_compensate_xyz_raw(&mag_comp_xyz, mag_valid); + mag->x = mag_comp_xyz.x; + mag->y = mag_comp_xyz.y; + mag->z = mag_comp_xyz.z; + } + + /* get xyz axis gyro data */ + if (gyro != NULL) + { + gyro->x = fifo_data[fifo_index + 0] + | fifo_data[fifo_index + 1] << 8; + gyro->y = fifo_data[fifo_index + 2] + | fifo_data[fifo_index + 3] << 8; + gyro->z = fifo_data[fifo_index + 4] + | fifo_data[fifo_index + 5] << 8; + fifo_index += 6; + } + + /* get xyz axis accel data */ + if (acc != NULL) + { + acc->x = fifo_data[fifo_index + 0] + | fifo_data[fifo_index + 1] << 8; + acc->y = fifo_data[fifo_index + 2] + | fifo_data[fifo_index + 3] << 8; + acc->z = fifo_data[fifo_index + 4] + | fifo_data[fifo_index + 5] << 8; + fifo_index += 6; + } + + return array_index; + +} + +static int bmi_pow(int x, int y) +{ + int result = 1; + + if (y == 1) + return x; + + + if (y > 0) { + while (--y) { + result *= x; + } + } else { + result = 0; + } + + return result; +} + +/* +* Decoding of FIFO frames (only exemplary subset). Calculates accurate timestamps based on the +* drift information. Returns value of the SENSORTIME frame. +* +* fifo_data_buf - pointer to fetched FIFO buffer +* fifo_length - number of valid bytes in the FIFO buffer +* drift - clock drift value, needed to calculate accurate timestamps +* timestamp - initial timestamp for the first sample of the FIFO chunk +* acc_odr - current value of the ACC_CONF.acc_odr register field +*/ +static uint64_t bmi_fifo_data_decode(uint8_t *fifo_data_buf, uint16_t fifo_length, + int drift, uint64_t timestamp, int odr_pow) +{ + int idx = 0; + uint8_t header; + uint64_t fifo_time = 0; + uint64_t timestamp_next = timestamp; + struct bmi160_value_t bmi160_value; + + while (idx < fifo_length) { + header = fifo_data_buf[idx]; + memset(&bmi160_value, 0, sizeof (bmi160_value)); + switch (header) { + case FIFO_HEAD_SENSOR_TIME: + /* sensortime frame, length = 4 bytes*/ + if (idx + 3 < fifo_length) { + fifo_time = fifo_data_buf[idx + 1] | + fifo_data_buf[idx + 2] << 8 | + fifo_data_buf[idx + 3] << 16; + return fifo_time; + } + idx += 4; + break; + case FIFO_HEAD_A: + /* accel frame, length = 7 bytes */ + idx += 1; + if (idx + 6 < fifo_length) { + bmi_fifo_get_decode_data( + &bmi160_value.acc, + NULL, NULL, + fifo_data_buf, idx); + bmi160_value.ts_intvl = + (int64_t)(625 * odr_pow * (drift > 0 ? drift : 1000)); + if (bmi_ring_buf_put(bmi160_value) == 0) + pr_info("bmi ring buf full head %d, tail %d", + s_ring_buf_head, s_ring_buf_tail); + if (drift > 0) + timestamp_next += (uint64_t)(625 * odr_pow * drift); + else + timestamp_next += (uint64_t)(625 * odr_pow * 1000); + } + idx += 6; + break; + case FIFO_HEAD_G: + /* gyro frame, length = 7 bytes */ + idx += 1; + if (idx + 6 < fifo_length) { + bmi_fifo_get_decode_data(NULL, + &bmi160_value.gyro, + NULL, fifo_data_buf, idx); + bmi160_value.ts_intvl = + (int64_t)(625 * odr_pow * (drift > 0 ? drift : 1000)); + if (bmi_ring_buf_put(bmi160_value) == 0) + pr_info("bmi ring buf full head %d, tail %d", + s_ring_buf_head, s_ring_buf_tail); + } + + idx += 6; + break; + case FIFO_HEAD_G_A: + idx += 1; + if (idx + 12 < fifo_length) { + bmi_fifo_get_decode_data(&bmi160_value.acc, + &bmi160_value.gyro, + NULL, fifo_data_buf, idx); + bmi160_value.ts_intvl = + (int64_t)(625 * odr_pow * (drift > 0 ? drift : 1000)); + if (bmi_ring_buf_put(bmi160_value) == 0) + pr_info("bmi ring buf full head %d, tail %d", + s_ring_buf_head, s_ring_buf_tail); + } + + idx += 12; + break; +#ifdef BMI160_MAG_INTERFACE_SUPPORT + case FIFO_HEAD_M: + idx +=1; + if (idx + 8 < fifo_length) { + bmi_fifo_get_decode_data(NULL, NULL, + &bmi160_value.mag, + fifo_data_buf, idx); + bmi160_value.ts_intvl = + (int64_t)(625 * odr_pow * (drift > 0 ? drift : 1000)); + if (bmi_ring_buf_put(bmi160_value) == 0) + pr_info("bmi ring buf full head %d, tail %d", + s_ring_buf_head, s_ring_buf_tail); + } + + idx += 8; + break; + case FIFO_HEAD_M_A: + idx +=1; + if (idx + 14 < fifo_length) { + bmi_fifo_get_decode_data(&bmi160_value.acc, NULL, + &bmi160_value.mag, fifo_data_buf, idx); + bmi160_value.ts_intvl = + (int64_t)(625 * odr_pow * (drift > 0 ? drift : 1000)); + if (bmi_ring_buf_put(bmi160_value) == 0) + pr_info("bmi ring buf full head %d, tail %d", + s_ring_buf_head, s_ring_buf_tail); + } + + idx += 14; + break; + + case FIFO_HEAD_M_G: + idx +=1; + if (idx + 14 < fifo_length) { + bmi_fifo_get_decode_data(NULL, &bmi160_value.gyro, + &bmi160_value.mag, fifo_data_buf, idx); + bmi160_value.ts_intvl = + (int64_t)(625 * odr_pow * (drift > 0 ? drift : 1000)); + if (bmi_ring_buf_put(bmi160_value) == 0) + pr_info("bmi ring buf full head %d, tail %d", + s_ring_buf_head, s_ring_buf_tail); + } + + idx += 14; + break; + case FIFO_HEAD_M_G_A: + idx +=1; + if (idx + 20 < fifo_length) { + bmi_fifo_get_decode_data(&bmi160_value.acc, + &bmi160_value.gyro, + &bmi160_value.mag, fifo_data_buf, idx); + bmi160_value.ts_intvl = + (int64_t)(625 * odr_pow * (drift > 0 ? drift : 1000)); + if (bmi_ring_buf_put(bmi160_value) == 0) + pr_info("bmi ring buf full head %d, tail %d", + s_ring_buf_head, s_ring_buf_tail); + } + + idx += 20; + pr_info("second interface mag"); + break; +#endif + case FIFO_HEAD_OVER_READ_LSB: + /* end of fifo chunk */ + idx = fifo_length; + break; + default: + pr_info("ERROR parsing FIFO!! header 0x%x", header); + idx = fifo_length; + break; + } + } + + return -1; +} + +static uint64_t bmi_fifo_next_timestamp_calc(uint64_t host_time_new, + uint64_t sensor_time_new, + int drift, int odr_pow, + uint8_t bmi_odr) +{ + uint64_t time_age = ((sensor_time_new & (0xFFFF >> bmi_odr)) + * (drift > 0 ? drift : 1000)) * 390625; + return ((host_time_new - div64_u64(time_age, 10000000) + + ((drift > 0 ? drift : 1000) * (625 * odr_pow)))); +} + +static int bmi_fifo_time_drift_calc(uint64_t host_time_new, + uint64_t sensor_time_new, + uint64_t host_time_old, + uint64_t sensor_time_old) +{ + uint64_t delta_st, delta_ht; + int drift = 0; + + if (host_time_old > 0) { + delta_st = sensor_time_new >= sensor_time_old ? + (sensor_time_new - sensor_time_old) : + (sensor_time_new + FIFO_SENSORTIME_OVERFLOW_MASK - sensor_time_old); + delta_ht = host_time_new - host_time_old; + if (delta_st != 0) + drift = (int)div64_u64(delta_ht * 10000, + (delta_st * FIFO_SENSORTIME_RESOLUTION)); + else + drift = 0; + + } else { + drift = 0; + } + + return drift; +} + +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; + static int time_drift = 0; + static uint64_t timestamp_next = 0; + uint8_t bmi_odr = client_data->odr.acc_odr; + int odr_pow = bmi_pow(2, 12 - bmi_odr + 1); + /*TO DO*/ + + if (client_data->fifo_data_sel == 4) + { + bmi_odr = client_data->odr.mag_odr; + odr_pow = bmi_pow(2, 12 - bmi_odr + 1); + } + + 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) + pr_info("pw_acc: %d, pw_gyro: %d\n", + client_data->pw.acc_pm, client_data->pw.gyro_pm); + if (!client_data->fifo_data_sel) + pr_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) + { + pr_info("fifo_bytecount is 0!!"); + 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*/ + memset (s_fifo_data_buf, 0, sizeof (s_fifo_data_buf)); + if (!err) { + err = bmi_burst_read_wrapper(client_data->device.dev_addr, + BMI160_USER_FIFO_DATA__REG, s_fifo_data_buf, + client_data->fifo_bytecount + fifo_frmbytes_ext); + /* store host timestamp after reading fifo */ + host_time_new = bmi_get_alarm_timestamp_ns(); + if (timestamp_next == 0) { + sensor_time_new = bmi_fifo_data_decode(s_fifo_data_buf, + client_data->fifo_bytecount + fifo_frmbytes_ext, + time_drift, timestamp_next, odr_pow); + } else { + sensor_time_new = bmi_fifo_data_decode(s_fifo_data_buf, + client_data->fifo_bytecount + fifo_frmbytes_ext, + time_drift, host_time_new, odr_pow); + } + if (sensor_time_new >= 0) { + time_drift = bmi_fifo_time_drift_calc(host_time_new, + sensor_time_new, host_time_old, sensor_time_old); + timestamp_next = bmi_fifo_next_timestamp_calc(host_time_new, + sensor_time_new, time_drift, odr_pow, bmi_odr); + /* store current timestamps as the old ones + for next delta calculation */ + host_time_old = host_time_new; + sensor_time_old = sensor_time_new; + } + } else { + dev_err(client_data->dev, "read fifo leght err"); + } + + if (err) + dev_err(client_data->dev, "brust read fifo err\n"); + +} + +static void bmi_signification_motion_interrupt_handle( + struct bmi_client_data *client_data) +{ + pr_info("bmi_signification_motion_interrupt_handle\n"); + input_event(client_data->input_accel, EV_MSC, INPUT_EVENT_SGM, 1); + input_sync(client_data->input_accel); + input_event(client_data->input_gyro, EV_MSC, INPUT_EVENT_SGM, 1); + input_sync(client_data->input_gyro); + 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); +} + +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}; + + 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_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); + + /* 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 irqreturn_t bmi_irq_handler(int irq, void *handle) +{ + struct bmi_client_data *client_data = handle; + + if (client_data == NULL) + return IRQ_HANDLED; + if (client_data->dev == NULL) + return IRQ_HANDLED; + 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]); + mdelay(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]); + mdelay(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 + mdelay(3); + } + mutex_unlock(&client->mutex_op_mode); + + return err; +} + +static void bmi160_set_acc_enable(struct device *dev, unsigned int enable) +{ + struct i2c_client *client = to_i2c_client(dev); + struct bmi_client_data *client_data = i2c_get_clientdata(client); + int acc_pre_enable = atomic_read(&client_data->wkqueue_en); + int gyro_current_enable; + + mutex_lock(&client_data->mutex_enable); + if (enable) { + if (acc_pre_enable == 0) { + if (!client_data->power_enabled) { + if (bmi160_power_ctl(client_data, true)) { + dev_err(dev, "power up sensor failed.\n"); + goto mutex_exit; + } + } + + 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 ((acc_pre_enable == 1) && client_data->power_enabled) { + 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); + gyro_current_enable = atomic_read(&client_data->gyro_en); + if (!gyro_current_enable) { + if (bmi160_power_ctl(client_data, false)) { + dev_err(dev, "power up sensor failed.\n"); + goto mutex_exit; + } + } + } + } + +mutex_exit: + mutex_unlock(&client_data->mutex_enable); + dev_notice(dev, + "acc_enable en_state=%d\n", + atomic_read(&client_data->wkqueue_en)); +} + + +static void bmi160_set_gyro_enable(struct device *dev, unsigned int enable) +{ + struct i2c_client *client = to_i2c_client(dev); + struct bmi_client_data *client_data = i2c_get_clientdata(client); + int gyro_pre_enable = atomic_read(&client_data->gyro_en); + int acc_current_enable; + + mutex_lock(&client_data->mutex_enable); + if (enable) { + if (gyro_pre_enable == 0) { + if (!client_data->power_enabled) { + if (bmi160_power_ctl(client_data, true)) { + dev_err(dev, "power up sensor failed.\n"); + goto mutex_exit; + } + } + bmi160_set_gyro_op_mode(client_data, BMI_GYRO_PM_NORMAL); + schedule_delayed_work(&client_data->gyro_work, + msecs_to_jiffies(atomic_read(&client_data->delay))); + atomic_set(&client_data->gyro_en, 1); + } + } else { + if ((gyro_pre_enable == 1) && client_data->power_enabled) { + bmi160_set_gyro_op_mode(client_data, BMI_GYRO_PM_SUSPEND); + cancel_delayed_work_sync(&client_data->gyro_work); + atomic_set(&client_data->gyro_en, 0); + acc_current_enable = atomic_read(&client_data->wkqueue_en); + if (!acc_current_enable) { + if (bmi160_power_ctl(client_data, false)) { + dev_err(dev, "power up sensor failed.\n"); + goto mutex_exit; + } + } + } + } + +mutex_exit: + mutex_unlock(&client_data->mutex_enable); + dev_notice(&client->dev, "gyro_enable en_state=%d\n", + atomic_read(&client_data->gyro_en)); +} + + +static int bmi160_self_calibration_xyz(struct sensors_classdev *sensors_cdev, + int axis, int apply_now) +{ + int err = 0; + s8 accel_offset_x = 0; + s8 accel_offset_y = 0; + s8 accel_offset_z = 0; + + struct bmi_client_data *client_data = container_of(sensors_cdev, + struct bmi_client_data, accel_cdev); + + err = BMI_CALL_API(set_accel_foc_trigger)(X_AXIS, + 1, &accel_offset_x); + if (!err) + client_data->calib_status |= + BMI_FAST_CALI_TRUE << BMI_ACC_X_FAST_CALI_RDY; + else + return -EIO; + + err = BMI_CALL_API(set_accel_foc_trigger)(Y_AXIS, + 1, &accel_offset_y); + if (!err) + client_data->calib_status |= + BMI_FAST_CALI_TRUE << BMI_ACC_Y_FAST_CALI_RDY; + else + return -EIO; + + err = BMI_CALL_API(set_accel_foc_trigger)(Z_AXIS, + 1, &accel_offset_z); + if (!err) + client_data->calib_status |= + BMI_FAST_CALI_TRUE << BMI_ACC_Z_FAST_CALI_RDY; + else + return -EIO; + + return 0; +} + +static int bmi160_accel_poll_delay(struct sensors_classdev *sensors_cdev, + unsigned int delay_ms) +{ + struct bmi_client_data *data = container_of(sensors_cdev, + struct bmi_client_data, accel_cdev); + + if (delay_ms < 10) + delay_ms = 10; + if (delay_ms > 10) + delay_ms = 10; + atomic_set(&data->delay, (unsigned int) delay_ms); + return 0; +} + +static int bmi160_cdev_enable_accel(struct sensors_classdev *sensors_cdev, + unsigned int enable) +{ + struct bmi_client_data *client_data = container_of(sensors_cdev, + struct bmi_client_data, accel_cdev); + bmi160_set_acc_enable(&client_data->i2c->dev, enable); + return 0; +} + +static int bmi160_gyro_poll_delay(struct sensors_classdev *sensors_cdev, + unsigned int delay_ms) +{ + struct bmi_client_data *data = container_of(sensors_cdev, + struct bmi_client_data, gyro_cdev); + + if (delay_ms < 10) + delay_ms = 10; + if (delay_ms > 10) + delay_ms = 10; + atomic_set(&data->delay, (unsigned int) delay_ms); + return 0; +} + + +static int bmi160_cdev_enable_gyro(struct sensors_classdev *sensors_cdev, + unsigned int enable) +{ + struct bmi_client_data *client_data = container_of(sensors_cdev, + struct bmi_client_data, gyro_cdev); + bmi160_set_gyro_enable(&client_data->i2c->dev, enable); + return 0; +} + + +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 + err = bmi160_power_init(client_data); + if (err) { + dev_err(&client_data->i2c->dev, + "Failed to get sensor regulators\n"); + err = -EINVAL; + goto exit_err_clean; + } + err = bmi160_power_ctl(client_data, true); + if (err) { + dev_err(&client_data->i2c->dev, + "Failed to enable sensor power\n"); + err = -EINVAL; + goto deinit_power_exit; + } + + /* check chip id */ + err = bmi_check_chip_id(client_data); + if (err) + goto disable_power_exit; + + dev_set_drvdata(dev, client_data); + client_data->dev = dev; + + mutex_init(&client_data->mutex_enable); + mutex_init(&client_data->mutex_op_mode); + mutex_init(&client_data->mutex_ring_buf); + + /* input device init */ + err = bmi_input_init(client_data); + if (err < 0) + goto disable_power_exit; + + /* sysfs node creation */ + err = sysfs_create_group(&client_data->i2c->dev.kobj, + &bmi160_attribute_group); + + if (err < 0) + goto exit_err_sysfs; + + /*to do*/ + client_data->accel_cdev = accel_cdev; + client_data->accel_cdev.sensors_enable = bmi160_cdev_enable_accel; + client_data->accel_cdev.sensors_poll_delay = bmi160_accel_poll_delay; + client_data->accel_cdev.sensors_calibrate = bmi160_self_calibration_xyz; + err = sensors_classdev_register(&client_data->input_accel->dev, + &client_data->accel_cdev); + if (err) { + dev_err(&client_data->i2c->dev, "sensors class register failed.\n"); + return err; + } + + client_data->gyro_cdev = gyro_cdev; + client_data->gyro_cdev.sensors_enable = bmi160_cdev_enable_gyro; + client_data->gyro_cdev.sensors_poll_delay = bmi160_gyro_poll_delay; + err = sensors_classdev_register(&client_data->input_gyro->dev, + &client_data->gyro_cdev); + if (err) { + dev_err(&client_data->i2c->dev, "sensors class register failed.\n"); + return err; + } + + 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); + INIT_DELAYED_WORK(&client_data->gyro_work, bmi_gyro_work_func); + atomic_set(&client_data->delay, BMI_DELAY_DEFAULT); + atomic_set(&client_data->wkqueue_en, 0); + atomic_set(&client_data->gyro_en, 0); + + /* h/w init */ + client_data->device.delay_msec = bmi_delay; + err = BMI_CALL_API(init)(&client_data->device); + + /*workqueue init*/ + INIT_WORK(&client_data->report_data_work, bmi_hrtimer_work_func); + reportdata_wq = create_singlethread_workqueue("bmi160_wq"); + if (NULL == reportdata_wq) { + pr_info("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; /*200Hz*/ + + 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); + mdelay(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); + mdelay(2); + err += bmi160_get_mag_power_mode_stat(&mag_op_mode); + mdelay(2); + err += BMI_CALL_API(get_i2c_device_addr)(&mag_dev_addr); + mdelay(2); +#ifdef BMI160_AKM09912_SUPPORT + err += BMI_CALL_API(set_i2c_device_addr)(BMI160_AKM09912_I2C_ADDRESS); + /*do not need to check the return value for mag 2nd interface*/ + bmi160_bst_akm_mag_interface_init(BMI160_AKM09912_I2C_ADDRESS); +#else + err += BMI_CALL_API(set_i2c_device_addr)(BMI160_AUX_BMM150_I2C_ADDRESS); + /*do not need to check the return value for mag 2nd interface*/ + bmi160_bmm150_mag_interface_init(); +#endif + err += bmi160_set_mag_burst(3); + err += bmi160_get_mag_burst(&mag_urst_len); + 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; + +#ifdef BMI160_ENABLE_INT1 + client_data->gpio_pin = of_get_named_gpio_flags(dev->of_node, + "bosch,gpio-int1", 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; + } + /* 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_int_drdy)(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 + client_data->gpio_pin = of_get_named_gpio_flags(dev->of_node, + "bosch,gpio-int2", 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; + } + /* 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_int_drdy)(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); + + client_data->selftest = 0; + + client_data->fifo_data_sel = 0; + 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 */ + + /* 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; + } + + bmi160_power_ctl(client_data, false); + + dev_notice(dev, "sensor_time:%d, %d", + sensortime_duration_tbl[0].ts_delat, + sensortime_duration_tbl[0].ts_duration_lsb); + dev_notice(dev, "sensor %s probed successfully", SENSOR_NAME); + + return 0; + +exit_err_sysfs: + if (err) + bmi_input_destroy(client_data); +disable_power_exit: + bmi160_power_ctl(client_data, false); +deinit_power_exit: + bmi160_power_deinit(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); + + mdelay(5); + + sysfs_remove_group(&client_data->i2c->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); + 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; + } + + 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"); + + 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; + } + + 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]); + /*client_data->pw.acc_pm = BMI_ACC_PM_SUSPEND;*/ + mdelay(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]); + /*client_data->pw.gyro_pm = BMI_GYRO_PM_SUSPEND;*/ + mdelay(3); + } + + if (client_data->pw.mag_pm != BMI_MAG_PM_SUSPEND) { +#ifdef 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.gyro_pm = BMI160_MAG_SUSPEND_MODE;*/ + mdelay(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); + 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]); + mdelay(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]); + mdelay(3); + } + + if (client_data->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 + mdelay(3); + } + /* post resume operation */ + err += bmi_post_resume(client_data); + + return err; +} +EXPORT_SYMBOL(bmi_resume); + diff --git a/drivers/input/misc/bmi160_driver.h b/drivers/input/misc/bmi160_driver.h new file mode 100644 index 0000000000000..70a432a5e170f --- /dev/null +++ b/drivers/input/misc/bmi160_driver.h @@ -0,0 +1,401 @@ +/*! + * @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 "09afbe6" + * @version 1.4 + * + * @brief + * The head file of BMI160 device driver core code +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif + +#include "bmi160.h" + +/* sensor specific */ +#define SENSOR_NAME "bmi160" +#define BMI160_ACCEL_INPUT_NAME "bmi160-accel" +#define BMI160_GYRO_INPUT_NAME "bmi160-gyro" +#define ABSMIN -512 +#define ABSMAX 512 +#define GYRO_MIN_VALUE -32768 +#define GYRO_MAX_VALUE 32767 + +#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 (100) +#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 20 +#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 regulator_map { + struct regulator *regulator; + int min_uv; + int max_uv; + char *supply; +}; + +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 REL_DIAL/*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 i2c_client *i2c; + struct device *dev; + struct input_dev *input_accel; + struct input_dev *input_gyro; + struct sensors_classdev accel_cdev; + struct sensors_classdev gyro_cdev; + struct regulator *vdd; + struct regulator *vio; + struct delayed_work work; + struct delayed_work gyro_work; + struct work_struct irq_work; + + struct work_struct report_data_work; + int is_timer_running; + struct hrtimer timer; + ktime_t work_delay_kt; + uint64_t timestamp; + uint64_t base_time; + uint64_t fifo_time; + uint64_t gyro_count; + uint64_t time_odr; + + 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; + + atomic_t wkqueue_en; /*TO DO acc gyro mag*/ + atomic_t gyro_en; + 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; + 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 mutex mutex_ring_buf; + struct bosch_sensor_specific *bst_pd; + bool power_enabled; + int IRQ; +#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); + + diff --git a/drivers/input/misc/bmi160_i2c.c b/drivers/input/misc/bmi160_i2c.c new file mode 100644 index 0000000000000..64648529ce5d8 --- /dev/null +++ b/drivers/input/misc/bmi160_i2c.c @@ -0,0 +1,366 @@ +/*! + * @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 "ba266c5" + * @version 1.3 + * + * @brief + * This file implements moudle function, which add + * the driver to I2C core. +*/ + +#include +#include +#include +#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 + mdelay(BMI_I2C_WRITE_DELAY_TIME); + } + + 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 + mdelay(BMI_I2C_WRITE_DELAY_TIME); + } + + 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; + } + + } + mdelay(2); + 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 { + mdelay(BMI_I2C_WRITE_DELAY_TIME); + } + } + if (BMI_MAX_RETRY_I2C_XFER <= retry) { + dev_err(&client->dev, "I2C xfer error"); + return -EIO; + } + reg_addr++; + data++; + } + + mdelay(2); + 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->i2c = client; + 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; + + /* post resume operation */ + 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 "); +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/misc/mmc3x30.c b/drivers/input/misc/mmc3x30.c new file mode 100644 index 0000000000000..08364d6ea0099 --- /dev/null +++ b/drivers/input/misc/mmc3x30.c @@ -0,0 +1,1269 @@ +/* + * Copyright (c) 2014, 2016 Linux Foundation. All rights reserved. + * Linux Foundation chooses to take subject only to the GPLv2 license + * terms, and distributes only under these terms. + * Copyright (C) 2010 MEMSIC, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define MMC3X30_DELAY_TM_MS 10 + +#define MMC3X30_DELAY_SET_MS 75 +#define MMC3X30_DELAY_RESET_MS 75 + +#define MMC3X30_RETRY_COUNT 10 +#define MMC3X30_DEFAULT_INTERVAL_MS 100 +#define MMC3X30_TIMEOUT_SET_MS 15000 + +#define MMC3X30_PRODUCT_ID 0x09 + +/* POWER SUPPLY VOLTAGE RANGE */ +#define MMC3X30_VDD_MIN_UV 2000000 +#define MMC3X30_VDD_MAX_UV 3300000 +#define MMC3X30_VIO_MIN_UV 1750000 +#define MMC3X30_VIO_MAX_UV 1950000 + +enum { + OBVERSE_X_AXIS_FORWARD = 0, + OBVERSE_X_AXIS_RIGHTWARD, + OBVERSE_X_AXIS_BACKWARD, + OBVERSE_X_AXIS_LEFTWARD, + REVERSE_X_AXIS_FORWARD, + REVERSE_X_AXIS_RIGHTWARD, + REVERSE_X_AXIS_BACKWARD, + REVERSE_X_AXIS_LEFTWARD, + MMC3X30_DIR_COUNT, +}; + +static char *mmc3x30_dir[MMC3X30_DIR_COUNT] = { + [OBVERSE_X_AXIS_FORWARD] = "obverse-x-axis-forward", + [OBVERSE_X_AXIS_RIGHTWARD] = "obverse-x-axis-rightward", + [OBVERSE_X_AXIS_BACKWARD] = "obverse-x-axis-backward", + [OBVERSE_X_AXIS_LEFTWARD] = "obverse-x-axis-leftward", + [REVERSE_X_AXIS_FORWARD] = "reverse-x-axis-forward", + [REVERSE_X_AXIS_RIGHTWARD] = "reverse-x-axis-rightward", + [REVERSE_X_AXIS_BACKWARD] = "reverse-x-axis-backward", + [REVERSE_X_AXIS_LEFTWARD] = "reverse-x-axis-leftward", +}; + +static s8 mmc3x30_rotation_matrix[MMC3X30_DIR_COUNT][9] = { + [OBVERSE_X_AXIS_FORWARD] = {0, -1, 0, 1, 0, 0, 0, 0, 1}, + [OBVERSE_X_AXIS_RIGHTWARD] = {1, 0, 0, 0, 1, 0, 0, 0, 1}, + [OBVERSE_X_AXIS_BACKWARD] = {0, 1, 0, -1, 0, 0, 0, 0, 1}, + [OBVERSE_X_AXIS_LEFTWARD] = {-1, 0, 0, 0, -1, 0, 0, 0, 1}, + [REVERSE_X_AXIS_FORWARD] = {0, 1, 0, 1, 0, 0, 0, 0, -1}, + [REVERSE_X_AXIS_RIGHTWARD] = {1, 0, 0, 0, -1, 0, 0, 0, -1}, + [REVERSE_X_AXIS_BACKWARD] = {0, -1, 0, -1, 0, 0, 0, 0, -1}, + [REVERSE_X_AXIS_LEFTWARD] = {-1, 0, 0, 0, 1, 0, 0, 0, -1}, +}; + +struct mmc3x30_vec { + int x; + int y; + int z; +}; + +struct mmc3x30_data { + struct mutex ecompass_lock; + struct mutex ops_lock; + struct delayed_work dwork; + struct sensors_classdev cdev; + struct mmc3x30_vec last; + + struct i2c_client *i2c; + struct input_dev *idev; + struct regulator *vdd; + struct regulator *vio; + struct regmap *regmap; + + int dir; + int auto_report; + int enable; + int poll_interval; + int power_enabled; + unsigned long timeout; + unsigned int device_id; +}; + +static struct sensors_classdev sensors_cdev = { + .name = "mmc3x30-mag", + .vendor = "MEMSIC, Inc", + .version = 1, + .handle = SENSORS_MAGNETIC_FIELD_HANDLE, + .type = SENSOR_TYPE_MAGNETIC_FIELD, + .max_range = "1228.8", + .resolution = "0.09765625", /* 1024 */ + .sensor_power = "0.35", + .min_delay = 20000, + .max_delay = 100000, /* 100ms */ + .fifo_reserved_event_count = 0, + .fifo_max_event_count = 0, + .enabled = 0, + .delay_msec = MMC3X30_DEFAULT_INTERVAL_MS, + .sensors_enable = NULL, + .sensors_poll_delay = NULL, +}; + +static struct mmc3x30_data *mmc3x30_data_struct; + +static int mmc3x30_read_xyz(struct mmc3x30_data *memsic, + struct mmc3x30_vec *vec) +{ + //int count = 0; + unsigned char data[6]; + //unsigned int status; + struct mmc3x30_vec tmp; + int rc = 0; + + mutex_lock(&memsic->ecompass_lock); +#if 0 + /* mmc3x30 need to be set periodly to avoid overflow */ + if (time_after(jiffies, memsic->timeout)) { + + if (memsic->device_id == MMC3524_DEVICE_ID || memsic->device_id == MMC3530_DEVICE_ID) + { + rc = regmap_write(memsic->regmap, MMC35XX_REG_CTRL0, MMC35XX_SET); + if (rc) { + dev_err(&memsic->i2c->dev, "write reg %d failed at %d.(%d)\n", + MMC35XX_REG_CTRL0, __LINE__, rc); + goto exit; + } + + /* Wait time to complete SET/RESET */ + usleep_range(1000, 1500); + memsic->timeout = jiffies + msecs_to_jiffies(MMC3X30_TIMEOUT_SET_MS); + + dev_dbg(&memsic->i2c->dev, "mmc3x30 reset is done\n"); + + } else if (memsic->device_id == MMC3630_DEVICE_ID) + { + rc = regmap_write(memsic->regmap, MMC36XX_REG_CTRL0, MMC36XX_SET); + if (rc) { + dev_err(&memsic->i2c->dev, "write reg %d failed at %d.(%d)\n", + MMC36XX_REG_CTRL0, __LINE__, rc); + goto exit; + } + + /* Wait time to complete SET/RESET */ + usleep_range(1000, 1500); + memsic->timeout = jiffies + msecs_to_jiffies(MMC3X30_TIMEOUT_SET_MS); + + dev_dbg(&memsic->i2c->dev, "mmc3x30 reset is done\n"); + } + + } +#endif + /* read xyz raw data */ + rc = regmap_bulk_read(memsic->regmap, MMC3X30_REG_DATA, data, 6); + if (rc) { + dev_err(&memsic->i2c->dev, "read reg %d failed at %d.(%d)\n", + MMC3X30_REG_DATA, __LINE__, rc); + goto exit; + } + + + tmp.x = (((u8)data[1]) << 8 | (u8)data[0]) - 32768; + tmp.y = (((u8)data[3]) << 8 | (u8)data[2]) - (((u8)data[5]) << 8 | (u8)data[4]) ; + tmp.z = (((u8)data[3]) << 8 | (u8)data[2]) + (((u8)data[5]) << 8 | (u8)data[4]) - 32768 - 32768; + + vec->x = tmp.x; + vec->y = tmp.y; + vec->z = -tmp.z; + +exit: + /* send TM cmd before read */ + if (memsic->device_id == MMC3524_DEVICE_ID || memsic->device_id == MMC3530_DEVICE_ID) + { + if (regmap_write(memsic->regmap, MMC35XX_REG_CTRL0, MMC35XX_SINGLE_TM)) { + + dev_warn(&memsic->i2c->dev, "write reg %d failed at %d.(%d)\n", + MMC35XX_REG_CTRL0, __LINE__, rc); + } + + } else if (memsic->device_id == MMC3630_DEVICE_ID) { + if (regmap_write(memsic->regmap, MMC36XX_REG_CTRL0, MMC36XX_SINGLE_TM)) { + + dev_warn(&memsic->i2c->dev, "write reg %d failed at %d.(%d)\n", + MMC36XX_REG_CTRL0, __LINE__, rc); + } + + } + + mutex_unlock(&memsic->ecompass_lock); + return rc; +} + +static void mmc3x30_poll(struct work_struct *work) +{ + int ret; + s8 *tmp; + struct mmc3x30_vec vec; + struct mmc3x30_vec report; + struct mmc3x30_data *memsic = container_of((struct delayed_work *)work, + struct mmc3x30_data, dwork); + + vec.x = vec.y = vec.z = 0; + + ret = mmc3x30_read_xyz(memsic, &vec); + if (ret) { + dev_warn(&memsic->i2c->dev, "read xyz failed\n"); + goto exit; + } + + tmp = &mmc3x30_rotation_matrix[memsic->dir][0]; + report.x = tmp[0] * vec.x + tmp[1] * vec.y + tmp[2] * vec.z; + report.y = tmp[3] * vec.x + tmp[4] * vec.y + tmp[5] * vec.z; + report.z = tmp[6] * vec.x + tmp[7] * vec.y + tmp[8] * vec.z; + + input_report_abs(memsic->idev, ABS_X, report.x); + input_report_abs(memsic->idev, ABS_Y, report.y); + input_report_abs(memsic->idev, ABS_Z, report.z); + input_sync(memsic->idev); + +exit: + schedule_delayed_work(&memsic->dwork, + msecs_to_jiffies(memsic->poll_interval)); +} + +static struct input_dev *mmc3x30_init_input(struct i2c_client *client) +{ + int status; + struct input_dev *input = NULL; + + input = devm_input_allocate_device(&client->dev); + if (!input) + return NULL; + + input->name = "compass"; + input->phys = "mmc3x30/input0"; + input->id.bustype = BUS_I2C; + + __set_bit(EV_ABS, input->evbit); + + input_set_abs_params(input, ABS_X, -1024*30, 1024*30, 0, 0); + input_set_abs_params(input, ABS_Y, -1024*30, 1024*30, 0, 0); + input_set_abs_params(input, ABS_Z, -1024*30, 1024*30, 0, 0); + + //input_set_capability(input, EV_ABS, ABS_X); + //input_set_capability(input, EV_ABS, ABS_Y); + //input_set_capability(input, EV_ABS, ABS_Z); + + status = input_register_device(input); + if (status) { + dev_err(&client->dev, + "error registering input device\n"); + return NULL; + } + + return input; +} + +static int mmc3x30_power_init(struct mmc3x30_data *data) +{ + int rc; + + data->vdd = devm_regulator_get(&data->i2c->dev, "vdd"); + if (IS_ERR(data->vdd)) { + rc = PTR_ERR(data->vdd); + dev_err(&data->i2c->dev, + "Regualtor get failed vdd rc=%d\n", rc); + return rc; + } + if (regulator_count_voltages(data->vdd) > 0) { + rc = regulator_set_voltage(data->vdd, + MMC3X30_VDD_MIN_UV, MMC3X30_VDD_MAX_UV); + if (rc) { + dev_err(&data->i2c->dev, + "Regulator set failed vdd rc=%d\n", + rc); + goto exit; + } + } + + rc = regulator_enable(data->vdd); + if (rc) { + dev_err(&data->i2c->dev, + "Regulator enable vdd failed rc=%d\n", rc); + goto exit; + } + data->vio = devm_regulator_get(&data->i2c->dev, "vio"); + if (IS_ERR(data->vio)) { + rc = PTR_ERR(data->vio); + dev_err(&data->i2c->dev, + "Regulator get failed vio rc=%d\n", rc); + goto reg_vdd_set; + } + + if (regulator_count_voltages(data->vio) > 0) { + rc = regulator_set_voltage(data->vio, + MMC3X30_VIO_MIN_UV, MMC3X30_VIO_MAX_UV); + if (rc) { + dev_err(&data->i2c->dev, + "Regulator set failed vio rc=%d\n", rc); + goto reg_vdd_set; + } + } + rc = regulator_enable(data->vio); + if (rc) { + dev_err(&data->i2c->dev, + "Regulator enable vio failed rc=%d\n", rc); + goto reg_vdd_set; + } + + /* The minimum time to operate device after VDD valid is 10 ms. */ + usleep_range(15000, 20000); + + data->power_enabled = true; + + return 0; + +reg_vdd_set: + regulator_disable(data->vdd); + if (regulator_count_voltages(data->vdd) > 0) + regulator_set_voltage(data->vdd, 0, MMC3X30_VDD_MAX_UV); +exit: + return rc; + +} + +static int mmc3x30_power_deinit(struct mmc3x30_data *data) +{ + if (!IS_ERR_OR_NULL(data->vio)) { + if (regulator_count_voltages(data->vio) > 0) + regulator_set_voltage(data->vio, 0, + MMC3X30_VIO_MAX_UV); + + regulator_disable(data->vio); + } + + if (!IS_ERR_OR_NULL(data->vdd)) { + if (regulator_count_voltages(data->vdd) > 0) + regulator_set_voltage(data->vdd, 0, + MMC3X30_VDD_MAX_UV); + + regulator_disable(data->vdd); + } + + data->power_enabled = false; + + return 0; +} + +static int mmc3x30_power_set(struct mmc3x30_data *memsic, bool on) +{ + int rc = 0; + + if (!on && memsic->power_enabled) { + mutex_lock(&memsic->ecompass_lock); + + rc = regulator_disable(memsic->vdd); + if (rc) { + dev_err(&memsic->i2c->dev, + "Regulator vdd disable failed rc=%d\n", rc); + goto err_vdd_disable; + } + + rc = regulator_disable(memsic->vio); + if (rc) { + dev_err(&memsic->i2c->dev, + "Regulator vio disable failed rc=%d\n", rc); + goto err_vio_disable; + } + memsic->power_enabled = false; + + mutex_unlock(&memsic->ecompass_lock); + return rc; + } else if (on && !memsic->power_enabled) { + mutex_lock(&memsic->ecompass_lock); + + rc = regulator_enable(memsic->vdd); + if (rc) { + dev_err(&memsic->i2c->dev, + "Regulator vdd enable failed rc=%d\n", rc); + goto err_vdd_enable; + } + + rc = regulator_enable(memsic->vio); + if (rc) { + dev_err(&memsic->i2c->dev, + "Regulator vio enable failed rc=%d\n", rc); + goto err_vio_enable; + } + memsic->power_enabled = true; + + mutex_unlock(&memsic->ecompass_lock); + + /* The minimum time to operate after VDD valid is 10 ms */ + usleep_range(15000, 20000); + + return rc; + } else { + dev_warn(&memsic->i2c->dev, + "Power on=%d. enabled=%d\n", + on, memsic->power_enabled); + return rc; + } + +err_vio_enable: + regulator_disable(memsic->vio); +err_vdd_enable: + mutex_unlock(&memsic->ecompass_lock); + return rc; + +err_vio_disable: + if (regulator_enable(memsic->vdd)) + dev_warn(&memsic->i2c->dev, "Regulator vdd enable failed\n"); +err_vdd_disable: + mutex_unlock(&memsic->ecompass_lock); + return rc; +} +static int mmc3x30_check_device(struct mmc3x30_data *memsic) +{ + unsigned int id[2] = {0, 0}; + unsigned int reg[2] = {MMC35XX_REG_ID, MMC36XX_REG_ID}; + int rc[2]; + int i; + + for (i = 0; i < 2; i++) + rc[i] = regmap_read(memsic->regmap, reg[i], &id[i]); + /* two id in the arrow */ + if (id[1] == MMC3630_DEVICE_ID) + memsic->device_id = MMC3630_DEVICE_ID; + else if (id[0] == MMC3530_DEVICE_ID) + memsic->device_id = MMC3530_DEVICE_ID; + else if (id[0] == MMC3524_DEVICE_ID) + memsic->device_id = MMC3524_DEVICE_ID; + else + return -ENODEV; + + return 0; +} + +static int mmc3x30_parse_dt(struct i2c_client *client, + struct mmc3x30_data *memsic) +{ + struct device_node *np = client->dev.of_node; + const char *tmp; + int rc; + int i; + + rc = of_property_read_string(np, "memsic,dir", &tmp); + + /* does not have a value or the string is not null-terminated */ + if (rc && (rc != -EINVAL)) { + dev_err(&client->dev, "Unable to read memsic,dir\n"); + return rc; + } + + for (i = 0; i < ARRAY_SIZE(mmc3x30_dir); i++) { + if (strcmp(mmc3x30_dir[i], tmp) == 0) + break; + } + + if (i >= ARRAY_SIZE(mmc3x30_dir)) { + dev_err(&client->dev, "Invalid memsic,dir property"); + return -EINVAL; + } + + /*PLEASE CONFIRM WITH SENSOR PROVIDER*/ + memsic->dir = 1; + + if (of_property_read_bool(np, "memsic,auto-report")) + memsic->auto_report = 1; + else + memsic->auto_report = 0; + + return 0; +} + +static int mmc3x30_set_enable(struct sensors_classdev *sensors_cdev, + unsigned int enable) +{ + int rc = 0; + struct mmc3x30_data *memsic = container_of(sensors_cdev, + struct mmc3x30_data, cdev); + + mutex_lock(&memsic->ops_lock); + + if (enable && (!memsic->enable)) { + rc = mmc3x30_power_set(memsic, true); + if (rc) { + dev_err(&memsic->i2c->dev, "Power up failed\n"); + goto exit; + } + + /* send TM cmd before read */ + if (memsic->device_id == MMC3524_DEVICE_ID || memsic->device_id == MMC3530_DEVICE_ID) + { + rc = regmap_write(memsic->regmap, MMC35XX_REG_CTRL0, + MMC35XX_SINGLE_TM); + if (rc) { + dev_err(&memsic->i2c->dev, "write reg %d failed.(%d)\n", + MMC35XX_REG_CTRL0, rc); + goto exit; + } + } else if (memsic->device_id == MMC3630_DEVICE_ID) { + rc = regmap_write(memsic->regmap, MMC36XX_REG_CTRL0, + MMC36XX_SINGLE_TM); + if (rc) { + dev_err(&memsic->i2c->dev, "write reg %d failed.(%d)\n", + MMC36XX_REG_CTRL0, rc); + goto exit; + } + } + memsic->timeout = jiffies; + if (memsic->auto_report) + schedule_delayed_work(&memsic->dwork, + msecs_to_jiffies(memsic->poll_interval)); + } else if ((!enable) && memsic->enable) { + if (memsic->auto_report) + cancel_delayed_work_sync(&memsic->dwork); + + if (mmc3x30_power_set(memsic, false)) + dev_warn(&memsic->i2c->dev, "Power off failed\n"); + } else { + dev_warn(&memsic->i2c->dev, + "ignore enable state change from %d to %d\n", + memsic->enable, enable); + } + memsic->enable = enable; + +exit: + mutex_unlock(&memsic->ops_lock); + return rc; +} + +static int mmc3x30_set_poll_delay(struct sensors_classdev *sensors_cdev, + unsigned int delay_msec) +{ + struct mmc3x30_data *memsic = container_of(sensors_cdev, + struct mmc3x30_data, cdev); + + mutex_lock(&memsic->ops_lock); + if (memsic->poll_interval != delay_msec) + memsic->poll_interval = delay_msec; + + if (memsic->auto_report) + mod_delayed_work(system_wq, &memsic->dwork, + msecs_to_jiffies(delay_msec)); + mutex_unlock(&memsic->ops_lock); + + return 0; +} + +static struct regmap_config mmc3x30_regmap_config = { + .reg_bits = 8, + .val_bits = 8, +}; +#ifdef INIT_SET +static int mmc3x30_device_initial(struct mmc3x30_data *memsic) +{ + int rc = -1; + + // Do SET operation + if (memsic->device_id == MMC3524_DEVICE_ID || memsic->device_id == MMC3530_DEVICE_ID) + { + rc = regmap_write(mmc3x30_data_struct->regmap, MMC35XX_REG_CTRL0, + MMC35XX_SET); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, "write reg %d failed at %d.(%d)\n", + MMC35XX_REG_CTRL0, __LINE__, rc); + + return -EFAULT; + } + + } else if (memsic->device_id == MMC3630_DEVICE_ID) { + rc = regmap_write(mmc3x30_data_struct->regmap, MMC36XX_REG_CTRL0, + MMC36XX_SET); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, "write reg %d failed at %d.(%d)\n", + MMC36XX_REG_CTRL0, __LINE__, rc); + + return -EFAULT; + } + } + + msleep(20);/* setting need 20ms */ + + return 0; +} +#endif +static int mmc3x30_open(struct inode *inode, struct file *file) +{ + + return nonseekable_open(inode, file); +} + +static int mmc3x30_release(struct inode *inode, struct file *file) +{ + + return 0; +} + +static long mmc3x30_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + void __user *pa = (void __user *)arg; + unsigned char data[16] = {0}; + unsigned char reg_addr; + unsigned char reg_num; + unsigned int reg_value; + int rc = -1; + + switch (cmd) { + case MMC3X30_IOC_SET: + if (mmc3x30_data_struct->device_id == MMC3524_DEVICE_ID || mmc3x30_data_struct->device_id == MMC3530_DEVICE_ID) + { + rc = regmap_write(mmc3x30_data_struct->regmap, MMC35XX_REG_CTRL0, + MMC35XX_SET); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, "write reg %d failed at %d.(%d)\n", + MMC35XX_REG_CTRL0, __LINE__, rc); + return -EFAULT; + } + + } else if (mmc3x30_data_struct->device_id == MMC3630_DEVICE_ID) { + rc = regmap_write(mmc3x30_data_struct->regmap, MMC36XX_REG_CTRL0, + MMC36XX_SET); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, "write reg %d failed at %d.(%d)\n", + MMC36XX_REG_CTRL0, __LINE__, rc); + return -EFAULT; + } + + } + msleep(20);/* setting need 20ms */ + break; + + case MMC3X30_IOC_RESET: + if (mmc3x30_data_struct->device_id == MMC3524_DEVICE_ID || mmc3x30_data_struct->device_id == MMC3530_DEVICE_ID) + { + rc = regmap_write(mmc3x30_data_struct->regmap, MMC35XX_REG_CTRL0, + MMC35XX_RESET); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, "write reg %d failed at %d.(%d)\n", + MMC35XX_REG_CTRL0, __LINE__, rc); + return -EFAULT; + } + + } else if (mmc3x30_data_struct->device_id == MMC3630_DEVICE_ID) { + rc = regmap_write(mmc3x30_data_struct->regmap, MMC36XX_REG_CTRL0, + MMC36XX_RESET); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, "write reg %d failed at %d.(%d)\n", + MMC36XX_REG_CTRL0, __LINE__, rc); + return -EFAULT; + } + + } + msleep(20);/* setting need 20ms */ + break; + + case MMC3X30_IOC_READ_REG: + if (copy_from_user(®_addr, pa, sizeof(reg_addr))) + return -EFAULT; + rc = regmap_read(mmc3x30_data_struct->regmap, reg_addr, ®_value); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, + "read reg %d failed at %d.(%d)\n", + reg_addr, __LINE__, rc); + } + pr_info("mmc3x30 Read register 0x%0x\n", reg_addr); + if (copy_to_user(pa, ®_value, sizeof(reg_value))) { + return -EFAULT; + } + break; + + case MMC3X30_IOC_WRITE_REG: + if (copy_from_user(&data, pa, sizeof(data))) + return -EFAULT; + + rc = regmap_write(mmc3x30_data_struct->regmap, + data[1], data[0]); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, + "write reg %d failed at %d.(%d)\n", + data[1], __LINE__, rc); + return -EFAULT; + } + pr_info("mmc3x30 Write '0x%0x' to register 0x%0x\n", + data[0], data[1]); + break; + + case MMC3X30_IOC_READ_REGS: + if (copy_from_user(&data, pa, sizeof(data))) + return -EFAULT; + reg_addr = data[0]; + reg_num = data[1]; + + rc = regmap_bulk_read(mmc3x30_data_struct->regmap, + reg_addr, data, reg_num); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, + "read reg %d failed at %d.(%d)\n", + reg_addr, __LINE__, rc); + } + pr_info("mmc3x30 data: %x %x %x \n%x %x %x\n", + data[0], data[1], data[2], + data[3], data[4], data[5]); + if (copy_to_user(pa, data, sizeof(data))) { + return -EFAULT; + } + break; + + default: + dev_dbg(&mmc3x30_data_struct->i2c->dev, "no ctl cmd !\n"); + return -EFAULT; + //break; + } + + return 0; + +} +#ifdef CONFIG_COMPAT +static long mmc3x30_compat_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + void __user *arg64 = compat_ptr(arg); + int ret =-1; + + if (!file->f_op || !file->f_op->unlocked_ioctl) + { + dev_err(&mmc3x30_data_struct->i2c->dev, + "file->f_op OR file->f_op->unlocked_ioctl is null!\n"); + return -EFAULT; + } + switch(cmd) + { + case COMPAT_MMC3X30_IOC_SET: + ret = file->f_op->unlocked_ioctl(file, + MMC3X30_IOC_SET, (unsigned long)arg64); + if (ret < 0) + { + dev_err(&mmc3x30_data_struct->i2c->dev, + "COMPAT_MMC3X30_IOC_SET is failed!\n"); + return -EFAULT; + } + break; + case COMPAT_MMC3X30_IOC_RESET: + ret = file->f_op->unlocked_ioctl(file, + MMC3X30_IOC_RESET, (unsigned long)arg64); + if (ret < 0) + { + dev_err(&mmc3x30_data_struct->i2c->dev, + "COMPAT_MMC3X30_IOC_RESET is failed!\n"); + return -EFAULT; + } + break; + case COMPAT_MMC3X30_IOC_READ_REG: + ret = file->f_op->unlocked_ioctl(file, + COMPAT_MMC3X30_IOC_READ_REG, + (unsigned long)arg64); + if (ret < 0) + { + dev_err(&mmc3x30_data_struct->i2c->dev, + "COMPAT_MMC3X30_IOC_READ_REG is failed!\n"); + return -EFAULT; + } + break; + case COMPAT_MMC3X30_IOC_WRITE_REG: + ret = file->f_op->unlocked_ioctl(file, + COMPAT_MMC3X30_IOC_WRITE_REG, + (unsigned long)arg64); + if (ret < 0) + { + dev_err(&mmc3x30_data_struct->i2c->dev, + "COMPAT_MMC3X30_IOC_WRITE_REG is failed!\n"); + return -EFAULT; + } + break; + case COMPAT_MMC3X30_IOC_READ_REGS: + ret = file->f_op->unlocked_ioctl(file, + COMPAT_MMC3X30_IOC_READ_REGS, + (unsigned long)arg64); + if (ret < 0) + { + dev_err(&mmc3x30_data_struct->i2c->dev, + "COMPAT_MMC3X30_IOC_READ_REGS is failed!\n"); + return -EFAULT; + } + break; + default: + dev_dbg(&mmc3x30_data_struct->i2c->dev, + "no compat ctl cmd !\n"); + return -EFAULT; + //break; + } + return 0; + +} + +#endif + +static struct file_operations mmc3x30_fops = { + .owner = THIS_MODULE, + .open = mmc3x30_open, + .release = mmc3x30_release, + .unlocked_ioctl = mmc3x30_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = mmc3x30_compat_ioctl, +#endif +}; + +static struct miscdevice mmc3x30_device = { + .minor = MISC_DYNAMIC_MINOR, + .name = MMC3X30_I2C_NAME, + .fops = &mmc3x30_fops, +}; +static ssize_t mmc3x30_otp_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + char data[10] = {0}; + unsigned char reg_addr; + unsigned char reg_num; + int rc = -1; + + if (mmc3x30_data_struct->device_id == MMC3524_DEVICE_ID + || mmc3x30_data_struct->device_id == MMC3530_DEVICE_ID) + { + reg_addr = MMC35XX_REG_OTP; + reg_num = 4; + rc = regmap_bulk_read(mmc3x30_data_struct->regmap, + reg_addr, data, reg_num); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, + "read reg %d failed at %d.(%d)\n", + reg_addr, __LINE__, rc); + } + return snprintf(buf, PAGE_SIZE, "%x,%x,%x,%x\n", + data[0], data[1], data[2], data[3]); + + } else if (mmc3x30_data_struct->device_id == MMC3630_DEVICE_ID) { + reg_addr = MMC36XX_REG_OTP_GATE0; + data[0] = MMC36XX_OTP_OPEN0; + rc = regmap_write(mmc3x30_data_struct->regmap, + reg_addr, data[0]); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, + "write reg %d failed at %d.(%d)\n", + reg_addr, __LINE__, rc); + } + reg_addr = MMC36XX_REG_OTP_GATE1; + data[0] = MMC36XX_OTP_OPEN1; + rc = regmap_write(mmc3x30_data_struct->regmap, + reg_addr, data[0]); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, + "write reg %d failed at %d.(%d)\n", + reg_addr, __LINE__, rc); + } + reg_addr = MMC36XX_REG_OTP_GATE2; + data[0] = MMC36XX_OTP_OPEN2; + rc = regmap_write(mmc3x30_data_struct->regmap, + reg_addr, data[0]); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, + "write reg %d failed at %d.(%d)\n", + reg_addr, __LINE__, rc); + } + reg_addr = MMC36XX_REG_CTRL2; + data[0] = MMC36XX_OTP_OPEN2; + rc = regmap_write(mmc3x30_data_struct->regmap, + reg_addr, data[0]); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, + "write reg %d failed at %d.(%d)\n", + reg_addr, __LINE__, rc); + } + + reg_addr = MMC36XX_REG_OTP; + reg_num = 2; + rc = regmap_bulk_read(mmc3x30_data_struct->regmap, + reg_addr, data, reg_num); + if (rc) { + dev_err(&mmc3x30_data_struct->i2c->dev, + "read reg %d failed at %d.(%d)\n", + reg_addr, __LINE__, rc); + } + return snprintf(buf, PAGE_SIZE, "%x,%x\n", data[0], data[1]); + } + else + { + dev_err(&mmc3x30_data_struct->i2c->dev, "No otp !\n"); + return -EFAULT; + } +} + +static ssize_t mmc3x30_value_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + struct mmc3x30_vec vec; + struct mmc3x30_data *memsic = dev_get_drvdata(dev); + + vec.x = vec.y = vec.z = 0; + + ret = mmc3x30_read_xyz(memsic, &vec); + if (ret) { + dev_warn(&memsic->i2c->dev, "read xyz failed\n"); + } + + return snprintf(buf, PAGE_SIZE, "%d %d %d\n", vec.x, vec.y, vec.z); +} +static ssize_t mmc3x30_set_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int rc = -1; + struct mmc3x30_data *memsic = dev_get_drvdata(dev); + + if (memsic->device_id == MMC3524_DEVICE_ID + || memsic->device_id == MMC3530_DEVICE_ID) + { + rc = regmap_write(memsic->regmap, MMC35XX_REG_CTRL0, + MMC35XX_SET); + if (rc) { + dev_err(&memsic->i2c->dev, + "write reg %d failed at %d.(%d)\n", + MMC35XX_REG_CTRL0, __LINE__, rc); + return -EFAULT; + } + + } else if (memsic->device_id == MMC3630_DEVICE_ID) { + rc = regmap_write(memsic->regmap, MMC36XX_REG_CTRL0, + MMC36XX_SET); + if (rc) { + dev_err(&memsic->i2c->dev, + "write reg %d failed at %d.(%d)\n", + MMC36XX_REG_CTRL0, __LINE__, rc); + return -EFAULT; + } + + } + msleep(20);/* setting time */ + return count;/* nothing return */ +} + +static ssize_t mmc3x30_reset_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + + int rc = -1; + struct mmc3x30_data *memsic = dev_get_drvdata(dev); + + if (memsic->device_id == MMC3524_DEVICE_ID + || memsic->device_id == MMC3530_DEVICE_ID) + { + rc = regmap_write(memsic->regmap, MMC35XX_REG_CTRL0, + MMC35XX_RESET); + if (rc) { + dev_err(&memsic->i2c->dev, + "write reg %d failed at %d.(%d)\n", + MMC35XX_REG_CTRL0, __LINE__, rc); + return -EFAULT; + } + + } else if (memsic->device_id == MMC3630_DEVICE_ID) { + rc = regmap_write(memsic->regmap, MMC36XX_REG_CTRL0, + MMC36XX_RESET); + if (rc) { + dev_err(&memsic->i2c->dev, + "write reg %d failed at %d.(%d)\n", + MMC36XX_REG_CTRL0, __LINE__, rc); + return -EFAULT; + } + + } + msleep(20);/* setting time */ + return count;/* nothing return */ +} + +/* add to create sysfs file node */ +static DEVICE_ATTR(otp, S_IRUSR|S_IRGRP, mmc3x30_otp_show, NULL); +static DEVICE_ATTR(value, S_IRUSR|S_IRGRP, mmc3x30_value_show, NULL); +static DEVICE_ATTR(set, S_IWUSR, NULL, mmc3x30_set_store); +static DEVICE_ATTR(reset, S_IWUSR, NULL, mmc3x30_reset_store); + +static struct attribute *mmc3x30_attributes[] = { + &dev_attr_otp.attr, + &dev_attr_value.attr, + &dev_attr_set.attr, + &dev_attr_reset.attr, + NULL, +}; + +static const struct attribute_group mmc3x30_attr_group = { + .attrs = mmc3x30_attributes, +}; + + +static int mmc3x30_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int res = 0; + struct mmc3x30_data *memsic; + + dev_info(&client->dev, "probing mmc3x30\n"); + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + pr_err("mmc3x30 i2c functionality check failed.\n"); + res = -ENODEV; + goto out; + } + + memsic = devm_kzalloc(&client->dev, sizeof(struct mmc3x30_data), + GFP_KERNEL); + if (!memsic) { + dev_err(&client->dev, "memory allocation failed.\n"); + res = -ENOMEM; + goto out; + } + + mmc3x30_data_struct = memsic; + + if (client->dev.of_node) { + res = mmc3x30_parse_dt(client, memsic); + if (res) { + dev_err(&client->dev, + "Unable to parse platform data.(%d)", res); + goto out; + } + } else { + memsic->dir = 1; + memsic->auto_report = 1; + } + + memsic->i2c = client; + dev_set_drvdata(&client->dev, memsic); + + mutex_init(&memsic->ecompass_lock); + mutex_init(&memsic->ops_lock); + + memsic->regmap = devm_regmap_init_i2c(client, &mmc3x30_regmap_config); + if (IS_ERR(memsic->regmap)) { + dev_err(&client->dev, "Init regmap failed.(%ld)", + PTR_ERR(memsic->regmap)); + res = PTR_ERR(memsic->regmap); + goto out; + } + + res = mmc3x30_power_init(memsic); + if (res) { + dev_err(&client->dev, "Power up mmc3x30 failed\n"); + goto out; + } + + res = mmc3x30_check_device(memsic); + if (res) { + dev_err(&client->dev, "Check device failed\n"); + goto out_check_device; + } + + memsic->idev = mmc3x30_init_input(client); + if (!memsic->idev) { + dev_err(&client->dev, "init input device failed\n"); + res = -ENODEV; + goto out_init_input; + } + + + if (memsic->auto_report) { + dev_info(&client->dev, "auto report is enabled\n"); + INIT_DELAYED_WORK(&memsic->dwork, mmc3x30_poll); + } + + memsic->cdev = sensors_cdev; + memsic->cdev.sensors_enable = mmc3x30_set_enable; + memsic->cdev.sensors_poll_delay = mmc3x30_set_poll_delay; + res = sensors_classdev_register(&client->dev, &memsic->cdev); + if (res) { + dev_err(&client->dev, "sensors class register failed.\n"); + goto out_register_classdev; + } +#ifdef INIT_SET + res = mmc3x30_device_initial(memsic); + if (res) { + pr_err("mmc3x30_device initial failed\n"); + } + else{ + pr_info("mmc3x30_device initial OK\n"); + } +#endif + + res = misc_register(&mmc3x30_device); + if (res) { + pr_err("%s: mmc3x30_device register failed\n", __FUNCTION__); + goto out_deregister; + } + + + res = mmc3x30_power_set(memsic, false); + if (res) { + dev_err(&client->dev, "Power off failed\n"); + goto out_power_set; + } + + memsic->poll_interval = MMC3X30_DEFAULT_INTERVAL_MS; + + /* create sysfs group */ + res = sysfs_create_group(&client->dev.kobj, &mmc3x30_attr_group); + if (res) { + res = -EROFS; + dev_err(&client->dev,"Unable to creat sysfs group\n"); + } + + dev_info(&client->dev, "mmc3x30 successfully probed\n"); + + return 0; + +out_power_set: + sensors_classdev_unregister(&memsic->cdev); +out_deregister: + misc_deregister(&mmc3x30_device); +out_register_classdev: + input_unregister_device(memsic->idev); +out_init_input: +out_check_device: + mmc3x30_power_deinit(memsic); +out: + return res; +} + +static int mmc3x30_remove(struct i2c_client *client) +{ + struct mmc3x30_data *memsic = dev_get_drvdata(&client->dev); + + sensors_classdev_unregister(&memsic->cdev); + misc_deregister(&mmc3x30_device); + mmc3x30_power_deinit(memsic); + + if (memsic->idev) + input_unregister_device(memsic->idev); + + sysfs_remove_group(&client->dev.kobj, &mmc3x30_attr_group); + + return 0; +} + +static int mmc3x30_suspend(struct device *dev) +{ + int res = 0; + struct mmc3x30_data *memsic = dev_get_drvdata(dev); + + dev_dbg(dev, "suspended\n"); + + if (memsic->enable) { + if (memsic->auto_report) + cancel_delayed_work_sync(&memsic->dwork); + + res = mmc3x30_power_set(memsic, false); + if (res) { + dev_err(dev, "failed to suspend mmc3x30\n"); + goto exit; + } + } +exit: + return res; +} + +static int mmc3x30_resume(struct device *dev) +{ + int res = 0; + struct mmc3x30_data *memsic = dev_get_drvdata(dev); + + dev_dbg(dev, "resumed\n"); + + if (!memsic->enable) { + res = mmc3x30_power_set(memsic, true); + if (res) { + dev_err(&memsic->i2c->dev, "Power enable failed\n"); + goto exit; + } + + if (memsic->auto_report) + schedule_delayed_work(&memsic->dwork, + msecs_to_jiffies(memsic->poll_interval)); + } + +exit: + return res; +} + +static const struct i2c_device_id mmc3x30_id[] = { + { MMC3X30_I2C_NAME, 0 }, + { } +}; + +static struct of_device_id mmc3x30_match_table[] = { + { .compatible = "memsic,mmc3x30", }, + { }, +}; + +static const struct dev_pm_ops mmc3x30_pm_ops = { + .suspend = mmc3x30_suspend, + .resume = mmc3x30_resume, +}; + +static struct i2c_driver mmc3x30_driver = { + .probe = mmc3x30_probe, + .remove = mmc3x30_remove, + .id_table = mmc3x30_id, + .driver = { + .owner = THIS_MODULE, + .name = MMC3X30_I2C_NAME, + .of_match_table = mmc3x30_match_table, + .pm = &mmc3x30_pm_ops, + }, +}; + +static int __init mmc3x30_init(void) +{ + return i2c_add_driver(&mmc3x30_driver); +} + +static void __exit mmc3x30_exit(void) +{ + i2c_del_driver(&mmc3x30_driver); +} + +//module_i2c_driver(mmc3x30_driver); +late_initcall(mmc3x30_init); +module_exit(mmc3x30_exit); + +MODULE_DESCRIPTION("MEMSIC MMC3X30 Magnetic Sensor Driver"); +MODULE_LICENSE("GPL"); + diff --git a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_rmi_dev.c b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_rmi_dev.c index 4f1dd7bf424fc..9d61eb110e2f1 100644 --- a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_rmi_dev.c +++ b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_rmi_dev.c @@ -381,7 +381,6 @@ static ssize_t rmidev_read(struct file *filp, char __user *buf, clean_up: mutex_unlock(&(dev_data->file_mutex)); - kfree(tmpbuf); return retval; } @@ -420,7 +419,6 @@ static ssize_t rmidev_write(struct file *filp, const char __user *buf, kfree(tmpbuf); return -EFAULT; } - mutex_lock(&(dev_data->file_mutex)); retval = synaptics_rmi4_reg_write(rmidev->rmi4_data, @@ -431,7 +429,6 @@ static ssize_t rmidev_write(struct file *filp, const char __user *buf, *f_pos += retval; mutex_unlock(&(dev_data->file_mutex)); - kfree(tmpbuf); return retval; } diff --git a/drivers/input/touchscreen/synaptics_rmi_dev.c b/drivers/input/touchscreen/synaptics_rmi_dev.c index e2d7c27eb6832..ff4f426df7d55 100644 --- a/drivers/input/touchscreen/synaptics_rmi_dev.c +++ b/drivers/input/touchscreen/synaptics_rmi_dev.c @@ -325,7 +325,6 @@ static ssize_t rmidev_read(struct file *filp, char __user *buf, clean_up: mutex_unlock(&(dev_data->file_mutex)); - kfree(tmpbuf); return retval; } diff --git a/drivers/iommu/msm_iommu_sec.c b/drivers/iommu/msm_iommu_sec.c index 9d09f27736d5b..b0ec8c6dfa66d 100644 --- a/drivers/iommu/msm_iommu_sec.c +++ b/drivers/iommu/msm_iommu_sec.c @@ -517,6 +517,9 @@ static int msm_iommu_sec_ptbl_map(struct msm_iommu_drvdata *iommu_drvdata, phys_addr_t flush_pa; int ret = 0; + if (!IS_ALIGNED(va, SZ_1M) || !IS_ALIGNED(len, SZ_1M) || + !IS_ALIGNED(pa, SZ_1M)) + return -EINVAL; map.plist.list = virt_to_phys(&pa); map.plist.list_size = 1; map.plist.size = len; @@ -568,22 +571,36 @@ static int msm_iommu_sec_ptbl_map_range(struct msm_iommu_drvdata *iommu_drvdata, unsigned int offset = 0, chunk_offset = 0; int ret; + if (!IS_ALIGNED(va, SZ_1M) || !IS_ALIGNED(len, SZ_1M)) + return -EINVAL; + map.info.id = iommu_drvdata->sec_id; map.info.ctx_id = ctx_drvdata->num; map.info.va = va; map.info.size = len; if (sg->length == len) { + /* + * physical address for secure mapping needs + * to be 1MB aligned + */ pa = get_phys_addr(sg); + if (!IS_ALIGNED(pa, SZ_1M)) + return -EINVAL; map.plist.list = virt_to_phys(&pa); map.plist.list_size = 1; map.plist.size = len; flush_va = &pa; } else { sgiter = sg; + if (!IS_ALIGNED(sgiter->length, SZ_1M)) + return -EINVAL; cnt = sg->length / SZ_1M; - while ((sgiter = sg_next(sgiter))) + while ((sgiter = sg_next(sgiter))) { + if (!IS_ALIGNED(sgiter->length, SZ_1M)) + return -EINVAL; cnt += sgiter->length / SZ_1M; + } pa_list = kmalloc(cnt * sizeof(*pa_list), GFP_KERNEL); if (!pa_list) @@ -592,6 +609,10 @@ static int msm_iommu_sec_ptbl_map_range(struct msm_iommu_drvdata *iommu_drvdata, sgiter = sg; cnt = 0; pa = get_phys_addr(sgiter); + if (!IS_ALIGNED(pa, SZ_1M)) { + kfree(pa_list); + return -EINVAL; + } while (offset < len) { pa += chunk_offset; pa_list[cnt] = pa; @@ -638,6 +659,8 @@ static int msm_iommu_sec_ptbl_unmap(struct msm_iommu_drvdata *iommu_drvdata, int ret, scm_ret; struct scm_desc desc = {0}; + if (!IS_ALIGNED(va, SZ_1M) || !IS_ALIGNED(len, SZ_1M)) + return -EINVAL; desc.args[0] = unmap.info.id = iommu_drvdata->sec_id; desc.args[1] = unmap.info.ctx_id = ctx_drvdata->num; desc.args[2] = unmap.info.va = va; @@ -878,6 +901,9 @@ static int msm_iommu_unmap_range(struct iommu_domain *domain, unsigned int va, struct msm_iommu_ctx_drvdata *ctx_drvdata; int ret = -EINVAL; + if (!IS_ALIGNED(va, SZ_1M) || !IS_ALIGNED(len, SZ_1M)) + return -EINVAL; + iommu_access_ops->iommu_lock_acquire(0); ret = get_drvdata(domain, &iommu_drvdata, &ctx_drvdata); diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c index 954bbfbe6ce4a..baf95a5f50d37 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c @@ -954,7 +954,7 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev, case VFE_READ_DMI_32BIT: case VFE_READ_DMI_64BIT: { if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_64BIT || - reg_cfg_cmd->cmd_type == VFE_READ_DMI_64BIT) { + reg_cfg_cmd->cmd_type == VFE_READ_DMI_64BIT) { if ((reg_cfg_cmd->u.dmi_info.hi_tbl_offset <= reg_cfg_cmd->u.dmi_info.lo_tbl_offset) || (reg_cfg_cmd->u.dmi_info.hi_tbl_offset - diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c index 1fd8da1e50ead..73cbe4a5cfb8b 100644 --- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c +++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c @@ -106,9 +106,9 @@ static struct msm_cam_clk_info ispif_8974_reset_clk_info[] = { {"camss_csi_vfe1_clk", NO_SET_RATE}, }; -static int msm_ispif_reset_hw(struct ispif_device *ispif) +static int msm_ispif_reset_hw(struct ispif_device *ispif, int release) { - int rc = 0; + int rc = 0, i; long timeout = 0; struct clk *reset_clk[ARRAY_SIZE(ispif_8974_reset_clk_info)]; struct clk *reset_clk1[ARRAY_SIZE(ispif_8626_reset_clk_info)]; @@ -133,6 +133,17 @@ static int msm_ispif_reset_hw(struct ispif_device *ispif) ispif->clk_idx = 1; } + if (release) { + for (i = 0; i < ispif->vfe_info.num_vfe; i++) { + msm_camera_io_w_mb(ISPIF_STOP_INTF_IMMEDIATELY, + ispif->base + ISPIF_VFE_m_INTF_CMD_0(i)); + msm_camera_io_w_mb(ISPIF_STOP_INTF_IMMEDIATELY, + ispif->base + ISPIF_VFE_m_INTF_CMD_1(i)); + } + msm_camera_io_w_mb(ISPIF_IRQ_GLOBAL_CLEAR_CMD, + ispif->base + ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR); + } + init_completion(&ispif->reset_complete[VFE0]); if (ispif->hw_num_isps > 1) init_completion(&ispif->reset_complete[VFE1]); @@ -258,11 +269,6 @@ static int msm_ispif_clk_ahb_enable(struct ispif_device *ispif, int enable) { int rc = 0; - if (ispif->csid_version < CSID_VERSION_V30) { - /* Older ISPIF versiond don't need ahb clokc */ - return 0; - } - rc = msm_ispif_get_ahb_clk_info(ispif, ispif->pdev, ispif_8974_ahb_clk_info); if (rc < 0) { @@ -556,7 +562,7 @@ static uint16_t msm_ispif_get_cids_mask_from_cfg( BUG_ON(!entry); - for (i = 0; i < entry->num_cids; i++) + for (i = 0; i < entry->num_cids && i < MAX_CID_CH_V2; i++) cids_mask |= (1 << entry->cids[i]); return cids_mask; @@ -573,6 +579,12 @@ static int msm_ispif_config(struct ispif_device *ispif, BUG_ON(!ispif); BUG_ON(!params); + if (!ispif->base) { + pr_err("%s: ispif base is NULL\n", __func__); + rc = -EPERM; + return rc; + } + if (ispif->ispif_state != ISPIF_POWER_UP) { pr_err("%s: ispif invalid state %d\n", __func__, ispif->ispif_state); @@ -690,7 +702,7 @@ static void msm_ispif_intf_cmd(struct ispif_device *ispif, uint32_t cmd_bits, pr_err("%s: invalid interface type\n", __func__); return; } - if (params->entries[i].num_cids > MAX_CID_CH) { + if (params->entries[i].num_cids > MAX_CID_CH_V2) { pr_err("%s: out of range of cid_num %d\n", __func__, params->entries[i].num_cids); return; @@ -1240,7 +1252,7 @@ static int msm_ispif_init(struct ispif_device *ispif, goto error_ahb; } - msm_ispif_reset_hw(ispif); + msm_ispif_reset_hw(ispif, 0); rc = msm_ispif_reset(ispif); if (rc == 0) { @@ -1273,8 +1285,10 @@ static void msm_ispif_release(struct ispif_device *ispif) return; } + msm_ispif_clk_ahb_enable(ispif, 1); + /* make sure no streaming going on */ - msm_ispif_reset(ispif); + msm_ispif_reset_hw(ispif, 1); msm_ispif_clk_ahb_enable(ispif, 0); @@ -1359,8 +1373,11 @@ static long msm_ispif_subdev_ioctl(struct v4l2_subdev *sd, case MSM_SD_SHUTDOWN: { struct ispif_device *ispif = (struct ispif_device *)v4l2_get_subdevdata(sd); - if (ispif && ispif->base) + if (ispif && ispif->base) { + mutex_lock(&ispif->mutex); msm_ispif_release(ispif); + mutex_unlock(&ispif->mutex); + } return 0; } default: diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c index 55efe8e444d20..0c2304338b800 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c +++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c @@ -85,11 +85,6 @@ static void msm_actuator_parse_i2c_params(struct msm_actuator_ctrl_t *a_ctrl, struct msm_camera_i2c_reg_array *i2c_tbl = a_ctrl->i2c_reg_tbl; CDBG("Enter\n"); for (i = 0; i < size; i++) { - /* check that the index into i2c_tbl cannot grow larger that - the allocated size of i2c_tbl */ - if ((a_ctrl->total_steps + 1) < (a_ctrl->i2c_tbl_index)) - break; - if (write_arr[i].reg_write_type == MSM_ACTUATOR_WRITE_DAC) { value = (next_lens_position << write_arr[i].data_shift) | @@ -103,6 +98,11 @@ static void msm_actuator_parse_i2c_params(struct msm_actuator_ctrl_t *a_ctrl, i2c_byte2 = value & 0xFF; CDBG("byte1:0x%x, byte2:0x%x\n", i2c_byte1, i2c_byte2); + if (a_ctrl->i2c_tbl_index > + a_ctrl->total_steps) { + pr_err("failed:i2c table index out of bound\n"); + break; + } i2c_tbl[a_ctrl->i2c_tbl_index]. reg_addr = i2c_byte1; i2c_tbl[a_ctrl->i2c_tbl_index]. @@ -149,6 +149,10 @@ static void msm_actuator_parse_i2c_params(struct msm_actuator_ctrl_t *a_ctrl, i2c_byte2 = (hw_dword & write_arr[i].hw_mask) >> write_arr[i].hw_shift; } + if (a_ctrl->i2c_tbl_index > a_ctrl->total_steps) { + pr_err("failed: i2c table index out of bound\n"); + break; + } CDBG("i2c_byte1:0x%x, i2c_byte2:0x%x\n", i2c_byte1, i2c_byte2); i2c_tbl[a_ctrl->i2c_tbl_index].reg_addr = i2c_byte1; i2c_tbl[a_ctrl->i2c_tbl_index].reg_data = i2c_byte2; diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c index 3103f042ae3dd..1450bbd2aa8f8 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c +++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014, 2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -72,7 +72,7 @@ int32_t msm_camera_cci_i2c_read_seq(struct msm_camera_i2c_client *client, return rc; if (num_byte > I2C_REG_DATA_MAX) { - pr_err("%s: Error num_byte:0x%x exceeds 8K max supported:0x%x\n", + pr_err("%s: Error num_byte:0x%x exceeds 8K max supported:0x%x\n", __func__, num_byte, I2C_REG_DATA_MAX); return rc; } 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 dd3446b878e03..1ecd4e0e7fd51 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 @@ -111,14 +111,14 @@ int32_t msm_camera_qup_i2c_read(struct msm_camera_i2c_client *client, return rc; if (client->addr_type > UINT_MAX - data_type) { - pr_err("%s: integer overflow prevented\n", __func__); - return rc; + pr_err("%s: integer overflow prevented\n", __func__); + return rc; } buf = kzalloc(client->addr_type+data_type, GFP_KERNEL); if (!buf) { - pr_err("%s:%d no memory\n", __func__, __LINE__); - return -ENOMEM; + pr_err("%s:%d no memory\n", __func__, __LINE__); + return -ENOMEM; } if (client->addr_type == MSM_CAMERA_I2C_BYTE_ADDR) { @@ -159,19 +159,19 @@ int32_t msm_camera_qup_i2c_read_seq(struct msm_camera_i2c_client *client, return rc; if (num_byte > I2C_REG_DATA_MAX) { - pr_err("%s: Error num_byte:0x%x exceeds 8K max supported:0x%x\n", - __func__, num_byte, I2C_REG_DATA_MAX); - return rc; + pr_err("%s: Error num_byte:0x%x exceeds 8K max supported:0x%x\n", + __func__, num_byte, I2C_REG_DATA_MAX); + return rc; } if (client->addr_type > UINT_MAX - num_byte) { - pr_err("%s: integer overflow prevented\n", __func__); - return rc; + pr_err("%s: integer overflow prevented\n", __func__); + return rc; } buf = kzalloc(client->addr_type+num_byte, GFP_KERNEL); if (!buf) { - pr_err("%s:%d no memory\n", __func__, __LINE__); - return -ENOMEM; + pr_err("%s:%d no memory\n", __func__, __LINE__); + return -ENOMEM; } if (client->addr_type == MSM_CAMERA_I2C_BYTE_ADDR) { diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.c b/drivers/media/platform/msm/vidc/hfi_packetization.c index d49acc41a775c..d3d32b4339163 100644 --- a/drivers/media/platform/msm/vidc/hfi_packetization.c +++ b/drivers/media/platform/msm/vidc/hfi_packetization.c @@ -176,6 +176,16 @@ static inline u32 get_hfi_codec(enum hal_video_codec hal_codec) return hfi_codec; } +static void create_pkt_enable(void *pkt, u32 type, bool enable) +{ + u32 *pkt_header = pkt; + u32 *pkt_type = &pkt_header[0]; + struct hfi_enable *hfi_enable = (struct hfi_enable *)&pkt_header[1]; + + *pkt_type = type; + hfi_enable->enable = enable; +} + int create_pkt_cmd_sys_init(struct hfi_cmd_sys_init_packet *pkt, u32 arch_type) { @@ -483,6 +493,19 @@ static int get_hfi_extradata_index(enum hal_extradata_id index) case HAL_EXTRADATA_METADATA_MBI: ret = HFI_PROPERTY_PARAM_VENC_MBI_DUMPING; break; + case HAL_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI: + ret = + HFI_PROPERTY_PARAM_VDEC_MASTERING_DISPLAY_COLOUR_SEI_EXTRADATA; + break; + case HAL_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI: + ret = HFI_PROPERTY_PARAM_VDEC_CONTENT_LIGHT_LEVEL_SEI_EXTRADATA; + break; + case HAL_EXTRADATA_VUI_DISPLAY_INFO: + ret = HFI_PROPERTY_PARAM_VUI_DISPLAY_INFO_EXTRADATA; + break; + case HAL_EXTRADATA_VPX_COLORSPACE: + ret = HFI_PROPERTY_PARAM_VDEC_VPX_COLORSPACE_EXTRADATA; + break; default: dprintk(VIDC_WARN, "Extradata index not found: %d\n", index); break; @@ -1898,6 +1921,34 @@ int create_pkt_cmd_session_set_property( sizeof(struct hfi_hybrid_hierp); break; } + case HAL_PARAM_VENC_VIDEO_SIGNAL_INFO: + { + struct hal_video_signal_info *hal = pdata; + struct hfi_video_signal_metadata *signal_info = + (struct hfi_video_signal_metadata *) + &pkt->rg_property_data[1]; + + signal_info->enable = true; + signal_info->video_format = MSM_VIDC_NTSC; + signal_info->video_full_range = hal->full_range; + signal_info->color_description = MSM_VIDC_COLOR_DESC_PRESENT; + signal_info->color_primaries = hal->color_space; + signal_info->transfer_characteristics = hal->transfer_chars; + signal_info->matrix_coeffs = hal->matrix_coeffs; + + pkt->rg_property_data[0] = + HFI_PROPERTY_PARAM_VENC_VIDEO_SIGNAL_INFO; + pkt->size += sizeof(u32) + sizeof(*signal_info); + break; + } + case HAL_PARAM_VENC_CONSTRAINED_INTRA_PRED: + { + create_pkt_enable(pkt->rg_property_data, + HFI_PROPERTY_PARAM_VENC_CONSTRAINED_INTRA_PRED, + ((struct hal_enable *)pdata)->enable); + pkt->size += sizeof(u32) + sizeof(struct hfi_enable); + break; + } /* FOLLOWING PROPERTIES ARE NOT IMPLEMENTED IN CORE YET */ case HAL_CONFIG_BUFFER_REQUIREMENTS: case HAL_CONFIG_PRIORITY: diff --git a/drivers/media/platform/msm/vidc/msm_smem.c b/drivers/media/platform/msm/vidc/msm_smem.c index f0455cc9e9854..48fc909140f7c 100644 --- a/drivers/media/platform/msm/vidc/msm_smem.c +++ b/drivers/media/platform/msm/vidc/msm_smem.c @@ -325,6 +325,17 @@ struct msm_smem *msm_smem_user_to_kernel(void *clt, int fd, u32 offset, return mem; } +bool msm_smem_compare_buffers(void *clt, int fd, void *priv) { + struct smem_client *client = clt; + struct ion_handle *handle = NULL; + bool ret = false; + handle = ion_import_dma_buf(client->clnt, fd); + ret = handle == priv; + handle ? ion_free(client->clnt, handle) : 0; + return ret; +} + + static int ion_cache_operations(struct smem_client *client, struct msm_smem *mem, enum smem_cache_ops cache_op) { diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c index 8c2b8731c2439..1a9cd222af863 100644 --- a/drivers/media/platform/msm/vidc/msm_vdec.c +++ b/drivers/media/platform/msm/vidc/msm_vdec.c @@ -50,27 +50,6 @@ static const char *const mpeg_video_output_order[] = { "Decode Order", NULL }; -static const char *const mpeg_video_vidc_extradata[] = { - "Extradata none", - "Extradata MB Quantization", - "Extradata Interlace Video", - "Extradata VC1 Framedisp", - "Extradata VC1 Seqdisp", - "Extradata timestamp", - "Extradata S3D Frame Packing", - "Extradata Frame Rate", - "Extradata Panscan Window", - "Extradata Recovery point SEI", - "Extradata Closed Caption UD", - "Extradata AFD UD", - "Extradata Multislice info", - "Extradata number of concealed MB", - "Extradata metadata filler", - "Extradata input crop", - "Extradata digital zoom", - "Extradata aspect ratio", - "Extradata mpeg2 seqdisp", -}; static const char *const mpeg_vidc_video_alloc_mode_type[] = { "Buffer Allocation Static", "Buffer Allocation Ring Buffer", @@ -246,7 +225,7 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { .name = "Extradata Type", .type = V4L2_CTRL_TYPE_MENU, .minimum = V4L2_MPEG_VIDC_EXTRADATA_NONE, - .maximum = V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO, + .maximum = V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE, .default_value = V4L2_MPEG_VIDC_EXTRADATA_NONE, .menu_skip_mask = ~( (1 << V4L2_MPEG_VIDC_EXTRADATA_NONE) | @@ -268,7 +247,12 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { (1 << V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP) | (1 << V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA) | (1 << V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP) | - (1 << V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO) + (1 << V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO) | + (1 << V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI) | + (1 << + V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI) | + (1 << V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY) | + (1 << V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE) ), .qmenu = mpeg_video_vidc_extradata, .step = 0, diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c index 2f8d8972e9cd6..819c5ee0129e1 100644 --- a/drivers/media/platform/msm/vidc/msm_venc.c +++ b/drivers/media/platform/msm/vidc/msm_venc.c @@ -152,29 +152,6 @@ static const char *const vp8_profile_level[] = { "2.0", "3.0", }; - -static const char *const mpeg_video_vidc_extradata[] = { - "Extradata none", - "Extradata MB Quantization", - "Extradata Interlace Video", - "Extradata VC1 Framedisp", - "Extradata VC1 Seqdisp", - "Extradata timestamp", - "Extradata S3D Frame Packing", - "Extradata Frame Rate", - "Extradata Panscan Window", - "Extradata Recovery point SEI", - "Extradata Closed Caption UD", - "Extradata AFD UD", - "Extradata Multislice info", - "Extradata number of concealed MB", - "Extradata metadata filler", - "Extradata input crop", - "Extradata digital zoom", - "Extradata aspect ratio", - "Extradata macroblock metadata", -}; - static const char *const perf_level[] = { "Nominal", "Performance", @@ -1083,6 +1060,55 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .step = 1, .qmenu = NULL, }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE, + .name = "Set Color space", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = MSM_VIDC_BT709_5, + .maximum = MSM_VIDC_BT2020, + .default_value = MSM_VIDC_BT601_6_625, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE, + .name = "Set Color space range", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE_DISABLE, + .maximum = V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE_ENABLE, + .default_value = V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE_DISABLE, + .step = 1, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS, + .name = "Set Color space transfer characterstics", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = MSM_VIDC_TRANSFER_BT709_5, + .maximum = MSM_VIDC_TRANSFER_BT_2020_12, + .default_value = MSM_VIDC_TRANSFER_601_6_625, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS, + .name = "Set Color space matrix coefficients", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = MSM_VIDC_MATRIX_BT_709_5, + .maximum = MSM_VIDC_MATRIX_BT_2020_CONST, + .default_value = MSM_VIDC_MATRIX_601_6_625, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC, + .name = "Set VPE Color space conversion coefficients", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_DISABLE, + .maximum = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_ENABLE, + .default_value = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_DISABLE, + .step = 1, + }, + }; #define NUM_CTRLS ARRAY_SIZE(msm_venc_ctrls) @@ -1163,6 +1189,8 @@ static struct msm_vidc_format venc_formats[] = { }, }; +static int msm_venc_set_csc(struct msm_vidc_inst *inst); + static int msm_venc_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, unsigned int *num_buffers, @@ -1837,6 +1865,7 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) struct hal_hybrid_hierp hyb_hierp; u32 hier_p_layers = 0, hier_b_layers = 0; struct hal_venc_perf_mode venc_mode; + struct hal_video_signal_info signal_info = {0}; if (!inst || !inst->core || !inst->core->device) { dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); @@ -2347,12 +2376,34 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) } case V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE: { struct v4l2_ctrl *air_mbs, *air_ref, *cir_mbs; + bool is_cont_intra_supported = false; + air_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS); air_ref = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF); cir_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS); - property_id = - HAL_PARAM_VENC_INTRA_REFRESH; + is_cont_intra_supported = + (inst->fmts[CAPTURE_PORT]->fourcc == V4L2_PIX_FMT_H264) || + (inst->fmts[CAPTURE_PORT]->fourcc == V4L2_PIX_FMT_HEVC); + + if (is_cont_intra_supported) { + if (air_mbs || air_ref || cir_mbs) + enable.enable = true; + else + enable.enable = false; + + rc = call_hfi_op(hdev, session_set_property, + (void *)inst->session, + HAL_PARAM_VENC_CONSTRAINED_INTRA_PRED, &enable); + if (rc) { + dprintk(VIDC_ERR, + "Failed to set constrained intra\n"); + rc = -EINVAL; + break; + } + } + + property_id = HAL_PARAM_VENC_INTRA_REFRESH; intra_refresh.mode = ctrl->val; intra_refresh.air_mbs = air_mbs->val; @@ -2697,6 +2748,71 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE: property_id = 0; break; + case V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE: + { + signal_info.color_space = ctrl->val; + temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE); + signal_info.full_range = temp_ctrl ? temp_ctrl->val : 0; + temp_ctrl = + TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS); + signal_info.transfer_chars = temp_ctrl ? temp_ctrl->val : 0; + temp_ctrl = + TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS); + signal_info.matrix_coeffs = temp_ctrl ? temp_ctrl->val : 0; + property_id = HAL_PARAM_VENC_VIDEO_SIGNAL_INFO; + pdata = &signal_info; + break; + } + case V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE: + { + signal_info.full_range = ctrl->val; + temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE); + signal_info.color_space = temp_ctrl ? temp_ctrl->val : 0; + temp_ctrl = + TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS); + signal_info.transfer_chars = temp_ctrl ? temp_ctrl->val : 0; + temp_ctrl = + TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS); + signal_info.matrix_coeffs = temp_ctrl ? temp_ctrl->val : 0; + property_id = HAL_PARAM_VENC_VIDEO_SIGNAL_INFO; + pdata = &signal_info; + break; + } + case V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS: + { + signal_info.transfer_chars = ctrl->val; + temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE); + signal_info.full_range = temp_ctrl ? temp_ctrl->val : 0; + temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE); + signal_info.color_space = temp_ctrl ? temp_ctrl->val : 0; + temp_ctrl = + TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS); + signal_info.matrix_coeffs = temp_ctrl ? temp_ctrl->val : 0; + property_id = HAL_PARAM_VENC_VIDEO_SIGNAL_INFO; + pdata = &signal_info; + break; + } + case V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS: + { + signal_info.matrix_coeffs = ctrl->val; + temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE); + signal_info.full_range = temp_ctrl ? temp_ctrl->val : 0; + temp_ctrl = + TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS); + signal_info.transfer_chars = temp_ctrl ? temp_ctrl->val : 0; + temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE); + signal_info.color_space = temp_ctrl ? temp_ctrl->val : 0; + property_id = HAL_PARAM_VENC_VIDEO_SIGNAL_INFO; + pdata = &signal_info; + break; + } + case V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC: + if (ctrl->val == V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_ENABLE) { + rc = msm_venc_set_csc(inst); + if (rc) + dprintk(VIDC_ERR, "fail to set csc: %d\n", rc); + } + break; default: dprintk(VIDC_ERR, "Unsupported index: %x\n", ctrl->id); rc = -ENOTSUPP; @@ -3097,7 +3213,7 @@ int msm_venc_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a) return rc; } -int msm_venc_set_csc(struct msm_vidc_inst *inst) +static int msm_venc_set_csc(struct msm_vidc_inst *inst) { int rc = 0; int count = 0; @@ -3140,10 +3256,6 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) } hdev = inst->core->device; - if (msm_vidc_vpe_csc_601_to_709) { - msm_venc_set_csc(inst); - } - if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { fmt = msm_comm_get_pixel_fmt_fourcc(venc_formats, ARRAY_SIZE(venc_formats), f->fmt.pix_mp.pixelformat, diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c index 84a48ca43b555..169d112088f72 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc.c +++ b/drivers/media/platform/msm/vidc/msm_vidc.c @@ -259,9 +259,11 @@ struct buffer_info *get_registered_buf(struct msm_vidc_inst *inst, list_for_each_entry(temp, &inst->registeredbufs.list, list) { for (i = 0; (i < temp->num_planes) && (i < VIDEO_MAX_PLANES); i++) { + bool ion_hndl_matches = + msm_smem_compare_buffers(inst->mem_client, fd, + temp->handle[i]->smem_priv); if (temp && - ((fd == temp->fd[i]) || - (device_addr == temp->device_addr[i])) && + (device_addr == temp->device_addr[i] || ion_hndl_matches) && (CONTAINS(temp->buff_off[i], temp->size[i], buff_off) || CONTAINS(buff_off, @@ -467,6 +469,9 @@ int map_and_register_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b) int plane = 0; int i = 0, rc = 0; struct msm_smem *same_fd_handle = NULL; + bool check_same_fd_handle = !is_dynamic_output_buffer_mode(b, inst) && + !( inst->session_type == MSM_VIDC_ENCODER && + b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); if (!b || !inst) { dprintk(VIDC_ERR, "%s: invalid input\n", __func__); @@ -530,7 +535,8 @@ int map_and_register_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b) if (rc < 0) goto exit; - if (!is_dynamic_output_buffer_mode(b, inst)) + //if (!is_dynamic_output_buffer_mode(b, inst)) + if (check_same_fd_handle) same_fd_handle = get_same_fd_buffer( &inst->registeredbufs, b->m.planes[i].reserved[0]); @@ -622,7 +628,7 @@ int unmap_and_deregister_buf(struct msm_vidc_inst *inst, for (i = 0; i < temp->num_planes; i++) { dprintk(VIDC_DBG, - "%s: [UNMAP] binfo = %pK, handle[%d] = %pK, device_addr = 0x%pKa, fd = %d, offset = %d, mapped = %d\n", + "%s: [UNMAP] binfo = %pK, handle[%d] = %pK, device_addr = 0x%pa, fd = %d, offset = %d, mapped = %d\n", __func__, temp, i, temp->handle[i], &temp->device_addr[i], temp->fd[i], temp->buff_off[i], temp->mapped[i]); diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c index dc76227a1749d..d6860109f2fbf 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_common.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c @@ -51,6 +51,39 @@ #define IS_SYS_CMD_VALID(cmd) (((cmd) >= SYS_MSG_START) && \ ((cmd) <= SYS_MSG_END)) +const char *const mpeg_video_vidc_extradata[] = { + "Extradata none", + "Extradata MB Quantization", + "Extradata Interlace Video", + "Extradata VC1 Framedisp", + "Extradata VC1 Seqdisp", + "Extradata timestamp", + "Extradata S3D Frame Packing", + "Extradata Frame Rate", + "Extradata Panscan Window", + "Extradata Recovery point SEI", + "Extradata Multislice info", + "Extradata number of concealed MB", + "Extradata metadata filler", + "Extradata input crop", + "Extradata digital zoom", + "Extradata aspect ratio", + "Extradata mpeg2 seqdisp", + "Extradata stream userdata", + "Extradata frame QP", + "Extradata frame bits info", + "Extradata LTR", + "Extradata macroblock metadata", + "Extradata VQZip SEI", + "Extradata YUV Stats", + "Extradata ROI QP", + "Extradata output crop", + "Extradata display colour SEI", + "Extradata light level SEI", + "Extradata display VUI", + "Extradata vpx color space", +}; + struct getprop_buf { struct list_head list; void *data; @@ -82,7 +115,6 @@ static inline bool is_non_realtime_session(struct msm_vidc_inst *inst) rc = v4l2_g_ctrl(&inst->ctrl_handler, &ctrl); return (!rc && ctrl.value); } - enum multi_stream msm_comm_get_stream_output_mode(struct msm_vidc_inst *inst) { if (inst->session_type == MSM_VIDC_DECODER) { @@ -4284,6 +4316,18 @@ enum hal_extradata_id msm_comm_get_hal_extradata_index( case V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI: ret = HAL_EXTRADATA_METADATA_MBI; break; + case V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI: + ret = HAL_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI; + break; + case V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI: + ret = HAL_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI; + break; + case V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY: + ret = HAL_EXTRADATA_VUI_DISPLAY_INFO; + break; + case V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE: + ret = HAL_EXTRADATA_VPX_COLORSPACE; + break; default: dprintk(VIDC_WARN, "Extradata not found: %d\n", index); break; diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.h b/drivers/media/platform/msm/vidc/msm_vidc_common.h index 890153b933116..d9cb73a86bcf5 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_common.h +++ b/drivers/media/platform/msm/vidc/msm_vidc_common.h @@ -18,6 +18,9 @@ struct vb2_buf_entry { struct list_head list; struct vb2_buffer *vb; }; + +extern const char *const mpeg_video_vidc_extradata[]; + struct msm_vidc_core *get_vidc_core(int core_id); const struct msm_vidc_format *msm_comm_get_pixel_fmt_index( const struct msm_vidc_format fmt[], int size, int index, int fmt_type); diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.c b/drivers/media/platform/msm/vidc/msm_vidc_debug.c index b0bda5de403fa..509ea440cf6e8 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_debug.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.c @@ -23,7 +23,6 @@ int msm_fw_debug_mode = 0x1; int msm_fw_low_power_mode = 0x1; int msm_vidc_hw_rsp_timeout = 1000; u32 msm_fw_coverage = 0x0; -int msm_vidc_vpe_csc_601_to_709 = 0x0; int msm_vidc_dcvs_mode = 0x1; int msm_vidc_sys_idle_indicator = 0x0; u32 msm_vidc_firmware_unload_delay = 15000; @@ -183,11 +182,6 @@ struct dentry *msm_vidc_debugfs_init_drv(void) dprintk(VIDC_ERR, "debugfs_create_file: fail\n"); goto failed_create_dir; } - if (!debugfs_create_bool("enable_vpe_csc_601_709", S_IRUGO | S_IWUSR, - dir, &msm_vidc_vpe_csc_601_to_709)) { - dprintk(VIDC_ERR, "debugfs_create_file: fail\n"); - goto failed_create_dir; - } if (!debugfs_create_bool("sys_idle_indicator", S_IRUGO | S_IWUSR, dir, &msm_vidc_sys_idle_indicator)) { dprintk(VIDC_ERR, diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h index ed696710215f6..4340308966176 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h +++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h @@ -390,6 +390,7 @@ int msm_smem_cache_operations(void *clt, struct msm_smem *mem, enum smem_cache_ops); struct msm_smem *msm_smem_user_to_kernel(void *clt, int fd, u32 offset, enum hal_buffer buffer_type); +bool msm_smem_compare_buffers(void *clt, int fd, void *priv); int msm_smem_get_domain_partition(void *clt, u32 flags, enum hal_buffer buffer_type, int *domain_num, int *partition_num); void msm_vidc_fw_unload_handler(struct work_struct *work); diff --git a/drivers/media/platform/msm/vidc/vidc_hfi.h b/drivers/media/platform/msm/vidc/vidc_hfi.h index 6199c1516f080..073985edc97b8 100644 --- a/drivers/media/platform/msm/vidc/vidc_hfi.h +++ b/drivers/media/platform/msm/vidc/vidc_hfi.h @@ -86,6 +86,7 @@ #define HFI_EXTRADATA_STREAM_USERDATA 0x0000000E #define HFI_EXTRADATA_FRAME_QP 0x0000000F #define HFI_EXTRADATA_FRAME_BITS_INFO 0x00000010 +#define HFI_EXTRADATA_VPX_COLORSPACE 0x00000014 #define HFI_EXTRADATA_MULTISLICE_INFO 0x7F100000 #define HFI_EXTRADATA_NUM_CONCEALED_MB 0x7F100001 #define HFI_EXTRADATA_INDEX 0x7F100002 @@ -217,6 +218,14 @@ struct hfi_extradata_header { (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x019) #define HFI_PROPERTY_PARAM_VDEC_SCS_THRESHOLD \ (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x01A) +#define HFI_PROPERTY_PARAM_VUI_DISPLAY_INFO_EXTRADATA \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x01B) +#define HFI_PROPERTY_PARAM_VDEC_VPX_COLORSPACE_EXTRADATA \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x001D) +#define HFI_PROPERTY_PARAM_VDEC_MASTERING_DISPLAY_COLOUR_SEI_EXTRADATA \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x001E) +#define HFI_PROPERTY_PARAM_VDEC_CONTENT_LIGHT_LEVEL_SEI_EXTRADATA \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x001F) #define HFI_PROPERTY_CONFIG_VDEC_OX_START \ (HFI_DOMAIN_BASE_VDEC + HFI_ARCH_OX_OFFSET + 0x0000) diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h index c92e179ae6281..323c4380e59cb 100644 --- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h +++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -114,6 +114,10 @@ enum hal_extradata_id { HAL_EXTRADATA_DIGITAL_ZOOM, HAL_EXTRADATA_LTR_INFO, HAL_EXTRADATA_METADATA_MBI, + HAL_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI, + HAL_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI, + HAL_EXTRADATA_VUI_DISPLAY_INFO, + HAL_EXTRADATA_VPX_COLORSPACE, }; enum hal_property { @@ -216,6 +220,8 @@ enum hal_property { HAL_PARAM_VENC_HIER_B_MAX_ENH_LAYERS, HAL_PARAM_VDEC_NON_SECURE_OUTPUT2, HAL_PARAM_VENC_HIER_P_HYBRID_MODE, + HAL_PARAM_VENC_VIDEO_SIGNAL_INFO, + HAL_PARAM_VENC_CONSTRAINED_INTRA_PRED, }; enum hal_domain { @@ -946,6 +952,13 @@ struct hal_vpe_color_space_conversion { u32 csc_limit[HAL_MAX_LIMIT_COEFFS]; }; +struct hal_video_signal_info { + u32 color_space; + u32 transfer_chars; + u32 matrix_coeffs; + bool full_range; +}; + enum vidc_resource_id { VIDC_RESOURCE_OCMEM = 0x00000001, VIDC_UNUSED_RESORUCE = 0x10000000, diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h index e6b58a0986737..13ed39410a660 100644 --- a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h +++ b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -338,7 +338,7 @@ struct hfi_buffer_info { (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x01B) #define HFI_PROPERTY_PARAM_VENC_LTRMODE \ (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x01C) -#define HFI_PROPERTY_PARAM_VENC_VIDEO_FULL_RANGE \ +#define HFI_PROPERTY_PARAM_VENC_VIDEO_SIGNAL_INFO \ (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x01D) #define HFI_PROPERTY_PARAM_VENC_H264_VUI_TIMING_INFO \ (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x01E) @@ -358,6 +358,8 @@ struct hfi_buffer_info { (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x028) #define HFI_PROPERTY_PARAM_VENC_VPX_ERROR_RESILIENCE_MODE \ (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x029) +#define HFI_PROPERTY_PARAM_VENC_CONSTRAINED_INTRA_PRED \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x02B) #define HFI_PROPERTY_PARAM_VENC_HIER_B_MAX_NUM_ENH_LAYER \ (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x02C) #define HFI_PROPERTY_PARAM_VENC_HIER_P_HYBRID_MODE \ @@ -626,6 +628,16 @@ struct hfi_frame_size { u32 height; }; +struct hfi_video_signal_metadata { + u32 enable; + u32 video_format; + u32 video_full_range; + u32 color_description; + u32 color_primaries; + u32 transfer_characteristics; + u32 matrix_coeffs; +}; + struct hfi_h264_vui_timing_info { u32 enable; u32 fixed_frame_rate; diff --git a/drivers/mfd/wcd9xxx-slimslave.c b/drivers/mfd/wcd9xxx-slimslave.c index ac113e5f65a5b..4076e93a4b0c4 100644 --- a/drivers/mfd/wcd9xxx-slimslave.c +++ b/drivers/mfd/wcd9xxx-slimslave.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -266,7 +266,7 @@ int wcd9xxx_cfg_slim_sch_rx(struct wcd9xxx *wcd9xxx, list_for_each_entry(rx, wcd9xxx_ch_list, list) { codec_port = rx->port; - pr_debug("%s: codec_port %d rx 0x%p, payload %d\n" + pr_debug("%s: codec_port %d rx 0x%pK, payload %d\n" "sh_ch.rx_port_ch_reg_base0 0x%x\n" "sh_ch.port_rx_cfg_reg_base 0x%x\n", __func__, codec_port, rx, payload, @@ -373,7 +373,7 @@ int wcd9xxx_cfg_slim_sch_tx(struct wcd9xxx *wcd9xxx, pr_debug("%s: ch_cnt[%d] rate[%d]\n", __func__, ch_cnt, rate); list_for_each_entry(tx, wcd9xxx_ch_list, list) { codec_port = tx->port; - pr_debug("%s: codec_port %d tx 0x%p, payload 0x%x\n", + pr_debug("%s: codec_port %d tx 0x%pK, payload 0x%x\n", __func__, codec_port, tx, payload); /* write to interface device */ ret = wcd9xxx_interface_reg_write(wcd9xxx, @@ -595,7 +595,7 @@ int wcd9xxx_slim_ch_master_open(struct wcd9xxx *wcd9xxx, __func__, rate, bit_sz); if (wcd9xxx == NULL || handle == NULL) { - pr_err("%s: Invalid params, wcd9xxx(%p) handle(%p)\n", + pr_err("%s: Invalid params, wcd9xxx(%pK) handle(%pK)\n", __func__, wcd9xxx, handle); return -EINVAL; } @@ -658,12 +658,12 @@ int wcd9xxx_slim_ch_master_open(struct wcd9xxx *wcd9xxx, *handle = (struct wcd9xxx_master_cfg *)tx_master; tx_master->slim_s.handle = *handle; init_completion(&tx_master->slim_s.sb_comp); - pr_debug("%s: Handle %p slim_cfg->ph1 %x slim grp handle %x\n" + pr_debug("%s: Handle %pK slim_cfg->ph1 %x slim grp handle %x\n" "chanh %x\n", __func__, tx_master->slim_s.handle, tx_master->slim_cfg->ph1, tx_master->slim_cfg->grph, tx_master->slim_cfg->chanh); mutex_unlock(&tx_master->lock); - pr_debug("%s: Handle %p slim_cfg->ph1 %x slim grp\n" + pr_debug("%s: Handle %pK slim_cfg->ph1 %x slim grp\n" "handle %x chanh %x ref count %x\n", __func__, tx_master->slim_s.handle, tx_master->slim_cfg->ph1, @@ -687,14 +687,14 @@ int wcd9xxx_slim_ch_master_close(struct wcd9xxx *wcd9xxx, void **handle) struct wcd9xxx_slim_master_prop *slim_cfg; if (wcd9xxx == NULL || handle == NULL) { - pr_err("%s: Invalid params, wcd9xxx(%p) handle(%p)\n", + pr_err("%s: Invalid params, wcd9xxx(%pK) handle(%pK)\n", __func__, wcd9xxx, handle); return -EINVAL; } tx_master = &slim_tx_master; if (*handle != tx_master->slim_s.handle) { - pr_err("%s: handle(%p) not matching slim_hdl(%p)\n", + pr_err("%s: handle(%pK) not matching slim_hdl(%pK)\n", __func__, *handle, tx_master->slim_s.handle); return -EINVAL; } @@ -751,7 +751,7 @@ int wcd9xxx_slim_ch_master_status(struct wcd9xxx *wcd9xxx, void *handle, } tx_master = &slim_tx_master; if (handle != tx_master->slim_s.handle) { - pr_err("%s: handle(%p) not matching slim_hdl(%p)\n", + pr_err("%s: handle(%pK) not matching slim_hdl(%pK)\n", __func__, handle, tx_master->slim_s.handle); return -EINVAL; } @@ -775,17 +775,17 @@ int wcd9xxx_slim_ch_master_enable_read(struct wcd9xxx *wcd9xxx, void *handle) int rc = 0; struct wcd9xxx_master_cfg *tx_master; struct wcd9xxx_slim_master_prop *slim_cfg; - pr_debug("%s:handle = %p\n", __func__, handle); + pr_debug("%s:handle = %pK\n", __func__, handle); if (wcd9xxx == NULL || handle == NULL) { - pr_err("%s: Invalid params, wcd9xxx(%p) handle(%p)\n", + pr_err("%s: Invalid params, wcd9xxx(%pK) handle(%pK)\n", __func__, wcd9xxx, handle); return -EINVAL; } tx_master = &slim_tx_master; if (handle != tx_master->slim_s.handle) { - pr_err("%s: handle(%p) not matching slim_hdl(%p)\n", + pr_err("%s: handle(%pK) not matching slim_hdl(%pK)\n", __func__, handle, tx_master->slim_s.handle); return -EINVAL; } @@ -822,7 +822,7 @@ int wcd9xxx_slim_ch_master_read(struct wcd9xxx *wcd9xxx, void *handle, struct wcd9xxx_slim_master_prop *slim_cfg; struct completion *sb_comp; - pr_debug("%s: handle %p len %x\n", + pr_debug("%s: handle %pK len %x\n", __func__, handle, read_len); if (wcd9xxx == NULL || handle == NULL) { @@ -832,7 +832,7 @@ int wcd9xxx_slim_ch_master_read(struct wcd9xxx *wcd9xxx, void *handle, tx_master = &slim_tx_master; if (handle != tx_master->slim_s.handle) { - pr_err("%s: handle(%p) not matching slim_hdl(%p)\n", + pr_err("%s: handle(%pK) not matching slim_hdl(%pK)\n", __func__, handle, tx_master->slim_s.handle); return -EINVAL; } diff --git a/drivers/misc/qcom/qdsp6v2/aac_in.c b/drivers/misc/qcom/qdsp6v2/aac_in.c index fbbdff4d5b3ed..a5ad927345f60 100644 --- a/drivers/misc/qcom/qdsp6v2/aac_in.c +++ b/drivers/misc/qcom/qdsp6v2/aac_in.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2014,2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and diff --git a/drivers/misc/qcom/qdsp6v2/amrwb_in.c b/drivers/misc/qcom/qdsp6v2/amrwb_in.c index 71adbce0e257c..43dcbd597d7c4 100644 --- a/drivers/misc/qcom/qdsp6v2/amrwb_in.c +++ b/drivers/misc/qcom/qdsp6v2/amrwb_in.c @@ -1,4 +1,5 @@ -/* Copyright (c) 2011-2012, 2014 The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2012, 2014, 2016 The Linux Foundation. All rights + * reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -309,7 +310,7 @@ static int amrwb_in_open(struct inode *inode, struct file *file) (void *)audio); if (!audio->ac) { - pr_err("%s:audio[%p]: Could not allocate memory for audio" + pr_err("%s:audio[%pK]: Could not allocate memory for audio" "client\n", __func__, audio); kfree(audio->enc_cfg); kfree(audio); diff --git a/drivers/misc/qcom/qdsp6v2/audio_aac.c b/drivers/misc/qcom/qdsp6v2/audio_aac.c index 24e31e71fd2dd..245efb72d4294 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_aac.c +++ b/drivers/misc/qcom/qdsp6v2/audio_aac.c @@ -218,10 +218,10 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; } default: { - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_ioctl(file, cmd, arg); if (rc) - pr_err("%s[%p]:Failed in utils_ioctl: %d\n", + pr_err("%s[%pK]:Failed in utils_ioctl: %d\n", __func__, audio, rc); } } @@ -325,10 +325,10 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, break; } default: { - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_compat_ioctl(file, cmd, arg); if (rc) - pr_err("%s[%p]:Failed in utils_ioctl: %d\n", + pr_err("%s[%pK]:Failed in utils_ioctl: %d\n", __func__, audio, rc); } } diff --git a/drivers/misc/qcom/qdsp6v2/audio_alac.c b/drivers/misc/qcom/qdsp6v2/audio_alac.c index 94a1843040e64..239614115ab3a 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_alac.c +++ b/drivers/misc/qcom/qdsp6v2/audio_alac.c @@ -33,7 +33,8 @@ static long audio_ioctl_shared(struct file *file, unsigned int cmd, case AUDIO_START: { struct asm_alac_cfg alac_cfg; struct msm_audio_alac_config *alac_config; - pr_debug("%s[%p]: AUDIO_START session_id[%d]\n", __func__, + + pr_debug("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, audio, audio->ac->session); if (audio->feedback == NON_TUNNEL_MODE) { /* Configure PCM output block */ diff --git a/drivers/misc/qcom/qdsp6v2/audio_amrnb.c b/drivers/misc/qcom/qdsp6v2/audio_amrnb.c index 5d57293995902..26240ec410cd1 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_amrnb.c +++ b/drivers/misc/qcom/qdsp6v2/audio_amrnb.c @@ -30,7 +30,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) switch (cmd) { case AUDIO_START: { - pr_debug("%s[%p]: AUDIO_START session_id[%d]\n", __func__, + pr_debug("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, audio, audio->ac->session); if (audio->feedback == NON_TUNNEL_MODE) { /* Configure PCM output block */ @@ -59,7 +59,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; } default: - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_ioctl(file, cmd, arg); } return rc; diff --git a/drivers/misc/qcom/qdsp6v2/audio_amrwb.c b/drivers/misc/qcom/qdsp6v2/audio_amrwb.c index d2728b7c67001..9b5bca64e3c56 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_amrwb.c +++ b/drivers/misc/qcom/qdsp6v2/audio_amrwb.c @@ -31,7 +31,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) switch (cmd) { case AUDIO_START: { - pr_debug("%s[%p]: AUDIO_START session_id[%d]\n", __func__, + pr_debug("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, audio, audio->ac->session); if (audio->feedback == NON_TUNNEL_MODE) { /* Configure PCM output block */ @@ -62,7 +62,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; } default: - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_ioctl(file, cmd, arg); } return rc; diff --git a/drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c b/drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c index 9b57a879f6e2c..25b6239107a48 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c +++ b/drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c @@ -2,7 +2,7 @@ * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2010-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2014,2016, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -52,7 +52,7 @@ static long audio_ioctl_shared(struct file *file, unsigned int cmd, switch (cmd) { case AUDIO_START: { - pr_err("%s[%p]: AUDIO_START session_id[%d]\n", __func__, + pr_err("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, audio, audio->ac->session); if (audio->feedback == NON_TUNNEL_MODE) { /* Configure PCM output block */ @@ -159,7 +159,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, break; } default: { - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_ioctl(file, cmd, arg); break; } @@ -275,7 +275,7 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, break; } default: { - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_compat_ioctl(file, cmd, arg); break; } diff --git a/drivers/misc/qcom/qdsp6v2/audio_ape.c b/drivers/misc/qcom/qdsp6v2/audio_ape.c index ab3ddb58388f3..c98c3260c58c1 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_ape.c +++ b/drivers/misc/qcom/qdsp6v2/audio_ape.c @@ -36,7 +36,7 @@ static long audio_ioctl_shared(struct file *file, unsigned int cmd, case AUDIO_START: { struct asm_ape_cfg ape_cfg; struct msm_audio_ape_config *ape_config; - pr_debug("%s[%p]: AUDIO_START session_id[%d]\n", __func__, + pr_debug("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, audio, audio->ac->session); if (audio->feedback == NON_TUNNEL_MODE) { /* Configure PCM output block */ @@ -130,7 +130,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; } default: { - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_ioctl(file, cmd, arg); if (rc) pr_err("Failed in utils_ioctl: %d\n", rc); @@ -228,7 +228,7 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, break; } default: { - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_compat_ioctl(file, cmd, arg); if (rc) pr_err("Failed in utils_ioctl: %d\n", rc); diff --git a/drivers/misc/qcom/qdsp6v2/audio_evrc.c b/drivers/misc/qcom/qdsp6v2/audio_evrc.c index 2de2178936a4a..83c260012984c 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_evrc.c +++ b/drivers/misc/qcom/qdsp6v2/audio_evrc.c @@ -33,7 +33,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) switch (cmd) { case AUDIO_START: { - pr_debug("%s[%p]: AUDIO_START session_id[%d]\n", __func__, + pr_debug("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, audio, audio->ac->session); if (audio->feedback == NON_TUNNEL_MODE) { /* Configure PCM output block */ @@ -64,7 +64,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; } default: - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_ioctl(file, cmd, arg); } return rc; diff --git a/drivers/misc/qcom/qdsp6v2/audio_mp3.c b/drivers/misc/qcom/qdsp6v2/audio_mp3.c index 9132486ef6cec..1105ed4ba3d62 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_mp3.c +++ b/drivers/misc/qcom/qdsp6v2/audio_mp3.c @@ -30,7 +30,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) int rc = 0; switch (cmd) { case AUDIO_START: { - pr_debug("%s[%p]: AUDIO_START session_id[%d]\n", __func__, + pr_debug("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, audio, audio->ac->session); if (audio->feedback == NON_TUNNEL_MODE) { /* Configure PCM output block */ @@ -66,7 +66,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; } default: - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_ioctl(file, cmd, arg); } return rc; diff --git a/drivers/misc/qcom/qdsp6v2/audio_multi_aac.c b/drivers/misc/qcom/qdsp6v2/audio_multi_aac.c index acf96f172c526..f4f669a043c95 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_multi_aac.c +++ b/drivers/misc/qcom/qdsp6v2/audio_multi_aac.c @@ -2,7 +2,7 @@ * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2014,2016, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and diff --git a/drivers/misc/qcom/qdsp6v2/audio_qcelp.c b/drivers/misc/qcom/qdsp6v2/audio_qcelp.c index acfcb654abe27..ec06083ba16f6 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_qcelp.c +++ b/drivers/misc/qcom/qdsp6v2/audio_qcelp.c @@ -33,7 +33,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) switch (cmd) { case AUDIO_START: { - pr_debug("%s[%p]: AUDIO_START session_id[%d]\n", __func__, + pr_debug("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, audio, audio->ac->session); if (audio->feedback == NON_TUNNEL_MODE) { /* Configure PCM output block */ @@ -64,7 +64,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; } default: - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_ioctl(file, cmd, arg); } return rc; diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils.c b/drivers/misc/qcom/qdsp6v2/audio_utils.c index 3dd58f2542353..4ce21a822cbe1 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_utils.c +++ b/drivers/misc/qcom/qdsp6v2/audio_utils.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2014, 2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -24,6 +24,15 @@ #include #include "audio_utils.h" +/* + * Define maximum buffer size. Below values are chosen considering the higher + * values used among all native drivers. + */ +#define MAX_FRAME_SIZE 1536 +#define MAX_FRAMES 5 +#define META_SIZE (sizeof(struct meta_out_dsp)) +#define MAX_BUFFER_SIZE (1 + ((MAX_FRAME_SIZE + META_SIZE) * MAX_FRAMES)) + static int audio_in_pause(struct q6audio_in *audio) { int rc; @@ -329,6 +338,10 @@ long audio_in_ioctl(struct file *file, rc = -EINVAL; break; } + if (cfg.buffer_size > MAX_BUFFER_SIZE) { + rc = -EINVAL; + break; + } audio->str_cfg.buffer_size = cfg.buffer_size; audio->str_cfg.buffer_count = cfg.buffer_count; if (audio->opened) { @@ -741,7 +754,7 @@ ssize_t audio_in_read(struct file *file, count -= bytes_to_copy; buf += bytes_to_copy; } else { - pr_err("%s:session id %d: short read data[%p] bytesavail[%d]bytesrequest[%zd]\n", + pr_err("%s:session id %d: short read data[%pK] bytesavail[%d]bytesrequest[%zd]\n", __func__, audio->ac->session, data, size, count); @@ -877,7 +890,7 @@ ssize_t audio_in_write(struct file *file, buf += xfer; } mutex_unlock(&audio->write_lock); - pr_debug("%s:session id %d: eos_condition 0x%x buf[0x%p] start[0x%p]\n", + pr_debug("%s:session id %d: eos_condition 0x%x buf[0x%pK] start[0x%pK]\n", __func__, audio->ac->session, nflags, buf, start); if (nflags & AUD_EOS_SET) { diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c index 80411116dedc1..49c0b9ab04cd6 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c +++ b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c @@ -1,6 +1,6 @@ /* Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2009-2014, 2016 The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -26,6 +26,7 @@ #include #include #include +#include #include "audio_utils_aio.h" #ifdef CONFIG_USE_DEV_CTRL_VOLUME #include @@ -83,7 +84,7 @@ int insert_eos_buf(struct q6audio_aio *audio, struct audio_aio_buffer_node *buf_node) { struct dec_meta_out *eos_buf = buf_node->kvaddr; - pr_debug("%s[%p]:insert_eos_buf\n", __func__, audio); + pr_debug("%s[%pK]:insert_eos_buf\n", __func__, audio); eos_buf->num_of_frames = 0xFFFFFFFF; eos_buf->meta_out_dsp[0].offset_to_frame = 0x0; eos_buf->meta_out_dsp[0].nflags = AUDIO_DEC_EOS_SET; @@ -131,14 +132,14 @@ static int audio_aio_ion_lookup_vaddr(struct q6audio_aio *audio, void *addr, } if (match_count > 1) { - pr_err("%s[%p]:multiple hits for vaddr %p, len %ld\n", + pr_err("%s[%pK]:multiple hits for vaddr %pK, len %ld\n", __func__, audio, addr, len); list_for_each_entry(region_elt, &audio->ion_region_queue, list) { if (addr >= region_elt->vaddr && addr < region_elt->vaddr + region_elt->len && addr + len <= region_elt->vaddr + region_elt->len) - pr_err("\t%s[%p]:%p, %ld --> %pa\n", + pr_err("\t%s[%pK]:%pK, %ld --> %pK\n", __func__, audio, region_elt->vaddr, region_elt->len, @@ -158,7 +159,7 @@ static phys_addr_t audio_aio_ion_fixup(struct q6audio_aio *audio, void *addr, ret = audio_aio_ion_lookup_vaddr(audio, addr, len, ®ion); if (ret) { - pr_err("%s[%p]:lookup (%p, %ld) failed\n", + pr_err("%s[%pK]:lookup (%pK, %ld) failed\n", __func__, audio, addr, len); return 0; } @@ -166,7 +167,7 @@ static phys_addr_t audio_aio_ion_fixup(struct q6audio_aio *audio, void *addr, region->ref_cnt++; else region->ref_cnt--; - pr_debug("%s[%p]:found region %p ref_cnt %d\n", + pr_debug("%s[%pK]:found region %pK ref_cnt %d\n", __func__, audio, region, region->ref_cnt); paddr = region->paddr + (addr - region->vaddr); /* provide kernel virtual address for accessing meta information */ @@ -179,26 +180,26 @@ static int audio_aio_pause(struct q6audio_aio *audio) { int rc = -EINVAL; - pr_debug("%s[%p], enabled = %d\n", __func__, audio, + pr_debug("%s[%pK], enabled = %d\n", __func__, audio, audio->enabled); if (audio->enabled) { rc = q6asm_cmd(audio->ac, CMD_PAUSE); if (rc < 0) - pr_err("%s[%p]: pause cmd failed rc=%d\n", + pr_err("%s[%pK]: pause cmd failed rc=%d\n", __func__, audio, rc); if (rc == 0) { /* Send suspend only if pause was successful */ rc = q6asm_cmd(audio->ac, CMD_SUSPEND); if (rc < 0) - pr_err("%s[%p]: suspend cmd failed rc=%d\n", + pr_err("%s[%pK]: suspend cmd failed rc=%d\n", __func__, audio, rc); } else - pr_err("%s[%p]: not sending suspend since pause failed\n", + pr_err("%s[%pK]: not sending suspend since pause failed\n", __func__, audio); } else - pr_err("%s[%p]: Driver not enabled\n", __func__, audio); + pr_err("%s[%pK]: Driver not enabled\n", __func__, audio); return rc; } @@ -212,7 +213,7 @@ static int audio_aio_flush(struct q6audio_aio *audio) if (!(audio->drv_status & ADRV_STATUS_PAUSE)) { rc = audio_aio_pause(audio); if (rc < 0) - pr_err("%s[%p}: pause cmd failed rc=%d\n", + pr_err("%s[%pK}: pause cmd failed rc=%d\n", __func__, audio, rc); else @@ -220,13 +221,13 @@ static int audio_aio_flush(struct q6audio_aio *audio) } rc = q6asm_cmd(audio->ac, CMD_FLUSH); if (rc < 0) - pr_err("%s[%p]: flush cmd failed rc=%d\n", + pr_err("%s[%pK]: flush cmd failed rc=%d\n", __func__, audio, rc); /* Not in stop state, reenable the stream */ if (audio->stopped == 0) { rc = audio_aio_enable(audio); if (rc) - pr_err("%s[%p]:audio re-enable failed\n", + pr_err("%s[%pK]:audio re-enable failed\n", __func__, audio); else { audio->enabled = 1; @@ -235,9 +236,9 @@ static int audio_aio_flush(struct q6audio_aio *audio) } } } - pr_debug("%s[%p]:in_bytes %d\n", + pr_debug("%s[%pK]:in_bytes %d\n", __func__, audio, atomic_read(&audio->in_bytes)); - pr_debug("%s[%p]:in_samples %d\n", + pr_debug("%s[%pK]:in_samples %d\n", __func__, audio, atomic_read(&audio->in_samples)); atomic_set(&audio->in_bytes, 0); atomic_set(&audio->in_samples, 0); @@ -250,7 +251,7 @@ static int audio_aio_outport_flush(struct q6audio_aio *audio) rc = q6asm_cmd(audio->ac, CMD_OUT_FLUSH); if (rc < 0) - pr_err("%s[%p}: output port flush cmd failed rc=%d\n", + pr_err("%s[%pK}: output port flush cmd failed rc=%d\n", __func__, audio, rc); return rc; } @@ -278,19 +279,19 @@ void audio_aio_async_write_ack(struct q6audio_aio *audio, uint32_t token, if (token == used_buf->token) { list_del(&used_buf->list); spin_unlock_irqrestore(&audio->dsp_lock, flags); - pr_debug("%s[%p]:consumed buffer\n", __func__, audio); + pr_debug("%s[%pK]:consumed buffer\n", __func__, audio); event_payload.aio_buf = used_buf->buf; audio_aio_post_event(audio, AUDIO_EVENT_WRITE_DONE, event_payload); kfree(used_buf); if (list_empty(&audio->out_queue) && (audio->drv_status & ADRV_STATUS_FSYNC)) { - pr_debug("%s[%p]: list is empty, reached EOS in Tunnel\n", + pr_debug("%s[%pK]: list is empty, reached EOS in Tunnel\n", __func__, audio); wake_up(&audio->write_wait); } } else { - pr_err("%s[%p]:expected=%lx ret=%x\n", + pr_err("%s[%pK]:expected=%lx ret=%x\n", __func__, audio, used_buf->token, token); spin_unlock_irqrestore(&audio->dsp_lock, flags); } @@ -304,13 +305,13 @@ void audio_aio_async_out_flush(struct q6audio_aio *audio) union msm_audio_event_payload payload; unsigned long flags; - pr_debug("%s[%p}\n", __func__, audio); + pr_debug("%s[%pK}\n", __func__, audio); /* EOS followed by flush, EOS response not guranteed, free EOS i/p buffer */ spin_lock_irqsave(&audio->dsp_lock, flags); if (audio->eos_flag && (audio->eos_write_payload.aio_buf.buf_addr)) { - pr_debug("%s[%p]: EOS followed by flush received,acknowledge"\ + pr_debug("%s[%pK]: EOS followed by flush received,acknowledge"\ " eos i/p buffer immediately\n", __func__, audio); audio_aio_post_event(audio, AUDIO_EVENT_WRITE_DONE, audio->eos_write_payload); @@ -324,7 +325,7 @@ void audio_aio_async_out_flush(struct q6audio_aio *audio) payload.aio_buf = buf_node->buf; audio_aio_post_event(audio, AUDIO_EVENT_WRITE_DONE, payload); kfree(buf_node); - pr_debug("%s[%p]: Propagate WRITE_DONE during flush\n", + pr_debug("%s[%pK]: Propagate WRITE_DONE during flush\n", __func__, audio); } } @@ -335,14 +336,14 @@ void audio_aio_async_in_flush(struct q6audio_aio *audio) struct list_head *ptr, *next; union msm_audio_event_payload payload; - pr_debug("%s[%p]\n", __func__, audio); + pr_debug("%s[%pK]\n", __func__, audio); list_for_each_safe(ptr, next, &audio->in_queue) { buf_node = list_entry(ptr, struct audio_aio_buffer_node, list); list_del(&buf_node->list); /* Forcefull send o/p eos buffer after flush, if no eos response * received by dsp even after sending eos command */ if ((audio->eos_rsp != 1) && audio->eos_flag) { - pr_debug("%s[%p]: send eos on o/p buffer during flush\n", + pr_debug("%s[%pK]: send eos on o/p buffer during flush\n", __func__, audio); payload.aio_buf = buf_node->buf; payload.aio_buf.data_len = @@ -355,7 +356,7 @@ void audio_aio_async_in_flush(struct q6audio_aio *audio) } audio_aio_post_event(audio, AUDIO_EVENT_READ_DONE, payload); kfree(buf_node); - pr_debug("%s[%p]: Propagate READ_DONE during flush\n", + pr_debug("%s[%pK]: Propagate READ_DONE during flush\n", __func__, audio); } } @@ -373,19 +374,19 @@ int audio_aio_disable(struct q6audio_aio *audio) if (audio->opened) { audio->enabled = 0; audio->opened = 0; - pr_debug("%s[%p]: inbytes[%d] insamples[%d]\n", __func__, + pr_debug("%s[%pK]: inbytes[%d] insamples[%d]\n", __func__, audio, atomic_read(&audio->in_bytes), atomic_read(&audio->in_samples)); /* Close the session */ rc = q6asm_cmd(audio->ac, CMD_CLOSE); if (rc < 0) - pr_err("%s[%p]:Failed to close the session rc=%d\n", + pr_err("%s[%pK]:Failed to close the session rc=%d\n", __func__, audio, rc); audio->stopped = 1; wake_up(&audio->write_wait); wake_up(&audio->cmd_wait); } - pr_debug("%s[%p]:enabled[%d]\n", __func__, audio, audio->enabled); + pr_debug("%s[%pK]:enabled[%d]\n", __func__, audio, audio->enabled); return rc; } @@ -434,16 +435,16 @@ static void audio_aio_unmap_ion_region(struct q6audio_aio *audio) struct list_head *ptr, *next; int rc = -EINVAL; - pr_debug("%s[%p]:\n", __func__, audio); + pr_debug("%s[%pK]:\n", __func__, audio); list_for_each_safe(ptr, next, &audio->ion_region_queue) { region = list_entry(ptr, struct audio_aio_ion_region, list); if (region != NULL) { - pr_debug("%s[%p]: phy_address = 0x%pa\n", + pr_debug("%s[%pK]: phy_address = 0x%pK\n", __func__, audio, ®ion->paddr); rc = q6asm_memory_unmap(audio->ac, region->paddr, IN); if (rc < 0) - pr_err("%s[%p]: memory unmap failed\n", + pr_err("%s[%pK]: memory unmap failed\n", __func__, audio); } } @@ -460,20 +461,20 @@ static void audio_aio_listner(u32 evt_id, union auddev_evt_data *evt_payload, switch (evt_id) { case AUDDEV_EVT_STREAM_VOL_CHG: audio->volume = evt_payload->session_vol; - pr_debug("%s[%p]: AUDDEV_EVT_STREAM_VOL_CHG, stream vol %d, enabled = %d\n", + pr_debug("%s[%pK]: AUDDEV_EVT_STREAM_VOL_CHG, stream vol %d, enabled = %d\n", __func__, audio, audio->volume, audio->enabled); if (audio->enabled == 1) { if (audio->ac) { rc = q6asm_set_volume(audio->ac, audio->volume); if (rc < 0) { - pr_err("%s[%p]: Send Volume command failed rc=%d\n", + pr_err("%s[%pK]: Send Volume command failed rc=%d\n", __func__, audio, rc); } } } break; default: - pr_err("%s[%p]:ERROR:wrong event\n", __func__, audio); + pr_err("%s[%pK]:ERROR:wrong event\n", __func__, audio); break; } } @@ -490,7 +491,7 @@ int register_volume_listener(struct q6audio_aio *audio) audio_aio_listner, (void *)audio); if (rc < 0) { - pr_err("%s[%p]: Event listener failed\n", __func__, audio); + pr_err("%s[%pK]: Event listener failed\n", __func__, audio); rc = -EACCES; } return rc; @@ -508,7 +509,7 @@ int enable_volume_ramp(struct q6audio_aio *audio) if (audio->ac == NULL) return -EINVAL; - pr_debug("%s[%p]\n", __func__, audio); + pr_debug("%s[%pK]\n", __func__, audio); softpause.enable = SOFT_PAUSE_ENABLE; softpause.period = SOFT_PAUSE_PERIOD; softpause.step = SOFT_PAUSE_STEP; @@ -568,8 +569,10 @@ int enable_volume_ramp(struct q6audio_aio *audio) int audio_aio_release(struct inode *inode, struct file *file) { struct q6audio_aio *audio = file->private_data; - pr_debug("%s[%p]\n", __func__, audio); + pr_debug("%s[%pK]\n", __func__, audio); mutex_lock(&audio->lock); + mutex_lock(&audio->read_lock); + mutex_lock(&audio->write_lock); audio->wflush = 1; if (audio->enabled) audio_aio_flush(audio); @@ -584,6 +587,8 @@ int audio_aio_release(struct inode *inode, struct file *file) wake_up(&audio->event_wait); audio_aio_reset_event_queue(audio); q6asm_audio_client_free(audio->ac); + mutex_unlock(&audio->write_lock); + mutex_unlock(&audio->read_lock); mutex_unlock(&audio->lock); mutex_destroy(&audio->lock); mutex_destroy(&audio->read_lock); @@ -613,56 +618,56 @@ int audio_aio_fsync(struct file *file, loff_t start, loff_t end, int datasync) audio->drv_status |= ADRV_STATUS_FSYNC; mutex_unlock(&audio->lock); - pr_debug("%s[%p]:\n", __func__, audio); + pr_debug("%s[%pK]:\n", __func__, audio); audio->eos_rsp = 0; - pr_debug("%s[%p]Wait for write done from DSP\n", __func__, audio); + pr_debug("%s[%pK]Wait for write done from DSP\n", __func__, audio); rc = wait_event_interruptible(audio->write_wait, (list_empty(&audio->out_queue)) || audio->wflush || audio->stopped); if (audio->stopped || audio->wflush) { - pr_debug("%s[%p]: Audio Flushed or Stopped,this is not EOS\n" + pr_debug("%s[%pK]: Audio Flushed or Stopped,this is not EOS\n" , __func__, audio); audio->wflush = 0; rc = -EBUSY; } if (rc < 0) { - pr_err("%s[%p]: wait event for list_empty failed, rc = %d\n", + pr_err("%s[%pK]: wait event for list_empty failed, rc = %d\n", __func__, audio, rc); goto done; } rc = q6asm_cmd(audio->ac, CMD_EOS); - pr_debug("%s[%p]: EOS cmd sent to DSP\n", __func__, audio); + pr_debug("%s[%pK]: EOS cmd sent to DSP\n", __func__, audio); if (rc < 0) - pr_err("%s[%p]: q6asm_cmd failed, rc = %d", + pr_err("%s[%pK]: q6asm_cmd failed, rc = %d", __func__, audio, rc); - pr_debug("%s[%p]: wait for RENDERED_EOS from DSP\n" + pr_debug("%s[%pK]: wait for RENDERED_EOS from DSP\n" , __func__, audio); rc = wait_event_interruptible(audio->write_wait, (audio->eos_rsp || audio->wflush || audio->stopped)); if (rc < 0) { - pr_err("%s[%p]: wait event for eos_rsp failed, rc = %d\n", + pr_err("%s[%pK]: wait event for eos_rsp failed, rc = %d\n", __func__, audio, rc); goto done; } if (audio->stopped || audio->wflush) { audio->wflush = 0; - pr_debug("%s[%p]: Audio Flushed or Stopped,this is not EOS\n" + pr_debug("%s[%pK]: Audio Flushed or Stopped,this is not EOS\n" , __func__, audio); rc = -EBUSY; } if (audio->eos_rsp == 1) - pr_debug("%s[%p]: EOS\n", __func__, audio); + pr_debug("%s[%pK]: EOS\n", __func__, audio); done: @@ -727,21 +732,21 @@ static long audio_aio_process_event_req_common(struct q6audio_aio *audio, usr_evt->event_payload = drv_evt->payload; list_add_tail(&drv_evt->list, &audio->free_event_queue); } else { - pr_err("%s[%p]:Unexpected path\n", __func__, audio); + pr_err("%s[%pK]:Unexpected path\n", __func__, audio); spin_unlock_irqrestore(&audio->event_queue_lock, flags); return -EPERM; } spin_unlock_irqrestore(&audio->event_queue_lock, flags); if (drv_evt->event_type == AUDIO_EVENT_WRITE_DONE) { - pr_debug("%s[%p]:posted AUDIO_EVENT_WRITE_DONE to user\n", + pr_debug("%s[%pK]:posted AUDIO_EVENT_WRITE_DONE to user\n", __func__, audio); mutex_lock(&audio->write_lock); audio_aio_ion_fixup(audio, drv_evt->payload.aio_buf.buf_addr, drv_evt->payload.aio_buf.buf_len, 0, 0); mutex_unlock(&audio->write_lock); } else if (drv_evt->event_type == AUDIO_EVENT_READ_DONE) { - pr_debug("%s[%p]:posted AUDIO_EVENT_READ_DONE to user\n", + pr_debug("%s[%pK]:posted AUDIO_EVENT_READ_DONE to user\n", __func__, audio); mutex_lock(&audio->read_lock); audio_aio_ion_fixup(audio, drv_evt->payload.aio_buf.buf_addr, @@ -753,7 +758,7 @@ static long audio_aio_process_event_req_common(struct q6audio_aio *audio, * Once EOS indicated */ if (audio->eos_rsp && !list_empty(&audio->in_queue)) { - pr_debug("%s[%p]:Send flush command to release read buffers"\ + pr_debug("%s[%pK]:Send flush command to release read buffers" " held up in DSP\n", __func__, audio); audio_aio_flush(audio); } @@ -894,7 +899,7 @@ static int audio_aio_ion_check(struct q6audio_aio *audio, list_for_each_entry(region_elt, &audio->ion_region_queue, list) { if (CONTAINS(region_elt, &t) || CONTAINS(&t, region_elt) || OVERLAPS(region_elt, &t)) { - pr_err("%s[%p]:region (vaddr %p len %ld) clashes with registered region (vaddr %p paddr %pa len %ld)\n", + pr_err("%s[%pK]:region (vaddr %pK len %ld) clashes with registered region (vaddr %pK paddr %pK len %ld)\n", __func__, audio, vaddr, len, region_elt->vaddr, ®ion_elt->paddr, region_elt->len); @@ -916,7 +921,7 @@ static int audio_aio_ion_add(struct q6audio_aio *audio, unsigned long ionflag; void *kvaddr = NULL; - pr_debug("%s[%p]:\n", __func__, audio); + pr_debug("%s[%pK]:\n", __func__, audio); region = kmalloc(sizeof(*region), GFP_KERNEL); if (!region) { @@ -945,14 +950,14 @@ static int audio_aio_ion_add(struct q6audio_aio *audio, region->kvaddr = kvaddr; region->len = len; region->ref_cnt = 0; - pr_debug("%s[%p]:add region paddr %pa vaddr %p, len %lu kvaddr %p\n", + pr_debug("%s[%pK]:add region paddr %pK vaddr %pK, len %lu kvaddr %pK\n", __func__, audio, ®ion->paddr, region->vaddr, region->len, region->kvaddr); list_add_tail(®ion->list, &audio->ion_region_queue); rc = q6asm_memory_map(audio->ac, paddr, IN, len, 1); if (rc < 0) { - pr_err("%s[%p]: memory map failed\n", __func__, audio); + pr_err("%s[%pK]: memory map failed\n", __func__, audio); goto mmap_error; } else { goto end; @@ -974,7 +979,7 @@ static int audio_aio_ion_remove(struct q6audio_aio *audio, struct list_head *ptr, *next; int rc = -EINVAL; - pr_debug("%s[%p]:info fd %d vaddr %p\n", + pr_debug("%s[%pK]:info fd %d vaddr %pK\n", __func__, audio, info->fd, info->vaddr); list_for_each_safe(ptr, next, &audio->ion_region_queue) { @@ -983,17 +988,17 @@ static int audio_aio_ion_remove(struct q6audio_aio *audio, if ((region->fd == info->fd) && (region->vaddr == info->vaddr)) { if (region->ref_cnt) { - pr_debug("%s[%p]:region %p in use ref_cnt %d\n", + pr_debug("%s[%pK]:region %pK in use ref_cnt %d\n", __func__, audio, region, region->ref_cnt); break; } - pr_debug("%s[%p]:remove region fd %d vaddr %p\n", + pr_debug("%s[%pK]:remove region fd %d vaddr %pK\n", __func__, audio, info->fd, info->vaddr); rc = q6asm_memory_unmap(audio->ac, (uint32_t) region->paddr, IN); if (rc < 0) - pr_err("%s[%p]: memory unmap failed\n", + pr_err("%s[%pK]: memory unmap failed\n", __func__, audio); list_del(®ion->list); @@ -1016,15 +1021,15 @@ static void audio_aio_async_write(struct q6audio_aio *audio, struct audio_aio_write_param param; if (!audio || !buf_node) { - pr_err("%s NULL pointer audio=[0x%p], buf_node=[0x%p]\n", + pr_err("%s NULL pointer audio=[0x%pK], buf_node=[0x%pK]\n", __func__, audio, buf_node); return; } - pr_debug("%s[%p]: Send write buff %p phy %pa len %d meta_enable = %d\n", + pr_debug("%s[%pK]: Send write buff %pK phy %pK len %d meta_enable = %d\n", __func__, audio, buf_node, &buf_node->paddr, buf_node->buf.data_len, audio->buf_cfg.meta_info_enable); - pr_debug("%s[%p]: flags = 0x%x\n", __func__, audio, + pr_debug("%s[%pK]: flags = 0x%x\n", __func__, audio, buf_node->meta_info.meta_in.nflags); ac = audio->ac; @@ -1053,7 +1058,7 @@ static void audio_aio_async_write(struct q6audio_aio *audio, buf_node->token = ac->session; rc = q6asm_async_write(ac, ¶m); if (rc < 0) - pr_err("%s[%p]:failed\n", __func__, audio); + pr_err("%s[%pK]:failed\n", __func__, audio); } void audio_aio_post_event(struct q6audio_aio *audio, int type, @@ -1071,7 +1076,7 @@ void audio_aio_post_event(struct q6audio_aio *audio, int type, } else { e_node = kmalloc(sizeof(struct audio_aio_event), GFP_ATOMIC); if (!e_node) { - pr_err("%s[%p]:No mem to post event %d\n", + pr_err("%s[%pK]:No mem to post event %d\n", __func__, audio, type); spin_unlock_irqrestore(&audio->event_queue_lock, flags); return; @@ -1093,7 +1098,7 @@ static void audio_aio_async_read(struct q6audio_aio *audio, struct audio_aio_read_param param; int rc; - pr_debug("%s[%p]: Send read buff %p phy %pa len %d\n", + pr_debug("%s[%pK]: Send read buff %pK phy %pK len %d\n", __func__, audio, buf_node, &buf_node->paddr, buf_node->buf.buf_len); ac = audio->ac; @@ -1107,15 +1112,14 @@ static void audio_aio_async_read(struct q6audio_aio *audio, buf_node->token = param.paddr; rc = q6asm_async_read(ac, ¶m); if (rc < 0) - pr_err("%s[%p]:failed\n", __func__, audio); + pr_err("%s[%pK]:failed\n", __func__, audio); } static int audio_aio_buf_add_shared(struct q6audio_aio *audio, u32 dir, struct audio_aio_buffer_node *buf_node) { unsigned long flags; - - pr_debug("%s[%p]:node %p dir %x buf_addr %p buf_len %d data_len %d\n", + pr_debug("%s[%pK]:node %pK dir %x buf_addr %pK buf_len %d data_len %d\n", __func__, audio, buf_node, dir, buf_node->buf.buf_addr, buf_node->buf.buf_len, buf_node->buf.data_len); buf_node->paddr = audio_aio_ion_fixup(audio, buf_node->buf.buf_addr, @@ -1140,7 +1144,7 @@ static int audio_aio_buf_add_shared(struct q6audio_aio *audio, u32 dir, } else if (buf_node->meta_info.meta_in.nflags & AUDIO_DEC_EOS_SET) { if (!audio->wflush) { - pr_debug("%s[%p]:Send EOS cmd at i/p\n", + pr_debug("%s[%pK]:Send EOS cmd at i/p\n", __func__, audio); /* Driver will forcefully post writedone event * once eos ack recived from DSP @@ -1186,7 +1190,7 @@ static int audio_aio_buf_add_shared(struct q6audio_aio *audio, u32 dir, event_payload.aio_buf = buf_node->buf; event_payload.aio_buf.data_len = insert_eos_buf(audio, buf_node); - pr_debug("%s[%p]: propagate READ_DONE as EOS done\n",\ + pr_debug("%s[%pK]: propagate READ_DONE as EOS done\n", __func__, audio); audio_aio_post_event(audio, AUDIO_EVENT_READ_DONE, event_payload); @@ -1255,7 +1259,8 @@ void audio_aio_ioport_reset(struct q6audio_aio *audio) * abort due to flush */ if (audio->drv_status & ADRV_STATUS_FSYNC) { - pr_debug("%s[%p]:fsync in progress\n", __func__, audio); + pr_debug("%s[%pK]:fsync in progress\n", + __func__, audio); audio->drv_ops.out_flush(audio); } else audio->drv_ops.out_flush(audio); @@ -1282,13 +1287,13 @@ int audio_aio_open(struct q6audio_aio *audio, struct file *file) /* Only AIO interface */ if (file->f_flags & O_NONBLOCK) { - pr_debug("%s[%p]:set to aio interface\n", __func__, audio); + pr_debug("%s[%pK]:set to aio interface\n", __func__, audio); audio->drv_status |= ADRV_STATUS_AIO_INTF; audio->drv_ops.out_flush = audio_aio_async_out_flush; audio->drv_ops.in_flush = audio_aio_async_in_flush; q6asm_set_io_mode(audio->ac, ASYNC_IO_MODE); } else { - pr_err("%s[%p]:SIO interface not supported\n", + pr_err("%s[%pK]:SIO interface not supported\n", __func__, audio); rc = -EACCES; goto fail; @@ -1320,7 +1325,7 @@ int audio_aio_open(struct q6audio_aio *audio, struct file *file) if (e_node) list_add_tail(&e_node->list, &audio->free_event_queue); else { - pr_err("%s[%p]:event pkt alloc failed\n", + pr_err("%s[%pK]:event pkt alloc failed\n", __func__, audio); rc = -ENOMEM; goto cleanup; @@ -1332,7 +1337,7 @@ int audio_aio_open(struct q6audio_aio *audio, struct file *file) rc = -ENOMEM; goto cleanup; } - pr_debug("Ion client create in audio_aio_open %p", audio->client); + pr_debug("Ion client create in audio_aio_open %pK", audio->client); rc = register_volume_listener(audio); if (rc < 0) @@ -1366,11 +1371,11 @@ static long audio_aio_shared_ioctl(struct file *file, unsigned int cmd, break; } case AUDIO_OUTPORT_FLUSH: { - pr_debug("%s[%p]:AUDIO_OUTPORT_FLUSH\n", __func__, audio); + pr_debug("%s[%pK]:AUDIO_OUTPORT_FLUSH\n", __func__, audio); mutex_lock(&audio->read_lock); rc = audio_aio_outport_flush(audio); if (rc < 0) { - pr_err("%s[%p]: AUDIO_OUTPORT_FLUSH failed\n", + pr_err("%s[%pK]: AUDIO_OUTPORT_FLUSH failed\n", __func__, audio); rc = -EINTR; } @@ -1378,13 +1383,13 @@ static long audio_aio_shared_ioctl(struct file *file, unsigned int cmd, break; } case AUDIO_STOP: { - pr_debug("%s[%p]: AUDIO_STOP session_id[%d]\n", __func__, + pr_debug("%s[%pK]: AUDIO_STOP session_id[%d]\n", __func__, audio, audio->ac->session); mutex_lock(&audio->lock); audio->stopped = 1; rc = audio_aio_flush(audio); if (rc < 0) { - pr_err("%s[%p]:Audio Stop procedure failed rc=%d\n", + pr_err("%s[%pK]:Audio Stop procedure failed rc=%d\n", __func__, audio, rc); mutex_unlock(&audio->lock); break; @@ -1392,7 +1397,7 @@ static long audio_aio_shared_ioctl(struct file *file, unsigned int cmd, audio->enabled = 0; audio->drv_status &= ~ADRV_STATUS_PAUSE; if (audio->drv_status & ADRV_STATUS_FSYNC) { - pr_debug("%s[%p] Waking up the audio_aio_fsync\n", + pr_debug("%s[%pK] Waking up the audio_aio_fsync\n", __func__, audio); wake_up(&audio->write_wait); } @@ -1400,12 +1405,12 @@ static long audio_aio_shared_ioctl(struct file *file, unsigned int cmd, break; } case AUDIO_PAUSE: { - pr_debug("%s[%p]:AUDIO_PAUSE %ld\n", __func__, audio, arg); + pr_debug("%s[%pK]:AUDIO_PAUSE %ld\n", __func__, audio, arg); mutex_lock(&audio->lock); if (arg == 1) { rc = audio_aio_pause(audio); if (rc < 0) { - pr_err("%s[%p]: pause FAILED rc=%d\n", + pr_err("%s[%pK]: pause FAILED rc=%d\n", __func__, audio, rc); mutex_unlock(&audio->lock); break; @@ -1415,7 +1420,7 @@ static long audio_aio_shared_ioctl(struct file *file, unsigned int cmd, if (audio->drv_status & ADRV_STATUS_PAUSE) { rc = audio_aio_enable(audio); if (rc) - pr_err("%s[%p]: audio enable failed\n", + pr_err("%s[%pK]: audio enable failed\n", __func__, audio); else { audio->drv_status &= ~ADRV_STATUS_PAUSE; @@ -1427,13 +1432,13 @@ static long audio_aio_shared_ioctl(struct file *file, unsigned int cmd, break; } case AUDIO_FLUSH: { - pr_debug("%s[%p]: AUDIO_FLUSH sessionid[%d]\n", __func__, + pr_debug("%s[%pK]: AUDIO_FLUSH sessionid[%d]\n", __func__, audio, audio->ac->session); mutex_lock(&audio->lock); audio->rflush = 1; audio->wflush = 1; if (audio->drv_status & ADRV_STATUS_FSYNC) { - pr_debug("%s[%p] Waking up the audio_aio_fsync\n", + pr_debug("%s[%pK] Waking up the audio_aio_fsync\n", __func__, audio); wake_up(&audio->write_wait); } @@ -1442,7 +1447,7 @@ static long audio_aio_shared_ioctl(struct file *file, unsigned int cmd, /* Flush input / Output buffer in software*/ audio_aio_ioport_reset(audio); if (rc < 0) { - pr_err("%s[%p]:AUDIO_FLUSH interrupted\n", + pr_err("%s[%pK]:AUDIO_FLUSH interrupted\n", __func__, audio); rc = -EINTR; } else { @@ -1474,8 +1479,6 @@ static long audio_aio_shared_ioctl(struct file *file, unsigned int cmd, rc = -EINVAL; } return rc; - - } static long audio_aio_ioctl(struct file *file, unsigned int cmd, @@ -1499,7 +1502,27 @@ static long audio_aio_ioctl(struct file *file, unsigned int cmd, memset(&stats, 0, sizeof(struct msm_audio_stats)); stats.byte_count = atomic_read(&audio->in_bytes); stats.sample_count = atomic_read(&audio->in_samples); - rc = q6asm_get_session_time(audio->ac, ×tamp); + switch (q6core_get_avs_version()) { + case (Q6_SUBSYS_AVS2_7): + case (Q6_SUBSYS_AVS2_8): + { + rc = q6asm_get_session_time(audio->ac, ×tamp); + break; + } + case (Q6_SUBSYS_AVS2_6): + { + rc = q6asm_get_session_time_legacy(audio->ac, + ×tamp); + break; + } + case (Q6_SUBSYS_INVALID): + default: + { + pr_err("%s: UNKNOWN AVS IMAGE VERSION\n", __func__); + rc = -EINVAL; + break; + } + } if (rc >= 0) memcpy(&stats.unused[0], ×tamp, sizeof(timestamp)); else @@ -1512,7 +1535,7 @@ static long audio_aio_ioctl(struct file *file, unsigned int cmd, break; } case AUDIO_GET_EVENT: { - pr_debug("%s[%p]:AUDIO_GET_EVENT\n", __func__, audio); + pr_debug("%s[%pK]:AUDIO_GET_EVENT\n", __func__, audio); if (mutex_trylock(&audio->get_event_lock)) { rc = audio_aio_process_event_req(audio, (void __user *)arg); @@ -1552,7 +1575,7 @@ static long audio_aio_ioctl(struct file *file, unsigned int cmd, memset(&cfg, 0, sizeof(cfg)); cfg.buffer_size = audio->str_cfg.buffer_size; cfg.buffer_count = audio->str_cfg.buffer_count; - pr_debug("%s[%p]:GET STREAM CFG %d %d\n", + pr_debug("%s[%pK]:GET STREAM CFG %d %d\n", __func__, audio, cfg.buffer_size, cfg.buffer_count); if (copy_to_user((void *)arg, &cfg, sizeof(cfg))) { pr_err( @@ -1565,7 +1588,7 @@ static long audio_aio_ioctl(struct file *file, unsigned int cmd, } case AUDIO_SET_STREAM_CONFIG: { struct msm_audio_stream_config cfg; - pr_debug("%s[%p]:SET STREAM CONFIG\n", __func__, audio); + pr_debug("%s[%pK]:SET STREAM CONFIG\n", __func__, audio); mutex_lock(&audio->lock); if (copy_from_user(&cfg, (void *)arg, sizeof(cfg))) { pr_err( @@ -1595,7 +1618,7 @@ static long audio_aio_ioctl(struct file *file, unsigned int cmd, } case AUDIO_SET_CONFIG: { struct msm_audio_config config; - pr_err("%s[%p]:AUDIO_SET_CONFIG\n", __func__, audio); + pr_err("%s[%pK]:AUDIO_SET_CONFIG\n", __func__, audio); mutex_lock(&audio->lock); if (copy_from_user(&config, (void *)arg, sizeof(config))) { pr_err( @@ -1606,7 +1629,7 @@ static long audio_aio_ioctl(struct file *file, unsigned int cmd, break; } if (audio->feedback != NON_TUNNEL_MODE) { - pr_err("%s[%p]:Not sufficient permission to change the playback mode\n", + pr_err("%s[%pK]:Not sufficient permission to change the playback mode\n", __func__, audio); rc = -EACCES; mutex_unlock(&audio->lock); @@ -1646,14 +1669,14 @@ static long audio_aio_ioctl(struct file *file, unsigned int cmd, } audio->buf_cfg.meta_info_enable = cfg.meta_info_enable; - pr_debug("%s[%p]:session id %d: Set-buf-cfg: meta[%d]", + pr_debug("%s[%pK]:session id %d: Set-buf-cfg: meta[%d]", __func__, audio, audio->ac->session, cfg.meta_info_enable); mutex_unlock(&audio->lock); break; } case AUDIO_GET_BUF_CFG: { - pr_debug("%s[%p]:session id %d: Get-buf-cfg: meta[%d] framesperbuf[%d]\n", + pr_debug("%s[%pK]:session id %d: Get-buf-cfg: meta[%d] framesperbuf[%d]\n", __func__, audio, audio->ac->session, audio->buf_cfg.meta_info_enable, audio->buf_cfg.frames_per_buf); @@ -1671,7 +1694,7 @@ static long audio_aio_ioctl(struct file *file, unsigned int cmd, } case AUDIO_REGISTER_ION: { struct msm_audio_ion_info info; - pr_debug("%s[%p]:AUDIO_REGISTER_ION\n", __func__, audio); + pr_debug("%s[%pK]:AUDIO_REGISTER_ION\n", __func__, audio); mutex_lock(&audio->lock); if (copy_from_user(&info, (void *)arg, sizeof(info))) { pr_err( @@ -1679,7 +1702,11 @@ static long audio_aio_ioctl(struct file *file, unsigned int cmd, __func__); rc = -EFAULT; } else { + mutex_lock(&audio->read_lock); + mutex_lock(&audio->write_lock); rc = audio_aio_ion_add(audio, &info); + mutex_unlock(&audio->write_lock); + mutex_unlock(&audio->read_lock); } mutex_unlock(&audio->lock); break; @@ -1687,14 +1714,18 @@ static long audio_aio_ioctl(struct file *file, unsigned int cmd, case AUDIO_DEREGISTER_ION: { struct msm_audio_ion_info info; mutex_lock(&audio->lock); - pr_debug("%s[%p]:AUDIO_DEREGISTER_ION\n", __func__, audio); + pr_debug("%s[%pK]:AUDIO_DEREGISTER_ION\n", __func__, audio); if (copy_from_user(&info, (void *)arg, sizeof(info))) { pr_err( "%s: copy_from_user for AUDIO_DEREGISTER_ION failed\n", __func__); rc = -EFAULT; } else { + mutex_lock(&audio->read_lock); + mutex_lock(&audio->write_lock); rc = audio_aio_ion_remove(audio, &info); + mutex_unlock(&audio->write_lock); + mutex_unlock(&audio->read_lock); } mutex_unlock(&audio->lock); break; @@ -1787,7 +1818,27 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, memset(&stats, 0, sizeof(struct msm_audio_stats32)); stats.byte_count = atomic_read(&audio->in_bytes); stats.sample_count = atomic_read(&audio->in_samples); - rc = q6asm_get_session_time(audio->ac, ×tamp); + switch (q6core_get_avs_version()) { + case (Q6_SUBSYS_AVS2_7): + case (Q6_SUBSYS_AVS2_8): + { + rc = q6asm_get_session_time(audio->ac, ×tamp); + break; + } + case (Q6_SUBSYS_AVS2_6): + { + rc = q6asm_get_session_time_legacy(audio->ac, + ×tamp); + break; + } + case (Q6_SUBSYS_INVALID): + default: + { + pr_err("%s: UNKNOWN AVS IMAGE VERSION\n", __func__); + rc = -EINVAL; + break; + } + } if (rc >= 0) memcpy(&stats.unused[0], ×tamp, sizeof(timestamp)); else @@ -1801,7 +1852,7 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, break; } case AUDIO_GET_EVENT_32: { - pr_debug("%s[%p]:AUDIO_GET_EVENT\n", __func__, audio); + pr_debug("%s[%pK]:AUDIO_GET_EVENT\n", __func__, audio); if (mutex_trylock(&audio->get_event_lock)) { rc = audio_aio_process_event_req_compat(audio, (void __user *)arg); @@ -1841,7 +1892,7 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, memset(&cfg, 0, sizeof(cfg)); cfg.buffer_size = audio->str_cfg.buffer_size; cfg.buffer_count = audio->str_cfg.buffer_count; - pr_debug("%s[%p]:GET STREAM CFG %d %d\n", + pr_debug("%s[%pK]:GET STREAM CFG %d %d\n", __func__, audio, cfg.buffer_size, cfg.buffer_count); if (copy_to_user((void *)arg, &cfg, sizeof(cfg))) { pr_err("%s: copy_to_user for AUDIO_GET_STREAM_CONFIG_32 failed\n", @@ -1854,7 +1905,7 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, case AUDIO_SET_STREAM_CONFIG_32: { struct msm_audio_stream_config32 cfg_32; struct msm_audio_stream_config cfg; - pr_debug("%s[%p]:SET STREAM CONFIG\n", __func__, audio); + pr_debug("%s[%pK]:SET STREAM CONFIG\n", __func__, audio); mutex_lock(&audio->lock); if (copy_from_user(&cfg_32, (void *)arg, sizeof(cfg_32))) { pr_err("%s: copy_from_user for AUDIO_SET_STREAM_CONFIG_32 failed\n", @@ -1898,13 +1949,13 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, mutex_lock(&audio->lock); if (audio->feedback != NON_TUNNEL_MODE) { - pr_err("%s[%p]:Not sufficient permission to change the playback mode\n", + pr_err("%s[%pK]:Not sufficient permission to change the playback mode\n", __func__, audio); rc = -EACCES; mutex_unlock(&audio->lock); break; } - pr_err("%s[%p]:AUDIO_SET_CONFIG\n", __func__, audio); + pr_err("%s[%pK]:AUDIO_SET_CONFIG\n", __func__, audio); if (copy_from_user(&config_32, (void *)arg, sizeof(config_32))) { pr_err("%s: copy_from_user for AUDIO_SET_CONFIG_32 failed\n", @@ -1958,7 +2009,7 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, } audio->buf_cfg.meta_info_enable = cfg.meta_info_enable; - pr_debug("%s[%p]:session id %d: Set-buf-cfg: meta[%d]", + pr_debug("%s[%pK]:session id %d: Set-buf-cfg: meta[%d]", __func__, audio, audio->ac->session, cfg.meta_info_enable); mutex_unlock(&audio->lock); @@ -1966,7 +2017,7 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, } case AUDIO_GET_BUF_CFG_32: { struct msm_audio_buf_cfg32 cfg_32; - pr_debug("%s[%p]:session id %d: Get-buf-cfg: meta[%d] framesperbuf[%d]\n", + pr_debug("%s[%pK]:session id %d: Get-buf-cfg: meta[%d] framesperbuf[%d]\n", __func__, audio, audio->ac->session, audio->buf_cfg.meta_info_enable, audio->buf_cfg.frames_per_buf); @@ -1987,7 +2038,7 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, case AUDIO_REGISTER_ION_32: { struct msm_audio_ion_info32 info_32; struct msm_audio_ion_info info; - pr_debug("%s[%p]:AUDIO_REGISTER_ION\n", __func__, audio); + pr_debug("%s[%pK]:AUDIO_REGISTER_ION\n", __func__, audio); mutex_lock(&audio->lock); if (copy_from_user(&info_32, (void *)arg, sizeof(info_32))) { pr_err("%s: copy_from_user for AUDIO_REGISTER_ION_32 failed\n", @@ -1996,7 +2047,11 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, } else { info.fd = info_32.fd; info.vaddr = compat_ptr(info_32.vaddr); + mutex_lock(&audio->read_lock); + mutex_lock(&audio->write_lock); rc = audio_aio_ion_add(audio, &info); + mutex_unlock(&audio->write_lock); + mutex_unlock(&audio->read_lock); } mutex_unlock(&audio->lock); break; @@ -2005,7 +2060,7 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, struct msm_audio_ion_info32 info_32; struct msm_audio_ion_info info; mutex_lock(&audio->lock); - pr_debug("%s[%p]:AUDIO_DEREGISTER_ION\n", __func__, audio); + pr_debug("%s[%pK]:AUDIO_DEREGISTER_ION\n", __func__, audio); if (copy_from_user(&info_32, (void *)arg, sizeof(info_32))) { pr_err("%s: copy_from_user for AUDIO_DEREGISTER_ION_32 failed\n", __func__); @@ -2013,7 +2068,11 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, } else { info.fd = info_32.fd; info.vaddr = compat_ptr(info_32.vaddr); + mutex_lock(&audio->read_lock); + mutex_lock(&audio->write_lock); rc = audio_aio_ion_remove(audio, &info); + mutex_unlock(&audio->write_lock); + mutex_unlock(&audio->read_lock); } mutex_unlock(&audio->lock); break; diff --git a/drivers/misc/qcom/qdsp6v2/audio_wma.c b/drivers/misc/qcom/qdsp6v2/audio_wma.c index cb5a9b1c3157b..44c5ee733ed02 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_wma.c +++ b/drivers/misc/qcom/qdsp6v2/audio_wma.c @@ -37,7 +37,7 @@ static long audio_ioctl_shared(struct file *file, unsigned int cmd, case AUDIO_START: { struct asm_wma_cfg wma_cfg; struct msm_audio_wma_config_v2 *wma_config; - pr_debug("%s[%p]: AUDIO_START session_id[%d]\n", __func__, + pr_debug("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, audio, audio->ac->session); if (audio->feedback == NON_TUNNEL_MODE) { /* Configure PCM output block */ @@ -118,7 +118,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; } default: { - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_ioctl(file, cmd, arg); if (rc) pr_err("Failed in utils_ioctl: %d\n", rc); @@ -207,7 +207,7 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, break; } default: { - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_compat_ioctl(file, cmd, arg); if (rc) pr_err("Failed in utils_ioctl: %d\n", rc); diff --git a/drivers/misc/qcom/qdsp6v2/audio_wmapro.c b/drivers/misc/qcom/qdsp6v2/audio_wmapro.c index 57885b824f2af..b6dad9bae28f4 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_wmapro.c +++ b/drivers/misc/qcom/qdsp6v2/audio_wmapro.c @@ -2,7 +2,7 @@ * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2009-2014,2016, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -176,7 +176,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; } default: { - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_ioctl(file, cmd, arg); if (rc) pr_err("Failed in utils_ioctl: %d\n", rc); @@ -286,7 +286,7 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, break; } default: { - pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio); + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_compat_ioctl(file, cmd, arg); if (rc) pr_err("Failed in utils_ioctl: %d\n", rc); diff --git a/drivers/misc/qcom/qdsp6v2/evrc_in.c b/drivers/misc/qcom/qdsp6v2/evrc_in.c index 3b3aa0d20633f..d7d67dec46061 100644 --- a/drivers/misc/qcom/qdsp6v2/evrc_in.c +++ b/drivers/misc/qcom/qdsp6v2/evrc_in.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2014,2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and diff --git a/drivers/misc/qcom/qdsp6v2/q6audio_v2_aio.c b/drivers/misc/qcom/qdsp6v2/q6audio_v2_aio.c index d8ae60d392a6a..d688bd5deff83 100644 --- a/drivers/misc/qcom/qdsp6v2/q6audio_v2_aio.c +++ b/drivers/misc/qcom/qdsp6v2/q6audio_v2_aio.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -54,18 +54,18 @@ void audio_aio_cb(uint32_t opcode, uint32_t token, switch (opcode) { case ASM_DATA_EVENT_WRITE_DONE_V2: - pr_debug("%s[%p]:ASM_DATA_EVENT_WRITE_DONE token = 0x%x\n", + pr_debug("%s[%pK]:ASM_DATA_EVENT_WRITE_DONE token = 0x%x\n", __func__, audio, token); audio_aio_async_write_ack(audio, token, payload); break; case ASM_DATA_EVENT_READ_DONE_V2: - pr_debug("%s[%p]:ASM_DATA_EVENT_READ_DONE token = 0x%x\n", + pr_debug("%s[%pK]:ASM_DATA_EVENT_READ_DONE token = 0x%x\n", __func__, audio, token); audio_aio_async_read_ack(audio, token, payload); break; case ASM_DATA_EVENT_RENDERED_EOS: /* EOS Handle */ - pr_debug("%s[%p]:ASM_DATA_CMDRSP_EOS\n", __func__, audio); + pr_debug("%s[%pK]:ASM_DATA_CMDRSP_EOS\n", __func__, audio); if (audio->feedback) { /* Non-Tunnel mode */ audio->eos_rsp = 1; /* propagate input EOS i/p buffer, @@ -87,16 +87,16 @@ void audio_aio_cb(uint32_t opcode, uint32_t token, break; case ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2: case ASM_STREAM_CMD_SET_ENCDEC_PARAM: - pr_debug("%s[%p]:payload0[%x] payloa1d[%x]opcode= 0x%x\n", + pr_debug("%s[%pK]:payload0[%x] payloa1d[%x]opcode= 0x%x\n", __func__, audio, payload[0], payload[1], opcode); break; case ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY: case ASM_DATA_EVENT_ENC_SR_CM_CHANGE_NOTIFY: - pr_debug("%s[%p]: ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY, payload[0]-sr = %d, payload[1]-chl = %d, payload[2] = %d, payload[3] = %d\n", + pr_debug("%s[%pK]: ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY, payload[0]-sr = %d, payload[1]-chl = %d, payload[2] = %d, payload[3] = %d\n", __func__, audio, payload[0], payload[1], payload[2], payload[3]); - pr_debug("%s[%p]: ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY, sr(prev) = %d, chl(prev) = %d,", + pr_debug("%s[%pK]: ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY, sr(prev) = %d, chl(prev) = %d,", __func__, audio, audio->pcm_cfg.sample_rate, audio->pcm_cfg.channel_count); @@ -129,7 +129,7 @@ void extract_meta_out_info(struct q6audio_aio *audio, else memset(&buf_node->meta_info.meta_in, 0, sizeof(struct dec_meta_in)); - pr_debug("%s[%p]:i/p: msw_ts 0x%d lsw_ts 0x%d nflags 0x%8x\n", + pr_debug("%s[%pK]:i/p: msw_ts 0x%d lsw_ts 0x%d nflags 0x%8x\n", __func__, audio, buf_node->meta_info.meta_in.ntimestamp.highpart, buf_node->meta_info.meta_in.ntimestamp.lowpart, @@ -144,7 +144,7 @@ void extract_meta_out_info(struct q6audio_aio *audio, meta_data->meta_out_dsp[0].lsw_ts; meta_data->meta_out_dsp[0].lsw_ts = temp; - pr_debug("%s[%p]:o/p: msw_ts 0x%d lsw_ts 0x%d nflags 0x%8x, num_frames = %d\n", + pr_debug("%s[%pK]:o/p: msw_ts 0x%d lsw_ts 0x%d nflags 0x%8x, num_frames = %d\n", __func__, audio, ((struct dec_meta_out *)buf_node->kvaddr)->\ meta_out_dsp[0].msw_ts, @@ -200,7 +200,7 @@ void audio_aio_async_read_ack(struct q6audio_aio *audio, uint32_t token, = payload[9]; event_payload.aio_buf.data_len = payload[4]\ + payload[5] + sizeof(struct dec_meta_out); - pr_debug("%s[%p]:nr of frames 0x%8x len=%d\n", + pr_debug("%s[%pK]:nr of frames 0x%8x len=%d\n", __func__, audio, filled_buf->meta_info.meta_out.num_of_frames, event_payload.aio_buf.data_len); @@ -212,7 +212,7 @@ void audio_aio_async_read_ack(struct q6audio_aio *audio, uint32_t token, event_payload); kfree(filled_buf); } else { - pr_err("%s[%p]:expected=%lx ret=%x\n", + pr_err("%s[%pK]:expected=%lx ret=%x\n", __func__, audio, filled_buf->token, token); spin_unlock_irqrestore(&audio->dsp_lock, flags); } diff --git a/drivers/misc/qcom/qdsp6v2/qcelp_in.c b/drivers/misc/qcom/qdsp6v2/qcelp_in.c index 5a08c5d5f108e..d1a8a8e5bcf78 100644 --- a/drivers/misc/qcom/qdsp6v2/qcelp_in.c +++ b/drivers/misc/qcom/qdsp6v2/qcelp_in.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2014,2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and diff --git a/drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.c b/drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.c index cb8f37a54cd3c..c43d105365cff 100644 --- a/drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.c +++ b/drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.c @@ -207,7 +207,7 @@ static int q6usm_us_client_buf_free(unsigned int dir, rc = q6usm_memory_unmap(port->phys, dir, usc->session, *((uint32_t *)port->ext)); - pr_debug("%s: data[%p]phys[%llx][%p]\n", __func__, + pr_debug("%s: data[%pK]phys[%llx][%pK]\n", __func__, (void *)port->data, (u64)port->phys, (void *)&port->phys); msm_audio_ion_free(port->client, port->handle); @@ -247,7 +247,7 @@ int q6usm_us_param_buf_free(unsigned int dir, rc = q6usm_memory_unmap(port->param_phys, dir, usc->session, *((uint32_t *)port->param_buf_mem_handle)); - pr_debug("%s: data[%p]phys[%llx][%p]\n", __func__, + pr_debug("%s: data[%pK]phys[%llx][%pK]\n", __func__, (void *)port->param_buf, (u64)port->param_phys, (void *)&port->param_phys); @@ -361,7 +361,7 @@ struct us_client *q6usm_us_client_alloc( spin_lock_init(&usc->port[lcnt].dsp_lock); usc->port[lcnt].ext = (void *)p_mem_handle++; usc->port[lcnt].param_buf_mem_handle = (void *)p_mem_handle++; - pr_err("%s: usc->port[%d].ext=%p;\n", + pr_err("%s: usc->port[%d].ext=%pK;\n", __func__, lcnt, usc->port[lcnt].ext); } atomic_set(&usc->cmd_state, 0); @@ -416,7 +416,7 @@ int q6usm_us_client_buf_alloc(unsigned int dir, port->buf_cnt = bufcnt; port->buf_size = bufsz; - pr_debug("%s: data[%p]; phys[%llx]; [%p]\n", __func__, + pr_debug("%s: data[%pK]; phys[%llx]; [%pK]\n", __func__, (void *)port->data, (u64)port->phys, (void *)&port->phys); @@ -481,7 +481,7 @@ int q6usm_us_param_buf_alloc(unsigned int dir, } port->param_buf_size = bufsz; - pr_debug("%s: param_buf[%p]; param_phys[%llx]; [%p]\n", __func__, + pr_debug("%s: param_buf[%pK]; param_phys[%llx]; [%pK]\n", __func__, (void *)port->param_buf, (u64)port->param_phys, (void *)&port->param_phys); @@ -1334,7 +1334,7 @@ int q6usm_set_us_detection(struct us_client *usc, if ((usc == NULL) || (detect_info_size == 0) || (detect_info == NULL)) { - pr_err("%s: wrong input: usc=0x%p, inf_size=%d; info=0x%p", + pr_err("%s: wrong input: usc=0x%pK, inf_size=%d; info=0x%pK", __func__, usc, detect_info_size, diff --git a/drivers/misc/qcom/qdsp6v2/ultrasound/usfcdev.c b/drivers/misc/qcom/qdsp6v2/ultrasound/usfcdev.c index 76bcc83e1c5ec..a4d63f0c0d1ac 100644 --- a/drivers/misc/qcom/qdsp6v2/ultrasound/usfcdev.c +++ b/drivers/misc/qcom/qdsp6v2/ultrasound/usfcdev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2013, 2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -170,7 +170,7 @@ static int usfcdev_connect(struct input_handler *handler, struct input_dev *dev, } usfc_handle->dev = dev; ret = input_register_handle(usfc_handle); - pr_debug("%s: name=[%s]; ind=%d; dev=0x%p\n", + pr_debug("%s: name=[%s]; ind=%d; dev=0x%pK\n", __func__, dev->name, ind, @@ -259,7 +259,7 @@ bool usfcdev_register( bool rc = false; if ((event_type_ind >= MAX_EVENT_TYPE_NUM) || !match_cb) { - pr_err("%s: wrong input: event_type_ind=%d; match_cb=0x%p\n", + pr_err("%s: wrong input: event_type_ind=%d; match_cb=0x%pK\n", __func__, event_type_ind, match_cb); diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c index d41cee0773b0e..116818159dad8 100644 --- a/drivers/misc/qseecom.c +++ b/drivers/misc/qseecom.c @@ -1079,7 +1079,7 @@ static int qseecom_set_client_mem_param(struct qseecom_dev_handle *data, if ((req.ifd_data_fd <= 0) || (req.virt_sb_base == NULL) || (req.sb_len == 0)) { - pr_err("Inavlid input(s)ion_fd(%d), sb_len(%d), vaddr(0x%p)\n", + pr_err("Inavlid input(s)ion_fd(%d), sb_len(%d), vaddr(0x%pK)\n", req.ifd_data_fd, req.sb_len, req.virt_sb_base); return -EFAULT; } @@ -1646,7 +1646,7 @@ int __qseecom_process_rpmb_svc_cmd(struct qseecom_dev_handle *data_ptr, void *req_buf = NULL; if ((req_ptr == NULL) || (send_svc_ireq_ptr == NULL)) { - pr_err("Error with pointer: req_ptr = %p, send_svc_ptr = %p\n", + pr_err("Error with pointer: req_ptr = %pK, send_svc_ptr = %pK\n", req_ptr, send_svc_ireq_ptr); return -EINVAL; } @@ -1693,7 +1693,7 @@ int __qseecom_process_fsm_key_svc_cmd(struct qseecom_dev_handle *data_ptr, uint32_t reqd_len_sb_in = 0; if ((req_ptr == NULL) || (send_svc_ireq_ptr == NULL)) { - pr_err("Error with pointer: req_ptr = %p, send_svc_ptr = %p\n", + pr_err("Error with pointer: req_ptr = %pK, send_svc_ptr = %pK\n", req_ptr, send_svc_ireq_ptr); return -EINVAL; } @@ -3018,7 +3018,7 @@ int qseecom_send_command(struct qseecom_handle *handle, void *send_buf, if (ret) return ret; - pr_debug("sending cmd_req->rsp size: %u, ptr: 0x%p\n", + pr_debug("sending cmd_req->rsp size: %u, ptr: 0x%pK\n", req.resp_len, req.resp_buf); return ret; } @@ -4675,7 +4675,7 @@ long qseecom_ioctl(struct file *file, unsigned cmd, unsigned long arg) ret = -EINVAL; break; } - pr_debug("SET_MEM_PARAM: qseecom addr = 0x%p\n", data); + pr_debug("SET_MEM_PARAM: qseecom addr = 0x%pK\n", data); ret = qseecom_set_client_mem_param(data, argp); if (ret) pr_err("failed Qqseecom_set_mem_param request: %d\n", @@ -4691,7 +4691,7 @@ long qseecom_ioctl(struct file *file, unsigned cmd, unsigned long arg) break; } data->type = QSEECOM_CLIENT_APP; - pr_debug("LOAD_APP_REQ: qseecom_addr = 0x%p\n", data); + pr_debug("LOAD_APP_REQ: qseecom_addr = 0x%pK\n", data); mutex_lock(&app_access_lock); atomic_inc(&data->ioctl_count); if (qseecom.qsee_version > QSEEE_VERSION_00) { @@ -4717,7 +4717,7 @@ long qseecom_ioctl(struct file *file, unsigned cmd, unsigned long arg) ret = -EINVAL; break; } - pr_debug("UNLOAD_APP: qseecom_addr = 0x%p\n", data); + pr_debug("UNLOAD_APP: qseecom_addr = 0x%pK\n", data); mutex_lock(&app_access_lock); atomic_inc(&data->ioctl_count); ret = qseecom_unload_app(data, false); @@ -4848,7 +4848,7 @@ long qseecom_ioctl(struct file *file, unsigned cmd, unsigned long arg) data->type = QSEECOM_CLIENT_APP; mutex_lock(&app_access_lock); atomic_inc(&data->ioctl_count); - pr_debug("APP_LOAD_QUERY: qseecom_addr = 0x%p\n", data); + pr_debug("APP_LOAD_QUERY: qseecom_addr = 0x%pK\n", data); ret = qseecom_query_app_loaded(data, argp); atomic_dec(&data->ioctl_count); mutex_unlock(&app_access_lock); @@ -5101,7 +5101,7 @@ static int qseecom_release(struct inode *inode, struct file *file) int ret = 0; if (data->released == false) { - pr_debug("data: released=false, type=%d, mode=%d, data=0x%p\n", + pr_debug("data: released=false, type=%d, mode=%d, data=0x%pK\n", data->type, data->mode, data); switch (data->type) { case QSEECOM_LISTENER_SERVICE: diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index e7644edf6329f..c91b28e285612 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -734,6 +734,9 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, mmc_rpm_hold(card->host, &card->dev); mmc_claim_host(card->host); + if (mmc_card_get_bkops_en_manual(card)) + mmc_stop_bkops(card); + err = mmc_blk_part_switch(card, md); if (err) goto cmd_rel_host; @@ -876,6 +879,9 @@ static int mmc_blk_ioctl_rpmb_cmd(struct block_device *bdev, mmc_rpm_hold(card->host, &card->dev); mmc_claim_host(card->host); + if (mmc_card_get_bkops_en_manual(card)) + mmc_stop_bkops(card); + err = mmc_blk_part_switch(card, md); if (err) goto cmd_rel_host; @@ -1362,7 +1368,7 @@ static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req) from = blk_rq_pos(req); nr = blk_rq_sectors(req); - if (card->ext_csd.bkops_en) + if (mmc_card_get_bkops_en_manual(card)) card->bkops_info.sectors_changed += blk_rq_sectors(req); if (mmc_can_discard(card)) @@ -2316,7 +2322,7 @@ static u8 mmc_blk_prep_packed_list(struct mmc_queue *mq, struct request *req) if (rq_data_dir(next) == WRITE) { mq->num_of_potential_packed_wr_reqs++; - if (card->ext_csd.bkops_en) + if (mmc_card_get_bkops_en_manual(card)) card->bkops_info.sectors_changed += blk_rq_sectors(next); } @@ -2573,7 +2579,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) return 0; if (rqc) { - if ((card->ext_csd.bkops_en) && (rq_data_dir(rqc) == WRITE)) + if (mmc_card_get_bkops_en_manual(card) && + (rq_data_dir(rqc) == WRITE)) card->bkops_info.sectors_changed += blk_rq_sectors(rqc); reqs = mmc_blk_prep_packed_list(mq, rqc); } @@ -2788,7 +2795,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) if (mmc_bus_needs_resume(card->host)) mmc_resume_bus(card->host); #endif - if (card->ext_csd.bkops_en) + if (mmc_card_get_bkops_en_manual(card)) mmc_stop_bkops(card); } diff --git a/drivers/mmc/card/mmc_block_test.c b/drivers/mmc/card/mmc_block_test.c index 6f017aca429ef..7b05bf81422ba 100644 --- a/drivers/mmc/card/mmc_block_test.c +++ b/drivers/mmc/card/mmc_block_test.c @@ -1788,7 +1788,7 @@ static int prepare_bkops(struct test_data *td) bkops_stat = &card->bkops_info.bkops_stats; - if (!card->ext_csd.bkops_en) { + if (!(mmc_card_get_bkops_en_manual(card))) { pr_err("%s: BKOPS is not enabled by card or host)", __func__); return -ENOTSUPP; diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index bcccddd41d781..ad8f52371cc82 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -400,7 +400,9 @@ EXPORT_SYMBOL(mmc_blk_init_bkops_statistics); */ void mmc_start_delayed_bkops(struct mmc_card *card) { - if (!card || !card->ext_csd.bkops_en || mmc_card_doing_bkops(card)) + if (!card || + !(mmc_card_get_bkops_en_manual(card)) || + mmc_card_doing_bkops(card)) return; if (card->bkops_info.sectors_changed < @@ -437,7 +439,7 @@ void mmc_start_bkops(struct mmc_card *card, bool from_exception) int err; BUG_ON(!card); - if (!card->ext_csd.bkops_en) + if (!(mmc_card_get_bkops_en_manual(card))) return; if ((card->bkops_info.cancel_delayed_work) && !from_exception) { diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c index 69db61ca9b6fd..165c2f7b0af2f 100644 --- a/drivers/mmc/core/debugfs.c +++ b/drivers/mmc/core/debugfs.c @@ -19,6 +19,7 @@ #include #include +#include #include "core.h" #include "mmc_ops.h" @@ -725,7 +726,7 @@ void mmc_add_card_debugfs(struct mmc_card *card) goto err; if (mmc_card_mmc(card) && (card->ext_csd.rev >= 5) && - card->ext_csd.bkops_en) + (mmc_card_get_bkops_en_manual(card))) if (!debugfs_create_file("bkops_stats", S_IRUSR, root, card, &mmc_dbg_bkops_stats_fops)) goto err; diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 5416db4268e1f..3587f95b49b10 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -10,6 +10,7 @@ * published by the Free Software Foundation. */ +#include #include #include #include @@ -533,15 +534,19 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) card->ext_csd.bkops_en = ext_csd[EXT_CSD_BKOPS_EN]; card->ext_csd.raw_bkops_status = ext_csd[EXT_CSD_BKOPS_STATUS]; - if (!card->ext_csd.bkops_en && + if (!(mmc_card_get_bkops_en_manual(card)) && card->host->caps2 & MMC_CAP2_INIT_BKOPS) { - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_BKOPS_EN, 1, 0); - if (err) + mmc_card_set_bkops_en_manual(card); + err = mmc_switch(card, + EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_BKOPS_EN, + card->ext_csd.bkops_en , 0); + if (err) { pr_warn("%s: Enabling BKOPS failed\n", mmc_hostname(card->host)); - else - card->ext_csd.bkops_en = 1; + mmc_card_clr_bkops_en_manual(card); + } + } } @@ -1701,8 +1706,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, goto free_card; } } - - if (card->ext_csd.bkops_en) { + if (mmc_card_get_bkops_en_manual(card)) { INIT_DELAYED_WORK(&card->bkops_info.dw, mmc_start_idle_time_bkops); diff --git a/drivers/net/ethernet/msm/msm_rmnet_bam.c b/drivers/net/ethernet/msm/msm_rmnet_bam.c index 94e25db91ab75..5c05a003172d2 100644 --- a/drivers/net/ethernet/msm/msm_rmnet_bam.c +++ b/drivers/net/ethernet/msm/msm_rmnet_bam.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -358,21 +358,6 @@ static void bam_notify(void *dev, int event, unsigned long data) static int __rmnet_open(struct net_device *dev) { - int r; - struct rmnet_private *p = netdev_priv(dev); - - DBG0("[%s] __rmnet_open()\n", dev->name); - - if (p->device_up == DEVICE_UNINITIALIZED) { - r = msm_bam_dmux_open(p->ch_id, dev, bam_notify); - if (r < 0) { - DBG0("%s: ch=%d failed with rc %d\n", - __func__, p->ch_id, r); - return -ENODEV; - } - } - - p->device_up = DEVICE_ACTIVE; return 0; } @@ -382,10 +367,7 @@ static int rmnet_open(struct net_device *dev) DBG0("[%s] rmnet_open()\n", dev->name); - rc = __rmnet_open(dev); - - if (rc == 0) - netif_start_queue(dev); + netif_start_queue(dev); return rc; } @@ -838,6 +820,20 @@ static int bam_rmnet_probe(struct platform_device *pdev) rmnet_debug_init(dev); + DBG0("[%s] OPEN()\n", dev->name); + + if (p->device_up == DEVICE_UNINITIALIZED) { + ret = msm_bam_dmux_open(p->ch_id, dev, bam_notify); + if (ret < 0) { + DBG0("%s: ch=%d failed with rc %d\n", + __func__, p->ch_id, ret); + unregister_netdev(dev); + free_netdev(dev); + return -EPROBE_DEFER; + } + } + + p->device_up = DEVICE_ACTIVE; return 0; } diff --git a/drivers/nfc/nq-nci.c b/drivers/nfc/nq-nci.c index 99075945654f2..54a4ade8d4baa 100644 --- a/drivers/nfc/nq-nci.c +++ b/drivers/nfc/nq-nci.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -24,8 +24,7 @@ #include #include #include "nq-nci.h" -#include -#include +#include #ifdef CONFIG_COMPAT #include #endif @@ -35,6 +34,7 @@ struct nqx_platform_data { unsigned int en_gpio; unsigned int clkreq_gpio; unsigned int firm_gpio; + unsigned int ese_gpio; const char *clk_src_name; }; @@ -44,16 +44,8 @@ static struct of_device_id msm_match_table[] = { }; MODULE_DEVICE_TABLE(of, msm_match_table); + #define MAX_BUFFER_SIZE (320) -#define PACKET_MAX_LENGTH (258) -/* Read data */ -#define PACKET_HEADER_SIZE_NCIPACKET_HEADER_SIZE_NCI (4) -#define MAX_PACKET_SIZE (PACKET_HEADER_SIZE_NCI + 255) -/* will timeout in approx. 100ms as 10us steps */ -#define NTF_TIMEOUT (100) -#define CORE_RESET_RSP_GID (0x60) -#define CORE_RESET_OID (0x00) -#define CORE_RST_NTF_LENGTH (0x02) #define WAKEUP_SRC_TIMEOUT (2000) struct nqx_dev { @@ -61,25 +53,37 @@ struct nqx_dev { struct mutex read_mutex; struct i2c_client *client; struct miscdevice nqx_device; + /* NFC GPIO variables */ unsigned int irq_gpio; unsigned int en_gpio; unsigned int firm_gpio; unsigned int clkreq_gpio; + unsigned int ese_gpio; + /* NFC VEN pin state powered by Nfc */ + bool nfc_ven_enabled; /* NFC_IRQ state */ bool irq_enabled; + /* NFC_IRQ wake-up state */ + bool irq_wake_up; spinlock_t irq_enabled_lock; unsigned int count_irq; - /* CLK control */ + /* Initial CORE RESET notification */ unsigned int core_reset_ntf; + /* CLK control */ bool clk_run; - struct dma_pool *nfc_dma_pool; - dma_addr_t dma_handle_physical_addr; - void *dma_virtual_addr; + struct clk *s_clk; + /* read buffer*/ + size_t kbuflen; + u8 *kbuf; + struct nqx_platform_data *pdata; }; static int nfcc_reboot(struct notifier_block *notifier, unsigned long val, void *v); - +/*clock enable function*/ +static int nqx_clock_select(struct nqx_dev *nqx_dev); +/*clock disable function*/ +static int nqx_clock_deselect(struct nqx_dev *nqx_dev); static struct notifier_block nfcc_notifier = { .notifier_call = nfcc_reboot, .next = NULL, @@ -105,35 +109,15 @@ static void nqx_disable_irq(struct nqx_dev *nqx_dev) spin_unlock_irqrestore(&nqx_dev->irq_enabled_lock, flags); } -static void nqx_enable_irq(struct nqx_dev *nqx_dev) -{ - unsigned long flags; - - spin_lock_irqsave(&nqx_dev->irq_enabled_lock, flags); - if (!nqx_dev->irq_enabled) { - nqx_dev->irq_enabled = true; - enable_irq(nqx_dev->client->irq); - } - spin_unlock_irqrestore(&nqx_dev->irq_enabled_lock, flags); -} - static irqreturn_t nqx_dev_irq_handler(int irq, void *dev_id) { struct nqx_dev *nqx_dev = dev_id; unsigned long flags; - int ret; - if (device_may_wakeup(&nqx_dev->client->dev) && - (nqx_dev->client->dev.power.is_suspended == true)) { + if (device_may_wakeup(&nqx_dev->client->dev)) pm_wakeup_event(&nqx_dev->client->dev, WAKEUP_SRC_TIMEOUT); - } - ret = gpio_get_value_cansleep(nqx_dev->irq_gpio); - if (!ret) { - dev_info(&nqx_dev->client->dev, - "nqx nfc : nqx_dev_irq_handler error = %d\n", ret); - return IRQ_HANDLED; - } + nqx_disable_irq(nqx_dev); spin_lock_irqsave(&nqx_dev->irq_enabled_lock, flags); nqx_dev->count_irq++; spin_unlock_irqrestore(&nqx_dev->irq_enabled_lock, flags); @@ -150,15 +134,20 @@ static ssize_t nfc_read(struct file *filp, char __user *buf, int ret; int irq_gpio_val = 0; - if (count > MAX_BUFFER_SIZE) - count = MAX_BUFFER_SIZE; + if (!nqx_dev) { + ret = -ENODEV; + goto out; + } + + if (count > nqx_dev->kbuflen) + count = nqx_dev->kbuflen; dev_dbg(&nqx_dev->client->dev, "%s : reading %zu bytes.\n", __func__, count); mutex_lock(&nqx_dev->read_mutex); - irq_gpio_val = gpio_get_value_cansleep(nqx_dev->irq_gpio); + irq_gpio_val = gpio_get_value(nqx_dev->irq_gpio); if (irq_gpio_val == 0) { if (filp->f_flags & O_NONBLOCK) { dev_err(&nqx_dev->client->dev, @@ -166,46 +155,65 @@ static ssize_t nfc_read(struct file *filp, char __user *buf, ret = -EAGAIN; goto err; } - nqx_dev->irq_enabled = true; - enable_irq(nqx_dev->client->irq); - if (gpio_get_value_cansleep(nqx_dev->irq_gpio)) { - nqx_disable_irq(nqx_dev); - } else { - ret = wait_event_interruptible(nqx_dev->read_wq, - gpio_get_value(nqx_dev->irq_gpio)); - nqx_disable_irq(nqx_dev); + while (1) { + ret = 0; + if (!nqx_dev->irq_enabled) { + nqx_dev->irq_enabled = true; + enable_irq(nqx_dev->client->irq); + } + if (!gpio_get_value(nqx_dev->irq_gpio)) { + ret = wait_event_interruptible(nqx_dev->read_wq, + !nqx_dev->irq_enabled); + } if (ret) goto err; + nqx_disable_irq(nqx_dev); + + if (gpio_get_value(nqx_dev->irq_gpio)) + break; + dev_err_ratelimited(&nqx_dev->client->dev, "gpio is low, no need to read data\n"); } } + tmp = nqx_dev->kbuf; + if (!tmp) { + dev_err(&nqx_dev->client->dev, + "%s: device doesn't exist anymore\n", __func__); + ret = -ENODEV; + goto err; + } + memset(tmp, 0x00, count); + /* Read data */ - tmp = nqx_dev->dma_virtual_addr; - memset(tmp, 0x00, MAX_BUFFER_SIZE); ret = i2c_master_recv(nqx_dev->client, tmp, count); - - mutex_unlock(&nqx_dev->read_mutex); - if (ret < 0) { dev_err(&nqx_dev->client->dev, "%s: i2c_master_recv returned %d\n", __func__, ret); - return ret; + goto err; } if (ret > count) { dev_err(&nqx_dev->client->dev, "%s: received too many bytes from i2c (%d)\n", __func__, ret); - return -EIO; + ret = -EIO; + goto err; } +#ifdef NFC_KERNEL_BU + dev_dbg(&nqx_dev->client->dev, "%s : NfcNciRx %x %x %x\n", + __func__, tmp[0], tmp[1], tmp[2]); +#endif if (copy_to_user(buf, tmp, ret)) { dev_warn(&nqx_dev->client->dev, "%s : failed to copy to user space\n", __func__); - return -EFAULT; + ret = -EFAULT; + goto err; } + mutex_unlock(&nqx_dev->read_mutex); return ret; err: mutex_unlock(&nqx_dev->read_mutex); +out: return ret; } @@ -213,30 +221,106 @@ static ssize_t nfc_write(struct file *filp, const char __user *buf, size_t count, loff_t *offset) { struct nqx_dev *nqx_dev = filp->private_data; - char tmp[MAX_BUFFER_SIZE]; + char *tmp = NULL; int ret = 0; - if (count > MAX_BUFFER_SIZE) { + + if (!nqx_dev) { + ret = -ENODEV; + goto out; + } + if (count > nqx_dev->kbuflen) { dev_err(&nqx_dev->client->dev, "%s: out of memory\n", __func__); - return -ENOMEM; + ret = -ENOMEM; + goto out; } - if (copy_from_user(tmp, buf, count)) { - dev_err(&nqx_dev->client->dev, - "%s: failed to copy from user space\n", __func__); - return -EFAULT; + + tmp = memdup_user(buf, count); + if (IS_ERR(tmp)) { + dev_err(&nqx_dev->client->dev, "%s: memdup_user failed\n", + __func__); + ret = PTR_ERR(tmp); + goto out; } + ret = i2c_master_send(nqx_dev->client, tmp, count); if (ret != count) { dev_err(&nqx_dev->client->dev, "%s: failed to write %d\n", __func__, ret); ret = -EIO; + goto out_free; } - dev_dbg(&nqx_dev->client->dev, "%s : NfcNciTx %x %x %x\n", - __func__, tmp[0], tmp[1], tmp[2]); +#ifdef NFC_KERNEL_BU + dev_dbg(&nqx_dev->client->dev, + "%s : i2c-%d: NfcNciTx %x %x %x\n", + __func__, iminor(file_inode(filp)), + tmp[0], tmp[1], tmp[2]); +#endif usleep_range(1000, 1100); +out_free: + kfree(tmp); +out: return ret; } +/* + Power management of the eSE + NFC & eSE ON : NFC_EN high and eSE_pwr_req high. + NFC OFF & eSE ON : NFC_EN high and eSE_pwr_req high. + NFC OFF & eSE OFF : NFC_EN low and eSE_pwr_req low. +*/ +static int nqx_ese_pwr(struct nqx_dev *nqx_dev, unsigned long int arg) +{ + int r = -1; + + /* Let's store the NFC_EN pin state*/ + if (arg == 0) { + /* We want to power on the eSE and to do so we need the + * eSE_pwr_req pin and the NFC_EN pin to be high + */ + nqx_dev->nfc_ven_enabled = gpio_get_value(nqx_dev->en_gpio); + if (!nqx_dev->nfc_ven_enabled) { + gpio_set_value(nqx_dev->en_gpio, 1); + /* hardware dependent delay */ + usleep_range(1000, 1100); + } + if (gpio_is_valid(nqx_dev->ese_gpio)) { + if (gpio_get_value(nqx_dev->ese_gpio)) { + dev_dbg(&nqx_dev->client->dev, "ese_gpio is already high\n"); + r = 0; + } else { + gpio_set_value(nqx_dev->ese_gpio, 1); + if (gpio_get_value(nqx_dev->ese_gpio)) { + dev_dbg(&nqx_dev->client->dev, "ese_gpio is enabled\n"); + r = 0; + } + } + } + } else if (arg == 1) { + if (gpio_is_valid(nqx_dev->ese_gpio)) { + gpio_set_value(nqx_dev->ese_gpio, 0); + if (!gpio_get_value(nqx_dev->ese_gpio)) { + dev_dbg(&nqx_dev->client->dev, "ese_gpio is disabled\n"); + r = 0; + } + } + if (!nqx_dev->nfc_ven_enabled) { + /* hardware dependent delay */ + usleep_range(1000, 1100); + dev_dbg(&nqx_dev->client->dev, "disabling en_gpio\n"); + gpio_set_value(nqx_dev->en_gpio, 0); + } + } else if (arg == 3) { + if (!nqx_dev->nfc_ven_enabled) + r = 0; + else { + if (gpio_is_valid(nqx_dev->ese_gpio)) + r = gpio_get_value(nqx_dev->ese_gpio); + } + } + return r; +} + static int nfc_open(struct inode *inode, struct file *filp) { int ret = 0; @@ -245,30 +329,26 @@ static int nfc_open(struct inode *inode, struct file *filp) filp->private_data = nqx_dev; nqx_init_stat(nqx_dev); - /* Enable interrupts from NFCC NFC_INT new NCI data available */ - nqx_enable_irq(nqx_dev); dev_dbg(&nqx_dev->client->dev, "%s: %d,%d\n", __func__, imajor(inode), iminor(inode)); return ret; } -/* - * Inside nfc_ioctl_power_states +/** + * nfc_ioctl_power_states() - power control + * @filp: pointer to the file descriptor + * @arg: mode that we want to move to * - * @brief ioctl functions - * - * - * Device control - * remove control via ioctl + * Device power control. Depending on the arg value, device moves to + * different states * (arg = 0): NFC_ENABLE GPIO = 0, FW_DL GPIO = 0 * (arg = 1): NFC_ENABLE GPIO = 1, FW_DL GPIO = 0 * (arg = 2): FW_DL GPIO = 1 * - * + * Return: -ENOIOCTLCMD if arg is not supported, 0 in any other case */ -int nfc_ioctl_power_states(struct file *filp, unsigned int cmd, - unsigned long arg) +int nfc_ioctl_power_states(struct file *filp, unsigned long arg) { int r = 0; struct nqx_dev *nqx_dev = filp->private_data; @@ -284,7 +364,22 @@ int nfc_ioctl_power_states(struct file *filp, unsigned int cmd, __func__, nqx_dev); if (gpio_is_valid(nqx_dev->firm_gpio)) gpio_set_value(nqx_dev->firm_gpio, 0); - gpio_set_value(nqx_dev->en_gpio, 0); + + if (gpio_is_valid(nqx_dev->ese_gpio)) { + if (!gpio_get_value(nqx_dev->ese_gpio)) { + dev_dbg(&nqx_dev->client->dev, "disabling en_gpio\n"); + gpio_set_value(nqx_dev->en_gpio, 0); + } else { + dev_dbg(&nqx_dev->client->dev, "keeping en_gpio high\n"); + } + } else { + dev_dbg(&nqx_dev->client->dev, "ese_gpio invalid, set en_gpio to low\n"); + gpio_set_value(nqx_dev->en_gpio, 0); + } + r = nqx_clock_deselect(nqx_dev); + if (r < 0) + dev_err(&nqx_dev->client->dev, "unable to disable clock\n"); + nqx_dev->nfc_ven_enabled = false; /* hardware dependent delay */ msleep(100); } else if (arg == 1) { @@ -294,11 +389,21 @@ int nfc_ioctl_power_states(struct file *filp, unsigned int cmd, if (gpio_is_valid(nqx_dev->firm_gpio)) gpio_set_value(nqx_dev->firm_gpio, 0); gpio_set_value(nqx_dev->en_gpio, 1); - msleep(100); + r = nqx_clock_select(nqx_dev); + if (r < 0) + dev_err(&nqx_dev->client->dev, "unable to enable clock\n"); + nqx_dev->nfc_ven_enabled = true; + msleep(20); } else if (arg == 2) { /* We are switching to Dowload Mode, toggle the enable pin * in order to set the NFCC in the new mode */ + if (gpio_is_valid(nqx_dev->ese_gpio)) { + if (gpio_get_value(nqx_dev->ese_gpio)) { + dev_err(&nqx_dev->client->dev, "FW download forbidden while ese is on\n"); + return -EBUSY; /* Device or resource busy */ + } + } gpio_set_value(nqx_dev->en_gpio, 1); msleep(20); if (gpio_is_valid(nqx_dev->firm_gpio)) @@ -311,6 +416,7 @@ int nfc_ioctl_power_states(struct file *filp, unsigned int cmd, } else { r = -ENOIOCTLCMD; } + return r; } @@ -323,7 +429,13 @@ static long nfc_compat_ioctl(struct file *pfile, unsigned int cmd, switch (cmd) { case NFC_SET_PWR: - nfc_ioctl_power_states(pfile, cmd, arg); + nfc_ioctl_power_states(pfile, arg); + break; + case ESE_SET_PWR: + nqx_ese_pwr(pfile->private_data, arg); + break; + case ESE_GET_PWR: + nqx_ese_pwr(pfile->private_data, 3); break; case SET_RX_BLOCK: break; @@ -336,18 +448,15 @@ static long nfc_compat_ioctl(struct file *pfile, unsigned int cmd, } #endif -/* - * Inside nfc_ioctl_core_reset_ntf - * - * @brief nfc_ioctl_core_reset_ntf +/** + * nfc_ioctl_core_reset_ntf() + * @filp: pointer to the file descriptor * * Allows callers to determine if a CORE_RESET_NTF has arrived * - * Returns the value of variable core_reset_ntf - * + * Return: the value of variable core_reset_ntf */ -int nfc_ioctl_core_reset_ntf(struct file *filp, unsigned int cmd, - unsigned long arg) +int nfc_ioctl_core_reset_ntf(struct file *filp) { struct nqx_dev *nqx_dev = filp->private_data; dev_dbg(&nqx_dev->client->dev, "%s: returning = %d\n", __func__, @@ -362,16 +471,20 @@ static long nfc_ioctl(struct file *pfile, unsigned int cmd, switch (cmd) { case NFC_SET_PWR: - r = nfc_ioctl_power_states(pfile, cmd, arg); + r = nfc_ioctl_power_states(pfile, arg); break; - case NFC_CLK_REQ: + case ESE_SET_PWR: + r = nqx_ese_pwr(pfile->private_data, arg); + break; + case ESE_GET_PWR: + r = nqx_ese_pwr(pfile->private_data, 3); break; case SET_RX_BLOCK: break; case SET_EMULATOR_TEST_POINT: break; case NFCC_INITIAL_CORE_RESET_NTF: - r = nfc_ioctl_core_reset_ntf(pfile, cmd, arg); + r = nfc_ioctl_core_reset_ntf(pfile); break; default: r = -ENOIOCTLCMD; @@ -391,6 +504,103 @@ static const struct file_operations nfc_dev_fops = { #endif }; +/* Check for availability of NQ_ NFC controller hardware */ +static int nfcc_hw_check(struct i2c_client *client, unsigned int enable_gpio) +{ + int ret = 0; + + unsigned char raw_nci_reset_cmd[] = {0x20, 0x00, 0x01, 0x00}; + unsigned char nci_reset_rsp[6]; + + /* making sure that the NFCC starts in a clean state. */ + gpio_set_value(enable_gpio, 0);/* ULPM: Disable */ + /* hardware dependent delay */ + msleep(20); + gpio_set_value(enable_gpio, 1);/* HPD : Enable*/ + /* hardware dependent delay */ + msleep(20); + + /* send NCI CORE RESET CMD with Keep Config parameters */ + ret = i2c_master_send(client, raw_nci_reset_cmd, + sizeof(raw_nci_reset_cmd)); + if (ret < 0) { + dev_err(&client->dev, + "%s: - i2c_master_send Error\n", __func__); + goto err_nfcc_hw_check; + } + /* hardware dependent delay */ + msleep(30); + + /* Read Response of RESET command */ + ret = i2c_master_recv(client, nci_reset_rsp, + sizeof(nci_reset_rsp)); + dev_err(&client->dev, + "%s: - nq - reset cmd answer : NfcNciRx %x %x %x\n", + __func__, nci_reset_rsp[0], + nci_reset_rsp[1], nci_reset_rsp[2]); + if (ret < 0) { + dev_err(&client->dev, + "%s: - i2c_master_recv Error\n", __func__); + goto err_nfcc_hw_check; + } + gpio_set_value(enable_gpio, 0);/* ULPM: Disable */ + ret = 0; + goto done; + +err_nfcc_hw_check: + ret = -ENXIO; + dev_err(&client->dev, + "%s: - NFCC HW not available\n", __func__); +done: + return ret; +} + +/* + Routine to enable clock. + this routine can be extended to select from multiple + sources based on clk_src_name. +*/ +static int nqx_clock_select(struct nqx_dev *nqx_dev) +{ + int r = 0; + + nqx_dev->s_clk = + clk_get(&nqx_dev->client->dev, "ref_clk"); + + if (nqx_dev->s_clk == NULL) + goto err_clk; + + if (nqx_dev->clk_run == false) + r = clk_prepare_enable(nqx_dev->s_clk); + + if (r) + goto err_clk; + + nqx_dev->clk_run = true; + + return r; + +err_clk: + r = -1; + return r; +} +/* + Routine to disable clocks +*/ +static int nqx_clock_deselect(struct nqx_dev *nqx_dev) +{ + int r = -1; + + if (nqx_dev->s_clk != NULL) { + if (nqx_dev->clk_run == true) { + clk_disable_unprepare(nqx_dev->s_clk); + nqx_dev->clk_run = false; + } + return 0; + } + return r; +} + static int nfc_parse_dt(struct device *dev, struct nqx_platform_data *pdata) { int r = 0; @@ -412,6 +622,13 @@ static int nfc_parse_dt(struct device *dev, struct nqx_platform_data *pdata) pdata->firm_gpio = -EINVAL; } + pdata->ese_gpio = of_get_named_gpio(np, "qcom,nq-esepwr", 0); + if (!gpio_is_valid(pdata->ese_gpio)) { + dev_warn(dev, + "ese GPIO error getting from OF node\n"); + pdata->ese_gpio = -EINVAL; + } + r = of_property_read_string(np, "qcom,clk-src", &pdata->clk_src_name); pdata->clkreq_gpio = of_get_named_gpio(np, "qcom,nq-clkreq", 0); @@ -450,112 +667,86 @@ static int nqx_probe(struct i2c_client *client, platform_data = devm_kzalloc(&client->dev, sizeof(struct nqx_platform_data), GFP_KERNEL); if (!platform_data) { - dev_err(&client->dev, - "%s: Failed to allocate memory\n", __func__); - return -ENOMEM; + r = -ENOMEM; + goto err_platform_data; } r = nfc_parse_dt(&client->dev, platform_data); if (r) - return r; - } else { + goto err_free_data; + } else platform_data = client->dev.platform_data; - } + dev_dbg(&client->dev, "%s, inside nfc-nci flags = %x\n", __func__, client->flags); + if (platform_data == NULL) { dev_err(&client->dev, "%s: failed\n", __func__); - return -ENODEV; + r = -ENODEV; + goto err_platform_data; } if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { dev_err(&client->dev, "%s: need I2C_FUNC_I2C\n", __func__); - return -ENODEV; + r = -ENODEV; + goto err_free_data; } nqx_dev = kzalloc(sizeof(*nqx_dev), GFP_KERNEL); if (nqx_dev == NULL) { - dev_err(&client->dev, - "%s: failed to allocate memory for module data\n", __func__); - return -ENOMEM; + r = -ENOMEM; + goto err_free_data; } nqx_dev->client = client; - - /* if coherent_dma_mask not set by the device, set it to ULONG_MAX */ - if (client->dev.coherent_dma_mask == 0) - client->dev.coherent_dma_mask = ULONG_MAX; - - nqx_dev->nfc_dma_pool = NULL; - nqx_dev->dma_virtual_addr = NULL; - - nqx_dev->nfc_dma_pool = dma_pool_create( - "NFC-DMA", &client->dev, - MAX_BUFFER_SIZE, 64, 4096); - if (!nqx_dev->nfc_dma_pool) { - dev_err(&client->dev, - "nfc-nci probe: failed to allocate memory for dma_pool\n"); - r = -ENOMEM; - goto err_free_dev; - } - - nqx_dev->dma_virtual_addr = dma_pool_alloc( - nqx_dev->nfc_dma_pool, GFP_KERNEL, - &nqx_dev->dma_handle_physical_addr); - if (!nqx_dev->dma_virtual_addr) { - dev_err(&client->dev, - "nfc-nci probe: failed to allocate coherent memory for i2c dma buffer\n"); - r = -ENOMEM; - goto err_free_dev; - } + nqx_dev->kbuflen = MAX_BUFFER_SIZE; + nqx_dev->kbuf = kzalloc(MAX_BUFFER_SIZE, GFP_KERNEL); + if (!nqx_dev->kbuf) { + dev_err(&client->dev, + "failed to allocate memory for nqx_dev->kbuf\n"); + r = -ENOMEM; + goto err_free_dev; + } if (gpio_is_valid(platform_data->en_gpio)) { r = gpio_request(platform_data->en_gpio, "nfc_reset_gpio"); if (r) { dev_err(&client->dev, - "%s: unable to request gpio [%d]\n", + "%s: unable to request nfc reset gpio [%d]\n", __func__, platform_data->en_gpio); - goto err_free_dev; + goto err_mem; } r = gpio_direction_output(platform_data->en_gpio, 0); if (r) { dev_err(&client->dev, - "%s: unable to set direction for gpio [%d]\n", + "%s: unable to set direction for nfc reset gpio [%d]\n", __func__, platform_data->en_gpio); goto err_en_gpio; } } else { - dev_err(&client->dev, "%s: dis gpio not provided\n", __func__); - goto err_free_dev; - } - - /* Register reboot notifier here */ - r = register_reboot_notifier(&nfcc_notifier); - if (r) { dev_err(&client->dev, - "%s: cannot register reboot notifier(err = %d)\n", - __func__, r); - goto err_en_gpio; + "%s: nfc reset gpio not provided\n", __func__); + goto err_mem; } + if (gpio_is_valid(platform_data->irq_gpio)) { r = gpio_request(platform_data->irq_gpio, "nfc_irq_gpio"); if (r) { - dev_err(&client->dev, "%s: unable to request gpio [%d]\n", + dev_err(&client->dev, "%s: unable to request nfc irq gpio [%d]\n", __func__, platform_data->irq_gpio); goto err_en_gpio; } r = gpio_direction_input(platform_data->irq_gpio); if (r) { - dev_err(&client->dev, - "%s: unable to set direction for gpio [%d]\n", + "%s: unable to set direction for nfc irq gpio [%d]\n", __func__, platform_data->irq_gpio); - goto err_irq; + goto err_irq_gpio; } irqn = gpio_to_irq(platform_data->irq_gpio); if (irqn < 0) { r = irqn; - goto err_irq; + goto err_irq_gpio; } client->irq = irqn; } else { @@ -567,47 +758,79 @@ static int nqx_probe(struct i2c_client *client, "nfc_firm_gpio"); if (r) { dev_err(&client->dev, - "%s: unable to request gpio [%d]\n", + "%s: unable to request nfc firmware gpio [%d]\n", __func__, platform_data->firm_gpio); - goto err_irq; + goto err_irq_gpio; } r = gpio_direction_output(platform_data->firm_gpio, 0); if (r) { dev_err(&client->dev, - "%s: cannot set direction for gpio [%d]\n", + "%s: cannot set direction for nfc firmware gpio [%d]\n", __func__, platform_data->firm_gpio); - goto err_irq; + goto err_firm_gpio; } - nqx_dev->firm_gpio = platform_data->firm_gpio; } else { dev_err(&client->dev, "%s: firm gpio not provided\n", __func__); + goto err_irq_gpio; + } + if (gpio_is_valid(platform_data->ese_gpio)) { + r = gpio_request(platform_data->ese_gpio, + "nfc-ese_pwr"); + if (r) { + nqx_dev->ese_gpio = -EINVAL; + dev_err(&client->dev, + "%s: unable to request nfc ese gpio [%d]\n", + __func__, platform_data->ese_gpio); + /* ese gpio optional so we should continue */ + } else { + nqx_dev->ese_gpio = platform_data->ese_gpio; + r = gpio_direction_output(platform_data->ese_gpio, 0); + if (r) { + /* free ese gpio and set invalid + to avoid further use + */ + gpio_free(platform_data->ese_gpio); + nqx_dev->ese_gpio = -EINVAL; + dev_err(&client->dev, + "%s: cannot set direction for nfc ese gpio [%d]\n", + __func__, platform_data->ese_gpio); + /* ese gpio optional so we should continue */ + } + } + } else { + nqx_dev->ese_gpio = -EINVAL; + dev_err(&client->dev, + "%s: ese gpio not provided\n", __func__); + /* ese gpio optional so we should continue */ } if (gpio_is_valid(platform_data->clkreq_gpio)) { r = gpio_request(platform_data->clkreq_gpio, "nfc_clkreq_gpio"); if (r) { dev_err(&client->dev, - "%s: unable to request gpio [%d]\n", + "%s: unable to request nfc clkreq gpio [%d]\n", __func__, platform_data->clkreq_gpio); - goto err_clkreq_gpio; + goto err_ese_gpio; } r = gpio_direction_input(platform_data->clkreq_gpio); if (r) { dev_err(&client->dev, - "%s: cannot set direction for gpio [%d]\n", + "%s: cannot set direction for nfc clkreq gpio [%d]\n", __func__, platform_data->clkreq_gpio); goto err_clkreq_gpio; } - nqx_dev->clkreq_gpio = platform_data->clkreq_gpio; } else { dev_err(&client->dev, "%s: clkreq gpio not provided\n", __func__); + goto err_ese_gpio; } nqx_dev->en_gpio = platform_data->en_gpio; nqx_dev->irq_gpio = platform_data->irq_gpio; nqx_dev->firm_gpio = platform_data->firm_gpio; + nqx_dev->clkreq_gpio = platform_data->clkreq_gpio; + nqx_dev->pdata = platform_data; /* init mutex and queues */ init_waitqueue_head(&nqx_dev->read_wq); @@ -627,69 +850,147 @@ static int nqx_probe(struct i2c_client *client, /* NFC_INT IRQ */ nqx_dev->irq_enabled = true; r = request_irq(client->irq, nqx_dev_irq_handler, - IRQF_TRIGGER_RISING, client->name, nqx_dev); + IRQF_TRIGGER_HIGH, client->name, nqx_dev); if (r) { dev_err(&client->dev, "%s: request_irq failed\n", __func__); goto err_request_irq_failed; } nqx_disable_irq(nqx_dev); + /* + * To be efficient we need to test whether nfcc hardware is physically + * present before attempting further hardware initialisation. + * + */ + r = nfcc_hw_check(client , platform_data->en_gpio); + if (r) { + /* make sure NFCC is not enabled */ + gpio_set_value(platform_data->en_gpio, 0); + /* We don't think there is hardware switch NFC OFF */ + goto err_request_hw_check_failed; + } + + /* Register reboot notifier here */ + r = register_reboot_notifier(&nfcc_notifier); + if (r) { + dev_err(&client->dev, + "%s: cannot register reboot notifier(err = %d)\n", + __func__, r); + /* nfcc_hw_check function not doing memory + allocation so using same goto target here + */ + goto err_request_hw_check_failed; + } + +#ifdef NFC_KERNEL_BU + r = nqx_clock_select(nqx_dev); + if (r < 0) { + dev_err(&client->dev, + "%s: nqx_clock_select failed\n", __func__); + goto err_clock_en_failed; + } + gpio_set_value(platform_data->en_gpio, 1); +#endif device_init_wakeup(&client->dev, true); device_set_wakeup_capable(&client->dev, true); i2c_set_clientdata(client, nqx_dev); - gpio_set_value(platform_data->en_gpio, 1); + nqx_dev->irq_wake_up = false; - dev_dbg(&client->dev, - "%s: probing nq0 exited successfully\n", + dev_err(&client->dev, + "%s: probing NFCC NQxxx exited successfully\n", __func__); return 0; +#ifdef NFC_KERNEL_BU +err_clock_en_failed: + unregister_reboot_notifier(&nfcc_notifier); +#endif +err_request_hw_check_failed: + free_irq(client->irq, nqx_dev); err_request_irq_failed: misc_deregister(&nqx_dev->nqx_device); err_misc_register: mutex_destroy(&nqx_dev->read_mutex); err_clkreq_gpio: gpio_free(platform_data->clkreq_gpio); -err_irq: +err_ese_gpio: + /* optional gpio, not sure was configured in probe */ + if (nqx_dev->ese_gpio > 0) + gpio_free(platform_data->ese_gpio); +err_firm_gpio: + gpio_free(platform_data->firm_gpio); +err_irq_gpio: gpio_free(platform_data->irq_gpio); err_en_gpio: gpio_free(platform_data->en_gpio); +err_mem: + kfree(nqx_dev->kbuf); err_free_dev: kfree(nqx_dev); - +err_free_data: + if (client->dev.of_node) + devm_kfree(&client->dev, platform_data); +err_platform_data: + dev_err(&client->dev, + "%s: probing nqxx failed, check hardware\n", + __func__); return r; } static int nqx_remove(struct i2c_client *client) { + int ret = 0; struct nqx_dev *nqx_dev; nqx_dev = i2c_get_clientdata(client); + if (!nqx_dev) { + dev_err(&client->dev, + "%s: device doesn't exist anymore\n", __func__); + ret = -ENODEV; + goto err; + } + + unregister_reboot_notifier(&nfcc_notifier); free_irq(client->irq, nqx_dev); misc_deregister(&nqx_dev->nqx_device); mutex_destroy(&nqx_dev->read_mutex); + gpio_free(nqx_dev->clkreq_gpio); + /* optional gpio, not sure was configured in probe */ + if (nqx_dev->ese_gpio > 0) + gpio_free(nqx_dev->ese_gpio); + gpio_free(nqx_dev->firm_gpio); gpio_free(nqx_dev->irq_gpio); gpio_free(nqx_dev->en_gpio); + kfree(nqx_dev->kbuf); + if (client->dev.of_node) + devm_kfree(&client->dev, nqx_dev->pdata); kfree(nqx_dev); - return 0; +err: + return ret; } static int nqx_suspend(struct device *device) { struct i2c_client *client = to_i2c_client(device); + struct nqx_dev *nqx_dev = i2c_get_clientdata(client); - if (device_may_wakeup(&client->dev)) - enable_irq_wake(client->irq); + if (device_may_wakeup(&client->dev) && nqx_dev->irq_enabled) { + if (!enable_irq_wake(client->irq)) + nqx_dev->irq_wake_up = true; + } return 0; } static int nqx_resume(struct device *device) { struct i2c_client *client = to_i2c_client(device); + struct nqx_dev *nqx_dev = i2c_get_clientdata(client); - if (device_may_wakeup(&client->dev)) - disable_irq_wake(client->irq); + if (device_may_wakeup(&client->dev) && nqx_dev->irq_wake_up) { + if (!disable_irq_wake(client->irq)) + nqx_dev->irq_wake_up = false; + } return 0; } diff --git a/drivers/nfc/nq-nci.h b/drivers/nfc/nq-nci.h index ca8f20354d2a1..7656e9e8917ec 100644 --- a/drivers/nfc/nq-nci.h +++ b/drivers/nfc/nq-nci.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -10,8 +10,8 @@ * GNU General Public License for more details. */ -#ifndef __NFC_NCI_H -#define __NFC_NCI_H +#ifndef __NQ_NCI_H +#define __NQ_NCI_H #include #include @@ -23,14 +23,14 @@ #include #include -#define NFC_SET_PWR _IOW(0xE9, 0x01, unsigned int) -#define SET_RX_BLOCK _IOW(0xE9, 0x04, unsigned int) -#define NFC_CLK_REQ _IOW(0xE9, 0x02, unsigned int) +#define NFC_SET_PWR _IOW(0xE9, 0x01, unsigned int) +#define ESE_SET_PWR _IOW(0xE9, 0x02, unsigned int) +#define ESE_GET_PWR _IOR(0xE9, 0x03, unsigned int) +#define SET_RX_BLOCK _IOW(0xE9, 0x04, unsigned int) #define SET_EMULATOR_TEST_POINT _IOW(0xE9, 0x05, unsigned int) #define NFCC_INITIAL_CORE_RESET_NTF _IOW(0xE9, 0x10, unsigned int) #define NFC_RX_BUFFER_CNT_START (0x0) - #define PAYLOAD_HEADER_LENGTH (0x3) #define PAYLOAD_LENGTH_MAX (256) #define BYTE (0x8) diff --git a/drivers/platform/msm/ipa/ipa.c b/drivers/platform/msm/ipa/ipa.c index 63ba8dea11642..32be313772073 100644 --- a/drivers/platform/msm/ipa/ipa.c +++ b/drivers/platform/msm/ipa/ipa.c @@ -470,7 +470,8 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (unlikely(((struct ipa_ioc_add_rt_rule *)param)->num_rules != pre_entry)) { IPAERR("current %d pre %d\n", - ((struct ipa_ioc_add_rt_rule *)param)->num_rules, + ((struct ipa_ioc_add_rt_rule *)param)-> + num_rules, pre_entry); retval = -EFAULT; break; @@ -491,10 +492,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_mdfy_rt_rule *)header)->num_rules; pyld_sz = sizeof(struct ipa_ioc_mdfy_rt_rule) + - ((struct ipa_ioc_mdfy_rt_rule *)header)->num_rules * - sizeof(struct ipa_rt_rule_mdfy); + pre_entry * sizeof(struct ipa_rt_rule_mdfy); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -504,6 +506,16 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_mdfy_rt_rule *)param)->num_rules + != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_mdfy_rt_rule *)param)-> + num_rules, + pre_entry); + retval = -EFAULT; + break; + } if (ipa_mdfy_rt_rule((struct ipa_ioc_mdfy_rt_rule *)param)) { retval = -EFAULT; break; @@ -577,7 +589,8 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (unlikely(((struct ipa_ioc_add_flt_rule *)param)->num_rules != pre_entry)) { IPAERR("current %d pre %d\n", - ((struct ipa_ioc_add_flt_rule *)param)->num_rules, + ((struct ipa_ioc_add_flt_rule *)param)-> + num_rules, pre_entry); retval = -EFAULT; break; @@ -616,7 +629,8 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (unlikely(((struct ipa_ioc_del_flt_rule *)param)->num_hdls != pre_entry)) { IPAERR("current %d pre %d\n", - ((struct ipa_ioc_del_flt_rule *)param)->num_hdls, + ((struct ipa_ioc_del_flt_rule *)param)-> + num_hdls, pre_entry); retval = -EFAULT; break; @@ -637,10 +651,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_mdfy_flt_rule *)header)->num_rules; pyld_sz = sizeof(struct ipa_ioc_mdfy_flt_rule) + - ((struct ipa_ioc_mdfy_flt_rule *)header)->num_rules * - sizeof(struct ipa_flt_rule_mdfy); + pre_entry * sizeof(struct ipa_flt_rule_mdfy); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -650,6 +665,16 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_mdfy_flt_rule *)param)->num_rules + != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_mdfy_flt_rule *)param)-> + num_rules, + pre_entry); + retval = -EFAULT; + break; + } if (ipa_mdfy_flt_rule((struct ipa_ioc_mdfy_flt_rule *)param)) { retval = -EFAULT; break; @@ -851,9 +876,10 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - - pyld_sz = sz + ((struct ipa_ioc_query_intf_ext_props *) - header)->num_ext_props * + pre_entry = + ((struct ipa_ioc_query_intf_ext_props *) + header)->num_ext_props; + pyld_sz = sz + pre_entry * sizeof(struct ipa_ioc_ext_intf_prop); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { @@ -864,6 +890,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_query_intf_ext_props *) + param)->num_ext_props != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_query_intf_ext_props *) + param)->num_ext_props, pre_entry); + retval = -EFAULT; + break; + } if (ipa_query_intf_ext_props( (struct ipa_ioc_query_intf_ext_props *)param)) { retval = -1; @@ -1017,10 +1052,12 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_add_hdr_proc_ctx *) + header)->num_proc_ctxs; pyld_sz = sizeof(struct ipa_ioc_add_hdr_proc_ctx) + - ((struct ipa_ioc_add_hdr_proc_ctx *)header)->num_proc_ctxs * - sizeof(struct ipa_hdr_proc_ctx_add); + pre_entry * sizeof(struct ipa_hdr_proc_ctx_add); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -1030,6 +1067,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_add_hdr_proc_ctx *) + param)->num_proc_ctxs != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_add_hdr_proc_ctx *) + param)->num_proc_ctxs, pre_entry); + retval = -EFAULT; + break; + } if (ipa_add_hdr_proc_ctx( (struct ipa_ioc_add_hdr_proc_ctx *)param)) { retval = -EFAULT; @@ -1046,10 +1092,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_del_hdr_proc_ctx *)header)->num_hdls; pyld_sz = sizeof(struct ipa_ioc_del_hdr_proc_ctx) + - ((struct ipa_ioc_del_hdr_proc_ctx *)header)->num_hdls * - sizeof(struct ipa_hdr_proc_ctx_del); + pre_entry * sizeof(struct ipa_hdr_proc_ctx_del); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -1059,6 +1106,16 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_del_hdr_proc_ctx *) + param)->num_hdls != pre_entry)) { + IPAERR("current %d pre %d\n", + ((struct ipa_ioc_del_hdr_proc_ctx *)param)-> + num_hdls, + pre_entry); + retval = -EFAULT; + break; + } if (ipa_del_hdr_proc_ctx( (struct ipa_ioc_del_hdr_proc_ctx *)param)) { retval = -EFAULT; diff --git a/drivers/soc/qcom/jtag-fuse.c b/drivers/soc/qcom/jtag-fuse.c index 46de4e5f2026e..d7389f397b9ce 100644 --- a/drivers/soc/qcom/jtag-fuse.c +++ b/drivers/soc/qcom/jtag-fuse.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -152,8 +152,6 @@ static int jtag_fuse_probe(struct platform_device *pdev) drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; - /* Store the driver data pointer for use in exported functions */ - fusedrvdata = drvdata; drvdata->dev = &pdev->dev; platform_set_drvdata(pdev, drvdata); @@ -174,6 +172,8 @@ static int jtag_fuse_probe(struct platform_device *pdev) if (!drvdata->base) return -ENOMEM; + /* Store the driver data pointer for use in exported functions */ + fusedrvdata = drvdata; dev_info(dev, "JTag Fuse initialized\n"); return 0; } diff --git a/drivers/soc/qcom/qdsp6v2/apr.c b/drivers/soc/qcom/qdsp6v2/apr.c index f2d3260c263bd..3a904d3eee59d 100644 --- a/drivers/soc/qcom/qdsp6v2/apr.c +++ b/drivers/soc/qcom/qdsp6v2/apr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2014, 2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -398,7 +398,6 @@ struct apr_svc *apr_register(char *dest, char *svc_name, apr_fn svc_fn, pr_err("APR: Service needs reset\n"); goto done; } - svc->priv = priv; svc->id = svc_id; svc->dest_id = dest_id; svc->client_id = client_id; @@ -423,6 +422,7 @@ struct apr_svc *apr_register(char *dest, char *svc_name, apr_fn svc_fn, svc->fn = svc_fn; if (svc->port_cnt) svc->svc_cnt++; + svc->priv = priv; } } @@ -457,7 +457,7 @@ void apr_cb_func(void *buf, int len, void *priv) pr_debug("\n*****************\n"); if (!buf || len <= APR_HDR_SIZE) { - pr_err("APR: Improper apr pkt received:%p %d\n", buf, len); + pr_err("APR: Improper apr pkt received:%pK %d\n", buf, len); return; } hdr = buf; @@ -543,7 +543,7 @@ void apr_cb_func(void *buf, int len, void *priv) return; } pr_debug("svc_idx = %d\n", i); - pr_debug("%x %x %x %p %p\n", c_svc->id, c_svc->dest_id, + pr_debug("%x %x %x %pK %pK\n", c_svc->id, c_svc->dest_id, c_svc->client_id, c_svc->fn, c_svc->priv); data.payload_size = hdr->pkt_size - hdr_size; data.opcode = hdr->opcode; @@ -607,7 +607,7 @@ static void apr_reset_deregister(struct work_struct *work) container_of(work, struct apr_reset_work, work); handle = apr_reset->handle; - pr_debug("%s:handle[%p]\n", __func__, handle); + pr_debug("%s:handle[%pK]\n", __func__, handle); apr_deregister(handle); kfree(apr_reset); } @@ -640,7 +640,7 @@ int apr_deregister(void *handle) client[dest_id][client_id].svc_cnt--; if (!client[dest_id][client_id].svc_cnt) { svc->need_reset = 0x0; - pr_debug("%s: service is reset %p\n", __func__, svc); + pr_debug("%s: service is reset %pK\n", __func__, svc); } } @@ -668,7 +668,7 @@ void apr_reset(void *handle) if (!handle) return; - pr_debug("%s: handle[%p]\n", __func__, handle); + pr_debug("%s: handle[%pK]\n", __func__, handle); if (apr_reset_workqueue == NULL) { pr_err("%s: apr_reset_workqueue is NULL\n", __func__); diff --git a/drivers/soc/qcom/qdsp6v2/msm_audio_ion.c b/drivers/soc/qcom/qdsp6v2/msm_audio_ion.c index 52c97e4e60bd0..8921c581273bd 100644 --- a/drivers/soc/qcom/qdsp6v2/msm_audio_ion.c +++ b/drivers/soc/qcom/qdsp6v2/msm_audio_ion.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -103,11 +103,11 @@ int msm_audio_ion_alloc(const char *name, struct ion_client **client, pr_err("%s: ION memory mapping for AUDIO failed\n", __func__); goto err_ion_handle; } - pr_debug("%s: mapped address = %p, size=%zd\n", __func__, + pr_debug("%s: mapped address = %pK, size=%zd\n", __func__, *vaddr, bufsz); if (bufsz != 0) { - pr_debug("%s: memset to 0 %p %zd\n", __func__, *vaddr, bufsz); + pr_debug("%s: memset to 0 %pK %zd\n", __func__, *vaddr, bufsz); memset((void *)*vaddr, 0, bufsz); } @@ -153,7 +153,7 @@ int msm_audio_ion_import(const char *name, struct ion_client **client, bufsz should be 0 and fd shouldn't be 0 as of now */ *handle = ion_import_dma_buf(*client, fd); - pr_debug("%s: DMA Buf name=%s, fd=%d handle=%p\n", __func__, + pr_debug("%s: DMA Buf name=%s, fd=%d handle=%pK\n", __func__, name, fd, *handle); if (IS_ERR_OR_NULL((void *) (*handle))) { pr_err("%s: ion import dma buffer failed\n", @@ -184,7 +184,7 @@ int msm_audio_ion_import(const char *name, struct ion_client **client, rc = -ENOMEM; goto err_ion_handle; } - pr_debug("%s: mapped address = %p, size=%zd\n", __func__, + pr_debug("%s: mapped address = %pK, size=%zd\n", __func__, *vaddr, bufsz); return 0; @@ -207,7 +207,7 @@ int msm_audio_ion_free(struct ion_client *client, struct ion_handle *handle) } if (msm_audio_ion_data.smmu_enabled) { /* Need to populate book kept infomation */ - pr_debug("client=%p, domain=%p, domain_id=%d, group=%p", + pr_debug("client=%pK, domain=%pK, domain_id=%d, group=%pK", client, msm_audio_ion_data.domain, msm_audio_ion_data.domain_id, msm_audio_ion_data.group); @@ -273,7 +273,7 @@ int msm_audio_ion_mmap(struct audio_buffer *ab, offset = 0; } len = min(len, remainder); - pr_debug("vma=%p, addr=%x len=%ld vm_start=%x vm_end=%x vm_page_prot=%ld\n", + pr_debug("vma=%pK, addr=%x len=%ld vm_start=%x vm_end=%x vm_page_prot=%ld\n", vma, (unsigned int)addr, len, (unsigned int)vma->vm_start, (unsigned int)vma->vm_end, @@ -296,8 +296,8 @@ int msm_audio_ion_mmap(struct audio_buffer *ab, , __func__ , ret); return ret; } - pr_debug("phys=%pa len=%zd\n", &phys_addr, phys_len); - pr_debug("vma=%p, vm_start=%x vm_end=%x vm_pgoff=%ld vm_page_prot=%ld\n", + pr_debug("phys=%pK len=%zd\n", &phys_addr, phys_len); + pr_debug("vma=%pK, vm_start=%x vm_end=%x vm_pgoff=%ld vm_page_prot=%ld\n", vma, (unsigned int)vma->vm_start, (unsigned int)vma->vm_end, vma->vm_pgoff, (unsigned long int)vma->vm_page_prot); @@ -333,7 +333,7 @@ struct ion_client *msm_audio_ion_client_create(const char *name) void msm_audio_ion_client_destroy(struct ion_client *client) { - pr_debug("%s: client = %p smmu_enabled = %d\n", __func__, + pr_debug("%s: client = %pK smmu_enabled = %d\n", __func__, client, msm_audio_ion_data.smmu_enabled); ion_client_destroy(client); @@ -355,7 +355,7 @@ int msm_audio_ion_import_legacy(const char *name, struct ion_client *client, bufsz should be 0 and fd shouldn't be 0 as of now */ *handle = ion_import_dma_buf(client, fd); - pr_debug("%s: DMA Buf name=%s, fd=%d handle=%p\n", __func__, + pr_debug("%s: DMA Buf name=%s, fd=%d handle=%pK\n", __func__, name, fd, *handle); if (IS_ERR_OR_NULL((void *)(*handle))) { pr_err("%s: ion import dma buffer failed\n", @@ -421,7 +421,7 @@ int msm_audio_ion_cache_operations(struct audio_buffer *abuff, int cache_op) int msm_cache_ops = 0; if (!abuff) { - pr_err("Invalid params: %p, %p\n", __func__, abuff); + pr_err("Invalid params: %pK, %pK\n", __func__, abuff); return -EINVAL; } rc = ion_handle_get_flags(abuff->client, abuff->handle, @@ -467,7 +467,7 @@ static int msm_audio_ion_get_phys(struct ion_client *client, pr_err("%s: ION map iommu failed %d\n", __func__, rc); return rc; } - pr_debug("client=%p, domain=%p, domain_id=%d, group=%p", + pr_debug("client=%pK, domain=%pK, domain_id=%d, group=%pK", client, msm_audio_ion_data.domain, msm_audio_ion_data.domain_id, msm_audio_ion_data.group); /* Append the SMMU SID information to the address */ @@ -476,7 +476,7 @@ static int msm_audio_ion_get_phys(struct ion_client *client, /* SMMU is disabled*/ rc = ion_phys(client, handle, addr, len); } - pr_debug("phys=%pa, len=%zd, rc=%d\n", &(*addr), *len, rc); + pr_debug("phys=%pK, len=%zd, rc=%d\n", &(*addr), *len, rc); return rc; } @@ -540,18 +540,18 @@ static int msm_audio_ion_probe(struct platform_device *pdev) msm_audio_ion_data.domain = iommu_group_get_iommudata(msm_audio_ion_data.group); if (IS_ERR_OR_NULL(msm_audio_ion_data.domain)) { - pr_err("Failed to get domain data for group %p", + pr_err("Failed to get domain data for group %pK", msm_audio_ion_data.group); goto fail_group; } msm_audio_ion_data.domain_id = msm_find_domain_no(msm_audio_ion_data.domain); if (msm_audio_ion_data.domain_id < 0) { - pr_err("Failed to get domain index for domain %p", + pr_err("Failed to get domain index for domain %pK", msm_audio_ion_data.domain); goto fail_group; } - pr_debug("domain=%p, domain_id=%d, group=%p", + pr_debug("domain=%pK, domain_id=%d, group=%pK", msm_audio_ion_data.domain, msm_audio_ion_data.domain_id, msm_audio_ion_data.group); @@ -575,7 +575,7 @@ static int msm_audio_ion_probe(struct platform_device *pdev) static int msm_audio_ion_remove(struct platform_device *pdev) { - pr_debug("%s: msm audio ion is unloaded, domain=%p, group=%p\n", + pr_debug("%s: msm audio ion is unloaded, domain=%pK, group=%pK\n", __func__, msm_audio_ion_data.domain, msm_audio_ion_data.group); iommu_detach_group(msm_audio_ion_data.domain, msm_audio_ion_data.group); diff --git a/drivers/soc/qcom/scm.c b/drivers/soc/qcom/scm.c index c806f110ad1ff..795f33da63aad 100644 --- a/drivers/soc/qcom/scm.c +++ b/drivers/soc/qcom/scm.c @@ -101,6 +101,7 @@ struct scm_response { #define R3_STR "x3" #define R4_STR "x4" #define R5_STR "x5" +#define R6_STR "x6" /* Outer caches unsupported on ARM64 platforms */ #define outer_inv_range(x, y) @@ -370,6 +371,7 @@ static int __scm_call_armv8_64(u64 x0, u64 x1, u64 x2, u64 x3, u64 x4, u64 x5, register u64 r3 asm("r3") = x3; register u64 r4 asm("r4") = x4; register u64 r5 asm("r5") = x5; + register u64 r6 asm("r6") = 0; do { asm volatile( @@ -383,14 +385,15 @@ static int __scm_call_armv8_64(u64 x0, u64 x1, u64 x2, u64 x3, u64 x4, u64 x5, __asmeq("%7", R3_STR) __asmeq("%8", R4_STR) __asmeq("%9", R5_STR) + __asmeq("%10", R6_STR) #ifdef REQUIRES_SEC ".arch_extension sec\n" #endif "smc #0\n" : "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3) : "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4), - "r" (r5) - : "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", + "r" (r5), "r" (r6) + : "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17"); } while (r0 == SCM_INTERRUPTED); @@ -413,6 +416,7 @@ static int __scm_call_armv8_32(u32 w0, u32 w1, u32 w2, u32 w3, u32 w4, u32 w5, register u32 r3 asm("r3") = w3; register u32 r4 asm("r4") = w4; register u32 r5 asm("r5") = w5; + register u32 r6 asm("r6") = 0; do { asm volatile( @@ -426,14 +430,15 @@ static int __scm_call_armv8_32(u32 w0, u32 w1, u32 w2, u32 w3, u32 w4, u32 w5, __asmeq("%7", R3_STR) __asmeq("%8", R4_STR) __asmeq("%9", R5_STR) + __asmeq("%10", R6_STR) #ifdef REQUIRES_SEC ".arch_extension sec\n" #endif "smc #0\n" : "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3) : "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4), - "r" (r5) - : "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", + "r" (r5), "r" (r6) + : "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17"); } while (r0 == SCM_INTERRUPTED); diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 253bb2f6bd713..b6380bf87f916 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -1133,7 +1133,7 @@ static void ion_vm_open(struct vm_area_struct *vma) mutex_lock(&buffer->lock); list_add(&vma_list->list, &buffer->vmas); mutex_unlock(&buffer->lock); - pr_debug("%s: adding %p\n", __func__, vma); + pr_debug("%s: adding %pK\n", __func__, vma); } static void ion_vm_close(struct vm_area_struct *vma) @@ -1148,7 +1148,7 @@ static void ion_vm_close(struct vm_area_struct *vma) continue; list_del(&vma_list->list); kfree(vma_list); - pr_debug("%s: deleting %p\n", __func__, vma); + pr_debug("%s: deleting %pK\n", __func__, vma); break; } mutex_unlock(&buffer->lock); diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c index 3fb6078e8c3fc..6d21aecce8ea1 100644 --- a/drivers/staging/android/ion/ion_cma_heap.c +++ b/drivers/staging/android/ion/ion_cma_heap.c @@ -97,7 +97,7 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer, /* keep this for memory release */ buffer->priv_virt = info; - dev_dbg(dev, "Allocate buffer %p\n", buffer); + dev_dbg(dev, "Allocate buffer %pK\n", buffer); return 0; err: @@ -110,7 +110,7 @@ static void ion_cma_free(struct ion_buffer *buffer) struct device *dev = buffer->heap->priv; struct ion_cma_buffer_info *info = buffer->priv_virt; - dev_dbg(dev, "Release buffer %p\n", buffer); + dev_dbg(dev, "Release buffer %pK\n", buffer); /* release memory */ dma_free_coherent(dev, buffer->size, info->cpu_addr, info->handle); sg_free_table(info->table); @@ -126,7 +126,7 @@ static int ion_cma_phys(struct ion_heap *heap, struct ion_buffer *buffer, struct device *dev = heap->priv; struct ion_cma_buffer_info *info = buffer->priv_virt; - dev_dbg(dev, "Return buffer %p physical address 0x%pa\n", buffer, + dev_dbg(dev, "Return buffer %pK physical address 0x%pa\n", buffer, &info->handle); *addr = info->handle; diff --git a/drivers/staging/android/ion/ion_cma_secure_heap.c b/drivers/staging/android/ion/ion_cma_secure_heap.c index 73299d67668de..ebd98e6d3bec3 100644 --- a/drivers/staging/android/ion/ion_cma_secure_heap.c +++ b/drivers/staging/android/ion/ion_cma_secure_heap.c @@ -3,7 +3,7 @@ * * Copyright (C) Linaro 2012 * Author: for ST-Ericsson. - * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2014,2016 The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -487,7 +487,7 @@ static struct ion_secure_cma_buffer_info *__ion_secure_cma_allocate( /* keep this for memory release */ buffer->priv_virt = info; - dev_dbg(sheap->dev, "Allocate buffer %p\n", buffer); + dev_dbg(sheap->dev, "Allocate buffer %pK\n", buffer); return info; err: @@ -571,7 +571,7 @@ static void ion_secure_cma_free(struct ion_buffer *buffer) struct ion_secure_cma_buffer_info *info = buffer->priv_virt; int ret = 0; - dev_dbg(sheap->dev, "Release buffer %p\n", buffer); + dev_dbg(sheap->dev, "Release buffer %pK\n", buffer); if (msm_secure_v2_is_supported()) ret = msm_ion_unsecure_table(info->table); atomic_sub(buffer->size, &sheap->total_allocated); @@ -593,8 +593,8 @@ static int ion_secure_cma_phys(struct ion_heap *heap, struct ion_buffer *buffer, container_of(heap, struct ion_cma_secure_heap, heap); struct ion_secure_cma_buffer_info *info = buffer->priv_virt; - dev_dbg(sheap->dev, "Return buffer %p physical address 0x%pa\n", buffer, - &info->phys); + dev_dbg(sheap->dev, "Return buffer %pK physical address 0x%pa\n", + buffer, &info->phys); *addr = info->phys; *len = buffer->size; diff --git a/drivers/staging/android/ion/msm/msm_ion.c b/drivers/staging/android/ion/msm/msm_ion.c index 9f8c1413e6824..9ec2d983ae8d4 100644 --- a/drivers/staging/android/ion/msm/msm_ion.c +++ b/drivers/staging/android/ion/msm/msm_ion.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014,2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -714,7 +714,7 @@ long msm_ion_custom_ioctl(struct ion_client *client, } else { handle = ion_import_dma_buf(client, data.flush_data.fd); if (IS_ERR(handle)) { - pr_info("%s: Could not import handle: %p\n", + pr_info("%s: Could not import handle: %pK\n", __func__, handle); return -EINVAL; } @@ -727,8 +727,8 @@ long msm_ion_custom_ioctl(struct ion_client *client, + data.flush_data.length; if (start && check_vaddr_bounds(start, end)) { - pr_err("%s: virtual address %p is out of bounds\n", - __func__, data.flush_data.vaddr); + pr_err("%s: virtual address %pK is out of bounds\n", + __func__, data.flush_data.vaddr); ret = -EINVAL; } else { ret = ion_do_cache_op( diff --git a/drivers/staging/android/ion/msm/secure_buffer.c b/drivers/staging/android/ion/msm/secure_buffer.c index c9f2523eaa40e..d09efdda13072 100644 --- a/drivers/staging/android/ion/msm/secure_buffer.c +++ b/drivers/staging/android/ion/msm/secure_buffer.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2011 Google, Inc - * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2014,2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -99,7 +99,7 @@ static int secure_buffer_change_table(struct sg_table *table, int lock) u32 base; u64 tmp = sg_dma_address(sg); WARN((tmp >> 32) & 0xffffffff, - "%s: there are ones in the upper 32 bits of the sg at %p! They will be truncated! Address: 0x%llx\n", + "%s: there are ones in the upper 32 bits of the sg at %pK! They will be truncated! Address: 0x%llx\n", __func__, sg, tmp); if (unlikely(!size || (size % V2_CHUNK_SIZE))) { WARN(1, diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index c5d6fa7e353c3..3ce8d95f25bd1 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -83,6 +83,8 @@ static unsigned long lowmem_deathpending_timeout; static atomic_t shift_adj = ATOMIC_INIT(0); static short adj_max_shift = 353; +module_param_named(adj_max_shift, adj_max_shift, short, + S_IRUGO | S_IWUSR); /* User knob to enable/disable adaptive lmk feature */ static int enable_adaptive_lmk; diff --git a/drivers/staging/android/oneshot_sync.c b/drivers/staging/android/oneshot_sync.c index 317720ade3a83..6a56ee9d6b062 100644 --- a/drivers/staging/android/oneshot_sync.c +++ b/drivers/staging/android/oneshot_sync.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014,2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 9ef2d2c15ecc9..a9fafabf4db4b 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -113,6 +113,7 @@ EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem); #define HUB_DEBOUNCE_STEP 25 #define HUB_DEBOUNCE_STABLE 100 +static void hub_release(struct kref *kref); static int usb_reset_and_verify_device(struct usb_device *udev); static inline char *portspeed(struct usb_hub *hub, int portstatus) @@ -1001,10 +1002,20 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) unsigned delay; /* Continue a partial initialization */ - if (type == HUB_INIT2) - goto init2; - if (type == HUB_INIT3) + if (type == HUB_INIT2 || type == HUB_INIT3) { + device_lock(hub->intfdev); + + /* Was the hub disconnected while we were waiting? */ + if (hub->disconnected) { + device_unlock(hub->intfdev); + kref_put(&hub->kref, hub_release); + return; + } + if (type == HUB_INIT2) + goto init2; goto init3; + } + kref_get(&hub->kref); /* The superspeed hub except for root hub has to use Hub Depth * value as an offset into the route string to locate the bits @@ -1209,6 +1220,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) PREPARE_DELAYED_WORK(&hub->init_work, hub_init_func3); schedule_delayed_work(&hub->init_work, msecs_to_jiffies(delay)); + device_unlock(hub->intfdev); return; /* Continues at init3: below */ } else { msleep(delay); @@ -1229,6 +1241,11 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) /* Allow autosuspend if it was suppressed */ if (type <= HUB_INIT3) usb_autopm_put_interface_async(to_usb_interface(hub->intfdev)); + + if (type == HUB_INIT2 || type == HUB_INIT3) + device_unlock(hub->intfdev); + + kref_put(&hub->kref, hub_release); } /* Implement the continuations for the delays above */ diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index c608227491a06..46fe9ac81db18 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -6,7 +6,7 @@ ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG obj-$(CONFIG_USB_GADGET) += udc-core.o obj-$(CONFIG_USB_LIBCOMPOSITE) += libcomposite.o libcomposite-y := usbstring.o config.o epautoconf.o -libcomposite-y += composite.o functions.o configfs.o +libcomposite-y += composite.o functions.o obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o obj-$(CONFIG_USB_NET2272) += net2272.o obj-$(CONFIG_USB_NET2280) += net2280.o diff --git a/drivers/usb/gadget/f_mtp.c b/drivers/usb/gadget/f_mtp.c index 5a06296aaded6..98b67ae8bbc02 100644 --- a/drivers/usb/gadget/f_mtp.c +++ b/drivers/usb/gadget/f_mtp.c @@ -26,6 +26,8 @@ #include #include +#include +#include #include #include #include @@ -67,6 +69,8 @@ #define MTP_RESPONSE_OK 0x2001 #define MTP_RESPONSE_DEVICE_BUSY 0x2019 +#define MAX_ITERATION 100 + unsigned int mtp_rx_req_len = MTP_BULK_BUFFER_SIZE; module_param(mtp_rx_req_len, uint, S_IRUGO | S_IWUSR); @@ -116,6 +120,15 @@ struct mtp_dev { uint16_t xfer_command; uint32_t xfer_transaction_id; int xfer_result; + struct { + unsigned long vfs_rbytes; + unsigned long vfs_wbytes; + unsigned vfs_rtime; + unsigned vfs_wtime; + } perf[MAX_ITERATION]; + unsigned dbg_read_index; + unsigned dbg_write_index; + bool is_ptp; }; static struct usb_interface_descriptor mtp_interface_desc = { @@ -322,10 +335,12 @@ struct mtp_ext_config_desc_function { }; /* MTP Extended Configuration Descriptor */ -struct { +struct ext_mtp_desc { struct mtp_ext_config_desc_header header; struct mtp_ext_config_desc_function function; -} mtp_ext_config_desc = { +}; + +struct ext_mtp_desc mtp_ext_config_desc = { .header = { .dwLength = __constant_cpu_to_le32(sizeof(mtp_ext_config_desc)), .bcdVersion = __constant_cpu_to_le16(0x0100), @@ -339,6 +354,20 @@ struct { }, }; +struct ext_mtp_desc ptp_ext_config_desc = { + .header = { + .dwLength = cpu_to_le32(sizeof(mtp_ext_config_desc)), + .bcdVersion = cpu_to_le16(0x0100), + .wIndex = cpu_to_le16(4), + .bCount = cpu_to_le16(1), + }, + .function = { + .bFirstInterfaceNumber = 0, + .bInterfaceCount = 1, + .compatibleID = { 'P', 'T', 'P' }, + }, +}; + struct mtp_device_status { __le16 wLength; __le16 wCode; @@ -760,6 +789,7 @@ static void send_file_work(struct work_struct *data) int xfer, ret, hdr_size; int r = 0; int sendZLP = 0; + ktime_t start_time; /* read our parameters */ smp_rmb(); @@ -815,14 +845,19 @@ static void send_file_work(struct work_struct *data) header->transaction_id = __cpu_to_le32(dev->xfer_transaction_id); } - + start_time = ktime_get(); ret = vfs_read(filp, req->buf + hdr_size, xfer - hdr_size, &offset); if (ret < 0) { r = ret; break; } + xfer = ret + hdr_size; + dev->perf[dev->dbg_read_index].vfs_rtime = + ktime_to_us(ktime_sub(ktime_get(), start_time)); + dev->perf[dev->dbg_read_index].vfs_rbytes = xfer; + dev->dbg_read_index = (dev->dbg_read_index + 1) % MAX_ITERATION; hdr_size = 0; req->length = xfer; @@ -862,6 +897,7 @@ static void receive_file_work(struct work_struct *data) int64_t count; int ret, cur_buf = 0; int r = 0; + ktime_t start_time; /* read our parameters */ smp_rmb(); @@ -895,6 +931,7 @@ static void receive_file_work(struct work_struct *data) if (write_req) { DBG(cdev, "rx %p %d\n", write_req, write_req->actual); + start_time = ktime_get(); ret = vfs_write(filp, write_req->buf, write_req->actual, &offset); DBG(cdev, "vfs_write %d\n", ret); @@ -904,6 +941,11 @@ static void receive_file_work(struct work_struct *data) dev->state = STATE_ERROR; break; } + dev->perf[dev->dbg_write_index].vfs_wtime = + ktime_to_us(ktime_sub(ktime_get(), start_time)); + dev->perf[dev->dbg_write_index].vfs_wbytes = ret; + dev->dbg_write_index = + (dev->dbg_write_index + 1) % MAX_ITERATION; write_req = NULL; } @@ -1238,9 +1280,21 @@ static int mtp_ctrlrequest(struct usb_composite_dev *cdev, if (ctrl->bRequest == 1 && (ctrl->bRequestType & USB_DIR_IN) && (w_index == 4 || w_index == 5)) { - value = (w_length < sizeof(mtp_ext_config_desc) ? - w_length : sizeof(mtp_ext_config_desc)); - memcpy(cdev->req->buf, &mtp_ext_config_desc, value); + if (!dev->is_ptp) { + value = (w_length < + sizeof(mtp_ext_config_desc) ? + w_length : + sizeof(mtp_ext_config_desc)); + memcpy(cdev->req->buf, &mtp_ext_config_desc, + value); + } else { + value = (w_length < + sizeof(ptp_ext_config_desc) ? + w_length : + sizeof(ptp_ext_config_desc)); + memcpy(cdev->req->buf, &ptp_ext_config_desc, + value); + } } } else if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS) { DBG(cdev, "class request: %d index: %d value: %d length: %d\n", @@ -1356,6 +1410,7 @@ mtp_function_unbind(struct usb_configuration *c, struct usb_function *f) while ((req = mtp_req_get(dev, &dev->intr_idle))) mtp_request_free(req, dev->ep_intr); dev->state = STATE_OFFLINE; + dev->is_ptp = false; } static int mtp_function_set_alt(struct usb_function *f, @@ -1462,9 +1517,123 @@ static int mtp_bind_config(struct usb_configuration *c, bool ptp_config) dev->function.set_alt = mtp_function_set_alt; dev->function.disable = mtp_function_disable; + dev->is_ptp = ptp_config; return usb_add_function(c, &dev->function); } +static int debug_mtp_read_stats(struct seq_file *s, void *unused) +{ + struct mtp_dev *dev = _mtp_dev; + int i; + unsigned long flags; + unsigned min, max = 0, sum = 0, iteration = 0; + + seq_puts(s, "\n=======================\n"); + seq_puts(s, "MTP Write Stats:\n"); + seq_puts(s, "\n=======================\n"); + spin_lock_irqsave(&dev->lock, flags); + min = dev->perf[0].vfs_wtime; + for (i = 0; i < MAX_ITERATION; i++) { + seq_printf(s, "vfs write: bytes:%ld\t\t time:%d\n", + dev->perf[i].vfs_wbytes, + dev->perf[i].vfs_wtime); + if (dev->perf[i].vfs_wbytes == mtp_rx_req_len) { + sum += dev->perf[i].vfs_wtime; + if (min > dev->perf[i].vfs_wtime) + min = dev->perf[i].vfs_wtime; + if (max < dev->perf[i].vfs_wtime) + max = dev->perf[i].vfs_wtime; + iteration++; + } + } + + seq_printf(s, "vfs_write(time in usec) min:%d\t max:%d\t avg:%d\n", + min, max, sum / iteration); + min = max = sum = iteration = 0; + seq_puts(s, "\n=======================\n"); + seq_puts(s, "MTP Read Stats:\n"); + seq_puts(s, "\n=======================\n"); + + min = dev->perf[0].vfs_rtime; + for (i = 0; i < MAX_ITERATION; i++) { + seq_printf(s, "vfs read: bytes:%ld\t\t time:%d\n", + dev->perf[i].vfs_rbytes, + dev->perf[i].vfs_rtime); + if (dev->perf[i].vfs_rbytes == mtp_tx_req_len) { + sum += dev->perf[i].vfs_rtime; + if (min > dev->perf[i].vfs_rtime) + min = dev->perf[i].vfs_rtime; + if (max < dev->perf[i].vfs_rtime) + max = dev->perf[i].vfs_rtime; + iteration++; + } + } + + seq_printf(s, "vfs_read(time in usec) min:%d\t max:%d\t avg:%d\n", + min, max, sum / iteration); + spin_unlock_irqrestore(&dev->lock, flags); + return 0; +} + +static ssize_t debug_mtp_reset_stats(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + int clear_stats; + unsigned long flags; + struct mtp_dev *dev = _mtp_dev; + + if (buf == NULL) { + pr_err("[%s] EINVAL\n", __func__); + goto done; + } + + if (sscanf(buf, "%u", &clear_stats) != 1 || clear_stats != 0) { + pr_err("Wrong value. To clear stats, enter value as 0.\n"); + goto done; + } + + spin_lock_irqsave(&dev->lock, flags); + memset(&dev->perf[0], 0, MAX_ITERATION * sizeof(dev->perf[0])); + dev->dbg_read_index = 0; + dev->dbg_write_index = 0; + spin_unlock_irqrestore(&dev->lock, flags); +done: + return count; +} + +static int debug_mtp_open(struct inode *inode, struct file *file) +{ + return single_open(file, debug_mtp_read_stats, inode->i_private); +} + +static const struct file_operations debug_mtp_ops = { + .open = debug_mtp_open, + .read = seq_read, + .write = debug_mtp_reset_stats, +}; + +struct dentry *dent_mtp; +static void mtp_debugfs_init(void) +{ + struct dentry *dent_mtp_status; + dent_mtp = debugfs_create_dir("usb_mtp", 0); + if (!dent_mtp || IS_ERR(dent_mtp)) + return; + + dent_mtp_status = debugfs_create_file("status", S_IRUGO | S_IWUSR, + dent_mtp, 0, &debug_mtp_ops); + if (!dent_mtp_status || IS_ERR(dent_mtp_status)) { + debugfs_remove(dent_mtp); + dent_mtp = NULL; + return; + } +} + +static void mtp_debugfs_remove(void) +{ + debugfs_remove_recursive(dent_mtp); +} + static int mtp_setup(void) { struct mtp_dev *dev; @@ -1497,6 +1666,7 @@ static int mtp_setup(void) if (ret) goto err2; + mtp_debugfs_init(); return 0; err2: @@ -1515,6 +1685,7 @@ static void mtp_cleanup(void) if (!dev) return; + mtp_debugfs_remove(); misc_deregister(&mtp_device); destroy_workqueue(dev->wq); _mtp_dev = NULL; diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index 030a47ed55985..7f0c734100a38 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c @@ -1258,6 +1258,9 @@ static ssize_t debug_read_status(struct file *file, char __user *ubuf, int ret; int result = 0; + if (!ui_dev) + return -EINVAL; + tty = ui_dev->port.tty; gser = ui_dev->port_usb; @@ -1310,6 +1313,9 @@ static ssize_t debug_write_reset(struct file *file, const char __user *buf, struct gs_port *ui_dev = file->private_data; unsigned long flags; + if (!ui_dev) + return -EINVAL; + spin_lock_irqsave(&ui_dev->port_lock, flags); ui_dev->nbytes_from_host = ui_dev->nbytes_to_tty = ui_dev->nbytes_from_tty = ui_dev->nbytes_to_host = 0; @@ -1339,6 +1345,9 @@ static void usb_debugfs_init(struct gs_port *ui_dev, int port_num) { char buf[48]; + if (!ui_dev) + return; + snprintf(buf, 48, "usb_serial%d", port_num); gs_dent = debugfs_create_dir(buf, 0); if (!gs_dent || IS_ERR(gs_dent)) diff --git a/drivers/video/adf/adf_client.c b/drivers/video/adf/adf_client.c index 8061d8e6b9fbd..75b2f0b18522e 100644 --- a/drivers/video/adf/adf_client.c +++ b/drivers/video/adf/adf_client.c @@ -305,8 +305,10 @@ static int adf_buffer_map(struct adf_device *dev, struct adf_buffer *buf, } done: - if (ret < 0) + if (ret < 0) { adf_buffer_mapping_cleanup(mapping, buf); + memset(mapping, 0, sizeof(*mapping)); + } return ret; } diff --git a/drivers/video/msm/mdss/mdp3.c b/drivers/video/msm/mdss/mdp3.c index fcf9cd1f3dcaf..521eb7e59e9f2 100644 --- a/drivers/video/msm/mdss/mdp3.c +++ b/drivers/video/msm/mdss/mdp3.c @@ -909,11 +909,19 @@ static int mdp3_check_version(void) { int rc; + rc = mdp3_footswitch_ctrl(1); + if (rc) { + pr_err("unable to turn on FS\n"); + return rc; + } + rc = mdp3_clk_update(MDP3_CLK_AHB, 1); rc |= mdp3_clk_update(MDP3_CLK_AXI, 1); rc |= mdp3_clk_update(MDP3_CLK_MDP_CORE, 1); - if (rc) + if (rc) { + mdp3_footswitch_ctrl(0); return rc; + } mdp3_res->mdp_rev = MDP3_REG_READ(MDP3_REG_HW_VERSION); @@ -923,6 +931,10 @@ static int mdp3_check_version(void) if (rc) pr_err("fail to turn off the MDP3_CLK_AHB clk\n"); + rc = mdp3_footswitch_ctrl(0); + if (rc) + pr_err("unable to turn off FS\n"); + if (mdp3_res->mdp_rev != MDP_CORE_HW_VERSION) { pr_err("mdp_hw_revision=%x mismatch\n", mdp3_res->mdp_rev); rc = -ENODEV; @@ -1084,7 +1096,7 @@ static int mdp3_res_init(void) mdp3_res->ion_client = msm_ion_client_create(mdp3_res->pdev->name); if (IS_ERR_OR_NULL(mdp3_res->ion_client)) { - pr_err("msm_ion_client_create() return error (%p)\n", + pr_err("msm_ion_client_create() return error (%pK)\n", mdp3_res->ion_client); mdp3_res->ion_client = NULL; return -EINVAL; @@ -1516,7 +1528,7 @@ void mdp3_unmap_iommu(struct ion_client *client, struct ion_handle *handle) mutex_lock(&mdp3_res->iommu_lock); meta = mdp3_iommu_meta_lookup(table); if (!meta) { - WARN(1, "%s: buffer was never mapped for %p\n", __func__, + WARN(1, "%s: buffer was never mapped for %pK\n", __func__, handle); mutex_unlock(&mdp3_res->iommu_lock); goto out; @@ -1544,7 +1556,7 @@ static void mdp3_iommu_meta_add(struct mdp3_iommu_meta *meta) } else if (meta->table > entry->table) { p = &(*p)->rb_right; } else { - pr_err("%s: handle %p already exists\n", __func__, + pr_err("%s: handle %pK already exists\n", __func__, entry->handle); BUG(); } @@ -1606,7 +1618,7 @@ static int mdp3_iommu_map_iommu(struct mdp3_iommu_meta *meta, ret = iommu_map_range(domain, meta->iova_addr + padding, table->sgl, size, prot); if (ret) { - pr_err("%s: could not map %pa in domain %p\n", + pr_err("%s: could not map %pa in domain %pK\n", __func__, &meta->iova_addr, domain); unmap_size = padding; goto out2; @@ -1729,12 +1741,12 @@ int mdp3_self_map_iommu(struct ion_client *client, struct ion_handle *handle, } } else { if (iommu_meta->flags != iommu_flags) { - pr_err("%s: handle %p is already mapped with diff flag\n", + pr_err("%s: handle %pK is already mapped with diff flag\n", __func__, handle); ret = -EINVAL; goto out_unlock; } else if (iommu_meta->mapped_size != iova_length) { - pr_err("%s: handle %p is already mapped with diff len\n", + pr_err("%s: handle %pK is already mapped with diff len\n", __func__, handle); ret = -EINVAL; goto out_unlock; @@ -1856,7 +1868,7 @@ int mdp3_get_img(struct msmfb_data *img, struct mdp3_img_data *data, int client) data->addr += img->offset; data->len -= img->offset; - pr_debug("mem=%d ihdl=%p buf=0x%pa len=0x%x\n", img->memory_id, + pr_debug("mem=%d ihdl=%pK buf=0x%pa len=0x%x\n", img->memory_id, data->srcp_ihdl, &data->addr, data->len); } else { mdp3_put_img(data, client); @@ -2089,7 +2101,7 @@ static int mdp3_alloc(struct msm_fb_data_type *mfd) return ret; } - pr_info("allocating %u bytes at %p (%lx phys) for fb %d\n", + pr_info("allocating %u bytes at %pK (%lx phys) for fb %d\n", size, virt, phys, mfd->index); mfd->fbi->screen_base = virt; diff --git a/drivers/video/msm/mdss/mdp3_ppp.c b/drivers/video/msm/mdss/mdp3_ppp.c index 5f556dd2f61e6..0f940d6642a2b 100644 --- a/drivers/video/msm/mdss/mdp3_ppp.c +++ b/drivers/video/msm/mdss/mdp3_ppp.c @@ -584,7 +584,12 @@ int mdp3_calc_ppp_res(struct msm_fb_data_type *mfd, struct blit_req_list *lreq) else fps = panel_info->mipi.frame_rate; } - + if (!(check_if_rgb(req->src.format))) { + /* Set max fps if video is not full screen */ + if((req->dst_rect.w < panel_info->xres) || + ( req->dst_rect.h < panel_info->yres)) + fps = panel_info->mipi.frame_rate; + } mdp3_get_bpp_info(req->src.format, &bpp); if (lreq->req_list[i].flags & MDP_SMART_BLIT) { /* diff --git a/drivers/video/msm/mdss/mdp3_ppp_hwio.c b/drivers/video/msm/mdss/mdp3_ppp_hwio.c index d8c4168e5ead1..43177262fc4b8 100644 --- a/drivers/video/msm/mdss/mdp3_ppp_hwio.c +++ b/drivers/video/msm/mdss/mdp3_ppp_hwio.c @@ -1291,7 +1291,8 @@ int config_ppp_op_mode(struct ppp_blit_op *blit_op) bg_mdp_ops = 0; } pr_debug("BLIT FG Param Fmt %d (x %d,y %d,w %d,h %d), ROI(x %d,y %d, w\ - %d, h %d) Addr_P0 %p, Stride S0 %d Addr_P1 %p, Stride S1 %d\n", + %d, h %d) Addr_P0 %pK, Stride S0 %d Addr_P1 %pK,\ + Stride S1 %d\n", blit_op->src.color_fmt, blit_op->src.prop.x, blit_op->src.prop.y, blit_op->src.prop.width, blit_op->src.prop.height, blit_op->src.roi.x, blit_op->src.roi.y, blit_op->src.roi.width, @@ -1299,14 +1300,15 @@ int config_ppp_op_mode(struct ppp_blit_op *blit_op) blit_op->src.p1, blit_op->src.stride1); if (blit_op->bg.p0 != blit_op->dst.p0) pr_debug("BLIT BG Param Fmt %d (x %d,y %d,w %d,h %d), ROI(x %d,y %d, w\ - %d, h %d) Addr %p, Stride S0 %d Addr_P1 %p, Stride S1 %d\n", + %d, h %d) Addr %pK, Stride S0 %d Addr_P1 %pK,\ + Stride S1 %d\n", blit_op->bg.color_fmt, blit_op->bg.prop.x, blit_op->bg.prop.y, blit_op->bg.prop.width, blit_op->bg.prop.height, blit_op->bg.roi.x, blit_op->bg.roi.y, blit_op->bg.roi.width, blit_op->bg.roi.height, blit_op->bg.p0, blit_op->bg.stride0, blit_op->bg.p1, blit_op->bg.stride1); pr_debug("BLIT FB Param Fmt %d (x %d,y %d,w %d,h %d), ROI(x %d,y %d, w\ - %d, h %d) Addr %p, Stride S0 %d Addr_P1 %p, Stride S1 %d\n", + %d, h %d) Addr %pK, Stride S0 %d Addr_P1 %pK, Stride S1 %d\n", blit_op->dst.color_fmt, blit_op->dst.prop.x, blit_op->dst.prop.y, blit_op->dst.prop.width, blit_op->dst.prop.height, blit_op->dst.roi.x, blit_op->dst.roi.y, blit_op->dst.roi.width, diff --git a/drivers/video/msm/mdss/mdss.h b/drivers/video/msm/mdss/mdss.h index 5308acbdd7b5a..e25f0630df054 100644 --- a/drivers/video/msm/mdss/mdss.h +++ b/drivers/video/msm/mdss/mdss.h @@ -60,6 +60,11 @@ struct mdss_hw_settings { u32 val; }; +struct mdss_max_bw_settings { + u32 mdss_max_bw_mode; + u32 mdss_max_bw_val; +}; + struct mdss_debug_inf { void *debug_data; void (*debug_enable_clock)(int on); @@ -258,6 +263,14 @@ struct mdss_data_type { u64 ab[MDSS_MAX_BUS_CLIENTS]; u64 ib[MDSS_MAX_BUS_CLIENTS]; + + struct mdss_max_bw_settings *max_bw_settings; + u32 bw_mode_bitmap; + u32 max_bw_settings_cnt; + + struct mdss_max_bw_settings *max_per_pipe_bw_settings; + u32 mdss_per_pipe_bw_cnt; + u32 min_bw_per_pipe; }; extern struct mdss_data_type *mdss_res; diff --git a/drivers/video/msm/mdss/mdss_debug.c b/drivers/video/msm/mdss/mdss_debug.c index 27d799ae26a2a..226e4555cb732 100644 --- a/drivers/video/msm/mdss/mdss_debug.c +++ b/drivers/video/msm/mdss/mdss_debug.c @@ -80,7 +80,7 @@ static ssize_t panel_debug_base_offset_write(struct file *file, buf[count] = 0; /* end of string */ - if (sscanf(buf, "%x %x", &off, &cnt) != 2) + if (sscanf(buf, "%x %u", &off, &cnt) != 2) return -EFAULT; if (off > dbg->max_offset) @@ -178,7 +178,7 @@ static ssize_t panel_debug_base_reg_write(struct file *file, for (i = 0; i < len; i++) { p = buf + i * 3; p[2] = 0; - pr_debug("p[%d] = %p:%s\n", i, p, p); + pr_debug("p[%d] = %pK:%s\n", i, p, p); cnt = sscanf(p, "%x", &tmp); reg[i] = tmp; pr_debug("reg[%d] = %x\n", i, (int)reg[i]); @@ -606,11 +606,11 @@ static ssize_t mdss_debug_factor_write(struct file *file, if (strnchr(buf, count, '/')) { /* Parsing buf as fraction */ - if (sscanf(buf, "%d/%d", &numer, &denom) != 2) + if (sscanf(buf, "%u/%u", &numer, &denom) != 2) return -EFAULT; } else { /* Parsing buf as percentage */ - if (sscanf(buf, "%d", &numer) != 1) + if (kstrtouint(buf, 0, &numer)) return -EFAULT; denom = 100; } @@ -857,6 +857,91 @@ static int mdss_debugfs_cleanup(struct mdss_debug_data *mdd) return 0; } +static ssize_t mdss_debug_perf_bw_limit_read(struct file *file, + char __user *buff, size_t count, loff_t *ppos) +{ + struct mdss_data_type *mdata = file->private_data; + struct mdss_max_bw_settings *temp_settings; + int len = 0, i; + char buf[256]; + + if (!mdata) + return -ENODEV; + + if (*ppos) + return 0; /* the end */ + + pr_debug("mdata->max_bw_settings_cnt = %d\n", + mdata->max_bw_settings_cnt); + + temp_settings = mdata->max_bw_settings; + for (i = 0; i < mdata->max_bw_settings_cnt; i++) { + len += snprintf(buf + len, sizeof(buf), "%d %d\n", + temp_settings->mdss_max_bw_mode, + temp_settings->mdss_max_bw_val); + temp_settings++; + } + + if (len < 0) + return 0; + + if (copy_to_user(buff, buf, len)) + return -EFAULT; + + *ppos += len; /* increase offset */ + + return len; +} + +static ssize_t mdss_debug_perf_bw_limit_write(struct file *file, + const char __user *user_buf, size_t count, loff_t *ppos) +{ + struct mdss_data_type *mdata = file->private_data; + char buf[32]; + u32 mode, val, cnt; + struct mdss_max_bw_settings *temp_settings; + + if (!mdata) + return -ENODEV; + + + if (count >= sizeof(buf)) + return -EFAULT; + + if (copy_from_user(buf, user_buf, count)) + return -EFAULT; + + buf[count] = 0; /* end of string */ + cnt = mdata->max_bw_settings_cnt; + temp_settings = mdata->max_bw_settings; + + if (strnchr(buf, count, ' ')) { + /* Parsing buf */ + if (sscanf(buf, "%u %u", &mode, &val) != 2) + return -EFAULT; + } + + while (cnt--) { + if (mode == temp_settings->mdss_max_bw_mode) { + temp_settings->mdss_max_bw_val = val; + break; + } else { + temp_settings++; + } + } + + if (cnt == 0) + pr_err("Input mode is invalid\n"); + + return count; +} + +static const struct file_operations mdss_perf_bw_limit_fops = { + .open = simple_open, + .read = mdss_debug_perf_bw_limit_read, + .write = mdss_debug_perf_bw_limit_write, +}; + static int mdss_debugfs_perf_init(struct mdss_debug_data *mdd, struct mdss_data_type *mdata) { @@ -910,6 +995,9 @@ static int mdss_debugfs_perf_init(struct mdss_debug_data *mdd, debugfs_create_u32("latency_buff_per", 0644, mdd->perf, (u32 *)&mdata->latency_buff_per); + debugfs_create_file("threshold_bw_limit", 0644, mdd->perf, + (struct mdss_data_type *)mdata, &mdss_perf_bw_limit_fops); + return 0; } @@ -984,7 +1072,7 @@ void mdss_dump_reg(char __iomem *base, int len) x4 = readl_relaxed(addr+0x4); x8 = readl_relaxed(addr+0x8); xc = readl_relaxed(addr+0xc); - pr_info("%p : %08x %08x %08x %08x\n", addr, x0, x4, x8, xc); + pr_info("%pK : %08x %08x %08x %08x\n", addr, x0, x4, x8, xc); addr += 16; } mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF); @@ -1104,7 +1192,7 @@ static inline struct mdss_mdp_misr_map *mdss_misr_get_map(u32 block_id, return NULL; } - pr_debug("MISR Module(%d) CTRL(0x%x) SIG(0x%x) intf_base(0x%p)\n", + pr_debug("MISR Module(%d) CTRL(0x%x) SIG(0x%x) intf_base(0x%pK)\n", block_id, map->ctrl_reg, map->value_reg, intf_base); return map; } @@ -1147,7 +1235,7 @@ int mdss_misr_set(struct mdss_data_type *mdata, bool use_mdp_up_misr = false; if (!mdata || !req || !ctl) { - pr_err("Invalid input params: mdata = %p req = %p ctl = %p", + pr_err("Invalid input params: mdata = %pK req = %pK ctl = %pK", mdata, req, ctl); return -EINVAL; } diff --git a/drivers/video/msm/mdss/mdss_dsi.c b/drivers/video/msm/mdss/mdss_dsi.c index f66b3eb3fb5d9..9169213e4b623 100644 --- a/drivers/video/msm/mdss/mdss_dsi.c +++ b/drivers/video/msm/mdss/mdss_dsi.c @@ -483,13 +483,7 @@ static int mdss_dsi_off(struct mdss_panel_data *pdata, int power_state) panel_info = &ctrl_pdata->panel_data.panel_info; -#if defined(CONFIG_MACH_CP8675) - /*add set reset low by liujianfeng3@yulong.com for yashi nt35596 lcd error display*/ - gpio_set_value((ctrl_pdata->rst_gpio), 0); - usleep(100 * 1000); -#endif - - pr_debug("%s+: ctrl=%p ndx=%d power_state=%d\n", + pr_debug("%s+: ctrl=%pK ndx=%d power_state=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx, power_state); if (power_state == panel_info->panel_power_state) { @@ -577,7 +571,7 @@ int mdss_dsi_on(struct mdss_panel_data *pdata) panel_data); cur_power_state = pdata->panel_info.panel_power_state; - pr_debug("%s+: ctrl=%p ndx=%d cur_power_state=%d\n", __func__, + pr_debug("%s+: ctrl=%pK ndx=%d cur_power_state=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx, cur_power_state); pinfo = &pdata->panel_info; @@ -729,7 +723,7 @@ static int mdss_dsi_unblank(struct mdss_panel_data *pdata) panel_data); mipi = &pdata->panel_info.mipi; - pr_debug("%s+: ctrl=%p ndx=%d cur_blank_state=%d\n", __func__, + pr_debug("%s+: ctrl=%pK ndx=%d cur_blank_state=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx, pdata->panel_info.blank_state); mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1); @@ -785,7 +779,7 @@ static int mdss_dsi_blank(struct mdss_panel_data *pdata, int power_state) panel_data); mipi = &pdata->panel_info.mipi; - pr_debug("%s+: ctrl=%p ndx=%d power_state=%d\n", + pr_debug("%s+: ctrl=%pK ndx=%d power_state=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx, power_state); mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1); @@ -855,7 +849,7 @@ static int mdss_dsi_post_panel_on(struct mdss_panel_data *pdata) ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); - pr_debug("%s+: ctrl=%p ndx=%d\n", __func__, + pr_debug("%s+: ctrl=%pK ndx=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx); mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1); @@ -887,7 +881,7 @@ int mdss_dsi_cont_splash_on(struct mdss_panel_data *pdata) ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); - pr_debug("%s+: ctrl=%p ndx=%d\n", __func__, + pr_debug("%s+: ctrl=%pK ndx=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx); WARN((ctrl_pdata->ctrl_state & CTRL_STATE_PANEL_INIT), @@ -1142,6 +1136,10 @@ static int mdss_dsi_dfps_config(struct mdss_panel_data *pdata, int new_fps) sctrl_pdata = mdss_dsi_get_other_ctrl(ctrl_pdata); } + ctrl_pdata->dfps_status = true; + if (sctrl_pdata) + sctrl_pdata->dfps_status = true; + if (new_fps != ctrl_pdata->panel_data.panel_info.mipi.frame_rate) { if (pdata->panel_info.dfps_update @@ -1725,7 +1723,7 @@ int mdss_dsi_retrieve_ctrl_resources(struct platform_device *pdev, int mode, return rc; } - pr_info("%s: ctrl_base=%p ctrl_size=%x phy_base=%p phy_size=%x\n", + pr_info("%s: ctrl_base=%pK ctrl_size=%x phy_base=%pK phy_size=%x\n", __func__, ctrl->ctrl_base, ctrl->reg_size, ctrl->phy_io.base, ctrl->phy_io.len); diff --git a/drivers/video/msm/mdss/mdss_dsi.h b/drivers/video/msm/mdss/mdss_dsi.h index 809258012d016..bdaaf88951c25 100644 --- a/drivers/video/msm/mdss/mdss_dsi.h +++ b/drivers/video/msm/mdss/mdss_dsi.h @@ -437,6 +437,8 @@ struct mdss_dsi_ctrl_pdata { int horizontal_idle_cnt; struct panel_horizontal_idle *line_idle; struct mdss_util_intf *mdss_util; + + bool dfps_status; /* dynamic refresh status */ }; struct dsi_status_data { @@ -449,10 +451,10 @@ int dsi_panel_device_register(struct device_node *pan_node, struct mdss_dsi_ctrl_pdata *ctrl_pdata); int mdss_dsi_cmds_tx(struct mdss_dsi_ctrl_pdata *ctrl, - struct dsi_cmd_desc *cmds, int cnt); + struct dsi_cmd_desc *cmds, int cnt, int use_dma_tpg); int mdss_dsi_cmds_rx(struct mdss_dsi_ctrl_pdata *ctrl, - struct dsi_cmd_desc *cmds, int rlen); + struct dsi_cmd_desc *cmds, int rlen, int use_dma_tpg); void mdss_dsi_host_init(struct mdss_panel_data *pdata); void mdss_dsi_op_mode_config(int mode, diff --git a/drivers/video/msm/mdss/mdss_dsi_cmd.h b/drivers/video/msm/mdss/mdss_dsi_cmd.h index 119ce349100ec..a015426241e57 100644 --- a/drivers/video/msm/mdss/mdss_dsi_cmd.h +++ b/drivers/video/msm/mdss/mdss_dsi_cmd.h @@ -99,6 +99,7 @@ struct dsi_cmd_desc { #define CMD_REQ_COMMIT 0x0002 #define CMD_CLK_CTRL 0x0004 #define CMD_REQ_UNICAST 0x0008 +#define CMD_REQ_DMA_TPG 0x0040 #define CMD_REQ_NO_MAX_PKT_SIZE 0x0008 #define CMD_REQ_LP_MODE 0x0010 #define CMD_REQ_HS_MODE 0x0020 diff --git a/drivers/video/msm/mdss/mdss_dsi_host.c b/drivers/video/msm/mdss/mdss_dsi_host.c index 7838edac6752e..762cb55f5de33 100644 --- a/drivers/video/msm/mdss/mdss_dsi_host.c +++ b/drivers/video/msm/mdss/mdss_dsi_host.c @@ -29,6 +29,8 @@ #include "mdss_debug.h" #define VSYNC_PERIOD 17 +#define DMA_TX_TIMEOUT 200 +#define DMA_TPG_FIFO_LEN 64 struct mdss_dsi_ctrl_pdata *ctrl_list[DSI_CTRL_MAX]; @@ -95,7 +97,7 @@ void mdss_dsi_ctrl_init(struct device *ctrl_dev, if (ctrl->mdss_util->register_irq(ctrl->dsi_hw)) pr_err("%s: mdss_register_irq failed.\n", __func__); - pr_debug("%s: ndx=%d base=%p\n", __func__, ctrl->ndx, ctrl->ctrl_base); + pr_debug("%s: ndx=%d base=%pK\n", __func__, ctrl->ndx, ctrl->ctrl_base); init_completion(&ctrl->dma_comp); init_completion(&ctrl->mdp_comp); @@ -262,9 +264,12 @@ void mdss_dsi_cmd_test_pattern(struct mdss_dsi_ctrl_pdata *ctrl) void mdss_dsi_get_hw_revision(struct mdss_dsi_ctrl_pdata *ctrl) { - mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 1); + if (ctrl->hw_rev) + return; + + mdss_dsi_clk_ctrl(ctrl, DSI_BUS_CLKS, 1); ctrl->hw_rev = MIPI_INP(ctrl->ctrl_base); - mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 0); + mdss_dsi_clk_ctrl(ctrl, DSI_BUS_CLKS, 0); pr_debug("%s: ndx=%d hw_rev=%x\n", __func__, ctrl->ndx, ctrl->hw_rev); @@ -1211,8 +1216,107 @@ static int mdss_dsi_cmd_dma_tx(struct mdss_dsi_ctrl_pdata *ctrl, static int mdss_dsi_cmd_dma_rx(struct mdss_dsi_ctrl_pdata *ctrl, struct dsi_buf *rp, int rlen); +static int mdss_dsi_cmd_dma_tpg_tx(struct mdss_dsi_ctrl_pdata *ctrl, + struct dsi_buf *tp) +{ + int len, i, ret = 0, data = 0; + u32 *bp; + struct mdss_dsi_ctrl_pdata *mctrl = NULL; + + if (tp->len > DMA_TPG_FIFO_LEN) { + pr_debug("command length more than FIFO length\n"); + return -EINVAL; + } + + mdss_dsi_get_hw_revision(ctrl); + + if (ctrl->hw_rev < MDSS_DSI_HW_REV_103) { + pr_err("CMD DMA TPG not supported for this DSI version\n"); + return -EINVAL; + } + + bp = (u32 *)tp->data; + len = ALIGN(tp->len, 4); + + INIT_COMPLETION(ctrl->dma_comp); + + if (mdss_dsi_sync_wait_trigger(ctrl)) + mctrl = mdss_dsi_get_other_ctrl(ctrl); + + data = BIT(16) | BIT(17); /* select CMD_DMA_PATTERN_SEL to 3 */ + data |= BIT(2); /* select CMD_DMA_FIFO_MODE to 1 */ + data |= BIT(1); /* enable CMD_DMA_TPG */ + + MIPI_OUTP(ctrl->ctrl_base + 0x15c, data); + if (mctrl) + MIPI_OUTP(mctrl->ctrl_base + 0x15c, data); + + /* + * The DMA command parameters need to be programmed to the DMA_INIT_VAL + * register in the proper order. The 'len' value will be a multiple + * of 4, the padding bytes to make sure of this will be taken care of in + * mdss_dsi_cmd_dma_add API. + */ + for (i = 0; i < len; i += 4) { + MIPI_OUTP(ctrl->ctrl_base + 0x17c, *bp); + if (mctrl) + MIPI_OUTP(mctrl->ctrl_base + 0x17c, *bp); + wmb(); /* make sure write happens before writing next command */ + bp++; + } + + /* + * The number of writes to the DMA_INIT_VAL register should be an even + * number of dwords (32 bits). In case 'len' is not a multiple of 8, + * we need to do make an extra write to the register with 0x00 to + * satisfy this condition. + */ + if ((len % 8) != 0) { + MIPI_OUTP(ctrl->ctrl_base + 0x17c, 0x00); + if (mctrl) + MIPI_OUTP(mctrl->ctrl_base + 0x17c, 0x00); + } + + if (mctrl) { + MIPI_OUTP(mctrl->ctrl_base + 0x04c, len); + MIPI_OUTP(mctrl->ctrl_base + 0x090, 0x01); /* trigger */ + } + MIPI_OUTP(ctrl->ctrl_base + 0x04c, len); + wmb(); /* make sure DMA length is programmed */ + + MIPI_OUTP(ctrl->ctrl_base + 0x090, 0x01); /* trigger */ + wmb(); /* make sure DMA trigger happens */ + + ret = wait_for_completion_timeout(&ctrl->dma_comp, + msecs_to_jiffies(DMA_TX_TIMEOUT)); + if (ret == 0) + ret = -ETIMEDOUT; + else + ret = tp->len; + + /* Reset the DMA TPG FIFO */ + MIPI_OUTP(ctrl->ctrl_base + 0x1ec, 0x1); + wmb(); /* make sure FIFO reset happens */ + MIPI_OUTP(ctrl->ctrl_base + 0x1ec, 0x0); + wmb(); /* make sure FIFO reset happens */ + /* Disable CMD_DMA_TPG */ + MIPI_OUTP(ctrl->ctrl_base + 0x15c, 0x0); + + if (mctrl) { + /* Reset the DMA TPG FIFO */ + MIPI_OUTP(mctrl->ctrl_base + 0x1ec, 0x1); + wmb(); /* make sure FIFO reset happens */ + MIPI_OUTP(mctrl->ctrl_base + 0x1ec, 0x0); + wmb(); /* make sure FIFO reset happens */ + /* Disable CMD_DMA_TPG */ + MIPI_OUTP(mctrl->ctrl_base + 0x15c, 0x0); + } + + return ret; +} + static int mdss_dsi_cmds2buf_tx(struct mdss_dsi_ctrl_pdata *ctrl, - struct dsi_cmd_desc *cmds, int cnt) + struct dsi_cmd_desc *cmds, int cnt, int use_dma_tpg) { struct dsi_buf *tp; struct dsi_cmd_desc *cm; @@ -1239,7 +1343,10 @@ static int mdss_dsi_cmds2buf_tx(struct mdss_dsi_ctrl_pdata *ctrl, wait = mdss_dsi_wait4video_eng_busy(ctrl); mdss_dsi_enable_irq(ctrl, DSI_CMD_TERM); - len = mdss_dsi_cmd_dma_tx(ctrl, tp); + if (use_dma_tpg) + len = mdss_dsi_cmd_dma_tpg_tx(ctrl, tp); + else + len = mdss_dsi_cmd_dma_tx(ctrl, tp); if (IS_ERR_VALUE(len)) { mdss_dsi_disable_irq(ctrl, DSI_CMD_TERM); pr_err("%s: failed to call cmd_dma_tx for cmd = 0x%x\n", @@ -1297,7 +1404,7 @@ static inline bool __mdss_dsi_cmd_mode_config( * thread context only */ int mdss_dsi_cmds_tx(struct mdss_dsi_ctrl_pdata *ctrl, - struct dsi_cmd_desc *cmds, int cnt) + struct dsi_cmd_desc *cmds, int cnt, int use_dma_tpg) { int len = 0; struct mdss_dsi_ctrl_pdata *mctrl = NULL; @@ -1332,7 +1439,7 @@ int mdss_dsi_cmds_tx(struct mdss_dsi_ctrl_pdata *ctrl, do_send: ctrl->cmd_cfg_restore = __mdss_dsi_cmd_mode_config(ctrl, 1); - len = mdss_dsi_cmds2buf_tx(ctrl, cmds, cnt); + len = mdss_dsi_cmds2buf_tx(ctrl, cmds, cnt, use_dma_tpg); if (!len) pr_err("%s: failed to call\n", __func__); @@ -1373,7 +1480,7 @@ static struct dsi_cmd_desc pkt_size_cmd = { * */ int mdss_dsi_cmds_rx(struct mdss_dsi_ctrl_pdata *ctrl, - struct dsi_cmd_desc *cmds, int rlen) + struct dsi_cmd_desc *cmds, int rlen, int use_dma_tpg) { int data_byte, rx_byte, dlen, end; int short_response, diff, pkt_size, ret = 0; @@ -1455,7 +1562,10 @@ int mdss_dsi_cmds_rx(struct mdss_dsi_ctrl_pdata *ctrl, mdss_dsi_wait4video_eng_busy(ctrl); mdss_dsi_enable_irq(ctrl, DSI_CMD_TERM); - ret = mdss_dsi_cmd_dma_tx(ctrl, tp); + if (use_dma_tpg) + ret = mdss_dsi_cmd_dma_tpg_tx(ctrl, tp); + else + ret = mdss_dsi_cmd_dma_tx(ctrl, tp); if (IS_ERR_VALUE(ret)) { mdss_dsi_disable_irq(ctrl, DSI_CMD_TERM); pr_err("%s: failed to tx max_pkt_size\n", @@ -1488,7 +1598,10 @@ int mdss_dsi_cmds_rx(struct mdss_dsi_ctrl_pdata *ctrl, mdss_dsi_wait4video_eng_busy(ctrl); /* video mode only */ mdss_dsi_enable_irq(ctrl, DSI_CMD_TERM); /* transmit read comamnd to client */ - ret = mdss_dsi_cmd_dma_tx(ctrl, tp); + if (use_dma_tpg) + ret = mdss_dsi_cmd_dma_tpg_tx(ctrl, tp); + else + ret = mdss_dsi_cmd_dma_tx(ctrl, tp); if (IS_ERR_VALUE(ret)) { mdss_dsi_disable_irq(ctrl, DSI_CMD_TERM); pr_err("%s: failed to tx cmd = 0x%x\n", @@ -1589,8 +1702,6 @@ int mdss_dsi_cmds_rx(struct mdss_dsi_ctrl_pdata *ctrl, return rp->read_cnt; } -#define DMA_TX_TIMEOUT 200 - static int mdss_dsi_cmd_dma_tx(struct mdss_dsi_ctrl_pdata *ctrl, struct dsi_buf *tp) { @@ -1984,7 +2095,8 @@ int mdss_dsi_cmdlist_tx(struct mdss_dsi_ctrl_pdata *ctrl, ctrl->do_unicast = true; } - len = mdss_dsi_cmds_tx(ctrl, req->cmds, req->cmds_cnt); + len = mdss_dsi_cmds_tx(ctrl, req->cmds, req->cmds_cnt, + (req->flags & CMD_REQ_DMA_TPG)); if (req->cb) req->cb(len); @@ -2000,7 +2112,8 @@ int mdss_dsi_cmdlist_rx(struct mdss_dsi_ctrl_pdata *ctrl, if (req->rbuf) { rp = &ctrl->rx_buf; - len = mdss_dsi_cmds_rx(ctrl, req->cmds, req->rlen); + len = mdss_dsi_cmds_rx(ctrl, req->cmds, req->rlen, + (req->flags & CMD_REQ_DMA_TPG)); memcpy(req->rbuf, rp->data, rp->len); ctrl->rx_len = len; } else { @@ -2047,6 +2160,11 @@ int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp) return rc; } + mdss_dsi_get_hw_revision(ctrl); + /* For DSI versions less than 1.3.0, CMD DMA TPG is not supported */ + if (ctrl->hw_rev < MDSS_DSI_HW_REV_103) + req->flags &= ~CMD_REQ_DMA_TPG; + pr_debug("%s: ctrl=%d from_mdp=%d pid=%d\n", __func__, ctrl->ndx, from_mdp, current->pid); @@ -2071,27 +2189,25 @@ int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp) MDSS_XLOG(ctrl->ndx, req->flags, req->cmds_cnt, from_mdp, current->pid); - /* - * mdss interrupt is generated in mdp core clock domain - * mdp clock need to be enabled to receive dsi interrupt - * also, axi bus bandwidth need since dsi controller will - * fetch dcs commands from axi bus - */ - if (ctrl->mdss_util->bus_bandwidth_ctrl) - ctrl->mdss_util->bus_bandwidth_ctrl(1); - - if (ctrl->mdss_util->bus_scale_set_quota) - ctrl->mdss_util->bus_scale_set_quota(MDSS_DSI_RT, SZ_1M, SZ_1M); pr_debug("%s: from_mdp=%d pid=%d\n", __func__, from_mdp, current->pid); mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 1); - if (ctrl->mdss_util->iommu_ctrl) { - rc = ctrl->mdss_util->iommu_ctrl(1); - if (IS_ERR_VALUE(rc)) { - pr_err("IOMMU attach failed\n"); - mutex_unlock(&ctrl->cmd_mutex); - return rc; + if (!(req->flags & CMD_REQ_DMA_TPG)) { + if (ctrl->mdss_util->bus_bandwidth_ctrl) + ctrl->mdss_util->bus_bandwidth_ctrl(1); + + if (ctrl->mdss_util->bus_scale_set_quota) + ctrl->mdss_util->bus_scale_set_quota(MDSS_DSI_RT, + SZ_1M, SZ_1M); + + if (ctrl->mdss_util->iommu_ctrl) { + rc = ctrl->mdss_util->iommu_ctrl(1); + if (IS_ERR_VALUE(rc)) { + pr_err("IOMMU attach failed\n"); + mutex_unlock(&ctrl->cmd_mutex); + return rc; + } } } @@ -2106,14 +2222,17 @@ int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp) if (req->flags & CMD_REQ_HS_MODE) mdss_dsi_set_tx_power_mode(1, &ctrl->panel_data); - if (ctrl->mdss_util->iommu_ctrl) - ctrl->mdss_util->iommu_ctrl(0); + if (!(req->flags & CMD_REQ_DMA_TPG)) { + if (ctrl->mdss_util->iommu_ctrl) + ctrl->mdss_util->iommu_ctrl(0); + + if (ctrl->mdss_util->bus_scale_set_quota) + ctrl->mdss_util->bus_scale_set_quota(MDSS_DSI_RT, 0, 0); + if (ctrl->mdss_util->bus_bandwidth_ctrl) + ctrl->mdss_util->bus_bandwidth_ctrl(0); + } mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 0); - if (ctrl->mdss_util->bus_scale_set_quota) - ctrl->mdss_util->bus_scale_set_quota(MDSS_DSI_RT, 0, 0); - if (ctrl->mdss_util->bus_bandwidth_ctrl) - ctrl->mdss_util->bus_bandwidth_ctrl(0); need_lock: MDSS_XLOG(ctrl->ndx, from_mdp, ctrl->mdp_busy, current->pid, @@ -2339,7 +2458,14 @@ void mdss_dsi_fifo_status(struct mdss_dsi_ctrl_pdata *ctrl) /* fifo underflow, overflow and empty*/ if (status & 0xcccc4489) { MIPI_OUTP(base + 0x000c, status); - pr_err("%s: status=%x\n", __func__, status); + + /* + * During dynamic refresh rate update, DSI fifo errors are + * expected, Check the dfps status and avoid the log. However, + * FIFO errors needs to be cleared. + */ + if (!ctrl->dfps_status) + pr_err("%s: status=%x\n", __func__, status); /* * if DSI FIFO overflow is masked, @@ -2358,6 +2484,9 @@ void mdss_dsi_fifo_status(struct mdss_dsi_ctrl_pdata *ctrl) if (status & 0x11110000) /* DLN_FIFO_EMPTY */ dsi_send_events(ctrl, DSI_EV_DSI_FIFO_EMPTY, 0); } + + if (ctrl->dfps_status) + ctrl->dfps_status = false; } void mdss_dsi_status(struct mdss_dsi_ctrl_pdata *ctrl) diff --git a/drivers/video/msm/mdss/mdss_dsi_panel.c b/drivers/video/msm/mdss/mdss_dsi_panel.c index 512e1030f5e19..45bff9588824c 100644 --- a/drivers/video/msm/mdss/mdss_dsi_panel.c +++ b/drivers/video/msm/mdss/mdss_dsi_panel.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -670,7 +670,7 @@ static int mdss_dsi_panel_on(struct mdss_panel_data *pdata) ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); - pr_debug("%s: ctrl=%p ndx=%d\n", __func__, ctrl, ctrl->ndx); + pr_debug("%s: ctrl=%pK ndx=%d\n", __func__, ctrl, ctrl->ndx); if (pinfo->dcs_cmd_by_left) { if (ctrl->ndx != DSI_CTRL_LEFT) @@ -700,7 +700,7 @@ static int mdss_dsi_post_panel_on(struct mdss_panel_data *pdata) ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); - pr_debug("%s: ctrl=%p ndx=%d\n", __func__, ctrl, ctrl->ndx); + pr_debug("%s: ctrl=%pK ndx=%d\n", __func__, ctrl, ctrl->ndx); pinfo = &pdata->panel_info; if (pinfo->dcs_cmd_by_left) { @@ -710,7 +710,7 @@ static int mdss_dsi_post_panel_on(struct mdss_panel_data *pdata) on_cmds = &ctrl->post_panel_on_cmds; - pr_debug("%s: ctrl=%p cmd_cnt=%d\n", __func__, ctrl, on_cmds->cmd_cnt); + pr_debug("%s: ctrl=%pK cmd_cnt=%d\n", __func__, ctrl, on_cmds->cmd_cnt); if (on_cmds->cmd_cnt) { msleep(50); /* wait for 3 vsync passed */ @@ -741,7 +741,7 @@ static int mdss_dsi_panel_off(struct mdss_panel_data *pdata) ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); - pr_debug("%s: ctrl=%p ndx=%d\n", __func__, ctrl, ctrl->ndx); + pr_debug("%s: ctrl=%pK ndx=%d\n", __func__, ctrl, ctrl->ndx); if (pinfo->dcs_cmd_by_left) { if (ctrl->ndx != DSI_CTRL_LEFT) @@ -772,7 +772,7 @@ static int mdss_dsi_panel_low_power_config(struct mdss_panel_data *pdata, ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); - pr_debug("%s: ctrl=%p ndx=%d enable=%d\n", __func__, ctrl, ctrl->ndx, + pr_debug("%s: ctrl=%pK ndx=%d enable=%d\n", __func__, ctrl, ctrl->ndx, enable); /* Any panel specific low power commands/config */ diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c index 3964a378062bd..2f3679c72b969 100644 --- a/drivers/video/msm/mdss/mdss_fb.c +++ b/drivers/video/msm/mdss/mdss_fb.c @@ -620,7 +620,7 @@ static int mdss_fb_lpm_enable(struct msm_fb_data_type *mfd, int mode) unlock_fb_info(mfd->fbi); mutex_lock(&mfd->bl_lock); - mfd->bl_updated = true; + mfd->allow_bl_update = true; mdss_fb_set_backlight(mfd, bl_lvl); mutex_unlock(&mfd->bl_lock); @@ -926,6 +926,8 @@ static int mdss_fb_remove(struct platform_device *pdev) if (mfd->key != MFD_KEY) return -EINVAL; + mdss_panel_debugfs_cleanup(mfd->panel_info); + if (mdss_fb_suspend_sub(mfd)) pr_err("msm_fb_remove: can't stop the device %d\n", mfd->index); @@ -1175,11 +1177,8 @@ void mdss_fb_set_backlight(struct msm_fb_data_type *mfd, u32 bkl_lvl) return; } - if ( -#ifndef CONFIG_LEDS_TRIGGER_BACKLIGHT - (((mdss_fb_is_power_off(mfd) && mfd->dcm_state != DCM_ENTER) - || !mfd->bl_updated) && !IS_CALIB_MODE_BL(mfd)) || -#endif + if ((((mdss_fb_is_power_off(mfd) && mfd->dcm_state != DCM_ENTER) + || !mfd->allow_bl_update) && !IS_CALIB_MODE_BL(mfd)) || mfd->panel_info->cont_splash_enabled) { mfd->unset_bl_level = bkl_lvl; return; @@ -1226,7 +1225,7 @@ void mdss_fb_update_backlight(struct msm_fb_data_type *mfd) if (!mfd->unset_bl_level) return; mutex_lock(&mfd->bl_lock); - if (!mfd->bl_updated) { + if (!mfd->allow_bl_update) { pdata = dev_get_platdata(&mfd->pdev->dev); if ((pdata) && (pdata->set_backlight)) { mfd->bl_level = mfd->unset_bl_level; @@ -1238,8 +1237,8 @@ void mdss_fb_update_backlight(struct msm_fb_data_type *mfd) mdss_fb_scale_bl(mfd, &temp); pdata->set_backlight(pdata, temp); mfd->bl_level_scaled = mfd->unset_bl_level; - mfd->bl_updated = 1; mdss_fb_bl_update_notify(mfd); + mfd->allow_bl_update = true; } } mutex_unlock(&mfd->bl_lock); @@ -1344,7 +1343,7 @@ static int mdss_fb_blank_blank(struct msm_fb_data_type *mfd, mdss_fb_stop_disp_thread(mfd); mutex_lock(&mfd->bl_lock); mdss_fb_set_backlight(mfd, 0); - mfd->bl_updated = 0; + mfd->allow_bl_update = false; mfd->unset_bl_level = current_bl; mutex_unlock(&mfd->bl_lock); } @@ -1411,8 +1410,8 @@ static int mdss_fb_blank_unblank(struct msm_fb_data_type *mfd) /* Reset the backlight only if the panel was off */ if (mdss_panel_is_power_off(cur_power_state)) { mutex_lock(&mfd->bl_lock); - if (!mfd->bl_updated) { - mfd->bl_updated = 1; + if (!mfd->allow_bl_update) { + mfd->allow_bl_update = true; /* * If in AD calibration mode then frameworks would not * be allowed to update backlight hence post unblank @@ -1423,6 +1422,13 @@ static int mdss_fb_blank_unblank(struct msm_fb_data_type *mfd) mdss_fb_set_backlight(mfd, mfd->calib_mode_bl); else if (!mfd->panel_info->mipi.post_init_delay) mdss_fb_set_backlight(mfd, mfd->unset_bl_level); + + /* + * it blocks the backlight update between unblank and + * first kickoff to avoid backlight turn on before black + * frame is transferred to panel through unblank call. + */ + mfd->allow_bl_update = false; } mutex_unlock(&mfd->bl_lock); } @@ -1647,7 +1653,7 @@ int mdss_fb_alloc_fb_ion_memory(struct msm_fb_data_type *mfd, size_t fb_size) goto fb_mmap_failed; } - pr_debug("alloc 0x%zuB vaddr = %p (%pa iova) for fb%d\n", fb_size, + pr_debug("alloc 0x%zuB vaddr = %pK (%pa iova) for fb%d\n", fb_size, vaddr, &mfd->iova, mfd->index); mfd->fbi->screen_base = (char *) vaddr; @@ -1740,7 +1746,7 @@ static int mdss_fb_fbmem_ion_mmap(struct fb_info *info, vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); - pr_debug("vma=%p, addr=%x len=%ld\n", + pr_debug("vma=%pK, addr=%x len=%ld\n", vma, (unsigned int)addr, len); pr_debug("vm_start=%x vm_end=%x vm_page_prot=%ld\n", (unsigned int)vma->vm_start, @@ -1910,7 +1916,7 @@ static int mdss_fb_alloc_fbmem_iommu(struct msm_fb_data_type *mfd, int dom) if (rc) pr_warn("Cannot map fb_mem %pa to IOMMU. rc=%d\n", &phys, rc); - pr_debug("alloc 0x%zxB @ (%pa phys) (0x%p virt) (%pa iova) for fb%d\n", + pr_debug("alloc 0x%zxB @ (%pa phys) (0x%pK virt) (%pa iova) for fb%d\n", size, &phys, virt, &mfd->iova, mfd->index); mfd->fbi->screen_base = virt; diff --git a/drivers/video/msm/mdss/mdss_fb.h b/drivers/video/msm/mdss/mdss_fb.h index 3327f1fbd90cc..c3f5811f2fc99 100644 --- a/drivers/video/msm/mdss/mdss_fb.h +++ b/drivers/video/msm/mdss/mdss_fb.h @@ -245,7 +245,7 @@ struct msm_fb_data_type { u32 bl_scale; u32 bl_min_lvl; u32 unset_bl_level; - u32 bl_updated; + bool allow_bl_update; u32 bl_level_scaled; struct mutex bl_lock; diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.c b/drivers/video/msm/mdss/mdss_hdmi_tx.c index 90f92678948c7..140a460b2acb7 100644 --- a/drivers/video/msm/mdss/mdss_hdmi_tx.c +++ b/drivers/video/msm/mdss/mdss_hdmi_tx.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2014,2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1035,7 +1035,7 @@ static int hdmi_tx_sysfs_create(struct hdmi_tx_ctrl *hdmi_ctrl, return rc; } hdmi_ctrl->kobj = &fbi->dev->kobj; - DEV_DBG("%s: sysfs group %p\n", __func__, hdmi_ctrl->kobj); + DEV_DBG("%s: sysfs group %pK\n", __func__, hdmi_ctrl->kobj); return 0; } /* hdmi_tx_sysfs_create */ @@ -3556,7 +3556,7 @@ static int hdmi_tx_init_resource(struct hdmi_tx_ctrl *hdmi_ctrl) DEV_DBG("%s: '%s' remap failed or not available\n", __func__, hdmi_tx_io_name(i)); } - DEV_INFO("%s: '%s': start = 0x%p, len=0x%x\n", __func__, + DEV_INFO("%s: '%s': start = 0x%pK, len=0x%x\n", __func__, hdmi_tx_io_name(i), pdata->io[i].base, pdata->io[i].len); } diff --git a/drivers/video/msm/mdss/mdss_hdmi_util.c b/drivers/video/msm/mdss/mdss_hdmi_util.c index b40ff288551c4..b50aee3483284 100644 --- a/drivers/video/msm/mdss/mdss_hdmi_util.c +++ b/drivers/video/msm/mdss/mdss_hdmi_util.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2014,2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -178,7 +178,7 @@ static void hdmi_ddc_print_data(struct hdmi_tx_ddc_data *ddc_data, return; } - DEV_DBG("%s: buf=%p, d_len=0x%x, d_addr=0x%x, no_align=%d\n", + DEV_DBG("%s: buf=%pK, d_len=0x%x, d_addr=0x%x, no_align=%d\n", caller, ddc_data->data_buf, ddc_data->data_len, ddc_data->dev_addr, ddc_data->no_align); DEV_DBG("%s: offset=0x%x, req_len=0x%x, retry=%d, what=%s\n", diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c index 4d9f3bf7f5edb..3a53359acb717 100644 --- a/drivers/video/msm/mdss/mdss_mdp.c +++ b/drivers/video/msm/mdss/mdss_mdp.c @@ -1207,7 +1207,7 @@ static u32 mdss_mdp_res_init(struct mdss_data_type *mdata) mdata->iclient = msm_ion_client_create(mdata->pdev->name); if (IS_ERR_OR_NULL(mdata->iclient)) { - pr_err("msm_ion_client_create() return error (%p)\n", + pr_err("msm_ion_client_create() return error (%pK)\n", mdata->iclient); mdata->iclient = NULL; } @@ -1423,10 +1423,29 @@ static ssize_t mdss_mdp_show_capabilities(struct device *dev, return cnt; } +static ssize_t mdss_mdp_store_max_limit_bw(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct mdss_data_type *mdata = dev_get_drvdata(dev); + u32 data = 0; + + if (kstrtouint(buf, 0, &data)) { + pr_info("Not able scan to bw_mode_bitmap\n"); + } else { + mdata->bw_mode_bitmap = data; + pr_debug("limit use case, bw_mode_bitmap = %d\n", data); + } + + return len; +} + static DEVICE_ATTR(caps, S_IRUGO, mdss_mdp_show_capabilities, NULL); +static DEVICE_ATTR(bw_mode_bitmap, S_IRUGO | S_IWUSR | S_IWGRP, NULL, + mdss_mdp_store_max_limit_bw); static struct attribute *mdp_fs_attrs[] = { &dev_attr_caps.attr, + &dev_attr_bw_mode_bitmap.attr, NULL }; @@ -1507,7 +1526,7 @@ static int mdss_mdp_probe(struct platform_device *pdev) if (rc) pr_debug("unable to map MDSS VBIF non-realtime base\n"); else - pr_debug("MDSS VBIF NRT HW Base addr=%p len=0x%x\n", + pr_debug("MDSS VBIF NRT HW Base addr=%pK len=0x%x\n", mdata->vbif_nrt_io.base, mdata->vbif_nrt_io.len); res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); @@ -2574,6 +2593,105 @@ static void mdss_mdp_parse_vbif_qos(struct platform_device *pdev) } } +static void mdss_mdp_parse_max_bw_array(const u32 *arr, + struct mdss_max_bw_settings *max_bw_settings, int count) +{ + int i; + for (i = 0; i < count; i++) { + max_bw_settings->mdss_max_bw_mode = be32_to_cpu(arr[i*2]); + max_bw_settings->mdss_max_bw_val = be32_to_cpu(arr[(i*2)+1]); + max_bw_settings++; + } +} + +static void mdss_mdp_parse_max_bandwidth(struct platform_device *pdev) +{ + struct mdss_data_type *mdata = platform_get_drvdata(pdev); + struct mdss_max_bw_settings *max_bw_settings; + int max_bw_settings_cnt = 0; + const u32 *max_bw; + + max_bw = of_get_property(pdev->dev.of_node, "qcom,max-bw-settings", + &max_bw_settings_cnt); + + if (!max_bw || !max_bw_settings_cnt) { + pr_debug("MDSS max bandwidth settings not found\n"); + return; + } + + max_bw_settings_cnt /= 2 * sizeof(u32); + + max_bw_settings = devm_kzalloc(&pdev->dev, sizeof(*max_bw_settings) + * max_bw_settings_cnt, GFP_KERNEL); + if (!max_bw_settings) { + pr_err("Memory allocation failed for max_bw_settings\n"); + return; + } + + mdss_mdp_parse_max_bw_array(max_bw, max_bw_settings, + max_bw_settings_cnt); + + mdata->max_bw_settings = max_bw_settings; + mdata->max_bw_settings_cnt = max_bw_settings_cnt; +} + +static void mdss_mdp_parse_per_pipe_bandwidth(struct platform_device *pdev) +{ + + struct mdss_data_type *mdata = platform_get_drvdata(pdev); + struct mdss_max_bw_settings *max_bw_per_pipe_settings; + int max_bw_settings_cnt = 0; + const u32 *max_bw_settings; + u32 max_bw, min_bw, threshold, i = 0; + + max_bw_settings = of_get_property(pdev->dev.of_node, + "qcom,max-bandwidth-per-pipe-kbps", + &max_bw_settings_cnt); + + if (!max_bw_settings || !max_bw_settings_cnt) { + pr_debug("MDSS per pipe max bandwidth settings not found\n"); + return; + } + + /* Support targets where a common per pipe max bw is provided */ + if ((max_bw_settings_cnt / sizeof(u32)) == 1) { + mdata->max_bw_per_pipe = be32_to_cpu(max_bw_settings[0]); + mdata->max_per_pipe_bw_settings = NULL; + pr_debug("Common per pipe max bandwidth provided\n"); + return; + } + + max_bw_settings_cnt /= 2 * sizeof(u32); + + max_bw_per_pipe_settings = devm_kzalloc(&pdev->dev, + sizeof(struct mdss_max_bw_settings) * max_bw_settings_cnt, + GFP_KERNEL); + if (!max_bw_per_pipe_settings) { + pr_err("Memory allocation failed for max_bw_settings\n"); + return; + } + + mdss_mdp_parse_max_bw_array(max_bw_settings, max_bw_per_pipe_settings, + max_bw_settings_cnt); + mdata->max_per_pipe_bw_settings = max_bw_per_pipe_settings; + mdata->mdss_per_pipe_bw_cnt = max_bw_settings_cnt; + + /* Calculate min and max allowed per pipe BW */ + min_bw = mdata->max_bw_high; + max_bw = 0; + + while (i < max_bw_settings_cnt) { + threshold = mdata->max_per_pipe_bw_settings[i].mdss_max_bw_val; + if (threshold > max_bw) + max_bw = threshold; + if (threshold < min_bw) + min_bw = threshold; + ++i; + } + mdata->max_bw_per_pipe = max_bw; + mdata->min_bw_per_pipe = min_bw; +} + static int mdss_mdp_parse_dt_misc(struct platform_device *pdev) { struct mdss_data_type *mdata = platform_get_drvdata(pdev); @@ -2692,10 +2810,9 @@ static int mdss_mdp_parse_dt_misc(struct platform_device *pdev) if (rc) pr_debug("max bandwidth (high) property not specified\n"); - rc = of_property_read_u32(pdev->dev.of_node, - "qcom,max-bandwidth-per-pipe-kbps", &mdata->max_bw_per_pipe); - if (rc) - pr_debug("max bandwidth (per pipe) property not specified\n"); + mdss_mdp_parse_per_pipe_bandwidth(pdev); + + mdss_mdp_parse_max_bandwidth(pdev); mdata->nclk_lvl = mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-clk-levels"); diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h index a70142f2116fa..e7524b8e33f3c 100644 --- a/drivers/video/msm/mdss/mdss_mdp.h +++ b/drivers/video/msm/mdss/mdss_mdp.h @@ -469,6 +469,8 @@ struct mdss_mdp_pipe { u8 chroma_sample_h; u8 chroma_sample_v; u8 csc_coeff_set; + + wait_queue_head_t free_waitq; }; struct mdss_mdp_writeback_arg { @@ -494,6 +496,7 @@ struct mdss_overlay_private { struct list_head overlay_list; struct list_head pipes_used; struct list_head pipes_cleanup; + struct list_head pipes_destroy; struct list_head rot_proc_list; bool mixer_swap; @@ -904,6 +907,8 @@ struct mdss_mdp_pipe *mdss_mdp_pipe_search(struct mdss_data_type *mdata, int mdss_mdp_pipe_map(struct mdss_mdp_pipe *pipe); void mdss_mdp_pipe_unmap(struct mdss_mdp_pipe *pipe); struct mdss_mdp_pipe *mdss_mdp_pipe_alloc_dma(struct mdss_mdp_mixer *mixer); +int mdss_mdp_get_pipe_info(struct mdss_data_type *mdata, u32 type, + struct mdss_mdp_pipe **pipe_pool); u32 mdss_mdp_smp_calc_num_blocks(struct mdss_mdp_pipe *pipe); u32 mdss_mdp_smp_get_size(struct mdss_mdp_pipe *pipe, u32 num_planes); diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c index 0f04a1230f673..100f5b4c6d24c 100644 --- a/drivers/video/msm/mdss/mdss_mdp_ctl.c +++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -908,13 +908,81 @@ static void __mdss_mdp_perf_calc_ctl_helper(struct mdss_mdp_ctl *ctl, *(perf->bw_vote_mode)); } +static u32 mdss_check_for_flip(struct mdss_mdp_ctl *ctl) +{ + u32 i, panel_orientation; + struct mdss_mdp_pipe *pipe; + u32 flags = 0; + + panel_orientation = ctl->mfd->panel_orientation; + if (panel_orientation & MDP_FLIP_LR) + flags |= MDSS_MAX_BW_LIMIT_HFLIP; + if (panel_orientation & MDP_FLIP_UD) + flags |= MDSS_MAX_BW_LIMIT_VFLIP; + + for (i = 0; i < MAX_PIPES_PER_LM; i++) { + if ((flags & MDSS_MAX_BW_LIMIT_HFLIP) && + (flags & MDSS_MAX_BW_LIMIT_VFLIP)) + return flags; + + if (ctl->mixer_left && ctl->mixer_left->stage_pipe[i]) { + pipe = ctl->mixer_left->stage_pipe[i]; + if (pipe->flags & MDP_FLIP_LR) + flags |= MDSS_MAX_BW_LIMIT_HFLIP; + if (pipe->flags & MDP_FLIP_UD) + flags |= MDSS_MAX_BW_LIMIT_VFLIP; + } + + if (ctl->mixer_right && ctl->mixer_right->stage_pipe[i]) { + pipe = ctl->mixer_right->stage_pipe[i]; + if (pipe->flags & MDP_FLIP_LR) + flags |= MDSS_MAX_BW_LIMIT_HFLIP; + if (pipe->flags & MDP_FLIP_UD) + flags |= MDSS_MAX_BW_LIMIT_VFLIP; + } + } + + return flags; +} + +static int mdss_mdp_set_threshold_max_bandwidth(struct mdss_mdp_ctl *ctl) +{ + u32 mode, threshold = 0, max = INT_MAX; + u32 i = 0; + struct mdss_max_bw_settings *max_bw_settings = + ctl->mdata->max_bw_settings; + + if (!ctl->mdata->max_bw_settings_cnt && !ctl->mdata->max_bw_settings) + return 0; + + mode = ctl->mdata->bw_mode_bitmap; + + if (!((mode & MDSS_MAX_BW_LIMIT_HFLIP) && + (mode & MDSS_MAX_BW_LIMIT_VFLIP))) + mode |= mdss_check_for_flip(ctl); + + pr_debug("final mode = %d, bw_mode_bitmap = %d\n", mode, + ctl->mdata->bw_mode_bitmap); + + /* Return minimum bandwidth limit */ + for (i = 0; i < ctl->mdata->max_bw_settings_cnt; i++) { + if (max_bw_settings[i].mdss_max_bw_mode & mode) { + threshold = max_bw_settings[i].mdss_max_bw_val; + if (threshold < max) + max = threshold; + } + } + + return max; +} + int mdss_mdp_perf_bw_check(struct mdss_mdp_ctl *ctl, struct mdss_mdp_pipe **left_plist, int left_cnt, struct mdss_mdp_pipe **right_plist, int right_cnt) { struct mdss_data_type *mdata = ctl->mdata; struct mdss_mdp_perf_params perf; - u32 bw, threshold; + u32 bw, threshold, max_bw; /* we only need bandwidth check on real-time clients (interfaces) */ if (ctl->intf_type == MDSS_MDP_NO_INTF) @@ -929,6 +997,14 @@ int mdss_mdp_perf_bw_check(struct mdss_mdp_ctl *ctl, pr_debug("calculated bandwidth=%uk\n", bw); threshold = ctl->is_video_mode ? mdata->max_bw_low : mdata->max_bw_high; + + max_bw = mdss_mdp_set_threshold_max_bandwidth(ctl); + + if (max_bw && (max_bw < threshold)) + threshold = max_bw; + + pr_debug("final threshold bw limit = %d\n", threshold); + if (bw > threshold) { pr_debug("exceeds bandwidth: %ukb > %ukb\n", bw, threshold); return -E2BIG; @@ -937,13 +1013,54 @@ int mdss_mdp_perf_bw_check(struct mdss_mdp_ctl *ctl, return 0; } +static u32 mdss_mdp_get_max_pipe_bw(struct mdss_mdp_pipe *pipe) +{ + + struct mdss_mdp_ctl *ctl = pipe->mixer_left->ctl; + struct mdss_max_bw_settings *max_per_pipe_bw_settings; + u32 flags = 0, threshold = 0, panel_orientation; + u32 i, max = INT_MAX; + + if (!ctl->mdata->mdss_per_pipe_bw_cnt + && !ctl->mdata->max_per_pipe_bw_settings) + return 0; + + panel_orientation = ctl->mfd->panel_orientation; + max_per_pipe_bw_settings = ctl->mdata->max_per_pipe_bw_settings; + + /* Check for panel orienatation */ + panel_orientation = ctl->mfd->panel_orientation; + if (panel_orientation & MDP_FLIP_LR) + flags |= MDSS_MAX_BW_LIMIT_HFLIP; + if (panel_orientation & MDP_FLIP_UD) + flags |= MDSS_MAX_BW_LIMIT_VFLIP; + + /* check for Hflip/Vflip in pipe */ + if (pipe->flags & MDP_FLIP_LR) + flags |= MDSS_MAX_BW_LIMIT_HFLIP; + if (pipe->flags & MDP_FLIP_UD) + flags |= MDSS_MAX_BW_LIMIT_VFLIP; + + flags |= ctl->mdata->bw_mode_bitmap; + + for (i = 0; i < ctl->mdata->mdss_per_pipe_bw_cnt; i++) { + if (max_per_pipe_bw_settings[i].mdss_max_bw_mode & flags) { + threshold = max_per_pipe_bw_settings[i].mdss_max_bw_val; + if (threshold < max) + max = threshold; + } + } + + return max; +} + int mdss_mdp_perf_bw_check_pipe(struct mdss_mdp_perf_params *perf, struct mdss_mdp_pipe *pipe) { struct mdss_data_type *mdata = pipe->mixer_left->ctl->mdata; struct mdss_mdp_ctl *ctl = pipe->mixer_left->ctl; u32 vbp_fac, threshold; - u64 prefill_bw, pipe_bw; + u64 prefill_bw, pipe_bw, max_pipe_bw; /* we only need bandwidth check on real-time clients (interfaces) */ if (ctl->intf_type == MDSS_MDP_NO_INTF) @@ -959,6 +1076,11 @@ int mdss_mdp_perf_bw_check_pipe(struct mdss_mdp_perf_params *perf, pipe_bw = DIV_ROUND_UP_ULL(pipe_bw, 1000); threshold = mdata->max_bw_per_pipe; + max_pipe_bw = mdss_mdp_get_max_pipe_bw(pipe); + + if (max_pipe_bw && (max_pipe_bw < threshold)) + threshold = max_pipe_bw; + pr_debug("bw=%llu threshold=%u\n", pipe_bw, threshold); if (threshold && pipe_bw > threshold) { @@ -3316,7 +3438,7 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg, } ATRACE_BEGIN("postproc_programming"); - if (ctl->mfd && ctl->mfd->dcm_state != DTM_ENTER) + if (ctl->is_video_mode && ctl->mfd && ctl->mfd->dcm_state != DTM_ENTER) /* postprocessing setup, including dspp */ mdss_mdp_pp_setup_locked(ctl); @@ -3359,6 +3481,14 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg, ATRACE_END("wait_pingpong sctl"); } } + + /* + * Moved pp programming to post ping pong + */ + if (!ctl->is_video_mode && ctl->mfd && ctl->mfd->dcm_state != DTM_ENTER) + /* postprocessing setup, including dspp */ + mdss_mdp_pp_setup_locked(ctl); + if (commit_cb) commit_cb->commit_cb_fnc(MDP_COMMIT_STAGE_READY_FOR_KICKOFF, commit_cb->data); diff --git a/drivers/video/msm/mdss/mdss_mdp_debug.c b/drivers/video/msm/mdss/mdss_mdp_debug.c index 39230d1968421..9b1ab8d9ab269 100644 --- a/drivers/video/msm/mdss/mdss_mdp_debug.c +++ b/drivers/video/msm/mdss/mdss_mdp_debug.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2014,2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -57,13 +57,13 @@ static void __dump_pipe(struct seq_file *s, struct mdss_mdp_pipe *pipe) seq_puts(s, "Data:\n"); if (pipe->front_buf.num_planes) { buf = pipe->front_buf.p; - seq_printf(s, "\tfront_buf ihdl=0x%p addr=%pa size=%lu\n", + seq_printf(s, "\tfront_buf ihdl=0x%pK addr=%pa size=%lu\n", buf->srcp_ihdl, &buf->addr, buf->len); } if (pipe->back_buf.num_planes) { buf = pipe->back_buf.p; - seq_printf(s, "\tback_buf ihdl=0x%p addr=%pa size=%lu\n", + seq_printf(s, "\tback_buf ihdl=0x%pK addr=%pa size=%lu\n", buf->srcp_ihdl, &buf->addr, buf->len); } } diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c index 6f6fc91b16b85..b07b3c523e5e1 100644 --- a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c +++ b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -581,7 +581,7 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg) ctx->rdptr_enabled, ctl->roi_bkup.w, ctl->roi_bkup.h); - pr_debug("%s: intf_num=%d ctx=%p koff_cnt=%d\n", __func__, + pr_debug("%s: intf_num=%d ctx=%pK koff_cnt=%d\n", __func__, ctl->intf_num, ctx, atomic_read(&ctx->koff_cnt)); rc = wait_event_timeout(ctx->pp_waitq, @@ -1164,7 +1164,7 @@ static int mdss_mdp_cmd_intfs_setup(struct mdss_mdp_ctl *ctl, ctx->intf_stopped = 0; - pr_debug("%s: ctx=%p num=%d mixer=%d\n", __func__, + pr_debug("%s: ctx=%pK num=%d mixer=%d\n", __func__, ctx, ctx->pp_num, mixer->num); MDSS_XLOG(ctl->num, atomic_read(&ctx->koff_cnt), ctx->clk_enabled, ctx->rdptr_enabled); diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_video.c b/drivers/video/msm/mdss/mdss_mdp_intf_video.c index 57fff13904c57..9ce6885af7544 100644 --- a/drivers/video/msm/mdss/mdss_mdp_intf_video.c +++ b/drivers/video/msm/mdss/mdss_mdp_intf_video.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -116,7 +116,7 @@ int mdss_mdp_video_addr_setup(struct mdss_data_type *mdata, for (i = 0; i < count; i++) { head[i].base = mdata->mdss_io.base + offsets[i]; - pr_debug("adding Video Intf #%d offset=0x%x virt=%p\n", i, + pr_debug("adding Video Intf #%d offset=0x%x virt=%pK\n", i, offsets[i], head[i].base); head[i].ref_cnt = 0; head[i].intf_num = i + MDSS_MDP_INTF0; @@ -213,7 +213,7 @@ static void mdss_mdp_video_intf_recovery(void *data, int event) mutex_unlock(&ctl->offlock); return; } else { - pr_warn("line count is less. line_cnt = %d\n", + pr_warn_once("line count is less. line_cnt = %d\n", line_cnt); /* Add delay so that line count is in active region */ udelay(delay); @@ -442,7 +442,7 @@ static int mdss_mdp_video_intfs_stop(struct mdss_mdp_ctl *ctl, pr_err("Intf %d not in use\n", (inum + MDSS_MDP_INTF0)); return -ENODEV; } - pr_debug("stop ctl=%d video Intf #%d base=%p", ctl->num, + pr_debug("stop ctl=%d video Intf #%d base=%pK", ctl->num, ctx->intf_num, ctx->base); } else { pr_err("Invalid intf number: %d\n", (inum + MDSS_MDP_INTF0)); @@ -1158,7 +1158,7 @@ static int mdss_mdp_video_intfs_setup(struct mdss_mdp_ctl *ctl, (inum + MDSS_MDP_INTF0)); return -EBUSY; } - pr_debug("video Intf #%d base=%p", ctx->intf_num, ctx->base); + pr_debug("video Intf #%d base=%pK", ctx->intf_num, ctx->base); ctx->ref_cnt++; } else { pr_err("Invalid intf number: %d\n", (inum + MDSS_MDP_INTF0)); diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c index 26df88aee1aa7..c61574478a4c3 100644 --- a/drivers/video/msm/mdss/mdss_mdp_overlay.c +++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c @@ -44,6 +44,8 @@ #define IS_RIGHT_MIXER_OV(flags, dst_x, left_lm_w) \ ((flags & MDSS_MDP_RIGHT_MIXER) || (dst_x >= left_lm_w)) +#define PIPE_CLEANUP_TIMEOUT_US 100000 + static int mdss_mdp_overlay_free_fb_pipe(struct msm_fb_data_type *mfd); static int mdss_mdp_overlay_fb_parse_dt(struct msm_fb_data_type *mfd); static int mdss_mdp_overlay_off(struct msm_fb_data_type *mfd); @@ -570,6 +572,96 @@ static inline void __mdss_mdp_overlay_set_chroma_sample( pipe->chroma_sample_v = 0; } +static int mdss_mdp_wait4pipe_helper(struct mdss_mdp_ctl *ctl, + u32 pipe_type) +{ + struct mdss_mdp_pipe *pipe = NULL; + struct mdss_mdp_mixer *mixer; + struct mdss_overlay_private *mdp5_data; + int pipe_cleanup_map = 0; + + if (!ctl || !ctl->mfd) + return 0; + + mixer = ctl->mixer_left; + mdp5_data = mfd_to_mdp5_data(ctl->mfd); + + if (!mixer->rotator_mode) { + mutex_lock(&mdp5_data->list_lock); + list_for_each_entry(pipe, &mdp5_data->pipes_destroy, list) { + if (pipe_type == pipe->type) { + pipe_cleanup_map |= pipe->ndx; + break; + } + } + if (!pipe_cleanup_map) { + list_for_each_entry(pipe, &mdp5_data->pipes_cleanup, + list) { + if (pipe_type == pipe->type) { + pipe_cleanup_map |= pipe->ndx; + break; + } + } + } + mutex_unlock(&mdp5_data->list_lock); + } else if (mixer->rotator_mode && + (pipe_type == MDSS_MDP_PIPE_TYPE_DMA)) { + if (ctl->mixer_left->num == MDSS_MDP_WB_LAYERMIXER0) + pipe_cleanup_map |= BIT(MDSS_MDP_SSPP_DMA0); + else + pipe_cleanup_map |= BIT(MDSS_MDP_SSPP_DMA1); + } + + return pipe_cleanup_map; +} + +static struct mdss_mdp_pipe *mdss_mdp_wait4pipe(struct msm_fb_data_type *mfd, + struct mdss_mdp_mixer *mixer, u32 pipe_type, + struct mdss_mdp_pipe *left_blend_pipe) +{ + struct mdss_mdp_pipe *pipes = NULL; + u32 i, npipes = 0; + int pipe_cleanup_map = 0; + struct mdss_mdp_pipe *wait_pipe = NULL; + struct mdss_data_type *mdata = mfd_to_mdata(mfd); + struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd); + + for (i = 0; i < mdata->nctl; i++) { + struct mdss_mdp_ctl *ctl = mdata->ctl_off + i; + if ((ctl != mdp5_data->ctl) && mdss_mdp_ctl_is_power_on(ctl)) + pipe_cleanup_map |= mdss_mdp_wait4pipe_helper(ctl, + pipe_type); + } + + npipes = mdss_mdp_get_pipe_info(mdata, pipe_type, &pipes); + + for (i = 0; i < npipes; i++) { + if (pipe_cleanup_map & pipes[i].ndx) { + wait_pipe = &pipes[i]; + break; + } + } + + if (wait_pipe) { + int ret; + + pr_debug("wait for pipe, pipe_type_used_map = 0x%x, pipe num = %d\n", + pipe_cleanup_map, wait_pipe->num); + + ret = wait_event_interruptible_timeout(wait_pipe->free_waitq, + !atomic_read(&wait_pipe->kref.refcount), + usecs_to_jiffies(PIPE_CLEANUP_TIMEOUT_US)); + if (IS_ERR_VALUE(ret)) + return NULL; + else + return mdss_mdp_pipe_alloc(mixer, pipe_type, + left_blend_pipe); + } + + return mdss_mdp_pipe_alloc(mixer, pipe_type, + left_blend_pipe); +} + int mdss_mdp_overlay_pipe_setup(struct msm_fb_data_type *mfd, struct mdp_overlay *req, struct mdss_mdp_pipe **ppipe, struct mdss_mdp_pipe *left_blend_pipe, bool is_single_layer) @@ -683,6 +775,10 @@ int mdss_mdp_overlay_pipe_setup(struct msm_fb_data_type *mfd, pipe = mdss_mdp_pipe_alloc(mixer, pipe_type, left_blend_pipe); + if (IS_ERR_OR_NULL(pipe) && (PTR_ERR(pipe) != -EBADSLT)) + pipe = mdss_mdp_wait4pipe(mfd, mixer, pipe_type, + left_blend_pipe); + /* RGB pipes can be used instead of DMA */ if ((req->pipe_type == PIPE_TYPE_AUTO) && !pipe && (pipe_type == MDSS_MDP_PIPE_TYPE_DMA)) { @@ -1091,8 +1187,7 @@ static void __mdss_mdp_overlay_free_list_add(struct msm_fb_data_type *mfd, * Goes through destroy_pipes list and ensures they are ready to be destroyed * and cleaned up. Also cleanup of any pipe buffers after flip. */ -static void mdss_mdp_overlay_cleanup(struct msm_fb_data_type *mfd, - struct list_head *destroy_pipes) +static void mdss_mdp_overlay_cleanup(struct msm_fb_data_type *mfd) { struct mdss_mdp_pipe *pipe, *tmp; struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd); @@ -1100,7 +1195,7 @@ static void mdss_mdp_overlay_cleanup(struct msm_fb_data_type *mfd, bool recovery_mode = false; mutex_lock(&mdp5_data->list_lock); - list_for_each_entry(pipe, destroy_pipes, list) { + list_for_each_entry(pipe, &mdp5_data->pipes_destroy, list) { /* make sure pipe fetch has been halted before freeing buffer */ if (mdss_mdp_pipe_fetch_halt(pipe)) { /* @@ -1135,7 +1230,7 @@ static void mdss_mdp_overlay_cleanup(struct msm_fb_data_type *mfd, } } - list_for_each_entry_safe(pipe, tmp, destroy_pipes, list) { + list_for_each_entry_safe(pipe, tmp, &mdp5_data->pipes_destroy, list) { /* * in case of secure UI, the buffer needs to be released as * soon as session is closed. @@ -1158,28 +1253,13 @@ static void mdss_mdp_overlay_cleanup(struct msm_fb_data_type *mfd, void mdss_mdp_handoff_cleanup_pipes(struct msm_fb_data_type *mfd, u32 type) { - u32 i, npipes; - struct mdss_mdp_pipe *pipes; + u32 i, npipes = 0; + struct mdss_mdp_pipe *pipes = NULL; struct mdss_mdp_pipe *pipe; struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd); struct mdss_data_type *mdata = mfd_to_mdata(mfd); - switch (type) { - case MDSS_MDP_PIPE_TYPE_VIG: - pipes = mdata->vig_pipes; - npipes = mdata->nvig_pipes; - break; - case MDSS_MDP_PIPE_TYPE_RGB: - pipes = mdata->rgb_pipes; - npipes = mdata->nrgb_pipes; - break; - case MDSS_MDP_PIPE_TYPE_DMA: - pipes = mdata->dma_pipes; - npipes = mdata->ndma_pipes; - break; - default: - return; - } + npipes = mdss_mdp_get_pipe_info(mdata, type, &pipes); for (i = 0; i < npipes; i++) { pipe = &pipes[i]; @@ -1224,6 +1304,10 @@ int mdss_mdp_overlay_start(struct msm_fb_data_type *mfd) mfd->index); return 0; } + } else if (mdata->handoff_pending) { + pr_warn("fb%d: commit while splash handoff pending\n", + mfd->index); + return -EPERM; } pr_debug("starting fb%d overlay\n", mfd->index); @@ -1442,7 +1526,6 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd, int sd_in_pipe = 0; bool need_cleanup = false; struct mdss_mdp_commit_cb commit_cb; - LIST_HEAD(destroy_pipes); ATRACE_BEGIN(__func__); if (ctl->shared_lock) { @@ -1521,7 +1604,7 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd, mdss_mdp_pipe_queue_data(pipe, NULL); mdss_mdp_mixer_pipe_unstage(pipe, pipe->mixer_left); mdss_mdp_mixer_pipe_unstage(pipe, pipe->mixer_right); - list_move(&pipe->list, &destroy_pipes); + list_move(&pipe->list, &mdp5_data->pipes_destroy); need_cleanup = true; } @@ -1584,7 +1667,7 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd, mdss_fb_update_notify_update(mfd); commit_fail: ATRACE_BEGIN("overlay_cleanup"); - mdss_mdp_overlay_cleanup(mfd, &destroy_pipes); + mdss_mdp_overlay_cleanup(mfd); ATRACE_END("overlay_cleanup"); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF); mdss_mdp_ctl_notify(ctl, MDP_NOTIFY_FRAME_FLUSHED); @@ -4141,6 +4224,7 @@ int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd) INIT_LIST_HEAD(&mdp5_data->pipes_used); INIT_LIST_HEAD(&mdp5_data->pipes_cleanup); + INIT_LIST_HEAD(&mdp5_data->pipes_destroy); INIT_LIST_HEAD(&mdp5_data->rot_proc_list); mutex_init(&mdp5_data->list_lock); mutex_init(&mdp5_data->ov_lock); diff --git a/drivers/video/msm/mdss/mdss_mdp_pipe.c b/drivers/video/msm/mdss/mdss_mdp_pipe.c index 77790f297587f..d8d01afb4e059 100644 --- a/drivers/video/msm/mdss/mdss_mdp_pipe.c +++ b/drivers/video/msm/mdss/mdss_mdp_pipe.c @@ -805,43 +805,29 @@ static void mdss_mdp_fixed_qos_arbiter_setup(struct mdss_data_type *mdata, mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF); } -static struct mdss_mdp_pipe *mdss_mdp_pipe_init(struct mdss_mdp_mixer *mixer, - u32 type, u32 off, struct mdss_mdp_pipe *left_blend_pipe) +int mdss_mdp_get_pipe_info(struct mdss_data_type *mdata, u32 type, + struct mdss_mdp_pipe **pipe_pool) { - struct mdss_mdp_pipe *pipe = NULL; - struct mdss_data_type *mdata; - struct mdss_mdp_pipe *pipe_pool = NULL; - u32 npipes; - bool pipe_share = false; - bool is_realtime; - u32 i, reg_val, force_off_mask; - - if (!mixer || !mixer->ctl || !mixer->ctl->mdata) - return NULL; - - mdata = mixer->ctl->mdata; + int npipes; switch (type) { case MDSS_MDP_PIPE_TYPE_VIG: - pipe_pool = mdata->vig_pipes; + *pipe_pool = mdata->vig_pipes; npipes = mdata->nvig_pipes; break; case MDSS_MDP_PIPE_TYPE_RGB: - pipe_pool = mdata->rgb_pipes; + *pipe_pool = mdata->rgb_pipes; npipes = mdata->nrgb_pipes; break; case MDSS_MDP_PIPE_TYPE_DMA: - pipe_pool = mdata->dma_pipes; + *pipe_pool = mdata->dma_pipes; npipes = mdata->ndma_pipes; - if ((mdata->wfd_mode == MDSS_MDP_WFD_SHARED) && - (mixer->type == MDSS_MDP_MIXER_TYPE_WRITEBACK)) - pipe_share = true; break; case MDSS_MDP_PIPE_TYPE_CURSOR: - pipe_pool = mdata->cursor_pipes; + *pipe_pool = mdata->cursor_pipes; npipes = mdata->ncursor_pipes; break; @@ -849,7 +835,39 @@ static struct mdss_mdp_pipe *mdss_mdp_pipe_init(struct mdss_mdp_mixer *mixer, npipes = 0; pr_err("invalid pipe type %d\n", type); break; - } +} + + return npipes; +} + +static void mdss_mdp_init_pipe_params(struct mdss_mdp_pipe *pipe) +{ + kref_init(&pipe->kref); + init_waitqueue_head(&pipe->free_waitq); +} + +static struct mdss_mdp_pipe *mdss_mdp_pipe_init(struct mdss_mdp_mixer *mixer, + u32 type, u32 off, struct mdss_mdp_pipe *left_blend_pipe) +{ + struct mdss_mdp_pipe *pipe = NULL; + struct mdss_data_type *mdata; + struct mdss_mdp_pipe *pipe_pool = NULL; + u32 npipes = 0; + bool pipe_share = false; + bool is_realtime; + u32 i, reg_val, force_off_mask; + + if (!mixer || !mixer->ctl || !mixer->ctl->mdata) + return NULL; + + mdata = mixer->ctl->mdata; + + npipes = mdss_mdp_get_pipe_info(mdata, type, &pipe_pool); + + if (type == MDSS_MDP_PIPE_TYPE_DMA && + (mdata->wfd_mode == MDSS_MDP_WFD_SHARED) && + (mixer->type == MDSS_MDP_MIXER_TYPE_WRITEBACK)) + pipe_share = true; for (i = off; i < npipes; i++) { pipe = pipe_pool + i; @@ -861,7 +879,7 @@ static struct mdss_mdp_pipe *mdss_mdp_pipe_init(struct mdss_mdp_mixer *mixer, } if (pipe && type == MDSS_MDP_PIPE_TYPE_CURSOR) { - kref_init(&pipe->kref); + mdss_mdp_init_pipe_params(pipe); goto cursor_done; } @@ -900,7 +918,7 @@ static struct mdss_mdp_pipe *mdss_mdp_pipe_init(struct mdss_mdp_mixer *mixer, pr_debug("type=%x pnum=%d\n", pipe->type, pipe->num); mutex_init(&pipe->pp_res.hist.hist_mutex); spin_lock_init(&pipe->pp_res.hist.hist_lock); - kref_init(&pipe->kref); + mdss_mdp_init_pipe_params(pipe); is_realtime = !((mixer->ctl->intf_num == MDSS_MDP_NO_INTF) || mixer->rotator_mode); mdss_mdp_qos_vbif_remapper_setup(mdata, pipe, is_realtime); @@ -1238,6 +1256,7 @@ int mdss_mdp_pipe_destroy(struct mdss_mdp_pipe *pipe) return -EBUSY; } + wake_up_all(&pipe->free_waitq); mutex_unlock(&mdss_mdp_sspp_lock); return 0; @@ -1305,7 +1324,7 @@ int mdss_mdp_pipe_handoff(struct mdss_mdp_pipe *pipe) pipe->is_handed_off = true; pipe->play_cnt = 1; - kref_init(&pipe->kref); + mdss_mdp_init_pipe_params(pipe); error: return rc; @@ -1720,7 +1739,7 @@ int mdss_mdp_pipe_queue_data(struct mdss_mdp_pipe *pipe, } if (src_data == NULL) { - pr_debug("src_data=%p pipe num=%dx\n", + pr_debug("src_data=%pK pipe num=%dx\n", src_data, pipe->num); goto update_nobuf; } diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c index 501e9d11d2d4f..6b136eaabf00c 100644 --- a/drivers/video/msm/mdss/mdss_mdp_pp.c +++ b/drivers/video/msm/mdss/mdss_mdp_pp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -2226,7 +2226,7 @@ static int pp_ad_calc_bl(struct msm_fb_data_type *mfd, int bl_in, int *bl_out, pr_debug("AD not supported on device.\n"); return ret; } else if (ret || !ad) { - pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n", + pr_err("Failed to get ad info: ret = %d, ad = 0x%pK.\n", ret, ad); return ret; } @@ -2242,7 +2242,7 @@ static int pp_ad_calc_bl(struct msm_fb_data_type *mfd, int bl_in, int *bl_out, if (!ad->bl_mfd || !ad->bl_mfd->panel_info || !ad->bl_att_lut) { - pr_err("Invalid ad info: bl_mfd = 0x%p, ad->bl_mfd->panel_info = 0x%p, bl_att_lut = 0x%p\n", + pr_err("Invalid ad info: bl_mfd = 0x%pK, ad->bl_mfd->panel_info = 0x%pK, bl_att_lut = 0x%pK\n", ad->bl_mfd, (!ad->bl_mfd) ? NULL : ad->bl_mfd->panel_info, ad->bl_att_lut); @@ -3607,7 +3607,7 @@ static int pp_hist_enable(struct pp_hist_col_info *hist_info, spin_lock_irqsave(&hist_info->hist_lock, flag); if (hist_info->col_en) { spin_unlock_irqrestore(&hist_info->hist_lock, flag); - pr_info("%s Hist collection has already been enabled %p\n", + pr_info("%s Hist collection has already been enabled %pK\n", __func__, hist_info->base); goto exit; } @@ -3744,15 +3744,17 @@ static int pp_hist_disable(struct pp_hist_col_info *hist_info) spin_lock_irqsave(&hist_info->hist_lock, flag); if (hist_info->col_en == false) { spin_unlock_irqrestore(&hist_info->hist_lock, flag); - pr_debug("Histogram already disabled (%p)\n", hist_info->base); + pr_debug("Histogram already disabled (%pK)\n", hist_info->base); ret = -EINVAL; goto exit; } - hist_info->col_en = false; - hist_info->col_state = HIST_UNKNOWN; spin_unlock_irqrestore(&hist_info->hist_lock, flag); mdss_mdp_hist_intr_req(&mdata->hist_intr, intr_mask << hist_info->intr_shift, false); + spin_lock_irqsave(&hist_info->hist_lock, flag); + hist_info->col_en = false; + hist_info->col_state = HIST_UNKNOWN; + spin_unlock_irqrestore(&hist_info->hist_lock, flag); complete_all(&hist_info->first_kick); complete_all(&hist_info->comp); /* if hist v2, make sure HW is unlocked */ @@ -3858,7 +3860,7 @@ int mdss_mdp_hist_intr_req(struct mdss_intr *intr, u32 bits, bool en) unsigned long flag; int ret = 0; if (!intr) { - pr_err("NULL addr passed, %p\n", intr); + pr_err("NULL addr passed, %pK\n", intr); return -EINVAL; } @@ -4418,6 +4420,7 @@ void mdss_mdp_hist_intr_done(u32 isr) bool need_complete = false; u32 isr_mask = (is_hist_v2) ? HIST_V2_INTR_BIT_MASK : HIST_V1_INTR_BIT_MASK; + u32 intr_mask = is_hist_v2 ? 1 : 3; isr &= isr_mask; while (isr != 0) { @@ -4452,7 +4455,16 @@ void mdss_mdp_hist_intr_done(u32 isr) * Histogram collection is disabled yet we got an * interrupt somehow. */ - pr_err("hist Done interrupt, col_en=false!\n"); + if (mdata->mdp_hist_irq_mask == + (intr_mask << hist_info->intr_shift)) { + mdss_mdp_hist_intr_req(&mdata->hist_intr, + intr_mask << hist_info->intr_shift, + false); + pr_err("Disable hist interrupt, irq mask=%x\n", + mdata->mdp_hist_irq_mask); + } else { + pr_err("hist Done interrupt, col_en=false!\n"); + } } /* Histogram Reset Done Interrupt */ if (hist_info && is_hist_reset_done && (hist_info->col_en)) { @@ -4612,7 +4624,7 @@ static int pp_ad_invalidate_input(struct msm_fb_data_type *mfd) ret = mdss_mdp_get_ad(mfd, &ad); if (ret || !ad) { - pr_err("Fail to get ad: ret = %d, ad = 0x%p\n", ret, ad); + pr_err("Fail to get ad: ret = %d, ad = 0x%pK\n", ret, ad); return -EINVAL; } pr_debug("AD backlight level changed (%d), trigger update to AD\n", diff --git a/drivers/video/msm/mdss/mdss_mdp_splash_logo.c b/drivers/video/msm/mdss/mdss_mdp_splash_logo.c index 805fd43b0b33b..9598cf34107fb 100644 --- a/drivers/video/msm/mdss/mdss_mdp_splash_logo.c +++ b/drivers/video/msm/mdss/mdss_mdp_splash_logo.c @@ -563,7 +563,7 @@ static int mdss_mdp_splash_thread(void *data) unlock_fb_info(mfd->fbi); mutex_lock(&mfd->bl_lock); - mfd->bl_updated = true; + mfd->allow_bl_update = true; mdss_fb_set_backlight(mfd, mfd->panel_info->bl_max >> 1); mutex_unlock(&mfd->bl_lock); diff --git a/drivers/video/msm/mdss/mdss_mdp_util.c b/drivers/video/msm/mdss/mdss_mdp_util.c index c62acf3db78b0..926dfdef15851 100644 --- a/drivers/video/msm/mdss/mdss_mdp_util.c +++ b/drivers/video/msm/mdss/mdss_mdp_util.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -507,7 +507,7 @@ static int mdss_mdp_put_img(struct mdss_mdp_img_data *data) pr_debug("pmem buf=0x%pa\n", &data->addr); data->srcp_file = NULL; } else if (!IS_ERR_OR_NULL(data->srcp_ihdl)) { - pr_debug("ion hdl=%p buf=0x%pa\n", data->srcp_ihdl, + pr_debug("ion hdl=%pK buf=0x%pa\n", data->srcp_ihdl, &data->addr); if (!iclient) { pr_err("invalid ion client\n"); @@ -599,7 +599,7 @@ static int mdss_mdp_get_img(struct msmfb_data *img, data->addr += data->offset; data->len -= data->offset; - pr_debug("mem=%d ihdl=%p buf=0x%pa len=0x%lu\n", img->memory_id, + pr_debug("mem=%d ihdl=%pK buf=0x%pa len=0x%lu\n", img->memory_id, data->srcp_ihdl, &data->addr, data->len); } else { mdss_mdp_put_img(data); @@ -653,7 +653,7 @@ static int mdss_mdp_map_buffer(struct mdss_mdp_img_data *data) data->addr += data->offset; data->len -= data->offset; - pr_debug("ihdl=%p buf=0x%pa len=0x%lu\n", + pr_debug("ihdl=%pK buf=0x%pa len=0x%lu\n", data->srcp_ihdl, &data->addr, data->len); } else { mdss_mdp_put_img(data); diff --git a/drivers/video/msm/mdss/mdss_mdp_wb.c b/drivers/video/msm/mdss/mdss_mdp_wb.c index def90ebb39490..da6587ef6a54f 100644 --- a/drivers/video/msm/mdss/mdss_mdp_wb.c +++ b/drivers/video/msm/mdss/mdss_mdp_wb.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -95,7 +95,7 @@ struct mdss_mdp_data *mdss_mdp_wb_debug_buffer(struct msm_fb_data_type *mfd) ihdl = ion_alloc(iclient, img_size, SZ_4K, ION_HEAP(ION_SF_HEAP_ID), 0); if (IS_ERR_OR_NULL(ihdl)) { - pr_err("unable to alloc fbmem from ion (%p)\n", ihdl); + pr_err("unable to alloc fbmem from ion (%pK)\n", ihdl); return NULL; } @@ -122,7 +122,7 @@ struct mdss_mdp_data *mdss_mdp_wb_debug_buffer(struct msm_fb_data_type *mfd) img->len = img_size; } - pr_debug("ihdl=%p virt=%p phys=0x%pa iova=0x%pa size=%u\n", + pr_debug("ihdl=%pK virt=%pK phys=0x%pa iova=0x%pa size=%u\n", ihdl, videomemory, &mdss_wb_mem, &img->addr, img_size); } return &mdss_wb_buffer; @@ -435,7 +435,7 @@ static struct mdss_mdp_wb_data *get_user_node(struct msm_fb_data_type *mfd, list_for_each_entry(node, &wb->register_queue, registered_entry) if ((node->buf_data.p[0].srcp_ihdl == ihdl) && (node->buf_info.offset == data->offset)) { - pr_debug("found fd=%d hdl=%p off=%x addr=%pa\n", + pr_debug("found fd=%d hdl=%pK off=%x addr=%pa\n", data->memory_id, ihdl, data->offset, &node->buf_data.p[0].addr); @@ -501,7 +501,7 @@ static void mdss_mdp_wb_free_node(struct mdss_mdp_wb_data *node) if (node->user_alloc) { buf = &node->buf_data.p[0]; - pr_debug("free user mem_id=%d ihdl=%p, offset=%u addr=0x%pa\n", + pr_debug("free user mem_id=%d ihdl=%pK, offset=%u addr=0x%pa\n", node->buf_info.memory_id, buf->srcp_ihdl, node->buf_info.offset, diff --git a/drivers/video/msm/mdss/mdss_panel.c b/drivers/video/msm/mdss/mdss_panel.c index 4095eee43046a..a240429d35c79 100644 --- a/drivers/video/msm/mdss/mdss_panel.c +++ b/drivers/video/msm/mdss/mdss_panel.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -33,6 +33,7 @@ int mdss_panel_debugfs_setup(struct mdss_panel_info *panel_info, struct dentry } debugfs_info->root = debugfs_create_dir(dsi_str, parent); + debugfs_info->parent = parent; if (IS_ERR_OR_NULL(debugfs_info->root)) { pr_err("Debugfs create dir failed with error: %ld\n", PTR_ERR(debugfs_info->root)); @@ -100,6 +101,7 @@ int mdss_panel_debugfs_init(struct mdss_panel_info *panel_info) dsi_str); if (rc) { pr_err("error in initilizing panel debugfs\n"); + mdss_panel_debugfs_cleanup(&pdata->panel_info); return rc; } pdata = pdata->next; @@ -113,13 +115,16 @@ void mdss_panel_debugfs_cleanup(struct mdss_panel_info *panel_info) { struct mdss_panel_data *pdata; struct mdss_panel_debugfs_info *debugfs_info; + struct dentry *parent = NULL; pdata = container_of(panel_info, struct mdss_panel_data, panel_info); do { debugfs_info = pdata->panel_info.debugfs_info; - if (debugfs_info && debugfs_info->root) - debugfs_remove_recursive(debugfs_info->root); + if (debugfs_info && !parent) + parent = debugfs_info->parent; + kfree(debugfs_info); pdata = pdata->next; } while (pdata); + debugfs_remove_recursive(parent); pr_debug("Cleaned up mdss_panel_debugfs_info\n"); } diff --git a/drivers/video/msm/mdss/mdss_panel.h b/drivers/video/msm/mdss/mdss_panel.h index 1aa51b2ff6683..13a979b8dd758 100644 --- a/drivers/video/msm/mdss/mdss_panel.h +++ b/drivers/video/msm/mdss/mdss_panel.h @@ -474,6 +474,7 @@ struct mdss_panel_debugfs_info { u32 xres; u32 yres; struct lcd_panel_info lcdc; + struct dentry *parent; u32 override_flag; char frame_rate; struct mdss_panel_debugfs_info *next; diff --git a/drivers/video/msm/mdss/mdss_util.c b/drivers/video/msm/mdss/mdss_util.c index 587db41a9d105..345b0927bc58e 100644 --- a/drivers/video/msm/mdss/mdss_util.c +++ b/drivers/video/msm/mdss/mdss_util.c @@ -1,5 +1,4 @@ - -/* Copyright (c) 2007-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2007-2014,2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -33,7 +32,7 @@ int mdss_register_irq(struct mdss_hw *hw) if (!mdss_irq_handlers[hw->hw_ndx]) mdss_irq_handlers[hw->hw_ndx] = hw; else - pr_err("panel %d's irq at %p is already registered\n", + pr_err("panel %d's irq at %pK is already registered\n", hw->hw_ndx, hw->irq_handler); spin_unlock_irqrestore(&mdss_lock, irq_flags); diff --git a/fs/ecryptfs/kthread.c b/fs/ecryptfs/kthread.c index f1ea610362c6c..84e7d54799eea 100644 --- a/fs/ecryptfs/kthread.c +++ b/fs/ecryptfs/kthread.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "ecryptfs_kernel.h" struct ecryptfs_open_req { @@ -147,7 +148,7 @@ int ecryptfs_privileged_open(struct file **lower_file, flags |= IS_RDONLY(lower_dentry->d_inode) ? O_RDONLY : O_RDWR; (*lower_file) = dentry_open(&req.path, flags, cred); if (!IS_ERR(*lower_file)) - goto out; + goto have_file; if ((flags & O_ACCMODE) == O_RDONLY) { rc = PTR_ERR((*lower_file)); goto out; @@ -165,8 +166,17 @@ int ecryptfs_privileged_open(struct file **lower_file, mutex_unlock(&ecryptfs_kthread_ctl.mux); wake_up(&ecryptfs_kthread_ctl.wait); wait_for_completion(&req.done); - if (IS_ERR(*lower_file)) + if (IS_ERR(*lower_file)) { rc = PTR_ERR(*lower_file); + goto out; + } + +have_file: + if ((*lower_file)->f_op->mmap == NULL) { + fput(*lower_file); + *lower_file = NULL; + rc = -EMEDIUMTYPE; + } out: return rc; } diff --git a/fs/fuse/Makefile b/fs/fuse/Makefile index e95eeb445e587..15b0b7edbec01 100644 --- a/fs/fuse/Makefile +++ b/fs/fuse/Makefile @@ -5,4 +5,4 @@ obj-$(CONFIG_FUSE_FS) += fuse.o obj-$(CONFIG_CUSE) += cuse.o -fuse-objs := dev.o dir.o file.o inode.o control.o +fuse-objs := dev.o dir.o file.o inode.o control.o shortcircuit.o diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index f4e875a29e7aa..8121e6aa3fa67 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -7,6 +7,7 @@ */ #include "fuse_i.h" +#include "fuse_shortcircuit.h" #include #include @@ -1876,6 +1877,8 @@ static ssize_t fuse_dev_do_write(struct fuse_conn *fc, err = copy_out_args(cs, &req->out, nbytes); fuse_copy_finish(cs); + fuse_setup_shortcircuit(fc, req); + spin_lock(&fc->lock); req->locked = 0; if (!err) { diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 28fa6811f6a6d..5f7df9946785e 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -472,6 +472,9 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, if (err) goto out_free_ff; + if (req->private_lower_rw_file != NULL) + ff->rw_lower_file = req->private_lower_rw_file; + err = -EIO; if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid)) goto out_free_ff; diff --git a/fs/fuse/file.c b/fs/fuse/file.c index e95b1e3efa5d2..354e7e206f5f8 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -7,6 +7,7 @@ */ #include "fuse_i.h" +#include "fuse_shortcircuit.h" #include #include @@ -21,7 +22,8 @@ static const struct file_operations fuse_direct_io_file_operations; static int fuse_send_open(struct fuse_conn *fc, u64 nodeid, struct file *file, - int opcode, struct fuse_open_out *outargp) + int opcode, struct fuse_open_out *outargp, + struct file **lower_file) { struct fuse_open_in inarg; struct fuse_req *req; @@ -45,6 +47,10 @@ static int fuse_send_open(struct fuse_conn *fc, u64 nodeid, struct file *file, req->out.args[0].value = outargp; fuse_request_send(fc, req); err = req->out.h.error; + + if (!err && req->private_lower_rw_file != NULL) + *lower_file = req->private_lower_rw_file; + fuse_put_request(fc, req); return err; @@ -58,6 +64,10 @@ struct fuse_file *fuse_file_alloc(struct fuse_conn *fc) if (unlikely(!ff)) return NULL; + ff->rw_lower_file = NULL; + ff->shortcircuit_enabled = 0; + if (fc->shortcircuit_io) + ff->shortcircuit_enabled = 1; ff->fc = fc; ff->reserved_req = fuse_request_alloc(0); if (unlikely(!ff->reserved_req)) { @@ -153,7 +163,8 @@ int fuse_do_open(struct fuse_conn *fc, u64 nodeid, struct file *file, if (!ff) return -ENOMEM; - err = fuse_send_open(fc, nodeid, file, opcode, &outarg); + err = fuse_send_open(fc, nodeid, file, opcode, &outarg, + &(ff->rw_lower_file)); if (err) { fuse_file_free(ff); return err; @@ -261,6 +272,8 @@ void fuse_release_common(struct file *file, int opcode) if (unlikely(!ff)) return; + fuse_shortcircuit_release(ff); + req = ff->reserved_req; fuse_prepare_release(ff, file->f_flags, opcode); @@ -959,8 +972,10 @@ static int fuse_readpages(struct file *file, struct address_space *mapping, static ssize_t fuse_file_aio_read(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t pos) { + ssize_t ret_val; struct inode *inode = iocb->ki_filp->f_mapping->host; struct fuse_conn *fc = get_fuse_conn(inode); + struct fuse_file *ff = iocb->ki_filp->private_data; /* * In auto invalidate mode, always update attributes on read. @@ -975,7 +990,12 @@ static ssize_t fuse_file_aio_read(struct kiocb *iocb, const struct iovec *iov, return err; } - return generic_file_aio_read(iocb, iov, nr_segs, pos); + if (ff && ff->shortcircuit_enabled && ff->rw_lower_file) + ret_val = fuse_shortcircuit_aio_read(iocb, iov, nr_segs, pos); + else + ret_val = generic_file_aio_read(iocb, iov, nr_segs, pos); + + return ret_val; } static void fuse_write_fill(struct fuse_req *req, struct fuse_file *ff, @@ -1213,6 +1233,7 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, { struct file *file = iocb->ki_filp; struct address_space *mapping = file->f_mapping; + struct fuse_file *ff = file->private_data; size_t count = 0; size_t ocount = 0; ssize_t written = 0; @@ -1231,7 +1252,7 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, return generic_file_aio_write(iocb, iov, nr_segs, pos); } - WARN_ON(iocb->ki_pos != pos); + BUG_ON(iocb->ki_pos != pos); ocount = 0; err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ); @@ -1259,6 +1280,24 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, if (err) goto out; + if (ff && ff->shortcircuit_enabled && ff->rw_lower_file) { + /* Use iocb->ki_pos instead of pos to handle the cases of files + * that are opened with O_APPEND. For example if multiple + * processes open the same file with O_APPEND then the + * iocb->ki_pos will not be equal to the new pos value that is + * updated with the file size(to guarantee appends even when + * the file has grown due to the writes by another process). + * We should use iocb->pos here since the lower filesystem + * is expected to adjust for O_APPEND anyway and may need to + * adjust the size for the file changes that occur due to + * some processes writing directly to the lower filesystem + * without using fuse. + */ + written = fuse_shortcircuit_aio_write(iocb, iov, nr_segs, + iocb->ki_pos); + goto out; + } + if (file->f_flags & O_DIRECT) { written = generic_file_direct_write(iocb, iov, &nr_segs, pos, &iocb->ki_pos, @@ -1839,6 +1878,9 @@ static const struct vm_operations_struct fuse_file_vm_ops = { static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma) { + struct fuse_file *ff = file->private_data; + + ff->shortcircuit_enabled = 0; if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE)) fuse_link_write_file(file); @@ -1849,6 +1891,10 @@ static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma) static int fuse_direct_mmap(struct file *file, struct vm_area_struct *vma) { + struct fuse_file *ff = file->private_data; + + ff->shortcircuit_enabled = 0; + /* Can't provide the coherency needed for MAP_SHARED */ if (vma->vm_flags & VM_MAYSHARE) return -ENODEV; diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index fba925b6a7bd5..f04a3e35781a8 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -157,6 +157,10 @@ struct fuse_file { /** Has flock been performed on this file? */ bool flock:1; + + /* the read write file */ + struct file *rw_lower_file; + bool shortcircuit_enabled; }; /** One input argument of a request */ @@ -361,6 +365,9 @@ struct fuse_req { /** Request is stolen from fuse_file->reserved_req */ struct file *stolen_file; + + /** fuse shortcircuit file */ + struct file *private_lower_rw_file; }; /** @@ -483,6 +490,9 @@ struct fuse_conn { /** write-back cache policy (default is write-through) */ unsigned writeback_cache:1; + /** Shortcircuited IO. */ + unsigned shortcircuit_io:1; + /* * The following bitfields are only for optimization purposes * and hence races in setting them will not cause malfunction diff --git a/fs/fuse/fuse_shortcircuit.h b/fs/fuse/fuse_shortcircuit.h new file mode 100644 index 0000000000000..5f269f9667f24 --- /dev/null +++ b/fs/fuse/fuse_shortcircuit.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2015, 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 _FS_FUSE_SHORCIRCUIT_H +#define _FS_FUSE_SHORCIRCUIT_H + +#include "fuse_i.h" + +#include +#include + +void fuse_setup_shortcircuit(struct fuse_conn *fc, struct fuse_req *req); + +ssize_t fuse_shortcircuit_aio_read(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos); + +ssize_t fuse_shortcircuit_aio_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos); + +void fuse_shortcircuit_release(struct fuse_file *ff); + +#endif /* _FS_FUSE_SHORCIRCUIT_H */ diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 2fa29257cf17a..54862c4955342 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -891,6 +891,12 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) fc->async_dio = 1; if (arg->flags & FUSE_WRITEBACK_CACHE) fc->writeback_cache = 1; + if (arg->flags & FUSE_SHORTCIRCUIT) { + fc->writeback_cache = 0; + fc->shortcircuit_io = 1; + pr_info("FUSE: SHORTCIRCUIT enabled [%s : %d]!\n", + current->comm, current->pid); + } if (arg->time_gran && arg->time_gran <= 1000000000) fc->sb->s_time_gran = arg->time_gran; else diff --git a/fs/fuse/shortcircuit.c b/fs/fuse/shortcircuit.c new file mode 100644 index 0000000000000..cf13c38d4a2e3 --- /dev/null +++ b/fs/fuse/shortcircuit.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2015, 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 "fuse_shortcircuit.h" + +#include +#include + +void fuse_setup_shortcircuit(struct fuse_conn *fc, struct fuse_req *req) +{ + int daemon_fd; + struct file *rw_lower_file = NULL; + struct fuse_open_out *open_out; + int open_out_index; + + req->private_lower_rw_file = NULL; + + if (!(fc->shortcircuit_io)) + return; + + if ((req->in.h.opcode != FUSE_OPEN) && + (req->in.h.opcode != FUSE_CREATE)) + return; + + open_out_index = req->in.numargs - 1; + + BUG_ON(open_out_index != 0 && open_out_index != 1); + BUG_ON(req->out.args[open_out_index].size != sizeof(*open_out)); + + open_out = req->out.args[open_out_index].value; + + daemon_fd = (int)open_out->lower_fd; + if (daemon_fd < 0) + return; + + rw_lower_file = fget_raw(daemon_fd); + if (!rw_lower_file) + return; + req->private_lower_rw_file = rw_lower_file; +} + +static ssize_t fuse_shortcircuit_aio_read_write(struct kiocb *iocb, + const struct iovec *iov, + unsigned long nr_segs, + loff_t pos, int do_write) +{ + ssize_t ret_val; + struct fuse_file *ff; + struct file *fuse_file, *lower_file; + struct inode *fuse_inode, *lower_inode; + + ff = iocb->ki_filp->private_data; + fuse_file = iocb->ki_filp; + lower_file = ff->rw_lower_file; + + /* lock lower file to prevent it from being released */ + get_file(lower_file); + iocb->ki_filp = lower_file; + fuse_inode = fuse_file->f_path.dentry->d_inode; + lower_inode = file_inode(lower_file); + + if (do_write) { + if (!lower_file->f_op->aio_write) + return -EIO; + + ret_val = lower_file->f_op->aio_write(iocb, iov, nr_segs, pos); + + if (ret_val >= 0 || ret_val == -EIOCBQUEUED) { + fsstack_copy_inode_size(fuse_inode, lower_inode); + fsstack_copy_attr_times(fuse_inode, lower_inode); + } + } else { + if (!lower_file->f_op->aio_read) + return -EIO; + + ret_val = lower_file->f_op->aio_read(iocb, iov, nr_segs, pos); + if (ret_val >= 0 || ret_val == -EIOCBQUEUED) + fsstack_copy_attr_atime(fuse_inode, lower_inode); + } + + iocb->ki_filp = fuse_file; + fput(lower_file); + /* unlock lower file */ + + return ret_val; +} + +ssize_t fuse_shortcircuit_aio_read(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) +{ + return fuse_shortcircuit_aio_read_write(iocb, iov, nr_segs, pos, 0); +} + +ssize_t fuse_shortcircuit_aio_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) +{ + return fuse_shortcircuit_aio_read_write(iocb, iov, nr_segs, pos, 1); +} + +void fuse_shortcircuit_release(struct fuse_file *ff) +{ + if (!(ff->rw_lower_file)) + return; + + /* Release the lower file. */ + fput(ff->rw_lower_file); + ff->rw_lower_file = NULL; +} diff --git a/fs/proc/fd.c b/fs/proc/fd.c index d7a4a28ef6302..50ac26b3182f7 100644 --- a/fs/proc/fd.c +++ b/fs/proc/fd.c @@ -305,7 +305,7 @@ int proc_fd_permission(struct inode *inode, int mask) int rv = generic_permission(inode, mask); if (rv == 0) return 0; - if (task_pid(current) == proc_pid(inode)) + if (task_tgid(current) == proc_pid(inode)) rv = 0; return rv; } diff --git a/fs/read_write.c b/fs/read_write.c index 1653768438362..d77987d787e95 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -411,7 +411,7 @@ ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, lof kiocb.ki_left = len; kiocb.ki_nbytes = len; - ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos); + ret = filp->f_op->aio_write(&kiocb, &iov, 1, *ppos); if (-EIOCBQUEUED == ret) ret = wait_on_sync_kiocb(&kiocb); *ppos = kiocb.ki_pos; diff --git a/include/linux/diagchar.h b/include/linux/diagchar.h index 548b79e00f763..ea58a3d28754c 100644 --- a/include/linux/diagchar.h +++ b/include/linux/diagchar.h @@ -139,10 +139,10 @@ the appropriate macros. */ /* This needs to be modified manually now, when we add a new RANGE of SSIDs to the msg_mask_tbl */ #define MSG_MASK_TBL_CNT 25 -#define APPS_EVENT_LAST_ID 0x0A70 +#define APPS_EVENT_LAST_ID 0x0B14 #define MSG_SSID_0 0 -#define MSG_SSID_0_LAST 111 +#define MSG_SSID_0_LAST 118 #define MSG_SSID_1 500 #define MSG_SSID_1_LAST 506 #define MSG_SSID_2 1000 @@ -154,15 +154,15 @@ the appropriate macros. */ #define MSG_SSID_5 4000 #define MSG_SSID_5_LAST 4010 #define MSG_SSID_6 4500 -#define MSG_SSID_6_LAST 4526 +#define MSG_SSID_6_LAST 4573 #define MSG_SSID_7 4600 #define MSG_SSID_7_LAST 4615 #define MSG_SSID_8 5000 -#define MSG_SSID_8_LAST 5031 +#define MSG_SSID_8_LAST 5032 #define MSG_SSID_9 5500 #define MSG_SSID_9_LAST 5516 #define MSG_SSID_10 6000 -#define MSG_SSID_10_LAST 6080 +#define MSG_SSID_10_LAST 6081 #define MSG_SSID_11 6500 #define MSG_SSID_11_LAST 6521 #define MSG_SSID_12 7000 @@ -174,7 +174,7 @@ the appropriate macros. */ #define MSG_SSID_15 8000 #define MSG_SSID_15_LAST 8000 #define MSG_SSID_16 8500 -#define MSG_SSID_16_LAST 8524 +#define MSG_SSID_16_LAST 8529 #define MSG_SSID_17 9000 #define MSG_SSID_17_LAST 9008 #define MSG_SSID_18 9500 @@ -321,7 +321,17 @@ static const uint32_t msg_bld_masks_0[] = { MSG_LVL_HIGH, MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, - MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_LOW, + MSG_LVL_MED, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_MED, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_HIGH }; static const uint32_t msg_bld_masks_1[] = { @@ -392,13 +402,60 @@ static const uint32_t msg_bld_masks_5[] = { }; static const uint32_t msg_bld_masks_6[] = { - MSG_LVL_MED, - MSG_LVL_MED, - MSG_LVL_MED, - MSG_LVL_MED, - MSG_LVL_MED, - MSG_LVL_MED, - MSG_LVL_MED, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, MSG_LVL_LOW, MSG_LVL_LOW, MSG_LVL_LOW, @@ -472,6 +529,7 @@ static const uint32_t msg_bld_masks_8[] = { MSG_LVL_MED, MSG_LVL_MED, MSG_LVL_MED, + MSG_LVL_MED, MSG_LVL_MED }; @@ -581,7 +639,8 @@ static const uint32_t msg_bld_masks_10[] = { MSG_LVL_LOW, MSG_LVL_LOW, MSG_LVL_LOW, - MSG_LVL_LOW + MSG_LVL_LOW, + MSG_LVL_MED }; static const uint32_t msg_bld_masks_11[] = { @@ -666,6 +725,11 @@ static const uint32_t msg_bld_masks_16[] = { MSG_LVL_LOW, MSG_LVL_LOW, MSG_LVL_LOW, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL }; static const uint32_t msg_bld_masks_17[] = { @@ -785,7 +849,7 @@ static const uint32_t msg_bld_masks_23[] = { /* LOG CODES */ static const uint32_t log_code_last_tbl[] = { 0x0, /* EQUIP ID 0 */ - 0x18A4, /* EQUIP ID 1 */ + 0x1966, /* EQUIP ID 1 */ 0x0, /* EQUIP ID 2 */ 0x0, /* EQUIP ID 3 */ 0x4910, /* EQUIP ID 4 */ @@ -797,7 +861,7 @@ static const uint32_t log_code_last_tbl[] = { 0xA38A, /* EQUIP ID 10 */ 0xB201, /* EQUIP ID 11 */ 0x0, /* EQUIP ID 12 */ - 0x0, /* EQUIP ID 13 */ + 0xD1FF, /* EQUIP ID 13 */ 0x0, /* EQUIP ID 14 */ 0x0, /* EQUIP ID 15 */ }; diff --git a/include/linux/i2c/mmc3x30.h b/include/linux/i2c/mmc3x30.h new file mode 100644 index 0000000000000..38a78c83c4ef0 --- /dev/null +++ b/include/linux/i2c/mmc3x30.h @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2010 MEMSIC, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* + * Definitions for mmc3x30 magnetic sensor chip. + */ +#ifndef __MMC3X30_H__ +#define __MMC3X30_H__ + +#include + + +#define MMC3X30_I2C_NAME "mmc3x30" + +#define MMC3X30_I2C_ADDR 0x30 + +//MEMSIC MMC3X30 Data +#define MMC3X30_REG_DATA 0x00 + +//MEMSIC MMC35XX REG +#define MMC35XX_REG_STATUS 0x06 +#define MMC35XX_REG_CTRL0 0x07 +#define MMC35XX_REG_CTRL1 0x08 +#define MMC35XX_REG_ID 0x20 +#define MMC35XX_REG_OTP 0x1B + +//MEMSIC MMC36XX REG +#define MMC36XX_REG_TMPT 0x06 +#define MMC36XX_REG_STATUS 0x07 +#define MMC36XX_REG_CTRL0 0x08 +#define MMC36XX_REG_CTRL1 0x09 +#define MMC36XX_REG_CTRL2 0x0A +#define MMC36XX_REG_X_THLD 0x0B +#define MMC36XX_REG_Y_THLD 0x0C +#define MMC36XX_REG_Z_THLD 0x0D +#define MMC36XX_REG_SELF_TEST 0x0E +#define MMC36XX_REG_OTP_GATE0 0x0F +#define MMC36XX_REG_OTP_GATE1 0x12 +#define MMC36XX_REG_OTP_GATE2 0x13 +#define MMC36XX_REG_OTP 0x2A +#define MMC36XX_REG_ID 0x2F + +//MEMSIC MMC35XX CMD +#define MMC35XX_SINGLE_TM 0x01 +#define MMC35XX_BW_16BIT_SLOW 0x00 +#define MMC35XX_BW_16BIT_FAST 0x01 +#define MMC35XX_BW_14BIT 0x02 +#define MMC35XX_CONT_MODE 0x02 +#define MMC35XX_CONT_FREQ_50HZ 0x00 +#define MMC35XX_CONT_FREQ_25HZ 0x04 +#define MMC35XX_CONT_FREQ_12HZ 0x08 +#define MMC35XX_CONT_FREQ_1_5HZ 0x0C + +//MEMSIC MMC36XX CMD +#define MMC36XX_OTP_OPEN0 0xE1 +#define MMC36XX_OTP_OPEN1 0x11 +#define MMC36XX_OTP_OPEN2 0x80 +#define MMC36XX_SINGLE_TM 0x01 +#define MMC36XX_SINGLE_TMPT 0x02 +#define MMC36XX_BW_16BIT_100HZ 0x00 +#define MMC36XX_BW_16BIT_200HZ 0x01 +#define MMC36XX_BW_16BIT_400HZ 0x02 +#define MMC36XX_BW_16BIT_600HZ 0x03 + +/*MMC35XX RESET*/ +#define MMC35XX_FILLCAP 0x80 +#define MMC35XX_RESET 0x40 +#define MMC35XX_SET 0x20 +#define MMC35XX_NOBOOST 0x10 +#define MMC35XX_ST_XYZ 0x20 +/*MEMSIC MMC35XX Status */ +#define MMC35XX_STATUS_MEASURE_DONE 0x01 +#define MMC35XX_STATUS_CHARGE_PUMP 0x02 +#define MMC35XX_STATUS_ST_XYZ 0x08 + +/*MMC36XX RESET*/ +#define MMC36XX_FILLCAP 0x20 +#define MMC36XX_RESET 0x10 +#define MMC36XX_SET 0x08 +#define MMC36XX_ST_POST 0x02 +#define MMC36XX_ST_NEGT 0x04 +#define MMC36XX_ST_DEFAULT 0x00 +#define MMC36XX_ST_DELTA_VALUE 100 +/*MEMSIC MMC36XX Status */ +#define MMC36XX_STATUS_MEASURE_DONE 0x01 +#define MMC36XX_STATUS_CHARGE_PUMP 0x08 + +/*DEVICE ID*/ +#define MMC3524_DEVICE_ID 0x08 +#define MMC3530_DEVICE_ID 0x09 +#define MMC3630_DEVICE_ID 0x0A + + +/* Use 'm' as magic number */ +#define MMC3X30_IOM 'm' +/* IOCTLs for MMC3X30 device */ +#define MMC3X30_IOC_TM _IO(MMC3X30_IOM, 0x00) +#define MMC3X30_IOC_SET _IO(MMC3X30_IOM, 0x01) +#define MMC3X30_IOC_READ _IOR(MMC3X30_IOM, 0x02, int[3]) +#define MMC3X30_IOC_READXYZ _IOR(MMC3X30_IOM, 0x03, int[3]) +#define MMC3X30_IOC_RESET _IO(MMC3X30_IOM, 0x04) +#define MMC3X30_IOC_NOBOOST _IO(MMC3X30_IOM, 0x05) +#define MMC3X30_IOC_ID _IOR(MMC3X30_IOM, 0x06, short) +#define MMC3X30_IOC_DIAG _IOR(MMC3X30_IOM, 0x14, int[1]) +#define MMC3X30_IOC_READ_REG _IOWR(MMC3X30_IOM, 0x15, unsigned char) +#define MMC3X30_IOC_WRITE_REG _IOW(MMC3X30_IOM, 0x16, unsigned char[2]) +#define MMC3X30_IOC_READ_REGS _IOWR(MMC3X30_IOM, 0x17, unsigned char[10]) +#define MMC3X30_IOC_WRITE_REGS _IOW(MMC3X30_IOM, 0x18, unsigned char[10]) + +#ifdef CONFIG_COMPAT +/* IOCTLs for MMC3X30 device */ +#define COMPAT_MMC3X30_IOC_TM _IO(MMC3X30_IOM, 0x00) +#define COMPAT_MMC3X30_IOC_SET _IO(MMC3X30_IOM, 0x01) +#define COMPAT_MMC3X30_IOC_READ _IOR(MMC3X30_IOM, 0x02, int[3]) +#define COMPAT_MMC3X30_IOC_READXYZ _IOR(MMC3X30_IOM, 0x03, int[3]) +#define COMPAT_MMC3X30_IOC_RESET _IO(MMC3X30_IOM, 0x04) +#define COMPAT_MMC3X30_IOC_NOBOOST _IO(MMC3X30_IOM, 0x05) +#define COMPAT_MMC3X30_IOC_ID _IOR(MMC3X30_IOM, 0x06, short) +#define COMPAT_MMC3X30_IOC_DIAG _IOR(MMC3X30_IOM, 0x14, int[1]) +#define COMPAT_MMC3X30_IOC_READ_REG _IOWR(MMC3X30_IOM, 0x15, unsigned char) +#define COMPAT_MMC3X30_IOC_WRITE_REG _IOW(MMC3X30_IOM, 0x16, unsigned char[2]) +#define COMPAT_MMC3X30_IOC_READ_REGS _IOWR(MMC3X30_IOM, 0x17, unsigned char[10]) +#define COMPAT_MMC3X30_IOC_WRITE_REGS _IOW(MMC3X30_IOM, 0x18, unsigned char[10]) +#endif + +#endif /* __MMC3X30_H__ */ + diff --git a/include/linux/inet_diag.h b/include/linux/inet_diag.h index 46da02410a096..25de5e73845cb 100644 --- a/include/linux/inet_diag.h +++ b/include/linux/inet_diag.h @@ -3,6 +3,7 @@ #include +struct net; struct sock; struct inet_hashinfo; struct nlattr; @@ -23,6 +24,10 @@ struct inet_diag_handler { void (*idiag_get_info)(struct sock *sk, struct inet_diag_msg *r, void *info); + + int (*destroy)(struct sk_buff *in_skb, + struct inet_diag_req_v2 *req); + __u16 idiag_type; }; @@ -39,6 +44,10 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_skb, const struct nlmsghdr *nlh, struct inet_diag_req_v2 *req); +struct sock *inet_diag_find_one_icsk(struct net *net, + struct inet_hashinfo *hashinfo, + struct inet_diag_req_v2 *req); + int inet_diag_bc_sk(const struct nlattr *_bc, struct sock *sk); extern int inet_diag_register(const struct inet_diag_handler *handler); diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index a6c5471822d38..f6f0c3cfd6771 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -41,6 +41,7 @@ struct ipv6_devconf { __s32 accept_source_route; #ifdef CONFIG_IPV6_OPTIMISTIC_DAD __s32 optimistic_dad; + __s32 use_optimistic; #endif #ifdef CONFIG_IPV6_MROUTE __s32 mc_forwarding; @@ -51,6 +52,7 @@ struct ipv6_devconf { __s32 ndisc_notify; __s32 accept_ra_prefix_route; __s32 accept_ra_mtu; + __s32 use_oif_addrs_only; void *sysctl; }; @@ -220,7 +222,7 @@ struct ipv6_pinfo { struct ipv6_ac_socklist *ipv6_ac_list; struct ipv6_fl_socklist __rcu *ipv6_fl_list; - struct ipv6_txoptions *opt; + struct ipv6_txoptions __rcu *opt; struct sk_buff *pktoptions; struct sk_buff *rxpmtu; struct { @@ -273,9 +275,9 @@ static inline struct inet6_timewait_sock *inet6_twsk(const struct sock *sk) } #if IS_ENABLED(CONFIG_IPV6) -static inline struct ipv6_pinfo * inet6_sk(const struct sock *__sk) +static inline struct ipv6_pinfo *inet6_sk(const struct sock *__sk) { - return inet_sk(__sk)->pinet6; + return sk_fullsock(__sk) ? inet_sk(__sk)->pinet6 : NULL; } static inline struct inet6_request_sock * diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 3d0723d93ec3c..1bd97aa78ce18 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -29,6 +29,19 @@ #define ULLONG_MAX (~0ULL) #define SIZE_MAX (~(size_t)0) +#define U8_MAX ((u8)~0U) +#define S8_MAX ((s8)(U8_MAX>>1)) +#define S8_MIN ((s8)(-S8_MAX - 1)) +#define U16_MAX ((u16)~0U) +#define S16_MAX ((s16)(U16_MAX>>1)) +#define S16_MIN ((s16)(-S16_MAX - 1)) +#define U32_MAX ((u32)~0U) +#define S32_MAX ((s32)(U32_MAX>>1)) +#define S32_MIN ((s32)(-S32_MAX - 1)) +#define U64_MAX ((u64)~0ULL) +#define S64_MAX ((s64)(U64_MAX>>1)) +#define S64_MIN ((s64)(-S64_MAX - 1)) + #define STACK_MAGIC 0xdeadbeef #define REPEAT_BYTE(x) ((~0ul / 0xff) * (x)) diff --git a/include/linux/mm.h b/include/linux/mm.h index 5ee09340acef2..269e3eddc0fd5 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -47,6 +47,17 @@ extern int sysctl_legacy_va_layout; #define sysctl_legacy_va_layout 0 #endif +#ifdef CONFIG_HAVE_ARCH_MMAP_RND_BITS +extern const int mmap_rnd_bits_min; +extern const int mmap_rnd_bits_max; +extern int mmap_rnd_bits __read_mostly; +#endif +#ifdef CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS +extern const int mmap_rnd_compat_bits_min; +extern const int mmap_rnd_compat_bits_max; +extern int mmap_rnd_compat_bits __read_mostly; +#endif + #include #include #include diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index faeaaf0bf9f18..ba89e363f3576 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -84,7 +84,7 @@ struct mmc_ext_csd { bool hpi; /* HPI support bit */ unsigned int hpi_cmd; /* cmd used as HPI */ bool bkops; /* background support bit */ - bool bkops_en; /* background enable bit */ + u8 bkops_en; /* background enable bits */ unsigned int data_sector_size; /* 512 bytes or 4KB */ unsigned int data_tag_unit_size; /* DATA TAG UNIT size */ unsigned int boot_ro_lock; /* ro lock support */ @@ -401,6 +401,23 @@ struct mmc_card { u8 *cached_ext_csd; }; +/* + * mmc_csd registers get/set/clr helpers + */ +#define mmc_card_get_bkops_en_manual(card) ((card->ext_csd.bkops_en) &\ + EXT_CSD_BKOPS_EN_MANUAL_EN) +#define mmc_card_set_bkops_en_manual(card) ((card->ext_csd.bkops_en) |= \ + EXT_CSD_BKOPS_EN_MANUAL_EN) +#define mmc_card_clr_bkops_en_manual(card) ((card->ext_csd.bkops_en) &= \ + ~EXT_CSD_BKOPS_EN_MANUAL_EN) + +#define mmc_card_get_bkops_en_auto(card) ((card->ext_csd.bkops_en) & \ + EXT_CSD_BKOPS_EN_AUTO_EN) +#define mmc_card_set_bkops_en_auto(card) ((card->ext_csd.bkops_en) |= \ + EXT_CSD_BKOPS_EN_AUTO_EN) +#define mmc_card_clr_bkops_en_auto(card) ((card->ext_csd.bkops_en) &= \ + ~EXT_CSD_BKOPS_EN_AUTO_EN) + /* * This function fill contents in mmc_part. */ diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index addf849db89d5..d8cbe40c8f5fb 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -282,6 +282,9 @@ struct _mmc_csd { * EXT_CSD field definitions */ +#define EXT_CSD_BKOPS_EN_MANUAL_EN BIT(0) +#define EXT_CSD_BKOPS_EN_AUTO_EN BIT(1) + #define EXT_CSD_WR_REL_PARAM_EN (1<<2) #define EXT_CSD_WR_REL_PARAM_EN_RPMB (1<<4) diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index d3ac528a935bd..f1213e198fa4c 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -433,11 +433,6 @@ struct perf_event { #endif /* CONFIG_PERF_EVENTS */ }; -enum perf_event_context_type { - task_context, - cpu_context, -}; - /** * struct perf_event_context - event context structure * @@ -445,7 +440,6 @@ enum perf_event_context_type { */ struct perf_event_context { struct pmu *pmu; - enum perf_event_context_type type; /* * Protect the states of the events in the list, * nr_active, and the list: diff --git a/include/linux/random.h b/include/linux/random.h index bf9085e89fb5d..1b91d7d186e71 100644 --- a/include/linux/random.h +++ b/include/linux/random.h @@ -24,6 +24,7 @@ extern const struct file_operations random_fops, urandom_fops; #endif unsigned int get_random_int(void); +unsigned long get_random_long(void); unsigned long randomize_range(unsigned long start, unsigned long end, unsigned long len); u32 prandom_u32(void); diff --git a/include/linux/sock_diag.h b/include/linux/sock_diag.h index 46cca4c068483..1a3b383ba4e61 100644 --- a/include/linux/sock_diag.h +++ b/include/linux/sock_diag.h @@ -11,6 +11,7 @@ struct sock; struct sock_diag_handler { __u8 family; int (*dump)(struct sk_buff *skb, struct nlmsghdr *nlh); + int (*destroy)(struct sk_buff *skb, struct nlmsghdr *nlh); }; int sock_diag_register(const struct sock_diag_handler *h); @@ -26,4 +27,5 @@ int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attr); int sock_diag_put_filterinfo(bool may_report_filterinfo, struct sock *sk, struct sk_buff *skb, int attrtype); +int sock_diag_destroy(struct sock *sk, int err); #endif diff --git a/include/media/msmb_ispif.h b/include/media/msmb_ispif.h index b512dc9a8547e..4e5e31db17c03 100644 --- a/include/media/msmb_ispif.h +++ b/include/media/msmb_ispif.h @@ -24,6 +24,7 @@ enum msm_ispif_intftype { }; #define MAX_PARAM_ENTRIES (INTF_MAX * 2) #define MAX_CID_CH 8 +#define MAX_CID_CH_V2 3 #define PIX0_MASK (1 << PIX0) #define PIX1_MASK (1 << PIX1) @@ -72,7 +73,7 @@ struct msm_ispif_params_entry { enum msm_ispif_vfe_intf vfe_intf; enum msm_ispif_intftype intftype; int num_cids; - enum msm_ispif_cid cids[3]; + enum msm_ispif_cid cids[MAX_CID_CH_V2]; enum msm_ispif_csid csid; int crop_enable; uint16_t crop_start_pixel; diff --git a/include/net/af_unix.h b/include/net/af_unix.h index dbdfd2b0f3b3d..9120783132e71 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -62,6 +62,7 @@ struct unix_sock { #define UNIX_GC_CANDIDATE 0 #define UNIX_GC_MAYBE_CYCLE 1 struct socket_wq peer_wq; + wait_queue_t peer_wake; }; #define unix_sk(__sk) ((struct unix_sock *)__sk) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 85d38d801ca8f..de5f7fda9ae64 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -114,6 +114,9 @@ enum ieee80211_band { * channel as the control or any of the secondary channels. * This may be due to the driver or due to regulatory bandwidth * restrictions. + * @IEEE80211_CHAN_INDOOR_ONLY: see %NL80211_FREQUENCY_ATTR_INDOOR_ONLY + * @IEEE80211_CHAN_GO_CONCURRENT: see %NL80211_FREQUENCY_ATTR_GO_CONCURRENT + * */ enum ieee80211_channel_flags { IEEE80211_CHAN_DISABLED = 1<<0, @@ -125,6 +128,8 @@ enum ieee80211_channel_flags { IEEE80211_CHAN_NO_OFDM = 1<<6, IEEE80211_CHAN_NO_80MHZ = 1<<7, IEEE80211_CHAN_NO_160MHZ = 1<<8, + IEEE80211_CHAN_INDOOR_ONLY = 1<<9, + IEEE80211_CHAN_GO_CONCURRENT = 1<<10, }; #define IEEE80211_CHAN_NO_HT40 \ @@ -1467,14 +1472,10 @@ struct cfg80211_auth_request { * * @ASSOC_REQ_DISABLE_HT: Disable HT (802.11n) * @ASSOC_REQ_DISABLE_VHT: Disable VHT - * @ASSOC_REQ_OFFLOAD_KEY_MGMT: Requests that device handle establishment - * of temporal keys if possible during initial RSN connection or after - * roaming */ enum cfg80211_assoc_req_flags { ASSOC_REQ_DISABLE_HT = BIT(0), ASSOC_REQ_DISABLE_VHT = BIT(1), - ASSOC_REQ_OFFLOAD_KEY_MGMT = BIT(2), }; /** @@ -1627,8 +1628,6 @@ struct cfg80211_ibss_params { * @ht_capa_mask: The bits of ht_capa which are to be used. * @vht_capa: VHT Capability overrides * @vht_capa_mask: The bits of vht_capa which are to be used. - * @psk: The Preshared Key to be used for the connection. - * (only valid if ASSOC_REQ_OFFLOAD_KEY_MGMT is set) */ struct cfg80211_connect_params { struct ieee80211_channel *channel; @@ -1651,7 +1650,6 @@ struct cfg80211_connect_params { struct ieee80211_ht_cap ht_capa_mask; struct ieee80211_vht_cap vht_capa; struct ieee80211_vht_cap vht_capa_mask; - const u8 *psk; }; /** @@ -1872,24 +1870,6 @@ struct cfg80211_qos_map { struct cfg80211_dscp_range up[8]; }; -/** - * struct cfg80211_auth_params - Information about a key managment offload - * - * Information reported when a key managment offload has completed. - * - * @status: whether offload was successful - * @key_replay_ctr: Key Replay Counter value last used in a valid - * EAPOL-Key frame - * @ptk_kck: the derived PTK KCK - * @ptk_kek: the derived PTK KEK - */ -struct cfg80211_auth_params { - enum nl80211_authorization_status status; - const u8 *key_replay_ctr; - const u8 *ptk_kck; - const u8 *ptk_kek; -}; - /** * struct cfg80211_ops - backend description for wireless configuration * @@ -2125,12 +2105,6 @@ struct cfg80211_auth_params { * @set_ap_chanwidth: Set the AP (including P2P GO) mode channel width for the * given interface This is used e.g. for dynamic HT 20/40 MHz channel width * changes during the lifetime of the BSS. - * - * @key_mgmt_set_pmk: Used to pass the PMK to the device for key management - * offload. This will be used in the case of key management offload on an - * already established PMKSA. If connection is FT (802.11r) enabled with - * 802.1X, then the second 256 bits of the MSK is passed instead of the - * PMK. */ struct cfg80211_ops { int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); @@ -2374,9 +2348,6 @@ struct cfg80211_ops { int (*set_ap_chanwidth)(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_chan_def *chandef); - - int (*key_mgmt_set_pmk)(struct wiphy *wiphy, struct net_device *dev, - const u8 *pmk, size_t pmk_len); }; /* @@ -2448,14 +2419,6 @@ struct cfg80211_ops { * @WIPHY_FLAG_OFFCHAN_TX: Device supports direct off-channel TX. * @WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL: Device supports remain-on-channel call. * @WIPHY_FLAG_DFS_OFFLOAD: The driver handles all the DFS related operations. - * @WIPHY_FLAG_HAS_KEY_MGMT_OFFLOAD: Device operating as a station is - * capable of doing the exchange necessary to establish temporal keys - * during initial RSN connection, after roaming, or during a PTK rekeying - * operation. Supplicant should expect to do the exchange itself, by - * preparing to process the EAPOL-Key frames, until - * NL80211_CMD_AUTHORIZATION_EVENT is sent with success status. The - * supported types of key management offload are advertised by - * NL80211_ATTR_KEY_MGMT_OFFLOAD. */ enum wiphy_flags { WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), @@ -2479,8 +2442,7 @@ enum wiphy_flags { WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD = BIT(19), WIPHY_FLAG_OFFCHAN_TX = BIT(20), WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL = BIT(21), - WIPHY_FLAG_DFS_OFFLOAD = BIT(22), - WIPHY_FLAG_HAS_KEY_MGMT_OFFLOAD = BIT(23), + WIPHY_FLAG_DFS_OFFLOAD = BIT(22) }; /** @@ -2763,14 +2725,6 @@ struct wiphy_vendor_command { * (including P2P GO) or 0 to indicate no such limit is advertised. The * driver is allowed to advertise a theoretical limit that it can reach in * some cases, but may not always reach. - * - * @key_mgmt_offload_support: Bitmap of supported types of key management - * that can be offloaded to the device. See - * nl80211_key_mgmt_offload_support. Only valid when - * WIPHY_FLAG_HAS_KEY_MGMT_OFFLOAD is set. - * @key_derive_offload_support: Bitmap of supported key derivations used as - * part of key management offload. See nl80211_key_derive_offload_support. - * Only valid when WIPHY_FLAG_HAS_KEY_MGMT_OFFLOAD is set. */ struct wiphy { /* assign these fields before you register the wiphy */ @@ -2887,9 +2841,6 @@ struct wiphy { u16 max_ap_assoc_sta; - u32 key_mgmt_offload_support; - u32 key_derive_offload_support; - char priv[0] __aligned(NETDEV_ALIGN); }; @@ -4544,55 +4495,6 @@ void cfg80211_ap_stopped(struct net_device *netdev, gfp_t gfp); */ bool cfg80211_is_gratuitous_arp_unsolicited_na(struct sk_buff *skb); -/** - * cfg80211_authorization_event - indicates key management offload complete - * @dev: the device reporting offload - * @auth_status: whether offload was successful - * @key_replay_ctr: Key Replay Counter value last used in a valid - * EAPOL-Key frame - * @gfp: allocation flags - * - * This function reports that the device offloaded the key management - * operation and established temporal keys for an RSN connection. In - * this case, the device handled the exchange necessary to establish - * the temporal keys by processing the EAPOL-Key frames instead of - * the supplicant doing it. This means the initial connection, roam - * operation, or PKT rekeying is complete and the supplicant should - * enter the authorized state for the port. This event can be signaled - * after cfg80211_connect_result during initial connection or after - * cfg80211_roamed in the case of roaming. This event might also be - * signaled after the device handles a PTK rekeying operation. If the - * auth_status parameter indicates that offload was not successful, - * then the supplicant should expect to do the necessary key management - * with the AP and the EAPOL-Key frames should be delivered to - * the supplicant. - */ -void cfg80211_authorization_event(struct net_device *dev, - enum nl80211_authorization_status auth_status, - const u8 *key_replay_ctr, - gfp_t gfp); - -/** - * cfg80211_key_mgmt_auth - indicates key management offload complete - * @dev: the device reporting offload - * @auth_params: information about the offload - * @gfp: allocation flags - * - * This function reports that the device offloaded the key management - * operation and established temporal keys for an RSN connection. In - * this case, the device handled the exchange necessary to establish - * the temporal keys by processing the EAPOL-Key frames instead of - * the supplicant doing it. This means the initial connection, roam - * operation, or PKT rekeying is complete and the supplicant should - * enter the authorized state for the port. This event can be signaled - * after cfg80211_connect_result during initial connection or after - * cfg80211_roamed in the case of roaming. This event might also be - * signaled after the device handles a PTK rekeying operation. - */ -void cfg80211_key_mgmt_auth(struct net_device *dev, - struct cfg80211_auth_params *auth_params, - gfp_t gfp); - void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info); /* Logging, debugging and troubleshooting/diagnostic helpers. */ diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 67b43806b6228..d90de07e0f5d1 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -203,6 +203,7 @@ extern rwlock_t ip6_ra_lock; */ struct ipv6_txoptions { + atomic_t refcnt; /* Length of this structure */ int tot_len; @@ -215,7 +216,7 @@ struct ipv6_txoptions { struct ipv6_opt_hdr *dst0opt; struct ipv6_rt_hdr *srcrt; /* Routing Header */ struct ipv6_opt_hdr *dst1opt; - + struct rcu_head rcu; /* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */ }; @@ -254,6 +255,23 @@ extern void fl6_free_socklist(struct sock *sk); extern int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen); extern int ip6_flowlabel_init(void); extern void ip6_flowlabel_cleanup(void); +static inline struct ipv6_txoptions *txopt_get(const struct ipv6_pinfo *np) +{ + struct ipv6_txoptions *opt; + + rcu_read_lock(); + opt = rcu_dereference(np->opt); + if (opt && !atomic_inc_not_zero(&opt->refcnt)) + opt = NULL; + rcu_read_unlock(); + return opt; +} + +static inline void txopt_put(struct ipv6_txoptions *opt) +{ + if (opt && atomic_dec_and_test(&opt->refcnt)) + kfree_rcu(opt, rcu); +} static inline void fl6_sock_release(struct ip6_flowlabel *fl) { diff --git a/include/net/sock.h b/include/net/sock.h index aaee3d659cf10..695c8563e0acc 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -67,6 +67,7 @@ #include #include #include +#include struct cgroup; struct cgroup_subsys; @@ -999,6 +1000,7 @@ struct proto { void (*destroy_cgroup)(struct mem_cgroup *memcg); struct cg_proto *(*proto_cgroup)(struct mem_cgroup *memcg); #endif + int (*diag_destroy)(struct sock *sk, int err); }; /* @@ -2245,6 +2247,15 @@ static inline struct sock *skb_steal_sock(struct sk_buff *skb) return NULL; } +/* This helper checks if a socket is a full socket, + * ie _not_ a timewait or request socket. + * TODO: Check for TCPF_NEW_SYN_RECV when that starts to exist. + */ +static inline bool sk_fullsock(const struct sock *sk) +{ + return (1 << sk->sk_state) & ~(TCPF_TIME_WAIT); +} + extern void sock_enable_timestamp(struct sock *sk, int flag); extern int sock_get_timestamp(struct sock *, struct timeval __user *); extern int sock_get_timestampns(struct sock *, struct timespec __user *); diff --git a/include/net/tcp.h b/include/net/tcp.h index 1b044c3d44157..4b94a61fc04e1 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1057,6 +1057,8 @@ extern void tcp_set_state(struct sock *sk, int state); extern void tcp_done(struct sock *sk); +int tcp_abort(struct sock *sk, int err); + static inline void tcp_sack_reset(struct tcp_options_received *rx_opt) { rx_opt->dsack = 0; diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h index 59d7ee1a2ac44..f6bd71f70abcc 100644 --- a/include/sound/apr_audio-v2.h +++ b/include/sound/apr_audio-v2.h @@ -2894,7 +2894,8 @@ struct asm_dec_ddp_endp_param_v2 { } __packed; /* @brief Multichannel PCM encoder configuration structure used - * in the #ASM_STREAM_CMD_OPEN_READ_V2 command. + * in the #ASM_STREAM_CMD_OPEN_READ_V2(for AVS2.6 image) OR + * ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2(FOR AVS2.7 image) command. */ struct asm_multi_channel_pcm_enc_cfg_v2 { @@ -3374,7 +3375,8 @@ struct asm_v13k_enc_cfg { #define ASM_MEDIA_FMT_EVRC_FS 0x00010BEE /* EVRC encoder configuration structure used in the - * #ASM_STREAM_CMD_OPEN_READ_V2 command. + * #ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2(for AVS2.6 image) + * #ASM_STREAM_CMD_OPEN_READ_V2(for AVS2.7 image) command. */ struct asm_evrc_enc_cfg { struct apr_hdr hdr; @@ -3583,6 +3585,8 @@ struct asm_amrwbplus_fmt_blk_v2 { } __packed; +#define ASM_MEDIA_FMT_AC3 0x00010DEE +#define ASM_MEDIA_FMT_EAC3 0x00010DEF #define ASM_MEDIA_FMT_AC3_DEC 0x00010BF6 #define ASM_MEDIA_FMT_EAC3_DEC 0x00010C3C #define ASM_MEDIA_FMT_DTS 0x00010D88 @@ -4329,6 +4333,8 @@ struct asm_stream_cmd_open_write_v3 { * - #ASM_MEDIA_FMT_SBC * - #ASM_MEDIA_FMT_WMA_V10PRO_V2 * - #ASM_MEDIA_FMT_WMA_V9_V2 + * - #ASM_MEDIA_FMT_AC3 + * - #ASM_MEDIA_FMT_EAC3 * - #ASM_MEDIA_FMT_AC3_DEC * - #ASM_MEDIA_FMT_EAC3_DEC * - #ASM_MEDIA_FMT_G711_ALAW_FS @@ -4501,6 +4507,7 @@ struct asm_stream_cmd_open_readwrite_v2 { * - #ASM_MEDIA_FMT_WMA_V10PRO_V2 * - #ASM_MEDIA_FMT_WMA_V9_V2 * - #ASM_MEDIA_FMT_AMR_WB_PLUS_V2 + * - #ASM_MEDIA_FMT_AC3 * - #ASM_MEDIA_FMT_AC3_DEC * - #ASM_MEDIA_FMT_G711_ALAW_FS * - #ASM_MEDIA_FMT_G711_MLAW_FS @@ -5117,6 +5124,8 @@ struct asm_stream_cmd_open_write_compressed { * Supported values: * - #ASM_MEDIA_FMT_AC3_DEC * - #ASM_MEDIA_FMT_EAC3_DEC + * - #ASM_MEDIA_FMT_AC3 + * - #ASM_MEDIA_FMT_EAC3 * - #ASM_MEDIA_FMT_DTS * - #ASM_MEDIA_FMT_ATRAC * - #ASM_MEDIA_FMT_MAT @@ -5935,6 +5944,7 @@ struct audproc_topology_module_id_info_t { * This module supports the following parameter IDs: * - #ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN * - #ASM_PARAM_ID_VOL_CTRL_LR_CHANNEL_GAIN + * - #ASM_PARAM_ID_MULTICHANNEL_GAIN * - #ASM_PARAM_ID_VOL_CTRL_MUTE_CONFIG * - #ASM_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS * - #ASM_PARAM_ID_SOFT_PAUSE_PARAMETERS @@ -5961,6 +5971,7 @@ struct audproc_topology_module_id_info_t { * @messagepayload * @structure{asm_volume_ctrl_lr_chan_gain} * @tablespace + * @inputtable{Audio_Postproc_ASM_PARAM_ID_MULTICHANNEL_GAIN.tex} * @inputtable{Audio_Postproc_ASM_PARAM_ID_VOL_CTRL_LR_CHANNEL_GAIN.tex} */ #define ASM_PARAM_ID_VOL_CTRL_LR_CHANNEL_GAIN 0x00010C00 @@ -6165,12 +6176,10 @@ struct asm_soft_pause_params { */ -struct asm_volume_ctrl_channelype_gain_pair { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; - uint8_t channelype; -/*< Channel type for which the gain setting is to be applied. +struct asm_volume_ctrl_channeltype_gain_pair { + uint8_t channeltype; +/* + *< Channel type for which the gain setting is to be applied. * Supported values: * - #PCM_CHANNEL_L * - #PCM_CHANNEL_R @@ -6200,7 +6209,8 @@ struct asm_volume_ctrl_channelype_gain_pair { /*< Clients must set this field to zero. */ uint32_t gain; -/*< Gain value for this channel in Q28 format. +/* + *< Gain value for this channel in Q28 format. * Supported values: Any */ } __packed; @@ -6219,14 +6229,14 @@ struct asm_volume_ctrl_multichannel_gain { struct asm_stream_cmd_set_pp_params_v2 param; struct asm_stream_param_data_v2 data; uint32_t num_channels; -/*< Number of channels for which gain values are provided. Any +/* + *< Number of channels for which gain values are provided. Any * channels present in the data for which gain is not provided are * set to unity gain. * Supported values: 1 to 8 */ - - struct asm_volume_ctrl_channelype_gain_pair + struct asm_volume_ctrl_channeltype_gain_pair gain_data[VOLUME_CONTROL_MAX_CHANNELS]; /*< Array of channel type/gain pairs.*/ } __packed; @@ -7459,6 +7469,154 @@ enum afe_lpass_clk_mode { Q6AFE_LPASS_MODE_BOTH_VALID, } __packed; +/* Clock ID Enumeration Define. */ +/* Clock ID for Primary I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT 0x100 +/* Clock ID for Primary I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_MI2S_EBIT 0x101 +/* Clock ID for Secondary I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT 0x102 +/* Clock ID for Secondary I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT 0x103 +/* Clock ID for Tertiary I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT 0x104 +/* Clock ID for Tertiary I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT 0x105 +/* Clock ID for Quartnery I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT 0x106 +/* Clock ID for Quartnery I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT 0x107 +/* Clock ID for Speaker I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_IBIT 0x108 +/* Clock ID for Speaker I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_EBIT 0x109 +/* Clock ID for Speaker I2S OSR */ +#define Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_OSR 0x10A + +/* Clock ID for QUINARY I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_QUI_MI2S_IBIT 0x10B +/* Clock ID for QUINARY I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_QUI_MI2S_EBIT 0x10C +/* Clock ID for SENARY I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_SEN_MI2S_IBIT 0x10D +/* Clock ID for SENARY I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_SEN_MI2S_EBIT 0x10E + +/* Clock ID for Primary PCM IBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_PCM_IBIT 0x200 +/* Clock ID for Primary PCM EBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_PCM_EBIT 0x201 +/* Clock ID for Secondary PCM IBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_PCM_IBIT 0x202 +/* Clock ID for Secondary PCM EBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_PCM_EBIT 0x203 +/* Clock ID for Tertiary PCM IBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_PCM_IBIT 0x204 +/* Clock ID for Tertiary PCM EBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_PCM_EBIT 0x205 +/* Clock ID for Quartery PCM IBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_PCM_IBIT 0x206 +/* Clock ID for Quartery PCM EBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_PCM_EBIT 0x207 + +/** Clock ID for Primary TDM IBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT 0x200 +/** Clock ID for Primary TDM EBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_TDM_EBIT 0x201 +/** Clock ID for Secondary TDM IBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_TDM_IBIT 0x202 +/** Clock ID for Secondary TDM EBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_TDM_EBIT 0x203 +/** Clock ID for Tertiary TDM IBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_TDM_IBIT 0x204 +/** Clock ID for Tertiary TDM EBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_TDM_EBIT 0x205 +/** Clock ID for Quartery TDM IBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT 0x206 +/** Clock ID for Quartery TDM EBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_TDM_EBIT 0x207 + +/* Clock ID for MCLK1 */ +#define Q6AFE_LPASS_CLK_ID_MCLK_1 0x300 +/* Clock ID for MCLK2 */ +#define Q6AFE_LPASS_CLK_ID_MCLK_2 0x301 +/* Clock ID for MCLK3 */ +#define Q6AFE_LPASS_CLK_ID_MCLK_3 0x302 +/* Clock ID for Internal Digital Codec Core */ +#define Q6AFE_LPASS_CLK_ID_INTERNAL_DIGITAL_CODEC_CORE 0x303 + +/* Clock ID for AHB HDMI input */ +#define Q6AFE_LPASS_CLK_ID_AHB_HDMI_INPUT 0x400 + +/* Clock ID for SPDIF core */ +#define Q6AFE_LPASS_CLK_ID_SPDIF_CORE 0x500 + + +/* Clock attribute for invalid use (reserved for internal usage) */ +#define Q6AFE_LPASS_CLK_ATTRIBUTE_INVALID 0x0 +/* Clock attribute for no couple case */ +#define Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO 0x1 +/* Clock attribute for dividend couple case */ +#define Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_DIVIDEND 0x2 +/* Clock attribute for divisor couple case */ +#define Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_DIVISOR 0x3 +/* Clock attribute for invert and no couple case */ +#define Q6AFE_LPASS_CLK_ATTRIBUTE_INVERT_COUPLE_NO 0x4 +/* Clock set API version */ +#define Q6AFE_LPASS_CLK_CONFIG_API_VERSION 0x1 + +struct afe_clk_set { + /* + * Minor version used for tracking clock set. + * @values #AFE_API_VERSION_CLOCK_SET + */ + uint32_t clk_set_minor_version; + + /* + * Clock ID + * @values + * - 0x100 to 0x10A - MSM8996 + * - 0x200 to 0x207 - MSM8996 + * - 0x300 to 0x302 - MSM8996 @tablebulletend + */ + uint32_t clk_id; + + /* + * Clock frequency (in Hertz) to be set. + * @values + * - >= 0 for clock frequency to set @tablebulletend + */ + uint32_t clk_freq_in_hz; + + /* Use to specific divider for two clocks if needed. + * Set to Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO for no divider + * relation clocks + * @values + * - #Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO + * - #Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_DIVIDEND + * - #Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_DIVISOR @tablebulletend + */ + uint16_t clk_attri; + + /* + * Specifies the root clock source. + * Currently, only Q6AFE_LPASS_CLK_ROOT_DEFAULT is valid + * @values + * - 0 @tablebulletend + */ + uint16_t clk_root; + + /* + * for enable and disable clock. + * "clk_freq_in_hz", "clk_attri", and "clk_root" + * are ignored in disable clock case. + * @values + * - 0 -- Disabled + * - 1 -- Enabled @tablebulletend + */ + uint32_t enable; +}; + struct afe_clk_cfg { /* Minor version used for tracking the version of the I2S * configuration interface. @@ -7496,7 +7654,8 @@ struct afe_clk_cfg { /* This param id is used to configure I2S clk */ #define AFE_PARAM_ID_LPAIF_CLK_CONFIG 0x00010238 - +#define AFE_MODULE_CLOCK_SET 0x0001028F +#define AFE_PARAM_ID_CLOCK_SET 0x00010290 struct afe_lpass_clk_config_command { struct apr_hdr hdr; @@ -7663,6 +7822,13 @@ struct afe_svc_cmd_set_param { uint32_t mem_map_handle; } __packed; +struct afe_svc_param_data { + uint32_t module_id; + uint32_t param_id; + uint16_t param_size; + uint16_t reserved; +} __packed; + struct afe_param_hw_mad_ctrl { uint32_t minor_version; uint16_t mad_type; @@ -7694,6 +7860,13 @@ struct afe_param_cdc_reg_cfg_payload { struct afe_param_cdc_reg_cfg reg_cfg; } __packed; +struct afe_lpass_clk_config_command_v2 { + struct apr_hdr hdr; + struct afe_svc_cmd_set_param param; + struct afe_svc_param_data pdata; + struct afe_clk_set clk_cfg; +} __packed; + /* * reg_data's size can be up to AFE_MAX_CDC_REGISTERS_TO_CONFIG */ @@ -7905,6 +8078,151 @@ struct asm_mtmx_strtr_params { u32 window_lsw; u32 window_msw; } __packed; + + + +/* Command for Matrix or Stream Router */ +#define ASM_SESSION_CMD_SET_MTMX_STRTR_PARAMS_V2 0x00010DCE +/* Module for AVSYNC */ +#define ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC 0x00010DC6 + +/* Parameter used by #ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC to specify the + * render window start value. This parameter is supported only for a Set + * command (not a Get command) in the Rx direction + * (#ASM_SESSION_CMD_SET_MTMX_STRTR_PARAMS_V2). + * Render window start is a value (session time minus timestamp, or ST-TS) + * below which frames are held, and after which frames are immediately + * rendered. + */ +#define ASM_SESSION_MTMX_STRTR_PARAM_RENDER_WINDOW_START_V2 0x00010DD1 + +/* Parameter used by #ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC to specify the + * render window end value. This parameter is supported only for a Set + * command (not a Get command) in the Rx direction + * (#ASM_SESSION_CMD_SET_MTMX_STRTR_PARAMS_V2). Render window end is a value + * (session time minus timestamp) above which frames are dropped, and below + * which frames are immediately rendered. + */ +#define ASM_SESSION_MTMX_STRTR_PARAM_RENDER_WINDOW_END_V2 0x00010DD2 + +/* Generic payload of the window parameters in the + * #ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC module. + * This payload is supported only for a Set command + * (not a Get command) on the Rx path. + */ + +#define ASM_SESSION_CMD_GET_MTMX_STRTR_PARAMS_V2 0x00010DCF +#define ASM_SESSION_CMDRSP_GET_MTMX_STRTR_PARAMS_V2 0x00010DD0 + +#define ASM_SESSION_MTMX_STRTR_PARAM_SESSION_TIME_V3 0x00012F0B +#define ASM_SESSION_MTMX_STRTR_PARAM_STIME_TSTMP_FLG_BMASK (0x80000000UL) + +struct asm_session_cmd_get_mtmx_strstr_params_v2 { + uint32_t data_payload_addr_lsw; + /* Lower 32 bits of the 64-bit data payload address. */ + + uint32_t data_payload_addr_msw; + /* + * Upper 32 bits of the 64-bit data payload address. + * If the address is not sent (NULL), the message is in the payload. + * If the address is sent (non-NULL), the parameter data payloads + * begin at the specified address. + */ + + uint32_t mem_map_handle; + /* + * Unique identifier for an address. This memory map handle is returned + * by the aDSP through the #ASM_CMD_SHARED_MEM_MAP_REGIONS command. + * values + * - NULL -- Parameter data payloads are within the message payload + * (in-band). + * - Non-NULL -- Parameter data payloads begin at the address specified + * in the data_payload_addr_lsw and data_payload_addr_msw fields + * (out-of-band). + */ + uint32_t direction; + /* + * Direction of the entity (matrix mixer or stream router) on which + * the parameter is to be set. + * values + * - 0 -- Rx (for Rx stream router or Rx matrix mixer) + * - 1 -- Tx (for Tx stream router or Tx matrix mixer) + */ + uint32_t module_id; + /* Unique module ID. */ + + uint32_t param_id; + /* Unique parameter ID. */ + + uint32_t param_max_size; +}; + +struct asm_session_mtmx_strtr_param_session_time_v3_t { + uint32_t session_time_lsw; + /* Lower 32 bits of the current session time in microseconds */ + + uint32_t session_time_msw; + /* + * Upper 32 bits of the current session time in microseconds. + * The 64-bit number formed by session_time_lsw and session_time_msw + * is treated as signed. + */ + + uint32_t absolute_time_lsw; + /* + * Lower 32 bits of the 64-bit absolute time in microseconds. + * This is the time when the sample corresponding to the + * session_time_lsw is rendered to the hardware. This absolute + * time can be slightly in the future or past. + */ + + uint32_t absolute_time_msw; + /* + * Upper 32 bits of the 64-bit absolute time in microseconds. + * This is the time when the sample corresponding to the + * session_time_msw is rendered to hardware. This absolute + * time can be slightly in the future or past. The 64-bit number + * formed by absolute_time_lsw and absolute_time_msw is treated as + * unsigned. + */ + + uint32_t time_stamp_lsw; + /* Lower 32 bits of the last processed timestamp in microseconds */ + + uint32_t time_stamp_msw; + /* + * Upper 32 bits of the last processed timestamp in microseconds. + * The 64-bit number formed by time_stamp_lsw and time_stamp_lsw + * is treated as unsigned. + */ + + uint32_t flags; + /* + * Keeps track of any additional flags needed. + * @values{for bit 31} + * - 0 -- Uninitialized/invalid + * - 1 -- Valid + * All other bits are reserved; clients must set them to zero. + */ +}; + +union asm_session_mtmx_strtr_data_type { + struct asm_session_mtmx_strtr_param_session_time_v3_t session_time; +}; + +struct asm_mtmx_strtr_get_params { + struct apr_hdr hdr; + struct asm_session_cmd_get_mtmx_strstr_params_v2 param_info; +} __packed; + +struct asm_mtmx_strtr_get_params_cmdrsp { + uint32_t err_code; + struct asm_stream_param_data_v2 param_info; + union asm_session_mtmx_strtr_data_type param_data; +} __packed; + + + #define AUDPROC_MODULE_ID_RESAMPLER 0x00010719 enum { diff --git a/include/sound/q6afe-v2.h b/include/sound/q6afe-v2.h index f965bc2fd0e38..46da0660919cd 100644 --- a/include/sound/q6afe-v2.h +++ b/include/sound/q6afe-v2.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -38,7 +38,6 @@ #define RT_PROXY_DAI_002_RX 0xF1 #define RT_PROXY_DAI_002_TX 0xE1 #define VIRTUAL_ID_TO_PORTID(val) ((val & 0xF) | 0x2000) - enum { IDX_PRIMARY_I2S_RX = 0, IDX_PRIMARY_I2S_TX = 1, @@ -198,6 +197,7 @@ int afe_convert_virtual_to_portid(u16 port_id); int afe_pseudo_port_start_nowait(u16 port_id); int afe_pseudo_port_stop_nowait(u16 port_id); int afe_set_lpass_clock(u16 port_id, struct afe_clk_cfg *cfg); +int afe_set_lpass_clock_v2(u16 port_id, struct afe_clk_set *cfg); int afe_set_digital_codec_core_clock(u16 port_id, struct afe_digital_clk_cfg *cfg); int afe_set_lpass_internal_digital_codec_clock(u16 port_id, diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h index d1252913b7327..3c6a456e9ae14 100644 --- a/include/sound/q6asm-v2.h +++ b/include/sound/q6asm-v2.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -205,7 +205,7 @@ struct audio_client *q6asm_get_audio_client(int session_id); int q6asm_audio_client_buf_alloc(unsigned int dir/* 1:Out,0:In */, struct audio_client *ac, unsigned int bufsz, - unsigned int bufcnt); + uint32_t bufcnt); int q6asm_audio_client_buf_alloc_contiguous(unsigned int dir /* 1:Out,0:In */, struct audio_client *ac, @@ -353,7 +353,8 @@ int q6asm_media_format_block_pcm_format_support(struct audio_client *ac, int q6asm_media_format_block_pcm_format_support_v2(struct audio_client *ac, uint32_t rate, uint32_t channels, - uint16_t bits_per_sample, int stream_id); + uint16_t bits_per_sample, int stream_id, + bool use_default_chmap, char *channel_map); int q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac, uint32_t rate, uint32_t channels, @@ -430,10 +431,15 @@ int q6asm_set_softvolume_v2(struct audio_client *ac, /* Send left-right channel gain */ int q6asm_set_lrgain(struct audio_client *ac, int left_gain, int right_gain); +/* Send multi channel gain */ +int q6asm_set_multich_gain(struct audio_client *ac, uint32_t channels, + uint32_t *gains, uint8_t *ch_map, bool use_default); + /* Enable Mute/unmute flag */ int q6asm_set_mute(struct audio_client *ac, int muteflag); int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp); +int q6asm_get_session_time_legacy(struct audio_client *ac, uint64_t *tstamp); int q6asm_send_audio_effects_params(struct audio_client *ac, char *params, uint32_t params_length); diff --git a/include/sound/q6core.h b/include/sound/q6core.h index 146fc1a6cfcd2..7d2eeef73a46f 100644 --- a/include/sound/q6core.h +++ b/include/sound/q6core.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -152,7 +152,97 @@ struct avcs_cmdrsp_get_license_validation_result { /* Length in bytes of the result that follows this structure*/ }; +/* Set Q6 topologies */ +/* + * Registers custom topologies in the aDSP for + * use in audio, voice, AFE and LSM. + */ + + +#define AVCS_CMD_SHARED_MEM_MAP_REGIONS 0x00012924 +#define AVCS_CMDRSP_SHARED_MEM_MAP_REGIONS 0x00012925 +#define AVCS_CMD_SHARED_MEM_UNMAP_REGIONS 0x00012926 + + +#define AVCS_CMD_REGISTER_TOPOLOGIES 0x00012923 + +/* The payload for the AVCS_CMD_REGISTER_TOPOLOGIES command */ +struct avcs_cmd_register_topologies { + struct apr_hdr hdr; + uint32_t payload_addr_lsw; + /* Lower 32 bits of the topology buffer address. */ + + uint32_t payload_addr_msw; + /* Upper 32 bits of the topology buffer address. */ + + uint32_t mem_map_handle; + /* Unique identifier for an address. + * -This memory map handle is returned by the aDSP through the + * memory map command. + * -NULL mem_map_handle is interpreted as in-band parameter + * passing. + * -Client has the flexibility to choose in-band or out-of-band. + * -Out-of-band is recommended in this case. + */ + + uint32_t payload_size; + /* Size in bytes of the valid data in the topology buffer. */ +} __packed; + + +#define AVCS_CMD_DEREGISTER_TOPOLOGIES 0x0001292a + +/* The payload for the AVCS_CMD_DEREGISTER_TOPOLOGIES command */ +struct avcs_cmd_deregister_topologies { + struct apr_hdr hdr; + uint32_t payload_addr_lsw; + /* Lower 32 bits of the topology buffer address. */ + + uint32_t payload_addr_msw; + /* Upper 32 bits of the topology buffer address. */ + + uint32_t mem_map_handle; + /* Unique identifier for an address. + * -This memory map handle is returned by the aDSP through the + * memory map command. + * -NULL mem_map_handle is interpreted as in-band parameter + * passing. + * -Client has the flexibility to choose in-band or out-of-band. + * -Out-of-band is recommended in this case. + */ + + uint32_t payload_size; + /* Size in bytes of the valid data in the topology buffer. */ + + uint32_t mode; + /* 1: Deregister selected topologies + * 2: Deregister all topologies + */ +} __packed; + +#define AVCS_MODE_DEREGISTER_ALL_CUSTOM_TOPOLOGIES 2 + + int32_t core_set_license(uint32_t key, uint32_t module_id); int32_t core_get_license_status(uint32_t module_id); +#define AVCS_GET_VERSIONS 0x00012905 +struct avcs_cmd_get_version_result { + struct apr_hdr hdr; + uint32_t id; +}; +#define AVCS_GET_VERSIONS_RSP 0x00012906 + +#define AVCS_CMDRSP_Q6_ID_2_6 0x00040000 +#define AVCS_CMDRSP_Q6_ID_2_7 0x00040001 +#define AVCS_CMDRSP_Q6_ID_2_8 0x00040002 + +enum q6_subsys_image { + Q6_SUBSYS_AVS2_6 = 1, + Q6_SUBSYS_AVS2_7, + Q6_SUBSYS_AVS2_8, + Q6_SUBSYS_INVALID, +}; +enum q6_subsys_image q6core_get_avs_version(void); +int core_get_adsp_ver(void); #endif /* __Q6CORE_H__ */ diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h index d1b4e2ca9672e..bafd0d840bb7f 100644 --- a/include/uapi/linux/fuse.h +++ b/include/uapi/linux/fuse.h @@ -244,6 +244,8 @@ struct fuse_file_lock { #define FUSE_ASYNC_DIO (1 << 15) #define FUSE_WRITEBACK_CACHE (1 << 16) +#define FUSE_SHORTCIRCUIT (1 << 31) + /** * CUSE INIT request/reply flags * @@ -466,7 +468,7 @@ struct fuse_create_in { struct fuse_open_out { uint64_t fh; uint32_t open_flags; - uint32_t padding; + int32_t lower_fd;/* lower layer file descriptor */ }; struct fuse_release_in { diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h index 80e15fa366517..ff6c5f3549c1b 100644 --- a/include/uapi/linux/ipv6.h +++ b/include/uapi/linux/ipv6.h @@ -163,6 +163,8 @@ enum { DEVCONF_ACCEPT_RA_PREFIX_ROUTE, DEVCONF_ACCEPT_RA_RT_TABLE, DEVCONF_ACCEPT_RA_MTU, + DEVCONF_USE_OPTIMISTIC, + DEVCONF_USE_OIF_ADDRS_ONLY, DEVCONF_MAX }; diff --git a/include/uapi/linux/msm_audio_calibration.h b/include/uapi/linux/msm_audio_calibration.h index de24f255dfa5c..990f576c67514 100644 --- a/include/uapi/linux/msm_audio_calibration.h +++ b/include/uapi/linux/msm_audio_calibration.h @@ -90,6 +90,7 @@ enum { AUDIO_CORE_METAINFO_CAL_TYPE, SRS_TRUMEDIA_CAL_TYPE, + CORE_CUSTOM_TOPOLOGIES_CAL_TYPE, MAX_CAL_TYPES, }; diff --git a/include/uapi/linux/msm_mdp.h b/include/uapi/linux/msm_mdp.h index 8298116d8912c..9013ebfb9be5f 100644 --- a/include/uapi/linux/msm_mdp.h +++ b/include/uapi/linux/msm_mdp.h @@ -182,6 +182,13 @@ enum { NUM_HSIC_PARAM, }; +enum mdss_mdp_max_bw_mode { + MDSS_MAX_BW_LIMIT_DEFAULT = 0x1, + MDSS_MAX_BW_LIMIT_CAMERA = 0x2, + MDSS_MAX_BW_LIMIT_HFLIP = 0x4, + MDSS_MAX_BW_LIMIT_VFLIP = 0x8, +}; + #define MDSS_MDP_ROT_ONLY 0x80 #define MDSS_MDP_RIGHT_MIXER 0x100 #define MDSS_MDP_DUAL_PIPE 0x200 diff --git a/include/uapi/linux/msm_rmnet.h b/include/uapi/linux/msm_rmnet.h index 936b4373d09f6..4892602c2b94f 100644 --- a/include/uapi/linux/msm_rmnet.h +++ b/include/uapi/linux/msm_rmnet.h @@ -59,7 +59,8 @@ enum rmnet_ioctl_extended_cmds_e { RMNET_IOCTL_SET_SLEEP_STATE = 0x0014, /* Set sleep state */ RMNET_IOCTL_SET_XLAT_DEV_INFO = 0x0015, /* xlat dev name */ RMNET_IOCTL_DEREGISTER_DEV = 0x0016, /* Dereg a net dev */ - RMNET_IOCTL_EXTENDED_MAX = 0x0017 + RMNET_IOCTL_GET_SG_SUPPORT = 0x0017, /* Query sg support*/ + RMNET_IOCTL_EXTENDED_MAX = 0x0018 }; /* Return values for the RMNET_IOCTL_GET_SUPPORTED_FEATURES IOCTL */ diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index f9bfc0acd94bd..cd3209a48c786 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -688,26 +688,6 @@ * QoS mapping is relevant for IP packets, it is only valid during an * association. This is cleared on disassociation and AP restart. * - * @NL80211_CMD_AUTHORIZATION_EVENT: Indicates that the device offloaded - * the establishment of temporal keys for an RSN connection. This is - * used as part of key managment offload, where a device operating as a - * station is capable of doing the exchange necessary to establish - * temporal keys during initial RSN connection or after roaming. This - * event might also be sent after the device handles a PTK rekeying - * operation. The supplicant should expect to do the exchange itself, - * by preparing to process the EAPOL-Key frames, until - * NL80211_CMD_AUTHORIZATION_EVENT is sent with success status. The - * NL80211_ATTR_AUTHORIZATION_STATUS attribute provides the status of - * the offload and NL80211_KEY_REPLAY_CTR provides the Key Replay - * Counter value last used in a valid EAPOL-Key frame. - * - * @NL80211_CMD_KEY_MGMT_SET_PMK: Used to pass the PMK to the device for - * key management offload. This will be used in the case of key - * management offload on an already established PMKSA. The PMK is passed - * in NL80211_ATTR_PMK once it is known by the supplicant. If connection - * is FT (802.11r) enabled with 802.1X, then the second 256 bits of the - * MSK is passed instead of the PMK. - * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -879,9 +859,6 @@ enum nl80211_commands { NL80211_CMD_SET_QOS_MAP, - NL80211_CMD_AUTHORIZATION_EVENT, - NL80211_CMD_KEY_MGMT_SET_PMK, - /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ @@ -1562,22 +1539,6 @@ enum nl80211_commands { * @NL80211_ATTR_TDLS_PEER_CAPABILITY: flags for TDLS peer capabilities, u32. * As specified in the &enum nl80211_tdls_peer_capability. * - * @NL80211_ATTR_AUTHORIZATION_STATUS: Status of key management offload. - * @NL80211_ATTR_KEY_REPLAY_CTR: Key Replay Counter value last used in a - * valid EAPOL-Key frame. - * @NL80211_ATTR_PSK: The Preshared Key to be used for the connection. - * @NL80211_ATTR_OFFLOAD_KEY_MGMT: Requests that device handle establishment - * of temporal keys if possible. - * @NL80211_ATTR_KEY_MGMT_OFFLOAD_SUPPORT: Supported types of device key - * management offload. - * @NL80211_ATTR_KEY_DERIVE_OFFLOAD_SUPPORT: Supported types of device key - * derivation used as part of key management offload. - * @NL80211_ATTR_PMK: The Pairwise Master Key to be used for the - * connection. - * @NL80211_ATTR_PMK_LEN: The length of the PMK. - * @NL80211_ATTR_PTK_KCK: Pairwise Transient Key, Key Confirmation Key. - * @NL80211_ATTR_PTK_KEK: Pairwise Transient Key, Key Encryption Key. - * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -1914,17 +1875,6 @@ enum nl80211_attrs { NL80211_ATTR_TDLS_PEER_CAPABILITY, - NL80211_ATTR_AUTHORIZATION_STATUS, - NL80211_ATTR_KEY_REPLAY_CTR, - NL80211_ATTR_PSK, - NL80211_ATTR_OFFLOAD_KEY_MGMT, - NL80211_ATTR_KEY_MGMT_OFFLOAD_SUPPORT, - NL80211_ATTR_KEY_DERIVE_OFFLOAD_SUPPORT, - NL80211_ATTR_PMK, - NL80211_ATTR_PMK_LEN, - NL80211_ATTR_PTK_KCK, - NL80211_ATTR_PTK_KEK, - /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -2341,9 +2291,32 @@ enum nl80211_band_attr { * @NL80211_FREQUENCY_ATTR_NO_160MHZ: any 160 MHz (but not 80+80) channel * using this channel as the primary or any of the secondary channels * isn't possible + * @NL80211_FREQUENCY_ATTR_DFS_CAC_TIME: DFS CAC time in milliseconds. + * @NL80211_FREQUENCY_ATTR_INDOOR_ONLY: Only indoor use is permitted on this + * channel. A channel that has the INDOOR_ONLY attribute can only be + * used when there is a clear assessment that the device is operating in + * an indoor surroundings, i.e., it is connected to AC power (and not + * through portable DC inverters) or is under the control of a master + * that is acting as an AP and is connected to AC power. + * @NL80211_FREQUENCY_ATTR_GO_CONCURRENT: GO operation is allowed on this + * channel if it's connected concurrently to a BSS on the same channel on + * the 2 GHz band or to a channel in the same UNII band (on the 5 GHz + * band), and IEEE80211_CHAN_RADAR is not set. Instantiating a GO on a + * channel that has the GO_CONCURRENT attribute set can be done when there + * is a clear assessment that the device is operating under the guidance of + * an authorized master, i.e., setting up a GO while the device is also + * connected to an AP with DFS and radar detection on the UNII band (it is + * up to user-space, i.e., wpa_supplicant to perform the required + * verifications) * @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number * currently defined * @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use + * + * See + * https://apps.fcc.gov/eas/comments/GetPublishedDocument.html?id=327&tn=528122 + * for more information on the FCC description of the relaxations allowed + * by NL80211_FREQUENCY_ATTR_INDOOR_ONLY and + * NL80211_FREQUENCY_ATTR_GO_CONCURRENT. */ enum nl80211_frequency_attr { __NL80211_FREQUENCY_ATTR_INVALID, @@ -2359,6 +2332,9 @@ enum nl80211_frequency_attr { NL80211_FREQUENCY_ATTR_NO_HT40_PLUS, NL80211_FREQUENCY_ATTR_NO_80MHZ, NL80211_FREQUENCY_ATTR_NO_160MHZ, + NL80211_FREQUENCY_ATTR_DFS_CAC_TIME, + NL80211_FREQUENCY_ATTR_INDOOR_ONLY, + NL80211_FREQUENCY_ATTR_GO_CONCURRENT, /* keep last */ __NL80211_FREQUENCY_ATTR_AFTER_LAST, @@ -4008,72 +3984,4 @@ enum nl80211_tdls_peer_capability { NL80211_TDLS_PEER_WMM = 1<<2, }; -#define NL80211_KEY_LEN_PSK 32 -#define NL80211_KEY_LEN_PMK 32 -#define NL80211_KEY_REPLAY_CTR_LEN 8 -#define NL80211_KEY_LEN_PTK_KCK 16 -#define NL80211_KEY_LEN_PTK_KEK 16 - -/** - * enum nl80211_key_mgmt_offload_support - key management offload types - * - * Supported types of device key management offload. Allows device - * to advertise types of connections where it can offload establishment - * of temporal keys during initial RSN connection or after roaming. - * - * @NL80211_KEY_MGMT_OFFLOAD_SUPPORT_PSK: WPA/WPA2 PSK key management. - * The NL80211_ATTR_PSK attribute is passed in NL80211_CMD_CONNECT. - * @NL80211_KEY_MGMT_OFFLOAD_SUPPORT_FT_PSK: 802.11r (FT) PSK key - * management. The NL80211_ATTR_PSK attribute is passed in - * NL80211_CMD_CONNECT. - * @NL80211_KEY_MGMT_OFFLOAD_SUPPORT_PMKSA: Key management on already - * established PMKSA. The PMK will be passed using - * NL80211_CMD_KEY_MGMT_SET_PMK once it is known. - * @NL80211_KEY_MGMT_OFFLOAD_SUPPORT_FT_802_1X: 802.11r (FT) with - * 802.1X. The second 256 bits of the MSK is passed using - * NL80211_CMD_KEY_MGMT_SET_PMK once it is known. - */ -enum nl80211_key_mgmt_offload_support { - NL80211_KEY_MGMT_OFFLOAD_SUPPORT_PSK = 1 << 0, - NL80211_KEY_MGMT_OFFLOAD_SUPPORT_FT_PSK = 1 << 1, - NL80211_KEY_MGMT_OFFLOAD_SUPPORT_PMKSA = 1 << 2, - NL80211_KEY_MGMT_OFFLOAD_SUPPORT_FT_802_1X = 1 << 3, -}; - -/** - * enum nl80211_key_derive_offload_support - key derivation offload types - * - * Supported types of device key derivation used as part of key - * management offload. Assumes that GTK key derivation is supported - * by default for all supported key management offload types. - * - * @NL80211_KEY_DERIVE_OFFLOAD_SUPPORT_IGTK: IGTK key derivation. - * @NL80211_KEY_DERIVE_OFFLOAD_SUPPORT_SHA256: SHA-256 key derivation. - */ -enum nl80211_key_derive_offload_support { - NL80211_KEY_DERIVE_OFFLOAD_SUPPORT_IGTK = 1 << 0, - NL80211_KEY_DERIVE_OFFLOAD_SUPPORT_SHA256 = 1 << 1, -}; - -/** - * enum nl80211_authorization_status - key management offload status - * - * Status of key management offload. Provided as part of - * NL80211_CMD_AUTHORIZATION_EVENT. - * - * @NL80211_CONNECTED: Device did not successfully offload key - * management. Supplicant should expect to do the security - * exchange necessary to establish the temporal keys for the - * connection. - * @NL80211_AUTHORIZED: Device successfully offloaded key - * management and established temporal keys for the connection, - * signfiying that the initial connection, roaming, or PTK - * rekeying is complete. Supplicant should enter the - * authorized state for the port. - */ -enum nl80211_authorization_status { - NL80211_CONNECTED, - NL80211_AUTHORIZED, -}; - #endif /* __LINUX_NL80211_H */ diff --git a/include/uapi/linux/sock_diag.h b/include/uapi/linux/sock_diag.h index b00e29efb1619..472adbb711ed5 100644 --- a/include/uapi/linux/sock_diag.h +++ b/include/uapi/linux/sock_diag.h @@ -4,6 +4,7 @@ #include #define SOCK_DIAG_BY_FAMILY 20 +#define SOCK_DESTROY_BACKPORT 21 struct sock_diag_req { __u8 sdiag_family; diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index 7576ce541889c..2803a2cd4ca45 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -739,6 +739,18 @@ enum v4l2_mpeg_vidc_extradata { V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO = 19, V4L2_MPEG_VIDC_EXTRADATA_LTR = 20, V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI = 21, +#define V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI \ + V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI + V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI = 26, +#define V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI \ + V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI + V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI = 27, +#define V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY \ + V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY + V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY = 28, +#define V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE \ + V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE + V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE = 29, }; #define V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL (V4L2_CID_MPEG_MSM_VIDC_BASE + 26) @@ -1003,6 +1015,31 @@ enum v4l2_mpeg_vidc_video_priority { #define V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 75) +#define V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 80) + +#define V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 81) + +enum v4l2_cid_mpeg_vidc_video_full_range { + V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE_DISABLE = 0, + V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE_ENABLE = 1, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 82) + +#define V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 83) + +#define V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 87) + +enum v4l2_cid_mpeg_vidc_video_vpe_csc_type_enable { + V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_DISABLE = 0, + V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_ENABLE = 1 +}; + /* Camera class control IDs */ #define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900) diff --git a/include/uapi/media/msm_vidc.h b/include/uapi/media/msm_vidc.h index 6fa53ad7997b7..2fda501aa0042 100644 --- a/include/uapi/media/msm_vidc.h +++ b/include/uapi/media/msm_vidc.h @@ -43,6 +43,19 @@ struct msm_vidc_mpeg2_seqdisp_payload { unsigned int disp_width; unsigned int disp_height; }; + +struct msm_vidc_vc1_seqdisp_payload { + unsigned int prog_seg_format; + unsigned int uv_sampl_fmt; + unsigned int color_format; + unsigned int color_primaries; + unsigned int transfer_char; + unsigned int matrix_coeffs; + unsigned int aspect_ratio; + unsigned int aspect_horiz; + unsigned int aspect_vert; +}; + struct msm_vidc_input_crop_payload { unsigned int size; unsigned int version; @@ -109,6 +122,44 @@ struct msm_vidc_s3d_frame_packing_payload { unsigned int fpa_extension_flag; }; +struct msm_vidc_vpx_colorspace_payload { + unsigned int color_space; + unsigned int yuv_range_flag; + unsigned int sumsampling_x; + unsigned int sumsampling_y; +}; + +struct msm_vidc_mastering_display_colour_sei_payload { + unsigned int nDisplayPrimariesX[3]; + unsigned int nDisplayPrimariesY[3]; + unsigned int nWhitePointX; + unsigned int nWhitePointY; + unsigned int nMaxDisplayMasteringLuminance; + unsigned int nMinDisplayMasteringLuminance; +}; + +struct msm_vidc_content_light_level_sei_payload { + unsigned int nMaxContentLight; + unsigned int nMaxPicAverageLight; +}; + +struct msm_vidc_vui_display_info_payload { + unsigned int video_signal_present_flag; + unsigned int video_format; + unsigned int bit_depth_y; + unsigned int bit_depth_c; + unsigned int video_full_range_flag; + unsigned int color_description_present_flag; + unsigned int color_primaries; + unsigned int transfer_characteristics; + unsigned int matrix_coefficients; + unsigned int chroma_location_info_present_flag; + unsigned int chroma_format_idc; + unsigned int separate_color_plane_flag; + unsigned int chroma_sample_loc_type_top_field; + unsigned int chroma_sample_loc_type_bottom_field; +}; + enum msm_vidc_extradata_type { MSM_VIDC_EXTRADATA_NONE = 0x00000000, MSM_VIDC_EXTRADATA_MB_QUANTIZATION = 0x00000001, @@ -124,8 +175,17 @@ enum msm_vidc_extradata_type { MSM_VIDC_EXTRADATA_STREAM_USERDATA = 0x0000000E, MSM_VIDC_EXTRADATA_FRAME_QP = 0x0000000F, MSM_VIDC_EXTRADATA_FRAME_BITS_INFO = 0x00000010, +#define MSM_VIDC_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI \ + MSM_VIDC_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI + MSM_VIDC_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI = 0x00000015, +#define MSM_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI \ + MSM_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI + MSM_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI = 0x00000016, MSM_VIDC_EXTRADATA_INPUT_CROP = 0x0700000E, MSM_VIDC_EXTRADATA_DIGITAL_ZOOM = 0x07000010, +#define MSM_VIDC_EXTRADATA_VPX_COLORSPACE_INFO \ + MSM_VIDC_EXTRADATA_VPX_COLORSPACE_INFO + MSM_VIDC_EXTRADATA_VPX_COLORSPACE_INFO = 0x070000011, MSM_VIDC_EXTRADATA_MULTISLICE_INFO = 0x7F100000, MSM_VIDC_EXTRADATA_NUM_CONCEALED_MB = 0x7F100001, MSM_VIDC_EXTRADATA_INDEX = 0x7F100002, @@ -133,6 +193,9 @@ enum msm_vidc_extradata_type { MSM_VIDC_EXTRADATA_METADATA_LTR = 0x7F100004, MSM_VIDC_EXTRADATA_METADATA_FILLER = 0x7FE00002, MSM_VIDC_EXTRADATA_METADATA_MBI = 0x7F100005, +#define MSM_VIDC_EXTRADATA_VUI_DISPLAY_INFO \ + MSM_VIDC_EXTRADATA_VUI_DISPLAY_INFO + MSM_VIDC_EXTRADATA_VUI_DISPLAY_INFO = 0x7F100006, }; enum msm_vidc_interlace_type { MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE = 0x01, @@ -151,4 +214,79 @@ enum msm_vidc_userdata_type { MSM_VIDC_USERDATA_TYPE_TOP_FIELD = 0x2, MSM_VIDC_USERDATA_TYPE_BOTTOM_FIELD = 0x3, }; +/* See colour_primaries of ISO/IEC 14496 for significance */ +enum msm_vidc_h264_color_primaries_values { + MSM_VIDC_RESERVED_1 = 0, + MSM_VIDC_BT709_5 = 1, + MSM_VIDC_UNSPECIFIED = 2, + MSM_VIDC_RESERVED_2 = 3, + MSM_VIDC_BT470_6_M = 4, + MSM_VIDC_BT601_6_625 = 5, + MSM_VIDC_BT470_6_BG = MSM_VIDC_BT601_6_625, + MSM_VIDC_BT601_6_525 = 6, + MSM_VIDC_SMPTE_240M = 7, + MSM_VIDC_GENERIC_FILM = 8, + MSM_VIDC_BT2020 = 9, +}; + +enum msm_vidc_vp9_color_primaries_values { + MSM_VIDC_CS_UNKNOWN, + MSM_VIDC_CS_BT_601, + MSM_VIDC_CS_BT_709, + MSM_VIDC_CS_SMPTE_170, + MSM_VIDC_CS_SMPTE_240, + MSM_VIDC_CS_BT_2020, + MSM_VIDC_CS_RESERVED, + MSM_VIDC_CS_RGB, +}; + +enum msm_vidc_h264_matrix_coeff_values { + MSM_VIDC_MATRIX_RGB = 0, + MSM_VIDC_MATRIX_BT_709_5 = 1, + MSM_VIDC_MATRIX_UNSPECIFIED = 2, + MSM_VIDC_MATRIX_RESERVED = 3, + MSM_VIDC_MATRIX_FCC_47 = 4, + MSM_VIDC_MATRIX_601_6_625 = 5, + MSM_VIDC_MATRIX_BT470_BG = MSM_VIDC_MATRIX_601_6_625, + MSM_VIDC_MATRIX_601_6_525 = 6, + MSM_VIDC_MATRIX_SMPTE_170M = MSM_VIDC_MATRIX_601_6_525, + MSM_VIDC_MATRIX_SMPTE_240M = 7, + MSM_VIDC_MATRIX_Y_CG_CO = 8, + MSM_VIDC_MATRIX_BT_2020 = 9, + MSM_VIDC_MATRIX_BT_2020_CONST = 10, +}; + +enum msm_vidc_h264_transfer_chars_values { + MSM_VIDC_TRANSFER_RESERVED_1 = 0, + MSM_VIDC_TRANSFER_BT709_5 = 1, + MSM_VIDC_TRANSFER_UNSPECIFIED = 2, + MSM_VIDC_TRANSFER_RESERVED_2 = 3, + MSM_VIDC_TRANSFER_BT_470_6_M = 4, + MSM_VIDC_TRANSFER_BT_470_6_BG = 5, + MSM_VIDC_TRANSFER_601_6_625 = 6, + MSM_VIDC_TRANSFER_601_6_525 = MSM_VIDC_TRANSFER_601_6_625, + MSM_VIDC_TRANSFER_SMPTE_240M = 7, + MSM_VIDC_TRANSFER_LINEAR = 8, + MSM_VIDC_TRANSFER_LOG_100_1 = 9, + MSM_VIDC_TRANSFER_LOG_100_SQRT10_1 = 10, + MSM_VIDC_TRANSFER_IEC_61966 = 11, + MSM_VIDC_TRANSFER_BT_1361 = 12, + MSM_VIDC_TRANSFER_SRGB = 13, + MSM_VIDC_TRANSFER_BT_2020_10 = 14, + MSM_VIDC_TRANSFER_BT_2020_12 = 15, +}; +enum msm_vidc_video_format { + MSM_VIDC_COMPONENT, + MSM_VIDC_PAL, + MSM_VIDC_NTSC, + MSM_VIDC_SECAM, + MSM_VIDC_MAC, + MSM_VIDC_UNSPECIFIED_FORMAT, + MSM_VIDC_RESERVED_1_FORMAT, + MSM_VIDC_RESERVED_2_FORMAT, +}; +enum msm_vidc_color_desc_flag { + MSM_VIDC_COLOR_DESC_NOT_PRESENT, + MSM_VIDC_COLOR_DESC_PRESENT, +}; #endif diff --git a/kernel/events/core.c b/kernel/events/core.c index 5d91b670a2b6d..806ee14590aef 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -163,6 +163,8 @@ int sysctl_perf_event_paranoid __read_mostly = 3; #else #ifdef CONFIG_PERF_EVENTS_USERMODE int sysctl_perf_event_paranoid __read_mostly = -1; +#elif defined CONFIG_SECURITY_PERF_EVENTS_RESTRICT +int sysctl_perf_event_paranoid __read_mostly = 3; #else int sysctl_perf_event_paranoid __read_mostly = 1; #endif @@ -6206,7 +6208,6 @@ int perf_pmu_register(struct pmu *pmu, char *name, int type) __perf_event_init_context(&cpuctx->ctx); lockdep_set_class(&cpuctx->ctx.mutex, &cpuctx_mutex); lockdep_set_class(&cpuctx->ctx.lock, &cpuctx_lock); - cpuctx->ctx.type = cpu_context; cpuctx->ctx.pmu = pmu; cpuctx->jiffies_interval = 1; INIT_LIST_HEAD(&cpuctx->rotation_list); @@ -6819,7 +6820,19 @@ SYSCALL_DEFINE5(perf_event_open, * task or CPU context: */ if (move_group) { - if (group_leader->ctx->type != ctx->type) + /* + * Make sure we're both on the same task, or both + * per-cpu events. + */ + if (group_leader->ctx->task != ctx->task) + goto err_context; + + /* + * Make sure we're both events for the same CPU; + * grouping events for different CPUs is broken; since + * you can never concurrently schedule them anyhow. + */ + if (group_leader->cpu != event->cpu) goto err_context; } else { if (group_leader->ctx != ctx) diff --git a/kernel/kthread.c b/kernel/kthread.c index 760e86df8c204..c56c6f8ec6078 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -398,6 +398,8 @@ int kthread_park(struct task_struct *k) if (k != current) { wake_up_process(k); wait_for_completion(&kthread->parked); + while (k->state != TASK_PARKED) + cond_resched(); } } ret = 0; diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 3e97737a8d2d1..c5205a4b30853 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -1658,6 +1658,28 @@ static struct ctl_table vm_table[] = { .mode = 0644, .proc_handler = proc_doulongvec_minmax, }, +#ifdef CONFIG_HAVE_ARCH_MMAP_RND_BITS + { + .procname = "mmap_rnd_bits", + .data = &mmap_rnd_bits, + .maxlen = sizeof(mmap_rnd_bits), + .mode = 0600, + .proc_handler = proc_dointvec_minmax, + .extra1 = (void *)&mmap_rnd_bits_min, + .extra2 = (void *)&mmap_rnd_bits_max, + }, +#endif +#ifdef CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS + { + .procname = "mmap_rnd_compat_bits", + .data = &mmap_rnd_compat_bits, + .maxlen = sizeof(mmap_rnd_compat_bits), + .mode = 0600, + .proc_handler = proc_dointvec_minmax, + .extra1 = (void *)&mmap_rnd_compat_bits_min, + .extra2 = (void *)&mmap_rnd_compat_bits_max, + }, +#endif { } }; diff --git a/lib/qmi_encdec.c b/lib/qmi_encdec.c index a205a5b719bbb..d930aae18e352 100644 --- a/lib/qmi_encdec.c +++ b/lib/qmi_encdec.c @@ -24,7 +24,6 @@ #define TLV_LEN_SIZE sizeof(uint16_t) #define TLV_TYPE_SIZE sizeof(uint8_t) -#define U8_MAX 255 #ifdef CONFIG_QMI_ENCDEC_DEBUG diff --git a/mm/mmap.c b/mm/mmap.c index 37528a3597ce0..641dd3d2c3dc9 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -52,6 +52,18 @@ #define arch_rebalance_pgtables(addr, len) (addr) #endif +#ifdef CONFIG_HAVE_ARCH_MMAP_RND_BITS +const int mmap_rnd_bits_min = CONFIG_ARCH_MMAP_RND_BITS_MIN; +const int mmap_rnd_bits_max = CONFIG_ARCH_MMAP_RND_BITS_MAX; +int mmap_rnd_bits __read_mostly = CONFIG_ARCH_MMAP_RND_BITS; +#endif +#ifdef CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS +const int mmap_rnd_compat_bits_min = CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN; +const int mmap_rnd_compat_bits_max = CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX; +int mmap_rnd_compat_bits __read_mostly = CONFIG_ARCH_MMAP_RND_COMPAT_BITS; +#endif + + static void unmap_region(struct mm_struct *mm, struct vm_area_struct *vma, struct vm_area_struct *prev, unsigned long start, unsigned long end); diff --git a/mm/process_reclaim.c b/mm/process_reclaim.c index 5afd106998dc3..0b6aea811d61c 100644 --- a/mm/process_reclaim.c +++ b/mm/process_reclaim.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -48,6 +48,10 @@ static unsigned long pressure_max = 90; module_param_named(pressure_min, pressure_min, ulong, S_IRUGO | S_IWUSR); module_param_named(pressure_max, pressure_max, ulong, S_IRUGO | S_IWUSR); +static short min_score_adj = 360; +module_param_named(min_score_adj, min_score_adj, short, + S_IRUGO | S_IWUSR); + /* * Scheduling process reclaim workqueue unecessarily * when the reclaim efficiency is low does not make @@ -114,7 +118,6 @@ static void swap_fn(struct work_struct *work) int i; int tasksize; int total_sz = 0; - short min_score_adj = 360; int total_scan = 0; int total_reclaimed = 0; int nr_to_reclaim; diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index f7c36826f3f4d..3b6e2439f7ab5 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -185,7 +185,7 @@ EXPORT_SYMBOL(bt_sock_unlink); void bt_accept_enqueue(struct sock *parent, struct sock *sk) { - BT_DBG("parent %p, sk %p", parent, sk); + BT_DBG("parent %pK, sk %pK", parent, sk); sock_hold(sk); list_add_tail(&bt_sk(sk)->accept_q, &bt_sk(parent)->accept_q); @@ -196,7 +196,7 @@ EXPORT_SYMBOL(bt_accept_enqueue); void bt_accept_unlink(struct sock *sk) { - BT_DBG("sk %p state %d", sk, sk->sk_state); + BT_DBG("sk %pK state %d", sk, sk->sk_state); list_del_init(&bt_sk(sk)->accept_q); bt_sk(sk)->parent->sk_ack_backlog--; @@ -210,7 +210,7 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock) struct list_head *p, *n; struct sock *sk; - BT_DBG("parent %p", parent); + BT_DBG("parent %pK", parent); list_for_each_safe(p, n, &bt_sk(parent)->accept_q) { sk = (struct sock *) list_entry(p, struct bt_sock, accept_q); @@ -250,7 +250,7 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, size_t copied; int err; - BT_DBG("sock %p sk %p len %zu", sock, sk, len); + BT_DBG("sock %pK sk %pK len %zu", sock, sk, len); if (flags & (MSG_OOB)) return -EOPNOTSUPP; @@ -319,7 +319,7 @@ int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock, if (flags & MSG_OOB) return -EOPNOTSUPP; - BT_DBG("sk %p size %zu", sk, size); + BT_DBG("sk %pK size %zu", sk, size); lock_sock(sk); @@ -435,7 +435,7 @@ unsigned int bt_sock_poll(struct file *file, struct socket *sock, struct sock *sk = sock->sk; unsigned int mask = 0; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); poll_wait(file, sk_sleep(sk), wait); @@ -479,7 +479,7 @@ int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) long amount; int err; - BT_DBG("sk %p cmd %x arg %lx", sk, cmd, arg); + BT_DBG("sk %pK cmd %x arg %lx", sk, cmd, arg); switch (cmd) { case TIOCOUTQ: @@ -525,7 +525,7 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo) DECLARE_WAITQUEUE(wait, current); int err = 0; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); add_wait_queue(sk_sleep(sk), &wait); set_current_state(TASK_INTERRUPTIBLE); diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index e430b1abcd2fa..13f3b1ff245d9 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c @@ -393,7 +393,7 @@ static int bnep_tx_frame(struct bnep_session *s, struct sk_buff *skb) int len = 0, il = 0; u8 type = 0; - BT_DBG("skb %p dev %p type %d", skb, skb->dev, skb->pkt_type); + BT_DBG("skb %pK dev %pK type %d", skb, skb->dev, skb->pkt_type); if (!skb->dev) { /* Control frame sent by us */ diff --git a/net/bluetooth/bnep/netdev.c b/net/bluetooth/bnep/netdev.c index 4b488ec261054..601b7b21ab581 100644 --- a/net/bluetooth/bnep/netdev.c +++ b/net/bluetooth/bnep/netdev.c @@ -156,7 +156,7 @@ static int bnep_net_proto_filter(struct sk_buff *skb, struct bnep_session *s) return 0; } - BT_DBG("BNEP: filtered skb %p, proto 0x%.4x", skb, proto); + BT_DBG("BNEP: filtered skb %pK, proto 0x%.4x", skb, proto); return 1; } #endif @@ -167,7 +167,7 @@ static netdev_tx_t bnep_net_xmit(struct sk_buff *skb, struct bnep_session *s = netdev_priv(dev); struct sock *sk = s->sock->sk; - BT_DBG("skb %p, dev %p", skb, dev); + BT_DBG("skb %pK, dev %pK", skb, dev); #ifdef CONFIG_BT_BNEP_MC_FILTER if (bnep_net_mc_filter(skb, s)) { diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c index 5f051290dabab..9340bf18063ce 100644 --- a/net/bluetooth/bnep/sock.c +++ b/net/bluetooth/bnep/sock.c @@ -37,7 +37,7 @@ static int bnep_sock_release(struct socket *sock) { struct sock *sk = sock->sk; - BT_DBG("sock %p sk %p", sock, sk); + BT_DBG("sock %pK sk %pK", sock, sk); if (!sk) return 0; @@ -190,7 +190,7 @@ static int bnep_sock_create(struct net *net, struct socket *sock, int protocol, { struct sock *sk; - BT_DBG("sock %p", sock); + BT_DBG("sock %pK", sock); if (sock->type != SOCK_RAW) return -ESOCKTNOSUPPORT; diff --git a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c index cd75e4d64b909..d09f976f35970 100644 --- a/net/bluetooth/cmtp/capi.c +++ b/net/bluetooth/cmtp/capi.c @@ -74,7 +74,7 @@ static struct cmtp_application *cmtp_application_add(struct cmtp_session *sessio { struct cmtp_application *app = kzalloc(sizeof(*app), GFP_KERNEL); - BT_DBG("session %p application %p appl %d", session, app, appl); + BT_DBG("session %pK application %pK appl %d", session, app, appl); if (!app) return NULL; @@ -89,7 +89,7 @@ static struct cmtp_application *cmtp_application_add(struct cmtp_session *sessio static void cmtp_application_del(struct cmtp_session *session, struct cmtp_application *app) { - BT_DBG("session %p application %p", session, app); + BT_DBG("session %pK application %pK", session, app); if (app) { list_del(&app->list); @@ -137,7 +137,7 @@ static void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb) { struct cmtp_scb *scb = (void *) skb->cb; - BT_DBG("session %p skb %p len %d", session, skb, skb->len); + BT_DBG("session %pK skb %pK len %d", session, skb, skb->len); scb->id = -1; scb->data = (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3); @@ -154,7 +154,8 @@ static void cmtp_send_interopmsg(struct cmtp_session *session, struct sk_buff *skb; unsigned char *s; - BT_DBG("session %p subcmd 0x%02x appl %d msgnum %d", session, subcmd, appl, msgnum); + BT_DBG("session %pK subcmd 0x%02x appl %d msgnum %d", + session, subcmd, appl, msgnum); skb = alloc_skb(CAPI_MSG_BASELEN + 6 + len, GFP_ATOMIC); if (!skb) { @@ -190,7 +191,7 @@ static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *s __u16 appl, msgnum, func, info; __u32 controller; - BT_DBG("session %p skb %p len %d", session, skb, skb->len); + BT_DBG("session %pK skb %pK len %d", session, skb, skb->len); switch (CAPIMSG_SUBCOMMAND(skb->data)) { case CAPI_CONF: @@ -329,7 +330,7 @@ void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb) __u16 appl; __u32 contr; - BT_DBG("session %p skb %p len %d", session, skb, skb->len); + BT_DBG("session %pK skb %pK len %d", session, skb, skb->len); if (skb->len < CAPI_MSG_BASELEN) return; @@ -373,7 +374,7 @@ void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb) static int cmtp_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) { - BT_DBG("ctrl %p data %p", ctrl, data); + BT_DBG("ctrl %pK data %pK", ctrl, data); return 0; } @@ -382,7 +383,7 @@ static void cmtp_reset_ctr(struct capi_ctr *ctrl) { struct cmtp_session *session = ctrl->driverdata; - BT_DBG("ctrl %p", ctrl); + BT_DBG("ctrl %pK", ctrl); capi_ctr_down(ctrl); @@ -399,8 +400,8 @@ static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_ unsigned char buf[8]; int err = 0, nconn, want = rp->level3cnt; - BT_DBG("ctrl %p appl %d level3cnt %d datablkcnt %d datablklen %d", - ctrl, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen); + BT_DBG("ctrl %pK appl %d level3cnt %d datablkcnt %d datablklen %d", + ctrl, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen); application = cmtp_application_add(session, appl); if (!application) { @@ -464,7 +465,7 @@ static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl) struct cmtp_session *session = ctrl->driverdata; struct cmtp_application *application; - BT_DBG("ctrl %p appl %d", ctrl, appl); + BT_DBG("ctrl %pK appl %d", ctrl, appl); application = cmtp_application_get(session, CMTP_APPLID, appl); if (!application) { @@ -490,7 +491,7 @@ static u16 cmtp_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) __u16 appl; __u32 contr; - BT_DBG("ctrl %p skb %p", ctrl, skb); + BT_DBG("ctrl %pK skb %pK", ctrl, skb); appl = CAPIMSG_APPID(skb->data); contr = CAPIMSG_CONTROL(skb->data); @@ -555,7 +556,7 @@ int cmtp_attach_device(struct cmtp_session *session) unsigned char buf[4]; long ret; - BT_DBG("session %p", session); + BT_DBG("session %pK", session); capimsg_setu32(buf, 0, 0); @@ -597,7 +598,7 @@ int cmtp_attach_device(struct cmtp_session *session) session->num = session->ctrl.cnr; - BT_DBG("session %p num %d", session, session->num); + BT_DBG("session %pK num %d", session, session->num); capimsg_setu32(buf, 0, 1); @@ -618,7 +619,7 @@ int cmtp_attach_device(struct cmtp_session *session) void cmtp_detach_device(struct cmtp_session *session) { - BT_DBG("session %p", session); + BT_DBG("session %pK", session); detach_capi_ctr(&session->ctrl); } diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index e0a6ebf2baa6f..d74d9fe541189 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c @@ -108,7 +108,7 @@ static inline void cmtp_add_msgpart(struct cmtp_session *session, int id, const struct sk_buff *skb = session->reassembly[id], *nskb; int size; - BT_DBG("session %p buf %p count %d", session, buf, count); + BT_DBG("session %pK buf %pK count %d", session, buf, count); size = (skb) ? skb->len + count : count; @@ -133,7 +133,7 @@ static inline int cmtp_recv_frame(struct cmtp_session *session, struct sk_buff * __u8 hdr, hdrlen, id; __u16 len; - BT_DBG("session %p skb %p len %d", session, skb, skb->len); + BT_DBG("session %pK skb %pK len %d", session, skb, skb->len); while (skb->len > 0) { hdr = skb->data[0]; @@ -196,7 +196,7 @@ static int cmtp_send_frame(struct cmtp_session *session, unsigned char *data, in struct kvec iv = { data, len }; struct msghdr msg; - BT_DBG("session %p data %p len %d", session, data, len); + BT_DBG("session %pK data %pK len %d", session, data, len); if (!len) return 0; @@ -212,7 +212,7 @@ static void cmtp_process_transmit(struct cmtp_session *session) unsigned char *hdr; unsigned int size, tail; - BT_DBG("session %p", session); + BT_DBG("session %pK", session); nskb = alloc_skb(session->mtu, GFP_ATOMIC); if (!nskb) { @@ -282,7 +282,7 @@ static int cmtp_session(void *arg) struct sk_buff *skb; wait_queue_t wait; - BT_DBG("session %p", session); + BT_DBG("session %pK", session); set_user_nice(current, -15); diff --git a/net/bluetooth/cmtp/sock.c b/net/bluetooth/cmtp/sock.c index d82787d417bdc..8d7d3c16c8b6f 100644 --- a/net/bluetooth/cmtp/sock.c +++ b/net/bluetooth/cmtp/sock.c @@ -50,7 +50,7 @@ static int cmtp_sock_release(struct socket *sock) { struct sock *sk = sock->sk; - BT_DBG("sock %p sk %p", sock, sk); + BT_DBG("sock %pK sk %pK", sock, sk); if (!sk) return 0; @@ -200,7 +200,7 @@ static int cmtp_sock_create(struct net *net, struct socket *sock, int protocol, { struct sock *sk; - BT_DBG("sock %p", sock); + BT_DBG("sock %pK", sock); if (sock->type != SOCK_RAW) return -ESOCKTNOSUPPORT; diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 44ed20c84745f..600a8acc61496 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -66,7 +66,7 @@ static void hci_acl_create_connection(struct hci_conn *conn) struct inquiry_entry *ie; struct hci_cp_create_conn cp; - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); conn->state = BT_CONNECT; conn->out = true; @@ -110,7 +110,7 @@ static void hci_acl_create_connection_cancel(struct hci_conn *conn) { struct hci_cp_create_conn_cancel cp; - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); if (conn->hdev->hci_ver < BLUETOOTH_VER_1_2) return; @@ -133,7 +133,7 @@ void hci_disconnect(struct hci_conn *conn, __u8 reason) { struct hci_cp_disconnect cp; - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); conn->state = BT_DISCONN; @@ -146,7 +146,7 @@ static void hci_amp_disconn(struct hci_conn *conn, __u8 reason) { struct hci_cp_disconn_phy_link cp; - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); conn->state = BT_DISCONN; @@ -161,7 +161,7 @@ static void hci_add_sco(struct hci_conn *conn, __u16 handle) struct hci_dev *hdev = conn->hdev; struct hci_cp_add_sco cp; - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); conn->state = BT_CONNECT; conn->out = true; @@ -179,7 +179,7 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle) struct hci_dev *hdev = conn->hdev; struct hci_cp_setup_sync_conn cp; - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); conn->state = BT_CONNECT; conn->out = true; @@ -223,7 +223,7 @@ void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8], struct hci_dev *hdev = conn->hdev; struct hci_cp_le_start_enc cp; - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); memset(&cp, 0, sizeof(cp)); @@ -243,7 +243,7 @@ void hci_sco_setup(struct hci_conn *conn, __u8 status) if (!sco) return; - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); if (!status) { if (lmp_esco_capable(conn->hdev)) @@ -275,7 +275,7 @@ static void hci_conn_timeout(struct work_struct *work) struct hci_conn *conn = container_of(work, struct hci_conn, disc_work.work); - BT_DBG("hcon %p state %s", conn, state_to_string(conn->state)); + BT_DBG("hcon %pK state %s", conn, state_to_string(conn->state)); if (atomic_read(&conn->refcnt)) return; @@ -307,7 +307,7 @@ static void hci_conn_enter_sniff_mode(struct hci_conn *conn) { struct hci_dev *hdev = conn->hdev; - BT_DBG("hcon %p mode %d", conn, conn->mode); + BT_DBG("hcon %pK mode %d", conn, conn->mode); if (test_bit(HCI_RAW, &hdev->flags)) return; @@ -345,7 +345,7 @@ static void hci_conn_idle(unsigned long arg) { struct hci_conn *conn = (void *) arg; - BT_DBG("hcon %p mode %d", conn, conn->mode); + BT_DBG("hcon %pK mode %d", conn, conn->mode); hci_conn_enter_sniff_mode(conn); } @@ -433,7 +433,7 @@ int hci_conn_del(struct hci_conn *conn) { struct hci_dev *hdev = conn->hdev; - BT_DBG("%s hcon %p handle %d", hdev->name, conn, conn->handle); + BT_DBG("%s hcon %pK handle %d", hdev->name, conn, conn->handle); del_timer(&conn->idle_timer); @@ -650,7 +650,7 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, /* Check link security requirement */ int hci_conn_check_link_mode(struct hci_conn *conn) { - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); if (hci_conn_ssp_enabled(conn) && !(conn->link_mode & HCI_LM_ENCRYPT)) return 0; @@ -661,7 +661,7 @@ int hci_conn_check_link_mode(struct hci_conn *conn) /* Authenticate remote device */ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) { - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); if (conn->pending_sec_level > sec_level) sec_level = conn->pending_sec_level; @@ -698,7 +698,7 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) /* Encrypt the the link */ static void hci_conn_encrypt(struct hci_conn *conn) { - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); if (!test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) { struct hci_cp_set_conn_encrypt cp; @@ -712,7 +712,7 @@ static void hci_conn_encrypt(struct hci_conn *conn) /* Enable security */ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) { - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); if (conn->type == LE_LINK) return smp_conn_security(conn, sec_level); @@ -768,7 +768,7 @@ EXPORT_SYMBOL(hci_conn_security); /* Check secure link requirement */ int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level) { - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); if (sec_level != BT_SECURITY_HIGH) return 1; /* Accept if non-secure is required */ @@ -783,7 +783,7 @@ EXPORT_SYMBOL(hci_conn_check_secure); /* Change link key */ int hci_conn_change_link_key(struct hci_conn *conn) { - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { struct hci_cp_change_conn_link_key cp; @@ -798,7 +798,7 @@ int hci_conn_change_link_key(struct hci_conn *conn) /* Switch role */ int hci_conn_switch_role(struct hci_conn *conn, __u8 role) { - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); if (!role && conn->link_mode & HCI_LM_MASTER) return 1; @@ -837,7 +837,7 @@ void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active) { struct hci_dev *hdev = conn->hdev; - BT_DBG("hcon %p mode %d", conn, conn->mode); + BT_DBG("hcon %pK mode %d", conn, conn->mode); if (test_bit(HCI_RAW, &hdev->flags)) return; @@ -1019,7 +1019,7 @@ struct hci_chan *hci_chan_create(struct hci_conn *conn) struct hci_dev *hdev = conn->hdev; struct hci_chan *chan; - BT_DBG("%s hcon %p", hdev->name, conn); + BT_DBG("%s hcon %pK", hdev->name, conn); chan = kzalloc(sizeof(struct hci_chan), GFP_KERNEL); if (!chan) @@ -1039,7 +1039,7 @@ void hci_chan_del(struct hci_chan *chan) struct hci_conn *conn = chan->conn; struct hci_dev *hdev = conn->hdev; - BT_DBG("%s hcon %p chan %p", hdev->name, conn, chan); + BT_DBG("%s hcon %pK chan %pK", hdev->name, conn, chan); list_del_rcu(&chan->list); @@ -1055,7 +1055,7 @@ void hci_chan_list_flush(struct hci_conn *conn) { struct hci_chan *chan, *n; - BT_DBG("hcon %p", conn); + BT_DBG("hcon %pK", conn); list_for_each_entry_safe(chan, n, &conn->chan_list, list) hci_chan_del(chan); diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index f91b3baf3e14a..3d8e183a5c3cf 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -771,7 +771,7 @@ struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, struct discovery_state *cache = &hdev->discovery; struct inquiry_entry *e; - BT_DBG("cache %p, %pMR", cache, bdaddr); + BT_DBG("cache %pK, %pMR", cache, bdaddr); list_for_each_entry(e, &cache->all, all) { if (!bacmp(&e->data.bdaddr, bdaddr)) @@ -787,7 +787,7 @@ struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, struct discovery_state *cache = &hdev->discovery; struct inquiry_entry *e; - BT_DBG("cache %p, %pMR", cache, bdaddr); + BT_DBG("cache %pK, %pMR", cache, bdaddr); list_for_each_entry(e, &cache->unknown, list) { if (!bacmp(&e->data.bdaddr, bdaddr)) @@ -804,7 +804,7 @@ struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, struct discovery_state *cache = &hdev->discovery; struct inquiry_entry *e; - BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state); + BT_DBG("cache %pK bdaddr %pMR state %d", cache, bdaddr, state); list_for_each_entry(e, &cache->resolve, list) { if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) @@ -841,7 +841,7 @@ bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, struct discovery_state *cache = &hdev->discovery; struct inquiry_entry *ie; - BT_DBG("cache %p, %pMR", cache, &data->bdaddr); + BT_DBG("cache %pK, %pMR", cache, &data->bdaddr); hci_remove_remote_oob_data(hdev, &data->bdaddr); @@ -917,7 +917,7 @@ static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf) copied++; } - BT_DBG("cache %p, copied %d", cache, copied); + BT_DBG("cache %pK, copied %d", cache, copied); return copied; } @@ -1114,7 +1114,7 @@ int hci_dev_open(__u16 dev) if (!hdev) return -ENODEV; - BT_DBG("%s %p", hdev->name, hdev); + BT_DBG("%s %pK", hdev->name, hdev); hci_req_lock(hdev); @@ -1203,7 +1203,7 @@ int hci_dev_open(__u16 dev) static int hci_dev_do_close(struct hci_dev *hdev) { - BT_DBG("%s %p", hdev->name, hdev); + BT_DBG("%s %pK", hdev->name, hdev); cancel_work_sync(&hdev->le_scan); @@ -1546,7 +1546,7 @@ static int hci_rfkill_set_block(void *data, bool blocked) { struct hci_dev *hdev = data; - BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); + BT_DBG("%pK name %s blocked %d", hdev, hdev->name, blocked); if (blocked) { set_bit(HCI_RFKILLED, &hdev->dev_flags); @@ -2215,7 +2215,7 @@ int hci_register_dev(struct hci_dev *hdev) snprintf(hdev->name, sizeof(hdev->name), "hci%d", id); hdev->id = id; - BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); + BT_DBG("%pK name %s bus %d", hdev, hdev->name, hdev->bus); write_lock(&hci_dev_list_lock); list_add(&hdev->list, &hci_dev_list); @@ -2284,7 +2284,7 @@ void hci_unregister_dev(struct hci_dev *hdev) { int i, id; - BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); + BT_DBG("%pK name %s bus %d", hdev, hdev->name, hdev->bus); set_bit(HCI_UNREGISTER, &hdev->dev_flags); @@ -2545,7 +2545,7 @@ EXPORT_SYMBOL(hci_recv_stream_fragment); int hci_register_cb(struct hci_cb *cb) { - BT_DBG("%p name %s", cb, cb->name); + BT_DBG("%pK name %s", cb, cb->name); write_lock(&hci_cb_list_lock); list_add(&cb->list, &hci_cb_list); @@ -2557,7 +2557,7 @@ EXPORT_SYMBOL(hci_register_cb); int hci_unregister_cb(struct hci_cb *cb) { - BT_DBG("%p name %s", cb, cb->name); + BT_DBG("%pK name %s", cb, cb->name); write_lock(&hci_cb_list_lock); list_del(&cb->list); @@ -2780,12 +2780,12 @@ static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, list = skb_shinfo(skb)->frag_list; if (!list) { /* Non fragmented */ - BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); + BT_DBG("%s nonfrag skb %pK len %d", hdev->name, skb, skb->len); skb_queue_tail(queue, skb); } else { /* Fragmented */ - BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); + BT_DBG("%s frag %pK len %d", hdev->name, skb, skb->len); skb_shinfo(skb)->frag_list = NULL; @@ -2803,7 +2803,7 @@ static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; hci_add_acl_hdr(skb, conn->handle, flags); - BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); + BT_DBG("%s frag %pK len %d", hdev->name, skb, skb->len); __skb_queue_tail(queue, skb); } while (list); @@ -2816,7 +2816,7 @@ void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) { struct hci_dev *hdev = chan->conn->hdev; - BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); + BT_DBG("%s chan %pK flags 0x%4.4x", hdev->name, chan, flags); skb->dev = (void *) hdev; @@ -2906,7 +2906,7 @@ static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, } else *quote = 0; - BT_DBG("conn %p quote %d", conn, *quote); + BT_DBG("conn %pK quote %d", conn, *quote); return conn; } @@ -3009,7 +3009,7 @@ static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, q = cnt / num; *quote = q ? q : 1; - BT_DBG("chan %p quote %d", chan, *quote); + BT_DBG("chan %pK quote %d", chan, *quote); return chan; } @@ -3051,7 +3051,7 @@ static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) skb->priority = HCI_PRIO_MAX - 1; - BT_DBG("chan %p skb %p promoted to %d", chan, skb, + BT_DBG("chan %pK skb %pK promoted to %d", chan, skb, skb->priority); } @@ -3093,7 +3093,7 @@ static void hci_sched_acl_pkt(struct hci_dev *hdev) (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { u32 priority = (skb_peek(&chan->data_q))->priority; while (quote-- && (skb = skb_peek(&chan->data_q))) { - BT_DBG("chan %p skb %p len %d priority %u", chan, skb, + BT_DBG("chan %pK skb %pK len %d priority %u", chan, skb, skb->len, skb->priority); /* Stop if priority has changed */ @@ -3141,7 +3141,7 @@ static void hci_sched_acl_blk(struct hci_dev *hdev) while (quote > 0 && (skb = skb_peek(&chan->data_q))) { int blocks; - BT_DBG("chan %p skb %p len %d priority %u", chan, skb, + BT_DBG("chan %pK skb %pK len %d priority %u", chan, skb, skb->len, skb->priority); /* Stop if priority has changed */ @@ -3209,7 +3209,7 @@ static void hci_sched_sco(struct hci_dev *hdev) while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { while (quote-- && (skb = skb_dequeue(&conn->data_q))) { - BT_DBG("skb %p len %d", skb, skb->len); + BT_DBG("skb %pK len %d", skb, skb->len); hci_send_frame(skb); conn->sent++; @@ -3233,7 +3233,7 @@ static void hci_sched_esco(struct hci_dev *hdev) while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, "e))) { while (quote-- && (skb = skb_dequeue(&conn->data_q))) { - BT_DBG("skb %p len %d", skb, skb->len); + BT_DBG("skb %pK len %d", skb, skb->len); hci_send_frame(skb); conn->sent++; @@ -3267,7 +3267,7 @@ static void hci_sched_le(struct hci_dev *hdev) while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { u32 priority = (skb_peek(&chan->data_q))->priority; while (quote-- && (skb = skb_peek(&chan->data_q))) { - BT_DBG("chan %p skb %p len %d priority %u", chan, skb, + BT_DBG("chan %pK skb %pK len %d priority %u", chan, skb, skb->len, skb->priority); /* Stop if priority has changed */ diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 9918688c78995..39f900d199ff1 100755 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1106,7 +1106,7 @@ static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); - BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn); + BT_DBG("%s bdaddr %pMR hcon %pK", hdev->name, &cp->bdaddr, conn); if (status) { if (conn && conn->state == BT_CONNECT) { @@ -1535,7 +1535,7 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status) return; } - BT_DBG("%s bdaddr %pMR conn %p", hdev->name, &conn->dst, conn); + BT_DBG("%s bdaddr %pMR conn %pK", hdev->name, &conn->dst, conn); conn->state = BT_CLOSED; mgmt_connect_failed(hdev, &conn->dst, conn->type, @@ -2533,7 +2533,7 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb) break; default: - BT_ERR("Unknown type %d conn %p", conn->type, conn); + BT_ERR("Unknown type %d conn %pK", conn->type, conn); break; } } @@ -2604,7 +2604,7 @@ static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb) break; default: - BT_ERR("Unknown type %d conn %p", conn->type, conn); + BT_ERR("Unknown type %d conn %pK", conn->type, conn); break; } } @@ -3488,7 +3488,7 @@ static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) hchan->handle = le16_to_cpu(ev->handle); - BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan); + BT_DBG("hcon %pK mgr %pK hchan %pK", hcon, hcon->amp_mgr, hchan); mgr = hcon->amp_mgr; if (mgr && mgr->bredr_chan) { diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index fa4bf66314255..4f5acc0247025 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -72,7 +72,7 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb) struct sock *sk; struct sk_buff *skb_copy = NULL; - BT_DBG("hdev %p len %d", hdev, skb->len); + BT_DBG("hdev %pK len %d", hdev, skb->len); read_lock(&hci_sk_list.lock); @@ -180,7 +180,7 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb) if (!atomic_read(&monitor_promisc)) return; - BT_DBG("hdev %p len %d", hdev, skb->len); + BT_DBG("hdev %pK len %d", hdev, skb->len); switch (bt_cb(skb)->pkt_type) { case HCI_COMMAND_PKT: @@ -413,7 +413,7 @@ static int hci_sock_release(struct socket *sock) struct sock *sk = sock->sk; struct hci_dev *hdev; - BT_DBG("sock %p sk %p", sock, sk); + BT_DBG("sock %pK sk %pK", sock, sk); if (!sk) return 0; @@ -590,7 +590,7 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, struct hci_dev *hdev = NULL; int len, err = 0; - BT_DBG("sock %p sk %p", sock, sk); + BT_DBG("sock %pK sk %pK", sock, sk); if (!addr) return -EINVAL; @@ -679,7 +679,7 @@ static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, struct sock *sk = sock->sk; struct hci_dev *hdev = hci_pi(sk)->hdev; - BT_DBG("sock %p sk %p", sock, sk); + BT_DBG("sock %pK sk %pK", sock, sk); if (!hdev) return -EBADFD; @@ -740,7 +740,7 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct sk_buff *skb; int copied, err; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); if (flags & (MSG_OOB)) return -EOPNOTSUPP; @@ -784,7 +784,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct sk_buff *skb; int err; - BT_DBG("sock %p sk %p", sock, sk); + BT_DBG("sock %pK sk %pK", sock, sk); if (msg->msg_flags & MSG_OOB) return -EOPNOTSUPP; @@ -888,7 +888,7 @@ static int hci_sock_setsockopt(struct socket *sock, int level, int optname, struct sock *sk = sock->sk; int err = 0, opt = 0; - BT_DBG("sk %p, opt %d", sk, optname); + BT_DBG("sk %pK, opt %d", sk, optname); lock_sock(sk); @@ -971,7 +971,7 @@ static int hci_sock_getsockopt(struct socket *sock, int level, int optname, struct sock *sk = sock->sk; int len, opt, err = 0; - BT_DBG("sk %p, opt %d", sk, optname); + BT_DBG("sk %pK, opt %d", sk, optname); if (get_user(len, optlen)) return -EFAULT; @@ -1061,7 +1061,7 @@ static int hci_sock_create(struct net *net, struct socket *sock, int protocol, { struct sock *sk; - BT_DBG("sock %p", sock); + BT_DBG("sock %pK", sock); if (sock->type != SOCK_RAW) return -ESOCKTNOSUPPORT; diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 7ad6ecf36f20a..1c207bf0afec4 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c @@ -103,7 +103,7 @@ void hci_conn_init_sysfs(struct hci_conn *conn) { struct hci_dev *hdev = conn->hdev; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); conn->dev.type = &bt_link; conn->dev.class = bt_class; @@ -116,7 +116,7 @@ void hci_conn_add_sysfs(struct hci_conn *conn) { struct hci_dev *hdev = conn->hdev; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle); @@ -547,7 +547,7 @@ int hci_add_sysfs(struct hci_dev *hdev) struct device *dev = &hdev->dev; int err; - BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); + BT_DBG("%pK name %s bus %d", hdev, hdev->name, hdev->bus); dev_set_name(dev, "%s", hdev->name); @@ -577,7 +577,7 @@ int hci_add_sysfs(struct hci_dev *hdev) void hci_del_sysfs(struct hci_dev *hdev) { - BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); + BT_DBG("%pK name %s bus %d", hdev, hdev->name, hdev->bus); debugfs_remove_recursive(hdev->debugfs); diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index b5cfba13bd379..5afd337cfa075 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -106,7 +106,7 @@ static int hidp_send_message(struct hidp_session *session, struct socket *sock, struct sk_buff *skb; struct sock *sk = sock->sk; - BT_DBG("session %p data %p size %d", session, data, size); + BT_DBG("session %pK data %pK size %d", session, data, size); if (atomic_read(&session->terminate)) return -EIO; @@ -150,7 +150,7 @@ static int hidp_input_event(struct input_dev *dev, unsigned int type, unsigned char newleds; unsigned char hdr, data[2]; - BT_DBG("session %p type %d code %d value %d", + BT_DBG("session %pK type %d code %d value %d", session, type, code, value); if (type != EV_LED) @@ -414,7 +414,7 @@ static void hidp_del_timer(struct hidp_session *session) static void hidp_process_handshake(struct hidp_session *session, unsigned char param) { - BT_DBG("session %p param 0x%02x", session, param); + BT_DBG("session %pK param 0x%02x", session, param); session->output_report_success = 0; /* default condition */ switch (param) { @@ -457,7 +457,7 @@ static void hidp_process_handshake(struct hidp_session *session, static void hidp_process_hid_control(struct hidp_session *session, unsigned char param) { - BT_DBG("session %p param 0x%02x", session, param); + BT_DBG("session %pK param 0x%02x", session, param); if (param == HIDP_CTRL_VIRTUAL_CABLE_UNPLUG) { /* Flush the transmit queues */ @@ -473,7 +473,8 @@ static int hidp_process_data(struct hidp_session *session, struct sk_buff *skb, unsigned char param) { int done_with_skb = 1; - BT_DBG("session %p skb %p len %d param 0x%02x", session, skb, skb->len, param); + BT_DBG("session %pK skb %pK len %d param 0x%02x", + session, skb, skb->len, param); switch (param) { case HIDP_DATA_RTYPE_INPUT: @@ -517,7 +518,7 @@ static void hidp_recv_ctrl_frame(struct hidp_session *session, unsigned char hdr, type, param; int free_skb = 1; - BT_DBG("session %p skb %p len %d", session, skb, skb->len); + BT_DBG("session %pK skb %pK len %d", session, skb, skb->len); hdr = skb->data[0]; skb_pull(skb, 1); @@ -553,7 +554,7 @@ static void hidp_recv_intr_frame(struct hidp_session *session, { unsigned char hdr; - BT_DBG("session %p skb %p len %d", session, skb, skb->len); + BT_DBG("session %pK skb %pK len %d", session, skb, skb->len); hdr = skb->data[0]; skb_pull(skb, 1); @@ -580,7 +581,7 @@ static int hidp_send_frame(struct socket *sock, unsigned char *data, int len) struct kvec iv = { data, len }; struct msghdr msg; - BT_DBG("sock %p data %p len %d", sock, data, len); + BT_DBG("sock %pK data %pK len %d", sock, data, len); if (!len) return 0; @@ -598,7 +599,7 @@ static void hidp_process_transmit(struct hidp_session *session, struct sk_buff *skb; int ret; - BT_DBG("session %p", session); + BT_DBG("session %pK", session); while ((skb = skb_dequeue(transmit))) { ret = hidp_send_frame(sock, skb->data, skb->len); @@ -1192,7 +1193,7 @@ static int hidp_session_thread(void *arg) struct hidp_session *session = arg; wait_queue_t ctrl_wait, intr_wait; - BT_DBG("session %p", session); + BT_DBG("session %pK", session); /* initialize runtime environment */ hidp_session_get(session); diff --git a/net/bluetooth/hidp/sock.c b/net/bluetooth/hidp/sock.c index cb3fdde1968a0..5b7abfad038b3 100644 --- a/net/bluetooth/hidp/sock.c +++ b/net/bluetooth/hidp/sock.c @@ -33,7 +33,7 @@ static int hidp_sock_release(struct socket *sock) { struct sock *sk = sock->sk; - BT_DBG("sock %p sk %p", sock, sk); + BT_DBG("sock %pK sk %pK", sock, sk); if (!sk) return 0; @@ -230,7 +230,7 @@ static int hidp_sock_create(struct net *net, struct socket *sock, int protocol, { struct sock *sk; - BT_DBG("sock %p", sock); + BT_DBG("sock %pK", sock); if (sock->type != SOCK_RAW) return -ESOCKTNOSUPPORT; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 79a680a122691..03c52804c3dcf 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -212,7 +212,7 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn) static void __l2cap_state_change(struct l2cap_chan *chan, int state) { - BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state), + BT_DBG("chan %pK %s -> %s", chan, state_to_string(chan->state), state_to_string(state)); chan->state = state; @@ -400,7 +400,7 @@ static void l2cap_chan_timeout(struct work_struct *work) struct l2cap_conn *conn = chan->conn; int reason; - BT_DBG("chan %p state %s", chan, state_to_string(chan->state)); + BT_DBG("chan %pK state %s", chan, state_to_string(chan->state)); mutex_lock(&conn->chan_lock); l2cap_chan_lock(chan); @@ -446,7 +446,7 @@ struct l2cap_chan *l2cap_chan_create(void) /* This flag is cleared in l2cap_chan_ready() */ set_bit(CONF_NOT_COMPLETE, &chan->conf_state); - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); return chan; } @@ -455,7 +455,7 @@ static void l2cap_chan_destroy(struct kref *kref) { struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref); - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); write_lock(&chan_list_lock); list_del(&chan->global_l); @@ -466,14 +466,14 @@ static void l2cap_chan_destroy(struct kref *kref) void l2cap_chan_hold(struct l2cap_chan *c) { - BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount)); + BT_DBG("chan %pK orig refcnt %d", c, atomic_read(&c->kref.refcount)); kref_get(&c->kref); } void l2cap_chan_put(struct l2cap_chan *c) { - BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount)); + BT_DBG("chan %pK orig refcnt %d", c, atomic_read(&c->kref.refcount)); kref_put(&c->kref, l2cap_chan_destroy); } @@ -492,7 +492,7 @@ void l2cap_chan_set_defaults(struct l2cap_chan *chan) void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) { - BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, + BT_DBG("conn %pK, psm 0x%2.2x, dcid 0x%4.4x", conn, __le16_to_cpu(chan->psm), chan->dcid); conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM; @@ -559,7 +559,7 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) __clear_chan_timer(chan); - BT_DBG("chan %p, conn %p, err %d", chan, conn, err); + BT_DBG("chan %pK, conn %pK, err %d", chan, conn, err); if (conn) { struct amp_mgr *mgr = conn->hcon->amp_mgr; @@ -580,7 +580,7 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) if (chan->hs_hchan) { struct hci_chan *hs_hchan = chan->hs_hchan; - BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan); + BT_DBG("chan %pK disconnect hs_hchan %pK", chan, hs_hchan); amp_disconnect_logical_link(hs_hchan); } @@ -618,7 +618,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason) struct l2cap_conn *conn = chan->conn; struct sock *sk = chan->sk; - BT_DBG("chan %p state %s sk %p", chan, state_to_string(chan->state), + BT_DBG("chan %pK state %s sk %pK", chan, state_to_string(chan->state), sk); switch (chan->state) { @@ -770,7 +770,7 @@ static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb) struct hci_conn *hcon = chan->conn->hcon; u16 flags; - BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len, + BT_DBG("chan %pK, skb %pK len %d priority %u", chan, skb, skb->len, skb->priority); if (chan->hs_hcon && !__chan_is_moving(chan)) { @@ -952,7 +952,7 @@ static void l2cap_send_sframe(struct l2cap_chan *chan, struct sk_buff *skb; u32 control_field; - BT_DBG("chan %p, control %p", chan, control); + BT_DBG("chan %pK, control %pK", chan, control); if (!control->sframe) return; @@ -991,7 +991,7 @@ static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll) { struct l2cap_ctrl control; - BT_DBG("chan %p, poll %d", chan, poll); + BT_DBG("chan %pK, poll %d", chan, poll); memset(&control, 0, sizeof(control)); control.sframe = 1; @@ -1062,7 +1062,7 @@ static void l2cap_move_setup(struct l2cap_chan *chan) { struct sk_buff *skb; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); if (chan->mode != L2CAP_MODE_ERTM) return; @@ -1096,7 +1096,7 @@ static void l2cap_move_setup(struct l2cap_chan *chan) static void l2cap_move_done(struct l2cap_chan *chan) { u8 move_role = chan->move_role; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); chan->move_state = L2CAP_MOVE_STABLE; chan->move_role = L2CAP_MOVE_ROLE_NONE; @@ -1129,7 +1129,7 @@ static void l2cap_chan_ready(struct l2cap_chan *chan) static void l2cap_start_connection(struct l2cap_chan *chan) { if (__amp_capable(chan)) { - BT_DBG("chan %p AMP capable: discover AMPs", chan); + BT_DBG("chan %pK AMP capable: discover AMPs", chan); a2mp_discover_amp(chan); } else { l2cap_send_conn_req(chan); @@ -1219,7 +1219,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn) { struct l2cap_chan *chan, *tmp; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); mutex_lock(&conn->chan_lock); @@ -1381,7 +1381,7 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) struct l2cap_chan *chan; struct hci_conn *hcon = conn->hcon; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); if (!hcon->out && hcon->type == LE_LINK) l2cap_le_conn_ready(conn); @@ -1426,7 +1426,7 @@ static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err) { struct l2cap_chan *chan; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); mutex_lock(&conn->chan_lock); @@ -1540,7 +1540,7 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) if (!conn) return; - BT_DBG("hcon %p conn %p, err %d", hcon, conn, err); + BT_DBG("hcon %pK conn %pK, err %d", hcon, conn, err); kfree_skb(conn->rx_skb); @@ -1583,7 +1583,7 @@ static void security_timeout(struct work_struct *work) struct l2cap_conn *conn = container_of(work, struct l2cap_conn, security_timer.work); - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) { smp_chan_destroy(conn); @@ -1615,7 +1615,7 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon) hci_conn_get(conn->hcon); conn->hchan = hchan; - BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan); + BT_DBG("hcon %pK conn %pK hchan %pK", hcon, conn, hchan); switch (hcon->type) { case LE_LINK: @@ -1891,7 +1891,7 @@ static void l2cap_monitor_timeout(struct work_struct *work) struct l2cap_chan *chan = container_of(work, struct l2cap_chan, monitor_timer.work); - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); l2cap_chan_lock(chan); @@ -1912,7 +1912,7 @@ static void l2cap_retrans_timeout(struct work_struct *work) struct l2cap_chan *chan = container_of(work, struct l2cap_chan, retrans_timer.work); - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); l2cap_chan_lock(chan); @@ -1933,7 +1933,7 @@ static void l2cap_streaming_send(struct l2cap_chan *chan, struct sk_buff *skb; struct l2cap_ctrl *control; - BT_DBG("chan %p, skbs %p", chan, skbs); + BT_DBG("chan %pK, skbs %pK", chan, skbs); if (__chan_is_moving(chan)) return; @@ -1972,7 +1972,7 @@ static int l2cap_ertm_send(struct l2cap_chan *chan) struct l2cap_ctrl *control; int sent = 0; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); if (chan->state != BT_CONNECTED) return -ENOTCONN; @@ -2043,7 +2043,7 @@ static void l2cap_ertm_resend(struct l2cap_chan *chan) struct sk_buff *tx_skb; u16 seq; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) return; @@ -2118,7 +2118,7 @@ static void l2cap_ertm_resend(struct l2cap_chan *chan) static void l2cap_retransmit(struct l2cap_chan *chan, struct l2cap_ctrl *control) { - BT_DBG("chan %p, control %p", chan, control); + BT_DBG("chan %pK, control %pK", chan, control); l2cap_seq_list_append(&chan->retrans_list, control->reqseq); l2cap_ertm_resend(chan); @@ -2129,7 +2129,7 @@ static void l2cap_retransmit_all(struct l2cap_chan *chan, { struct sk_buff *skb; - BT_DBG("chan %p, control %p", chan, control); + BT_DBG("chan %pK, control %pK", chan, control); if (control->poll) set_bit(CONN_SEND_FBIT, &chan->conn_state); @@ -2165,7 +2165,7 @@ static void l2cap_send_ack(struct l2cap_chan *chan) chan->last_acked_seq); int threshold; - BT_DBG("chan %p last_acked_seq %d buffer_seq %d", + BT_DBG("chan %pK last_acked_seq %d buffer_seq %d", chan, chan->last_acked_seq, chan->buffer_seq); memset(&control, 0, sizeof(control)); @@ -2262,7 +2262,7 @@ static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE; struct l2cap_hdr *lh; - BT_DBG("chan %p len %zu priority %u", chan, len, priority); + BT_DBG("chan %pK len %zu priority %u", chan, len, priority); count = min_t(unsigned int, (conn->mtu - hlen), len); @@ -2296,7 +2296,7 @@ static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, int err, count; struct l2cap_hdr *lh; - BT_DBG("chan %p len %zu", chan, len); + BT_DBG("chan %pK len %zu", chan, len); count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len); @@ -2329,7 +2329,7 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, int err, count, hlen; struct l2cap_hdr *lh; - BT_DBG("chan %p len %zu", chan, len); + BT_DBG("chan %pK len %zu", chan, len); if (!conn) return ERR_PTR(-ENOTCONN); @@ -2383,7 +2383,7 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan, size_t pdu_len; u8 sar; - BT_DBG("chan %p, msg %p, len %zu", chan, msg, len); + BT_DBG("chan %pK, msg %pK, len %zu", chan, msg, len); /* It is critical that ERTM PDUs fit in a single HCI fragment, * so fragmented skbs are not used. The HCI layer's handling @@ -2529,7 +2529,7 @@ static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq) struct l2cap_ctrl control; u16 seq; - BT_DBG("chan %p, txseq %u", chan, txseq); + BT_DBG("chan %pK, txseq %u", chan, txseq); memset(&control, 0, sizeof(control)); control.sframe = 1; @@ -2551,7 +2551,7 @@ static void l2cap_send_srej_tail(struct l2cap_chan *chan) { struct l2cap_ctrl control; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR) return; @@ -2569,7 +2569,7 @@ static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq) u16 initial_head; u16 seq; - BT_DBG("chan %p, txseq %u", chan, txseq); + BT_DBG("chan %pK, txseq %u", chan, txseq); memset(&control, 0, sizeof(control)); control.sframe = 1; @@ -2594,7 +2594,7 @@ static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq) struct sk_buff *acked_skb; u16 ackseq; - BT_DBG("chan %p, reqseq %u", chan, reqseq); + BT_DBG("chan %pK, reqseq %u", chan, reqseq); if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq) return; @@ -2623,7 +2623,7 @@ static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq) static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan) { - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); chan->expected_tx_seq = chan->buffer_seq; l2cap_seq_list_clear(&chan->srej_list); @@ -2635,7 +2635,7 @@ static void l2cap_tx_state_xmit(struct l2cap_chan *chan, struct l2cap_ctrl *control, struct sk_buff_head *skbs, u8 event) { - BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs, + BT_DBG("chan %pK, control %pK, skbs %pK, event %d", chan, control, skbs, event); switch (event) { @@ -2707,7 +2707,7 @@ static void l2cap_tx_state_wait_f(struct l2cap_chan *chan, struct l2cap_ctrl *control, struct sk_buff_head *skbs, u8 event) { - BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs, + BT_DBG("chan %pK, control %pK, skbs %pK, event %d", chan, control, skbs, event); switch (event) { @@ -2784,7 +2784,7 @@ static void l2cap_tx_state_wait_f(struct l2cap_chan *chan, static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control, struct sk_buff_head *skbs, u8 event) { - BT_DBG("chan %p, control %p, skbs %p, event %d, state %d", + BT_DBG("chan %pK, control %pK, skbs %pK, event %d, state %d", chan, control, skbs, event, chan->tx_state); switch (chan->tx_state) { @@ -2803,14 +2803,14 @@ static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control, static void l2cap_pass_to_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control) { - BT_DBG("chan %p, control %p", chan, control); + BT_DBG("chan %pK, control %pK", chan, control); l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT); } static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan, struct l2cap_ctrl *control) { - BT_DBG("chan %p, control %p", chan, control); + BT_DBG("chan %pK, control %pK", chan, control); l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT); } @@ -2820,7 +2820,7 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) struct sk_buff *nskb; struct l2cap_chan *chan; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); mutex_lock(&conn->chan_lock); @@ -2852,7 +2852,7 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code, struct l2cap_hdr *lh; int len, count; - BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u", + BT_DBG("conn %pK, code 0x%2.2x, ident 0x%2.2x, len %u", conn, code, ident, dlen); if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE) @@ -3011,7 +3011,7 @@ static void l2cap_ack_timeout(struct work_struct *work) ack_timer.work); u16 frames_to_ack; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); l2cap_chan_lock(chan); @@ -3153,7 +3153,7 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) void *ptr = req->data; u16 size; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); if (chan->num_conf_req || chan->num_conf_rsp) goto done; @@ -3279,7 +3279,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) u16 result = L2CAP_CONF_SUCCESS; u16 size; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); while (len >= L2CAP_CONF_OPT_SIZE) { len -= l2cap_get_conf_opt(&req, &type, &olen, &val); @@ -3488,7 +3488,7 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC }; struct l2cap_conf_efs efs; - BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data); + BT_DBG("chan %pK, rsp %pK, len %d, req %pK", chan, rsp, len, data); while (len >= L2CAP_CONF_OPT_SIZE) { len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val); @@ -3593,7 +3593,7 @@ static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data, struct l2cap_conf_rsp *rsp = data; void *ptr = rsp->data; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); rsp->scid = cpu_to_le16(chan->dcid); rsp->result = cpu_to_le16(result); @@ -3619,7 +3619,7 @@ void __l2cap_connect_rsp_defer(struct l2cap_chan *chan) else rsp_code = L2CAP_CONN_RSP; - BT_DBG("chan %p rsp_code %u", chan, rsp_code); + BT_DBG("chan %pK rsp_code %u", chan, rsp_code); l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp); @@ -3647,7 +3647,7 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len) .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW), }; - BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len); + BT_DBG("chan %pK, rsp %pK, len %d", chan, rsp, len); if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING)) return; @@ -3948,7 +3948,7 @@ static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data, { struct l2cap_conn *conn = chan->conn; - BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident, + BT_DBG("conn %pK chan %pK ident %d flags 0x%4.4x", conn, chan, ident, flags); clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state); @@ -4442,7 +4442,8 @@ static int l2cap_create_channel_req(struct l2cap_conn *conn, return -EFAULT; } - BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon); + BT_DBG("mgr %pK bredr_chan %pK hs_hcon %pK", + mgr, chan, hs_hcon); mgr->bredr_chan = chan; chan->hs_hcon = hs_hcon; @@ -4471,7 +4472,7 @@ static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id) struct l2cap_move_chan_req req; u8 ident; - BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id); + BT_DBG("chan %pK, dest_amp_id %d", chan, dest_amp_id); ident = l2cap_get_ident(chan->conn); chan->ident = ident; @@ -4489,7 +4490,7 @@ static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result) { struct l2cap_move_chan_rsp rsp; - BT_DBG("chan %p, result 0x%4.4x", chan, result); + BT_DBG("chan %pK, result 0x%4.4x", chan, result); rsp.icid = cpu_to_le16(chan->dcid); rsp.result = cpu_to_le16(result); @@ -4502,7 +4503,7 @@ static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result) { struct l2cap_move_chan_cfm cfm; - BT_DBG("chan %p, result 0x%4.4x", chan, result); + BT_DBG("chan %pK, result 0x%4.4x", chan, result); chan->ident = l2cap_get_ident(chan->conn); @@ -4519,7 +4520,7 @@ static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid) { struct l2cap_move_chan_cfm cfm; - BT_DBG("conn %p, icid 0x%4.4x", conn, icid); + BT_DBG("conn %pK, icid 0x%4.4x", conn, icid); cfm.icid = cpu_to_le16(icid); cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED); @@ -4639,7 +4640,7 @@ static void l2cap_logical_finish_move(struct l2cap_chan *chan, void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan, u8 status) { - BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status); + BT_DBG("chan %pK, hchan %pK, status %d", chan, hchan, status); if (status) { l2cap_logical_fail(chan); @@ -4658,7 +4659,7 @@ void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan, void l2cap_move_start(struct l2cap_chan *chan) { - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); if (chan->local_amp_id == HCI_BREDR_ID) { if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED) @@ -4678,7 +4679,7 @@ void l2cap_move_start(struct l2cap_chan *chan) static void l2cap_do_create(struct l2cap_chan *chan, int result, u8 local_amp_id, u8 remote_amp_id) { - BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state), + BT_DBG("chan %pK state %s %u -> %u", chan, state_to_string(chan->state), local_amp_id, remote_amp_id); chan->fcs = L2CAP_FCS_NONE; @@ -4787,7 +4788,7 @@ void __l2cap_physical_cfm(struct l2cap_chan *chan, int result) u8 local_amp_id = chan->local_amp_id; u8 remote_amp_id = chan->remote_amp_id; - BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d", + BT_DBG("chan %pK, result %d, local_amp_id %d, remote_amp_id %d", chan, result, local_amp_id, remote_amp_id); if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) { @@ -5369,7 +5370,7 @@ static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan) { struct l2cap_ctrl control; - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); memset(&control, 0, sizeof(control)); control.sframe = 1; @@ -5524,7 +5525,7 @@ static int l2cap_rx_queued_iframes(struct l2cap_chan *chan) * until a gap is encountered. */ - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { struct sk_buff *skb; @@ -5556,7 +5557,7 @@ static void l2cap_handle_srej(struct l2cap_chan *chan, { struct sk_buff *skb; - BT_DBG("chan %p, control %p", chan, control); + BT_DBG("chan %pK, control %pK", chan, control); if (control->reqseq == chan->next_tx_seq) { BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq); @@ -5614,7 +5615,7 @@ static void l2cap_handle_rej(struct l2cap_chan *chan, { struct sk_buff *skb; - BT_DBG("chan %p, control %p", chan, control); + BT_DBG("chan %pK, control %pK", chan, control); if (control->reqseq == chan->next_tx_seq) { BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq); @@ -5648,7 +5649,7 @@ static void l2cap_handle_rej(struct l2cap_chan *chan, static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq) { - BT_DBG("chan %p, txseq %d", chan, txseq); + BT_DBG("chan %pK, txseq %d", chan, txseq); BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq, chan->expected_tx_seq); @@ -5739,7 +5740,7 @@ static int l2cap_rx_state_recv(struct l2cap_chan *chan, int err = 0; bool skb_in_use = 0; - BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb, + BT_DBG("chan %pK, control %pK, skb %pK, event %d", chan, control, skb, event); switch (event) { @@ -5795,7 +5796,7 @@ static int l2cap_rx_state_recv(struct l2cap_chan *chan, */ skb_queue_tail(&chan->srej_q, skb); skb_in_use = 1; - BT_DBG("Queued %p (queue len %d)", skb, + BT_DBG("Queued %pK (queue len %d)", skb, skb_queue_len(&chan->srej_q)); clear_bit(CONN_SREJ_ACT, &chan->conn_state); @@ -5859,7 +5860,7 @@ static int l2cap_rx_state_recv(struct l2cap_chan *chan, } if (skb && !skb_in_use) { - BT_DBG("Freeing %p", skb); + BT_DBG("Freeing %pK", skb); kfree_skb(skb); } @@ -5874,7 +5875,7 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, u16 txseq = control->txseq; bool skb_in_use = 0; - BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb, + BT_DBG("chan %pK, control %pK, skb %pK, event %d", chan, control, skb, event); switch (event) { @@ -5885,7 +5886,7 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, l2cap_pass_to_tx(chan, control); skb_queue_tail(&chan->srej_q, skb); skb_in_use = 1; - BT_DBG("Queued %p (queue len %d)", skb, + BT_DBG("Queued %pK (queue len %d)", skb, skb_queue_len(&chan->srej_q)); chan->expected_tx_seq = __next_seq(chan, txseq); @@ -5896,7 +5897,7 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, l2cap_pass_to_tx(chan, control); skb_queue_tail(&chan->srej_q, skb); skb_in_use = 1; - BT_DBG("Queued %p (queue len %d)", skb, + BT_DBG("Queued %pK (queue len %d)", skb, skb_queue_len(&chan->srej_q)); err = l2cap_rx_queued_iframes(chan); @@ -5911,7 +5912,7 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, */ skb_queue_tail(&chan->srej_q, skb); skb_in_use = 1; - BT_DBG("Queued %p (queue len %d)", skb, + BT_DBG("Queued %pK (queue len %d)", skb, skb_queue_len(&chan->srej_q)); l2cap_pass_to_tx(chan, control); @@ -5925,7 +5926,7 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, */ skb_queue_tail(&chan->srej_q, skb); skb_in_use = 1; - BT_DBG("Queued %p (queue len %d)", skb, + BT_DBG("Queued %pK (queue len %d)", skb, skb_queue_len(&chan->srej_q)); l2cap_pass_to_tx(chan, control); @@ -6002,7 +6003,7 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, } if (skb && !skb_in_use) { - BT_DBG("Freeing %p", skb); + BT_DBG("Freeing %pK", skb); kfree_skb(skb); } @@ -6011,7 +6012,7 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, static int l2cap_finish_move(struct l2cap_chan *chan) { - BT_DBG("chan %p", chan); + BT_DBG("chan %pK", chan); chan->rx_state = L2CAP_RX_STATE_RECV; @@ -6029,7 +6030,7 @@ static int l2cap_rx_state_wait_p(struct l2cap_chan *chan, { int err; - BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb, + BT_DBG("chan %pK, control %pK, skb %pK, event %d", chan, control, skb, event); if (!control->poll) @@ -6113,7 +6114,7 @@ static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control, { int err = 0; - BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan, + BT_DBG("chan %pK, control %pK, skb %pK, event %d, state %d", chan, control, skb, event, chan->rx_state); if (__valid_reqseq(chan, control->reqseq)) { @@ -6150,7 +6151,7 @@ static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control, { int err = 0; - BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb, + BT_DBG("chan %pK, control %pK, skb %pK, state %d", chan, control, skb, chan->rx_state); if (l2cap_classify_txseq(chan, control->txseq) == @@ -6172,7 +6173,7 @@ static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control, chan->sdu_len = 0; if (skb) { - BT_DBG("Freeing %p", skb); + BT_DBG("Freeing %pK", skb); kfree_skb(skb); } } @@ -6294,7 +6295,7 @@ static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid, } } - BT_DBG("chan %p, len %d", chan, skb->len); + BT_DBG("chan %pK, len %d", chan, skb->len); if (chan->state != BT_CONNECTED) goto drop; @@ -6319,7 +6320,7 @@ static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid, goto done; default: - BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode); + BT_DBG("chan %pK: bad mode 0x%2.2x", chan, chan->mode); break; } @@ -6339,7 +6340,7 @@ static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, if (!chan) goto drop; - BT_DBG("chan %p, len %d", chan, skb->len); + BT_DBG("chan %pK, len %d", chan, skb->len); if (chan->state != BT_BOUND && chan->state != BT_CONNECTED) goto drop; @@ -6364,7 +6365,7 @@ static void l2cap_att_channel(struct l2cap_conn *conn, if (!chan) goto drop; - BT_DBG("chan %p, len %d", chan, skb->len); + BT_DBG("chan %pK, len %d", chan, skb->len); if (chan->state != BT_BOUND && chan->state != BT_CONNECTED) goto drop; @@ -6460,7 +6461,7 @@ void l2cap_connect_cfm(struct hci_conn *hcon, u8 status) { struct l2cap_conn *conn; - BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status); + BT_DBG("hcon %pK bdaddr %pMR status %d", hcon, &hcon->dst, status); if (!status) { conn = l2cap_conn_add(hcon); @@ -6475,7 +6476,7 @@ int l2cap_disconn_ind(struct hci_conn *hcon) { struct l2cap_conn *conn = hcon->l2cap_data; - BT_DBG("hcon %p", hcon); + BT_DBG("hcon %pK", hcon); if (!conn) return HCI_ERROR_REMOTE_USER_TERM; @@ -6484,7 +6485,7 @@ int l2cap_disconn_ind(struct hci_conn *hcon) void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason) { - BT_DBG("hcon %p reason %d", hcon, reason); + BT_DBG("hcon %pK reason %d", hcon, reason); l2cap_conn_del(hcon, bt_to_errno(reason)); } @@ -6513,7 +6514,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) if (!conn) return 0; - BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt); + BT_DBG("conn %pK status 0x%2.2x encrypt %u", conn, status, encrypt); if (hcon->type == LE_LINK) { if (!status && encrypt) @@ -6526,7 +6527,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) list_for_each_entry(chan, &conn->chan_l, list) { l2cap_chan_lock(chan); - BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid, + BT_DBG("chan %pK scid 0x%4.4x state %s", chan, chan->scid, state_to_string(chan->state)); if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) { @@ -6637,7 +6638,7 @@ int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) if (!conn) goto drop; - BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags); + BT_DBG("conn %pK len %d flags 0x%x", conn, skb->len, flags); switch (flags) { case ACL_START: diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 302d29b3744d4..c676811c25797 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -56,7 +56,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) struct sockaddr_l2 la; int len, err = 0; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (!addr || addr->sa_family != AF_BLUETOOTH) return -EINVAL; @@ -121,7 +121,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, struct sockaddr_l2 la; int len, err = 0; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (!addr || alen < sizeof(addr->sa_family) || addr->sa_family != AF_BLUETOOTH) @@ -155,7 +155,7 @@ static int l2cap_sock_listen(struct socket *sock, int backlog) struct l2cap_chan *chan = l2cap_pi(sk)->chan; int err = 0; - BT_DBG("sk %p backlog %d", sk, backlog); + BT_DBG("sk %pK backlog %d", sk, backlog); lock_sock(sk); @@ -205,7 +205,7 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); - BT_DBG("sk %p timeo %ld", sk, timeo); + BT_DBG("sk %pK timeo %ld", sk, timeo); /* Wait for an incoming connection. (wake-one). */ add_wait_queue_exclusive(sk_sleep(sk), &wait); @@ -243,7 +243,7 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, newsock->state = SS_CONNECTED; - BT_DBG("new socket %p", nsk); + BT_DBG("new socket %pK", nsk); done: release_sock(sk); @@ -257,7 +257,7 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, struct sock *sk = sock->sk; struct l2cap_chan *chan = l2cap_pi(sk)->chan; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); memset(la, 0, sizeof(struct sockaddr_l2)); addr->sa_family = AF_BLUETOOTH; @@ -286,7 +286,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, int len, err = 0; u32 opt; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (get_user(len, optlen)) return -EFAULT; @@ -373,7 +373,7 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, struct bt_power pwr; int len, err = 0; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (level == SOL_L2CAP) return l2cap_sock_getsockopt_old(sock, optname, optval, optlen); @@ -488,7 +488,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, int len, err = 0; u32 opt; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); lock_sock(sk); @@ -590,7 +590,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, int len, err = 0; u32 opt; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (level == SOL_L2CAP) return l2cap_sock_setsockopt_old(sock, optname, optval, optlen); @@ -765,7 +765,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct l2cap_chan *chan = l2cap_pi(sk)->chan; int err; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); err = sock_error(sk); if (err) @@ -847,7 +847,7 @@ static void l2cap_sock_kill(struct sock *sk) if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) return; - BT_DBG("sk %p state %s", sk, state_to_string(sk->sk_state)); + BT_DBG("sk %pK state %s", sk, state_to_string(sk->sk_state)); /* Kill poor orphan */ @@ -863,7 +863,7 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) struct l2cap_conn *conn; int err = 0; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); if (!sk) return 0; @@ -909,7 +909,7 @@ static int l2cap_sock_release(struct socket *sock) struct sock *sk = sock->sk; int err; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); if (!sk) return 0; @@ -927,7 +927,7 @@ static void l2cap_sock_cleanup_listen(struct sock *parent) { struct sock *sk; - BT_DBG("parent %p", parent); + BT_DBG("parent %pK", parent); /* Close not yet accepted channels */ while ((sk = bt_accept_dequeue(parent, NULL))) { @@ -1085,7 +1085,7 @@ static void l2cap_sock_ready_cb(struct l2cap_chan *chan) parent = bt_sk(sk)->parent; - BT_DBG("sk %p, parent %p", sk, parent); + BT_DBG("sk %pK, parent %pK", sk, parent); sk->sk_state = BT_CONNECTED; sk->sk_state_change(sk); @@ -1119,7 +1119,7 @@ static struct l2cap_ops l2cap_chan_ops = { static void l2cap_sock_destruct(struct sock *sk) { - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (l2cap_pi(sk)->chan) l2cap_chan_put(l2cap_pi(sk)->chan); @@ -1137,7 +1137,7 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent) struct l2cap_pinfo *pi = l2cap_pi(sk); struct l2cap_chan *chan = pi->chan; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (parent) { struct l2cap_chan *pchan = l2cap_pi(parent)->chan; @@ -1239,7 +1239,7 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol, { struct sock *sk; - BT_DBG("sock %p", sock); + BT_DBG("sock %pK", sock); sock->state = SS_UNCONNECTED; diff --git a/net/bluetooth/lib.c b/net/bluetooth/lib.c index b3fbc73516c41..79c8f55d695ea 100644 --- a/net/bluetooth/lib.c +++ b/net/bluetooth/lib.c @@ -145,7 +145,7 @@ int bt_info(const char *format, ...) vaf.fmt = format; vaf.va = &args; - r = pr_info("%pV", &vaf); + r = pr_info("%pKV", &vaf); va_end(args); @@ -164,7 +164,7 @@ int bt_err(const char *format, ...) vaf.fmt = format; vaf.va = &args; - r = pr_err("%pV", &vaf); + r = pr_err("%pKV", &vaf); va_end(args); diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 3e574540b2c2f..b21964051ef81 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -213,7 +213,7 @@ static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status) struct mgmt_ev_cmd_status *ev; int err; - BT_DBG("sock %p, index %u, cmd %u, status %u", sk, index, cmd, status); + BT_DBG("sock %pK, index %u, cmd %u, status %u", sk, index, cmd, status); skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_KERNEL); if (!skb) @@ -244,7 +244,7 @@ static int cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status, struct mgmt_ev_cmd_complete *ev; int err; - BT_DBG("sock %p", sk); + BT_DBG("sock %pK", sk); skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + rp_len, GFP_KERNEL); if (!skb) @@ -275,7 +275,7 @@ static int read_version(struct sock *sk, struct hci_dev *hdev, void *data, { struct mgmt_rp_read_version rp; - BT_DBG("sock %p", sk); + BT_DBG("sock %pK", sk); rp.version = MGMT_VERSION; rp.revision = __constant_cpu_to_le16(MGMT_REVISION); @@ -294,7 +294,7 @@ static int read_commands(struct sock *sk, struct hci_dev *hdev, void *data, size_t rp_size; int i, err; - BT_DBG("sock %p", sk); + BT_DBG("sock %pK", sk); rp_size = sizeof(*rp) + ((num_commands + num_events) * sizeof(u16)); @@ -327,7 +327,7 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, u16 count; int err; - BT_DBG("sock %p", sk); + BT_DBG("sock %pK", sk); read_lock(&hci_dev_list_lock); @@ -698,7 +698,7 @@ static int read_controller_info(struct sock *sk, struct hci_dev *hdev, { struct mgmt_rp_read_info rp; - BT_DBG("sock %p %s", sk, hdev->name); + BT_DBG("sock %pK %s", sk, hdev->name); hci_dev_lock(hdev); diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 0c77476d33d20..03a9c68e6c833 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -182,13 +182,13 @@ static inline int __check_fcs(u8 *data, int type, u8 fcs) /* ---- L2CAP callbacks ---- */ static void rfcomm_l2state_change(struct sock *sk) { - BT_DBG("%p state %d", sk, sk->sk_state); + BT_DBG("%pK state %d", sk, sk->sk_state); rfcomm_schedule(); } static void rfcomm_l2data_ready(struct sock *sk, int bytes) { - BT_DBG("%p bytes %d", sk, bytes); + BT_DBG("%pK bytes %d", sk, bytes); rfcomm_schedule(); } @@ -233,7 +233,7 @@ static void rfcomm_session_timeout(unsigned long arg) { struct rfcomm_session *s = (void *) arg; - BT_DBG("session %p state %ld", s, s->state); + BT_DBG("session %pK state %ld", s, s->state); set_bit(RFCOMM_TIMED_OUT, &s->flags); rfcomm_schedule(); @@ -241,14 +241,14 @@ static void rfcomm_session_timeout(unsigned long arg) static void rfcomm_session_set_timer(struct rfcomm_session *s, long timeout) { - BT_DBG("session %p state %ld timeout %ld", s, s->state, timeout); + BT_DBG("session %pK state %ld timeout %ld", s, s->state, timeout); mod_timer(&s->timer, jiffies + timeout); } static void rfcomm_session_clear_timer(struct rfcomm_session *s) { - BT_DBG("session %p state %ld", s, s->state); + BT_DBG("session %pK state %ld", s, s->state); del_timer_sync(&s->timer); } @@ -258,7 +258,7 @@ static void rfcomm_dlc_timeout(unsigned long arg) { struct rfcomm_dlc *d = (void *) arg; - BT_DBG("dlc %p state %ld", d, d->state); + BT_DBG("dlc %pK state %ld", d, d->state); set_bit(RFCOMM_TIMED_OUT, &d->flags); rfcomm_dlc_put(d); @@ -267,7 +267,7 @@ static void rfcomm_dlc_timeout(unsigned long arg) static void rfcomm_dlc_set_timer(struct rfcomm_dlc *d, long timeout) { - BT_DBG("dlc %p state %ld timeout %ld", d, d->state, timeout); + BT_DBG("dlc %pK state %ld timeout %ld", d, d->state, timeout); if (!mod_timer(&d->timer, jiffies + timeout)) rfcomm_dlc_hold(d); @@ -275,7 +275,7 @@ static void rfcomm_dlc_set_timer(struct rfcomm_dlc *d, long timeout) static void rfcomm_dlc_clear_timer(struct rfcomm_dlc *d) { - BT_DBG("dlc %p state %ld", d, d->state); + BT_DBG("dlc %pK state %ld", d, d->state); if (del_timer(&d->timer)) rfcomm_dlc_put(d); @@ -283,7 +283,7 @@ static void rfcomm_dlc_clear_timer(struct rfcomm_dlc *d) static void rfcomm_dlc_clear_state(struct rfcomm_dlc *d) { - BT_DBG("%p", d); + BT_DBG("%pK", d); d->state = BT_OPEN; d->flags = 0; @@ -311,14 +311,14 @@ struct rfcomm_dlc *rfcomm_dlc_alloc(gfp_t prio) rfcomm_dlc_clear_state(d); - BT_DBG("%p", d); + BT_DBG("%pK", d); return d; } void rfcomm_dlc_free(struct rfcomm_dlc *d) { - BT_DBG("%p", d); + BT_DBG("%pK", d); skb_queue_purge(&d->tx_queue); kfree(d); @@ -326,7 +326,7 @@ void rfcomm_dlc_free(struct rfcomm_dlc *d) static void rfcomm_dlc_link(struct rfcomm_session *s, struct rfcomm_dlc *d) { - BT_DBG("dlc %p session %p", d, s); + BT_DBG("dlc %pK session %pK", d, s); rfcomm_session_clear_timer(s); rfcomm_dlc_hold(d); @@ -338,7 +338,7 @@ static void rfcomm_dlc_unlink(struct rfcomm_dlc *d) { struct rfcomm_session *s = d->session; - BT_DBG("dlc %p refcnt %d session %p", d, atomic_read(&d->refcnt), s); + BT_DBG("dlc %pK refcnt %d session %pK", d, atomic_read(&d->refcnt), s); list_del(&d->list); d->session = NULL; @@ -365,7 +365,7 @@ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, int err = 0; u8 dlci; - BT_DBG("dlc %p state %ld %pMR -> %pMR channel %d", + BT_DBG("dlc %pK state %ld %pMR -> %pMR channel %d", d, d->state, src, dst, channel); if (channel < 1 || channel > 30) @@ -431,8 +431,8 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err) if (!s) return 0; - BT_DBG("dlc %p state %ld dlci %d err %d session %p", - d, d->state, d->dlci, err, s); + BT_DBG("dlc %pK state %ld dlci %d err %d session %pK", + d, d->state, d->dlci, err, s); switch (d->state) { case BT_CONNECT: @@ -484,7 +484,7 @@ int rfcomm_dlc_close(struct rfcomm_dlc *d, int err) struct rfcomm_dlc *d_list; struct rfcomm_session *s, *s_list; - BT_DBG("dlc %p state %ld dlci %d err %d", d, d->state, d->dlci, err); + BT_DBG("dlc %pK state %ld dlci %d err %d", d, d->state, d->dlci, err); rfcomm_lock(); @@ -519,7 +519,7 @@ int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb) if (d->state != BT_CONNECTED) return -ENOTCONN; - BT_DBG("dlc %p mtu %d len %d", d, d->mtu, len); + BT_DBG("dlc %pK mtu %d len %d", d, d->mtu, len); if (len > d->mtu) return -EINVAL; @@ -534,7 +534,7 @@ int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb) void __rfcomm_dlc_throttle(struct rfcomm_dlc *d) { - BT_DBG("dlc %p state %ld", d, d->state); + BT_DBG("dlc %pK state %ld", d, d->state); if (!d->cfc) { d->v24_sig |= RFCOMM_V24_FC; @@ -545,7 +545,7 @@ void __rfcomm_dlc_throttle(struct rfcomm_dlc *d) void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d) { - BT_DBG("dlc %p state %ld", d, d->state); + BT_DBG("dlc %pK state %ld", d, d->state); if (!d->cfc) { d->v24_sig &= ~RFCOMM_V24_FC; @@ -561,8 +561,8 @@ void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d) */ int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig) { - BT_DBG("dlc %p state %ld v24_sig 0x%x", - d, d->state, v24_sig); + BT_DBG("dlc %pK state %ld v24_sig 0x%x", + d, d->state, v24_sig); if (test_bit(RFCOMM_RX_THROTTLED, &d->flags)) v24_sig |= RFCOMM_V24_FC; @@ -579,8 +579,8 @@ int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig) int rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig) { - BT_DBG("dlc %p state %ld v24_sig 0x%x", - d, d->state, d->v24_sig); + BT_DBG("dlc %pK state %ld v24_sig 0x%x", + d, d->state, d->v24_sig); *v24_sig = d->v24_sig; return 0; @@ -594,7 +594,7 @@ static struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state) if (!s) return NULL; - BT_DBG("session %p sock %p", s, sock); + BT_DBG("session %pK sock %pK", s, sock); setup_timer(&s->timer, rfcomm_session_timeout, (unsigned long) s); @@ -622,7 +622,7 @@ static struct rfcomm_session *rfcomm_session_del(struct rfcomm_session *s) { int state = s->state; - BT_DBG("session %p state %ld", s, s->state); + BT_DBG("session %pK state %ld", s, s->state); list_del(&s->list); @@ -660,7 +660,7 @@ static struct rfcomm_session *rfcomm_session_close(struct rfcomm_session *s, s->state = BT_CLOSED; - BT_DBG("session %p state %ld err %d", s, s->state, err); + BT_DBG("session %pK state %ld err %d", s, s->state, err); /* Close all dlcs */ list_for_each_safe(p, n, &s->dlcs) { @@ -744,7 +744,7 @@ static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len) struct kvec iv = { data, len }; struct msghdr msg; - BT_DBG("session %p len %d", s, len); + BT_DBG("session %pK len %d", s, len); memset(&msg, 0, sizeof(msg)); @@ -753,7 +753,7 @@ static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len) static int rfcomm_send_cmd(struct rfcomm_session *s, struct rfcomm_cmd *cmd) { - BT_DBG("%p cmd %u", s, cmd->ctrl); + BT_DBG("%pK cmd %u", s, cmd->ctrl); return rfcomm_send_frame(s, (void *) cmd, sizeof(*cmd)); } @@ -762,7 +762,7 @@ static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci) { struct rfcomm_cmd cmd; - BT_DBG("%p dlci %d", s, dlci); + BT_DBG("%pK dlci %d", s, dlci); cmd.addr = __addr(s->initiator, dlci); cmd.ctrl = __ctrl(RFCOMM_SABM, 1); @@ -776,7 +776,7 @@ static int rfcomm_send_ua(struct rfcomm_session *s, u8 dlci) { struct rfcomm_cmd cmd; - BT_DBG("%p dlci %d", s, dlci); + BT_DBG("%pK dlci %d", s, dlci); cmd.addr = __addr(!s->initiator, dlci); cmd.ctrl = __ctrl(RFCOMM_UA, 1); @@ -790,7 +790,7 @@ static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci) { struct rfcomm_cmd cmd; - BT_DBG("%p dlci %d", s, dlci); + BT_DBG("%pK dlci %d", s, dlci); cmd.addr = __addr(s->initiator, dlci); cmd.ctrl = __ctrl(RFCOMM_DISC, 1); @@ -805,7 +805,7 @@ static int rfcomm_queue_disc(struct rfcomm_dlc *d) struct rfcomm_cmd *cmd; struct sk_buff *skb; - BT_DBG("dlc %p dlci %d", d, d->dlci); + BT_DBG("dlc %pK dlci %d", d, d->dlci); skb = alloc_skb(sizeof(*cmd), GFP_KERNEL); if (!skb) @@ -826,7 +826,7 @@ static int rfcomm_send_dm(struct rfcomm_session *s, u8 dlci) { struct rfcomm_cmd cmd; - BT_DBG("%p dlci %d", s, dlci); + BT_DBG("%pK dlci %d", s, dlci); cmd.addr = __addr(!s->initiator, dlci); cmd.ctrl = __ctrl(RFCOMM_DM, 1); @@ -842,7 +842,7 @@ static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type) struct rfcomm_mcc *mcc; u8 buf[16], *ptr = buf; - BT_DBG("%p cr %d type %d", s, cr, type); + BT_DBG("%pK cr %d type %d", s, cr, type); hdr = (void *) ptr; ptr += sizeof(*hdr); hdr->addr = __addr(s->initiator, 0); @@ -868,7 +868,7 @@ static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d struct rfcomm_pn *pn; u8 buf[16], *ptr = buf; - BT_DBG("%p cr %d dlci %d mtu %d", s, cr, d->dlci, d->mtu); + BT_DBG("%pK cr %d dlci %d mtu %d", s, cr, d->dlci, d->mtu); hdr = (void *) ptr; ptr += sizeof(*hdr); hdr->addr = __addr(s->initiator, 0); @@ -913,10 +913,9 @@ int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci, struct rfcomm_rpn *rpn; u8 buf[16], *ptr = buf; - BT_DBG("%p cr %d dlci %d bit_r 0x%x data_b 0x%x stop_b 0x%x parity 0x%x" - " flwc_s 0x%x xon_c 0x%x xoff_c 0x%x p_mask 0x%x", - s, cr, dlci, bit_rate, data_bits, stop_bits, parity, - flow_ctrl_settings, xon_char, xoff_char, param_mask); + BT_DBG("%pK cr %d dlci %d bit_r 0x%x data_b 0x%x stop_b 0x%x parity 0x%x flwc_s 0x%x xon_c 0x%x xoff_c 0x%x p_mask 0x%x", + s, cr, dlci, bit_rate, data_bits, stop_bits, parity, + flow_ctrl_settings, xon_char, xoff_char, param_mask); hdr = (void *) ptr; ptr += sizeof(*hdr); hdr->addr = __addr(s->initiator, 0); @@ -948,7 +947,7 @@ static int rfcomm_send_rls(struct rfcomm_session *s, int cr, u8 dlci, u8 status) struct rfcomm_rls *rls; u8 buf[16], *ptr = buf; - BT_DBG("%p cr %d status 0x%x", s, cr, status); + BT_DBG("%pK cr %d status 0x%x", s, cr, status); hdr = (void *) ptr; ptr += sizeof(*hdr); hdr->addr = __addr(s->initiator, 0); @@ -975,7 +974,7 @@ static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig struct rfcomm_msc *msc; u8 buf[16], *ptr = buf; - BT_DBG("%p cr %d v24 0x%x", s, cr, v24_sig); + BT_DBG("%pK cr %d v24 0x%x", s, cr, v24_sig); hdr = (void *) ptr; ptr += sizeof(*hdr); hdr->addr = __addr(s->initiator, 0); @@ -1001,7 +1000,7 @@ static int rfcomm_send_fcoff(struct rfcomm_session *s, int cr) struct rfcomm_mcc *mcc; u8 buf[16], *ptr = buf; - BT_DBG("%p cr %d", s, cr); + BT_DBG("%pK cr %d", s, cr); hdr = (void *) ptr; ptr += sizeof(*hdr); hdr->addr = __addr(s->initiator, 0); @@ -1023,7 +1022,7 @@ static int rfcomm_send_fcon(struct rfcomm_session *s, int cr) struct rfcomm_mcc *mcc; u8 buf[16], *ptr = buf; - BT_DBG("%p cr %d", s, cr); + BT_DBG("%pK cr %d", s, cr); hdr = (void *) ptr; ptr += sizeof(*hdr); hdr->addr = __addr(s->initiator, 0); @@ -1049,7 +1048,7 @@ static int rfcomm_send_test(struct rfcomm_session *s, int cr, u8 *pattern, int l if (len > 125) return -EINVAL; - BT_DBG("%p cr %d", s, cr); + BT_DBG("%pK cr %d", s, cr); hdr[0] = __addr(s->initiator, 0); hdr[1] = __ctrl(RFCOMM_UIH, 0); @@ -1076,7 +1075,7 @@ static int rfcomm_send_credits(struct rfcomm_session *s, u8 addr, u8 credits) struct rfcomm_hdr *hdr; u8 buf[16], *ptr = buf; - BT_DBG("%p addr %d credits %d", s, addr, credits); + BT_DBG("%pK addr %d credits %d", s, addr, credits); hdr = (void *) ptr; ptr += sizeof(*hdr); hdr->addr = addr; @@ -1113,7 +1112,7 @@ static void rfcomm_make_uih(struct sk_buff *skb, u8 addr) /* ---- RFCOMM frame reception ---- */ static struct rfcomm_session *rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci) { - BT_DBG("session %p state %ld dlci %d", s, s->state, dlci); + BT_DBG("session %pK state %ld dlci %d", s, s->state, dlci); if (dlci) { /* Data channel */ @@ -1167,7 +1166,7 @@ static struct rfcomm_session *rfcomm_recv_dm(struct rfcomm_session *s, u8 dlci) { int err = 0; - BT_DBG("session %p state %ld dlci %d", s, s->state, dlci); + BT_DBG("session %pK state %ld dlci %d", s, s->state, dlci); if (dlci) { /* Data DLC */ @@ -1197,7 +1196,7 @@ static struct rfcomm_session *rfcomm_recv_disc(struct rfcomm_session *s, { int err = 0; - BT_DBG("session %p state %ld dlci %d", s, s->state, dlci); + BT_DBG("session %pK state %ld dlci %d", s, s->state, dlci); if (dlci) { struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci); @@ -1232,7 +1231,7 @@ void rfcomm_dlc_accept(struct rfcomm_dlc *d) struct sock *sk = d->session->sock->sk; struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn; - BT_DBG("dlc %p", d); + BT_DBG("dlc %pK", d); rfcomm_send_ua(d->session, d->dlci); @@ -1273,7 +1272,7 @@ static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci) struct rfcomm_dlc *d; u8 channel; - BT_DBG("session %p state %ld dlci %d", s, s->state, dlci); + BT_DBG("session %pK state %ld dlci %d", s, s->state, dlci); if (!dlci) { rfcomm_send_ua(s, 0); @@ -1314,8 +1313,8 @@ static int rfcomm_apply_pn(struct rfcomm_dlc *d, int cr, struct rfcomm_pn *pn) { struct rfcomm_session *s = d->session; - BT_DBG("dlc %p state %ld dlci %d mtu %d fc 0x%x credits %d", - d, d->state, d->dlci, pn->mtu, pn->flow_ctrl, pn->credits); + BT_DBG("dlc %pK state %ld dlci %d mtu %d fc 0x%x credits %d", + d, d->state, d->dlci, pn->mtu, pn->flow_ctrl, pn->credits); if ((pn->flow_ctrl == 0xf0 && s->cfc != RFCOMM_CFC_DISABLED) || pn->flow_ctrl == 0xe0) { @@ -1345,7 +1344,7 @@ static int rfcomm_recv_pn(struct rfcomm_session *s, int cr, struct sk_buff *skb) struct rfcomm_dlc *d; u8 dlci = pn->dlci; - BT_DBG("session %p state %ld dlci %d", s, s->state, dlci); + BT_DBG("session %pK state %ld dlci %d", s, s->state, dlci); if (!dlci) return 0; @@ -1561,7 +1560,7 @@ static int rfcomm_recv_mcc(struct rfcomm_session *s, struct sk_buff *skb) type = __get_mcc_type(mcc->type); len = __get_mcc_len(mcc->len); - BT_DBG("%p type 0x%x cr %d", s, type, cr); + BT_DBG("%pK type 0x%x cr %d", s, type, cr); skb_pull(skb, 2); @@ -1616,7 +1615,7 @@ static int rfcomm_recv_data(struct rfcomm_session *s, u8 dlci, int pf, struct sk { struct rfcomm_dlc *d; - BT_DBG("session %p state %ld dlci %d pf %d", s, s->state, dlci, pf); + BT_DBG("session %pK state %ld dlci %d pf %d", s, s->state, dlci, pf); d = rfcomm_dlc_get(s, dlci); if (!d) { @@ -1718,7 +1717,7 @@ static void rfcomm_process_connect(struct rfcomm_session *s) struct rfcomm_dlc *d; struct list_head *p, *n; - BT_DBG("session %p state %ld", s, s->state); + BT_DBG("session %pK state %ld", s, s->state); list_for_each_safe(p, n, &s->dlcs) { d = list_entry(p, struct rfcomm_dlc, list); @@ -1742,8 +1741,8 @@ static int rfcomm_process_tx(struct rfcomm_dlc *d) struct sk_buff *skb; int err; - BT_DBG("dlc %p state %ld cfc %d rx_credits %d tx_credits %d", - d, d->state, d->cfc, d->rx_credits, d->tx_credits); + BT_DBG("dlc %pK state %ld cfc %d rx_credits %d tx_credits %d", + d, d->state, d->cfc, d->rx_credits, d->tx_credits); /* Send pending MSC */ if (test_and_clear_bit(RFCOMM_MSC_PENDING, &d->flags)) @@ -1790,7 +1789,7 @@ static void rfcomm_process_dlcs(struct rfcomm_session *s) struct rfcomm_dlc *d; struct list_head *p, *n; - BT_DBG("session %p state %ld", s, s->state); + BT_DBG("session %pK state %ld", s, s->state); list_for_each_safe(p, n, &s->dlcs) { d = list_entry(p, struct rfcomm_dlc, list); @@ -1851,7 +1850,8 @@ static struct rfcomm_session *rfcomm_process_rx(struct rfcomm_session *s) struct sock *sk = sock->sk; struct sk_buff *skb; - BT_DBG("session %p state %ld qlen %d", s, s->state, skb_queue_len(&sk->sk_receive_queue)); + BT_DBG("session %pK state %ld qlen %d", s, s->state, + skb_queue_len(&sk->sk_receive_queue)); /* Get data directly from socket receive queue without copying it. */ while ((skb = skb_dequeue(&sk->sk_receive_queue))) { @@ -1878,7 +1878,7 @@ static void rfcomm_accept_connection(struct rfcomm_session *s) if (list_empty(&bt_sk(sock->sk)->accept_q)) return; - BT_DBG("session %p", s); + BT_DBG("session %pK", s); err = kernel_accept(sock, &nsock, O_NONBLOCK); if (err < 0) @@ -1904,7 +1904,7 @@ static struct rfcomm_session *rfcomm_check_connection(struct rfcomm_session *s) { struct sock *sk = s->sock->sk; - BT_DBG("%p state %ld", s, s->state); + BT_DBG("%pK state %ld", s, s->state); switch (sk->sk_state) { case BT_CONNECTED: @@ -2059,7 +2059,7 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt) struct rfcomm_dlc *d; struct list_head *p, *n; - BT_DBG("conn %p status 0x%02x encrypt 0x%02x", conn, status, encrypt); + BT_DBG("conn %pK status 0x%02x encrypt 0x%02x", conn, status, encrypt); s = rfcomm_session_get(&conn->hdev->bdaddr, &conn->dst); if (!s) diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 2892d6a84b288..75f10eee71f01 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -68,7 +68,7 @@ static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err) if (!sk) return; - BT_DBG("dlc %p state %ld err %d", d, d->state, err); + BT_DBG("dlc %pK state %ld err %d", d, d->state, err); local_irq_save(flags); bh_lock_sock(sk); @@ -150,7 +150,7 @@ static void rfcomm_sock_destruct(struct sock *sk) { struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc; - BT_DBG("sk %p dlc %p", sk, d); + BT_DBG("sk %pK dlc %pK", sk, d); skb_queue_purge(&sk->sk_receive_queue); skb_queue_purge(&sk->sk_write_queue); @@ -170,7 +170,7 @@ static void rfcomm_sock_cleanup_listen(struct sock *parent) { struct sock *sk; - BT_DBG("parent %p", parent); + BT_DBG("parent %pK", parent); /* Close not yet accepted dlcs */ while ((sk = bt_accept_dequeue(parent, NULL))) { @@ -190,7 +190,8 @@ static void rfcomm_sock_kill(struct sock *sk) if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) return; - BT_DBG("sk %p state %d refcnt %d", sk, sk->sk_state, atomic_read(&sk->sk_refcnt)); + BT_DBG("sk %pK state %d refcnt %d", sk, sk->sk_state, + atomic_read(&sk->sk_refcnt)); /* Kill poor orphan */ bt_sock_unlink(&rfcomm_sk_list, sk); @@ -202,7 +203,7 @@ static void __rfcomm_sock_close(struct sock *sk) { struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc; - BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket); + BT_DBG("sk %pK state %d socket %pK", sk, sk->sk_state, sk->sk_socket); switch (sk->sk_state) { case BT_LISTEN: @@ -235,7 +236,7 @@ static void rfcomm_sock_init(struct sock *sk, struct sock *parent) { struct rfcomm_pinfo *pi = rfcomm_pi(sk); - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (parent) { sk->sk_type = parent->sk_type; @@ -300,7 +301,7 @@ static struct sock *rfcomm_sock_alloc(struct net *net, struct socket *sock, int bt_sock_link(&rfcomm_sk_list, sk); - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); return sk; } @@ -309,7 +310,7 @@ static int rfcomm_sock_create(struct net *net, struct socket *sock, { struct sock *sk; - BT_DBG("sock %p", sock); + BT_DBG("sock %pK", sock); sock->state = SS_UNCONNECTED; @@ -328,19 +329,15 @@ static int rfcomm_sock_create(struct net *net, struct socket *sock, static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len) { - struct sockaddr_rc sa; + struct sockaddr_rc *sa = (struct sockaddr_rc *) addr; struct sock *sk = sock->sk; - int len, err = 0; + int err = 0; + + BT_DBG("sk %pK %pMR", sk, &sa->rc_bdaddr); if (!addr || addr->sa_family != AF_BLUETOOTH) return -EINVAL; - memset(&sa, 0, sizeof(sa)); - len = min_t(unsigned int, sizeof(sa), addr_len); - memcpy(&sa, addr, len); - - BT_DBG("sk %p %pMR", sk, &sa.rc_bdaddr); - lock_sock(sk); if (sk->sk_state != BT_OPEN) { @@ -355,12 +352,12 @@ static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr write_lock(&rfcomm_sk_list.lock); - if (sa.rc_channel && __rfcomm_get_sock_by_addr(sa.rc_channel, &sa.rc_bdaddr)) { + if (sa->rc_channel && __rfcomm_get_sock_by_addr(sa->rc_channel, &sa->rc_bdaddr)) { err = -EADDRINUSE; } else { /* Save source address */ - bacpy(&bt_sk(sk)->src, &sa.rc_bdaddr); - rfcomm_pi(sk)->channel = sa.rc_channel; + bacpy(&bt_sk(sk)->src, &sa->rc_bdaddr); + rfcomm_pi(sk)->channel = sa->rc_channel; sk->sk_state = BT_BOUND; } @@ -378,7 +375,7 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc; int err = 0; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (alen < sizeof(struct sockaddr_rc) || addr->sa_family != AF_BLUETOOTH) @@ -418,7 +415,7 @@ static int rfcomm_sock_listen(struct socket *sock, int backlog) struct sock *sk = sock->sk; int err = 0; - BT_DBG("sk %p backlog %d", sk, backlog); + BT_DBG("sk %pK backlog %d", sk, backlog); lock_sock(sk); @@ -478,7 +475,7 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); - BT_DBG("sk %p timeo %ld", sk, timeo); + BT_DBG("sk %pK timeo %ld", sk, timeo); /* Wait for an incoming connection. (wake-one). */ add_wait_queue_exclusive(sk_sleep(sk), &wait); @@ -516,7 +513,7 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f newsock->state = SS_CONNECTED; - BT_DBG("new socket %p", nsk); + BT_DBG("new socket %pK", nsk); done: release_sock(sk); @@ -528,7 +525,7 @@ static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, int * struct sockaddr_rc *sa = (struct sockaddr_rc *) addr; struct sock *sk = sock->sk; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); memset(sa, 0, sizeof(*sa)); sa->rc_family = AF_BLUETOOTH; @@ -559,7 +556,7 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock, if (sk->sk_shutdown & SEND_SHUTDOWN) return -EPIPE; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); lock_sock(sk); @@ -634,7 +631,7 @@ static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __u int err = 0; u32 opt; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); lock_sock(sk); @@ -672,7 +669,7 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, c size_t len; u32 opt; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (level == SOL_RFCOMM) return rfcomm_sock_setsockopt_old(sock, optname, optval, optlen); @@ -740,7 +737,7 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u int len, err = 0; u32 opt; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (get_user(len, optlen)) return -EFAULT; @@ -804,7 +801,7 @@ static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, c struct bt_security sec; int len, err = 0; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (level == SOL_RFCOMM) return rfcomm_sock_getsockopt_old(sock, optname, optval, optlen); @@ -859,7 +856,7 @@ static int rfcomm_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned lon struct sock *sk __maybe_unused = sock->sk; int err; - BT_DBG("sk %p cmd %x arg %lx", sk, cmd, arg); + BT_DBG("sk %pK cmd %x arg %lx", sk, cmd, arg); err = bt_sock_ioctl(sock, cmd, arg); @@ -881,7 +878,7 @@ static int rfcomm_sock_shutdown(struct socket *sock, int how) struct sock *sk = sock->sk; int err = 0; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); if (!sk) return 0; @@ -903,7 +900,7 @@ static int rfcomm_sock_release(struct socket *sock) struct sock *sk = sock->sk; int err; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); if (!sk) return 0; @@ -925,7 +922,7 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc * bdaddr_t src, dst; int result = 0; - BT_DBG("session %p channel %d", s, channel); + BT_DBG("session %pK channel %d", s, channel); rfcomm_session_getaddr(s, &src, &dst); diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index b6e44ad6cca6e..d2ce585a3c152 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -88,7 +88,7 @@ static void rfcomm_dev_destruct(struct tty_port *port) struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port); struct rfcomm_dlc *dlc = dev->dlc; - BT_DBG("dev %p dlc %p", dev, dlc); + BT_DBG("dev %pK dlc %pK", dev, dlc); /* Refcount should only hit zero when called from rfcomm_dev_del() which will have taken us off the list. Everything else are @@ -304,7 +304,7 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) static void rfcomm_dev_del(struct rfcomm_dev *dev) { unsigned long flags; - BT_DBG("dev %p", dev); + BT_DBG("dev %pK", dev); BUG_ON(test_and_set_bit(RFCOMM_TTY_RELEASED, &dev->flags)); @@ -373,7 +373,7 @@ static int rfcomm_create_dev(struct sock *sk, void __user *arg) if (copy_from_user(&req, arg, sizeof(req))) return -EFAULT; - BT_DBG("sk %p dev_id %d flags 0x%x", sk, req.dev_id, req.flags); + BT_DBG("sk %pK dev_id %d flags 0x%x", sk, req.dev_id, req.flags); if (req.flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN)) return -EPERM; @@ -518,7 +518,7 @@ static int rfcomm_get_dev_info(void __user *arg) int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, void __user *arg) { - BT_DBG("cmd %d arg %p", cmd, arg); + BT_DBG("cmd %d arg %pK", cmd, arg); switch (cmd) { case RFCOMMCREATEDEV: @@ -552,7 +552,7 @@ static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb) return; } - BT_DBG("dlc %p len %d", dlc, skb->len); + BT_DBG("dlc %pK len %d", dlc, skb->len); tty_insert_flip_string(&dev->port, skb->data, skb->len); tty_flip_buffer_push(&dev->port); @@ -566,7 +566,7 @@ static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err) if (!dev) return; - BT_DBG("dlc %p dev %p err %d", dlc, dev, err); + BT_DBG("dlc %pK dev %pK err %d", dlc, dev, err); dev->err = err; wake_up_interruptible(&dev->wait); @@ -602,7 +602,7 @@ static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig) if (!dev) return; - BT_DBG("dlc %p dev %p v24_sig 0x%02x", dlc, dev, v24_sig); + BT_DBG("dlc %pK dev %pK v24_sig 0x%02x", dlc, dev, v24_sig); if ((dev->modem_status & TIOCM_CD) && !(v24_sig & RFCOMM_V24_DV)) { if (dev->port.tty && !C_CLOCAL(dev->port.tty)) @@ -622,7 +622,7 @@ static void rfcomm_tty_copy_pending(struct rfcomm_dev *dev) struct sk_buff *skb; int inserted = 0; - BT_DBG("dev %p", dev); + BT_DBG("dev %pK", dev); rfcomm_dlc_lock(dev->dlc); @@ -648,7 +648,7 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp) id = tty->index; - BT_DBG("tty %p id %d", tty, id); + BT_DBG("tty %pK id %d", tty, id); /* We don't leak this refcount. For reasons which are not entirely clear, the TTY layer will call our ->close() method even if the @@ -658,7 +658,7 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp) if (!dev) return -ENODEV; - BT_DBG("dev %p dst %pMR channel %d opened %d", dev, &dev->dst, + BT_DBG("dev %pK dst %pMR channel %d opened %d", dev, &dev->dst, dev->channel, dev->port.count); spin_lock_irqsave(&dev->port.lock, flags); @@ -726,8 +726,8 @@ static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp) if (!dev) return; - BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc, - dev->port.count); + BT_DBG("tty %pK dev %pK dlc %pK opened %d", tty, dev, dev->dlc, + dev->port.count); spin_lock_irqsave(&dev->port.lock, flags); if (!--dev->port.count) { @@ -765,7 +765,7 @@ static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, in struct sk_buff *skb; int err = 0, sent = 0, size; - BT_DBG("tty %p count %d", tty, count); + BT_DBG("tty %pK count %d", tty, count); while (count) { size = min_t(uint, count, dlc->mtu); @@ -797,7 +797,7 @@ static int rfcomm_tty_write_room(struct tty_struct *tty) struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; int room; - BT_DBG("tty %p", tty); + BT_DBG("tty %pK", tty); if (!dev || !dev->dlc) return 0; @@ -811,7 +811,7 @@ static int rfcomm_tty_write_room(struct tty_struct *tty) static int rfcomm_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { - BT_DBG("tty %p cmd 0x%02x", tty, cmd); + BT_DBG("tty %pK cmd 0x%02x", tty, cmd); switch (cmd) { case TCGETS: @@ -865,7 +865,7 @@ static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old) struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; - BT_DBG("tty %p termios %p", tty, old); + BT_DBG("tty %pK termios %pK", tty, old); if (!dev || !dev->dlc || !dev->dlc->session) return; @@ -997,7 +997,7 @@ static void rfcomm_tty_throttle(struct tty_struct *tty) { struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; - BT_DBG("tty %p dev %p", tty, dev); + BT_DBG("tty %pK dev %pK", tty, dev); rfcomm_dlc_throttle(dev->dlc); } @@ -1006,7 +1006,7 @@ static void rfcomm_tty_unthrottle(struct tty_struct *tty) { struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; - BT_DBG("tty %p dev %p", tty, dev); + BT_DBG("tty %pK dev %pK", tty, dev); rfcomm_dlc_unthrottle(dev->dlc); } @@ -1015,7 +1015,7 @@ static int rfcomm_tty_chars_in_buffer(struct tty_struct *tty) { struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; - BT_DBG("tty %p dev %p", tty, dev); + BT_DBG("tty %pK dev %pK", tty, dev); if (!dev || !dev->dlc) return 0; @@ -1030,7 +1030,7 @@ static void rfcomm_tty_flush_buffer(struct tty_struct *tty) { struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; - BT_DBG("tty %p dev %p", tty, dev); + BT_DBG("tty %pK dev %pK", tty, dev); if (!dev || !dev->dlc) return; @@ -1041,19 +1041,19 @@ static void rfcomm_tty_flush_buffer(struct tty_struct *tty) static void rfcomm_tty_send_xchar(struct tty_struct *tty, char ch) { - BT_DBG("tty %p ch %c", tty, ch); + BT_DBG("tty %pK ch %c", tty, ch); } static void rfcomm_tty_wait_until_sent(struct tty_struct *tty, int timeout) { - BT_DBG("tty %p timeout %d", tty, timeout); + BT_DBG("tty %pK timeout %d", tty, timeout); } static void rfcomm_tty_hangup(struct tty_struct *tty) { struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; - BT_DBG("tty %p dev %p", tty, dev); + BT_DBG("tty %pK dev %pK", tty, dev); if (!dev) return; @@ -1072,7 +1072,7 @@ static int rfcomm_tty_tiocmget(struct tty_struct *tty) { struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; - BT_DBG("tty %p dev %p", tty, dev); + BT_DBG("tty %pK dev %pK", tty, dev); return dev->modem_status; } @@ -1083,7 +1083,7 @@ static int rfcomm_tty_tiocmset(struct tty_struct *tty, unsigned int set, unsigne struct rfcomm_dlc *dlc = dev->dlc; u8 v24_sig; - BT_DBG("tty %p dev %p set 0x%02x clear 0x%02x", tty, dev, set, clear); + BT_DBG("tty %pK dev %pK set 0x%02x clear 0x%02x", tty, dev, set, clear); rfcomm_dlc_get_modem_status(dlc, &v24_sig); diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 63716b707b798..f457dc2f4fcc8 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -51,7 +51,7 @@ static void sco_sock_timeout(unsigned long arg) { struct sock *sk = (struct sock *) arg; - BT_DBG("sock %p state %d", sk, sk->sk_state); + BT_DBG("sock %pK state %d", sk, sk->sk_state); bh_lock_sock(sk); sk->sk_err = ETIMEDOUT; @@ -64,13 +64,13 @@ static void sco_sock_timeout(unsigned long arg) static void sco_sock_set_timer(struct sock *sk, long timeout) { - BT_DBG("sock %p state %d timeout %ld", sk, sk->sk_state, timeout); + BT_DBG("sock %pK state %d timeout %ld", sk, sk->sk_state, timeout); sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout); } static void sco_sock_clear_timer(struct sock *sk) { - BT_DBG("sock %p state %d", sk, sk->sk_state); + BT_DBG("sock %pK state %d", sk, sk->sk_state); sk_stop_timer(sk, &sk->sk_timer); } @@ -100,7 +100,7 @@ static struct sco_conn *sco_conn_add(struct hci_conn *hcon) else conn->mtu = 60; - BT_DBG("hcon %p conn %p", hcon, conn); + BT_DBG("hcon %pK conn %pK", hcon, conn); return conn; } @@ -122,7 +122,7 @@ static int sco_conn_del(struct hci_conn *hcon, int err) if (!conn) return 0; - BT_DBG("hcon %p conn %p, err %d", hcon, conn, err); + BT_DBG("hcon %pK conn %pK, err %d", hcon, conn, err); /* Kill socket */ sk = sco_chan_get(conn); @@ -224,7 +224,7 @@ static int sco_send_frame(struct sock *sk, struct msghdr *msg, int len) if (len > conn->mtu) return -EINVAL; - BT_DBG("sk %p len %d", sk, len); + BT_DBG("sk %pK len %d", sk, len); skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err); if (!skb) @@ -247,7 +247,7 @@ static void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb) if (!sk) goto drop; - BT_DBG("sk %p len %d", sk, skb->len); + BT_DBG("sk %pK len %d", sk, skb->len); if (sk->sk_state != BT_CONNECTED) goto drop; @@ -304,7 +304,7 @@ static struct sock *sco_get_sock_listen(bdaddr_t *src) static void sco_sock_destruct(struct sock *sk) { - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); skb_queue_purge(&sk->sk_receive_queue); skb_queue_purge(&sk->sk_write_queue); @@ -314,7 +314,7 @@ static void sco_sock_cleanup_listen(struct sock *parent) { struct sock *sk; - BT_DBG("parent %p", parent); + BT_DBG("parent %pK", parent); /* Close not yet accepted channels */ while ((sk = bt_accept_dequeue(parent, NULL))) { @@ -334,7 +334,7 @@ static void sco_sock_kill(struct sock *sk) if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) return; - BT_DBG("sk %p state %d", sk, sk->sk_state); + BT_DBG("sk %pK state %d", sk, sk->sk_state); /* Kill poor orphan */ bt_sock_unlink(&sco_sk_list, sk); @@ -344,7 +344,7 @@ static void sco_sock_kill(struct sock *sk) static void __sco_sock_close(struct sock *sk) { - BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket); + BT_DBG("sk %pK state %d socket %pK", sk, sk->sk_state, sk->sk_socket); switch (sk->sk_state) { case BT_LISTEN: @@ -388,7 +388,7 @@ static void sco_sock_close(struct sock *sk) static void sco_sock_init(struct sock *sk, struct sock *parent) { - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (parent) { sk->sk_type = parent->sk_type; @@ -433,7 +433,7 @@ static int sco_sock_create(struct net *net, struct socket *sock, int protocol, { struct sock *sk; - BT_DBG("sock %p", sock); + BT_DBG("sock %pK", sock); sock->state = SS_UNCONNECTED; @@ -456,7 +456,7 @@ static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) struct sock *sk = sock->sk; int len, err = 0; - BT_DBG("sk %p %pMR", sk, &sa.sco_bdaddr); + BT_DBG("sk %pK %pMR", sk, &sa.sco_bdaddr); if (!addr || addr->sa_family != AF_BLUETOOTH) return -EINVAL; @@ -496,7 +496,7 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen struct sockaddr_sco sa; int len, err; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (!addr || addr->sa_family != AF_BLUETOOTH) return -EINVAL; @@ -539,7 +539,7 @@ static int sco_sock_listen(struct socket *sock, int backlog) bdaddr_t *src = &bt_sk(sk)->src; int err = 0; - BT_DBG("sk %p backlog %d", sk, backlog); + BT_DBG("sk %pK backlog %d", sk, backlog); lock_sock(sk); @@ -584,7 +584,7 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); - BT_DBG("sk %p timeo %ld", sk, timeo); + BT_DBG("sk %pK timeo %ld", sk, timeo); /* Wait for an incoming connection. (wake-one). */ add_wait_queue_exclusive(sk_sleep(sk), &wait); @@ -622,7 +622,7 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag newsock->state = SS_CONNECTED; - BT_DBG("new socket %p", ch); + BT_DBG("new socket %pK", ch); done: release_sock(sk); @@ -634,7 +634,7 @@ static int sco_sock_getname(struct socket *sock, struct sockaddr *addr, int *len struct sockaddr_sco *sa = (struct sockaddr_sco *) addr; struct sock *sk = sock->sk; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); addr->sa_family = AF_BLUETOOTH; *len = sizeof(struct sockaddr_sco); @@ -654,7 +654,7 @@ static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct sock *sk = sock->sk; int err; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); err = sock_error(sk); if (err) @@ -678,7 +678,7 @@ static void sco_conn_defer_accept(struct hci_conn *conn, int mask) { struct hci_dev *hdev = conn->hdev; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); conn->state = BT_CONFIG; @@ -738,7 +738,7 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char int err = 0; u32 opt; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); lock_sock(sk); @@ -777,7 +777,7 @@ static int sco_sock_getsockopt_old(struct socket *sock, int optname, char __user struct sco_conninfo cinfo; int len, err = 0; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (get_user(len, optlen)) return -EFAULT; @@ -831,7 +831,7 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char struct sock *sk = sock->sk; int len, err = 0; - BT_DBG("sk %p", sk); + BT_DBG("sk %pK", sk); if (level == SOL_SCO) return sco_sock_getsockopt_old(sock, optname, optval, optlen); @@ -869,7 +869,7 @@ static int sco_sock_shutdown(struct socket *sock, int how) struct sock *sk = sock->sk; int err = 0; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); if (!sk) return 0; @@ -893,7 +893,7 @@ static int sco_sock_release(struct socket *sock) struct sock *sk = sock->sk; int err = 0; - BT_DBG("sock %p, sk %p", sock, sk); + BT_DBG("sock %pK, sk %pK", sock, sk); if (!sk) return 0; @@ -913,7 +913,7 @@ static int sco_sock_release(struct socket *sock) static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent) { - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); sco_pi(sk)->conn = conn; conn->sk = sk; @@ -930,7 +930,7 @@ static void sco_chan_del(struct sock *sk, int err) conn = sco_pi(sk)->conn; - BT_DBG("sk %p, conn %p, err %d", sk, conn, err); + BT_DBG("sk %pK, conn %pK, err %d", sk, conn, err); if (conn) { sco_conn_lock(conn); @@ -954,7 +954,7 @@ static void sco_conn_ready(struct sco_conn *conn) struct sock *parent; struct sock *sk = conn->sk; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); if (sk) { sco_sock_clear_timer(sk); @@ -1033,7 +1033,7 @@ int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags) void sco_connect_cfm(struct hci_conn *hcon, __u8 status) { - BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status); + BT_DBG("hcon %pK bdaddr %pMR status %d", hcon, &hcon->dst, status); if (!status) { struct sco_conn *conn; @@ -1046,7 +1046,7 @@ void sco_connect_cfm(struct hci_conn *hcon, __u8 status) void sco_disconn_cfm(struct hci_conn *hcon, __u8 reason) { - BT_DBG("hcon %p reason %d", hcon, reason); + BT_DBG("hcon %pK reason %d", hcon, reason); sco_conn_del(hcon, bt_to_errno(reason)); } @@ -1058,7 +1058,7 @@ int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb) if (!conn) goto drop; - BT_DBG("conn %p len %d", conn, skb->len); + BT_DBG("conn %pK len %d", conn, skb->len); if (skb->len) { sco_recv_frame(conn, skb); diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 3c66c2922c21f..d937dd0821803 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -56,7 +56,7 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r) unsigned char iv[128]; if (tfm == NULL) { - BT_ERR("tfm %p", tfm); + BT_ERR("tfm %pK", tfm); return -EINVAL; } @@ -375,7 +375,7 @@ static void confirm_work(struct work_struct *work) int ret; u8 res[16], reason; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); tfm = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(tfm)) { @@ -422,7 +422,7 @@ static void random_work(struct work_struct *work) goto error; } - BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); + BT_DBG("conn %pK %s", conn, conn->hcon->out ? "master" : "slave"); if (hcon->out) ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp, 0, @@ -574,7 +574,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) u8 auth = SMP_AUTH_NONE; int ret; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); if (conn->hcon->link_mode & HCI_LM_MASTER) return SMP_CMD_NOTSUPP; @@ -628,7 +628,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) u8 key_size, auth = SMP_AUTH_NONE; int ret; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); if (!(conn->hcon->link_mode & HCI_LM_MASTER)) return SMP_CMD_NOTSUPP; @@ -674,7 +674,7 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) struct smp_chan *smp = conn->smp_chan; struct hci_dev *hdev = conn->hcon->hdev; - BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); + BT_DBG("conn %pK %s", conn, conn->hcon->out ? "master" : "slave"); memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf)); skb_pull(skb, sizeof(smp->pcnf)); @@ -699,7 +699,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) struct smp_chan *smp = conn->smp_chan; struct hci_dev *hdev = conn->hcon->hdev; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); swap128(skb->data, smp->rrnd); skb_pull(skb, sizeof(smp->rrnd)); @@ -737,7 +737,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) struct hci_conn *hcon = conn->hcon; struct smp_chan *smp; - BT_DBG("conn %p", conn); + BT_DBG("conn %pK", conn); hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req); @@ -770,7 +770,7 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) struct smp_chan *smp = conn->smp_chan; __u8 authreq; - BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level); + BT_DBG("conn %pK hcon %pK level 0x%2.2x", conn, hcon, sec_level); if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) return 1; @@ -938,7 +938,7 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force) struct smp_chan *smp = conn->smp_chan; __u8 *keydist; - BT_DBG("conn %p force %d", conn, force); + BT_DBG("conn %pK force %d", conn, force); if (!test_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) return 0; diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index ae43dd807bb2b..8d2327d2cd885 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -907,6 +907,14 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, .dma = dev->dma, .port = dev->if_port, }; + memset(&map, 0, sizeof(map)); + map.mem_start = dev->mem_start; + map.mem_end = dev->mem_end; + map.base_addr = dev->base_addr; + map.irq = dev->irq; + map.dma = dev->dma; + map.port = dev->if_port; + if (nla_put(skb, IFLA_MAP, sizeof(map), &map)) goto nla_put_failure; } diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c index c38e7a2b5a8ee..3f78978b21730 100644 --- a/net/core/sock_diag.c +++ b/net/core/sock_diag.c @@ -135,7 +135,7 @@ void sock_diag_unregister(const struct sock_diag_handler *hnld) } EXPORT_SYMBOL_GPL(sock_diag_unregister); -static int __sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) +static int __sock_diag_cmd(struct sk_buff *skb, struct nlmsghdr *nlh) { int err; struct sock_diag_req *req = nlmsg_data(nlh); @@ -155,8 +155,12 @@ static int __sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) hndl = sock_diag_handlers[req->sdiag_family]; if (hndl == NULL) err = -ENOENT; - else + else if (nlh->nlmsg_type == SOCK_DIAG_BY_FAMILY) err = hndl->dump(skb, nlh); + else if (nlh->nlmsg_type == SOCK_DESTROY_BACKPORT && hndl->destroy) + err = hndl->destroy(skb, nlh); + else + err = -EOPNOTSUPP; mutex_unlock(&sock_diag_table_mutex); return err; @@ -182,7 +186,8 @@ static int sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) return ret; case SOCK_DIAG_BY_FAMILY: - return __sock_diag_rcv_msg(skb, nlh); + case SOCK_DESTROY_BACKPORT: + return __sock_diag_cmd(skb, nlh); default: return -EINVAL; } @@ -197,6 +202,18 @@ static void sock_diag_rcv(struct sk_buff *skb) mutex_unlock(&sock_diag_mutex); } +int sock_diag_destroy(struct sock *sk, int err) +{ + if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) + return -EPERM; + + if (!sk->sk_prot->diag_destroy) + return -EOPNOTSUPP; + + return sk->sk_prot->diag_destroy(sk, err); +} +EXPORT_SYMBOL_GPL(sock_diag_destroy); + static int __net_init diag_net_init(struct net *net) { struct netlink_kernel_cfg cfg = { diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 6cf9f7782ad42..86eedbaf037ff 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c @@ -235,7 +235,9 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req) security_req_classify_flow(req, flowi6_to_flowi(&fl6)); - final_p = fl6_update_dst(&fl6, np->opt, &final); + rcu_read_lock(); + final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final); + rcu_read_unlock(); dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); if (IS_ERR(dst)) { @@ -252,7 +254,10 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req) &ireq6->loc_addr, &ireq6->rmt_addr); fl6.daddr = ireq6->rmt_addr; - err = ip6_xmit(sk, skb, &fl6, np->opt, np->tclass); + rcu_read_lock(); + err = ip6_xmit(sk, skb, &fl6, rcu_dereference(np->opt), + np->tclass); + rcu_read_unlock(); err = net_xmit_eval(err); } @@ -448,6 +453,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, { struct inet6_request_sock *ireq6 = inet6_rsk(req); struct ipv6_pinfo *newnp, *np = inet6_sk(sk); + struct ipv6_txoptions *opt; struct inet_sock *newinet; struct dccp6_sock *newdp6; struct sock *newsk; @@ -571,13 +577,15 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, * Yes, keeping reference count would be much more clever, but we make * one more one thing there: reattach optmem to newsk. */ - if (np->opt != NULL) - newnp->opt = ipv6_dup_options(newsk, np->opt); - + opt = rcu_dereference(np->opt); + if (opt) { + opt = ipv6_dup_options(newsk, opt); + RCU_INIT_POINTER(newnp->opt, opt); + } inet_csk(newsk)->icsk_ext_hdr_len = 0; - if (newnp->opt != NULL) - inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen + - newnp->opt->opt_flen); + if (opt) + inet_csk(newsk)->icsk_ext_hdr_len = opt->opt_nflen + + opt->opt_flen; dccp_sync_mss(newsk, dst_mtu(dst)); @@ -829,6 +837,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, struct ipv6_pinfo *np = inet6_sk(sk); struct dccp_sock *dp = dccp_sk(sk); struct in6_addr *saddr = NULL, *final_p, final; + struct ipv6_txoptions *opt; struct flowi6 fl6; struct dst_entry *dst; int addr_type; @@ -931,7 +940,8 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, fl6.fl6_sport = inet->inet_sport; security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); - final_p = fl6_update_dst(&fl6, np->opt, &final); + opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk)); + final_p = fl6_update_dst(&fl6, opt, &final); dst = ip6_dst_lookup_flow(sk, &fl6, final_p, true); if (IS_ERR(dst)) { @@ -951,9 +961,8 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, __ip6_dst_store(sk, dst, NULL, NULL); icsk->icsk_ext_hdr_len = 0; - if (np->opt != NULL) - icsk->icsk_ext_hdr_len = (np->opt->opt_flen + - np->opt->opt_nflen); + if (opt) + icsk->icsk_ext_hdr_len = opt->opt_flen + opt->opt_nflen; inet->inet_dport = usin->sin6_port; diff --git a/net/ipc_router/ipc_router_socket.c b/net/ipc_router/ipc_router_socket.c index f74448eccbb71..8ba511b5d77dc 100644 --- a/net/ipc_router/ipc_router_socket.c +++ b/net/ipc_router/ipc_router_socket.c @@ -629,10 +629,18 @@ static unsigned int msm_ipc_router_poll(struct file *file, static int msm_ipc_router_close(struct socket *sock) { struct sock *sk = sock->sk; - struct msm_ipc_port *port_ptr = msm_ipc_sk_port(sk); + struct msm_ipc_port *port_ptr; int ret; + if (!sk) + return -EINVAL; + lock_sock(sk); + port_ptr = msm_ipc_sk_port(sk); + if (!port_ptr) { + release_sock(sk); + return -EINVAL; + } ret = msm_ipc_router_close_port(port_ptr); msm_ipc_unload_default_node(msm_ipc_sk(sk)->default_node_vote_info); release_sock(sk); diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index 8603ca8271041..0ee167c3ee3bc 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig @@ -433,6 +433,19 @@ config INET_UDP_DIAG Support for UDP socket monitoring interface used by the ss tool. If unsure, say Y. +config INET_DIAG_DESTROY + bool "INET: allow privileged process to administratively close sockets" + depends on INET_DIAG + default n + ---help--- + Provides a SOCK_DESTROY_BACKPORT operation that allows privileged processes + (e.g., a connection manager or a network administration tool such as + ss) to close sockets opened by other processes. Closing a socket in + this way interrupts any blocking read/write/connect operations on + the socket and causes future socket calls to behave as if the socket + had been disconnected. + If unsure, say N. + menuconfig TCP_CONG_ADVANCED bool "TCP: advanced congestion control" ---help--- diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 45dbdab915e20..b7527bfdc6a72 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c @@ -290,15 +290,12 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, return inet_csk_diag_fill(sk, skb, r, user_ns, portid, seq, nlmsg_flags, unlh); } -int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_skb, - const struct nlmsghdr *nlh, struct inet_diag_req_v2 *req) +struct sock *inet_diag_find_one_icsk(struct net *net, + struct inet_hashinfo *hashinfo, + struct inet_diag_req_v2 *req) { - int err; struct sock *sk; - struct sk_buff *rep; - struct net *net = sock_net(in_skb->sk); - err = -EINVAL; if (req->sdiag_family == AF_INET) { sk = inet_lookup(net, hashinfo, req->id.idiag_dst[0], req->id.idiag_dport, req->id.idiag_src[0], @@ -306,25 +303,53 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_s } #if IS_ENABLED(CONFIG_IPV6) else if (req->sdiag_family == AF_INET6) { - sk = inet6_lookup(net, hashinfo, - (struct in6_addr *)req->id.idiag_dst, - req->id.idiag_dport, - (struct in6_addr *)req->id.idiag_src, - req->id.idiag_sport, - req->id.idiag_if); + if (ipv6_addr_v4mapped((struct in6_addr *)req->id.idiag_dst) && + ipv6_addr_v4mapped((struct in6_addr *)req->id.idiag_src)) + sk = inet_lookup(net, hashinfo, req->id.idiag_dst[3], + req->id.idiag_dport, req->id.idiag_src[3], + req->id.idiag_sport, req->id.idiag_if); + else + sk = inet6_lookup(net, hashinfo, + (struct in6_addr *)req->id.idiag_dst, + req->id.idiag_dport, + (struct in6_addr *)req->id.idiag_src, + req->id.idiag_sport, + req->id.idiag_if); } #endif else { - goto out_nosk; + return ERR_PTR(-EINVAL); } - err = -ENOENT; - if (sk == NULL) - goto out_nosk; + if (!sk) + return ERR_PTR(-ENOENT); - err = sock_diag_check_cookie(sk, req->id.idiag_cookie); - if (err) - goto out; + if (sock_diag_check_cookie(sk, req->id.idiag_cookie)) { + /* NOTE: forward-ports should use sock_gen_put(sk) instead. */ + if (sk->sk_state == TCP_TIME_WAIT) + inet_twsk_put((struct inet_timewait_sock *)sk); + else + sock_put(sk); + return ERR_PTR(-ENOENT); + } + + return sk; +} +EXPORT_SYMBOL_GPL(inet_diag_find_one_icsk); + +int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, + struct sk_buff *in_skb, + const struct nlmsghdr *nlh, + struct inet_diag_req_v2 *req) +{ + struct net *net = sock_net(in_skb->sk); + struct sk_buff *rep; + struct sock *sk; + int err; + + sk = inet_diag_find_one_icsk(net, hashinfo, req); + if (IS_ERR(sk)) + return PTR_ERR(sk); rep = nlmsg_new(sizeof(struct inet_diag_msg) + sizeof(struct inet_diag_meminfo) + @@ -355,12 +380,11 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_s else sock_put(sk); } -out_nosk: return err; } EXPORT_SYMBOL_GPL(inet_diag_dump_one_icsk); -static int inet_diag_get_exact(struct sk_buff *in_skb, +static int inet_diag_cmd_exact(int cmd, struct sk_buff *in_skb, const struct nlmsghdr *nlh, struct inet_diag_req_v2 *req) { @@ -370,8 +394,12 @@ static int inet_diag_get_exact(struct sk_buff *in_skb, handler = inet_diag_lock_handler(req->sdiag_protocol); if (IS_ERR(handler)) err = PTR_ERR(handler); - else + else if (cmd == SOCK_DIAG_BY_FAMILY) err = handler->dump_one(in_skb, nlh, req); + else if (cmd == SOCK_DESTROY_BACKPORT && handler->destroy) + err = handler->destroy(in_skb, req); + else + err = -EOPNOTSUPP; inet_diag_unlock_handler(handler); return err; @@ -1071,7 +1099,7 @@ static int inet_diag_get_exact_compat(struct sk_buff *in_skb, req.idiag_states = rc->idiag_states; req.id = rc->id; - return inet_diag_get_exact(in_skb, nlh, &req); + return inet_diag_cmd_exact(SOCK_DIAG_BY_FAMILY, in_skb, nlh, &req); } static int inet_diag_rcv_msg_compat(struct sk_buff *skb, struct nlmsghdr *nlh) @@ -1105,7 +1133,7 @@ static int inet_diag_rcv_msg_compat(struct sk_buff *skb, struct nlmsghdr *nlh) return inet_diag_get_exact_compat(skb, nlh); } -static int inet_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h) +static int inet_diag_handler_cmd(struct sk_buff *skb, struct nlmsghdr *h) { int hdrlen = sizeof(struct inet_diag_req_v2); struct net *net = sock_net(skb->sk); @@ -1113,7 +1141,8 @@ static int inet_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h) if (nlmsg_len(h) < hdrlen) return -EINVAL; - if (h->nlmsg_flags & NLM_F_DUMP) { + if (h->nlmsg_type == SOCK_DIAG_BY_FAMILY && + h->nlmsg_flags & NLM_F_DUMP) { if (nlmsg_attrlen(h, hdrlen)) { struct nlattr *attr; attr = nlmsg_find_attr(h, hdrlen, @@ -1131,17 +1160,19 @@ static int inet_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h) } } - return inet_diag_get_exact(skb, h, nlmsg_data(h)); + return inet_diag_cmd_exact(h->nlmsg_type, skb, h, nlmsg_data(h)); } static const struct sock_diag_handler inet_diag_handler = { .family = AF_INET, - .dump = inet_diag_handler_dump, + .dump = inet_diag_handler_cmd, + .destroy = inet_diag_handler_cmd, }; static const struct sock_diag_handler inet6_diag_handler = { .family = AF_INET6, - .dump = inet_diag_handler_dump, + .dump = inet_diag_handler_cmd, + .destroy = inet_diag_handler_cmd, }; int inet_diag_register(const struct inet_diag_handler *h) diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index c6a8e98dbe123..738e62d548ce7 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -470,14 +470,12 @@ static int mark_source_chains(const struct xt_table_info *newinfo, return 1; } -static inline int check_entry(const struct arpt_entry *e, const char *name) +static inline int check_entry(const struct arpt_entry *e) { const struct xt_entry_target *t; - if (!arp_checkentry(&e->arp)) { - duprintf("arp_tables: arp check failed %p %s.\n", e, name); + if (!arp_checkentry(&e->arp)) return -EINVAL; - } if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset) return -EINVAL; @@ -518,10 +516,6 @@ find_check_entry(struct arpt_entry *e, const char *name, unsigned int size) struct xt_target *target; int ret; - ret = check_entry(e, name); - if (ret) - return ret; - t = arpt_get_target(e); target = xt_request_find_target(NFPROTO_ARP, t->u.user.name, t->u.user.revision); @@ -566,6 +560,7 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, unsigned int valid_hooks) { unsigned int h; + int err; if ((unsigned long)e % __alignof__(struct arpt_entry) != 0 || (unsigned char *)e + sizeof(struct arpt_entry) >= limit || @@ -581,6 +576,10 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, return -EINVAL; } + err = check_entry(e); + if (err) + return err; + /* Check hooks & underflows */ for (h = 0; h < NF_ARP_NUMHOOKS; h++) { if (!(valid_hooks & (1 << h))) @@ -1239,7 +1238,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e, } /* For purposes of check_entry casting the compat entry is fine */ - ret = check_entry((struct arpt_entry *)e, name); + ret = check_entry((struct arpt_entry *)e); if (ret) return ret; diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 9bb6ca7cf5761..2c8fb724dde5d 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -564,14 +564,12 @@ static void cleanup_match(struct xt_entry_match *m, struct net *net) } static int -check_entry(const struct ipt_entry *e, const char *name) +check_entry(const struct ipt_entry *e) { const struct xt_entry_target *t; - if (!ip_checkentry(&e->ip)) { - duprintf("ip check failed %p %s.\n", e, name); + if (!ip_checkentry(&e->ip)) return -EINVAL; - } if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset) @@ -661,10 +659,6 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name, struct xt_mtchk_param mtpar; struct xt_entry_match *ematch; - ret = check_entry(e, name); - if (ret) - return ret; - j = 0; mtpar.net = net; mtpar.table = name; @@ -728,6 +722,7 @@ check_entry_size_and_hooks(struct ipt_entry *e, unsigned int valid_hooks) { unsigned int h; + int err; if ((unsigned long)e % __alignof__(struct ipt_entry) != 0 || (unsigned char *)e + sizeof(struct ipt_entry) >= limit || @@ -743,6 +738,10 @@ check_entry_size_and_hooks(struct ipt_entry *e, return -EINVAL; } + err = check_entry(e); + if (err) + return err; + /* Check hooks & underflows */ for (h = 0; h < NF_INET_NUMHOOKS; h++) { if (!(valid_hooks & (1 << h))) @@ -1504,7 +1503,7 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e, } /* For purposes of check_entry casting the compat entry is fine */ - ret = check_entry((struct ipt_entry *)e, name); + ret = check_entry((struct ipt_entry *)e); if (ret) return ret; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 65fd0484cbed6..8ec0db2d54077 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -3386,6 +3386,43 @@ void tcp_done(struct sock *sk) } EXPORT_SYMBOL_GPL(tcp_done); +int tcp_abort(struct sock *sk, int err) +{ + if (sk->sk_state == TCP_TIME_WAIT) { + inet_twsk_put((struct inet_timewait_sock *)sk); + return -EOPNOTSUPP; + } + + /* Don't race with userspace socket closes such as tcp_close. */ + lock_sock(sk); + + if (sk->sk_state == TCP_LISTEN) { + tcp_set_state(sk, TCP_CLOSE); + inet_csk_listen_stop(sk); + } + + /* Don't race with BH socket closes such as inet_csk_listen_stop. */ + local_bh_disable(); + bh_lock_sock(sk); + + if (!sock_flag(sk, SOCK_DEAD)) { + sk->sk_err = err; + /* This barrier is coupled with smp_rmb() in tcp_poll() */ + smp_wmb(); + sk->sk_error_report(sk); + if (tcp_need_reset(sk->sk_state)) + tcp_send_active_reset(sk, GFP_ATOMIC); + tcp_done(sk); + } + + bh_unlock_sock(sk); + local_bh_enable(); + release_sock(sk); + sock_put(sk); + return 0; +} +EXPORT_SYMBOL_GPL(tcp_abort); + extern struct tcp_congestion_ops tcp_reno; static __initdata unsigned long thash_entries; diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c index ed3f2ad42e0f0..a56461c21b97d 100644 --- a/net/ipv4/tcp_diag.c +++ b/net/ipv4/tcp_diag.c @@ -11,6 +11,8 @@ #include +#include +#include #include #include @@ -46,11 +48,28 @@ static int tcp_diag_dump_one(struct sk_buff *in_skb, const struct nlmsghdr *nlh, return inet_diag_dump_one_icsk(&tcp_hashinfo, in_skb, nlh, req); } +#ifdef CONFIG_INET_DIAG_DESTROY +static int tcp_diag_destroy(struct sk_buff *in_skb, + struct inet_diag_req_v2 *req) +{ + struct net *net = sock_net(in_skb->sk); + struct sock *sk = inet_diag_find_one_icsk(net, &tcp_hashinfo, req); + + if (IS_ERR(sk)) + return PTR_ERR(sk); + + return sock_diag_destroy(sk, ECONNABORTED); +} +#endif + static const struct inet_diag_handler tcp_diag_handler = { .dump = tcp_diag_dump, .dump_one = tcp_diag_dump_one, .idiag_get_info = tcp_diag_get_info, .idiag_type = IPPROTO_TCP, +#ifdef CONFIG_INET_DIAG_DESTROY + .destroy = tcp_diag_destroy, +#endif }; static int __init tcp_diag_init(void) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index ae45e53a0e845..4128dc4eb6321 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -3295,13 +3295,13 @@ static void tcp_send_challenge_ack(struct sock *sk) u32 half = (sysctl_tcp_challenge_ack_limit + 1) >> 1; challenge_timestamp = now; - ACCESS_ONCE(challenge_count) = half + - reciprocal_divide(prandom_u32(), - sysctl_tcp_challenge_ack_limit); + ACCESS_ONCE(challenge_count) = half + + reciprocal_divide(prandom_u32(), + sysctl_tcp_challenge_ack_limit); } count = ACCESS_ONCE(challenge_count); if (count > 0) { - ACCESS_ONCE(challenge_count) = count - 1; + ACCESS_ONCE(challenge_count) = count - 1; NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPCHALLENGEACK); tcp_send_ack(sk); } diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index fefe36a6d3d7f..fbfe33afc5591 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2892,6 +2892,7 @@ struct proto tcp_prot = { .destroy_cgroup = tcp_destroy_cgroup, .proto_cgroup = tcp_proto_cgroup, #endif + .diag_destroy = tcp_abort, }; EXPORT_SYMBOL(tcp_prot); diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 346018946dc55..3b24e05ca2b4e 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -207,6 +207,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = { .accept_dad = 1, .accept_ra_prefix_route = 1, .accept_ra_mtu = 1, + .use_oif_addrs_only = 0, }; static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { @@ -244,6 +245,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { .accept_dad = 1, .accept_ra_prefix_route = 1, .accept_ra_mtu = 1, + .use_oif_addrs_only = 0, }; /* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */ @@ -1181,6 +1183,9 @@ enum { #endif IPV6_SADDR_RULE_ORCHID, IPV6_SADDR_RULE_PREFIX, +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD + IPV6_SADDR_RULE_NOT_OPTIMISTIC, +#endif IPV6_SADDR_RULE_MAX }; @@ -1208,6 +1213,15 @@ static inline int ipv6_saddr_preferred(int type) return 0; } +static inline bool ipv6_use_optimistic_addr(struct inet6_dev *idev) +{ +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD + return idev && idev->cnf.optimistic_dad && idev->cnf.use_optimistic; +#else + return false; +#endif +} + static int ipv6_get_saddr_eval(struct net *net, struct ipv6_saddr_score *score, struct ipv6_saddr_dst *dst, @@ -1268,10 +1282,16 @@ static int ipv6_get_saddr_eval(struct net *net, score->scopedist = ret; break; case IPV6_SADDR_RULE_PREFERRED: + { /* Rule 3: Avoid deprecated and optimistic addresses */ + u8 avoid = IFA_F_DEPRECATED; + + if (!ipv6_use_optimistic_addr(score->ifa->idev)) + avoid |= IFA_F_OPTIMISTIC; ret = ipv6_saddr_preferred(score->addr_type) || - !(score->ifa->flags & (IFA_F_DEPRECATED|IFA_F_OPTIMISTIC)); + !(score->ifa->flags & avoid); break; + } #ifdef CONFIG_IPV6_MIP6 case IPV6_SADDR_RULE_HOA: { @@ -1319,6 +1339,14 @@ static int ipv6_get_saddr_eval(struct net *net, ret = score->ifa->prefix_len; score->matchlen = ret; break; +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD + case IPV6_SADDR_RULE_NOT_OPTIMISTIC: + /* Optimistic addresses still have lower precedence than other + * preferred addresses. + */ + ret = !(score->ifa->flags & IFA_F_OPTIMISTIC); + break; +#endif default: ret = 0; } @@ -1366,9 +1394,15 @@ int ipv6_dev_get_saddr(struct net *net, const struct net_device *dst_dev, * include addresses assigned to interfaces * belonging to the same site as the outgoing * interface.) + * - "It is RECOMMENDED that the candidate source addresses + * be the set of unicast addresses assigned to the + * interface that will be used to send to the destination + * (the 'outgoing' interface)." (RFC 6724) */ + idev = dst_dev ? __in6_dev_get(dst_dev) : NULL; if (((dst_type & IPV6_ADDR_MULTICAST) || - dst.scope <= IPV6_ADDR_SCOPE_LINKLOCAL) && + dst.scope <= IPV6_ADDR_SCOPE_LINKLOCAL || + (idev && idev->cnf.use_oif_addrs_only)) && dst.ifindex && dev->ifindex != dst.ifindex) continue; @@ -1514,7 +1548,9 @@ int ipv6_chk_addr(struct net *net, const struct in6_addr *addr, if (!net_eq(dev_net(ifp->idev->dev), net)) continue; if (ipv6_addr_equal(&ifp->addr, addr) && - !(ifp->flags&IFA_F_TENTATIVE) && + (!(ifp->flags&IFA_F_TENTATIVE) || + (ipv6_use_optimistic_addr(ifp->idev) && + ifp->flags&IFA_F_OPTIMISTIC)) && (dev == NULL || ifp->idev->dev == dev || !(ifp->scope&(IFA_LINK|IFA_HOST) || strict))) { rcu_read_unlock_bh(); @@ -3296,8 +3332,15 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp) * Optimistic nodes can start receiving * Frames right away */ - if (ifp->flags & IFA_F_OPTIMISTIC) + if (ifp->flags & IFA_F_OPTIMISTIC) { ip6_ins_rt(ifp->rt); + if (ipv6_use_optimistic_addr(idev)) { + /* Because optimistic nodes can use this address, + * notify listeners. If DAD fails, RTM_DELADDR is sent. + */ + ipv6_ifa_notify(RTM_NEWADDR, ifp); + } + } addrconf_dad_kick(ifp); out: @@ -4243,6 +4286,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, array[DEVCONF_ACCEPT_SOURCE_ROUTE] = cnf->accept_source_route; #ifdef CONFIG_IPV6_OPTIMISTIC_DAD array[DEVCONF_OPTIMISTIC_DAD] = cnf->optimistic_dad; + array[DEVCONF_USE_OPTIMISTIC] = cnf->use_optimistic; #endif #ifdef CONFIG_IPV6_MROUTE array[DEVCONF_MC_FORWARDING] = cnf->mc_forwarding; @@ -4252,6 +4296,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, array[DEVCONF_FORCE_TLLAO] = cnf->force_tllao; array[DEVCONF_NDISC_NOTIFY] = cnf->ndisc_notify; array[DEVCONF_ACCEPT_RA_MTU] = cnf->accept_ra_mtu; + array[DEVCONF_USE_OIF_ADDRS_ONLY] = cnf->use_oif_addrs_only; } static inline size_t inet6_ifla6_size(void) @@ -4993,6 +5038,14 @@ static struct addrconf_sysctl_table .proc_handler = proc_dointvec, }, + { + .procname = "use_optimistic", + .data = &ipv6_devconf.use_optimistic, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + + }, #endif #ifdef CONFIG_IPV6_MROUTE { @@ -5045,6 +5098,14 @@ static struct addrconf_sysctl_table .mode = 0644, .proc_handler = proc_dointvec, }, + { + .procname = "use_oif_addrs_only", + .data = &ipv6_devconf.use_oif_addrs_only, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + + }, { /* sentinel */ } diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 0f2e8b892b721..9c24fbf3d8653 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -451,9 +451,11 @@ void inet6_destroy_sock(struct sock *sk) /* Free tx options */ - opt = xchg(&np->opt, NULL); - if (opt != NULL) - sock_kfree_s(sk, opt, opt->tot_len); + opt = xchg((__force struct ipv6_txoptions **)&np->opt, NULL); + if (opt) { + atomic_sub(opt->tot_len, &sk->sk_omem_alloc); + txopt_put(opt); + } } EXPORT_SYMBOL_GPL(inet6_destroy_sock); @@ -700,7 +702,10 @@ int inet6_sk_rebuild_header(struct sock *sk) fl6.flowi6_uid = sock_i_uid(sk); security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); - final_p = fl6_update_dst(&fl6, np->opt, &final); + rcu_read_lock(); + final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), + &final); + rcu_read_unlock(); dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); if (IS_ERR(dst)) { diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index e9a8ca614aaea..58e6cf78ad42c 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -169,8 +169,10 @@ int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); - opt = flowlabel ? flowlabel->opt : np->opt; + rcu_read_lock(); + opt = flowlabel ? flowlabel->opt : rcu_dereference(np->opt); final_p = fl6_update_dst(&fl6, opt, &final); + rcu_read_unlock(); dst = ip6_dst_lookup_flow(sk, &fl6, final_p, true); err = 0; diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 8d67900aa0036..33dbd6c1a00df 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c @@ -727,6 +727,7 @@ ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt) *((char **)&opt2->dst1opt) += dif; if (opt2->srcrt) *((char **)&opt2->srcrt) += dif; + atomic_set(&opt2->refcnt, 1); } return opt2; } @@ -790,7 +791,7 @@ ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt, return ERR_PTR(-ENOBUFS); memset(opt2, 0, tot_len); - + atomic_set(&opt2->refcnt, 1); opt2->tot_len = tot_len; p = (char *)(opt2 + 1); diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index 329985bb067b7..f92676cb879f5 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c @@ -78,7 +78,9 @@ struct dst_entry *inet6_csk_route_req(struct sock *sk, memset(fl6, 0, sizeof(*fl6)); fl6->flowi6_proto = IPPROTO_TCP; fl6->daddr = treq->rmt_addr; - final_p = fl6_update_dst(fl6, np->opt, &final); + rcu_read_lock(); + final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final); + rcu_read_unlock(); fl6->saddr = treq->loc_addr; fl6->flowi6_oif = treq->iif; fl6->flowi6_mark = inet_rsk(req)->ir_mark; @@ -214,7 +216,9 @@ static struct dst_entry *inet6_csk_route_socket(struct sock *sk, fl6->fl6_dport = inet->inet_dport; security_sk_classify_flow(sk, flowi6_to_flowi(fl6)); - final_p = fl6_update_dst(fl6, np->opt, &final); + rcu_read_lock(); + final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final); + rcu_read_unlock(); dst = __inet6_csk_dst_check(sk, np->dst_cookie); if (!dst) { @@ -248,7 +252,8 @@ int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused) /* Restore final destination back after routing done */ fl6.daddr = np->daddr; - res = ip6_xmit(sk, skb, &fl6, np->opt, np->tclass); + res = ip6_xmit(sk, skb, &fl6, rcu_dereference(np->opt), + np->tclass); rcu_read_unlock(); return res; } diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index d1e2e8ef29c54..f4d2412d9c608 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -110,10 +110,12 @@ struct ipv6_txoptions *ipv6_update_options(struct sock *sk, icsk->icsk_ext_hdr_len = opt->opt_flen + opt->opt_nflen; icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie); } - opt = xchg(&inet6_sk(sk)->opt, opt); + opt = xchg((__force struct ipv6_txoptions **)&inet6_sk(sk)->opt, + opt); } else { spin_lock(&sk->sk_dst_lock); - opt = xchg(&inet6_sk(sk)->opt, opt); + opt = xchg((__force struct ipv6_txoptions **)&inet6_sk(sk)->opt, + opt); spin_unlock(&sk->sk_dst_lock); } sk_dst_reset(sk); @@ -213,9 +215,12 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, sk->sk_socket->ops = &inet_dgram_ops; sk->sk_family = PF_INET; } - opt = xchg(&np->opt, NULL); - if (opt) - sock_kfree_s(sk, opt, opt->tot_len); + opt = xchg((__force struct ipv6_txoptions **)&np->opt, + NULL); + if (opt) { + atomic_sub(opt->tot_len, &sk->sk_omem_alloc); + txopt_put(opt); + } pktopt = xchg(&np->pktoptions, NULL); kfree_skb(pktopt); @@ -385,7 +390,8 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, if (optname != IPV6_RTHDR && !ns_capable(net->user_ns, CAP_NET_RAW)) break; - opt = ipv6_renew_options(sk, np->opt, optname, + opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk)); + opt = ipv6_renew_options(sk, opt, optname, (struct ipv6_opt_hdr __user *)optval, optlen); if (IS_ERR(opt)) { @@ -414,8 +420,10 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, retv = 0; opt = ipv6_update_options(sk, opt); sticky_done: - if (opt) - sock_kfree_s(sk, opt, opt->tot_len); + if (opt) { + atomic_sub(opt->tot_len, &sk->sk_omem_alloc); + txopt_put(opt); + } break; } @@ -468,6 +476,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, break; memset(opt, 0, sizeof(*opt)); + atomic_set(&opt->refcnt, 1); opt->tot_len = sizeof(*opt) + optlen; retv = -EFAULT; if (copy_from_user(opt+1, optval, optlen)) @@ -484,8 +493,10 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, retv = 0; opt = ipv6_update_options(sk, opt); done: - if (opt) - sock_kfree_s(sk, opt, opt->tot_len); + if (opt) { + atomic_sub(opt->tot_len, &sk->sk_omem_alloc); + txopt_put(opt); + } break; } case IPV6_UNICAST_HOPS: @@ -1085,10 +1096,11 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, case IPV6_RTHDR: case IPV6_DSTOPTS: { + struct ipv6_txoptions *opt; lock_sock(sk); - len = ipv6_getsockopt_sticky(sk, np->opt, - optname, optval, len); + opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk)); + len = ipv6_getsockopt_sticky(sk, opt, optname, optval, len); release_sock(sk); /* check if ipv6_getsockopt_sticky() returns err code */ if (len < 0) diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 2a0c4819e277a..bc0615b1cf63e 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -574,14 +574,12 @@ static void cleanup_match(struct xt_entry_match *m, struct net *net) } static int -check_entry(const struct ip6t_entry *e, const char *name) +check_entry(const struct ip6t_entry *e) { const struct xt_entry_target *t; - if (!ip6_checkentry(&e->ipv6)) { - duprintf("ip_tables: ip check failed %p %s.\n", e, name); + if (!ip6_checkentry(&e->ipv6)) return -EINVAL; - } if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset) @@ -672,10 +670,6 @@ find_check_entry(struct ip6t_entry *e, struct net *net, const char *name, struct xt_mtchk_param mtpar; struct xt_entry_match *ematch; - ret = check_entry(e, name); - if (ret) - return ret; - j = 0; mtpar.net = net; mtpar.table = name; @@ -739,6 +733,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e, unsigned int valid_hooks) { unsigned int h; + int err; if ((unsigned long)e % __alignof__(struct ip6t_entry) != 0 || (unsigned char *)e + sizeof(struct ip6t_entry) >= limit || @@ -754,6 +749,10 @@ check_entry_size_and_hooks(struct ip6t_entry *e, return -EINVAL; } + err = check_entry(e); + if (err) + return err; + /* Check hooks & underflows */ for (h = 0; h < NF_INET_NUMHOOKS; h++) { if (!(valid_hooks & (1 << h))) @@ -1516,7 +1515,7 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e, } /* For purposes of check_entry casting the compat entry is fine */ - ret = check_entry((struct ip6t_entry *)e, name); + ret = check_entry((struct ip6t_entry *)e); if (ret) return ret; diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 32c0d4e14a5ed..80f082cd4d5c6 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -726,6 +726,7 @@ static int rawv6_probe_proto_opt(struct flowi6 *fl6, struct msghdr *msg) static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, size_t len) { + struct ipv6_txoptions *opt_to_free = NULL; struct ipv6_txoptions opt_space; struct sockaddr_in6 * sin6 = (struct sockaddr_in6 *) msg->msg_name; struct in6_addr *daddr, *final_p, final; @@ -833,8 +834,10 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, if (!(opt->opt_nflen|opt->opt_flen)) opt = NULL; } - if (opt == NULL) - opt = np->opt; + if (!opt) { + opt = txopt_get(np); + opt_to_free = opt; + } if (flowlabel) opt = fl6_merge_options(&opt_space, flowlabel, opt); opt = ipv6_fixup_options(&opt_space, opt); @@ -901,7 +904,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, dst_release(dst); out: fl6_sock_release(flowlabel); - return err<0?err:len; + txopt_put(opt_to_free); + return err < 0 ? err : len; do_confirm: dst_confirm(dst); if (!(msg->msg_flags & MSG_PROBE) || len) diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index ba8622daffd7e..701d0656a4021 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c @@ -237,7 +237,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) memset(&fl6, 0, sizeof(fl6)); fl6.flowi6_proto = IPPROTO_TCP; fl6.daddr = ireq6->rmt_addr; - final_p = fl6_update_dst(&fl6, np->opt, &final); + final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final); fl6.saddr = ireq6->loc_addr; fl6.flowi6_oif = sk->sk_bound_dev_if; fl6.flowi6_mark = ireq->ir_mark; diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 9c2f2b9c17e6b..dc348c13838ea 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -133,6 +133,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, struct ipv6_pinfo *np = inet6_sk(sk); struct tcp_sock *tp = tcp_sk(sk); struct in6_addr *saddr = NULL, *final_p, final; + struct ipv6_txoptions *opt; struct rt6_info *rt; struct flowi6 fl6; struct dst_entry *dst; @@ -254,7 +255,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, fl6.fl6_sport = inet->inet_sport; fl6.flowi6_uid = sock_i_uid(sk); - final_p = fl6_update_dst(&fl6, np->opt, &final); + opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk)); + final_p = fl6_update_dst(&fl6, opt, &final); security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); @@ -283,9 +285,9 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, tcp_fetch_timewait_stamp(sk, dst); icsk->icsk_ext_hdr_len = 0; - if (np->opt) - icsk->icsk_ext_hdr_len = (np->opt->opt_flen + - np->opt->opt_nflen); + if (opt) + icsk->icsk_ext_hdr_len = opt->opt_flen + + opt->opt_nflen; tp->rx_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); @@ -481,7 +483,8 @@ static int tcp_v6_send_synack(struct sock *sk, struct dst_entry *dst, fl6->daddr = treq->rmt_addr; skb_set_queue_mapping(skb, queue_mapping); - err = ip6_xmit(sk, skb, fl6, np->opt, np->tclass); + err = ip6_xmit(sk, skb, fl6, rcu_dereference(np->opt), + np->tclass); err = net_xmit_eval(err); } @@ -1090,6 +1093,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, struct inet6_request_sock *treq; struct ipv6_pinfo *newnp, *np = inet6_sk(sk); struct tcp6_sock *newtcp6sk; + struct ipv6_txoptions *opt; struct inet_sock *newinet; struct tcp_sock *newtp; struct sock *newsk; @@ -1223,13 +1227,15 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, but we make one more one thing there: reattach optmem to newsk. */ - if (np->opt) - newnp->opt = ipv6_dup_options(newsk, np->opt); - + opt = rcu_dereference(np->opt); + if (opt) { + opt = ipv6_dup_options(newsk, opt); + RCU_INIT_POINTER(newnp->opt, opt); + } inet_csk(newsk)->icsk_ext_hdr_len = 0; - if (newnp->opt) - inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen + - newnp->opt->opt_flen); + if (opt) + inet_csk(newsk)->icsk_ext_hdr_len = opt->opt_nflen + + opt->opt_flen; tcp_mtup_init(newsk); tcp_sync_mss(newsk, dst_mtu(dst)); @@ -1948,6 +1954,7 @@ struct proto tcpv6_prot = { .proto_cgroup = tcp_proto_cgroup, #endif .clear_sk = tcp_v6_clear_sk, + .diag_destroy = tcp_abort, }; static const struct inet6_protocol tcpv6_protocol = { diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index a963e61f40d97..19beecacb0ac4 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -1016,6 +1016,7 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) msg->msg_name; struct in6_addr *daddr, *final_p, final; struct ipv6_txoptions *opt = NULL; + struct ipv6_txoptions *opt_to_free = NULL; struct ip6_flowlabel *flowlabel = NULL; struct flowi6 fl6; struct dst_entry *dst; @@ -1170,8 +1171,10 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, opt = NULL; connected = 0; } - if (opt == NULL) - opt = np->opt; + if (!opt) { + opt = txopt_get(np); + opt_to_free = opt; + } if (flowlabel) opt = fl6_merge_options(&opt_space, flowlabel, opt); opt = ipv6_fixup_options(&opt_space, opt); @@ -1272,6 +1275,7 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, out: dst_release(dst); fl6_sock_release(flowlabel); + txopt_put(opt_to_free); if (!err) return len; /* diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c index e6e8408c9e367..3b61ddd6e4a67 100644 --- a/net/l2tp/l2tp_ip6.c +++ b/net/l2tp/l2tp_ip6.c @@ -485,6 +485,7 @@ static int l2tp_ip6_sendmsg(struct kiocb *iocb, struct sock *sk, (struct sockaddr_l2tpip6 *) msg->msg_name; struct in6_addr *daddr, *final_p, final; struct ipv6_pinfo *np = inet6_sk(sk); + struct ipv6_txoptions *opt_to_free = NULL; struct ipv6_txoptions *opt = NULL; struct ip6_flowlabel *flowlabel = NULL; struct dst_entry *dst = NULL; @@ -575,8 +576,10 @@ static int l2tp_ip6_sendmsg(struct kiocb *iocb, struct sock *sk, opt = NULL; } - if (opt == NULL) - opt = np->opt; + if (!opt) { + opt = txopt_get(np); + opt_to_free = opt; + } if (flowlabel) opt = fl6_merge_options(&opt_space, flowlabel, opt); opt = ipv6_fixup_options(&opt_space, opt); @@ -637,6 +640,7 @@ static int l2tp_ip6_sendmsg(struct kiocb *iocb, struct sock *sk, dst_release(dst); out: fl6_sock_release(flowlabel); + txopt_put(opt_to_free); return err < 0 ? err : len; diff --git a/net/rmnet_data/rmnet_data_vnd.c b/net/rmnet_data/rmnet_data_vnd.c index ef8b8a62a3a88..f6ef21464850c 100644 --- a/net/rmnet_data/rmnet_data_vnd.c +++ b/net/rmnet_data/rmnet_data_vnd.c @@ -921,7 +921,7 @@ int rmnet_vnd_add_tc_flow(uint32_t id, uint32_t map_flow, uint32_t tc_flow) list_add(&(itm->list), &(dev_conf->flow_head)); write_unlock_irqrestore(&dev_conf->flow_map_lock, flags); - LOGD("Created flow mapping [%s][0x%08X][0x%08X]@%p", + LOGD("Created flow mapping [%s][0x%08X][0x%08X]@%pK", dev->name, itm->map_flow_id, itm->tc_flow_id[0], itm); return RMNET_CONFIG_OK; diff --git a/net/rmnet_data/rmnet_map_data.c b/net/rmnet_data/rmnet_map_data.c index 4a00b775c0997..18f239a17b7b8 100644 --- a/net/rmnet_data/rmnet_map_data.c +++ b/net/rmnet_data/rmnet_map_data.c @@ -79,6 +79,15 @@ struct rmnet_map_header_s *rmnet_map_add_map_header(struct sk_buff *skb, padding = ALIGN(map_datalen, 4) - map_datalen; + if (padding == 0) + goto done; + + if ((skb->dev->features & NETIF_F_GSO) && + skb_is_nonlinear(skb) && unlikely((padding != 0))) { + LOGE("pad:%d required for non linear skb", padding); + BUG(); + } + if (skb_tailroom(skb) < padding) return 0; @@ -86,6 +95,7 @@ struct rmnet_map_header_s *rmnet_map_add_map_header(struct sk_buff *skb, LOGD("pad: %d", padding); memset(padbytes, 0, padding); +done: map_header->pkt_len = htons(map_datalen + padding); map_header->pad_len = padding&0x3F; diff --git a/net/socket.c b/net/socket.c index 59c989619a5b0..9f53f2810ad6e 100644 --- a/net/socket.c +++ b/net/socket.c @@ -2437,19 +2437,20 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, * We may return less entries than requested (vlen) if the * sock is non block and there aren't enough datagrams... */ - if (err != -EAGAIN) { - /* - * ... or if recvmsg returns an error after we - * received some datagrams, where we record the - * error to return on the next call or if the - * app asks about it using getsockopt(SO_ERROR). - */ - sock->sk->sk_err = -err; - } + if (err != -EAGAIN) { + /* + * ... or if recvmsg returns an error after we + * received some datagrams, where we record the + * error to return on the next call or if the + * app asks about it using getsockopt(SO_ERROR). + */ + sock->sk->sk_err = -err; + } + out_put: - fput_light(sock->file, fput_needed); + fput_light(sock->file, fput_needed); - return datagrams; + return datagrams; } SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg, diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index e8195114571c7..f5c9e5eaf072d 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -314,7 +314,119 @@ static struct sock *unix_find_socket_byinode(struct inode *i) return s; } -static inline int unix_writable(struct sock *sk) +/* Support code for asymmetrically connected dgram sockets + * + * If a datagram socket is connected to a socket not itself connected + * to the first socket (eg, /dev/log), clients may only enqueue more + * messages if the present receive queue of the server socket is not + * "too large". This means there's a second writeability condition + * poll and sendmsg need to test. The dgram recv code will do a wake + * up on the peer_wait wait queue of a socket upon reception of a + * datagram which needs to be propagated to sleeping would-be writers + * since these might not have sent anything so far. This can't be + * accomplished via poll_wait because the lifetime of the server + * socket might be less than that of its clients if these break their + * association with it or if the server socket is closed while clients + * are still connected to it and there's no way to inform "a polling + * implementation" that it should let go of a certain wait queue + * + * In order to propagate a wake up, a wait_queue_t of the client + * socket is enqueued on the peer_wait queue of the server socket + * whose wake function does a wake_up on the ordinary client socket + * wait queue. This connection is established whenever a write (or + * poll for write) hit the flow control condition and broken when the + * association to the server socket is dissolved or after a wake up + * was relayed. + */ + +static int unix_dgram_peer_wake_relay(wait_queue_t *q, unsigned mode, int flags, + void *key) +{ + struct unix_sock *u; + wait_queue_head_t *u_sleep; + + u = container_of(q, struct unix_sock, peer_wake); + + __remove_wait_queue(&unix_sk(u->peer_wake.private)->peer_wait, + q); + u->peer_wake.private = NULL; + + /* relaying can only happen while the wq still exists */ + u_sleep = sk_sleep(&u->sk); + if (u_sleep) + wake_up_interruptible_poll(u_sleep, key); + + return 0; +} + +static int unix_dgram_peer_wake_connect(struct sock *sk, struct sock *other) +{ + struct unix_sock *u, *u_other; + int rc; + + u = unix_sk(sk); + u_other = unix_sk(other); + rc = 0; + spin_lock(&u_other->peer_wait.lock); + + if (!u->peer_wake.private) { + u->peer_wake.private = other; + __add_wait_queue(&u_other->peer_wait, &u->peer_wake); + + rc = 1; + } + + spin_unlock(&u_other->peer_wait.lock); + return rc; +} + +static void unix_dgram_peer_wake_disconnect(struct sock *sk, + struct sock *other) +{ + struct unix_sock *u, *u_other; + + u = unix_sk(sk); + u_other = unix_sk(other); + spin_lock(&u_other->peer_wait.lock); + + if (u->peer_wake.private == other) { + __remove_wait_queue(&u_other->peer_wait, &u->peer_wake); + u->peer_wake.private = NULL; + } + + spin_unlock(&u_other->peer_wait.lock); +} + +static void unix_dgram_peer_wake_disconnect_wakeup(struct sock *sk, + struct sock *other) +{ + unix_dgram_peer_wake_disconnect(sk, other); + wake_up_interruptible_poll(sk_sleep(sk), + POLLOUT | + POLLWRNORM | + POLLWRBAND); +} + +/* preconditions: + * - unix_peer(sk) == other + * - association is stable + */ +static int unix_dgram_peer_wake_me(struct sock *sk, struct sock *other) +{ + int connected; + + connected = unix_dgram_peer_wake_connect(sk, other); + + if (unix_recvq_full(other)) + return 1; + + if (connected) + unix_dgram_peer_wake_disconnect(sk, other); + + return 0; +} + +static int unix_writable(const struct sock *sk) { return (atomic_read(&sk->sk_wmem_alloc) << 2) <= sk->sk_sndbuf; } @@ -418,6 +530,8 @@ static void unix_release_sock(struct sock *sk, int embrion) skpair->sk_state_change(skpair); sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP); } + + unix_dgram_peer_wake_disconnect(sk, skpair); sock_put(skpair); /* It may now die */ unix_peer(sk) = NULL; } @@ -651,6 +765,7 @@ static struct sock *unix_create1(struct net *net, struct socket *sock) INIT_LIST_HEAD(&u->link); mutex_init(&u->readlock); /* single task reading lock */ init_waitqueue_head(&u->peer_wait); + init_waitqueue_func_entry(&u->peer_wake, unix_dgram_peer_wake_relay); unix_insert_socket(unix_sockets_unbound(sk), sk); out: if (sk == NULL) @@ -1018,6 +1133,8 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr, if (unix_peer(sk)) { struct sock *old_peer = unix_peer(sk); unix_peer(sk) = other; + unix_dgram_peer_wake_disconnect_wakeup(sk, old_peer); + unix_state_double_unlock(sk, other); if (other != old_peer) @@ -1457,6 +1574,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, struct scm_cookie tmp_scm; int max_level; int data_len = 0; + int sk_locked; if (NULL == siocb->scm) siocb->scm = &tmp_scm; @@ -1533,12 +1651,14 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, goto out_free; } + sk_locked = 0; unix_state_lock(other); +restart_locked: err = -EPERM; if (!unix_may_send(sk, other)) goto out_unlock; - if (sock_flag(other, SOCK_DEAD)) { + if (unlikely(sock_flag(other, SOCK_DEAD))) { /* * Check with 1003.1g - what should * datagram error @@ -1546,10 +1666,14 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, unix_state_unlock(other); sock_put(other); + if (!sk_locked) + unix_state_lock(sk); + err = 0; - unix_state_lock(sk); if (unix_peer(sk) == other) { unix_peer(sk) = NULL; + unix_dgram_peer_wake_disconnect_wakeup(sk, other); + unix_state_unlock(sk); unix_dgram_disconnected(sk, other); @@ -1579,22 +1703,38 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, * - unix_peer(sk) == NULL, destination address bound to sk * - unix_peer(sk) == sk by time of get but disconnected before lock */ - if (other != sk && - unlikely(unix_peer(other) != sk && unix_recvq_full(other))) { - if (!timeo) { - err = -EAGAIN; - goto out_unlock; + if (unlikely(unix_peer(other) != sk && unix_recvq_full(other))) { + if (timeo) { + timeo = unix_wait_for_peer(other, timeo); + + err = sock_intr_errno(timeo); + if (signal_pending(current)) + goto out_free; + + goto restart; } - timeo = unix_wait_for_peer(other, timeo); + if (!sk_locked) { + unix_state_unlock(other); + unix_state_double_lock(sk, other); + } - err = sock_intr_errno(timeo); - if (signal_pending(current)) - goto out_free; + if (unix_peer(sk) != other || + unix_dgram_peer_wake_me(sk, other)) { + err = -EAGAIN; + sk_locked = 1; + goto out_unlock; + } - goto restart; + if (!sk_locked) { + sk_locked = 1; + goto restart_locked; + } } + if (unlikely(sk_locked)) + unix_state_unlock(sk); + if (sock_flag(other, SOCK_RCVTSTAMP)) __net_timestamp(skb); maybe_add_creds(skb, sock, other); @@ -1608,6 +1748,8 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, return len; out_unlock: + if (sk_locked) + unix_state_unlock(sk); unix_state_unlock(other); out_free: kfree_skb(skb); @@ -2246,14 +2388,16 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock, return mask; writable = unix_writable(sk); - other = unix_peer_get(sk); - if (other) { - if (unix_peer(other) != sk) { - sock_poll_wait(file, &unix_sk(other)->peer_wait, wait); - if (unix_recvq_full(other)) - writable = 0; - } - sock_put(other); + if (writable) { + unix_state_lock(sk); + + other = unix_peer(sk); + if (other && unix_peer(other) != sk && + unix_recvq_full(other) && + unix_dgram_peer_wake_me(sk, other)) + writable = 0; + + unix_state_unlock(sk); } if (writable) diff --git a/net/wireless/core.h b/net/wireless/core.h index 508a1fae008c2..36d2d64a401d4 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -210,7 +210,6 @@ enum cfg80211_event_type { EVENT_ROAMED, EVENT_DISCONNECTED, EVENT_IBSS_JOINED, - EVENT_AUTHORIZATION, }; struct cfg80211_event { @@ -241,12 +240,6 @@ struct cfg80211_event { struct { u8 bssid[ETH_ALEN]; } ij; - struct { - enum nl80211_authorization_status auth_status; - u8 key_replay_ctr[NL80211_KEY_REPLAY_CTR_LEN]; - u8 ptk_kck[NL80211_KEY_LEN_PTK_KCK]; - u8 ptk_kek[NL80211_KEY_LEN_PTK_KEK]; - } au; }; }; @@ -403,10 +396,6 @@ void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *resp_ie, size_t resp_ie_len); int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev); -void __cfg80211_authorization_event(struct net_device *dev, - enum nl80211_authorization_status auth_status, - const u8 *key_replay_ctr, const u8 *ptk_kck, - const u8 *ptk_kek); void cfg80211_conn_work(struct work_struct *work); void cfg80211_sme_failed_assoc(struct wireless_dev *wdev); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index e85cacfbbb99c..4db9ee0ac5f1a 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -389,21 +389,6 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_MAC_HINT] = { .len = ETH_ALEN }, [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 }, [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 }, - [NL80211_ATTR_AUTHORIZATION_STATUS] = { .type = NLA_U8 }, - [NL80211_ATTR_KEY_REPLAY_CTR] = { .type = NLA_BINARY, - .len = NL80211_KEY_REPLAY_CTR_LEN }, - [NL80211_ATTR_PSK] = { .type = NLA_BINARY, - .len = NL80211_KEY_LEN_PSK }, - [NL80211_ATTR_OFFLOAD_KEY_MGMT] = { .type = NLA_FLAG }, - [NL80211_ATTR_KEY_MGMT_OFFLOAD_SUPPORT] = { .type = NLA_U32 }, - [NL80211_ATTR_KEY_DERIVE_OFFLOAD_SUPPORT] = { .type = NLA_U32 }, - [NL80211_ATTR_PMK] = { .type = NLA_BINARY, - .len = NL80211_KEY_LEN_PMK }, - [NL80211_ATTR_PMK_LEN] = { .type = NLA_U32 }, - [NL80211_ATTR_PTK_KCK] = { .type = NLA_BINARY, - .len = NL80211_KEY_LEN_PTK_KCK }, - [NL80211_ATTR_PTK_KEK] = { .type = NLA_BINARY, - .len = NL80211_KEY_LEN_PTK_KEK }, }; /* policy for the key attributes */ @@ -628,6 +613,12 @@ static int nl80211_msg_put_channel(struct sk_buff *msg, if ((chan->flags & IEEE80211_CHAN_NO_160MHZ) && nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_160MHZ)) goto nla_put_failure; + if ((chan->flags & IEEE80211_CHAN_INDOOR_ONLY) && + nla_put_flag(msg, NL80211_FREQUENCY_ATTR_INDOOR_ONLY)) + goto nla_put_failure; + if ((chan->flags & IEEE80211_CHAN_GO_CONCURRENT) && + nla_put_flag(msg, NL80211_FREQUENCY_ATTR_GO_CONCURRENT)) + goto nla_put_failure; } if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER, @@ -1256,12 +1247,6 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, if ((dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) && nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP)) goto nla_put_failure; - if ((dev->wiphy.flags & WIPHY_FLAG_HAS_KEY_MGMT_OFFLOAD) && - (nla_put_u32(msg, NL80211_ATTR_KEY_MGMT_OFFLOAD_SUPPORT, - dev->wiphy.key_mgmt_offload_support) || - nla_put_u32(msg, NL80211_ATTR_KEY_DERIVE_OFFLOAD_SUPPORT, - dev->wiphy.key_derive_offload_support))) - goto nla_put_failure; (*split_start)++; if (split) @@ -7001,12 +6986,6 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) sizeof(connect.vht_capa)); } - if (nla_get_flag(info->attrs[NL80211_ATTR_OFFLOAD_KEY_MGMT])) - connect.flags |= ASSOC_REQ_OFFLOAD_KEY_MGMT; - - if (info->attrs[NL80211_ATTR_PSK]) - connect.psk = nla_data(info->attrs[NL80211_ATTR_PSK]); - err = cfg80211_connect(rdev, dev, &connect, connkeys); if (err) kfree(connkeys); @@ -8733,28 +8712,6 @@ static int nl80211_set_qos_map(struct sk_buff *skb, return ret; } -static int nl80211_key_mgmt_set_pmk(struct sk_buff *skb, struct genl_info *info) -{ - struct cfg80211_registered_device *rdev = info->user_ptr[0]; - struct net_device *dev = info->user_ptr[1]; - u8 *pmk; - size_t pmk_len; - - if (info->attrs[NL80211_ATTR_PMK]) - pmk = nla_data(info->attrs[NL80211_ATTR_PMK]); - else - return -EINVAL; - if (info->attrs[NL80211_ATTR_PMK_LEN]) - pmk_len = nla_get_u32(info->attrs[NL80211_ATTR_PMK_LEN]); - else - return -EINVAL; - - if (!rdev->ops->key_mgmt_set_pmk) - return -EOPNOTSUPP; - - return rdev_key_mgmt_set_pmk(rdev, dev, pmk, pmk_len); -} - #define NL80211_FLAG_NEED_WIPHY 0x01 #define NL80211_FLAG_NEED_NETDEV 0x02 #define NL80211_FLAG_NEED_RTNL 0x04 @@ -9476,14 +9433,6 @@ static struct genl_ops nl80211_ops[] = { .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, - { - .cmd = NL80211_CMD_KEY_MGMT_SET_PMK, - .doit = nl80211_key_mgmt_set_pmk, - .policy = nl80211_policy, - .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | - NL80211_FLAG_NEED_RTNL, - }, }; static struct genl_multicast_group nl80211_mlme_mcgrp = { @@ -11291,127 +11240,6 @@ void cfg80211_ap_stopped(struct net_device *netdev, gfp_t gfp) } EXPORT_SYMBOL(cfg80211_ap_stopped); -void __cfg80211_authorization_event(struct net_device *dev, - enum nl80211_authorization_status auth_status, - const u8 *key_replay_ctr, const u8 *ptk_kck, - const u8 *ptk_kek) -{ - struct wireless_dev *wdev = dev->ieee80211_ptr; - struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); - struct sk_buff *msg; - void *hdr; - int err; - - msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (!msg) - return; - - hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_AUTHORIZATION_EVENT); - if (!hdr) { - nlmsg_free(msg); - return; - } - - if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || - nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || - nla_put_u8(msg, NL80211_ATTR_AUTHORIZATION_STATUS, auth_status) || - nla_put(msg, NL80211_ATTR_KEY_REPLAY_CTR, - NL80211_KEY_REPLAY_CTR_LEN, key_replay_ctr) || - nla_put(msg, NL80211_ATTR_PTK_KCK, NL80211_KEY_LEN_PTK_KCK, - ptk_kck) || - nla_put(msg, NL80211_ATTR_PTK_KEK, NL80211_KEY_LEN_PTK_KEK, - ptk_kek)) - goto nla_put_failure; - - err = genlmsg_end(msg, hdr); - if (err < 0) { - nlmsg_free(msg); - return; - } - - genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, - nl80211_mlme_mcgrp.id, GFP_KERNEL); - return; - -nla_put_failure: - genlmsg_cancel(msg, hdr); - nlmsg_free(msg); -} - -void cfg80211_authorization_event(struct net_device *dev, - enum nl80211_authorization_status auth_status, - const u8 *key_replay_ctr, - gfp_t gfp) -{ - struct wireless_dev *wdev = dev->ieee80211_ptr; - struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); - struct cfg80211_event *ev; - unsigned long flags; - - /* Valid only in SME_CONNECTED state */ - if (wdev->sme_state != CFG80211_SME_CONNECTED) - return; - - ev = kzalloc(sizeof(*ev), gfp); - if (!ev) - return; - - trace_cfg80211_authorization_event(wdev->wiphy, dev, auth_status); - - ev->type = EVENT_AUTHORIZATION; - ev->au.auth_status = auth_status; - memcpy(ev->au.key_replay_ctr, key_replay_ctr, - NL80211_KEY_REPLAY_CTR_LEN); - - spin_lock_irqsave(&wdev->event_lock, flags); - list_add_tail(&ev->list, &wdev->event_list); - spin_unlock_irqrestore(&wdev->event_lock, flags); - queue_work(cfg80211_wq, &rdev->event_work); -} -EXPORT_SYMBOL(cfg80211_authorization_event); - -void cfg80211_key_mgmt_auth(struct net_device *dev, - struct cfg80211_auth_params *auth_params, - gfp_t gfp) -{ - struct wireless_dev *wdev = dev->ieee80211_ptr; - struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); - struct cfg80211_event *ev; - unsigned long flags; - - /* Valid only in SME_CONNECTED state */ - if (wdev->sme_state != CFG80211_SME_CONNECTED) - return; - - ev = kzalloc(sizeof(*ev), gfp); - if (!ev) - return; - - trace_cfg80211_authorization_event(wdev->wiphy, dev, - auth_params->status); - - ev->type = EVENT_AUTHORIZATION; - ev->au.auth_status = auth_params->status; - if (auth_params->key_replay_ctr) { - memcpy(ev->au.key_replay_ctr, auth_params->key_replay_ctr, - NL80211_KEY_REPLAY_CTR_LEN); - } - if (auth_params->ptk_kck) { - memcpy(ev->au.ptk_kck, auth_params->ptk_kck, - NL80211_KEY_LEN_PTK_KCK); - } - if (auth_params->ptk_kek) { - memcpy(ev->au.ptk_kek, auth_params->ptk_kek, - NL80211_KEY_LEN_PTK_KEK); - } - - spin_lock_irqsave(&wdev->event_lock, flags); - list_add_tail(&ev->list, &wdev->event_list); - spin_unlock_irqrestore(&wdev->event_lock, flags); - queue_work(cfg80211_wq, &rdev->event_work); -} -EXPORT_SYMBOL(cfg80211_key_mgmt_auth); - /* initialisation/exit functions */ int nl80211_init(void) diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index 4291a7ff21176..bc1960bac7734 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h @@ -954,17 +954,4 @@ rdev_set_ap_chanwidth(struct cfg80211_registered_device *rdev, return ret; } -static inline int rdev_key_mgmt_set_pmk(struct cfg80211_registered_device *rdev, - struct net_device *dev, u8 *pmk, - size_t pmk_len) -{ - int ret; - - trace_rdev_key_mgmt_set_pmk(&rdev->wiphy, dev, pmk); - ret = rdev->ops->key_mgmt_set_pmk(&rdev->wiphy, dev, pmk, pmk_len); - trace_rdev_return_int(&rdev->wiphy, ret); - - return ret; -} - #endif /* __CFG80211_RDEV_OPS */ diff --git a/net/wireless/reg.c b/net/wireless/reg.c index b99215db7a5f7..527f7a712ae6b 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -712,6 +712,8 @@ static u32 map_regdom_flags(u32 rd_flags) channel_flags |= IEEE80211_CHAN_RADAR; if (rd_flags & NL80211_RRF_NO_OFDM) channel_flags |= IEEE80211_CHAN_NO_OFDM; + if (rd_flags & NL80211_RRF_NO_OUTDOOR) + channel_flags |= IEEE80211_CHAN_INDOOR_ONLY; return channel_flags; } diff --git a/net/wireless/trace.h b/net/wireless/trace.h index d30f7a1048605..bf88313f0a78a 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -2586,29 +2586,6 @@ TRACE_EVENT(cfg80211_ft_event, WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(target_ap)) ); -DEFINE_EVENT(wiphy_netdev_mac_evt, rdev_key_mgmt_set_pmk, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, const u8 *pmk), - TP_ARGS(wiphy, netdev, pmk) -); - -TRACE_EVENT(cfg80211_authorization_event, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - enum nl80211_authorization_status auth_status), - TP_ARGS(wiphy, netdev, auth_status), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - __field(enum nl80211_authorization_status, auth_status) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - __entry->auth_status = auth_status; - ), - TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", auth_status: %d", - WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->auth_status) -); - #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */ #undef TRACE_INCLUDE_PATH diff --git a/net/wireless/util.c b/net/wireless/util.c index 1b6f49020e635..6f093e4da8d87 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -790,13 +790,6 @@ void cfg80211_process_wdev_events(struct wireless_dev *wdev) case EVENT_IBSS_JOINED: __cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid); break; - case EVENT_AUTHORIZATION: - __cfg80211_authorization_event(wdev->netdev, - ev->au.auth_status, - ev->au.key_replay_ctr, - ev->au.ptk_kck, - ev->au.ptk_kek); - break; } wdev_unlock(wdev); diff --git a/security/selinux/avc.c b/security/selinux/avc.c index f3dbbc0f15dd5..386aafb2e69b1 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -49,7 +49,7 @@ struct avc_entry { u32 tsid; u16 tclass; struct av_decision avd; - struct avc_operation_node *ops_node; + struct avc_xperms_node *xp_node; }; struct avc_node { @@ -58,6 +58,16 @@ struct avc_node { struct rcu_head rhead; }; +struct avc_xperms_decision_node { + struct extended_perms_decision xpd; + struct list_head xpd_list; /* list of extended_perms_decision */ +}; + +struct avc_xperms_node { + struct extended_perms xp; + struct list_head xpd_head; /* list head of extended_perms_decision */ +}; + struct avc_cache { struct hlist_head slots[AVC_CACHE_SLOTS]; /* head for avc_node->list */ spinlock_t slots_lock[AVC_CACHE_SLOTS]; /* lock for writes */ @@ -66,16 +76,6 @@ struct avc_cache { u32 latest_notif; /* latest revocation notification */ }; -struct avc_operation_decision_node { - struct operation_decision od; - struct list_head od_list; -}; - -struct avc_operation_node { - struct operation ops; - struct list_head od_head; /* list of operation_decision_node */ -}; - struct avc_callback_node { int (*callback) (u32 event); u32 events; @@ -92,9 +92,9 @@ DEFINE_PER_CPU(struct avc_cache_stats, avc_cache_stats) = { 0 }; static struct avc_cache avc_cache; static struct avc_callback_node *avc_callbacks; static struct kmem_cache *avc_node_cachep; -static struct kmem_cache *avc_operation_decision_node_cachep; -static struct kmem_cache *avc_operation_node_cachep; -static struct kmem_cache *avc_operation_perm_cachep; +static struct kmem_cache *avc_xperms_data_cachep; +static struct kmem_cache *avc_xperms_decision_cachep; +static struct kmem_cache *avc_xperms_cachep; static inline int avc_hash(u32 ssid, u32 tsid, u16 tclass) { @@ -185,17 +185,17 @@ void __init avc_init(void) atomic_set(&avc_cache.lru_hint, 0); avc_node_cachep = kmem_cache_create("avc_node", sizeof(struct avc_node), - 0, SLAB_PANIC, NULL); - avc_operation_node_cachep = kmem_cache_create("avc_operation_node", - sizeof(struct avc_operation_node), - 0, SLAB_PANIC, NULL); - avc_operation_decision_node_cachep = kmem_cache_create( - "avc_operation_decision_node", - sizeof(struct avc_operation_decision_node), - 0, SLAB_PANIC, NULL); - avc_operation_perm_cachep = kmem_cache_create("avc_operation_perm", - sizeof(struct operation_perm), - 0, SLAB_PANIC, NULL); + 0, SLAB_PANIC, NULL); + avc_xperms_cachep = kmem_cache_create("avc_xperms_node", + sizeof(struct avc_xperms_node), + 0, SLAB_PANIC, NULL); + avc_xperms_decision_cachep = kmem_cache_create( + "avc_xperms_decision_node", + sizeof(struct avc_xperms_decision_node), + 0, SLAB_PANIC, NULL); + avc_xperms_data_cachep = kmem_cache_create("avc_xperms_data", + sizeof(struct extended_perms_data), + 0, SLAB_PANIC, NULL); audit_log(current->audit_context, GFP_KERNEL, AUDIT_KERNEL, "AVC INITIALIZED\n"); } @@ -231,222 +231,214 @@ int avc_get_hash_stats(char *page) } /* - * using a linked list for operation_decision lookup because the list is + * using a linked list for extended_perms_decision lookup because the list is * always small. i.e. less than 5, typically 1 */ -static struct operation_decision *avc_operation_lookup(u8 type, - struct avc_operation_node *ops_node) +static struct extended_perms_decision *avc_xperms_decision_lookup(u8 driver, + struct avc_xperms_node *xp_node) { - struct avc_operation_decision_node *od_node; - struct operation_decision *od = NULL; + struct avc_xperms_decision_node *xpd_node; - list_for_each_entry(od_node, &ops_node->od_head, od_list) { - if (od_node->od.type != type) - continue; - od = &od_node->od; - break; + list_for_each_entry(xpd_node, &xp_node->xpd_head, xpd_list) { + if (xpd_node->xpd.driver == driver) + return &xpd_node->xpd; } - return od; + return NULL; } -static inline unsigned int avc_operation_has_perm(struct operation_decision *od, - u16 cmd, u8 specified) +static inline unsigned int +avc_xperms_has_perm(struct extended_perms_decision *xpd, + u8 perm, u8 which) { unsigned int rc = 0; - u8 num = cmd & 0xff; - - if ((specified == OPERATION_ALLOWED) && - (od->specified & OPERATION_ALLOWED)) - rc = security_operation_test(od->allowed->perms, num); - else if ((specified == OPERATION_AUDITALLOW) && - (od->specified & OPERATION_AUDITALLOW)) - rc = security_operation_test(od->auditallow->perms, num); - else if ((specified == OPERATION_DONTAUDIT) && - (od->specified & OPERATION_DONTAUDIT)) - rc = security_operation_test(od->dontaudit->perms, num); + + if ((which == XPERMS_ALLOWED) && + (xpd->used & XPERMS_ALLOWED)) + rc = security_xperm_test(xpd->allowed->p, perm); + else if ((which == XPERMS_AUDITALLOW) && + (xpd->used & XPERMS_AUDITALLOW)) + rc = security_xperm_test(xpd->auditallow->p, perm); + else if ((which == XPERMS_DONTAUDIT) && + (xpd->used & XPERMS_DONTAUDIT)) + rc = security_xperm_test(xpd->dontaudit->p, perm); return rc; } -static void avc_operation_allow_perm(struct avc_operation_node *node, u16 cmd) +static void avc_xperms_allow_perm(struct avc_xperms_node *xp_node, + u8 driver, u8 perm) { - struct operation_decision *od; - u8 type; - u8 num; - - type = cmd >> 8; - num = cmd & 0xff; - security_operation_set(node->ops.type, type); - od = avc_operation_lookup(type, node); - if (od && od->allowed) - security_operation_set(od->allowed->perms, num); + struct extended_perms_decision *xpd; + security_xperm_set(xp_node->xp.drivers.p, driver); + xpd = avc_xperms_decision_lookup(driver, xp_node); + if (xpd && xpd->allowed) + security_xperm_set(xpd->allowed->p, perm); } -static void avc_operation_decision_free( - struct avc_operation_decision_node *od_node) +static void avc_xperms_decision_free(struct avc_xperms_decision_node *xpd_node) { - struct operation_decision *od; - - od = &od_node->od; - if (od->allowed) - kmem_cache_free(avc_operation_perm_cachep, od->allowed); - if (od->auditallow) - kmem_cache_free(avc_operation_perm_cachep, od->auditallow); - if (od->dontaudit) - kmem_cache_free(avc_operation_perm_cachep, od->dontaudit); - kmem_cache_free(avc_operation_decision_node_cachep, od_node); + struct extended_perms_decision *xpd; + + xpd = &xpd_node->xpd; + if (xpd->allowed) + kmem_cache_free(avc_xperms_data_cachep, xpd->allowed); + if (xpd->auditallow) + kmem_cache_free(avc_xperms_data_cachep, xpd->auditallow); + if (xpd->dontaudit) + kmem_cache_free(avc_xperms_data_cachep, xpd->dontaudit); + kmem_cache_free(avc_xperms_decision_cachep, xpd_node); } -static void avc_operation_free(struct avc_operation_node *ops_node) +static void avc_xperms_free(struct avc_xperms_node *xp_node) { - struct avc_operation_decision_node *od_node, *tmp; + struct avc_xperms_decision_node *xpd_node, *tmp; - if (!ops_node) + if (!xp_node) return; - list_for_each_entry_safe(od_node, tmp, &ops_node->od_head, od_list) { - list_del(&od_node->od_list); - avc_operation_decision_free(od_node); + list_for_each_entry_safe(xpd_node, tmp, &xp_node->xpd_head, xpd_list) { + list_del(&xpd_node->xpd_list); + avc_xperms_decision_free(xpd_node); } - kmem_cache_free(avc_operation_node_cachep, ops_node); + kmem_cache_free(avc_xperms_cachep, xp_node); } -static void avc_copy_operation_decision(struct operation_decision *dest, - struct operation_decision *src) +static void avc_copy_xperms_decision(struct extended_perms_decision *dest, + struct extended_perms_decision *src) { - dest->type = src->type; - dest->specified = src->specified; - if (dest->specified & OPERATION_ALLOWED) - memcpy(dest->allowed->perms, src->allowed->perms, - sizeof(src->allowed->perms)); - if (dest->specified & OPERATION_AUDITALLOW) - memcpy(dest->auditallow->perms, src->auditallow->perms, - sizeof(src->auditallow->perms)); - if (dest->specified & OPERATION_DONTAUDIT) - memcpy(dest->dontaudit->perms, src->dontaudit->perms, - sizeof(src->dontaudit->perms)); + dest->driver = src->driver; + dest->used = src->used; + if (dest->used & XPERMS_ALLOWED) + memcpy(dest->allowed->p, src->allowed->p, + sizeof(src->allowed->p)); + if (dest->used & XPERMS_AUDITALLOW) + memcpy(dest->auditallow->p, src->auditallow->p, + sizeof(src->auditallow->p)); + if (dest->used & XPERMS_DONTAUDIT) + memcpy(dest->dontaudit->p, src->dontaudit->p, + sizeof(src->dontaudit->p)); } /* - * similar to avc_copy_operation_decision, but only copy decision - * information relevant to this command + * similar to avc_copy_xperms_decision, but only copy decision + * information relevant to this perm */ -static inline void avc_quick_copy_operation_decision(u16 cmd, - struct operation_decision *dest, - struct operation_decision *src) +static inline void avc_quick_copy_xperms_decision(u8 perm, + struct extended_perms_decision *dest, + struct extended_perms_decision *src) { /* * compute index of the u32 of the 256 bits (8 u32s) that contain this * command permission */ - u8 i = (0xff & cmd) >> 5; - - dest->specified = src->specified; - if (dest->specified & OPERATION_ALLOWED) - dest->allowed->perms[i] = src->allowed->perms[i]; - if (dest->specified & OPERATION_AUDITALLOW) - dest->auditallow->perms[i] = src->auditallow->perms[i]; - if (dest->specified & OPERATION_DONTAUDIT) - dest->dontaudit->perms[i] = src->dontaudit->perms[i]; + u8 i = perm >> 5; + + dest->used = src->used; + if (dest->used & XPERMS_ALLOWED) + dest->allowed->p[i] = src->allowed->p[i]; + if (dest->used & XPERMS_AUDITALLOW) + dest->auditallow->p[i] = src->auditallow->p[i]; + if (dest->used & XPERMS_DONTAUDIT) + dest->dontaudit->p[i] = src->dontaudit->p[i]; } -static struct avc_operation_decision_node - *avc_operation_decision_alloc(u8 specified) +static struct avc_xperms_decision_node + *avc_xperms_decision_alloc(u8 which) { - struct avc_operation_decision_node *node; - struct operation_decision *od; + struct avc_xperms_decision_node *xpd_node; + struct extended_perms_decision *xpd; - node = kmem_cache_zalloc(avc_operation_decision_node_cachep, + xpd_node = kmem_cache_zalloc(avc_xperms_decision_cachep, GFP_ATOMIC | __GFP_NOMEMALLOC); - if (!node) + if (!xpd_node) return NULL; - od = &node->od; - if (specified & OPERATION_ALLOWED) { - od->allowed = kmem_cache_zalloc(avc_operation_perm_cachep, + xpd = &xpd_node->xpd; + if (which & XPERMS_ALLOWED) { + xpd->allowed = kmem_cache_zalloc(avc_xperms_data_cachep, GFP_ATOMIC | __GFP_NOMEMALLOC); - if (!od->allowed) + if (!xpd->allowed) goto error; } - if (specified & OPERATION_AUDITALLOW) { - od->auditallow = kmem_cache_zalloc(avc_operation_perm_cachep, + if (which & XPERMS_AUDITALLOW) { + xpd->auditallow = kmem_cache_zalloc(avc_xperms_data_cachep, GFP_ATOMIC | __GFP_NOMEMALLOC); - if (!od->auditallow) + if (!xpd->auditallow) goto error; } - if (specified & OPERATION_DONTAUDIT) { - od->dontaudit = kmem_cache_zalloc(avc_operation_perm_cachep, + if (which & XPERMS_DONTAUDIT) { + xpd->dontaudit = kmem_cache_zalloc(avc_xperms_data_cachep, GFP_ATOMIC | __GFP_NOMEMALLOC); - if (!od->dontaudit) + if (!xpd->dontaudit) goto error; } - return node; + return xpd_node; error: - avc_operation_decision_free(node); + avc_xperms_decision_free(xpd_node); return NULL; } -static int avc_add_operation(struct avc_node *node, - struct operation_decision *od) +static int avc_add_xperms_decision(struct avc_node *node, + struct extended_perms_decision *src) { - struct avc_operation_decision_node *dest_od; + struct avc_xperms_decision_node *dest_xpd; - node->ae.ops_node->ops.len++; - dest_od = avc_operation_decision_alloc(od->specified); - if (!dest_od) + node->ae.xp_node->xp.len++; + dest_xpd = avc_xperms_decision_alloc(src->used); + if (!dest_xpd) return -ENOMEM; - avc_copy_operation_decision(&dest_od->od, od); - list_add(&dest_od->od_list, &node->ae.ops_node->od_head); + avc_copy_xperms_decision(&dest_xpd->xpd, src); + list_add(&dest_xpd->xpd_list, &node->ae.xp_node->xpd_head); return 0; } -static struct avc_operation_node *avc_operation_alloc(void) +static struct avc_xperms_node *avc_xperms_alloc(void) { - struct avc_operation_node *ops; + struct avc_xperms_node *xp_node; - ops = kmem_cache_zalloc(avc_operation_node_cachep, + xp_node = kmem_cache_zalloc(avc_xperms_cachep, GFP_ATOMIC|__GFP_NOMEMALLOC); - if (!ops) - return ops; - INIT_LIST_HEAD(&ops->od_head); - return ops; + if (!xp_node) + return xp_node; + INIT_LIST_HEAD(&xp_node->xpd_head); + return xp_node; } -static int avc_operation_populate(struct avc_node *node, - struct avc_operation_node *src) +static int avc_xperms_populate(struct avc_node *node, + struct avc_xperms_node *src) { - struct avc_operation_node *dest; - struct avc_operation_decision_node *dest_od; - struct avc_operation_decision_node *src_od; + struct avc_xperms_node *dest; + struct avc_xperms_decision_node *dest_xpd; + struct avc_xperms_decision_node *src_xpd; - if (src->ops.len == 0) + if (src->xp.len == 0) return 0; - dest = avc_operation_alloc(); + dest = avc_xperms_alloc(); if (!dest) return -ENOMEM; - memcpy(dest->ops.type, &src->ops.type, sizeof(dest->ops.type)); - dest->ops.len = src->ops.len; + memcpy(dest->xp.drivers.p, src->xp.drivers.p, sizeof(dest->xp.drivers.p)); + dest->xp.len = src->xp.len; - /* for each source od allocate a destination od and copy */ - list_for_each_entry(src_od, &src->od_head, od_list) { - dest_od = avc_operation_decision_alloc(src_od->od.specified); - if (!dest_od) + /* for each source xpd allocate a destination xpd and copy */ + list_for_each_entry(src_xpd, &src->xpd_head, xpd_list) { + dest_xpd = avc_xperms_decision_alloc(src_xpd->xpd.used); + if (!dest_xpd) goto error; - avc_copy_operation_decision(&dest_od->od, &src_od->od); - list_add(&dest_od->od_list, &dest->od_head); + avc_copy_xperms_decision(&dest_xpd->xpd, &src_xpd->xpd); + list_add(&dest_xpd->xpd_list, &dest->xpd_head); } - node->ae.ops_node = dest; + node->ae.xp_node = dest; return 0; error: - avc_operation_free(dest); + avc_xperms_free(dest); return -ENOMEM; } -static inline u32 avc_operation_audit_required(u32 requested, +static inline u32 avc_xperms_audit_required(u32 requested, struct av_decision *avd, - struct operation_decision *od, - u16 cmd, + struct extended_perms_decision *xpd, + u8 perm, int result, u32 *deniedp) { @@ -455,18 +447,16 @@ static inline u32 avc_operation_audit_required(u32 requested, denied = requested & ~avd->allowed; if (unlikely(denied)) { audited = denied & avd->auditdeny; - if (audited && od) { - if (avc_operation_has_perm(od, cmd, - OPERATION_DONTAUDIT)) + if (audited && xpd) { + if (avc_xperms_has_perm(xpd, perm, XPERMS_DONTAUDIT)) audited &= ~requested; } } else if (result) { audited = denied = requested; } else { audited = requested & avd->auditallow; - if (audited && od) { - if (!avc_operation_has_perm(od, cmd, - OPERATION_AUDITALLOW)) + if (audited && xpd) { + if (!avc_xperms_has_perm(xpd, perm, XPERMS_AUDITALLOW)) audited &= ~requested; } } @@ -475,16 +465,16 @@ static inline u32 avc_operation_audit_required(u32 requested, return audited; } -static inline int avc_operation_audit(u32 ssid, u32 tsid, u16 tclass, +static inline int avc_xperms_audit(u32 ssid, u32 tsid, u16 tclass, u32 requested, struct av_decision *avd, - struct operation_decision *od, - u16 cmd, int result, + struct extended_perms_decision *xpd, + u8 perm, int result, struct common_audit_data *ad) { u32 audited, denied; - audited = avc_operation_audit_required( - requested, avd, od, cmd, result, &denied); + audited = avc_xperms_audit_required( + requested, avd, xpd, perm, result, &denied); if (likely(!audited)) return 0; return slow_avc_audit(ssid, tsid, tclass, requested, @@ -494,7 +484,7 @@ static inline int avc_operation_audit(u32 ssid, u32 tsid, u16 tclass, static void avc_node_free(struct rcu_head *rhead) { struct avc_node *node = container_of(rhead, struct avc_node, rhead); - avc_operation_free(node->ae.ops_node); + avc_xperms_free(node->ae.xp_node); kmem_cache_free(avc_node_cachep, node); avc_cache_stats_incr(frees); } @@ -508,7 +498,7 @@ static void avc_node_delete(struct avc_node *node) static void avc_node_kill(struct avc_node *node) { - avc_operation_free(node->ae.ops_node); + avc_xperms_free(node->ae.xp_node); kmem_cache_free(avc_node_cachep, node); avc_cache_stats_incr(frees); atomic_dec(&avc_cache.active_nodes); @@ -655,7 +645,7 @@ static int avc_latest_notif_update(int seqno, int is_insert) * @tsid: target security identifier * @tclass: target security class * @avd: resulting av decision - * @ops: resulting operation decisions + * @xp_node: resulting extended permissions * * Insert an AVC entry for the SID pair * (@ssid, @tsid) and class @tclass. @@ -669,7 +659,7 @@ static int avc_latest_notif_update(int seqno, int is_insert) */ static struct avc_node *avc_insert(u32 ssid, u32 tsid, u16 tclass, struct av_decision *avd, - struct avc_operation_node *ops_node) + struct avc_xperms_node *xp_node) { struct avc_node *pos, *node = NULL; int hvalue; @@ -686,7 +676,7 @@ static struct avc_node *avc_insert(u32 ssid, u32 tsid, u16 tclass, hvalue = avc_hash(ssid, tsid, tclass); avc_node_populate(node, ssid, tsid, tclass, avd); - rc = avc_operation_populate(node, ops_node); + rc = avc_xperms_populate(node, xp_node); if (rc) { kmem_cache_free(avc_node_cachep, node); return NULL; @@ -824,16 +814,16 @@ static inline int avc_sidcmp(u32 x, u32 y) * @perms : Permission mask bits * @ssid,@tsid,@tclass : identifier of an AVC entry * @seqno : sequence number when decision was made - * @od: operation_decision to be added to the node + * @xpd: extended_perms_decision to be added to the node * * if a valid AVC entry doesn't exist,this function returns -ENOENT. * if kmalloc() called internal returns NULL, this function returns -ENOMEM. * otherwise, this function updates the AVC entry. The original AVC-entry object * will release later by RCU. */ -static int avc_update_node(u32 event, u32 perms, u16 cmd, u32 ssid, u32 tsid, - u16 tclass, u32 seqno, - struct operation_decision *od, +static int avc_update_node(u32 event, u32 perms, u8 driver, u8 xperm, u32 ssid, + u32 tsid, u16 tclass, u32 seqno, + struct extended_perms_decision *xpd, u32 flags) { int hvalue, rc = 0; @@ -878,8 +868,8 @@ static int avc_update_node(u32 event, u32 perms, u16 cmd, u32 ssid, u32 tsid, avc_node_populate(node, ssid, tsid, tclass, &orig->ae.avd); - if (orig->ae.ops_node) { - rc = avc_operation_populate(node, orig->ae.ops_node); + if (orig->ae.xp_node) { + rc = avc_xperms_populate(node, orig->ae.xp_node); if (rc) { kmem_cache_free(avc_node_cachep, node); goto out_unlock; @@ -889,8 +879,8 @@ static int avc_update_node(u32 event, u32 perms, u16 cmd, u32 ssid, u32 tsid, switch (event) { case AVC_CALLBACK_GRANT: node->ae.avd.allowed |= perms; - if (node->ae.ops_node && (flags & AVC_OPERATION_CMD)) - avc_operation_allow_perm(node->ae.ops_node, cmd); + if (node->ae.xp_node && (flags & AVC_EXTENDED_PERMS)) + avc_xperms_allow_perm(node->ae.xp_node, driver, xperm); break; case AVC_CALLBACK_TRY_REVOKE: case AVC_CALLBACK_REVOKE: @@ -908,8 +898,8 @@ static int avc_update_node(u32 event, u32 perms, u16 cmd, u32 ssid, u32 tsid, case AVC_CALLBACK_AUDITDENY_DISABLE: node->ae.avd.auditdeny &= ~perms; break; - case AVC_CALLBACK_ADD_OPERATION: - avc_add_operation(node, od); + case AVC_CALLBACK_ADD_XPERMS: + avc_add_xperms_decision(node, xpd); break; } avc_node_replace(node, orig); @@ -983,18 +973,18 @@ int avc_ss_reset(u32 seqno) */ static noinline struct avc_node *avc_compute_av(u32 ssid, u32 tsid, u16 tclass, struct av_decision *avd, - struct avc_operation_node *ops_node) + struct avc_xperms_node *xp_node) { rcu_read_unlock(); - INIT_LIST_HEAD(&ops_node->od_head); - security_compute_av(ssid, tsid, tclass, avd, &ops_node->ops); + INIT_LIST_HEAD(&xp_node->xpd_head); + security_compute_av(ssid, tsid, tclass, avd, &xp_node->xp); rcu_read_lock(); - return avc_insert(ssid, tsid, tclass, avd, ops_node); + return avc_insert(ssid, tsid, tclass, avd, xp_node); } static noinline int avc_denied(u32 ssid, u32 tsid, u16 tclass, u32 requested, - u16 cmd, unsigned flags, + u8 driver, u8 xperm, unsigned flags, struct av_decision *avd) { if (flags & AVC_STRICT) @@ -1003,88 +993,87 @@ static noinline int avc_denied(u32 ssid, u32 tsid, if (selinux_enforcing && !(avd->flags & AVD_FLAGS_PERMISSIVE)) return -EACCES; - avc_update_node(AVC_CALLBACK_GRANT, requested, cmd, ssid, + avc_update_node(AVC_CALLBACK_GRANT, requested, driver, xperm, ssid, tsid, tclass, avd->seqno, NULL, flags); return 0; } /* - * ioctl commands are comprised of four fields, direction, size, type, and - * number. The avc operation logic filters based on two of them: - * - * type: or code, typically unique to each driver - * number: or function - * - * For example, 0x89 is a socket type, and number 0x27 is the get hardware - * address function. + * The avc extended permissions logic adds an additional 256 bits of + * permissions to an avc node when extended permissions for that node are + * specified in the avtab. If the additional 256 permissions is not adequate, + * as-is the case with ioctls, then multiple may be chained together and the + * driver field is used to specify which set contains the permission. */ -int avc_has_operation(u32 ssid, u32 tsid, u16 tclass, u32 requested, - u16 cmd, struct common_audit_data *ad) +int avc_has_extended_perms(u32 ssid, u32 tsid, u16 tclass, u32 requested, + u8 driver, u8 xperm, struct common_audit_data *ad) { struct avc_node *node; struct av_decision avd; u32 denied; - struct operation_decision *od = NULL; - struct operation_decision od_local; - struct operation_perm allowed; - struct operation_perm auditallow; - struct operation_perm dontaudit; - struct avc_operation_node local_ops_node; - struct avc_operation_node *ops_node; - u8 type = cmd >> 8; + struct extended_perms_decision local_xpd; + struct extended_perms_decision *xpd = NULL; + struct extended_perms_data allowed; + struct extended_perms_data auditallow; + struct extended_perms_data dontaudit; + struct avc_xperms_node local_xp_node; + struct avc_xperms_node *xp_node; int rc = 0, rc2; - ops_node = &local_ops_node; + xp_node = &local_xp_node; BUG_ON(!requested); rcu_read_lock(); node = avc_lookup(ssid, tsid, tclass); if (unlikely(!node)) { - node = avc_compute_av(ssid, tsid, tclass, &avd, ops_node); + node = avc_compute_av(ssid, tsid, tclass, &avd, xp_node); } else { memcpy(&avd, &node->ae.avd, sizeof(avd)); - ops_node = node->ae.ops_node; + xp_node = node->ae.xp_node; } - /* if operations are not defined, only consider av_decision */ - if (!ops_node || !ops_node->ops.len) + /* if extended permissions are not defined, only consider av_decision */ + if (!xp_node || !xp_node->xp.len) goto decision; - od_local.allowed = &allowed; - od_local.auditallow = &auditallow; - od_local.dontaudit = &dontaudit; + local_xpd.allowed = &allowed; + local_xpd.auditallow = &auditallow; + local_xpd.dontaudit = &dontaudit; - /* lookup operation decision */ - od = avc_operation_lookup(type, ops_node); - if (unlikely(!od)) { - /* Compute operation decision if type is flagged */ - if (!security_operation_test(ops_node->ops.type, type)) { + xpd = avc_xperms_decision_lookup(driver, xp_node); + if (unlikely(!xpd)) { + /* + * Compute the extended_perms_decision only if the driver + * is flagged + */ + if (!security_xperm_test(xp_node->xp.drivers.p, driver)) { avd.allowed &= ~requested; goto decision; } rcu_read_unlock(); - security_compute_operation(ssid, tsid, tclass, type, &od_local); + security_compute_xperms_decision(ssid, tsid, tclass, driver, + &local_xpd); rcu_read_lock(); - avc_update_node(AVC_CALLBACK_ADD_OPERATION, requested, cmd, - ssid, tsid, tclass, avd.seqno, &od_local, 0); + avc_update_node(AVC_CALLBACK_ADD_XPERMS, requested, driver, xperm, + ssid, tsid, tclass, avd.seqno, &local_xpd, 0); } else { - avc_quick_copy_operation_decision(cmd, &od_local, od); + avc_quick_copy_xperms_decision(xperm, &local_xpd, xpd); } - od = &od_local; + xpd = &local_xpd; - if (!avc_operation_has_perm(od, cmd, OPERATION_ALLOWED)) + if (!avc_xperms_has_perm(xpd, xperm, XPERMS_ALLOWED)) avd.allowed &= ~requested; decision: denied = requested & ~(avd.allowed); if (unlikely(denied)) - rc = avc_denied(ssid, tsid, tclass, requested, cmd, - AVC_OPERATION_CMD, &avd); + rc = avc_denied(ssid, tsid, tclass, requested, driver, xperm, + AVC_EXTENDED_PERMS, &avd); rcu_read_unlock(); - rc2 = avc_operation_audit(ssid, tsid, tclass, requested, - &avd, od, cmd, rc, ad); + rc2 = avc_xperms_audit(ssid, tsid, tclass, requested, + &avd, xpd, xperm, rc, ad); if (rc2) return rc2; return rc; @@ -1116,7 +1105,7 @@ inline int avc_has_perm_noaudit(u32 ssid, u32 tsid, struct av_decision *avd) { struct avc_node *node; - struct avc_operation_node ops_node; + struct avc_xperms_node xp_node; int rc = 0; u32 denied; @@ -1126,13 +1115,13 @@ inline int avc_has_perm_noaudit(u32 ssid, u32 tsid, node = avc_lookup(ssid, tsid, tclass); if (unlikely(!node)) - node = avc_compute_av(ssid, tsid, tclass, avd, &ops_node); + node = avc_compute_av(ssid, tsid, tclass, avd, &xp_node); else memcpy(avd, &node->ae.avd, sizeof(*avd)); denied = requested & ~(avd->allowed); if (unlikely(denied)) - rc = avc_denied(ssid, tsid, tclass, requested, 0, flags, avd); + rc = avc_denied(ssid, tsid, tclass, requested, 0, 0, flags, avd); rcu_read_unlock(); return rc; diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 0089fea50249a..14ca80cb0ec15 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -432,8 +432,11 @@ static int sb_finish_set_opts(struct super_block *sb) sbsec->behavior > ARRAY_SIZE(labeling_behaviors)) sbsec->flags &= ~SE_SBLABELSUPP; - /* Special handling for sysfs. Is genfs but also has setxattr handler*/ - if (strncmp(sb->s_type->name, "sysfs", sizeof("sysfs")) == 0) + /* Special handling. Is genfs but also has in-core setxattr handler*/ + if (!strcmp(sb->s_type->name, "sysfs") || + !strcmp(sb->s_type->name, "pstore") || + !strcmp(sb->s_type->name, "debugfs") || + !strcmp(sb->s_type->name, "rootfs")) sbsec->flags |= SE_SBLABELSUPP; /* @@ -2863,7 +2866,8 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET)) return dentry_has_perm(cred, dentry, FILE__SETATTR); - if (selinux_policycap_openperm && (ia_valid & ATTR_SIZE)) + if (selinux_policycap_openperm && (ia_valid & ATTR_SIZE) + && !(ia_valid & ATTR_FILE)) av |= FILE__OPEN; return dentry_has_perm(cred, dentry, av); @@ -3172,6 +3176,8 @@ int ioctl_has_perm(const struct cred *cred, struct file *file, struct lsm_ioctlop_audit ioctl; u32 ssid = cred_sid(cred); int rc; + u8 driver = cmd >> 8; + u8 xperm = cmd & 0xff; ad.type = LSM_AUDIT_DATA_IOCTL_OP; ad.u.op = &ioctl; @@ -3190,8 +3196,8 @@ int ioctl_has_perm(const struct cred *cred, struct file *file, if (unlikely(IS_PRIVATE(inode))) return 0; - rc = avc_has_operation(ssid, isec->sid, isec->sclass, - requested, cmd, &ad); + rc = avc_has_extended_perms(ssid, isec->sid, isec->sclass, + requested, driver, xperm, &ad); out: return rc; } diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h index 8109ad846e996..6d65f77fd8008 100644 --- a/security/selinux/include/avc.h +++ b/security/selinux/include/avc.h @@ -142,15 +142,12 @@ static inline int avc_audit(u32 ssid, u32 tsid, } #define AVC_STRICT 1 /* Ignore permissive mode. */ -#define AVC_OPERATION_CMD 2 /* ignore command when updating operations */ +#define AVC_EXTENDED_PERMS 2 /* update extended permissions */ int avc_has_perm_noaudit(u32 ssid, u32 tsid, u16 tclass, u32 requested, unsigned flags, struct av_decision *avd); -int avc_has_operation(u32 ssid, u32 tsid, u16 tclass, u32 requested, - u16 cmd, struct common_audit_data *ad); - int avc_has_perm_flags(u32 ssid, u32 tsid, u16 tclass, u32 requested, struct common_audit_data *auditdata, @@ -163,6 +160,9 @@ static inline int avc_has_perm(u32 ssid, u32 tsid, return avc_has_perm_flags(ssid, tsid, tclass, requested, auditdata, 0); } +int avc_has_extended_perms(u32 ssid, u32 tsid, u16 tclass, u32 requested, + u8 driver, u8 perm, struct common_audit_data *ad); + u32 avc_policy_seqno(void); #define AVC_CALLBACK_GRANT 1 @@ -173,7 +173,7 @@ u32 avc_policy_seqno(void); #define AVC_CALLBACK_AUDITALLOW_DISABLE 32 #define AVC_CALLBACK_AUDITDENY_ENABLE 64 #define AVC_CALLBACK_AUDITDENY_DISABLE 128 -#define AVC_CALLBACK_ADD_OPERATION 256 +#define AVC_CALLBACK_ADD_XPERMS 256 int avc_add_callback(int (*callback)(u32 event), u32 events); diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index e72d8de93725a..eb25aa9fb3135 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -34,14 +34,14 @@ #define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS 27 #define POLICYDB_VERSION_DEFAULT_TYPE 28 #define POLICYDB_VERSION_CONSTRAINT_NAMES 29 -#define POLICYDB_VERSION_IOCTL_OPERATIONS 30 +#define POLICYDB_VERSION_XPERMS_IOCTL 30 /* Range of policy versions we understand*/ #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX #define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE #else -#define POLICYDB_VERSION_MAX POLICYDB_VERSION_IOCTL_OPERATIONS +#define POLICYDB_VERSION_MAX POLICYDB_VERSION_XPERMS_IOCTL #endif /* Mask for just the mount related flags */ @@ -104,29 +104,27 @@ struct av_decision { u32 flags; }; -#define security_operation_set(perms, x) (perms[x >> 5] |= 1 << (x & 0x1f)) -#define security_operation_test(perms, x) (1 & (perms[x >> 5] >> (x & 0x1f))) +#define XPERMS_ALLOWED 1 +#define XPERMS_AUDITALLOW 2 +#define XPERMS_DONTAUDIT 4 -struct operation_perm { - u32 perms[8]; +#define security_xperm_set(perms, x) (perms[x >> 5] |= 1 << (x & 0x1f)) +#define security_xperm_test(perms, x) (1 & (perms[x >> 5] >> (x & 0x1f))) +struct extended_perms_data { + u32 p[8]; }; -struct operation_decision { - u8 type; - u8 specified; - struct operation_perm *allowed; - struct operation_perm *auditallow; - struct operation_perm *dontaudit; +struct extended_perms_decision { + u8 used; + u8 driver; + struct extended_perms_data *allowed; + struct extended_perms_data *auditallow; + struct extended_perms_data *dontaudit; }; -#define OPERATION_ALLOWED 1 -#define OPERATION_AUDITALLOW 2 -#define OPERATION_DONTAUDIT 4 -#define OPERATION_ALL (OPERATION_ALLOWED | OPERATION_AUDITALLOW |\ - OPERATION_DONTAUDIT) -struct operation { - u16 len; /* length of operation decision chain */ - u32 type[8]; /* 256 types */ +struct extended_perms { + u16 len; /* length associated decision chain */ + struct extended_perms_data drivers; /* flag drivers that are used */ }; /* definitions of av_decision.flags */ @@ -134,10 +132,10 @@ struct operation { void security_compute_av(u32 ssid, u32 tsid, u16 tclass, struct av_decision *avd, - struct operation *ops); + struct extended_perms *xperms); -void security_compute_operation(u32 ssid, u32 tsid, u16 tclass, - u8 type, struct operation_decision *od); +void security_compute_xperms_decision(u32 ssid, u32 tsid, u16 tclass, + u8 driver, struct extended_perms_decision *xpermd); void security_compute_av_user(u32 ssid, u32 tsid, u16 tclass, struct av_decision *avd); diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c index 855e464e92efb..a619a235a3ebd 100644 --- a/security/selinux/nlmsgtab.c +++ b/security/selinux/nlmsgtab.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "flask.h" #include "av_permissions.h" @@ -76,8 +77,10 @@ static struct nlmsg_perm nlmsg_route_perms[] = static struct nlmsg_perm nlmsg_tcpdiag_perms[] = { - { TCPDIAG_GETSOCK, NETLINK_TCPDIAG_SOCKET__NLMSG_READ }, - { DCCPDIAG_GETSOCK, NETLINK_TCPDIAG_SOCKET__NLMSG_READ }, + { TCPDIAG_GETSOCK, NETLINK_TCPDIAG_SOCKET__NLMSG_READ }, + { DCCPDIAG_GETSOCK, NETLINK_TCPDIAG_SOCKET__NLMSG_READ }, + { SOCK_DIAG_BY_FAMILY, NETLINK_TCPDIAG_SOCKET__NLMSG_READ }, + { SOCK_DESTROY_BACKPORT, NETLINK_TCPDIAG_SOCKET__NLMSG_WRITE }, }; static struct nlmsg_perm nlmsg_xfrm_perms[] = diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c index dd7466cb2021d..640c16b9d3fb7 100644 --- a/security/selinux/ss/avtab.c +++ b/security/selinux/ss/avtab.c @@ -24,7 +24,7 @@ #include "policydb.h" static struct kmem_cache *avtab_node_cachep; -static struct kmem_cache *avtab_operation_cachep; +static struct kmem_cache *avtab_xperms_cachep; static inline int avtab_hash(struct avtab_key *keyp, u16 mask) { @@ -38,20 +38,20 @@ avtab_insert_node(struct avtab *h, int hvalue, struct avtab_key *key, struct avtab_datum *datum) { struct avtab_node *newnode; - struct avtab_operation *ops; + struct avtab_extended_perms *xperms; newnode = kmem_cache_zalloc(avtab_node_cachep, GFP_KERNEL); if (newnode == NULL) return NULL; newnode->key = *key; - if (key->specified & AVTAB_OP) { - ops = kmem_cache_zalloc(avtab_operation_cachep, GFP_KERNEL); - if (ops == NULL) { + if (key->specified & AVTAB_XPERMS) { + xperms = kmem_cache_zalloc(avtab_xperms_cachep, GFP_KERNEL); + if (xperms == NULL) { kmem_cache_free(avtab_node_cachep, newnode); return NULL; } - *ops = *(datum->u.ops); - newnode->datum.u.ops = ops; + *xperms = *(datum->u.xperms); + newnode->datum.u.xperms = xperms; } else { newnode->datum.u.data = datum->u.data; } @@ -85,7 +85,8 @@ static int avtab_insert(struct avtab *h, struct avtab_key *key, struct avtab_dat key->target_type == cur->key.target_type && key->target_class == cur->key.target_class && (specified & cur->key.specified)) { - if (specified & AVTAB_OPNUM) + /* extended perms may not be unique */ + if (specified & AVTAB_XPERMS) break; return -EEXIST; } @@ -249,9 +250,9 @@ void avtab_destroy(struct avtab *h) while (cur) { temp = cur; cur = cur->next; - if (temp->key.specified & AVTAB_OP) - kmem_cache_free(avtab_operation_cachep, - temp->datum.u.ops); + if (temp->key.specified & AVTAB_XPERMS) + kmem_cache_free(avtab_xperms_cachep, + temp->datum.u.xperms); kmem_cache_free(avtab_node_cachep, temp); } h->htable[i] = NULL; @@ -334,6 +335,32 @@ void avtab_hash_eval(struct avtab *h, char *tag) chain2_len_sum); } +/* + * extended permissions compatibility. Make ToT Android kernels compatible + * with Android M releases + */ +#define AVTAB_OPTYPE_ALLOWED 0x1000 +#define AVTAB_OPTYPE_AUDITALLOW 0x2000 +#define AVTAB_OPTYPE_DONTAUDIT 0x4000 +#define AVTAB_OPTYPE (AVTAB_OPTYPE_ALLOWED | \ + AVTAB_OPTYPE_AUDITALLOW | \ + AVTAB_OPTYPE_DONTAUDIT) +#define AVTAB_XPERMS_OPTYPE 4 + +#define avtab_xperms_to_optype(x) (x << AVTAB_XPERMS_OPTYPE) +#define avtab_optype_to_xperms(x) (x >> AVTAB_XPERMS_OPTYPE) + +static unsigned int avtab_android_m_compat; + +static void avtab_android_m_compat_set(void) +{ + if (!avtab_android_m_compat) { + pr_info("SELinux: Android master kernel running Android" + " M policy in compatibility mode.\n"); + avtab_android_m_compat = 1; + } +} + static uint16_t spec_order[] = { AVTAB_ALLOWED, AVTAB_AUDITDENY, @@ -341,12 +368,9 @@ static uint16_t spec_order[] = { AVTAB_TRANSITION, AVTAB_CHANGE, AVTAB_MEMBER, - AVTAB_OPNUM_ALLOWED, - AVTAB_OPNUM_AUDITALLOW, - AVTAB_OPNUM_DONTAUDIT, - AVTAB_OPTYPE_ALLOWED, - AVTAB_OPTYPE_AUDITALLOW, - AVTAB_OPTYPE_DONTAUDIT + AVTAB_XPERMS_ALLOWED, + AVTAB_XPERMS_AUDITALLOW, + AVTAB_XPERMS_DONTAUDIT }; int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, @@ -359,8 +383,9 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, u32 items, items2, val, vers = pol->policyvers; struct avtab_key key; struct avtab_datum datum; - struct avtab_operation ops; - __le32 buf32[ARRAY_SIZE(ops.op.perms)]; + struct avtab_extended_perms xperms; + __le32 buf32[ARRAY_SIZE(xperms.perms.p)]; + unsigned int android_m_compat_optype = 0; int i, rc; unsigned set; @@ -417,8 +442,8 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, printk(KERN_ERR "SELinux: avtab: entry has both access vectors and types\n"); return -EINVAL; } - if (val & AVTAB_OP) { - printk(KERN_ERR "SELinux: avtab: entry has operations\n"); + if (val & AVTAB_XPERMS) { + printk(KERN_ERR "SELinux: avtab: entry has extended permissions\n"); return -EINVAL; } @@ -444,12 +469,20 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, printk(KERN_ERR "SELinux: avtab: truncated entry\n"); return rc; } + items = 0; key.source_type = le16_to_cpu(buf16[items++]); key.target_type = le16_to_cpu(buf16[items++]); key.target_class = le16_to_cpu(buf16[items++]); key.specified = le16_to_cpu(buf16[items++]); + if ((key.specified & AVTAB_OPTYPE) && + (vers == POLICYDB_VERSION_XPERMS_IOCTL)) { + key.specified = avtab_optype_to_xperms(key.specified); + android_m_compat_optype = 1; + avtab_android_m_compat_set(); + } + if (!policydb_type_isvalid(pol, key.source_type) || !policydb_type_isvalid(pol, key.target_type) || !policydb_class_isvalid(pol, key.target_class)) { @@ -467,29 +500,51 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, return -EINVAL; } - if ((vers < POLICYDB_VERSION_IOCTL_OPERATIONS) - || !(key.specified & AVTAB_OP)) { - rc = next_entry(buf32, fp, sizeof(u32)); + if ((vers < POLICYDB_VERSION_XPERMS_IOCTL) && + (key.specified & AVTAB_XPERMS)) { + printk(KERN_ERR "SELinux: avtab: policy version %u does not " + "support extended permissions rules and one " + "was specified\n", vers); + return -EINVAL; + } else if (key.specified & AVTAB_XPERMS) { + memset(&xperms, 0, sizeof(struct avtab_extended_perms)); + rc = next_entry(&xperms.specified, fp, sizeof(u8)); if (rc) { printk(KERN_ERR "SELinux: avtab: truncated entry\n"); return rc; } - datum.u.data = le32_to_cpu(*buf32); - } else { - memset(&ops, 0, sizeof(struct avtab_operation)); - rc = next_entry(&ops.type, fp, sizeof(u8)); + if (avtab_android_m_compat || + ((xperms.specified != AVTAB_XPERMS_IOCTLFUNCTION) && + (xperms.specified != AVTAB_XPERMS_IOCTLDRIVER) && + (vers == POLICYDB_VERSION_XPERMS_IOCTL))) { + xperms.driver = xperms.specified; + if (android_m_compat_optype) + xperms.specified = AVTAB_XPERMS_IOCTLDRIVER; + else + xperms.specified = AVTAB_XPERMS_IOCTLFUNCTION; + avtab_android_m_compat_set(); + } else { + rc = next_entry(&xperms.driver, fp, sizeof(u8)); + if (rc) { + printk(KERN_ERR "SELinux: avtab: truncated entry\n"); + return rc; + } + } + rc = next_entry(buf32, fp, sizeof(u32)*ARRAY_SIZE(xperms.perms.p)); if (rc) { printk(KERN_ERR "SELinux: avtab: truncated entry\n"); return rc; } - rc = next_entry(buf32, fp, sizeof(u32)*ARRAY_SIZE(ops.op.perms)); + for (i = 0; i < ARRAY_SIZE(xperms.perms.p); i++) + xperms.perms.p[i] = le32_to_cpu(buf32[i]); + datum.u.xperms = &xperms; + } else { + rc = next_entry(buf32, fp, sizeof(u32)); if (rc) { printk(KERN_ERR "SELinux: avtab: truncated entry\n"); return rc; } - for (i = 0; i < ARRAY_SIZE(ops.op.perms); i++) - ops.op.perms[i] = le32_to_cpu(buf32[i]); - datum.u.ops = &ops; + datum.u.data = le32_to_cpu(*buf32); } if ((key.specified & AVTAB_TYPE) && !policydb_type_isvalid(pol, datum.u.data)) { @@ -552,26 +607,36 @@ int avtab_read(struct avtab *a, void *fp, struct policydb *pol) int avtab_write_item(struct policydb *p, struct avtab_node *cur, void *fp) { __le16 buf16[4]; - __le32 buf32[ARRAY_SIZE(cur->datum.u.ops->op.perms)]; + __le32 buf32[ARRAY_SIZE(cur->datum.u.xperms->perms.p)]; int rc; unsigned int i; buf16[0] = cpu_to_le16(cur->key.source_type); buf16[1] = cpu_to_le16(cur->key.target_type); buf16[2] = cpu_to_le16(cur->key.target_class); - buf16[3] = cpu_to_le16(cur->key.specified); + if (avtab_android_m_compat && (cur->key.specified & AVTAB_XPERMS) && + (cur->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLDRIVER)) + buf16[3] = cpu_to_le16(avtab_xperms_to_optype(cur->key.specified)); + else + buf16[3] = cpu_to_le16(cur->key.specified); rc = put_entry(buf16, sizeof(u16), 4, fp); if (rc) return rc; - if (cur->key.specified & AVTAB_OP) { - rc = put_entry(&cur->datum.u.ops->type, sizeof(u8), 1, fp); + if (cur->key.specified & AVTAB_XPERMS) { + if (avtab_android_m_compat == 0) { + rc = put_entry(&cur->datum.u.xperms->specified, + sizeof(u8), 1, fp); + if (rc) + return rc; + } + rc = put_entry(&cur->datum.u.xperms->driver, sizeof(u8), 1, fp); if (rc) return rc; - for (i = 0; i < ARRAY_SIZE(cur->datum.u.ops->op.perms); i++) - buf32[i] = cpu_to_le32(cur->datum.u.ops->op.perms[i]); + for (i = 0; i < ARRAY_SIZE(cur->datum.u.xperms->perms.p); i++) + buf32[i] = cpu_to_le32(cur->datum.u.xperms->perms.p[i]); rc = put_entry(buf32, sizeof(u32), - ARRAY_SIZE(cur->datum.u.ops->op.perms), fp); + ARRAY_SIZE(cur->datum.u.xperms->perms.p), fp); } else { buf32[0] = cpu_to_le32(cur->datum.u.data); rc = put_entry(buf32, sizeof(u32), 1, fp); @@ -608,13 +673,13 @@ void avtab_cache_init(void) avtab_node_cachep = kmem_cache_create("avtab_node", sizeof(struct avtab_node), 0, SLAB_PANIC, NULL); - avtab_operation_cachep = kmem_cache_create("avtab_operation", - sizeof(struct avtab_operation), - 0, SLAB_PANIC, NULL); + avtab_xperms_cachep = kmem_cache_create("avtab_extended_perms", + sizeof(struct avtab_extended_perms), + 0, SLAB_PANIC, NULL); } void avtab_cache_destroy(void) { kmem_cache_destroy(avtab_node_cachep); - kmem_cache_destroy(avtab_operation_cachep); + kmem_cache_destroy(avtab_xperms_cachep); } diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h index 97acd6fa705e7..8133523ca679b 100644 --- a/security/selinux/ss/avtab.h +++ b/security/selinux/ss/avtab.h @@ -37,33 +37,42 @@ struct avtab_key { #define AVTAB_MEMBER 0x0020 #define AVTAB_CHANGE 0x0040 #define AVTAB_TYPE (AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE) -#define AVTAB_OPNUM_ALLOWED 0x0100 -#define AVTAB_OPNUM_AUDITALLOW 0x0200 -#define AVTAB_OPNUM_DONTAUDIT 0x0400 -#define AVTAB_OPNUM (AVTAB_OPNUM_ALLOWED | \ - AVTAB_OPNUM_AUDITALLOW | \ - AVTAB_OPNUM_DONTAUDIT) -#define AVTAB_OPTYPE_ALLOWED 0x1000 -#define AVTAB_OPTYPE_AUDITALLOW 0x2000 -#define AVTAB_OPTYPE_DONTAUDIT 0x4000 -#define AVTAB_OPTYPE (AVTAB_OPTYPE_ALLOWED | \ - AVTAB_OPTYPE_AUDITALLOW | \ - AVTAB_OPTYPE_DONTAUDIT) -#define AVTAB_OP (AVTAB_OPNUM | AVTAB_OPTYPE) +/* extended permissions */ +#define AVTAB_XPERMS_ALLOWED 0x0100 +#define AVTAB_XPERMS_AUDITALLOW 0x0200 +#define AVTAB_XPERMS_DONTAUDIT 0x0400 +#define AVTAB_XPERMS (AVTAB_XPERMS_ALLOWED | \ + AVTAB_XPERMS_AUDITALLOW | \ + AVTAB_XPERMS_DONTAUDIT) #define AVTAB_ENABLED_OLD 0x80000000 /* reserved for used in cond_avtab */ #define AVTAB_ENABLED 0x8000 /* reserved for used in cond_avtab */ u16 specified; /* what field is specified */ }; -struct avtab_operation { - u8 type; - struct operation_perm op; +/* + * For operations that require more than the 32 permissions provided by the avc + * extended permissions may be used to provide 256 bits of permissions. + */ +struct avtab_extended_perms { +/* These are not flags. All 256 values may be used */ +#define AVTAB_XPERMS_IOCTLFUNCTION 0x01 +#define AVTAB_XPERMS_IOCTLDRIVER 0x02 + /* extension of the avtab_key specified */ + u8 specified; /* ioctl, netfilter, ... */ + /* + * if 256 bits is not adequate as is often the case with ioctls, then + * multiple extended perms may be used and the driver field + * specifies which permissions are included. + */ + u8 driver; + /* 256 bits of permissions */ + struct extended_perms_data perms; }; struct avtab_datum { union { u32 data; /* access vector or type value */ - struct avtab_operation *ops; /* ioctl operations */ + struct avtab_extended_perms *xperms; } u; }; diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c index 16651c7a15419..ba7dd93661040 100644 --- a/security/selinux/ss/conditional.c +++ b/security/selinux/ss/conditional.c @@ -619,18 +619,18 @@ int cond_write_list(struct policydb *p, struct cond_node *list, void *fp) return 0; } -void cond_compute_operation(struct avtab *ctab, struct avtab_key *key, - struct operation_decision *od) +void cond_compute_xperms(struct avtab *ctab, struct avtab_key *key, + struct extended_perms_decision *xpermd) { struct avtab_node *node; - if (!ctab || !key || !od) + if (!ctab || !key || !xpermd) return; for (node = avtab_search_node(ctab, key); node; node = avtab_search_node_next(node, key->specified)) { if (node->key.specified & AVTAB_ENABLED) - services_compute_operation_num(od, node); + services_compute_xperms_decision(xpermd, node); } return; @@ -639,11 +639,11 @@ void cond_compute_operation(struct avtab *ctab, struct avtab_key *key, * av table, and if so, add them to the result */ void cond_compute_av(struct avtab *ctab, struct avtab_key *key, - struct av_decision *avd, struct operation *ops) + struct av_decision *avd, struct extended_perms *xperms) { struct avtab_node *node; - if (!ctab || !key || !avd || !ops) + if (!ctab || !key || !avd) return; for (node = avtab_search_node(ctab, key); node; @@ -662,9 +662,9 @@ void cond_compute_av(struct avtab *ctab, struct avtab_key *key, if ((u16)(AVTAB_AUDITALLOW|AVTAB_ENABLED) == (node->key.specified & (AVTAB_AUDITALLOW|AVTAB_ENABLED))) avd->auditallow |= node->datum.u.data; - if ((node->key.specified & AVTAB_ENABLED) && - (node->key.specified & AVTAB_OP)) - services_compute_operation_type(ops, node); + if (xperms && (node->key.specified & AVTAB_ENABLED) && + (node->key.specified & AVTAB_XPERMS)) + services_compute_xperms_drivers(xperms, node); } return; } diff --git a/security/selinux/ss/conditional.h b/security/selinux/ss/conditional.h index 80ee2bb20eee4..ddb43e7e1c756 100644 --- a/security/selinux/ss/conditional.h +++ b/security/selinux/ss/conditional.h @@ -74,9 +74,9 @@ int cond_write_bool(void *key, void *datum, void *ptr); int cond_write_list(struct policydb *p, struct cond_node *list, void *fp); void cond_compute_av(struct avtab *ctab, struct avtab_key *key, - struct av_decision *avd, struct operation *ops); -void cond_compute_operation(struct avtab *ctab, struct avtab_key *key, - struct operation_decision *od); + struct av_decision *avd, struct extended_perms *xperms); +void cond_compute_xperms(struct avtab *ctab, struct avtab_key *key, + struct extended_perms_decision *xpermd); int evaluate_cond_node(struct policydb *p, struct cond_node *node); #endif /* _CONDITIONAL_H_ */ diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index a683475e16359..ca2c6f47d9054 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -149,7 +149,7 @@ static struct policydb_compat_info policydb_compat[] = { .ocon_num = OCON_NUM, }, { - .version = POLICYDB_VERSION_IOCTL_OPERATIONS, + .version = POLICYDB_VERSION_XPERMS_IOCTL, .sym_num = SYM_NUM, .ocon_num = OCON_NUM, }, diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 88178da2b834e..cf905cdce93f2 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -95,7 +95,7 @@ static void context_struct_compute_av(struct context *scontext, struct context *tcontext, u16 tclass, struct av_decision *avd, - struct operation *ops); + struct extended_perms *xperms); struct selinux_mapping { u16 value; /* policy value */ @@ -615,39 +615,40 @@ static void type_attribute_bounds_av(struct context *scontext, } } -/* flag ioctl types that have operation permissions */ -void services_compute_operation_type( - struct operation *ops, +/* + * flag which drivers have permissions + * only looking for ioctl based extended permssions + */ +void services_compute_xperms_drivers( + struct extended_perms *xperms, struct avtab_node *node) { - u8 type; unsigned int i; - if (node->key.specified & AVTAB_OPTYPE) { - /* if allowing one or more complete types */ - for (i = 0; i < ARRAY_SIZE(ops->type); i++) - ops->type[i] |= node->datum.u.ops->op.perms[i]; - } else { - /* if allowing operations within a type */ - type = node->datum.u.ops->type; - security_operation_set(ops->type, type); + if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) { + /* if one or more driver has all permissions allowed */ + for (i = 0; i < ARRAY_SIZE(xperms->drivers.p); i++) + xperms->drivers.p[i] |= node->datum.u.xperms->perms.p[i]; + } else if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION) { + /* if allowing permissions within a driver */ + security_xperm_set(xperms->drivers.p, + node->datum.u.xperms->driver); } /* If no ioctl commands are allowed, ignore auditallow and auditdeny */ - if (node->key.specified & AVTAB_OPTYPE_ALLOWED || - node->key.specified & AVTAB_OPNUM_ALLOWED) - ops->len = 1; + if (node->key.specified & AVTAB_XPERMS_ALLOWED) + xperms->len = 1; } /* - * Compute access vectors and operations ranges based on a context + * Compute access vectors and extended permissions based on a context * structure pair for the permissions in a particular class. */ static void context_struct_compute_av(struct context *scontext, struct context *tcontext, u16 tclass, struct av_decision *avd, - struct operation *ops) + struct extended_perms *xperms) { struct constraint_node *constraint; struct role_allow *ra; @@ -661,9 +662,9 @@ static void context_struct_compute_av(struct context *scontext, avd->allowed = 0; avd->auditallow = 0; avd->auditdeny = 0xffffffff; - if (ops) { - memset(&ops->type, 0, sizeof(ops->type)); - ops->len = 0; + if (xperms) { + memset(&xperms->drivers, 0, sizeof(xperms->drivers)); + xperms->len = 0; } if (unlikely(!tclass || tclass > policydb.p_classes.nprim)) { @@ -679,7 +680,7 @@ static void context_struct_compute_av(struct context *scontext, * this permission check, then use it. */ avkey.target_class = tclass; - avkey.specified = AVTAB_AV | AVTAB_OP; + avkey.specified = AVTAB_AV | AVTAB_XPERMS; sattr = flex_array_get(policydb.type_attr_map_array, scontext->type - 1); BUG_ON(!sattr); tattr = flex_array_get(policydb.type_attr_map_array, tcontext->type - 1); @@ -697,12 +698,13 @@ static void context_struct_compute_av(struct context *scontext, avd->auditallow |= node->datum.u.data; else if (node->key.specified == AVTAB_AUDITDENY) avd->auditdeny &= node->datum.u.data; - else if (ops && (node->key.specified & AVTAB_OP)) - services_compute_operation_type(ops, node); + else if (xperms && (node->key.specified & AVTAB_XPERMS)) + services_compute_xperms_drivers(xperms, node); } /* Check conditional av table for additional permissions */ - cond_compute_av(&policydb.te_cond_avtab, &avkey, avd, ops); + cond_compute_av(&policydb.te_cond_avtab, &avkey, + avd, xperms); } } @@ -933,57 +935,65 @@ static void avd_init(struct av_decision *avd) avd->flags = 0; } -void services_compute_operation_num(struct operation_decision *od, +void services_compute_xperms_decision(struct extended_perms_decision *xpermd, struct avtab_node *node) { unsigned int i; - if (node->key.specified & AVTAB_OPNUM) { - if (od->type != node->datum.u.ops->type) + if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION) { + if (xpermd->driver != node->datum.u.xperms->driver) return; - } else { - if (!security_operation_test(node->datum.u.ops->op.perms, - od->type)) + } else if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) { + if (!security_xperm_test(node->datum.u.xperms->perms.p, + xpermd->driver)) return; + } else { + BUG(); } - if (node->key.specified == AVTAB_OPTYPE_ALLOWED) { - od->specified |= OPERATION_ALLOWED; - memset(od->allowed->perms, 0xff, - sizeof(od->allowed->perms)); - } else if (node->key.specified == AVTAB_OPTYPE_AUDITALLOW) { - od->specified |= OPERATION_AUDITALLOW; - memset(od->auditallow->perms, 0xff, - sizeof(od->auditallow->perms)); - } else if (node->key.specified == AVTAB_OPTYPE_DONTAUDIT) { - od->specified |= OPERATION_DONTAUDIT; - memset(od->dontaudit->perms, 0xff, - sizeof(od->dontaudit->perms)); - } else if (node->key.specified == AVTAB_OPNUM_ALLOWED) { - od->specified |= OPERATION_ALLOWED; - for (i = 0; i < ARRAY_SIZE(od->allowed->perms); i++) - od->allowed->perms[i] |= - node->datum.u.ops->op.perms[i]; - } else if (node->key.specified == AVTAB_OPNUM_AUDITALLOW) { - od->specified |= OPERATION_AUDITALLOW; - for (i = 0; i < ARRAY_SIZE(od->auditallow->perms); i++) - od->auditallow->perms[i] |= - node->datum.u.ops->op.perms[i]; - } else if (node->key.specified == AVTAB_OPNUM_DONTAUDIT) { - od->specified |= OPERATION_DONTAUDIT; - for (i = 0; i < ARRAY_SIZE(od->dontaudit->perms); i++) - od->dontaudit->perms[i] |= - node->datum.u.ops->op.perms[i]; + if (node->key.specified == AVTAB_XPERMS_ALLOWED) { + xpermd->used |= XPERMS_ALLOWED; + if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) { + memset(xpermd->allowed->p, 0xff, + sizeof(xpermd->allowed->p)); + } + if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION) { + for (i = 0; i < ARRAY_SIZE(xpermd->allowed->p); i++) + xpermd->allowed->p[i] |= + node->datum.u.xperms->perms.p[i]; + } + } else if (node->key.specified == AVTAB_XPERMS_AUDITALLOW) { + xpermd->used |= XPERMS_AUDITALLOW; + if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) { + memset(xpermd->auditallow->p, 0xff, + sizeof(xpermd->auditallow->p)); + } + if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION) { + for (i = 0; i < ARRAY_SIZE(xpermd->auditallow->p); i++) + xpermd->auditallow->p[i] |= + node->datum.u.xperms->perms.p[i]; + } + } else if (node->key.specified == AVTAB_XPERMS_DONTAUDIT) { + xpermd->used |= XPERMS_DONTAUDIT; + if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) { + memset(xpermd->dontaudit->p, 0xff, + sizeof(xpermd->dontaudit->p)); + } + if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION) { + for (i = 0; i < ARRAY_SIZE(xpermd->dontaudit->p); i++) + xpermd->dontaudit->p[i] |= + node->datum.u.xperms->perms.p[i]; + } } else { BUG(); } } -void security_compute_operation(u32 ssid, +void security_compute_xperms_decision(u32 ssid, u32 tsid, u16 orig_tclass, - u8 type, - struct operation_decision *od) + u8 driver, + struct extended_perms_decision *xpermd) { u16 tclass; struct context *scontext, *tcontext; @@ -993,11 +1003,11 @@ void security_compute_operation(u32 ssid, struct ebitmap_node *snode, *tnode; unsigned int i, j; - od->type = type; - od->specified = 0; - memset(od->allowed->perms, 0, sizeof(od->allowed->perms)); - memset(od->auditallow->perms, 0, sizeof(od->auditallow->perms)); - memset(od->dontaudit->perms, 0, sizeof(od->dontaudit->perms)); + xpermd->driver = driver; + xpermd->used = 0; + memset(xpermd->allowed->p, 0, sizeof(xpermd->allowed->p)); + memset(xpermd->auditallow->p, 0, sizeof(xpermd->auditallow->p)); + memset(xpermd->dontaudit->p, 0, sizeof(xpermd->dontaudit->p)); read_lock(&policy_rwlock); if (!ss_initialized) @@ -1031,7 +1041,7 @@ void security_compute_operation(u32 ssid, } avkey.target_class = tclass; - avkey.specified = AVTAB_OP; + avkey.specified = AVTAB_XPERMS; sattr = flex_array_get(policydb.type_attr_map_array, scontext->type - 1); BUG_ON(!sattr); @@ -1045,26 +1055,27 @@ void security_compute_operation(u32 ssid, for (node = avtab_search_node(&policydb.te_avtab, &avkey); node; node = avtab_search_node_next(node, avkey.specified)) - services_compute_operation_num(od, node); + services_compute_xperms_decision(xpermd, node); - cond_compute_operation(&policydb.te_cond_avtab, - &avkey, od); + cond_compute_xperms(&policydb.te_cond_avtab, + &avkey, xpermd); } } out: read_unlock(&policy_rwlock); return; allow: - memset(od->allowed->perms, 0xff, sizeof(od->allowed->perms)); + memset(xpermd->allowed->p, 0xff, sizeof(xpermd->allowed->p)); goto out; } + /** * security_compute_av - Compute access vector decisions. * @ssid: source security identifier * @tsid: target security identifier * @tclass: target security class * @avd: access vector decisions - * @od: operation decisions + * @xperms: extended permissions * * Compute a set of access vector decisions based on the * SID pair (@ssid, @tsid) for the permissions in @tclass. @@ -1073,14 +1084,14 @@ void security_compute_av(u32 ssid, u32 tsid, u16 orig_tclass, struct av_decision *avd, - struct operation *ops) + struct extended_perms *xperms) { u16 tclass; struct context *scontext = NULL, *tcontext = NULL; read_lock(&policy_rwlock); avd_init(avd); - ops->len = 0; + xperms->len = 0; if (!ss_initialized) goto allow; @@ -1108,7 +1119,7 @@ void security_compute_av(u32 ssid, goto allow; goto out; } - context_struct_compute_av(scontext, tcontext, tclass, avd, ops); + context_struct_compute_av(scontext, tcontext, tclass, avd, xperms); map_decision(orig_tclass, avd, policydb.allow_unknown); out: read_unlock(&policy_rwlock); diff --git a/security/selinux/ss/services.h b/security/selinux/ss/services.h index 569757484d052..6abcd8729ec3a 100644 --- a/security/selinux/ss/services.h +++ b/security/selinux/ss/services.h @@ -11,10 +11,10 @@ extern struct policydb policydb; -void services_compute_operation_type(struct operation *ops, +void services_compute_xperms_drivers(struct extended_perms *xperms, struct avtab_node *node); -void services_compute_operation_num(struct operation_decision *od, +void services_compute_xperms_decision(struct extended_perms_decision *xpermd, struct avtab_node *node); #endif /* _SS_SERVICES_H_ */ diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index 35a7c95c49b63..e958624521add 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c @@ -44,6 +44,8 @@ #include #include +#define U32_MAX ((u32)~0U) + /* TODO: * - add substream support for multiple devices in case of * SND_DYNAMIC_MINORS is not used @@ -496,7 +498,7 @@ static int snd_compress_check_input(struct snd_compr_params *params) { /* first let's check the buffer parameter's */ if (params->buffer.fragment_size == 0 || - params->buffer.fragments > SIZE_MAX / params->buffer.fragment_size) + params->buffer.fragments > U32_MAX / params->buffer.fragment_size) return -EINVAL; /* now codec parameters */ diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c index f9077361c119d..4c9aa462de9b1 100644 --- a/sound/core/seq/seq_queue.c +++ b/sound/core/seq/seq_queue.c @@ -144,8 +144,10 @@ static struct snd_seq_queue *queue_new(int owner, int locked) static void queue_delete(struct snd_seq_queue *q) { /* stop and release the timer */ + mutex_lock(&q->timer_mutex); snd_seq_timer_stop(q->timer); snd_seq_timer_close(q); + mutex_unlock(&q->timer_mutex); /* wait until access free */ snd_use_lock_sync(&q->use_lock); /* release resources... */ diff --git a/sound/soc/codecs/audio-ext-clk.c b/sound/soc/codecs/audio-ext-clk.c index 672ab43dc558b..eed1c0e8b590c 100644 --- a/sound/soc/codecs/audio-ext-clk.c +++ b/sound/soc/codecs/audio-ext-clk.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "../msm/msm-audio-pinctrl.h" @@ -48,6 +49,14 @@ struct audio_ext_pmi_clk { struct clk c; }; +static struct afe_clk_set digital_cdc_core_clk = { + Q6AFE_LPASS_CLK_CONFIG_API_VERSION, + Q6AFE_LPASS_CLK_ID_INTERNAL_DIGITAL_CODEC_CORE, + Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, +}; + static int audio_ext_clk_prepare(struct clk *clk); static void audio_ext_clk_unprepare(struct clk *clk); @@ -113,12 +122,6 @@ static int audio_ext_clk_prepare(struct clk *clk) goto err; } - tasha_digital_cdc_clk.i2s_cfg_minor_version = - AFE_API_VERSION_I2S_CONFIG; - tasha_digital_cdc_clk.clk_val = 9600000; - tasha_digital_cdc_clk.clk_root = 5; - tasha_digital_cdc_clk.reserved = 0; - vaddr = ioremap(LPASS_CSR_GP_IO_MUX_SPKR_CTL , 4); val = ioread32(vaddr); val = val | 0x00000002; @@ -129,13 +132,34 @@ static int audio_ext_clk_prepare(struct clk *clk) val = val | 0x00000002; iowrite32(val, vaddr); - ret = afe_set_digital_codec_core_clock( - AFE_PORT_ID_PRIMARY_MI2S_RX , &tasha_digital_cdc_clk); - - if (ret < 0) { - pr_err("%s afe_set_digital_codec_core_clock failed\n", - __func__); - return ret; + switch (q6core_get_avs_version()) { + case (Q6_SUBSYS_AVS2_6): + tasha_digital_cdc_clk.i2s_cfg_minor_version = + AFE_API_VERSION_I2S_CONFIG; + tasha_digital_cdc_clk.clk_val = 9600000; + tasha_digital_cdc_clk.clk_root = 5; + tasha_digital_cdc_clk.reserved = 0; + ret = afe_set_digital_codec_core_clock( + AFE_PORT_ID_PRIMARY_MI2S_RX, + &tasha_digital_cdc_clk); + if (ret < 0) { + pr_err("%s afe_set_digital_codec_core_clock failed\n", + __func__); + return ret; + } + break; + case (Q6_SUBSYS_AVS2_7): + case (Q6_SUBSYS_AVS2_8): + digital_cdc_core_clk.enable = 1; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_PRIMARY_MI2S_RX, + &digital_cdc_core_clk); + break; + case (Q6_SUBSYS_INVALID): + default: + ret = -EINVAL; + pr_err("%s: INVALID AVS IMAGE\n", __func__); + break; } } else { pr_err("%s: gpio: %d\n", __func__, audio_clk->gpio); @@ -159,14 +183,30 @@ static void audio_ext_clk_unprepare(struct clk *clk) __func__, ret); ret = -EIO; } - tasha_digital_cdc_clk.clk_val = 0; + switch (q6core_get_avs_version()) { + case (Q6_SUBSYS_AVS2_6): + tasha_digital_cdc_clk.clk_val = 0; - ret = afe_set_digital_codec_core_clock( - AFE_PORT_ID_PRIMARY_MI2S_RX, &tasha_digital_cdc_clk); + ret = afe_set_digital_codec_core_clock( + AFE_PORT_ID_PRIMARY_MI2S_RX, + &tasha_digital_cdc_clk); - if (ret < 0) { - pr_err("%s afe_set_digital_codec_core_clock failed\n", - __func__); + if (ret < 0) { + pr_err("%s afe_set_digital_codec_core_clock failed\n", + __func__); + } + case (Q6_SUBSYS_AVS2_7): + case (Q6_SUBSYS_AVS2_8): + digital_cdc_core_clk.enable = 0; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_PRIMARY_MI2S_RX, + &digital_cdc_core_clk); + break; + case (Q6_SUBSYS_INVALID): + default: + ret = -EINVAL; + pr_err("%s: INVALID AVS IMAGE\n", __func__); + break; } } else { pr_debug("%s: gpio: %d\n", __func__, audio_clk->gpio); diff --git a/sound/soc/codecs/msm8x16-wcd.c b/sound/soc/codecs/msm8x16-wcd.c index df3326a2ef4be..3a9b6d3e1eb1d 100644 --- a/sound/soc/codecs/msm8x16-wcd.c +++ b/sound/soc/codecs/msm8x16-wcd.c @@ -5970,7 +5970,7 @@ static int msm8x16_wcd_spmi_probe(struct spmi_device *spmi) } - dev_dbg(&spmi->dev, "%s(%d):start addr = 0x%pa\n", + dev_dbg(&spmi->dev, "%s(%d):start addr = 0x%pK\n", __func__, __LINE__, &wcd_resource->start); if (wcd_resource->start != TOMBAK_CORE_0_SPMI_ADDR) diff --git a/sound/soc/codecs/wcd-mbhc-v2.c b/sound/soc/codecs/wcd-mbhc-v2.c index 4c8a76d89887e..ad0803d7b799d 100644 --- a/sound/soc/codecs/wcd-mbhc-v2.c +++ b/sound/soc/codecs/wcd-mbhc-v2.c @@ -2071,7 +2071,7 @@ int wcd_mbhc_start(struct wcd_mbhc *mbhc, schedule_delayed_work(&mbhc->mbhc_firmware_dwork, usecs_to_jiffies(FW_READ_TIMEOUT)); else - pr_err("%s: Skipping to read mbhc fw, 0x%p %p\n", + pr_err("%s: Skipping to read mbhc fw, 0x%pK %pK\n", __func__, mbhc->mbhc_fw, mbhc->mbhc_cal); } pr_debug("%s: leave %d\n", __func__, rc); diff --git a/sound/soc/codecs/wcd9306.c b/sound/soc/codecs/wcd9306.c index 1d2f2884a6c72..46111855ffa95 100644 --- a/sound/soc/codecs/wcd9306.c +++ b/sound/soc/codecs/wcd9306.c @@ -3800,7 +3800,7 @@ static int tapan_get_channel_map(struct snd_soc_dai *dai, case AIF2_PB: case AIF3_PB: if (!rx_slot || !rx_num) { - pr_err("%s: Invalid rx_slot %p or rx_num %p\n", + pr_err("%s: Invalid rx_slot %pK or rx_num %pK\n", __func__, rx_slot, rx_num); return -EINVAL; } @@ -3817,7 +3817,7 @@ static int tapan_get_channel_map(struct snd_soc_dai *dai, case AIF2_CAP: case AIF3_CAP: if (!tx_slot || !tx_num) { - pr_err("%s: Invalid tx_slot %p or tx_num %p\n", + pr_err("%s: Invalid tx_slot %pK or tx_num %pK\n", __func__, tx_slot, tx_num); return -EINVAL; } diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c index 0334a74b02e29..697a1b63098b1 100644 --- a/sound/soc/codecs/wcd9320.c +++ b/sound/soc/codecs/wcd9320.c @@ -4716,7 +4716,7 @@ static int taiko_set_channel_map(struct snd_soc_dai *dai, struct taiko_priv *taiko = snd_soc_codec_get_drvdata(dai->codec); struct wcd9xxx *core = dev_get_drvdata(dai->codec->dev->parent); if (!tx_slot || !rx_slot) { - pr_err("%s: Invalid tx_slot=%p, rx_slot=%p\n", __func__, + pr_err("%s: Invalid tx_slot=%pK, rx_slot=%pK\n", __func__, tx_slot, rx_slot); return -EINVAL; } diff --git a/sound/soc/codecs/wcd9330.c b/sound/soc/codecs/wcd9330.c index 7e9c009abd6a4..05e88895d3d0a 100644 --- a/sound/soc/codecs/wcd9330.c +++ b/sound/soc/codecs/wcd9330.c @@ -5362,7 +5362,7 @@ static int tomtom_set_channel_map(struct snd_soc_dai *dai, struct tomtom_priv *tomtom = snd_soc_codec_get_drvdata(dai->codec); struct wcd9xxx *core = dev_get_drvdata(dai->codec->dev->parent); if (!tx_slot || !rx_slot) { - pr_err("%s: Invalid tx_slot=%p, rx_slot=%p\n", + pr_err("%s: Invalid tx_slot=%pK, rx_slot=%pK\n", __func__, tx_slot, rx_slot); return -EINVAL; } @@ -5398,7 +5398,7 @@ static int tomtom_get_channel_map(struct snd_soc_dai *dai, case AIF2_PB: case AIF3_PB: if (!rx_slot || !rx_num) { - pr_err("%s: Invalid rx_slot %p or rx_num %p\n", + pr_err("%s: Invalid rx_slot %pK or rx_num %pK\n", __func__, rx_slot, rx_num); return -EINVAL; } @@ -5417,7 +5417,7 @@ static int tomtom_get_channel_map(struct snd_soc_dai *dai, case AIF4_VIFEED: case AIF4_MAD_TX: if (!tx_slot || !tx_num) { - pr_err("%s: Invalid tx_slot %p or tx_num %p\n", + pr_err("%s: Invalid tx_slot %pK or tx_num %pK\n", __func__, tx_slot, tx_num); return -EINVAL; } @@ -8036,7 +8036,7 @@ static void tomtom_compute_impedance(struct wcd9xxx_mbhc *mbhc, s16 *l, s16 *r, struct tomtom_priv *tomtom; if (!mbhc) { - pr_err("%s: Invalid parameters mbhc = %p\n", + pr_err("%s: Invalid parameters mbhc = %pK\n", __func__, mbhc); return; } @@ -8095,7 +8095,7 @@ static void tomtom_zdet_error_approx(struct wcd9xxx_mbhc *mbhc, uint32_t *zl, const int shift = TOMTOM_ZDET_ERROR_APPROX_SHIFT; if (!zl || !zr || !mbhc) { - pr_err("%s: Invalid parameters zl = %p zr = %p, mbhc = %p\n", + pr_err("%s: Invalid parameters zl = %pK zr = %pK, mbhc = %pK\n", __func__, zl, zr, mbhc); return; } diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 8cd5825244411..3fa5346a0cbe5 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -9465,7 +9465,7 @@ static int tasha_get_channel_map(struct snd_soc_dai *dai, case AIF3_PB: case AIF_MIX1_PB: if (!rx_slot || !rx_num) { - pr_err("%s: Invalid rx_slot %p or rx_num %p\n", + pr_err("%s: Invalid rx_slot %pK or rx_num %pK\n", __func__, rx_slot, rx_num); return -EINVAL; } @@ -9484,7 +9484,7 @@ static int tasha_get_channel_map(struct snd_soc_dai *dai, case AIF4_MAD_TX: case AIF4_VIFEED: if (!tx_slot || !tx_num) { - pr_err("%s: Invalid tx_slot %p or tx_num %p\n", + pr_err("%s: Invalid tx_slot %pK or tx_num %pK\n", __func__, tx_slot, tx_num); return -EINVAL; } @@ -9522,7 +9522,7 @@ static int tasha_set_channel_map(struct snd_soc_dai *dai, core = dev_get_drvdata(dai->codec->dev->parent); if (!tx_slot || !rx_slot) { - pr_err("%s: Invalid tx_slot=%p, rx_slot=%p\n", + pr_err("%s: Invalid tx_slot=%pK, rx_slot=%pK\n", __func__, tx_slot, rx_slot); return -EINVAL; } diff --git a/sound/soc/codecs/wcd9xxx-mbhc.c b/sound/soc/codecs/wcd9xxx-mbhc.c index 407b0e2515e99..e187b39c6184b 100644 --- a/sound/soc/codecs/wcd9xxx-mbhc.c +++ b/sound/soc/codecs/wcd9xxx-mbhc.c @@ -4631,7 +4631,7 @@ int wcd9xxx_mbhc_start(struct wcd9xxx_mbhc *mbhc, schedule_delayed_work(&mbhc->mbhc_firmware_dwork, usecs_to_jiffies(FW_READ_TIMEOUT)); else - pr_debug("%s: Skipping to read mbhc fw, 0x%p %p\n", + pr_debug("%s: Skipping to read mbhc fw, 0x%pK %pK\n", __func__, mbhc->mbhc_fw, mbhc->mbhc_cal); } @@ -5024,7 +5024,7 @@ static int wcd9xxx_remeasure_z_values(struct wcd9xxx_mbhc *mbhc, right = !!(r); dev_dbg(codec->dev, "%s: Remeasuring impedance values\n", __func__); - dev_dbg(codec->dev, "%s: l: %p, r: %p, left=%d, right=%d\n", __func__, + dev_dbg(codec->dev, "%s: l: %pK, r: %pK, left=%d, right=%d\n", __func__, l, r, left, right); /* Remeasure V2 values */ diff --git a/sound/soc/codecs/wcd_cpe_core.c b/sound/soc/codecs/wcd_cpe_core.c index beebcebfdb40a..235d0670fcb05 100644 --- a/sound/soc/codecs/wcd_cpe_core.c +++ b/sound/soc/codecs/wcd_cpe_core.c @@ -429,7 +429,7 @@ static int wcd_cpe_load_fw(struct wcd_cpe_core *core, bool load_segment; if (!core || !core->cpe_handle) { - pr_err("%s: Error CPE core %p\n", __func__, + pr_err("%s: Error CPE core %pK\n", __func__, core); return -EINVAL; } diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 29e95f93d4822..223b5b327cff8 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -3340,7 +3340,7 @@ int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, dev_warn(codec->dev, "Failed to configure MICBIAS%d: %d\n", micbias, ret); - dev_dbg(codec->dev, "Configuring microphone detection on %d %p\n", + dev_dbg(codec->dev, "Configuring microphone detection on %d %pK\n", micbias, jack); /* Store the configuration */ diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c index db22ec4ecef73..ea9e5f0d40bd2 100644 --- a/sound/soc/codecs/wsa881x.c +++ b/sound/soc/codecs/wsa881x.c @@ -888,7 +888,7 @@ int wsa881x_set_channel_map(struct snd_soc_codec *codec, u8 *port, u8 num_port, if (!port || !ch_mask || !ch_rate || (num_port > WSA881X_MAX_SWR_PORTS)) { dev_err(codec->dev, - "%s: Invalid port=%p, ch_mask=%p, ch_rate=%p\n", + "%s: Invalid port=%pK, ch_mask=%pK, ch_rate=%pK\n", __func__, port, ch_mask, ch_rate); return -EINVAL; } diff --git a/sound/soc/msm/msm-cpe-lsm.c b/sound/soc/msm/msm-cpe-lsm.c index b9c7784fca4ac..4437c95f91225 100644 --- a/sound/soc/msm/msm-cpe-lsm.c +++ b/sound/soc/msm/msm-cpe-lsm.c @@ -457,7 +457,7 @@ static int msm_cpe_lab_buf_alloc(struct snd_pcm_substream *substream, pcm_buf[count].mem = pcm_buf[0].mem + (count * bufsz); pcm_buf[count].phys = pcm_buf[0].phys + (count * bufsz); dev_dbg(rtd->dev, - "%s: pcm_buf[%d].mem %p pcm_buf[%d].phys %pa\n", + "%s: pcm_buf[%d].mem %pK pcm_buf[%d].phys %pK\n", __func__, count, (void *)pcm_buf[count].mem, count, &(pcm_buf[count].phys)); @@ -681,7 +681,7 @@ static int msm_cpe_lab_thread(void *data) buf_count++; } dev_dbg(rtd->dev, - "%s: Cur buf = %p Next Buf = %p\n" + "%s: Cur buf = %pK Next Buf = %pK\n" " buf count = 0x%x\n", __func__, cur_buf, next_buf, buf_count); } else { @@ -1170,6 +1170,7 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: No memory for sound model\n", __func__); kfree(session->conf_levels); + session->conf_levels = NULL; return -ENOMEM; } session->snd_model_size = snd_model.data_size; @@ -1181,6 +1182,8 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream, __func__); kfree(session->conf_levels); kfree(session->snd_model_data); + session->conf_levels = NULL; + session->snd_model_data = NULL; return -EFAULT; } @@ -1192,6 +1195,8 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream, __func__, rc); kfree(session->snd_model_data); kfree(session->conf_levels); + session->snd_model_data = NULL; + session->conf_levels = NULL; return rc; } @@ -1205,6 +1210,8 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream, lsm_ops->lsm_shmem_dealloc(cpe->core_handle, session); kfree(session->snd_model_data); kfree(session->conf_levels); + session->snd_model_data = NULL; + session->conf_levels = NULL; return rc; } @@ -1512,7 +1519,7 @@ static int msm_cpe_lsm_lab_start(struct snd_pcm_substream *substream, int rc; if (!substream || !substream->private_data) { - pr_err("%s: invalid substream (%p)\n", + pr_err("%s: invalid substream (%pK)\n", __func__, substream); return -EINVAL; } @@ -1602,7 +1609,7 @@ static int msm_cpe_lsm_ioctl(struct snd_pcm_substream *substream, struct wcd_cpe_lsm_ops *lsm_ops; if (!substream || !substream->private_data) { - pr_err("%s: invalid substream (%p)\n", + pr_err("%s: invalid substream (%pK)\n", __func__, substream); return -EINVAL; } @@ -1775,7 +1782,7 @@ static int msm_cpe_lsm_ioctl_compat(struct snd_pcm_substream *substream, struct wcd_cpe_lsm_ops *lsm_ops; if (!substream || !substream->private_data) { - pr_err("%s: invalid substream (%p)\n", + pr_err("%s: invalid substream (%pK)\n", __func__, substream); return -EINVAL; } @@ -2261,7 +2268,7 @@ static int msm_cpe_lsm_copy(struct snd_pcm_substream *substream, int a, if (lab_d->buf_idx >= (lsm_d->hw_params.period_count)) lab_d->buf_idx = 0; pcm_buf = (lab_d->pcm_buf[lab_d->buf_idx].mem); - pr_debug("%s: Buf IDX = 0x%x pcm_buf %pa\n", + pr_debug("%s: Buf IDX = 0x%x pcm_buf %pK\n", __func__, lab_d->buf_idx, &(lab_d->pcm_buf[lab_d->buf_idx])); diff --git a/sound/soc/msm/msm8x16.c b/sound/soc/msm/msm8x16.c index 61da7ca54707f..3574ee29159e1 100644 --- a/sound/soc/msm/msm8x16.c +++ b/sound/soc/msm/msm8x16.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include "qdsp6v2/msm-pcm-routing-v2.h" #include "../codecs/msm8x16-wcd.h" @@ -105,6 +106,7 @@ static int msm_btsco_ch = 1; static int msm_mi2s_tx_ch = 2; static int msm_pri_mi2s_rx_ch = 2; static int pri_rx_sample_rate = SAMPLING_RATE_48KHZ; +static int mi2s_tx_sample_rate = SAMPLING_RATE_48KHZ; static int msm_proxy_rx_ch = 2; static int msm8909_auxpcm_rate = 8000; @@ -265,7 +267,7 @@ void *def_tapan_mbhc_cal(void) return tapan_cal; } -static struct afe_clk_cfg mi2s_rx_clk = { +static struct afe_clk_cfg mi2s_rx_clk_v1 = { AFE_API_VERSION_I2S_CONFIG, Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, Q6AFE_LPASS_OSR_CLK_12_P288_MHZ, @@ -275,7 +277,7 @@ static struct afe_clk_cfg mi2s_rx_clk = { 0, }; -static struct afe_clk_cfg mi2s_tx_clk = { +static struct afe_clk_cfg mi2s_tx_clk_v1 = { AFE_API_VERSION_I2S_CONFIG, Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, Q6AFE_LPASS_OSR_CLK_12_P288_MHZ, @@ -285,6 +287,24 @@ static struct afe_clk_cfg mi2s_tx_clk = { 0, }; +static struct afe_clk_set mi2s_tx_clk = { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, +}; + +static struct afe_clk_set mi2s_rx_clk = { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, +}; + struct cdc_pdm_pinctrl_info { struct pinctrl *pinctrl; struct pinctrl_state *cdc_lines_sus; @@ -423,6 +443,13 @@ static const struct snd_soc_dapm_widget msm8x16_dapm_widgets[] = { SND_SOC_DAPM_MIC("Digital Mic3", NULL), }; +static struct snd_soc_dapm_route wcd9335_audio_paths[] = { + {"MIC BIAS1", NULL, "MCLK"}, + {"MIC BIAS2", NULL, "MCLK"}, + {"MIC BIAS3", NULL, "MCLK"}, + {"MIC BIAS4", NULL, "MCLK"}, +}; + static char const *rx_bit_format_text[] = {"S16_LE", "S24_LE"}; static const char *const mi2s_tx_ch_text[] = {"One", "Two", "Three", "Four"}; static char const *mi2s_rx_sample_rate_text[] = {"KHZ_48", "KHZ_96", "KHZ_192"}; @@ -436,6 +463,9 @@ static const char *const lineout_text[] = {"DISABLE", "ENABLE", "DUALMODE"}; #ifdef CONFIG_MACH_T86519A1 static const char *const quatmi2s_clk_text[] = {"DISABLE", "ENABLE"}; #endif +static char const *mi2s_tx_sample_rate_text[] = {"KHZ_48", "KHZ_96", + "KHZ_192", "KHZ_8", + "KHZ_16", "KHZ_32"}; static int msm_auxpcm_be_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) @@ -452,6 +482,43 @@ static int msm_auxpcm_be_params_fixup(struct snd_soc_pcm_runtime *rtd, return 0; } +static int msm8x16_get_clk_id(int port_id) +{ + switch (port_id) { + case AFE_PORT_ID_PRIMARY_MI2S_RX: + return Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT; + case AFE_PORT_ID_SECONDARY_MI2S_RX: + return Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT; + case AFE_PORT_ID_TERTIARY_MI2S_TX: + return Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT; + case AFE_PORT_ID_QUATERNARY_MI2S_RX: + case AFE_PORT_ID_QUATERNARY_MI2S_TX: + return Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT; + default: + pr_err("%s: invalid port_id: 0x%x\n", __func__, port_id); + return -EINVAL; + } +} + +static int msm8x16_get_port_id(int be_id) +{ + switch (be_id) { + case MSM_BACKEND_DAI_PRI_MI2S_RX: + return AFE_PORT_ID_PRIMARY_MI2S_RX; + case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: + return AFE_PORT_ID_SECONDARY_MI2S_RX; + case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: + return AFE_PORT_ID_TERTIARY_MI2S_TX; + case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: + return AFE_PORT_ID_QUATERNARY_MI2S_RX; + case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: + return AFE_PORT_ID_QUATERNARY_MI2S_TX; + default: + pr_err("%s: Invalid be_id: %d\n", __func__, be_id); + return -EINVAL; + } +} + static int enable_spk_ext_pa(struct snd_soc_codec *codec, int enable) { struct snd_soc_card *card = codec->card; @@ -864,8 +931,9 @@ static int msm_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); - pr_debug("%s(), channel:%d\n", __func__, msm_mi2s_tx_ch); - rate->min = rate->max = 48000; + pr_debug("%s(), channel:%d sample rate %d\n", __func__, + msm_mi2s_tx_ch, mi2s_tx_sample_rate); + rate->min = rate->max = mi2s_tx_sample_rate; channels->min = channels->max = msm_mi2s_tx_ch; return 0; @@ -951,6 +1019,68 @@ static int pri_rx_sample_rate_put(struct snd_kcontrol *kcontrol, return 0; } +static int mi2s_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val = 0; + + switch (mi2s_tx_sample_rate) { + case SAMPLING_RATE_32KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_8KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_48KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: sample_rate_val = %d\n", __func__, + sample_rate_val); + + return 0; +} + +static int mi2s_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 5: + mi2s_tx_sample_rate = SAMPLING_RATE_32KHZ; + break; + case 4: + mi2s_tx_sample_rate = SAMPLING_RATE_16KHZ; + break; + case 3: + mi2s_tx_sample_rate = SAMPLING_RATE_8KHZ; + break; + case 2: + mi2s_tx_sample_rate = SAMPLING_RATE_192KHZ; + break; + case 1: + mi2s_tx_sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + mi2s_tx_sample_rate = SAMPLING_RATE_48KHZ; + } + pr_debug("%s: mi2s_tx_sample_rate = %d\n", __func__, + mi2s_tx_sample_rate); + return 0; +} + static int msm_mi2s_tx_ch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -986,19 +1116,20 @@ static int quat_mi2s_sclk_ctl(struct snd_pcm_substream *substream, bool enable) if (enable) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (mi2s_rx_bit_format == SNDRV_PCM_FORMAT_S24_LE) - mi2s_rx_clk.clk_val1 = + mi2s_rx_clk_v1.clk_val1 = Q6AFE_LPASS_IBIT_CLK_3_P072_MHZ; else - mi2s_rx_clk.clk_val1 = + mi2s_rx_clk_v1.clk_val1 = Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; ret = afe_set_lpass_clock( AFE_PORT_ID_QUATERNARY_MI2S_RX, - &mi2s_rx_clk); + &mi2s_rx_clk_v1); } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { - mi2s_tx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; + mi2s_tx_clk_v1.clk_val1 = + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; ret = afe_set_lpass_clock( AFE_PORT_ID_QUATERNARY_MI2S_TX, - &mi2s_tx_clk); + &mi2s_tx_clk_v1); } else { pr_err("%s:Not valid substream.\n", __func__); } @@ -1008,10 +1139,10 @@ static int quat_mi2s_sclk_ctl(struct snd_pcm_substream *substream, bool enable) } else { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - mi2s_rx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; + mi2s_rx_clk_v1.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; ret = afe_set_lpass_clock( AFE_PORT_ID_QUATERNARY_MI2S_RX, - &mi2s_rx_clk); + &mi2s_rx_clk_v1); } else { pr_err("%s:Not valid substream.\n", __func__); } @@ -1029,13 +1160,13 @@ static int sec_mi2s_sclk_ctl(struct snd_pcm_substream *substream, bool enable) if (enable) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (mi2s_rx_bit_format == SNDRV_PCM_FORMAT_S24_LE) - mi2s_rx_clk.clk_val1 = + mi2s_rx_clk_v1.clk_val1 = Q6AFE_LPASS_IBIT_CLK_3_P072_MHZ; else - mi2s_rx_clk.clk_val1 = + mi2s_rx_clk_v1.clk_val1 = Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; ret = afe_set_lpass_clock(AFE_PORT_ID_SECONDARY_MI2S_RX, - &mi2s_rx_clk); + &mi2s_rx_clk_v1); } else pr_err("%s:Not valid substream.\n", __func__); @@ -1044,9 +1175,9 @@ static int sec_mi2s_sclk_ctl(struct snd_pcm_substream *substream, bool enable) } else { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - mi2s_rx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; + mi2s_rx_clk_v1.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; ret = afe_set_lpass_clock(AFE_PORT_ID_SECONDARY_MI2S_RX, - &mi2s_rx_clk); + &mi2s_rx_clk_v1); } else pr_err("%s:Not valid substream.\n", __func__); @@ -1062,17 +1193,18 @@ static int mi2s_clk_ctl(struct snd_pcm_substream *substream, bool enable) if (enable) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (mi2s_rx_bit_format == SNDRV_PCM_FORMAT_S24_LE) - mi2s_rx_clk.clk_val1 = + mi2s_rx_clk_v1.clk_val1 = Q6AFE_LPASS_IBIT_CLK_3_P072_MHZ; else - mi2s_rx_clk.clk_val1 = + mi2s_rx_clk_v1.clk_val1 = Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; ret = afe_set_lpass_clock(AFE_PORT_ID_PRIMARY_MI2S_RX, - &mi2s_rx_clk); + &mi2s_rx_clk_v1); } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { - mi2s_tx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; + mi2s_tx_clk_v1.clk_val1 = + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; ret = afe_set_lpass_clock(AFE_PORT_ID_TERTIARY_MI2S_TX, - &mi2s_tx_clk); + &mi2s_tx_clk_v1); } else pr_err("%s:Not valid substream.\n", __func__); @@ -1081,13 +1213,13 @@ static int mi2s_clk_ctl(struct snd_pcm_substream *substream, bool enable) } else { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - mi2s_rx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; + mi2s_rx_clk_v1.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; ret = afe_set_lpass_clock(AFE_PORT_ID_PRIMARY_MI2S_RX, - &mi2s_rx_clk); + &mi2s_rx_clk_v1); } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { - mi2s_tx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; + mi2s_tx_clk_v1.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; ret = afe_set_lpass_clock(AFE_PORT_ID_TERTIARY_MI2S_TX, - &mi2s_tx_clk); + &mi2s_tx_clk_v1); } else pr_err("%s:Not valid substream.\n", __func__); @@ -1098,23 +1230,82 @@ static int mi2s_clk_ctl(struct snd_pcm_substream *substream, bool enable) return ret; } -static int ext_mi2s_clk_ctl(struct snd_pcm_substream *substream, bool enable, - u16 port_id) +static uint32_t get_mi2s_rx_clk_val(void) +{ + uint32_t clk_val; + + clk_val = pri_rx_sample_rate * bits_per_sample * 2; + + return clk_val; +} + +static uint32_t get_mi2s_tx_clk_val(void) +{ + return mi2s_tx_sample_rate * bits_per_sample * 2; +} + +static int ext_mi2s_clk_ctl(struct snd_pcm_substream *substream, bool enable) { int ret = 0; + int port_id = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + + port_id = msm8x16_get_port_id(rtd->dai_link->be_id); + if (port_id < 0) { + pr_err("%s: Invalid port_id\n", __func__); + return -EINVAL; + } if (enable) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - u32 clk_val = pri_rx_sample_rate * bits_per_sample * 2; - mi2s_rx_clk.clk_val1 = clk_val; - ret = afe_set_lpass_clock( - port_id, + switch (q6core_get_avs_version()) { + case (Q6_SUBSYS_AVS2_6): + mi2s_rx_clk_v1.clk_val1 = get_mi2s_rx_clk_val(); + ret = afe_set_lpass_clock( + port_id, + &mi2s_rx_clk_v1); + break; + case (Q6_SUBSYS_AVS2_7): + case (Q6_SUBSYS_AVS2_8): + mi2s_rx_clk.enable = enable; + mi2s_rx_clk.clk_id = + msm8x16_get_clk_id(port_id); + mi2s_rx_clk.clk_freq_in_hz = + get_mi2s_rx_clk_val(); + ret = afe_set_lpass_clock_v2(port_id, &mi2s_rx_clk); + break; + case (Q6_SUBSYS_INVALID): + default: + ret = -EINVAL; + pr_err("%s: INVALID AVS IMAGE\n", __func__); + break; + } } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { - mi2s_tx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; - ret = afe_set_lpass_clock( - port_id, + switch (q6core_get_avs_version()) { + case (Q6_SUBSYS_AVS2_6): + mi2s_tx_clk_v1.clk_val1 = + get_mi2s_tx_clk_val(); + ret = afe_set_lpass_clock( + port_id, + &mi2s_tx_clk_v1); + break; + case (Q6_SUBSYS_AVS2_7): + case (Q6_SUBSYS_AVS2_8): + mi2s_tx_clk.enable = enable; + mi2s_tx_clk.clk_id = + msm8x16_get_clk_id(port_id); + mi2s_tx_clk.clk_freq_in_hz = + get_mi2s_tx_clk_val(); + ret = afe_set_lpass_clock_v2(port_id, &mi2s_tx_clk); + break; + case (Q6_SUBSYS_INVALID): + default: + ret = -EINVAL; + pr_err("%s: INVALID AVS IMAGE\n", __func__); + break; + } } else pr_err("%s:Not valid substream.\n", __func__); @@ -1123,15 +1314,53 @@ static int ext_mi2s_clk_ctl(struct snd_pcm_substream *substream, bool enable, __func__, ret); } else { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - mi2s_rx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; - ret = afe_set_lpass_clock( - port_id, - &mi2s_rx_clk); + switch (q6core_get_avs_version()) { + case (Q6_SUBSYS_AVS2_6): + mi2s_rx_clk_v1.clk_val1 = + Q6AFE_LPASS_IBIT_CLK_DISABLE; + ret = afe_set_lpass_clock( + port_id, + &mi2s_rx_clk_v1); + break; + case (Q6_SUBSYS_AVS2_7): + case (Q6_SUBSYS_AVS2_8): + mi2s_rx_clk.enable = enable; + mi2s_rx_clk.clk_id = + msm8x16_get_clk_id(port_id); + mi2s_rx_clk.clk_freq_in_hz = 0; + ret = afe_set_lpass_clock_v2(port_id, + &mi2s_rx_clk); + break; + case (Q6_SUBSYS_INVALID): + default: + ret = -EINVAL; + pr_err("%s: INVALID AVS IMAGE\n", __func__); + break; + } } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { - mi2s_tx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; - ret = afe_set_lpass_clock( - port_id, - &mi2s_tx_clk); + switch (q6core_get_avs_version()) { + case (Q6_SUBSYS_AVS2_6): + mi2s_tx_clk_v1.clk_val1 = + Q6AFE_LPASS_IBIT_CLK_DISABLE; + ret = afe_set_lpass_clock( + port_id, + &mi2s_tx_clk_v1); + break; + case (Q6_SUBSYS_AVS2_7): + case (Q6_SUBSYS_AVS2_8): + mi2s_tx_clk.enable = enable; + mi2s_tx_clk.clk_id = + msm8x16_get_clk_id(port_id); + mi2s_tx_clk.clk_freq_in_hz = 0; + ret = afe_set_lpass_clock_v2(port_id, + &mi2s_tx_clk); + break; + case (Q6_SUBSYS_INVALID): + default: + ret = -EINVAL; + pr_err("%s: INVALID AVS IMAGE\n", __func__); + break; + } } else pr_err("%s:Not valid substream %d\n", __func__, substream->stream); @@ -1256,44 +1485,8 @@ static int msm8x16_enable_codec_ext_clk_wm8998(struct snd_soc_codec *codec, static int msm8x16_enable_extcodec_ext_clk(struct snd_soc_codec *codec, int enable, bool dapm) { - int ret = 0; - struct msm8916_asoc_mach_data *pdata = NULL; - - pdata = snd_soc_card_get_drvdata(codec->card); - - pr_debug("%s: enable = %d codec name %s enable %d mclk ref counter %d\n", - __func__, enable, codec->name, enable, - atomic_read(&pdata->mclk_rsc_ref)); - if (enable) { - if (atomic_inc_return(&pdata->mclk_rsc_ref) == 1) { - mutex_lock(&pdata->cdc_mclk_mutex); - pdata->digital_cdc_clk.clk_val = 9600000; - afe_set_digital_codec_core_clock( - AFE_PORT_ID_PRIMARY_MI2S_RX, - &pdata->digital_cdc_clk); - pdata->digital_cdc_clk.clk_val = 9600000; - afe_set_digital_codec_core_clock( - AFE_PORT_ID_QUATERNARY_MI2S_RX, - &pdata->digital_cdc_clk); - mutex_unlock(&pdata->cdc_mclk_mutex); - tasha_cdc_mclk_enable(codec, 1, dapm); - } - } else { - if (atomic_dec_return(&pdata->mclk_rsc_ref) == 0) { - mutex_lock(&pdata->cdc_mclk_mutex); - pdata->digital_cdc_clk.clk_val = 0; - afe_set_digital_codec_core_clock( - AFE_PORT_ID_PRIMARY_MI2S_RX, - &pdata->digital_cdc_clk); - pdata->digital_cdc_clk.clk_val = 0; - afe_set_digital_codec_core_clock( - AFE_PORT_ID_QUATERNARY_MI2S_RX, - &pdata->digital_cdc_clk); - mutex_unlock(&pdata->cdc_mclk_mutex); - tasha_cdc_mclk_enable(codec, 0, dapm); - } - } - return ret; + tasha_cdc_mclk_enable(codec, enable, dapm); + return 0; } static int msm_btsco_rate_get(struct snd_kcontrol *kcontrol, @@ -1335,6 +1528,7 @@ static const struct soc_enum msm_snd_enum[] = { #ifdef CONFIG_MACH_T86519A1 SOC_ENUM_SINGLE_EXT(2, quatmi2s_clk_text), #endif + SOC_ENUM_SINGLE_EXT(6, mi2s_tx_sample_rate_text), }; static const char *const btsco_rate_text[] = {"BTSCO_RATE_8KHZ", @@ -1362,6 +1556,8 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { SOC_ENUM_EXT("Lineout_1 amp", msm_snd_enum[5], lineout_status_get, lineout_status_put), #endif + SOC_ENUM_EXT("MI2S TX SampleRate", msm_snd_enum[4], + mi2s_tx_sample_rate_get, mi2s_tx_sample_rate_put), }; static int msm8x16_mclk_event(struct snd_soc_dapm_widget *w, @@ -1391,6 +1587,10 @@ static int msm8x16_mclk_event(struct snd_soc_dapm_widget *w, return msm8x16_enable_codec_ext_clk(w->codec, 1, true); break; #endif + case SND_SOC_DAPM_PRE_PMU: + if (pdata->codec_type) + msm8x16_enable_extcodec_ext_clk(w->codec, 1, true); + break; case SND_SOC_DAPM_POST_PMD: pr_debug("%s: mclk_res_ref = %d\n", __func__, atomic_read(&pdata->mclk_rsc_ref)); @@ -1411,6 +1611,8 @@ static int msm8x16_mclk_event(struct snd_soc_dapm_widget *w, pr_err("%s: error during pinctrl state select\n", __func__); } + } else { + msm8x16_enable_extcodec_ext_clk(w->codec, 0, true); } break; default: @@ -1456,7 +1658,6 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) int ret; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_card *card = rtd->card; - struct snd_soc_codec *codec = rtd->codec; struct msm8916_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); pr_debug("%s(): substream = %s stream = %d\n", __func__, @@ -1474,24 +1675,15 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) atomic_read(&pdata->mclk_rsc_ref)); } } else { - ret = msm_gpioset_suspend(CLIENT_WCD_EXT, "pri_i2s"); - if (ret < 0) { - pr_err("%s: gpio set cannot be de-activated %sd", - __func__, "quin_i2s"); - return; - } - ret = msm8x16_enable_extcodec_ext_clk(codec, 0, false); + ret = msm_gpioset_suspend(CLIENT_WCD_EXT, "pri_i2s"); if (ret < 0) { - pr_err("%s: failed to enable mclk; ret=%d\n", - __func__, ret); + pr_err("%s: gpio set cannot be de-activated %sd", + __func__, "quin_i2s"); return; } - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - ret = ext_mi2s_clk_ctl(substream, false, - AFE_PORT_ID_PRIMARY_MI2S_RX); - else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - ret = ext_mi2s_clk_ctl(substream, false, - AFE_PORT_ID_PRIMARY_MI2S_TX); + ret = ext_mi2s_clk_ctl(substream, false); + if (ret < 0) + pr_err("%s: failed to enable sclk\n", __func__); } } @@ -1737,19 +1929,11 @@ static int msm_quat_mi2s_snd_startup(struct snd_pcm_substream *substream) __func__); return ret; } - ret = msm8x16_enable_extcodec_ext_clk(codec, 1, true); + ret = ext_mi2s_clk_ctl(substream, true); if (ret < 0) { - pr_err("%s: failed to enable mclk; ret=%d\n", - __func__, ret); + pr_err("%s: failed to enable sclk\n", __func__); return ret; } - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - ret = ext_mi2s_clk_ctl(substream, true, - AFE_PORT_ID_QUATERNARY_MI2S_RX); - } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { - ret = ext_mi2s_clk_ctl(substream, true, - AFE_PORT_ID_QUATERNARY_MI2S_TX); - } } if (atomic_inc_return(&quat_mi2s_clk_ref) == 1) { ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS); @@ -1808,18 +1992,9 @@ static void msm_quat_mi2s_snd_shutdown(struct snd_pcm_substream *substream) __func__, "quin_i2s"); } - ret = msm8x16_enable_extcodec_ext_clk(codec, 0, false); - if (ret < 0) { - pr_err("%s: failed to enable mclk; ret=%d\n", - __func__, ret); - return; - } - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - ret = ext_mi2s_clk_ctl(substream, false, - AFE_PORT_ID_QUATERNARY_MI2S_RX); - else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - ret = ext_mi2s_clk_ctl(substream, false, - AFE_PORT_ID_QUATERNARY_MI2S_TX); + ret = ext_mi2s_clk_ctl(substream, false); + if (ret < 0) + pr_err("%s: failed to disable sclk\n", __func__); if (atomic_read(&quat_mi2s_clk_ref) > 0) atomic_dec(&quat_mi2s_clk_ref); @@ -1911,18 +2086,11 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) return ret; } - ret = msm8x16_enable_extcodec_ext_clk(codec, 1, true); + ret = ext_mi2s_clk_ctl(substream, true); if (ret < 0) { - pr_err("%s: failed to enable mclk; ret=%d\n", - __func__, ret); + pr_err("%s: failed to enable sclk\n", __func__); return ret; } - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - ret = ext_mi2s_clk_ctl(substream, true, - AFE_PORT_ID_PRIMARY_MI2S_RX); - else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - ret = ext_mi2s_clk_ctl(substream, true, - AFE_PORT_ID_PRIMARY_MI2S_TX); } ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS); if (ret < 0) @@ -2093,6 +2261,9 @@ static int msm_audrx_init_wcd(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_new_controls(dapm, msm8x16_dapm_widgets, ARRAY_SIZE(msm8x16_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, wcd9335_audio_paths, + ARRAY_SIZE(wcd9335_audio_paths)); + snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1"); @@ -3773,6 +3944,15 @@ static int msm8x16_asoc_machine_probe(struct platform_device *pdev) ret); goto err; } + + ret = core_get_adsp_ver(); + if (ret < 0) { + ret = -EPROBE_DEFER; + dev_info(&pdev->dev, "%s: Get adsp version failed (%d)\n", + __func__, ret); + goto err; + } + return 0; err: if (pdata->vaddr_gpio_mux_spkr_ctl) diff --git a/sound/soc/msm/qdsp6v2/audio_cal_utils.c b/sound/soc/msm/qdsp6v2/audio_cal_utils.c index 95ad79af15bd8..c8e754474c3bb 100644 --- a/sound/soc/msm/qdsp6v2/audio_cal_utils.c +++ b/sound/soc/msm/qdsp6v2/audio_cal_utils.c @@ -56,6 +56,7 @@ size_t get_cal_info_size(int32_t cal_type) size = sizeof(struct audio_cal_info_adm_top); break; case ADM_CUST_TOPOLOGY_CAL_TYPE: + case CORE_CUSTOM_TOPOLOGIES_CAL_TYPE: size = 0; break; case ADM_AUDPROC_CAL_TYPE: @@ -174,6 +175,7 @@ size_t get_user_cal_type_size(int32_t cal_type) size = sizeof(struct audio_cal_type_adm_top); break; case ADM_CUST_TOPOLOGY_CAL_TYPE: + case CORE_CUSTOM_TOPOLOGIES_CAL_TYPE: size = sizeof(struct audio_cal_type_basic); break; case ADM_AUDPROC_CAL_TYPE: @@ -580,7 +582,7 @@ static struct cal_block_data *create_cal_block(struct cal_type_data *cal_type, goto err; } cal_block->buffer_number = basic_cal->cal_hdr.buffer_number; - pr_debug("%s: created block for cal type %d, buf num %d, map handle %d, map size %zd paddr 0x%pa!\n", + pr_debug("%s: created block for cal type %d, buf num %d, map handle %d, map size %zd paddr 0x%pK!\n", __func__, cal_type->info.reg.cal_type, cal_block->buffer_number, cal_block->map_data.ion_map_handle, diff --git a/sound/soc/msm/qdsp6v2/audio_calibration.c b/sound/soc/msm/qdsp6v2/audio_calibration.c index 29d5e461a0a01..c8806481ed03a 100644 --- a/sound/soc/msm/qdsp6v2/audio_calibration.c +++ b/sound/soc/msm/qdsp6v2/audio_calibration.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014, 2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -496,8 +496,8 @@ static long audio_cal_shared_ioctl(struct file *file, unsigned int cmd, goto unlock; if ((sizeof(data->hdr) + data->hdr.cal_type_size) > size) { pr_err("%s: header size %zd plus cal type size %d are greater than data buffer size %d\n", - __func__, sizeof(data->hdr), - data->hdr.cal_type_size, size); + __func__, sizeof(data->hdr), + data->hdr.cal_type_size, size); ret = -EFAULT; goto unlock; } else if (copy_to_user((void *)arg, data, diff --git a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c index cec79eaa81e4c..ccd9cdd951b6e 100644 --- a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c @@ -192,7 +192,7 @@ static void compr_event_handler(uint32_t opcode, pr_debug("%s:writing %d bytes of buffer[%d] to dsp 2\n", __func__, prtd->pcm_count, prtd->out_head); temp = buf[0].phys + (prtd->out_head * prtd->pcm_count); - pr_debug("%s:writing buffer[%d] from 0x%pa\n", + pr_debug("%s:writing buffer[%d] from 0x%pK\n", __func__, prtd->out_head, &temp); if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) @@ -243,7 +243,7 @@ static void compr_event_handler(uint32_t opcode, break; case ASM_DATA_EVENT_READ_DONE_V2: { pr_debug("ASM_DATA_EVENT_READ_DONE\n"); - pr_debug("buf = %p, data = 0x%X, *data = %p,\n" + pr_debug("buf = %pK, data = 0x%X, *data = %pK,\n" "prtd->pcm_irq_pos = %d\n", prtd->audio_client->port[OUT].buf, *(uint32_t *)prtd->audio_client->port[OUT].buf->data, @@ -253,7 +253,7 @@ static void compr_event_handler(uint32_t opcode, memcpy(prtd->audio_client->port[OUT].buf->data + prtd->pcm_irq_pos, (ptrmem + READDONE_IDX_SIZE), COMPRE_CAPTURE_HEADER_SIZE); - pr_debug("buf = %p, updated data = 0x%X, *data = %p\n", + pr_debug("buf = %pK, updated data = 0x%X, *data = %pK\n", prtd->audio_client->port[OUT].buf, *(uint32_t *)(prtd->audio_client->port[OUT].buf->data + prtd->pcm_irq_pos), @@ -269,7 +269,7 @@ static void compr_event_handler(uint32_t opcode, } buf = prtd->audio_client->port[OUT].buf; - pr_debug("pcm_irq_pos=%d, buf[0].phys = 0x%pa\n", + pr_debug("pcm_irq_pos=%d, buf[0].phys = 0x%pK\n", prtd->pcm_irq_pos, &buf[0].phys); read_param.len = prtd->pcm_count - COMPRE_CAPTURE_HEADER_SIZE; read_param.paddr = buf[0].phys + @@ -295,7 +295,7 @@ static void compr_event_handler(uint32_t opcode, pr_debug("%s: writing %d bytes of buffer[%d] to dsp\n", __func__, prtd->pcm_count, prtd->out_head); buf = prtd->audio_client->port[IN].buf; - pr_debug("%s: writing buffer[%d] from 0x%pa head %d count %d\n", + pr_debug("%s: writing buffer[%d] from 0x%pK head %d count %d\n", __func__, prtd->out_head, &buf[0].phys, prtd->pcm_count, prtd->out_head); if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) @@ -602,7 +602,7 @@ static int msm_compr_capture_prepare(struct snd_pcm_substream *substream) - COMPRE_CAPTURE_HEADER_SIZE; read_param.paddr = buf[i].phys + COMPRE_CAPTURE_HEADER_SIZE; - pr_debug("Push buffer [%d] to DSP, paddr: %pa, vaddr: %p\n", + pr_debug("Push buffer [%d] to DSP, paddr: %pK, vaddr: %pK\n", i, &read_param.paddr, buf[i].data); q6asm_async_read(prtd->audio_client, &read_param); @@ -963,7 +963,7 @@ static int msm_compr_hw_params(struct snd_pcm_substream *substream, dma_buf->addr = buf[0].phys; dma_buf->bytes = runtime->hw.buffer_bytes_max; - pr_debug("%s: buf[%p]dma_buf->area[%p]dma_buf->addr[%pa]\n" + pr_debug("%s: buf[%pK]dma_buf->area[%pK]dma_buf->addr[%pK]\n" "dma_buf->bytes[%zd]\n", __func__, (void *)buf, (void *)dma_buf->area, &dma_buf->addr, dma_buf->bytes); @@ -1036,6 +1036,7 @@ static int msm_compr_ioctl_shared(struct snd_pcm_substream *substream, struct snd_dec_ddp *ddp = &compr->info.codec_param.codec.options.ddp; uint32_t params_length = 0; + memset(params_value, 0, MAX_AC3_PARAM_SIZE); /* check integer overflow */ if (ddp->params_length > UINT_MAX/sizeof(int)) { pr_err("%s: Integer overflow ddp->params_length %d\n", @@ -1076,13 +1077,16 @@ static int msm_compr_ioctl_shared(struct snd_pcm_substream *substream, struct snd_dec_ddp *ddp = &compr->info.codec_param.codec.options.ddp; uint32_t params_length = 0; + memset(params_value, 0, MAX_AC3_PARAM_SIZE); /* check integer overflow */ if (ddp->params_length > UINT_MAX/sizeof(int)) { pr_err("%s: Integer overflow ddp->params_length %d\n", __func__, ddp->params_length); return -EINVAL; } - params_length = ddp->params_length*sizeof(int); + + params_length = ddp->params_length*sizeof(int); + if (params_length > MAX_AC3_PARAM_SIZE) { /*MAX is 36*sizeof(int) this should not happen*/ pr_err("%s: params_length(%d) is greater than %zd\n", diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c index 5f137b89d06d6..78e1eec390f33 100644 --- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -99,6 +100,7 @@ struct msm_compr_pdata { struct msm_compr_audio_effects *audio_effects[MSM_FRONTEND_DAI_MAX]; bool use_dsp_gapless_mode; struct msm_compr_dec_params *dec_params[MSM_FRONTEND_DAI_MAX]; + struct msm_compr_ch_map *ch_map[MSM_FRONTEND_DAI_MAX]; }; struct msm_compr_audio { @@ -181,6 +183,11 @@ struct msm_compr_dec_params { struct snd_dec_ddp ddp_params; }; +struct msm_compr_ch_map { + bool set_ch_map; + char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL]; +}; + static int msm_compr_send_dec_params(struct snd_compr_stream *cstream, struct msm_compr_dec_params *dec_params, int stream_id); @@ -189,8 +196,13 @@ static int msm_compr_set_volume(struct snd_compr_stream *cstream, uint32_t volume_l, uint32_t volume_r) { struct msm_compr_audio *prtd; - int rc = 0; - uint32_t avg_vol; + int i, rc = -1; + uint32_t avg_vol, gain_list[VOLUME_CONTROL_MAX_CHANNELS]; + uint32_t num_channels; + struct snd_soc_pcm_runtime *rtd; + struct msm_compr_pdata *pdata; + bool use_default = true; + u8 *chmap = NULL; pr_debug("%s: volume_l %d volume_r %d\n", __func__, volume_l, volume_r); @@ -198,18 +210,30 @@ static int msm_compr_set_volume(struct snd_compr_stream *cstream, pr_err("%s: session not active\n", __func__); return -EPERM; } + rtd = cstream->private_data; prtd = cstream->runtime->private_data; if (!prtd || !prtd->audio_client) { - pr_err("%s: invalid session prtd or no audio client", __func__); + pr_err("%s: invalid session/rtd, prtd or no audio client", + __func__); return rc; } + pdata = snd_soc_platform_get_drvdata(rtd->platform); if (prtd->compr_passthr != LEGACY_PCM) { pr_debug("%s: No volume config for passthrough %d\n", __func__, prtd->compr_passthr); return rc; } + + use_default = !(pdata->ch_map[rtd->dai_link->be_id]->set_ch_map); + chmap = pdata->ch_map[rtd->dai_link->be_id]->channel_map; + num_channels = prtd->num_channels; + pr_debug("%s: call q6asm_set_volume volume_l(%d)volume_r(%d)num of channels(%d)\n", + __func__, volume_l, volume_r, prtd->num_channels); + pr_debug("%s: AVS version(%d): 0 for AVS2.6, 1 for AVS2.7\n", + __func__, q6core_get_avs_version()); + if (prtd->num_channels > 2) { /* * Currently the left and right gains are averaged an applied @@ -220,28 +244,64 @@ static int msm_compr_set_volume(struct snd_compr_stream *cstream, * channel gains. * */ - pr_debug("%s: call q6asm_set_volume for multichannel\n", - __func__); - avg_vol = (volume_l + volume_r) / 2; - rc = q6asm_set_volume(prtd->audio_client, avg_vol); + switch (q6core_get_avs_version()) { + case Q6_SUBSYS_AVS2_7: + case Q6_SUBSYS_AVS2_8: + avg_vol = (volume_l + volume_r) / 2; + for (i = 0; i < prtd->num_channels; i++) + gain_list[i] = avg_vol; + rc = q6asm_set_multich_gain(prtd->audio_client, + num_channels, gain_list, chmap, use_default); + break; + case Q6_SUBSYS_AVS2_6: + avg_vol = (volume_l + volume_r) / 2; + rc = q6asm_set_volume(prtd->audio_client, avg_vol); + break; + case Q6_SUBSYS_INVALID: + default: + pr_err("%s: UNKNOWN AVS IMAGE\n", __func__); + return rc; + } } else { - pr_debug("%s: call q6asm_set_lrgain\n", __func__); - rc = q6asm_set_lrgain(prtd->audio_client, volume_l, volume_r); - if (rc < 0) { - pr_err("%s: Send LR gain command failed rc=%d\n", - __func__, rc); - } else { - pr_debug("%s: now calling msm_dts_eagle_set_volume\n", - __func__); - rc = msm_dts_eagle_set_volume(prtd->audio_client, - volume_l, volume_r); - if (rc < 0) { - pr_err("%s: Send Volume command failed (DTS_EAGLE) rc=%d\n", + switch (q6core_get_avs_version()) { + case Q6_SUBSYS_AVS2_7: + case Q6_SUBSYS_AVS2_8: + gain_list[0] = volume_l; + gain_list[1] = volume_r; + /* force sending FR/FL/FC volume for mono */ + if (prtd->num_channels == 1) { + gain_list[2] = volume_l; + num_channels = 3; + use_default = true; + } + rc = q6asm_set_multich_gain(prtd->audio_client, + num_channels, gain_list, chmap, use_default); + break; + case Q6_SUBSYS_AVS2_6: + pr_debug("%s: call q6asm_set_lrgain\n", __func__); + rc = q6asm_set_lrgain(prtd->audio_client, + volume_l, volume_r); + if (rc < 0) + pr_err("%s: Send LR gain command failed rc=%d\n", + __func__, rc); + else { + pr_debug("%s: now calling msm_dts_eagle_set_volume\n", + __func__); + rc = msm_dts_eagle_set_volume( + prtd->audio_client, + volume_l, volume_r); + if (rc < 0) { + pr_err("%s: Send Volume command failed (DTS_EAGLE) rc=%d\n", __func__, rc); + } } + break; + case Q6_SUBSYS_INVALID: + default: + pr_err("%s: UNKNOWN AVS IMAGE\n", __func__); + return rc; } } - if (rc < 0) pr_err("%s: Send vol gain command failed rc=%d\n", __func__, rc); @@ -613,6 +673,9 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream, { struct snd_compr_runtime *runtime = cstream->runtime; struct msm_compr_audio *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = cstream->private_data; + struct msm_compr_pdata *pdata = + snd_soc_platform_get_drvdata(rtd->platform); struct asm_aac_cfg aac_cfg; struct asm_wma_cfg wma_cfg; struct asm_wmapro_cfg wma_pro_cfg; @@ -624,6 +687,8 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream, int ret = 0; uint16_t bit_width = 16; + bool use_default_chmap = true; + char *chmap = NULL; pr_debug("%s: use_gapless_codec_options %d\n", __func__, use_gapless_codec_options); @@ -641,13 +706,21 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream, switch (prtd->codec) { case FORMAT_LINEAR_PCM: pr_debug("SND_AUDIOCODEC_PCM\n"); + if (pdata->ch_map[rtd->dai_link->be_id]) { + use_default_chmap = + !(pdata->ch_map[rtd->dai_link->be_id]->set_ch_map); + chmap = + pdata->ch_map[rtd->dai_link->be_id]->channel_map; + } if (prtd->codec_param.codec.format == SNDRV_PCM_FORMAT_S24_LE) bit_width = 24; ret = q6asm_media_format_block_pcm_format_support_v2( prtd->audio_client, prtd->sample_rate, prtd->num_channels, - bit_width, stream_id); + bit_width, stream_id, + use_default_chmap, + chmap); if (ret < 0) pr_err("%s: CMD Format block failed\n", __func__); @@ -1171,7 +1244,9 @@ static int msm_compr_free(struct snd_compr_stream *cstream) q6asm_audio_client_free(ac); kfree(pdata->audio_effects[soc_prtd->dai_link->be_id]); + pdata->audio_effects[soc_prtd->dai_link->be_id] = NULL; kfree(pdata->dec_params[soc_prtd->dai_link->be_id]); + pdata->dec_params[soc_prtd->dai_link->be_id] = NULL; kfree(prtd); return 0; @@ -1688,9 +1763,31 @@ static int msm_compr_trigger(struct snd_compr_stream *cstream, int cmd) /* * Cache this time as last known time */ - q6asm_get_session_time(prtd->audio_client, - &prtd->marker_timestamp); + switch (q6core_get_avs_version()) { + case (Q6_SUBSYS_AVS2_7): + case (Q6_SUBSYS_AVS2_8): + { + q6asm_get_session_time(prtd->audio_client, + &prtd->marker_timestamp); + break; + } + case (Q6_SUBSYS_AVS2_6): + { + q6asm_get_session_time_legacy( + prtd->audio_client, + &prtd->marker_timestamp); + break; + } + case (Q6_SUBSYS_INVALID): + default: + { + pr_err("%s: UNKNOWN AVS IMAGE VERSION\n", + __func__); + break; + } + } spin_lock_irqsave(&prtd->lock, flags); + /* * Don't reset these as these vars map to * total_bytes_transferred and total_bytes_available. @@ -1847,7 +1944,28 @@ static int msm_compr_pointer(struct snd_compr_stream *cstream, pr_debug("%s session time in gapless transition", __func__); - rc = q6asm_get_session_time(prtd->audio_client, ×tamp); + switch (q6core_get_avs_version()) { + case (Q6_SUBSYS_AVS2_7): + case (Q6_SUBSYS_AVS2_8): + { + rc = q6asm_get_session_time(prtd->audio_client, + ×tamp); + break; + } + case (Q6_SUBSYS_AVS2_6): + { + rc = q6asm_get_session_time_legacy( + prtd->audio_client, ×tamp); + break; + } + case (Q6_SUBSYS_INVALID): + default: + { + pr_err("%s: UNKNOWN AVS IMAGE VERSION\n", __func__); + rc = -EINVAL; + break; + } + } if (rc < 0) { pr_err("%s: Get Session Time return value =%lld\n", __func__, timestamp); @@ -1992,7 +2110,7 @@ static int msm_compr_get_caps(struct snd_compr_stream *cstream, memcpy(arg, &prtd->compr_cap, sizeof(struct snd_compr_caps)); } else { ret = -EINVAL; - pr_err("%s: arg (0x%p), prtd (0x%p)\n", __func__, arg, prtd); + pr_err("%s: arg (0x%pK), prtd (0x%pK)\n", __func__, arg, prtd); } return ret; @@ -2455,6 +2573,64 @@ static int msm_compr_app_type_cfg_get(struct snd_kcontrol *kcontrol, return 0; } +static int msm_compr_channel_map_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_platform *platform = snd_kcontrol_chip(kcontrol); + u64 fe_id = kcontrol->private_value; + struct msm_compr_pdata *pdata = (struct msm_compr_pdata *) + snd_soc_platform_get_drvdata(platform); + int rc = 0, i; + + pr_debug("%s: fe_id- %llu\n", __func__, fe_id); + + if (fe_id >= MSM_FRONTEND_DAI_MAX) { + pr_err("%s Received out of bounds fe_id %llu\n", + __func__, fe_id); + rc = -EINVAL; + goto end; + } + + if (pdata->ch_map[fe_id]) { + pdata->ch_map[fe_id]->set_ch_map = true; + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) + pdata->ch_map[fe_id]->channel_map[i] = + (char)(ucontrol->value.integer.value[i]); + } else { + pr_debug("%s: no memory for ch_map, default will be set\n", + __func__); + } +end: + pr_debug("%s: ret %d\n", __func__, rc); + return rc; +} + +static int msm_compr_channel_map_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_platform *platform = snd_kcontrol_chip(kcontrol); + u64 fe_id = kcontrol->private_value; + struct msm_compr_pdata *pdata = (struct msm_compr_pdata *) + snd_soc_platform_get_drvdata(platform); + int rc = 0, i; + + pr_debug("%s: fe_id- %llu\n", __func__, fe_id); + if (fe_id >= MSM_FRONTEND_DAI_MAX) { + pr_err("%s: Received out of bounds fe_id %llu\n", + __func__, fe_id); + rc = -EINVAL; + goto end; + } + if (pdata->ch_map[fe_id]) { + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) + ucontrol->value.integer.value[i] = + pdata->ch_map[fe_id]->channel_map[i]; + } +end: + pr_debug("%s: ret %d\n", __func__, rc); + return rc; +} + static int msm_compr_probe(struct snd_soc_platform *platform) { struct msm_compr_pdata *pdata; @@ -2476,6 +2652,7 @@ static int msm_compr_probe(struct snd_soc_platform *platform) pdata->audio_effects[i] = NULL; pdata->dec_params[i] = NULL; pdata->cstream[i] = NULL; + pdata->ch_map[i] = NULL; } /* @@ -2528,6 +2705,16 @@ static int msm_compr_app_type_cfg_info(struct snd_kcontrol *kcontrol, return 0; } +static int msm_compr_channel_map_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 8; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 0xFFFFFFFF; + return 0; +} + static int msm_compr_add_volume_control(struct snd_soc_pcm_runtime *rtd) { const char *mixer_ctl_name = "Compress Playback"; @@ -2754,6 +2941,65 @@ static int msm_compr_add_app_type_cfg_control(struct snd_soc_pcm_runtime *rtd) return 0; } +static int msm_compr_add_channel_map_control(struct snd_soc_pcm_runtime *rtd) +{ + const char *mixer_ctl_name = "Playback Channel Map"; + const char *deviceNo = "NN"; + char *mixer_str = NULL; + struct msm_compr_pdata *pdata = NULL; + int ctl_len; + struct snd_kcontrol_new fe_channel_map_control[1] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_compr_channel_map_info, + .get = msm_compr_channel_map_get, + .put = msm_compr_channel_map_put, + .private_value = 0, + } + }; + + if (!rtd) { + pr_err("%s: NULL rtd\n", __func__); + return -EINVAL; + } + + pr_debug("%s: added new compr FE with name %s, id %d, cpu dai %s, device no %d\n", + __func__, rtd->dai_link->name, rtd->dai_link->be_id, + rtd->dai_link->cpu_dai_name, rtd->pcm->device); + + ctl_len = strlen(mixer_ctl_name) + strlen(deviceNo) + 1; + mixer_str = kzalloc(ctl_len, GFP_KERNEL); + + if (!mixer_str) { + pr_err("%s: failed to allocate mixer ctrl str of len %d\n", + __func__, ctl_len); + return -ENOMEM; + } + + snprintf(mixer_str, ctl_len, "%s%d", mixer_ctl_name, rtd->pcm->device); + + fe_channel_map_control[0].name = mixer_str; + fe_channel_map_control[0].private_value = rtd->dai_link->be_id; + pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str); + snd_soc_add_platform_controls(rtd->platform, + fe_channel_map_control, + ARRAY_SIZE(fe_channel_map_control)); + + pdata = snd_soc_platform_get_drvdata(rtd->platform); + pdata->ch_map[rtd->dai_link->be_id] = + kzalloc(sizeof(struct msm_compr_ch_map), GFP_KERNEL); + if (!pdata->ch_map[rtd->dai_link->be_id]) { + pr_err("%s: Could not allocate memory for channel map\n", + __func__); + kfree(mixer_str); + return -ENOMEM; + } + kfree(mixer_str); + return 0; +} + static int msm_compr_new(struct snd_soc_pcm_runtime *rtd) { int rc; @@ -2771,7 +3017,11 @@ static int msm_compr_new(struct snd_soc_pcm_runtime *rtd) __func__); rc = msm_compr_add_app_type_cfg_control(rtd); if (rc) - pr_err("%s: Could not add Compr Dec runtime params Control\n", + pr_err("%s: Could not add Compr App Type Cfg Control\n", + __func__); + rc = msm_compr_add_channel_map_control(rtd); + if (rc) + pr_err("%s: Could not add Compr Channel Map Control\n", __func__); return 0; } diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c index 8787fb35e7a5e..0ad6f9f1c15d9 100644 --- a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1666,7 +1666,7 @@ static int msm_auxpcm_dev_probe(struct platform_device *pdev) goto fail_pdata_nomem; } - dev_dbg(&pdev->dev, "%s: dev %p, dai_data %p, auxpcm_pdata %p\n", + dev_dbg(&pdev->dev, "%s: dev %pK, dai_data %pK, auxpcm_pdata %pK\n", __func__, &pdev->dev, dai_data, auxpcm_pdata); rc = of_property_read_u32_array(pdev->dev.of_node, diff --git a/sound/soc/msm/qdsp6v2/msm-dai-slim.c b/sound/soc/msm/qdsp6v2/msm-dai-slim.c index a93dfa6ec853c..618da977ef1ef 100644 --- a/sound/soc/msm/qdsp6v2/msm-dai-slim.c +++ b/sound/soc/msm/qdsp6v2/msm-dai-slim.c @@ -446,7 +446,9 @@ static void msm_dai_slim_remove_dai_data( dai_data_t = &drv_data->slim_dai_data[i]; kfree(dai_data_t->chan_h); + dai_data_t->chan_h = NULL; kfree(dai_data_t->sh_ch); + dai_data_t->sh_ch = NULL; } } diff --git a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c index 83a85377aad57..75bb08da21b69 100644 --- a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c +++ b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c @@ -1103,7 +1103,7 @@ static int msm_ds2_dap_send_end_point(int dev_map_idx, int endp_idx) ds2_ap_params_obj = &ds2_dap_params[cache_device]; pr_debug("%s: cache dev %d, dev_map_idx %d\n", __func__, cache_device, dev_map_idx); - pr_debug("%s: endp - %p %p\n", __func__, + pr_debug("%s: endp - %pK %pK\n", __func__, &ds2_dap_params[cache_device], ds2_ap_params_obj); params_value = kzalloc(params_length, GFP_KERNEL); @@ -1189,7 +1189,7 @@ static int msm_ds2_dap_send_cached_params(int dev_map_idx, } ds2_ap_params_obj = &ds2_dap_params[cache_device]; - pr_debug("%s: cached param - %p %p, cache_device %d\n", __func__, + pr_debug("%s: cached param - %pK %pK, cache_device %d\n", __func__, &ds2_dap_params[cache_device], ds2_ap_params_obj, cache_device); params_value = kzalloc(params_length, GFP_KERNEL); diff --git a/sound/soc/msm/qdsp6v2/msm-dts-eagle.c b/sound/soc/msm/qdsp6v2/msm-dts-eagle.c index 3b334c3fc9152..359cdc96ca272 100644 --- a/sound/soc/msm/qdsp6v2/msm-dts-eagle.c +++ b/sound/soc/msm/qdsp6v2/msm-dts-eagle.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014, 2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -487,7 +487,7 @@ int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg) pr_info("DTS_EAGLE_DRIVER_POST: %s called with control 0x%X (allocate param cache)\n", __func__, cmd); if (copy_from_user((void *)&size, (void *)arg, sizeof(size))) { - pr_err("DTS_EAGLE_DRIVER_POST: error copying size (src:%p, tgt:%p, size:%zu)\n", + pr_err("DTS_EAGLE_DRIVER_POST: error copying size (src:%pK, tgt:%pK, size:%zu)\n", (void *)arg, &size, sizeof(size)); return -EFAULT; } else if (size < 0 || size > DEPC_MAX_SIZE) { @@ -527,7 +527,7 @@ int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg) pr_info("DTS_EAGLE_DRIVER_POST: %s called, control 0x%X (get param)\n", __func__, cmd); if (copy_from_user((void *)&depd, (void *)arg, sizeof(depd))) { - pr_err("DTS_EAGLE_DRIVER_POST: error copying dts_eagle_param_desc (src:%p, tgt:%p, size:%zu)\n", + pr_err("DTS_EAGLE_DRIVER_POST: error copying dts_eagle_param_desc (src:%pK, tgt:%pK, size:%zu)\n", (void *)arg, &depd, sizeof(depd)); return -EFAULT; } @@ -583,7 +583,7 @@ int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg) pr_info("DTS_EAGLE_DRIVER_POST: %s called, control 0x%X (set param)\n", __func__, cmd); if (copy_from_user((void *)&depd, (void *)arg, sizeof(depd))) { - pr_err("DTS_EAGLE_DRIVER_POST: error copying dts_eagle_param_desc (src:%p, tgt:%p, size:%zu)\n", + pr_err("DTS_EAGLE_DRIVER_POST: error copying dts_eagle_param_desc (src:%pK, tgt:%pK, size:%zu)\n", (void *)arg, &depd, sizeof(depd)); return -EFAULT; } @@ -603,7 +603,7 @@ int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg) if (copy_from_user((void *)&_depc[offset], (void *)(((char *)arg)+sizeof(depd)), depd.size)) { - pr_err("DTS_EAGLE_DRIVER_POST: error copying param to cache (src:%p, tgt:%p, size:%i)\n", + pr_err("DTS_EAGLE_DRIVER_POST: error copying param to cache (src:%pK, tgt:%pK, size:%i)\n", ((char *)arg)+sizeof(depd), &_depc[offset], depd.size); return -EFAULT; @@ -639,7 +639,7 @@ int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg) pr_info("DTS_EAGLE_DRIVER_POST: %s called with control 0x%X (set param cache block)\n", __func__, cmd); if (copy_from_user((void *)b_, (void *)arg, sizeof(b_))) { - pr_err("DTS_EAGLE_DRIVER_POST: error copying cache block data (src:%p, tgt:%p, size:%zu)\n", + pr_err("DTS_EAGLE_DRIVER_POST: error copying cache block data (src:%pK, tgt:%pK, size:%zu)\n", (void *)arg, b_, sizeof(b_)); return -EFAULT; } @@ -669,7 +669,7 @@ int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg) pr_info("DTS_EAGLE_DRIVER_POST: %s called with control 0x%X (set active device)\n", __func__, cmd); if (copy_from_user((void *)data, (void *)arg, sizeof(data))) { - pr_err("DTS_EAGLE_DRIVER_POST: error copying active device data (src:%p, tgt:%p, size:%zu)\n", + pr_err("DTS_EAGLE_DRIVER_POST: error copying active device data (src:%pK, tgt:%pK, size:%zu)\n", (void *)arg, data, sizeof(data)); return -EFAULT; } @@ -691,7 +691,7 @@ int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg) __func__, cmd); if (copy_from_user((void *)&target, (void *)arg, sizeof(target))) { - pr_err("DTS_EAGLE_DRIVER_POST: error reading license index. (src:%p, tgt:%p, size:%zu)\n", + pr_err("DTS_EAGLE_DRIVER_POST: error reading license index. (src:%pK, tgt:%pK, size:%zu)\n", (void *)arg, &target, sizeof(target)); return -EFAULT; } @@ -736,7 +736,7 @@ int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg) __func__, cmd); if (copy_from_user((void *)target, (void *)arg, sizeof(target))) { - pr_err("DTS_EAGLE_DRIVER_POST: error reading license index (src:%p, tgt:%p, size:%zu)\n", + pr_err("DTS_EAGLE_DRIVER_POST: error reading license index (src:%pK, tgt:%pK, size:%zu)\n", (void *)arg, target, sizeof(target)); return -EFAULT; } @@ -777,7 +777,7 @@ int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg) if (copy_from_user((void *)&(((__s32 *)sec_blob[target[0]])[1]), (void *)(((char *)arg)+sizeof(target)), target[1])) { - pr_err("DTS_EAGLE_DRIVER_POST: error copying license to index %i, size %i (src:%p, tgt:%p, size:%i)\n", + pr_err("DTS_EAGLE_DRIVER_POST: error copying license to index %i, size %i (src:%pK, tgt:%pK, size:%i)\n", target[0], target[1], ((char *)arg)+sizeof(target), &(((__s32 *)sec_blob[target[0]])[1]), @@ -795,7 +795,7 @@ int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg) __func__, cmd); if (copy_from_user((void *)&target, (void *)arg, sizeof(target))) { - pr_err("DTS_EAGLE_DRIVER_POST: error reading license index (src:%p, tgt:%p, size:%zu)\n", + pr_err("DTS_EAGLE_DRIVER_POST: error reading license index (src:%pK, tgt:%pK, size:%zu)\n", (void *)arg, &target, sizeof(target)); return -EFAULT; } @@ -825,7 +825,7 @@ int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg) __func__, cmd); if (copy_from_user((void *)&spec, (void *)arg, sizeof(spec))) { - pr_err("DTS_EAGLE_DRIVER_POST: error reading volume command specifier (src:%p, tgt:%p, size:%zu)\n", + pr_err("DTS_EAGLE_DRIVER_POST: error reading volume command specifier (src:%pK, tgt:%pK, size:%zu)\n", (void *)arg, &spec, sizeof(spec)); return -EFAULT; } @@ -846,7 +846,7 @@ int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg) if (copy_from_user((void *)&vol_cmds_d[idx], (void *)(((char *)arg) + sizeof(int)), sizeof(struct vol_cmds_d_))) { - pr_err("DTS_EAGLE_DRIVER_POST: error reading volume command descriptor (src:%p, tgt:%p, size:%zu)\n", + pr_err("DTS_EAGLE_DRIVER_POST: error reading volume command descriptor (src:%pK, tgt:%pK, size:%zu)\n", ((char *)arg) + sizeof(int), &vol_cmds_d[idx], sizeof(struct vol_cmds_d_)); @@ -859,7 +859,7 @@ int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg) if (copy_from_user((void *)vol_cmds[idx], (void *)(((char *)arg) + (sizeof(int) + sizeof(struct vol_cmds_d_))), size)) { - pr_err("DTS_EAGLE_DRIVER_POST: error reading volume command string (src:%p, tgt:%p, size:%i)\n", + pr_err("DTS_EAGLE_DRIVER_POST: error reading volume command string (src:%pK, tgt:%pK, size:%i)\n", ((char *)arg) + (sizeof(int) + sizeof(struct vol_cmds_d_)), vol_cmds[idx], size); @@ -909,7 +909,7 @@ int msm_dts_eagle_init_pre(struct audio_client *ac) if (_depc_size == 0 || !_depc || offset < 0 || size <= 0 || cmd == 0 || (offset + size) > _depc_size) { - pr_err("DTS_EAGLE_DRIVER_SENDCACHE_PRE: in %s, primary device %i cache index %i general error - cache size = %u, cache ptr = %p, offset = %i, size = %i, cmd = %i\n", + pr_err("DTS_EAGLE_DRIVER_SENDCACHE_PRE: in %s, primary device %i cache index %i general error - cache size = %u, cache ptr = %pK, offset = %i, size = %i, cmd = %i\n", __func__, _device_primary, cidx, _depc_size, _depc, offset, size, cmd); return -EINVAL; @@ -984,7 +984,7 @@ int msm_dts_eagle_init_post(int port_id, int copp_idx, int topology) if (_depc_size == 0 || !_depc || offset < 0 || size <= 0 || cmd == 0 || (offset + size) > _depc_size) { - pr_err("DTS_EAGLE_DRIVER_SENDCACHE_POST: in %s, primary device %i cache index %i port_id 0x%X general error - cache size = %u, cache ptr = %p, offset = %i, size = %i, cmd = %i\n", + pr_err("DTS_EAGLE_DRIVER_SENDCACHE_POST: in %s, primary device %i cache index %i port_id 0x%X general error - cache size = %u, cache ptr = %pK, offset = %i, size = %i, cmd = %i\n", __func__, _device_primary, cidx, port_id, _depc_size, _depc, offset, size, cmd); return -EINVAL; diff --git a/sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.c b/sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.c index dc5e84fb7e5eb..1fb31ea331ede 100644 --- a/sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.c +++ b/sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2014, 2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -289,8 +289,8 @@ static int reg_ion_mem(void) &po.kvaddr); if (rc != 0) pr_err("%s: failed to allocate memory.\n", __func__); - pr_debug("%s: exited ion_client = %p, ion_handle = %p, phys_addr = %lu,\ - length = %d, vaddr = %p, rc = 0x%x\n", + pr_debug("%s: exited ion_client = %pK, ion_handle = %pK, phys_addr = %lu,\ + length = %d, vaddr = %pK, rc = 0x%x\n", __func__, ion_client, ion_handle, (long)po.paddr, (unsigned int)po.size, po.kvaddr, rc); return rc; diff --git a/sound/soc/msm/qdsp6v2/msm-lsm-client.c b/sound/soc/msm/qdsp6v2/msm-lsm-client.c index 27aff76a2cd6b..f7cecd5396cd7 100644 --- a/sound/soc/msm/qdsp6v2/msm-lsm-client.c +++ b/sound/soc/msm/qdsp6v2/msm-lsm-client.c @@ -100,7 +100,7 @@ static int msm_lsm_queue_lab_buffer(struct lsm_priv *prtd, int i) struct snd_soc_pcm_runtime *rtd; if (!prtd || !prtd->lsm_client) { - pr_err("%s: Invalid params prtd %p lsm client %p\n", + pr_err("%s: Invalid params prtd %pK lsm client %pK\n", __func__, prtd, ((!prtd) ? NULL : prtd->lsm_client)); return -EINVAL; } @@ -114,7 +114,7 @@ static int msm_lsm_queue_lab_buffer(struct lsm_priv *prtd, int i) if (!prtd->lsm_client->lab_buffer || i >= prtd->lsm_client->hw_params.period_count) { dev_err(rtd->dev, - "%s: Lab buffer not setup %p incorrect index %d period count %d\n", + "%s: Lab buffer not setup %pK incorrect index %d period count %d\n", __func__, prtd->lsm_client->lab_buffer, i, prtd->lsm_client->hw_params.period_count); return -EINVAL; @@ -141,7 +141,7 @@ static int lsm_lab_buffer_sanity(struct lsm_priv *prtd, struct snd_soc_pcm_runtime *rtd; if (!prtd || !read_done || !index) { - pr_err("%s: Invalid params prtd %p read_done %p index %p\n", + pr_err("%s: Invalid params prtd %pK read_done %pK index %pK\n", __func__, prtd, read_done, index); return -EINVAL; } @@ -155,7 +155,7 @@ static int lsm_lab_buffer_sanity(struct lsm_priv *prtd, if (!prtd->lsm_client->lab_enable || !prtd->lsm_client->lab_buffer) { dev_err(rtd->dev, - "%s: Lab not enabled %d invalid lab buffer %p\n", + "%s: Lab not enabled %d invalid lab buffer %pK\n", __func__, prtd->lsm_client->lab_enable, prtd->lsm_client->lab_buffer); return -EINVAL; @@ -169,7 +169,7 @@ static int lsm_lab_buffer_sanity(struct lsm_priv *prtd, (prtd->lsm_client->lab_buffer[i].mem_map_handle == read_done->mem_map_handle)) { dev_dbg(rtd->dev, - "%s: Buffer found %pa memmap handle %d\n", + "%s: Buffer found %pK memmap handle %d\n", __func__, &prtd->lsm_client->lab_buffer[i].phys, prtd->lsm_client->lab_buffer[i].mem_map_handle); if (read_done->total_size > @@ -216,7 +216,7 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, if (prtd->lsm_client->session != token || !read_done) { dev_err(rtd->dev, - "%s: EVENT_READ_DONE invalid callback, session %d callback %d payload %p", + "%s: EVENT_READ_DONE invalid callback, session %d callback %d payload %pK", __func__, prtd->lsm_client->session, token, read_done); return; @@ -315,7 +315,7 @@ static int msm_lsm_lab_buffer_alloc(struct lsm_priv *lsm, int alloc) int ret = 0; struct snd_dma_buffer *dma_buf = NULL; if (!lsm) { - pr_err("%s: Invalid param lsm %p\n", __func__, lsm); + pr_err("%s: Invalid param lsm %pK\n", __func__, lsm); return -EINVAL; } if (alloc) { @@ -787,7 +787,7 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, snd_model_v2.data, snd_model_v2.data_size)) { dev_err(rtd->dev, "%s: copy from user data failed\n" - "data %p size %d\n", __func__, + "data %pK size %d\n", __func__, snd_model_v2.data, snd_model_v2.data_size); q6lsm_snd_model_buf_free(prtd->lsm_client); rc = -EFAULT; @@ -1111,6 +1111,7 @@ struct snd_lsm_detection_params_32 { enum lsm_detection_mode detect_mode; u8 num_confidence_levels; bool detect_failure; + bool poll_enable; }; struct lsm_params_info_32 { @@ -1292,6 +1293,7 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, det_params32.num_confidence_levels; det_params.detect_failure = det_params32.detect_failure; + det_params.poll_enable = det_params32.poll_enable; cmd = SNDRV_LSM_SET_PARAMS; err = msm_lsm_ioctl_shared(substream, cmd, &det_params); @@ -1728,7 +1730,6 @@ static int msm_lsm_open(struct snd_pcm_substream *substream) prtd->lsm_client->poll_enable = true; prtd->lsm_client->perf_mode = 0; prtd->lsm_client->opened = false; - return 0; } @@ -1850,7 +1851,7 @@ static int msm_lsm_hw_params(struct snd_pcm_substream *substream, if (!prtd || !params) { dev_err(rtd->dev, - "%s: invalid params prtd %p params %p", + "%s: invalid params prtd %pK params %pK", __func__, prtd, params); return -EINVAL; } @@ -1892,7 +1893,7 @@ static snd_pcm_uframes_t msm_lsm_pcm_pointer( if (!prtd) { dev_err(rtd->dev, - "%s: Invalid param %p\n", __func__, prtd); + "%s: Invalid param %pK\n", __func__, prtd); return 0; } @@ -1920,7 +1921,7 @@ static int msm_lsm_pcm_copy(struct snd_pcm_substream *substream, int ch, if (!prtd) { dev_err(rtd->dev, - "%s: Invalid param %p\n", __func__, prtd); + "%s: Invalid param %pK\n", __func__, prtd); return -EINVAL; } diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c index d3d1891763dca..f40db1a2b7da9 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -387,7 +387,7 @@ static int msm_afe_open(struct snd_pcm_substream *substream) pr_err("Failed to allocate memory for msm_audio\n"); return -ENOMEM; } else - pr_debug("prtd %p\n", prtd); + pr_debug("prtd %pK\n", prtd); mutex_init(&prtd->lock); spin_lock_init(&prtd->dsp_lock); @@ -606,7 +606,7 @@ static int msm_afe_hw_params(struct snd_pcm_substream *substream, return -ENOMEM; } - pr_debug("%s:buf = %p\n", __func__, buf); + pr_debug("%s:buf = %pK\n", __func__, buf); dma_buf->dev.type = SNDRV_DMA_TYPE_DEV; dma_buf->dev.dev = substream->pcm->card->dev; dma_buf->private_data = NULL; diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-host-voice-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-host-voice-v2.c index c1909778e0822..48f4a2456c847 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-host-voice-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-host-voice-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2014, 2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -504,7 +504,7 @@ static int hpcm_allocate_shared_memory(struct hpcm_drv *prtd) sess->tp_mem_table.size = sizeof(struct vss_imemory_table_t); - pr_debug("%s: data %p phys %pa\n", __func__, + pr_debug("%s: data %pK phys %pK\n", __func__, sess->tp_mem_table.data, &sess->tp_mem_table.phys); /* Split 4096 block into four 1024 byte blocks for each dai */ @@ -682,7 +682,7 @@ void hpcm_notify_evt_processing(uint8_t *data, char *session, } if (tp == NULL || tmd == NULL) { - pr_err("%s: tp = %p or tmd = %p is null\n", __func__, + pr_err("%s: tp = %pK or tmd = %pK is null\n", __func__, tp, tmd); return; diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c index 64d3fe086a6a1..3d31e1eea430d 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2014, 2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -132,7 +132,7 @@ static void event_handler(uint32_t opcode, pr_debug("%s:writing %d bytes of buffer[%d] to dsp 2\n", __func__, prtd->pcm_count, prtd->out_head); temp = buf[0].phys + (prtd->out_head * prtd->pcm_count); - pr_debug("%s:writing buffer[%d] from 0x%pa\n", + pr_debug("%s:writing buffer[%d] from 0x%pK\n", __func__, prtd->out_head, &temp); if (prtd->meta_data_mode) { memcpy(&output_meta_data, (char *)(buf->data + @@ -623,7 +623,7 @@ static int msm_pcm_hw_params(struct snd_pcm_substream *substream, if (buf == NULL || buf[0].data == NULL) return -ENOMEM; - pr_debug("%s:buf = %p\n", __func__, buf); + pr_debug("%s:buf = %pK\n", __func__, buf); dma_buf->dev.type = SNDRV_DMA_TYPE_DEV; dma_buf->dev.dev = substream->pcm->card->dev; dma_buf->private_data = NULL; diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c index 528c6bd246499..3593da589ed2c 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -740,7 +740,7 @@ static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, pr_debug("%s: pcm stopped in_count 0\n", __func__); return 0; } - pr_debug("Checking if valid buffer is available...%p\n", + pr_debug("Checking if valid buffer is available...%pK\n", data); data = q6asm_is_cpu_buf_avail(OUT, prtd->audio_client, &size, &idx); bufptr = data; @@ -897,7 +897,7 @@ static int msm_pcm_hw_params(struct snd_pcm_substream *substream, if (buf == NULL || buf[0].data == NULL) return -ENOMEM; - pr_debug("%s:buf = %p\n", __func__, buf); + pr_debug("%s:buf = %pK\n", __func__, buf); dma_buf->dev.type = SNDRV_DMA_TYPE_DEV; dma_buf->dev.dev = substream->pcm->card->dev; dma_buf->private_data = NULL; diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c index a7c01ce922447..997e09b68c226 100644 --- a/sound/soc/msm/qdsp6v2/q6adm.c +++ b/sound/soc/msm/qdsp6v2/q6adm.c @@ -329,7 +329,7 @@ int adm_dts_eagle_get(int port_id, int copp_idx, int param_id, } if ((size == 0) || !data) { - pr_err("DTS_EAGLE_ADM - %s: invalid size %u or pointer %p.\n", + pr_err("DTS_EAGLE_ADM - %s: invalid size %u or pointer %pK.\n", __func__, size, data); return -EINVAL; } @@ -1082,7 +1082,7 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) payload = data->payload; if (data->opcode == RESET_EVENTS) { - pr_debug("%s: Reset event is received: %d %d apr[%p]\n", + pr_debug("%s: Reset event is received: %d %d apr[%pK]\n", __func__, data->reset_event, data->reset_proc, this_adm.apr); if (this_adm.apr) { @@ -1531,7 +1531,7 @@ static void remap_cal_data(struct cal_block_data *cal_block, int cal_index) pr_err("%s: ADM mmap did not work! size = %zd ret %d\n", __func__, cal_block->map_data.map_size, ret); - pr_debug("%s: ADM mmap did not work! addr = 0x%pa, size = %zd ret %d\n", + pr_debug("%s: ADM mmap did not work! addr = 0x%pK, size = %zd ret %d\n", __func__, &cal_block->cal_data.paddr, cal_block->map_data.map_size, ret); @@ -1593,7 +1593,7 @@ static void send_adm_custom_topology(void) adm_top.payload_size = cal_block->cal_data.size; atomic_set(&this_adm.adm_stat, 0); - pr_debug("%s: Sending ADM_CMD_ADD_TOPOLOGIES payload = 0x%pa, size = %d\n", + pr_debug("%s: Sending ADM_CMD_ADD_TOPOLOGIES payload = 0x%pK, size = %d\n", __func__, &cal_block->cal_data.paddr, adm_top.payload_size); result = apr_send_pkt(this_adm.apr, (uint32_t *)&adm_top); @@ -1675,14 +1675,14 @@ static int send_adm_cal_block(int port_id, int copp_idx, adm_params.payload_size = cal_block->cal_data.size; atomic_set(&this_adm.copp.stat[port_idx][copp_idx], 0); - pr_debug("%s: Sending SET_PARAMS payload = 0x%pa, size = %d\n", + pr_debug("%s: Sending SET_PARAMS payload = 0x%pK, size = %d\n", __func__, &cal_block->cal_data.paddr, adm_params.payload_size); result = apr_send_pkt(this_adm.apr, (uint32_t *)&adm_params); if (result < 0) { pr_err("%s: Set params failed port 0x%x result %d\n", __func__, port_id, result); - pr_debug("%s: Set params failed port = 0x%x payload = 0x%pa result %d\n", + pr_debug("%s: Set params failed port = 0x%x payload = 0x%pK result %d\n", __func__, port_id, &cal_block->cal_data.paddr, result); result = -EINVAL; goto done; @@ -1694,7 +1694,7 @@ static int send_adm_cal_block(int port_id, int copp_idx, if (!result) { pr_err("%s: Set params timed out port = 0x%x\n", __func__, port_id); - pr_debug("%s: Set params timed out port = 0x%x, payload = 0x%pa\n", + pr_debug("%s: Set params timed out port = 0x%x, payload = 0x%pK\n", __func__, port_id, &cal_block->cal_data.paddr); result = -EINVAL; goto done; @@ -2047,7 +2047,7 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, res = adm_memory_map_regions(&this_adm.outband_memmap.paddr, 0, (uint32_t *)&this_adm.outband_memmap.size, 1); if (res < 0) { - pr_err("%s: SRS adm_memory_map_regions failed ! addr = 0x%p, size = %d\n", + pr_err("%s: SRS adm_memory_map_regions failed ! addr = 0x%pK, size = %d\n", __func__, (void*)this_adm.outband_memmap.paddr, (uint32_t)this_adm.outband_memmap.size); } @@ -2097,14 +2097,14 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, } else if (channel_mode == 4) { open.dev_channel_mapping[0] = PCM_CHANNEL_FL; open.dev_channel_mapping[1] = PCM_CHANNEL_FR; - open.dev_channel_mapping[2] = PCM_CHANNEL_RB; - open.dev_channel_mapping[3] = PCM_CHANNEL_LB; + open.dev_channel_mapping[2] = PCM_CHANNEL_LS; + open.dev_channel_mapping[3] = PCM_CHANNEL_RS; } else if (channel_mode == 5) { open.dev_channel_mapping[0] = PCM_CHANNEL_FL; open.dev_channel_mapping[1] = PCM_CHANNEL_FR; open.dev_channel_mapping[2] = PCM_CHANNEL_FC; - open.dev_channel_mapping[3] = PCM_CHANNEL_LB; - open.dev_channel_mapping[4] = PCM_CHANNEL_RB; + open.dev_channel_mapping[3] = PCM_CHANNEL_LS; + open.dev_channel_mapping[4] = PCM_CHANNEL_RS; } else if (channel_mode == 6) { open.dev_channel_mapping[0] = PCM_CHANNEL_FL; open.dev_channel_mapping[1] = PCM_CHANNEL_FR; @@ -2117,10 +2117,10 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, open.dev_channel_mapping[1] = PCM_CHANNEL_FR; open.dev_channel_mapping[2] = PCM_CHANNEL_LFE; open.dev_channel_mapping[3] = PCM_CHANNEL_FC; - open.dev_channel_mapping[4] = PCM_CHANNEL_LB; - open.dev_channel_mapping[5] = PCM_CHANNEL_RB; - open.dev_channel_mapping[6] = PCM_CHANNEL_FLC; - open.dev_channel_mapping[7] = PCM_CHANNEL_FRC; + open.dev_channel_mapping[4] = PCM_CHANNEL_LS; + open.dev_channel_mapping[5] = PCM_CHANNEL_RS; + open.dev_channel_mapping[6] = PCM_CHANNEL_LB; + open.dev_channel_mapping[7] = PCM_CHANNEL_RB; } else { pr_err("%s: invalid num_chan %d\n", __func__, channel_mode); @@ -2135,8 +2135,8 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, __func__, open.endpoint_id_1, open.sample_rate, open.topology_id); - if (open.topology_id == VPM_TX_LEC_STEREO_REF || - open.topology_id == VPM_TX_LEC_MONO_REF) { + if ((this_adm.ec_ref_cfg.channel != 0) && (path != 1) && + (open.endpoint_id_2 != 0xFFFF)) { int ref_end_channel_mode = this_adm.ec_ref_cfg.channel; use_open_v6 = true; /* overwrite open opcode and pkt size here to use @@ -2513,7 +2513,7 @@ int adm_map_rtac_block(struct rtac_cal_block_data *cal_block) pr_err("%s: RTAC mmap did not work! size = %d result %d\n", __func__, cal_block->map_data.map_size, result); - pr_debug("%s: RTAC mmap did not work! addr = 0x%pa, size = %d\n", + pr_debug("%s: RTAC mmap did not work! addr = 0x%pK, size = %d\n", __func__, &cal_block->cal_data.paddr, cal_block->map_data.map_size); @@ -3625,7 +3625,7 @@ static int adm_source_tracking_alloc_map_memory(void) (uint32_t *)&this_adm.sourceTrackingData.memmap.size, 1); if (ret < 0) { - pr_err("%s: failed to map memory, paddr = 0x%p, size = %d\n", + pr_err("%s: failed to map memory, paddr = 0x%pK, size = %d\n", __func__, (void *)this_adm.sourceTrackingData.memmap.paddr, (uint32_t)this_adm.sourceTrackingData.memmap.size); @@ -3645,7 +3645,7 @@ static int adm_source_tracking_alloc_map_memory(void) goto done; } ret = 0; - pr_debug("%s: paddr = 0x%p, size = %d, mem_map_handle = 0x%x\n", + pr_debug("%s: paddr = 0x%pK, size = %d, mem_map_handle = 0x%x\n", __func__, (void *)this_adm.sourceTrackingData.memmap.paddr, (uint32_t)this_adm.sourceTrackingData.memmap.size, atomic_read(&this_adm.mem_map_handles diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c index 95f92f5c10f34..5e6da527d97d1 100644 --- a/sound/soc/msm/qdsp6v2/q6afe.c +++ b/sound/soc/msm/qdsp6v2/q6afe.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -154,7 +154,7 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) return -EINVAL; } if (data->opcode == RESET_EVENTS) { - pr_debug("%s: reset event = %d %d apr[%p]\n", + pr_debug("%s: reset event = %d %d apr[%pK]\n", __func__, data->reset_event, data->reset_proc, this_afe.apr); @@ -184,7 +184,7 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) if ((data->payload_size < sizeof(this_afe.calib_data)) || !payload || (data->token >= AFE_MAX_PORTS)) { - pr_err("%s: Error: size %d payload %p token %d\n", + pr_err("%s: Error: size %d payload %pK token %d\n", __func__, data->payload_size, payload, data->token); return -EINVAL; @@ -504,7 +504,7 @@ static int afe_send_cal_block(u16 port_id, struct cal_block_data *cal_block) upper_32_bits(cal_block->cal_data.paddr); afe_cal.param.mem_map_handle = cal_block->map_data.q6map_handle; - pr_debug("%s: AFE cal sent for device port = 0x%x, cal size = %zd, cal addr = 0x%pa\n", + pr_debug("%s: AFE cal sent for device port = 0x%x, cal size = %zd, cal addr = 0x%pK\n", __func__, port_id, cal_block->cal_data.size, &cal_block->cal_data.paddr); @@ -838,7 +838,7 @@ static void remap_cal_data(struct cal_block_data *cal_block, int cal_index) pr_err("%s: mmap did not work! size = %zd ret %d\n", __func__, cal_block->map_data.map_size, ret); - pr_debug("%s: mmap did not work! addr = 0x%pa, size = %zd\n", + pr_debug("%s: mmap did not work! addr = 0x%pK, size = %zd\n", __func__, &cal_block->cal_data.paddr, cal_block->map_data.map_size); @@ -2520,7 +2520,7 @@ int q6afe_audio_client_buf_alloc_contiguous(unsigned int dir, size_t len; if (!(ac) || ((dir != IN) && (dir != OUT))) { - pr_err("%s: ac %p dir %d\n", __func__, ac, dir); + pr_err("%s: ac %pK dir %d\n", __func__, ac, dir); return -EINVAL; } @@ -2572,7 +2572,7 @@ int q6afe_audio_client_buf_alloc_contiguous(unsigned int dir, buf[cnt].used = dir ^ 1; buf[cnt].size = bufsz; buf[cnt].actual_size = bufsz; - pr_debug("%s: data[%p]phys[%pa][%p]\n", __func__, + pr_debug("%s: data[%pK]phys[%pK][%pK]\n", __func__, buf[cnt].data, &buf[cnt].phys, &buf[cnt].phys); @@ -2669,7 +2669,7 @@ int afe_cmd_memory_map(phys_addr_t dma_addr_p, u32 dma_buf_sz) mregion_pl->shm_addr_msw = upper_32_bits(dma_addr_p); mregion_pl->mem_size_bytes = dma_buf_sz; - pr_debug("%s: dma_addr_p 0x%pa , size %d\n", __func__, + pr_debug("%s: dma_addr_p 0x%pK , size %d\n", __func__, &dma_addr_p, dma_buf_sz); atomic_set(&this_afe.state, 1); atomic_set(&this_afe.status, 0); @@ -2793,7 +2793,7 @@ int q6afe_audio_client_buf_free_contiguous(unsigned int dir, cnt = port->max_buf_cnt - 1; if (port->buf[0].data) { - pr_debug("%s: data[%p]phys[%pa][%p] , client[%p] handle[%p]\n", + pr_debug("%s: data[%pK]phys[%pK][%pK] , client[%pK] handle[%pK]\n", __func__, port->buf[0].data, &port->buf[0].phys, @@ -3785,6 +3785,113 @@ int afe_set_lpass_clock(u16 port_id, struct afe_clk_cfg *cfg) return ret; } +int afe_set_lpass_clk_cfg(int index, struct afe_clk_set *cfg) +{ + struct afe_lpass_clk_config_command_v2 clk_cfg; + int ret = 0; + + if (!cfg) { + pr_err("%s: clock cfg is NULL\n", __func__); + ret = -EINVAL; + return ret; + } + + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: index[%d] invalid!\n", __func__, index); + return -EINVAL; + } + + ret = afe_q6_interface_prepare(); + if (ret != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return ret; + } + + mutex_lock(&this_afe.afe_cmd_lock); + clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + clk_cfg.hdr.pkt_size = sizeof(clk_cfg); + clk_cfg.hdr.src_port = 0; + clk_cfg.hdr.dest_port = 0; + clk_cfg.hdr.token = index; + + clk_cfg.hdr.opcode = AFE_SVC_CMD_SET_PARAM; + clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr) + - sizeof(clk_cfg.param); + clk_cfg.param.payload_address_lsw = 0x00; + clk_cfg.param.payload_address_msw = 0x00; + clk_cfg.param.mem_map_handle = 0x00; + clk_cfg.pdata.module_id = AFE_MODULE_CLOCK_SET; + clk_cfg.pdata.param_id = AFE_PARAM_ID_CLOCK_SET; + clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg); + clk_cfg.clk_cfg = *cfg; + + + pr_debug("%s: Minor version =0x%x clk id = %d\n" + "clk freq (Hz) = %d, clk attri = 0x%x\n" + "clk root = 0x%x clk enable = 0x%x\n", + __func__, cfg->clk_set_minor_version, + cfg->clk_id, cfg->clk_freq_in_hz, cfg->clk_attri, + cfg->clk_root, cfg->enable); + + atomic_set(&this_afe.state, 1); + atomic_set(&this_afe.status, 0); + ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg); + if (ret < 0) { + pr_err("%s: AFE clk cfg failed with ret %d\n", + __func__, ret); + ret = -EINVAL; + goto fail_cmd; + } + + ret = wait_event_timeout(this_afe.wait[index], + (atomic_read(&this_afe.state) == 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -EINVAL; + goto fail_cmd; + } else { + /* set ret to 0 as no timeout happened */ + ret = 0; + } + if (atomic_read(&this_afe.status) != 0) { + pr_err("%s: config cmd failed\n", __func__); + ret = -EINVAL; + goto fail_cmd; + } + +fail_cmd: + mutex_unlock(&this_afe.afe_cmd_lock); + return ret; +} + +int afe_set_lpass_clock_v2(u16 port_id, struct afe_clk_set *cfg) +{ + int index = 0; + int ret = 0; + + index = q6audio_get_port_index(port_id); + if (index < 0 || index > AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + ret = q6audio_is_digital_pcm_interface(port_id); + if (ret < 0) { + pr_err("%s: q6audio_is_digital_pcm_interface fail %d\n", + __func__, ret); + return -EINVAL; + } + + ret = afe_set_lpass_clk_cfg(index, cfg); + if (ret) + pr_err("%s: afe_set_lpass_clk_cfg_v2 failed %d\n", + __func__, ret); + + return ret; +} + int afe_set_lpass_internal_digital_codec_clock(u16 port_id, struct afe_digital_clk_cfg *cfg) { @@ -4303,7 +4410,7 @@ static int afe_map_cal_data(int32_t cal_type, pr_err("%s: mmap did not work! size = %zd ret %d\n", __func__, cal_block->map_data.map_size, ret); - pr_debug("%s: mmap did not work! addr = 0x%pa, size = %zd\n", + pr_debug("%s: mmap did not work! addr = 0x%pK, size = %zd\n", __func__, &cal_block->cal_data.paddr, cal_block->map_data.map_size); @@ -4438,7 +4545,7 @@ int afe_map_rtac_block(struct rtac_cal_block_data *cal_block) result = afe_cmd_memory_map(cal_block->cal_data.paddr, cal_block->map_data.map_size); if (result < 0) { - pr_err("%s: afe_cmd_memory_map failed for addr = 0x%pa, size = %d, err %d\n", + pr_err("%s: afe_cmd_memory_map failed for addr = 0x%pK, size = %d, err %d\n", __func__, &cal_block->cal_data.paddr, cal_block->map_data.map_size, result); return result; diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c index e03ba24610ca2..d46cbfbc4d1dd 100644 --- a/sound/soc/msm/qdsp6v2/q6asm.c +++ b/sound/soc/msm/qdsp6v2/q6asm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * Author: Brian Swetland * * This software is licensed under the terms of the GNU General Public @@ -38,6 +38,7 @@ #include #include +#include #include #include @@ -45,6 +46,7 @@ #define FALSE 0x00 #define CMD_GET_HDR_SZ 16 +#define U32_MAX ((u32)~0U) enum { ASM_TOPOLOGY_CAL = 0, @@ -479,7 +481,7 @@ static int q6asm_map_cal_memory(struct cal_block_data *cal_block) pr_err("%s: mmap did not work! size = %zd result %d\n", __func__, cal_block->map_data.map_size, result); - pr_debug("%s: mmap did not work! addr = 0x%pa, size = %zd\n", + pr_debug("%s: mmap did not work! addr = 0x%pK, size = %zd\n", __func__, &cal_block->cal_data.paddr, cal_block->map_data.map_size); @@ -612,7 +614,7 @@ int send_asm_custom_topology(struct audio_client *ac) asm_top.mem_map_handle = cal_block->map_data.q6map_handle; asm_top.payload_size = cal_block->cal_data.size; - pr_debug("%s: Sending ASM_CMD_ADD_TOPOLOGIES payload = %pa, size = %d, map handle = 0x%x\n", + pr_debug("%s: Sending ASM_CMD_ADD_TOPOLOGIES payload = %pK, size = %d, map handle = 0x%x\n", __func__, &cal_block->cal_data.paddr, asm_top.payload_size, asm_top.mem_map_handle); @@ -620,7 +622,7 @@ int send_asm_custom_topology(struct audio_client *ac) if (result < 0) { pr_err("%s: Set topologies failed result %d\n", __func__, result); - pr_debug("%s: Set topologies failed payload = 0x%pa\n", + pr_debug("%s: Set topologies failed payload = 0x%pK\n", __func__, &cal_block->cal_data.paddr); goto unmap; @@ -630,7 +632,7 @@ int send_asm_custom_topology(struct audio_client *ac) (atomic_read(&ac->mem_state) <= 0), 5*HZ); if (!result) { pr_err("%s: Set topologies failed timeout\n", __func__); - pr_debug("%s: Set topologies failed after timedout payload = 0x%pa\n", + pr_debug("%s: Set topologies failed after timedout payload = 0x%pK\n", __func__, &cal_block->cal_data.paddr); result = -ETIMEDOUT; goto unmap; @@ -706,7 +708,7 @@ int q6asm_map_rtac_block(struct rtac_cal_block_data *cal_block) pr_err("%s: mmap did not work! size = %d result %d\n", __func__, cal_block->map_data.map_size, result); - pr_debug("%s: mmap did not work! addr = 0x%pa, size = %d\n", + pr_debug("%s: mmap did not work! addr = 0x%pK, size = %d\n", __func__, &cal_block->cal_data.paddr, cal_block->map_data.map_size); @@ -843,7 +845,7 @@ int q6asm_audio_client_buf_free_contiguous(unsigned int dir, } if (port->buf[0].data) { - pr_debug("%s: data[%p]phys[%pa][%p] , client[%p] handle[%p]\n", + pr_debug("%s: data[%pK]phys[%pK][%pK] , client[%pK] handle[%pK]\n", __func__, port->buf[0].data, &port->buf[0].phys, @@ -874,7 +876,7 @@ void q6asm_audio_client_free(struct audio_client *ac) int loopcnt; struct audio_port_data *port; if (!ac) { - pr_err("%s: ac %p\n", __func__, ac); + pr_err("%s: ac %pK\n", __func__, ac); return; } if (!ac->session) { @@ -1082,7 +1084,7 @@ struct audio_client *q6asm_get_audio_client(int session_id) int q6asm_audio_client_buf_alloc(unsigned int dir, struct audio_client *ac, unsigned int bufsz, - unsigned int bufcnt) + uint32_t bufcnt) { int cnt = 0; int rc = 0; @@ -1090,7 +1092,7 @@ int q6asm_audio_client_buf_alloc(unsigned int dir, size_t len; if (!(ac) || ((dir != IN) && (dir != OUT))) { - pr_err("%s: ac %p dir %d\n", __func__, ac, dir); + pr_err("%s: ac %pK dir %d\n", __func__, ac, dir); return -EINVAL; } @@ -1109,7 +1111,7 @@ int q6asm_audio_client_buf_alloc(unsigned int dir, return 0; } mutex_lock(&ac->cmd_lock); - if (bufcnt > (LONG_MAX/sizeof(struct audio_buffer))) { + if (bufcnt > (U32_MAX/sizeof(struct audio_buffer))) { pr_err("%s: Buffer size overflows", __func__); mutex_unlock(&ac->cmd_lock); goto fail; @@ -1143,7 +1145,7 @@ int q6asm_audio_client_buf_alloc(unsigned int dir, buf[cnt].used = 1; buf[cnt].size = bufsz; buf[cnt].actual_size = bufsz; - pr_debug("%s: data[%p]phys[%pa][%p]\n", + pr_debug("%s: data[%pK]phys[%pK][%pK]\n", __func__, buf[cnt].data, &buf[cnt].phys, @@ -1180,7 +1182,7 @@ int q6asm_audio_client_buf_alloc_contiguous(unsigned int dir, int bytes_to_alloc; if (!(ac) || ((dir != IN) && (dir != OUT))) { - pr_err("%s: ac %p dir %d\n", __func__, ac, dir); + pr_err("%s: ac %pK dir %d\n", __func__, ac, dir); return -EINVAL; } @@ -1249,7 +1251,7 @@ int q6asm_audio_client_buf_alloc_contiguous(unsigned int dir, buf[cnt].used = dir ^ 1; buf[cnt].size = bufsz; buf[cnt].actual_size = bufsz; - pr_debug("%s: data[%p]phys[%pa][%p]\n", + pr_debug("%s: data[%pK]phys[%pK][%pK]\n", __func__, buf[cnt].data, &buf[cnt].phys, @@ -1292,7 +1294,7 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) payload = data->payload; if (data->opcode == RESET_EVENTS) { - pr_debug("%s: Reset event is received: %d %d apr[%p]\n", + pr_debug("%s: Reset event is received: %d %d apr[%pK]\n", __func__, data->reset_event, data->reset_proc, @@ -1438,6 +1440,57 @@ static int32_t is_no_wait_cmd_rsp(uint32_t opcode, uint32_t *cmd_type) return 0; } +static void q6asm_process_mtmx_get_param_rsp(struct audio_client *ac, + struct asm_mtmx_strtr_get_params_cmdrsp *cmdrsp) +{ + struct asm_session_mtmx_strtr_param_session_time_v3_t *time; + + if (cmdrsp->err_code) { + dev_err_ratelimited(ac->dev, + "%s: err=%x, mod_id=%x, param_id=%x\n", + __func__, cmdrsp->err_code, + cmdrsp->param_info.module_id, + cmdrsp->param_info.param_id); + return; + } + dev_dbg_ratelimited(ac->dev, + "%s: mod_id=%x, param_id=%x\n", __func__, + cmdrsp->param_info.module_id, + cmdrsp->param_info.param_id); + + switch (cmdrsp->param_info.module_id) { + case ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC: + switch (cmdrsp->param_info.param_id) { + case ASM_SESSION_MTMX_STRTR_PARAM_SESSION_TIME_V3: + time = &cmdrsp->param_data.session_time; + dev_vdbg(ac->dev, "%s: GET_TIME_V3, time_lsw=%x, time_msw=%x\n", + __func__, time->session_time_lsw, + time->session_time_msw); + ac->time_stamp = (uint64_t)(((uint64_t) + time->session_time_msw << 32) | + time->session_time_lsw); + if (time->flags & + ASM_SESSION_MTMX_STRTR_PARAM_STIME_TSTMP_FLG_BMASK) + dev_warn_ratelimited(ac->dev, + "%s: recv inval tstmp\n", + __func__); + if (atomic_cmpxchg(&ac->time_flag, 1, 0)) + wake_up(&ac->time_wait); + + break; + default: + dev_err(ac->dev, "%s: unexpected param_id %x\n", + __func__, cmdrsp->param_info.param_id); + break; + } + break; + default: + dev_err(ac->dev, "%s: unexpected mod_id %x\n", __func__, + cmdrsp->param_info.module_id); + break; + } +} + static int32_t q6asm_callback(struct apr_client_data *data, void *priv) { int i = 0; @@ -1458,7 +1511,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) return -EINVAL; } if (!q6asm_is_valid_audio_client(ac)) { - pr_err("%s: audio client pointer is invalid, ac = %p\n", + pr_err("%s: audio client pointer is invalid, ac = %pK\n", __func__, ac); return -EINVAL; } @@ -1484,7 +1537,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) atomic_set(&ac->reset, 1); if (ac->apr == NULL) ac->apr = ac->apr2; - pr_debug("%s: Reset event is received: %d %d apr[%p]\n", + pr_debug("%s: Reset event is received: %d %d apr[%pK]\n", __func__, data->reset_event, data->reset_proc, ac->apr); if (ac->cb) @@ -1627,7 +1680,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) payload[0] || upper_32_bits(port->buf[data->token].phys) != payload[1]) { - pr_debug("%s: Expected addr %pa\n", + pr_debug("%s: Expected addr %pK\n", __func__, &port->buf[data->token].phys); pr_err("%s: rxedl[0x%x] rxedu [0x%x]\n", __func__, payload[0], payload[1]); @@ -1702,7 +1755,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) payload[READDONE_IDX_BUFADD_LSW] || upper_32_bits(port->buf[token].phys) != payload[READDONE_IDX_BUFADD_MSW]) { - dev_vdbg(ac->dev, "%s: Expected addr %pa\n", + dev_vdbg(ac->dev, "%s: Expected addr %pK\n", __func__, &port->buf[token].phys); pr_err("%s: rxedl[0x%x] rxedu[0x%x]\n", __func__, @@ -1757,6 +1810,9 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) payload[0], payload[1], payload[2], payload[3]); break; + case ASM_SESSION_CMDRSP_GET_MTMX_STRTR_PARAMS_V2: + q6asm_process_mtmx_get_param_rsp(ac, (void *) payload); + break; } if (ac->cb) ac->cb(data->opcode, data->token, @@ -1773,7 +1829,7 @@ void *q6asm_is_cpu_buf_avail(int dir, struct audio_client *ac, uint32_t *size, struct audio_port_data *port; if (!ac || ((dir != IN) && (dir != OUT))) { - pr_err("%s: ac %p dir %d\n", __func__, ac, dir); + pr_err("%s: ac %pK dir %d\n", __func__, ac, dir); return NULL; } @@ -1800,7 +1856,7 @@ void *q6asm_is_cpu_buf_avail(int dir, struct audio_client *ac, uint32_t *size, *size = port->buf[idx].actual_size; *index = port->cpu_buf; data = port->buf[idx].data; - dev_vdbg(ac->dev, "%s: session[%d]index[%d] data[%p]size[%d]\n", + dev_vdbg(ac->dev, "%s: session[%d]index[%d] data[%pK]size[%d]\n", __func__, ac->session, port->cpu_buf, @@ -1825,7 +1881,7 @@ void *q6asm_is_cpu_buf_avail_nolock(int dir, struct audio_client *ac, struct audio_port_data *port; if (!ac || ((dir != IN) && (dir != OUT))) { - pr_err("%s: ac %p dir %d\n", __func__, ac, dir); + pr_err("%s: ac %pK dir %d\n", __func__, ac, dir); return NULL; } @@ -1852,7 +1908,7 @@ void *q6asm_is_cpu_buf_avail_nolock(int dir, struct audio_client *ac, *size = port->buf[idx].actual_size; *index = port->cpu_buf; data = port->buf[idx].data; - dev_vdbg(ac->dev, "%s: session[%d]index[%d] data[%p]size[%d]\n", + dev_vdbg(ac->dev, "%s: session[%d]index[%d] data[%pK]size[%d]\n", __func__, ac->session, port->cpu_buf, data, *size); /* @@ -1873,7 +1929,7 @@ int q6asm_is_dsp_buf_avail(int dir, struct audio_client *ac) uint32_t idx; if (!ac || (dir != OUT)) { - pr_err("%s: ac %p dir %d\n", __func__, ac, dir); + pr_err("%s: ac %pK dir %d\n", __func__, ac, dir); return ret; } @@ -2139,13 +2195,13 @@ int q6asm_open_write_compressed(struct audio_client *ac, uint32_t format, struct asm_stream_cmd_open_write_compressed open; if (ac == NULL) { - pr_err("%s: ac[%p] NULL\n", __func__, ac); + pr_err("%s: ac[%pK] NULL\n", __func__, ac); rc = -EINVAL; goto fail_cmd; } if (ac->apr == NULL) { - pr_err("%s: APR handle[%p] NULL\n", __func__, ac->apr); + pr_err("%s: APR handle[%pK] NULL\n", __func__, ac->apr); rc = -EINVAL; goto fail_cmd; } @@ -2158,14 +2214,35 @@ int q6asm_open_write_compressed(struct audio_client *ac, uint32_t format, switch (format) { case FORMAT_AC3: - open.fmt_id = ASM_MEDIA_FMT_AC3_DEC; - break; + switch (q6core_get_avs_version()) { + case Q6_SUBSYS_AVS2_7: + open.fmt_id = ASM_MEDIA_FMT_AC3; + break; + case Q6_SUBSYS_AVS2_6: + open.fmt_id = ASM_MEDIA_FMT_AC3_DEC; + break; + case Q6_SUBSYS_INVALID: + default: + pr_err("%s: Invalid format[%d]\n", + __func__, format); + rc = -EINVAL; + goto fail_cmd; + } case FORMAT_EAC3: - open.fmt_id = ASM_MEDIA_FMT_EAC3_DEC; - break; - default: - pr_err("%s: Invalid format[%d]\n", __func__, format); - goto fail_cmd; + switch (q6core_get_avs_version()) { + case Q6_SUBSYS_AVS2_7: + open.fmt_id = ASM_MEDIA_FMT_EAC3; + break; + case Q6_SUBSYS_AVS2_6: + open.fmt_id = ASM_MEDIA_FMT_EAC3_DEC; + break; + case Q6_SUBSYS_INVALID: + default: + pr_err("%s: Invalid format[%d]\n", + __func__, format); + rc = -EINVAL; + goto fail_cmd; + } } /*Below flag indicates the DSP that Compressed audio input stream is not IEC 61937 or IEC 60958 packetizied*/ @@ -2206,6 +2283,7 @@ static int __q6asm_open_write(struct audio_client *ac, uint32_t format, bool is_gapless_mode) { int rc = 0x00; + struct asm_stream_cmd_open_write_v3 open; if (ac == NULL) { @@ -2281,10 +2359,36 @@ static int __q6asm_open_write(struct audio_client *ac, uint32_t format, open.dec_fmt_id = ASM_MEDIA_FMT_MP3; break; case FORMAT_AC3: - open.dec_fmt_id = ASM_MEDIA_FMT_EAC3_DEC; + switch (q6core_get_avs_version()) { + case Q6_SUBSYS_AVS2_7: + open.dec_fmt_id = ASM_MEDIA_FMT_AC3; + break; + case Q6_SUBSYS_AVS2_6: + open.dec_fmt_id = ASM_MEDIA_FMT_AC3_DEC; + break; + case Q6_SUBSYS_INVALID: + default: + pr_err("%s: Invalid format[%d]\n", + __func__, format); + rc = -EINVAL; + goto fail_cmd; + } break; case FORMAT_EAC3: - open.dec_fmt_id = ASM_MEDIA_FMT_EAC3_DEC; + switch (q6core_get_avs_version()) { + case Q6_SUBSYS_AVS2_7: + open.dec_fmt_id = ASM_MEDIA_FMT_EAC3; + break; + case Q6_SUBSYS_AVS2_6: + open.dec_fmt_id = ASM_MEDIA_FMT_EAC3_DEC; + break; + case Q6_SUBSYS_INVALID: + default: + pr_err("%s: Invalid format[%d]\n", + __func__, format); + rc = -EINVAL; + goto fail_cmd; + } break; case FORMAT_MP2: open.dec_fmt_id = ASM_MEDIA_FMT_MP2; @@ -2908,14 +3012,14 @@ static int q6asm_map_channels(u8 *channel_mapping, uint32_t channels) } else if (channels == 4) { lchannel_mapping[0] = PCM_CHANNEL_FL; lchannel_mapping[1] = PCM_CHANNEL_FR; - lchannel_mapping[2] = PCM_CHANNEL_RB; - lchannel_mapping[3] = PCM_CHANNEL_LB; + lchannel_mapping[2] = PCM_CHANNEL_LS; + lchannel_mapping[3] = PCM_CHANNEL_RS; } else if (channels == 5) { lchannel_mapping[0] = PCM_CHANNEL_FL; lchannel_mapping[1] = PCM_CHANNEL_FR; lchannel_mapping[2] = PCM_CHANNEL_FC; - lchannel_mapping[3] = PCM_CHANNEL_LB; - lchannel_mapping[4] = PCM_CHANNEL_RB; + lchannel_mapping[3] = PCM_CHANNEL_LS; + lchannel_mapping[4] = PCM_CHANNEL_RS; } else if (channels == 6) { lchannel_mapping[0] = PCM_CHANNEL_FL; lchannel_mapping[1] = PCM_CHANNEL_FR; @@ -2930,15 +3034,14 @@ static int q6asm_map_channels(u8 *channel_mapping, uint32_t channels) lchannel_mapping[3] = PCM_CHANNEL_LFE; lchannel_mapping[4] = PCM_CHANNEL_LB; lchannel_mapping[5] = PCM_CHANNEL_RB; - lchannel_mapping[6] = PCM_CHANNEL_FLC; - lchannel_mapping[7] = PCM_CHANNEL_FRC; + lchannel_mapping[6] = PCM_CHANNEL_LS; + lchannel_mapping[7] = PCM_CHANNEL_RS; } else { pr_err("%s: ERROR.unsupported num_ch = %u\n", __func__, channels); return -EINVAL; } return 0; - } int q6asm_enable_sbrps(struct audio_client *ac, @@ -3264,7 +3367,8 @@ int q6asm_enc_cfg_blk_amrwb(struct audio_client *ac, uint32_t frames_per_buf, static int __q6asm_media_format_block_pcm(struct audio_client *ac, uint32_t rate, uint32_t channels, - uint16_t bits_per_sample, int stream_id) + uint16_t bits_per_sample, int stream_id, + bool use_default_chmap, char *channel_map) { struct asm_multi_channel_pcm_fmt_blk_v2 fmt; u8 *channel_mapping; @@ -3299,9 +3403,15 @@ static int __q6asm_media_format_block_pcm(struct audio_client *ac, memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL); - if (q6asm_map_channels(channel_mapping, channels)) { - pr_err("%s: map channels failed %d\n", __func__, channels); - return -EINVAL; + if (use_default_chmap) { + if (q6asm_map_channels(channel_mapping, channels)) { + pr_err("%s: map channels failed %d\n", + __func__, channels); + return -EINVAL; + } + } else { + memcpy(channel_mapping, channel_map, + PCM_FORMAT_MAX_NUM_CHANNEL); } rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt); @@ -3329,7 +3439,8 @@ int q6asm_media_format_block_pcm(struct audio_client *ac, uint32_t rate, uint32_t channels) { return __q6asm_media_format_block_pcm(ac, rate, - channels, 16, ac->stream_id); + channels, 16, ac->stream_id, + true, NULL); } int q6asm_media_format_block_pcm_format_support(struct audio_client *ac, @@ -3337,15 +3448,23 @@ int q6asm_media_format_block_pcm_format_support(struct audio_client *ac, uint16_t bits_per_sample) { return __q6asm_media_format_block_pcm(ac, rate, - channels, bits_per_sample, ac->stream_id); + channels, bits_per_sample, ac->stream_id, + true, NULL); } int q6asm_media_format_block_pcm_format_support_v2(struct audio_client *ac, uint32_t rate, uint32_t channels, - uint16_t bits_per_sample, int stream_id) + uint16_t bits_per_sample, int stream_id, + bool use_default_chmap, char *channel_map) { + if (!use_default_chmap && (channel_map == NULL)) { + pr_err("%s: No valid chan map and can't use default\n", + __func__); + return -EINVAL; + } return __q6asm_media_format_block_pcm(ac, rate, - channels, bits_per_sample, stream_id); + channels, bits_per_sample, stream_id, + use_default_chmap, channel_map); } static int __q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac, @@ -3941,7 +4060,7 @@ int q6asm_memory_map(struct audio_client *ac, phys_addr_t buf_add, int dir, ac->port[dir].tmp_hdl = 0; port = &ac->port[dir]; - pr_debug("%s: buf_add 0x%pa, bufsz: %d\n", __func__, + pr_debug("%s: buf_add 0x%pK, bufsz: %d\n", __func__, &buf_add, bufsz); mregions->shm_addr_lsw = lower_32_bits(buf_add); mregions->shm_addr_msw = upper_32_bits(buf_add); @@ -4127,7 +4246,7 @@ static int q6asm_memory_map_regions(struct audio_client *ac, int dir, q6asm_add_mmaphdr(ac, &mmap_regions->hdr, cmd_size, TRUE, ((ac->session << 8) | dir)); atomic_set(&ac->mem_state, 1); - pr_debug("%s: mmap_region=0x%p token=0x%x\n", __func__, + pr_debug("%s: mmap_region=0x%pK token=0x%x\n", __func__, mmap_regions, ((ac->session << 8) | dir)); mmap_regions->hdr.opcode = ASM_CMD_SHARED_MEM_MAP_REGIONS; @@ -4183,7 +4302,7 @@ static int q6asm_memory_map_regions(struct audio_client *ac, int dir, buffer_node[i].mmap_hdl = ac->port[dir].tmp_hdl; list_add_tail(&buffer_node[i].list, &ac->port[dir].mem_map_handle); - pr_debug("%s: i=%d, bufadd[i] = 0x%pa, maphdl[i] = 0x%x\n", + pr_debug("%s: i=%d, bufadd[i] = 0x%pK, maphdl[i] = 0x%x\n", __func__, i, &buffer_node[i].buf_phys_addr, buffer_node[i].mmap_hdl); } @@ -4342,6 +4461,110 @@ int q6asm_set_lrgain(struct audio_client *ac, int left_gain, int right_gain) return rc; } +/* + * q6asm_set_multich_gain: set multiple channel gains on an ASM session + * @ac: audio client handle + * @channels: number of channels caller intends to set gains + * @gains: list of gains of audio channels + * @ch_map: list of channel mapping. Only valid if use_default is false + * @use_default: flag to indicate whether to use default mapping + */ +int q6asm_set_multich_gain(struct audio_client *ac, uint32_t channels, + uint32_t *gains, uint8_t *ch_map, bool use_default) +{ + struct asm_volume_ctrl_multichannel_gain multich_gain; + int sz = 0; + int rc = 0; + int i; + u8 default_chmap[VOLUME_CONTROL_MAX_CHANNELS]; + + if (ac == NULL) { + pr_err("%s: ac is NULL\n", __func__); + rc = -EINVAL; + goto done; + } + if (ac->apr == NULL) { + dev_err(ac->dev, "%s: AC APR handle NULL\n", __func__); + rc = -EINVAL; + goto done; + } + if (gains == NULL) { + dev_err(ac->dev, "%s: gain_list is NULL\n", __func__); + rc = -EINVAL; + goto done; + } + if (channels > VOLUME_CONTROL_MAX_CHANNELS) { + dev_err(ac->dev, "%s: Invalid channel count %d\n", + __func__, channels); + rc = -EINVAL; + goto done; + } + if (!use_default && ch_map == NULL) { + dev_err(ac->dev, "%s: NULL channel map\n", __func__); + rc = -EINVAL; + goto done; + } + + memset(&multich_gain, 0, sizeof(multich_gain)); + sz = sizeof(struct asm_volume_ctrl_multichannel_gain); + q6asm_add_hdr_async(ac, &multich_gain.hdr, sz, TRUE); + atomic_set(&ac->cmd_state, 1); + multich_gain.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; + multich_gain.param.data_payload_addr_lsw = 0; + multich_gain.param.data_payload_addr_msw = 0; + multich_gain.param.mem_map_handle = 0; + multich_gain.param.data_payload_size = sizeof(multich_gain) - + sizeof(multich_gain.hdr) - sizeof(multich_gain.param); + multich_gain.data.module_id = ASM_MODULE_ID_VOL_CTRL; + multich_gain.data.param_id = ASM_PARAM_ID_MULTICHANNEL_GAIN; + multich_gain.data.param_size = multich_gain.param.data_payload_size - + sizeof(multich_gain.data); + multich_gain.data.reserved = 0; + + if (use_default) { + rc = q6asm_map_channels(default_chmap, channels); + if (rc < 0) + goto done; + for (i = 0; i < channels; i++) { + multich_gain.gain_data[i].channeltype = + default_chmap[i]; + multich_gain.gain_data[i].gain = gains[i] << 15; + } + } else { + for (i = 0; i < channels; i++) { + multich_gain.gain_data[i].channeltype = ch_map[i]; + multich_gain.gain_data[i].gain = gains[i] << 15; + } + } + multich_gain.num_channels = channels; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &multich_gain); + if (rc < 0) { + pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", + __func__, multich_gain.data.param_id, rc); + goto done; + } + + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) <= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__, + multich_gain.data.param_id); + rc = -EINVAL; + goto done; + } + if (atomic_read(&ac->cmd_state) < 0) { + pr_err("%s: DSP returned error[%d] , set-params paramid[0x%x]\n", + __func__, atomic_read(&ac->cmd_state), + multich_gain.data.param_id); + rc = -EINVAL; + goto done; + } + rc = 0; +done: + return rc; +} + int q6asm_set_mute(struct audio_client *ac, int muteflag) { struct asm_volume_ctrl_mute_config mute; @@ -4415,7 +4638,7 @@ int q6asm_dts_eagle_set(struct audio_client *ac, int param_id, uint32_t size, } if (!ac || ac->apr == NULL || (size == 0) || !data) { - pr_err("DTS_EAGLE_ASM - %s: APR handle NULL, invalid size %u or pointer %p.\n", + pr_err("DTS_EAGLE_ASM - %s: APR handle NULL, invalid size %u or pointer %pK.\n", __func__, size, data); return -EINVAL; } @@ -4466,7 +4689,7 @@ int q6asm_dts_eagle_get(struct audio_client *ac, int param_id, uint32_t size, uint32_t sz; if (!ac || ac->apr == NULL || (size == 0) || !data) { - pr_err("DTS_EAGLE_ASM - %s: APR handle NULL, invalid size %u or pointer %p.\n", + pr_err("DTS_EAGLE_ASM - %s: APR handle NULL, invalid size %u or pointer %pK.\n", __func__, size, data); return -EINVAL; } @@ -4891,7 +5114,7 @@ static int __q6asm_read(struct audio_client *ac, bool is_custom_len_reqd, } ab = &port->buf[dsp_buf]; - dev_vdbg(ac->dev, "%s: session[%d]dsp-buf[%d][%p]cpu_buf[%d][%pa]\n", + dev_vdbg(ac->dev, "%s: session[%d]dsp-buf[%d][%pK]cpu_buf[%d][%pK]\n", __func__, ac->session, dsp_buf, @@ -4917,7 +5140,7 @@ static int __q6asm_read(struct audio_client *ac, bool is_custom_len_reqd, port->dsp_buf = q6asm_get_next_buf(port->dsp_buf, port->max_buf_cnt); mutex_unlock(&port->lock); - dev_vdbg(ac->dev, "%s: buf add[%pa] token[%d] uid[%d]\n", + dev_vdbg(ac->dev, "%s: buf add[%pK] token[%d] uid[%d]\n", __func__, &ab->phys, read.hdr.token, read.seq_id); rc = apr_send_pkt(ac->apr, (uint32_t *) &read); @@ -4969,7 +5192,7 @@ int q6asm_read_nolock(struct audio_client *ac) dsp_buf = port->dsp_buf; ab = &port->buf[dsp_buf]; - dev_vdbg(ac->dev, "%s: session[%d]dsp-buf[%d][%p]cpu_buf[%d][%pa]\n", + dev_vdbg(ac->dev, "%s: session[%d]dsp-buf[%d][%pK]cpu_buf[%d][%pK]\n", __func__, ac->session, dsp_buf, @@ -4993,9 +5216,8 @@ int q6asm_read_nolock(struct audio_client *ac) } } - port->dsp_buf = q6asm_get_next_buf(port->dsp_buf, - port->max_buf_cnt); - dev_vdbg(ac->dev, "%s: buf add[%pa] token[%d] uid[%d]\n", + port->dsp_buf = (port->dsp_buf + 1) & (port->max_buf_cnt - 1); + dev_vdbg(ac->dev, "%s: buf add[%pK] token[%d] uid[%d]\n", __func__, &ab->phys, read.hdr.token, read.seq_id); rc = apr_send_pkt(ac->apr, (uint32_t *) &read); @@ -5058,7 +5280,7 @@ int q6asm_async_write(struct audio_client *ac, else lbuf_phys_addr = param->paddr; - dev_vdbg(ac->dev, "%s: token[0x%x], buf_addr[%pa], buf_size[0x%x], ts_msw[0x%x], ts_lsw[0x%x], lbuf_phys_addr: 0x[%pa]\n", + dev_vdbg(ac->dev, "%s: token[0x%x], buf_addr[%pK], buf_size[0x%x], ts_msw[0x%x], ts_lsw[0x%x], lbuf_phys_addr: 0x[%pK]\n", __func__, write.hdr.token, ¶m->paddr, write.buf_size, write.timestamp_msw, @@ -5206,7 +5428,7 @@ int q6asm_write(struct audio_client *ac, uint32_t len, uint32_t msw_ts, list); write.mem_map_handle = buf_node->mmap_hdl; - dev_vdbg(ac->dev, "%s: ab->phys[%pa]bufadd[0x%x] token[0x%x]buf_id[0x%x]buf_size[0x%x]mmaphdl[0x%x]" + dev_vdbg(ac->dev, "%s: ab->phys[%pK]bufadd[0x%x] token[0x%x]buf_id[0x%x]buf_size[0x%x]mmaphdl[0x%x]" , __func__, &ab->phys, write.buf_addr_lsw, @@ -5280,7 +5502,7 @@ int q6asm_write_nolock(struct audio_client *ac, uint32_t len, uint32_t msw_ts, port->dsp_buf = q6asm_get_next_buf(port->dsp_buf, port->max_buf_cnt); - dev_vdbg(ac->dev, "%s: ab->phys[%pa]bufadd[0x%x]token[0x%x] buf_id[0x%x]buf_size[0x%x]mmaphdl[0x%x]" + dev_vdbg(ac->dev, "%s: ab->phys[%pK]bufadd[0x%x]token[0x%x] buf_id[0x%x]buf_size[0x%x]mmaphdl[0x%x]" , __func__, &ab->phys, write.buf_addr_lsw, @@ -5302,6 +5524,63 @@ int q6asm_write_nolock(struct audio_client *ac, uint32_t len, uint32_t msw_ts, } int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp) +{ + struct asm_mtmx_strtr_get_params mtmx_params; + int rc; + + if (ac == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + return -EINVAL; + } + if (tstamp == NULL) { + pr_err("%s: tstamp NULL\n", __func__); + return -EINVAL; + } + + q6asm_add_hdr(ac, &mtmx_params.hdr, sizeof(mtmx_params), TRUE); + mtmx_params.hdr.opcode = ASM_SESSION_CMD_GET_MTMX_STRTR_PARAMS_V2; + mtmx_params.param_info.data_payload_addr_lsw = 0; + mtmx_params.param_info.data_payload_addr_msw = 0; + mtmx_params.param_info.mem_map_handle = 0; + mtmx_params.param_info.direction = (ac->io_mode & TUN_READ_IO_MODE + ? 1 : 0); + mtmx_params.param_info.module_id = + ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC; + mtmx_params.param_info.param_id = + ASM_SESSION_MTMX_STRTR_PARAM_SESSION_TIME_V3; + mtmx_params.param_info.param_max_size = + sizeof(struct asm_stream_param_data_v2) + + sizeof(struct asm_session_mtmx_strtr_param_session_time_v3_t); + atomic_set(&ac->time_flag, 1); + + dev_vdbg(ac->dev, "%s: session[%d]opcode[0x%x]\n", __func__, + ac->session, mtmx_params.hdr.opcode); + rc = apr_send_pkt(ac->apr, (uint32_t *) &mtmx_params); + if (rc < 0) { + pr_err("%s: Commmand 0x%x failed %d\n", __func__, + mtmx_params.hdr.opcode, rc); + goto fail_cmd; + } + rc = wait_event_timeout(ac->time_wait, + (atomic_read(&ac->time_flag) == 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout in getting session time from DSP\n", + __func__); + goto fail_cmd; + } + + *tstamp = ac->time_stamp; + return 0; + +fail_cmd: + return -EINVAL; +} + +int q6asm_get_session_time_legacy(struct audio_client *ac, uint64_t *tstamp) { struct apr_hdr hdr; int rc; diff --git a/sound/soc/msm/qdsp6v2/q6core.c b/sound/soc/msm/qdsp6v2/q6core.c index f9163bcce191c..a5af8b52858e4 100644 --- a/sound/soc/msm/qdsp6v2/q6core.c +++ b/sound/soc/msm/qdsp6v2/q6core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -33,6 +33,12 @@ */ #define Q6_READY_TIMEOUT_MS 100 +enum { + META_CAL, + CUST_TOP_CAL, + CORE_MAX_CAL +}; + struct q6core_str { struct apr_svc *core_handle_q; wait_queue_head_t bus_bw_req_wait; @@ -40,7 +46,8 @@ struct q6core_str { u32 bus_bw_resp_received; enum cmd_flags { FLAG_NONE, - FLAG_CMDRSP_LICENSE_RESULT + FLAG_CMDRSP_LICENSE_RESULT, + FLAG_AVCS_GET_VERSIONS_RESULT, } cmd_resp_received_flag; struct mutex cmd_lock; union { @@ -49,7 +56,10 @@ struct q6core_str { } cmd_resp_payload; struct avcs_cmd_rsp_get_low_power_segments_info_t lp_ocm_payload; u32 param; - struct cal_type_data *cal_data; + u32 q6_core_avs_version; + struct cal_type_data *cal_data[CORE_MAX_CAL]; + uint32_t mem_map_cal_handle; + int32_t adsp_status; }; static struct q6core_str q6core_lcl; @@ -94,6 +104,32 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) pr_info("%s: Cmd = AVCS_CMD_GET_LOW_POWER_SEGMENTS_INFO status[0x%x]\n", __func__, payload1[1]); break; + case AVCS_CMD_SHARED_MEM_UNMAP_REGIONS: + pr_debug("%s: Cmd = AVCS_CMD_SHARED_MEM_UNMAP_REGIONS status[0x%x]\n", + __func__, payload1[1]); + q6core_lcl.bus_bw_resp_received = 1; + wake_up(&q6core_lcl.bus_bw_req_wait); + break; + case AVCS_CMD_SHARED_MEM_MAP_REGIONS: + pr_debug("%s: Cmd = AVCS_CMD_SHARED_MEM_MAP_REGIONS status[0x%x]\n", + __func__, payload1[1]); + q6core_lcl.bus_bw_resp_received = 1; + wake_up(&q6core_lcl.bus_bw_req_wait); + break; + case AVCS_CMD_REGISTER_TOPOLOGIES: + pr_debug("%s: Cmd = AVCS_CMD_REGISTER_TOPOLOGIES status[0x%x]\n", + __func__, payload1[1]); + /* -ADSP status to match Linux error standard */ + q6core_lcl.adsp_status = -payload1[1]; + q6core_lcl.bus_bw_resp_received = 1; + wake_up(&q6core_lcl.bus_bw_req_wait); + break; + case AVCS_CMD_DEREGISTER_TOPOLOGIES: + pr_debug("%s: Cmd = AVCS_CMD_DEREGISTER_TOPOLOGIES status[0x%x]\n", + __func__, payload1[1]); + q6core_lcl.bus_bw_resp_received = 1; + wake_up(&q6core_lcl.bus_bw_req_wait); + break; default: pr_err("%s: Invalid cmd rsp[0x%x][0x%x] opcode %d\n", __func__, @@ -136,7 +172,14 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) q6core_lcl.core_handle_q = NULL; break; } - + case AVCS_CMDRSP_SHARED_MEM_MAP_REGIONS: + payload1 = data->payload; + pr_debug("%s: AVCS_CMDRSP_SHARED_MEM_MAP_REGIONS handle %d\n", + __func__, payload1[0]); + q6core_lcl.mem_map_cal_handle = payload1[0]; + q6core_lcl.bus_bw_resp_received = 1; + wake_up(&q6core_lcl.bus_bw_req_wait); + break; case AVCS_CMDRSP_ADSP_EVENT_GET_STATE: payload1 = data->payload; q6core_lcl.param = payload1[0]; @@ -147,7 +190,33 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) q6core_lcl.bus_bw_resp_received = 1; wake_up(&q6core_lcl.bus_bw_req_wait); break; - case AVCS_CMDRSP_GET_LICENSE_VALIDATION_RESULT: + case AVCS_GET_VERSIONS_RSP: + payload1 = data->payload; + pr_debug("%s: Received ADSP version response[3]0x%x\n", + __func__, payload1[3]); + q6core_lcl.cmd_resp_received_flag = + FLAG_AVCS_GET_VERSIONS_RESULT; + if (AVCS_CMDRSP_Q6_ID_2_6 == payload1[3]) { + q6core_lcl.q6_core_avs_version = Q6_SUBSYS_AVS2_6; + pr_debug("%s: Received ADSP version as 2.6\n", + __func__); + } else if (AVCS_CMDRSP_Q6_ID_2_7 == payload1[3]) { + q6core_lcl.q6_core_avs_version = Q6_SUBSYS_AVS2_7; + pr_debug("%s: Received ADSP version as 2.7\n", + __func__); + } else if (AVCS_CMDRSP_Q6_ID_2_8 == payload1[3]) { + q6core_lcl.q6_core_avs_version = Q6_SUBSYS_AVS2_8; + pr_info("%s: Received ADSP version as 2.8\n", + __func__); + } else { + pr_err("%s: ADSP version is neither 2.6 nor 2.7\n", + __func__); + q6core_lcl.q6_core_avs_version = Q6_SUBSYS_INVALID; + } + wake_up(&q6core_lcl.cmd_req_wait); + break; + + case AVCS_CMDRSP_GET_LICENSE_VALIDATION_RESULT: payload1 = data->payload; pr_debug("%s: cmd = LICENSE_VALIDATION_RESULT, result = 0x%x\n", __func__, payload1[0]); @@ -173,7 +242,6 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) } break; } - return 0; } @@ -184,7 +252,7 @@ void ocm_core_open(void) if (q6core_lcl.core_handle_q == NULL) q6core_lcl.core_handle_q = apr_register("ADSP", "CORE", aprv2_core_fn_q, 0xFFFFFFFF, NULL); - pr_debug("%s: Open_q %p\n", __func__, q6core_lcl.core_handle_q); + pr_debug("%s: Open_q %pK\n", __func__, q6core_lcl.core_handle_q); if (q6core_lcl.core_handle_q == NULL) { if (__ratelimit(&rl)) pr_err("%s: Unable to register CORE\n", @@ -202,16 +270,18 @@ int32_t core_set_license(uint32_t key, uint32_t module_id) pr_debug("%s: key:0x%x, id:0x%x\n", __func__, key, module_id); mutex_lock(&(q6core_lcl.cmd_lock)); - if (q6core_lcl.cal_data == NULL) { + if (q6core_lcl.cal_data[META_CAL] == NULL) { pr_err("%s: cal_data not initialized yet!!\n", __func__); rc = -EINVAL; goto unlock1; } - mutex_lock(&((q6core_lcl.cal_data)->lock)); - cal_block = cal_utils_get_only_cal_block(q6core_lcl.cal_data); - if (cal_block == NULL || cal_block->cal_data.kvaddr == NULL || - cal_block->cal_data.size <= 0) { + mutex_lock(&((q6core_lcl.cal_data[META_CAL])->lock)); + cal_block = + cal_utils_get_only_cal_block(q6core_lcl.cal_data[META_CAL]); + if (cal_block == NULL || + cal_block->cal_data.kvaddr == NULL || + cal_block->cal_data.size <= 0) { pr_err("%s: Invalid cal block to send", __func__); rc = -EINVAL; goto unlock2; @@ -263,7 +333,8 @@ int32_t core_set_license(uint32_t key, uint32_t module_id) cmd_setl->overwrite = 1; cmd_setl->size = cal_block->cal_data.size; memcpy((uint8_t *)cmd_setl + sizeof(struct avcs_cmd_set_license), - cal_block->cal_data.kvaddr, cal_block->cal_data.size); + cal_block->cal_data.kvaddr, + cal_block->cal_data.size); pr_info("%s: Set license opcode=0x%x ,key=0x%x, id =0x%x, size = %d\n", __func__, cmd_setl->hdr.opcode, metainfo->nKey, cmd_setl->id, cmd_setl->size); @@ -275,13 +346,72 @@ int32_t core_set_license(uint32_t key, uint32_t module_id) fail_cmd: kfree(cmd_setl); unlock2: - mutex_unlock(&((q6core_lcl.cal_data)->lock)); + mutex_unlock(&((q6core_lcl.cal_data[META_CAL])->lock)); unlock1: mutex_unlock(&(q6core_lcl.cmd_lock)); return rc; } +int core_get_adsp_ver(void) +{ + struct avcs_cmd_get_version_result get_aver_cmd; + int ret = 0; + + mutex_lock(&(q6core_lcl.cmd_lock)); + ocm_core_open(); + if (q6core_lcl.core_handle_q == NULL) { + pr_err("%s: apr registration for CORE failed\n", __func__); + ret = -ENODEV; + goto fail_cmd; + } + + get_aver_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + get_aver_cmd.hdr.pkt_size = sizeof(get_aver_cmd); + get_aver_cmd.hdr.src_port = 0; + get_aver_cmd.hdr.dest_port = 0; + get_aver_cmd.hdr.token = 0; + get_aver_cmd.hdr.opcode = AVCS_GET_VERSIONS; + + ret = apr_send_pkt(q6core_lcl.core_handle_q, + (uint32_t *) &get_aver_cmd); + if (ret < 0) { + pr_err("%s: Core get DSP version request failed, err %d\n", + __func__, ret); + ret = -EREMOTE; + goto fail_cmd; + } + + q6core_lcl.cmd_resp_received_flag &= ~(FLAG_AVCS_GET_VERSIONS_RESULT); + mutex_unlock(&(q6core_lcl.cmd_lock)); + ret = wait_event_timeout(q6core_lcl.cmd_req_wait, + (q6core_lcl.cmd_resp_received_flag == + FLAG_AVCS_GET_VERSIONS_RESULT), + msecs_to_jiffies(TIMEOUT_MS)); + mutex_lock(&(q6core_lcl.cmd_lock)); + if (!ret) { + pr_err("%s: wait_event timeout for AVCS_GET_VERSIONS_RESULT\n", + __func__); + ret = -ETIMEDOUT; + goto fail_cmd; + } + q6core_lcl.cmd_resp_received_flag &= ~(FLAG_AVCS_GET_VERSIONS_RESULT); + +fail_cmd: + if (ret < 0) + q6core_lcl.q6_core_avs_version = Q6_SUBSYS_INVALID; + mutex_unlock(&(q6core_lcl.cmd_lock)); + return ret; +} + +enum q6_subsys_image q6core_get_avs_version(void) +{ + if (q6core_lcl.q6_core_avs_version == 0) + core_get_adsp_ver(); + return q6core_lcl.q6_core_avs_version; +} + int32_t core_get_license_status(uint32_t module_id) { struct avcs_cmd_get_license_validation_result get_lvr_cmd; @@ -347,7 +477,7 @@ int core_dts_eagle_set(int size, char *data) pr_debug("DTS_EAGLE_CORE - %s\n", __func__); if (size <= 0 || !data) { - pr_err("DTS_EAGLE_CORE - %s: invalid size %i or pointer %p.\n", + pr_err("DTS_EAGLE_CORE - %s: invalid size %i or pointer %pK.\n", __func__, size, data); return -EINVAL; } @@ -393,7 +523,7 @@ int core_dts_eagle_get(int id, int size, char *data) pr_debug("DTS_EAGLE_CORE - %s\n", __func__); if (size <= 0 || !data) { - pr_err("DTS_EAGLE_CORE - %s: invalid size %i or pointer %p.\n", + pr_err("DTS_EAGLE_CORE - %s: invalid size %i or pointer %pK.\n", __func__, size, data); return -EINVAL; } @@ -568,35 +698,337 @@ bool q6core_is_adsp_ready(void) return ret; } + +static int q6core_map_memory_regions(phys_addr_t *buf_add, uint32_t mempool_id, + uint32_t *bufsz, uint32_t bufcnt, uint32_t *map_handle) +{ + struct avs_cmd_shared_mem_map_regions *mmap_regions = NULL; + struct avs_shared_map_region_payload *mregions = NULL; + void *mmap_region_cmd = NULL; + void *payload = NULL; + int ret = 0; + int i = 0; + int cmd_size = 0; + + cmd_size = sizeof(struct avs_cmd_shared_mem_map_regions) + + sizeof(struct avs_shared_map_region_payload) + * bufcnt; + + mmap_region_cmd = kzalloc(cmd_size, GFP_KERNEL); + if (mmap_region_cmd == NULL) + return -ENOMEM; + + mmap_regions = (struct avs_cmd_shared_mem_map_regions *)mmap_region_cmd; + mmap_regions->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + mmap_regions->hdr.pkt_size = cmd_size; + mmap_regions->hdr.src_port = 0; + mmap_regions->hdr.dest_port = 0; + mmap_regions->hdr.token = 0; + mmap_regions->hdr.opcode = AVCS_CMD_SHARED_MEM_MAP_REGIONS; + mmap_regions->mem_pool_id = ADSP_MEMORY_MAP_SHMEM8_4K_POOL & 0x00ff; + mmap_regions->num_regions = bufcnt & 0x00ff; + mmap_regions->property_flag = 0x00; + + payload = ((u8 *) mmap_region_cmd + + sizeof(struct avs_cmd_shared_mem_map_regions)); + mregions = (struct avs_shared_map_region_payload *)payload; + + for (i = 0; i < bufcnt; i++) { + mregions->shm_addr_lsw = lower_32_bits(buf_add[i]); + mregions->shm_addr_msw = upper_32_bits(buf_add[i]); + mregions->mem_size_bytes = bufsz[i]; + ++mregions; + } + + pr_debug("%s: sending memory map, addr %pa, size %d, bufcnt = %d\n", + __func__, buf_add, bufsz[0], mmap_regions->num_regions); + + *map_handle = 0; + q6core_lcl.bus_bw_resp_received = 0; + ret = apr_send_pkt(q6core_lcl.core_handle_q, (uint32_t *) + mmap_regions); + if (ret < 0) { + pr_err("%s: mmap regions failed %d\n", + __func__, ret); + ret = -EINVAL; + goto done; + } + + ret = wait_event_timeout(q6core_lcl.bus_bw_req_wait, + (q6core_lcl.bus_bw_resp_received == 1), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: timeout. waited for memory map\n", __func__); + ret = -ETIME; + goto done; + } + + *map_handle = q6core_lcl.mem_map_cal_handle; +done: + kfree(mmap_region_cmd); + return ret; +} + +static int q6core_memory_unmap_regions(uint32_t mem_map_handle) +{ + struct avs_cmd_shared_mem_unmap_regions unmap_regions; + int ret = 0; + + memset(&unmap_regions, 0, sizeof(unmap_regions)); + unmap_regions.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + unmap_regions.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(unmap_regions)); + unmap_regions.hdr.src_svc = APR_SVC_ADSP_CORE; + unmap_regions.hdr.src_domain = APR_DOMAIN_APPS; + unmap_regions.hdr.src_port = 0; + unmap_regions.hdr.dest_svc = APR_SVC_ADSP_CORE; + unmap_regions.hdr.dest_domain = APR_DOMAIN_ADSP; + unmap_regions.hdr.dest_port = 0; + unmap_regions.hdr.token = 0; + unmap_regions.hdr.opcode = AVCS_CMD_SHARED_MEM_UNMAP_REGIONS; + unmap_regions.mem_map_handle = mem_map_handle; + + q6core_lcl.bus_bw_resp_received = 0; + + pr_debug("%s: unmap regions map handle %d\n", + __func__, mem_map_handle); + + ret = apr_send_pkt(q6core_lcl.core_handle_q, (uint32_t *) + &unmap_regions); + if (ret < 0) { + pr_err("%s: unmap regions failed %d\n", + __func__, ret); + ret = -EINVAL; + goto done; + } + + ret = wait_event_timeout(q6core_lcl.bus_bw_req_wait, + (q6core_lcl.bus_bw_resp_received == 1), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: timeout. waited for memory_unmap\n", + __func__); + ret = -ETIME; + goto done; + } +done: + return ret; +} + +static int q6core_dereg_all_custom_topologies(void) +{ + int ret = 0; + struct avcs_cmd_deregister_topologies dereg_top; + + memset(&dereg_top, 0, sizeof(dereg_top)); + dereg_top.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + dereg_top.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, sizeof(dereg_top)); + dereg_top.hdr.src_svc = APR_SVC_ADSP_CORE; + dereg_top.hdr.src_domain = APR_DOMAIN_APPS; + dereg_top.hdr.src_port = 0; + dereg_top.hdr.dest_svc = APR_SVC_ADSP_CORE; + dereg_top.hdr.dest_domain = APR_DOMAIN_ADSP; + dereg_top.hdr.dest_port = 0; + dereg_top.hdr.token = 0; + dereg_top.hdr.opcode = AVCS_CMD_DEREGISTER_TOPOLOGIES; + dereg_top.payload_addr_lsw = 0; + dereg_top.payload_addr_msw = 0; + dereg_top.mem_map_handle = 0; + dereg_top.payload_size = 0; + dereg_top.mode = AVCS_MODE_DEREGISTER_ALL_CUSTOM_TOPOLOGIES; + + q6core_lcl.bus_bw_resp_received = 0; + + pr_debug("%s: Deregister topologies mode %d\n", + __func__, dereg_top.mode); + + ret = apr_send_pkt(q6core_lcl.core_handle_q, (uint32_t *) &dereg_top); + if (ret < 0) { + pr_err("%s: Deregister topologies failed %d\n", + __func__, ret); + goto done; + } + + ret = wait_event_timeout(q6core_lcl.bus_bw_req_wait, + (q6core_lcl.bus_bw_resp_received == 1), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout for Deregister topologies\n", + __func__); + goto done; + } +done: + return ret; +} + +static int q6core_send_custom_topologies(void) +{ + int ret = 0; + int ret2 = 0; + struct cal_block_data *cal_block = NULL; + struct avcs_cmd_register_topologies reg_top; + + memset(®_top, 0, sizeof(reg_top)); + mutex_lock(&q6core_lcl.cal_data[CUST_TOP_CAL]->lock); + mutex_lock(&q6core_lcl.cmd_lock); + + cal_block = cal_utils_get_only_cal_block( + q6core_lcl.cal_data[CUST_TOP_CAL]); + if (cal_block == NULL) { + pr_debug("%s: cal block is NULL!\n", __func__); + goto unlock; + } + if (cal_block->cal_data.size <= 0) { + pr_debug("%s: cal size is %zd not sending\n", + __func__, cal_block->cal_data.size); + goto unlock; + } + + if (!q6core_is_adsp_ready()) { + pr_err("%s: ADSP is not ready!\n", __func__); + ret = -ENODEV; + goto unlock; + } + + q6core_dereg_all_custom_topologies(); + + ret = q6core_map_memory_regions(&cal_block->cal_data.paddr, 0, + (uint32_t *)&cal_block->map_data.map_size, 1, + &cal_block->map_data.q6map_handle); + if (!ret) { + pr_err("%s: q6core_map_memory_regions failed\n", __func__); + goto unlock; + } + + reg_top.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + reg_top.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, sizeof(reg_top)); + reg_top.hdr.src_svc = APR_SVC_ADSP_CORE; + reg_top.hdr.src_domain = APR_DOMAIN_APPS; + reg_top.hdr.src_port = 0; + reg_top.hdr.dest_svc = APR_SVC_ADSP_CORE; + reg_top.hdr.dest_domain = APR_DOMAIN_ADSP; + reg_top.hdr.dest_port = 0; + reg_top.hdr.token = 0; + reg_top.hdr.opcode = AVCS_CMD_REGISTER_TOPOLOGIES; + reg_top.payload_addr_lsw = + lower_32_bits(cal_block->cal_data.paddr); + reg_top.payload_addr_msw = + upper_32_bits(cal_block->cal_data.paddr); + reg_top.mem_map_handle = cal_block->map_data.q6map_handle; + reg_top.payload_size = cal_block->cal_data.size; + + q6core_lcl.adsp_status = 0; + q6core_lcl.bus_bw_resp_received = 0; + + pr_debug("%s: Register topologies addr %pa, size %zd, map handle %d\n", + __func__, &cal_block->cal_data.paddr, cal_block->cal_data.size, + cal_block->map_data.q6map_handle); + + ret = apr_send_pkt(q6core_lcl.core_handle_q, (uint32_t *) ®_top); + if (ret < 0) { + pr_err("%s: Register topologies failed %d\n", + __func__, ret); + goto unmap; + } + + ret = wait_event_timeout(q6core_lcl.bus_bw_req_wait, + (q6core_lcl.bus_bw_resp_received == 1), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout for Register topologies\n", + __func__); + goto unmap; + } + + if (q6core_lcl.adsp_status < 0) + ret = q6core_lcl.adsp_status; +unmap: + ret2 = q6core_memory_unmap_regions(cal_block->map_data.q6map_handle); + if (!ret2) { + pr_err("%s: q6core_memory_unmap_regions failed for map handle %d\n", + __func__, cal_block->map_data.q6map_handle); + ret = ret2; + goto unlock; + } + +unlock: + mutex_unlock(&q6core_lcl.cmd_lock); + mutex_unlock(&q6core_lcl.cal_data[CUST_TOP_CAL]->lock); + + return ret; +} + +static int get_cal_type_index(int32_t cal_type) +{ + int ret = -EINVAL; + + switch (cal_type) { + case AUDIO_CORE_METAINFO_CAL_TYPE: + ret = META_CAL; + break; + case CORE_CUSTOM_TOPOLOGIES_CAL_TYPE: + ret = CUST_TOP_CAL; + break; + default: + pr_err("%s: invalid cal type %d!\n", __func__, cal_type); + } + return ret; +} + static int q6core_alloc_cal(int32_t cal_type, size_t data_size, void *data) { - int ret = 0; - pr_debug("%s:\n", __func__); + int ret = 0; + int cal_index; + + cal_index = get_cal_type_index(cal_type); + if (cal_index < 0) { + pr_err("%s: could not get cal index %d!\n", + __func__, cal_index); + ret = -EINVAL; + goto done; + } + ret = cal_utils_alloc_cal(data_size, data, - q6core_lcl.cal_data, 0, NULL); + q6core_lcl.cal_data[cal_index], 0, NULL); if (ret < 0) { pr_err("%s: cal_utils_alloc_block failed, ret = %d, cal type = %d!\n", __func__, ret, cal_type); - ret = -EINVAL; + goto done; } +done: return ret; } static int q6core_dealloc_cal(int32_t cal_type, size_t data_size, void *data) { - int ret = 0; - pr_debug("%s:\n", __func__); + int ret = 0; + int cal_index; + + cal_index = get_cal_type_index(cal_type); + if (cal_index < 0) { + pr_err("%s: could not get cal index %d!\n", + __func__, cal_index); + ret = -EINVAL; + goto done; + } + ret = cal_utils_dealloc_cal(data_size, data, - q6core_lcl.cal_data); + q6core_lcl.cal_data[cal_index]); if (ret < 0) { pr_err("%s: cal_utils_dealloc_block failed, ret = %d, cal type = %d!\n", __func__, ret, cal_type); - ret = -EINVAL; + goto done; } +done: return ret; } @@ -604,15 +1036,28 @@ static int q6core_set_cal(int32_t cal_type, size_t data_size, void *data) { int ret = 0; - pr_debug("%s:\n", __func__); + int cal_index; + + cal_index = get_cal_type_index(cal_type); + if (cal_index < 0) { + pr_err("%s: could not get cal index %d!\n", + __func__, cal_index); + ret = -EINVAL; + goto done; + } + ret = cal_utils_set_cal(data_size, data, - q6core_lcl.cal_data, 0, NULL); + q6core_lcl.cal_data[cal_index], 0, NULL); if (ret < 0) { pr_err("%s: cal_utils_set_cal failed, ret = %d, cal type = %d!\n", __func__, ret, cal_type); - ret = -EINVAL; + goto done; } + + if (cal_index == CUST_TOP_CAL) + ret = q6core_send_custom_topologies(); +done: return ret; } @@ -620,7 +1065,7 @@ static void q6core_delete_cal_data(void) { pr_debug("%s:\n", __func__); - cal_utils_destroy_cal_types(1, &q6core_lcl.cal_data); + cal_utils_destroy_cal_types(CORE_MAX_CAL, q6core_lcl.cal_data); return; } @@ -628,16 +1073,21 @@ static void q6core_delete_cal_data(void) static int q6core_init_cal_data(void) { int ret = 0; - struct cal_type_info cal_type_info = { - {AUDIO_CORE_METAINFO_CAL_TYPE, + struct cal_type_info cal_type_info[] = { + {{AUDIO_CORE_METAINFO_CAL_TYPE, + {q6core_alloc_cal, q6core_dealloc_cal, NULL, + q6core_set_cal, NULL, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} }, + + {{CORE_CUSTOM_TOPOLOGIES_CAL_TYPE, {q6core_alloc_cal, q6core_dealloc_cal, NULL, q6core_set_cal, NULL, NULL} }, - {NULL, NULL, cal_utils_match_buf_num} + {NULL, NULL, cal_utils_match_buf_num} } }; pr_debug("%s:\n", __func__); - ret = cal_utils_create_cal_types(1, &q6core_lcl.cal_data, - &cal_type_info); + ret = cal_utils_create_cal_types(CORE_MAX_CAL, + q6core_lcl.cal_data, cal_type_info); if (ret < 0) { pr_err("%s: could not create cal type!\n", __func__); @@ -661,6 +1111,8 @@ static int __init core_init(void) init_waitqueue_head(&q6core_lcl.cmd_req_wait); q6core_lcl.cmd_resp_received_flag = FLAG_NONE; mutex_init(&q6core_lcl.cmd_lock); + q6core_lcl.mem_map_cal_handle = 0; + q6core_lcl.adsp_status = 0; if (q6core_init_cal_data()) pr_err("%s: could not init cal data!\n", __func__); diff --git a/sound/soc/msm/qdsp6v2/q6lsm.c b/sound/soc/msm/qdsp6v2/q6lsm.c index 04f37682dfe26..29d0ba3f2ca12 100644 --- a/sound/soc/msm/qdsp6v2/q6lsm.c +++ b/sound/soc/msm/qdsp6v2/q6lsm.c @@ -134,7 +134,7 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) uint32_t *payload; if (!client || !data) { - pr_err("%s: client %p data %p\n", + pr_err("%s: client %pK data %pK\n", __func__, client, data); WARN_ON(1); return -EINVAL; @@ -347,6 +347,7 @@ void q6lsm_client_free(struct lsm_client *client) q6lsm_mmap_apr_dereg(); mutex_destroy(&client->cmd_lock); kfree(client); + client = NULL; } /* @@ -942,7 +943,7 @@ int q6lsm_register_sound_model(struct lsm_client *client, rmb(); cmd.mem_map_handle = client->sound_model.mem_map_handle; - pr_debug("%s: addr %pa, size %d, handle 0x%x\n", __func__, + pr_debug("%s: addr %pK, size %d, handle 0x%x\n", __func__, &client->sound_model.phys, cmd.model_size, cmd.mem_map_handle); rc = q6lsm_apr_send_pkt(client, client->apr, &cmd, true, NULL); if (rc) @@ -1016,7 +1017,7 @@ static int q6lsm_memory_map_regions(struct lsm_client *client, int rc; int cmd_size = 0; - pr_debug("%s: dma_addr_p 0x%pa, dma_buf_sz %d, mmap_p 0x%p, session %d\n", + pr_debug("%s: dma_addr_p 0x%pK, dma_buf_sz %d, mmap_p 0x%pK, session %d\n", __func__, &dma_addr_p, dma_buf_sz, mmap_p, client->session); if (CHECK_SESSION(client->session)) { @@ -1296,7 +1297,7 @@ int q6lsm_snd_model_buf_alloc(struct lsm_client *client, size_t len, if (cal_block == NULL) goto fail; - pr_debug("%s:Snd Model len = %zd cal size %zd phys addr %pa", __func__, + pr_debug("%s:Snd Model len = %zd cal size %zd phys addr %pK", __func__, len, cal_block->cal_data.size, &cal_block->cal_data.paddr); if (!cal_block->cal_data.paddr) { @@ -1351,8 +1352,8 @@ int q6lsm_snd_model_buf_alloc(struct lsm_client *client, size_t len, memcpy((client->sound_model.data + pad_zero + client->sound_model.size), (uint32_t *)cal_block->cal_data.kvaddr, client->lsm_cal_size); - pr_debug("%s: Copy cal start virt_addr %p phy_addr %pa\n" - "Offset cal virtual Addr %p\n", __func__, + pr_debug("%s: Copy cal start virt_addr %pK phy_addr %pK\n" + "Offset cal virtual Addr %pK\n", __func__, client->sound_model.data, &client->sound_model.phys, (pad_zero + client->sound_model.data + client->sound_model.size)); @@ -1680,7 +1681,7 @@ int q6lsm_lab_control(struct lsm_client *client, u32 enable) u32 param_size; if (!client) { - pr_err("%s: invalid param client %p\n", __func__, client); + pr_err("%s: invalid param client %pK\n", __func__, client); return -EINVAL; } /* enable/disable lab on dsp */ @@ -1737,7 +1738,7 @@ int q6lsm_stop_lab(struct lsm_client *client) { int rc = 0; if (!client) { - pr_err("%s: invalid param client %p\n", __func__, client); + pr_err("%s: invalid param client %pK\n", __func__, client); return -EINVAL; } rc = q6lsm_cmd(client, LSM_SESSION_CMD_EOB, true); @@ -1750,7 +1751,7 @@ int q6lsm_read(struct lsm_client *client, struct lsm_cmd_read *read) { int rc = 0; if (!client || !read) { - pr_err("%s: Invalid params client %p read %p\n", __func__, + pr_err("%s: Invalid params client %pK read %pK\n", __func__, client, read); return -EINVAL; } @@ -1820,7 +1821,7 @@ int q6lsm_lab_buffer_alloc(struct lsm_client *client, bool alloc) kfree(client->lab_buffer); client->lab_buffer = NULL; } else { - pr_debug("%s: Memory map handle %x phys %pa size %d\n", + pr_debug("%s: Memory map handle %x phys %pK size %d\n", __func__, client->lab_buffer[0].mem_map_handle, &client->lab_buffer[0].phys, diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c index 828c796d662a0..5ba0ca45864d5 100644 --- a/sound/soc/msm/qdsp6v2/q6voice.c +++ b/sound/soc/msm/qdsp6v2/q6voice.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -326,7 +326,7 @@ static struct voice_data *voice_get_session(u32 session_id) break; } - pr_debug("%s:session_id 0x%x session handle %p\n", + pr_debug("%s:session_id 0x%x session handle %pK\n", __func__, session_id, v); return v; @@ -2978,7 +2978,7 @@ static int voice_map_cal_memory(struct cal_block_data *cal_block, cal_block->map_data.map_size, VOC_CAL_MEM_MAP_TOKEN); if (result < 0) { - pr_err("%s: Mmap did not work! addr = 0x%pa, size = %zd\n", + pr_err("%s: Mmap did not work! addr = 0x%pK, size = %zd\n", __func__, &cal_block->cal_data.paddr, cal_block->map_data.map_size); @@ -3011,7 +3011,7 @@ static int remap_cal_data(struct cal_block_data *cal_block, goto done; } } else { - pr_debug("%s: Cal block 0x%pa, size %zd already mapped. Q6 map handle = %d\n", + pr_debug("%s: Cal block 0x%pK, size %zd already mapped. Q6 map handle = %d\n", __func__, &cal_block->cal_data.paddr, cal_block->map_data.map_size, cal_block->map_data.q6map_handle); @@ -3209,7 +3209,7 @@ int voc_map_rtac_block(struct rtac_cal_block_data *cal_block) if (!is_rtac_memory_allocated()) { result = voice_alloc_rtac_mem_map_table(); if (result < 0) { - pr_err("%s: RTAC alloc mem map table did not work! addr = 0x%pa, size = %d\n", + pr_err("%s: RTAC alloc mem map table did not work! addr = 0x%pK, size = %d\n", __func__, &cal_block->cal_data.paddr, cal_block->map_data.map_size); @@ -3224,7 +3224,7 @@ int voc_map_rtac_block(struct rtac_cal_block_data *cal_block) cal_block->map_data.map_size, VOC_RTAC_MEM_MAP_TOKEN); if (result < 0) { - pr_err("%s: RTAC mmap did not work! addr = 0x%pa, size = %d\n", + pr_err("%s: RTAC mmap did not work! addr = 0x%pK, size = %d\n", __func__, &cal_block->cal_data.paddr, cal_block->map_data.map_size); @@ -3915,7 +3915,7 @@ static int voice_send_cvs_packet_exchange_config_cmd(struct voice_data *v) packet_exchange_config_pkt.enc_buf_addr = (uint32_t)enc_buf; packet_exchange_config_pkt.enc_buf_size = 4096; - pr_debug("%s: dec buf: add %pa, size %d, enc buf: add %pa, size %d\n", + pr_debug("%s: dec buf: add %pK, size %d, enc buf: add %pK, size %d\n", __func__, &dec_buf, packet_exchange_config_pkt.dec_buf_size, @@ -4328,7 +4328,7 @@ int voc_start_record(uint32_t port_id, uint32_t set, uint32_t session_id) break; } - pr_debug("%s: port_id: %d, set: %d, v: %p\n", + pr_debug("%s: port_id: %d, set: %d, v: %pK\n", __func__, port_id, set, v); mutex_lock(&v->lock); @@ -6400,12 +6400,12 @@ static int voice_alloc_oob_shared_mem(void) cnt++; } - pr_debug("%s buf[0].data:[%p], buf[0].phys:[%pa], &buf[0].phys:[%p],\n", + pr_debug("%s buf[0].data:[%pK], buf[0].phys:[%pK], &buf[0].phys:[%pK],\n", __func__, (void *)v->shmem_info.sh_buf.buf[0].data, &v->shmem_info.sh_buf.buf[0].phys, (void *)&v->shmem_info.sh_buf.buf[0].phys); - pr_debug("%s: buf[1].data:[%p], buf[1].phys[%pa], &buf[1].phys[%p]\n", + pr_debug("%s: buf[1].data:[%pK], buf[1].phys[%pK], &buf[1].phys[%pK]\n", __func__, (void *)v->shmem_info.sh_buf.buf[1].data, &v->shmem_info.sh_buf.buf[1].phys, @@ -6447,7 +6447,7 @@ static int voice_alloc_oob_mem_table(void) } v->shmem_info.memtbl.size = sizeof(struct vss_imemory_table_t); - pr_debug("%s data[%p]phys[%pa][%p]\n", __func__, + pr_debug("%s data[%pK]phys[%pK][%pK]\n", __func__, (void *)v->shmem_info.memtbl.data, &v->shmem_info.memtbl.phys, (void *)&v->shmem_info.memtbl.phys); @@ -6799,7 +6799,7 @@ static int voice_alloc_cal_mem_map_table(void) } common.cal_mem_map_table.size = sizeof(struct vss_imemory_table_t); - pr_debug("%s: data %p phys %pa\n", __func__, + pr_debug("%s: data %pK phys %pK\n", __func__, common.cal_mem_map_table.data, &common.cal_mem_map_table.phys); @@ -6826,7 +6826,7 @@ static int voice_alloc_rtac_mem_map_table(void) } common.rtac_mem_map_table.size = sizeof(struct vss_imemory_table_t); - pr_debug("%s: data %p phys %pa\n", __func__, + pr_debug("%s: data %pK phys %pK\n", __func__, common.rtac_mem_map_table.data, &common.rtac_mem_map_table.phys); @@ -7427,7 +7427,7 @@ static int voice_alloc_source_tracking_shared_memory(void) memset((void *)(common.source_tracking_sh_mem.sh_mem_block.data), 0, common.source_tracking_sh_mem.sh_mem_block.size); - pr_debug("%s: sh_mem_block: phys:[%pa], data:[0x%p], size:[%zd]\n", + pr_debug("%s: sh_mem_block: phys:[%pK], data:[0x%pK], size:[%zd]\n", __func__, &(common.source_tracking_sh_mem.sh_mem_block.phys), (void *)(common.source_tracking_sh_mem.sh_mem_block.data), @@ -7458,7 +7458,7 @@ static int voice_alloc_source_tracking_shared_memory(void) memset((void *)(common.source_tracking_sh_mem.sh_mem_table.data), 0, common.source_tracking_sh_mem.sh_mem_table.size); - pr_debug("%s sh_mem_table: phys:[%pa], data:[0x%p], size:[%zd],\n", + pr_debug("%s sh_mem_table: phys:[%pK], data:[0x%pK], size:[%zd],\n", __func__, &(common.source_tracking_sh_mem.sh_mem_table.phys), (void *)(common.source_tracking_sh_mem.sh_mem_table.data), diff --git a/sound/soc/msm/qdsp6v2/rtac.c b/sound/soc/msm/qdsp6v2/rtac.c index fcae47f6355c9..f1705897b18e6 100644 --- a/sound/soc/msm/qdsp6v2/rtac.c +++ b/sound/soc/msm/qdsp6v2/rtac.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -174,7 +174,7 @@ int rtac_allocate_cal_buffer(uint32_t cal_type) } if (rtac_cal[cal_type].cal_data.paddr != 0) { - pr_err("%s: memory already allocated! cal_type %d, paddr 0x%pa\n", + pr_err("%s: memory already allocated! cal_type %d, paddr 0x%pK\n", __func__, cal_type, &rtac_cal[cal_type].cal_data.paddr); result = -EPERM; goto done; @@ -193,7 +193,7 @@ int rtac_allocate_cal_buffer(uint32_t cal_type) goto done; } - pr_debug("%s: cal_type %d, paddr 0x%pa, kvaddr 0x%p, map_size 0x%x\n", + pr_debug("%s: cal_type %d, paddr 0x%pK, kvaddr 0x%pK, map_size 0x%x\n", __func__, cal_type, &rtac_cal[cal_type].cal_data.paddr, rtac_cal[cal_type].cal_data.kvaddr, @@ -223,7 +223,7 @@ int rtac_free_cal_buffer(uint32_t cal_type) result = msm_audio_ion_free(rtac_cal[cal_type].map_data.ion_client, rtac_cal[cal_type].map_data.ion_handle); if (result < 0) { - pr_err("%s: ION free for RTAC failed! cal_type %d, paddr 0x%pa\n", + pr_err("%s: ION free for RTAC failed! cal_type %d, paddr 0x%pK\n", __func__, cal_type, &rtac_cal[cal_type].cal_data.paddr); goto done; } @@ -657,7 +657,7 @@ static int get_voice_index(u32 mode, u32 handle) /* ADM APR */ void rtac_set_adm_handle(void *handle) { - pr_debug("%s: handle = %p\n", __func__, handle); + pr_debug("%s: handle = %pK\n", __func__, handle); mutex_lock(&rtac_adm_apr_mutex); rtac_adm_apr_data.apr_handle = handle; @@ -715,7 +715,7 @@ u32 send_adm_apr(void *buf, u32 opcode) if (copy_from_user(&user_buf_size, (void *)buf, sizeof(user_buf_size))) { - pr_err("%s: Copy from user failed! buf = 0x%p\n", + pr_err("%s: Copy from user failed! buf = 0x%pK\n", __func__, buf); goto done; } @@ -810,7 +810,7 @@ u32 send_adm_apr(void *buf, u32 opcode) memcpy(rtac_adm_buffer, &adm_params, sizeof(adm_params)); atomic_set(&rtac_adm_apr_data.cmd_state, 1); - pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%pa\n", + pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%pK\n", __func__, opcode, &rtac_cal[ADM_RTAC_CAL].cal_data.paddr); @@ -921,7 +921,7 @@ u32 send_rtac_asm_apr(void *buf, u32 opcode) if (copy_from_user(&user_buf_size, (void *)buf, sizeof(user_buf_size))) { - pr_err("%s: Copy from user failed! buf = 0x%p\n", + pr_err("%s: Copy from user failed! buf = 0x%pK\n", __func__, buf); goto done; } @@ -1016,7 +1016,7 @@ u32 send_rtac_asm_apr(void *buf, u32 opcode) memcpy(rtac_asm_buffer, &asm_params, sizeof(asm_params)); atomic_set(&rtac_asm_apr_data[session_id].cmd_state, 1); - pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%pa\n", + pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%pK\n", __func__, opcode, &rtac_cal[ASM_RTAC_CAL].cal_data.paddr); @@ -1148,7 +1148,7 @@ static u32 send_rtac_afe_apr(void *buf, uint32_t opcode) if (copy_from_user(&user_afe_buf, (void *)buf, sizeof(struct rtac_afe_user_data))) { - pr_err("%s: Copy from user failed! buf = 0x%p\n", + pr_err("%s: Copy from user failed! buf = 0x%pK\n", __func__, buf); goto done; } @@ -1256,7 +1256,7 @@ static u32 send_rtac_afe_apr(void *buf, uint32_t opcode) atomic_set(&rtac_afe_apr_data.cmd_state, 1); - pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%pa\n", + pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%pK\n", __func__, opcode, &rtac_cal[AFE_RTAC_CAL].cal_data.paddr); @@ -1372,7 +1372,7 @@ u32 send_voice_apr(u32 mode, void *buf, u32 opcode) if (copy_from_user(&user_buf_size, (void *)buf, sizeof(user_buf_size))) { - pr_err("%s: Copy from user failed! buf = 0x%p\n", + pr_err("%s: Copy from user failed! buf = 0x%pK\n", __func__, buf); goto done; } @@ -1468,7 +1468,7 @@ u32 send_voice_apr(u32 mode, void *buf, u32 opcode) memcpy(rtac_voice_buffer, &voice_params, sizeof(voice_params)); atomic_set(&rtac_voice_apr_data[mode].cmd_state, 1); - pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%pa\n", + pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%pK\n", __func__, opcode, &rtac_cal[VOICE_RTAC_CAL].cal_data.paddr); diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c index 4b3be6c3c91e2..6305074255f1e 100644 --- a/sound/soc/soc-utils.c +++ b/sound/soc/soc-utils.c @@ -123,6 +123,9 @@ static int snd_soc_dummy_probe(struct platform_device *pdev) { int ret; + memset(&dummy_codec, 0, + sizeof(struct snd_soc_codec_driver)); + ret = snd_soc_register_codec(&pdev->dev, &dummy_codec, &dummy_dai, 1); if (ret < 0) return ret; diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 63b6f8c8edf28..54494df33dd27 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1515,12 +1515,15 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, case EPERM: case EACCES: return scnprintf(msg, size, - "You may not have permission to collect %sstats.\n" - "Consider tweaking /proc/sys/kernel/perf_event_paranoid:\n" - " -1 - Not paranoid at all\n" - " 0 - Disallow raw tracepoint access for unpriv\n" - " 1 - Disallow cpu events for unpriv\n" - " 2 - Disallow kernel profiling for unpriv", + "You may not have permission to collect %sstats.\n\n" + "Consider tweaking /proc/sys/kernel/perf_event_paranoid,\n" + "which controls use of the performance events system by\n" + "unprivileged users (without CAP_SYS_ADMIN).\n\n" + "The default value is 1:\n\n" + " -1: Allow use of (almost) all events by all users\n" + ">= 0: Disallow raw tracepoint access by users without CAP_IOC_LOCK\n" + ">= 1: Disallow CPU event access by users without CAP_SYS_ADMIN\n" + ">= 2: Disallow kernel profiling by users without CAP_SYS_ADMIN", target->system_wide ? "system-wide " : ""); case ENOENT: return scnprintf(msg, size, "The %s event is not supported.",