Merge "charger: fix soc incorrect when fg_restart is executing" into android-msm-triton-3.18
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..4341e3a
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,27 @@
+cc_binary_host {
+ name: "unifdef",
+ srcs: ["scripts/unifdef.c"],
+ sanitize: {
+ never: true,
+ }
+}
+
+gensrcs {
+ name: "qseecom-kernel-includes",
+
+ // move to out/ as root for header generation because of scripts/unifdef
+ // storage - at the expense of extra ../ references
+ cmd: "pushd out && mkdir -p scripts && rm -f scripts/unifdef && ln -s ../../$(location unifdef) scripts/unifdef && ../$(location scripts/headers_install.sh) `dirname ../$(out)` ../ $(in) && popd",
+
+ tools: ["unifdef"],
+ tool_files: ["scripts/headers_install.sh"],
+ export_include_dirs: ["include/uapi"],
+ srcs: ["include/uapi/linux/qseecom.h"],
+ output_extension: "h",
+}
+
+cc_library_headers {
+ name: "qseecom-kernel-headers",
+ generated_headers: ["qseecom-kernel-includes"],
+ export_generated_headers: ["qseecom-kernel-includes"],
+}
diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs
index b8d0a30..f82da9b 100644
--- a/Documentation/ABI/testing/sysfs-fs-f2fs
+++ b/Documentation/ABI/testing/sysfs-fs-f2fs
@@ -101,6 +101,7 @@
Contact: "Jaegeuk Kim" <jaegeuk@kernel.org>
Description:
Controls the trimming rate in batch mode.
+ <deprecated>
What: /sys/fs/f2fs/<disk>/cp_interval
Date: October 2015
diff --git a/Documentation/device-mapper/thin-provisioning.txt b/Documentation/device-mapper/thin-provisioning.txt
index 2f51735..2800b01 100644
--- a/Documentation/device-mapper/thin-provisioning.txt
+++ b/Documentation/device-mapper/thin-provisioning.txt
@@ -112,9 +112,11 @@
free space on the data device drops below this level then a dm event
will be triggered which a userspace daemon should catch allowing it to
extend the pool device. Only one such event will be sent.
-Resuming a device with a new table itself triggers an event so the
-userspace daemon can use this to detect a situation where a new table
-already exceeds the threshold.
+
+No special event is triggered if a just resumed device's free space is below
+the low water mark. However, resuming a device always triggers an
+event; a userspace daemon should verify that free space exceeds the low
+water mark when handling this event.
A low water mark for the metadata device is maintained in the kernel and
will trigger a dm event if free space on the metadata device drops below
diff --git a/Documentation/devicetree/bindings/iio/imu/st-asm330.txt b/Documentation/devicetree/bindings/iio/imu/st-asm330.txt
new file mode 100644
index 0000000..3833d59
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/imu/st-asm330.txt
@@ -0,0 +1,44 @@
+The ASM330 is a highly integrated, low power inertial measurement unit (IMU)
+that provides precise acceleration and angular rate (gyroscopic) measurement.
+
+To enable driver probing, add the asm330lhh node to the platform device tree as described below.
+
+Required properties:
+
+- compatible: "st,asm330lhh"
+- reg: the I2C address or SPI chip select the device will respond to
+- interrupt-parent: phandle to the parent interrupt controller as documented in [interrupts][4]
+- interrupts: interrupt mapping for IRQ as documented in [interrupts][4]
+
+Recommended properties for SPI bus usage:
+- spi-max-frequency: maximum SPI bus frequency as documented in [SPI][3]
+
+Optional properties:
+- st,drdy-int-pin: MEMS sensor interrupt line to use (default 1)
+
+I2C example (based on Raspberry PI 3):
+
+ &i2c0 {
+ status = "ok";
+ #address-cells = <0x1>;
+ #size-cells = <0x0>;
+ asm330lhh@6b {
+ compatible = "st,asm330lhh";
+ reg = <0x6b>;
+ interrupt-parent = <&gpio>;
+ interrupts = <26 IRQ_TYPE_EDGE_RISING>;
+ };
+
+SPI example (based on Raspberry PI 3):
+
+ &spi0 {
+ status = "ok";
+ #address-cells = <0x1>;
+ #size-cells = <0x0>;
+ asm330lhh@0 {
+ spi-max-frequency = <500000>;
+ compatible = "st,asm330lhh";
+ reg = <0>;
+ interrupt-parent = <&gpio>;
+ interrupts = <26 IRQ_TYPE_EDGE_RISING>;
+ };
diff --git a/Documentation/devicetree/bindings/input/touchscreen/himax_i2c_ts.txt b/Documentation/devicetree/bindings/input/touchscreen/himax_i2c_ts.txt
new file mode 100644
index 0000000..9889f55
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/himax_i2c_ts.txt
@@ -0,0 +1,57 @@
+Himax touch controller
+
+Required properties:
+
+ - compatible : should be "himax,hxcommon"
+ - reg : i2c slave address of the device
+ - interrupt-parent : parent of interrupt
+ - interrupts : touch sample interrupt to indicate presense or release
+ of fingers on the panel.
+ - himax,irq-gpio : irq gpio
+ - himax,reset-gpio : reset gpio
+
+Optional property:
+ - vdd-supply : Analog power supply needed to power device
+ - vcc_i2c-supply : Power source required to pull up i2c bus
+ - himax,i2c-pull-up : specify to indicate pull up is needed
+ - himax,disable-gpios : specify to disable gpios in suspend (power saving)
+ - himax,button-map : virtual key code mappings to be used
+ - himax,x-flip : modify orientation of the x axis
+ - himax,y-flip : modify orientation of the y axis
+ - himax,panel-coords : touch panel min x, min y, max x and
+ max y resolution
+ - himax,display-coords : display min x, min y, max x and
+ max y resolution
+ - himax,reset-delay : reset delay for controller (ms), default 100
+ - himax,fw-image-name : name of firmware .img file in /etc/firmware
+ - himax,power-down : fully power down regulators in suspend
+ - himax,do-lockdown : perform one time lockdown procedure
+
+Example:
+ i2c@f9927000 { /* BLSP1 QUP5 */
+ cell-index = <5>;
+ compatible = "himax,hxcommon";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-names = "qup_phys_addr";
+ reg = <0xf9927000 0x1000>;
+ interrupt-names = "qup_err_intr";
+ interrupts = <0 99 0>;
+ gpios = <&msmgpio 19 0>, /* SCL */
+ <&msmgpio 18 0>; /* SDA */
+ qcom,i2c-bus-freq = <100000>;
+ qcom,i2c-src-freq = <19200000>;
+
+ himax_ts@20 {
+ compatible = "himax,hxcommon"
+ reg = <0x20>;
+ interrupt-parent = <&tlmm>;
+ interrupts = <255 0x2008>;
+ vdd-supply = <&pm8994_l15>;
+ avdd-supply = <&pm8994_l22>;
+ himax,panel-coords = <0 720 0 1440>;
+ himax,display-coords = <0 720 0 1440>;
+ himax,irq-gpio = <&tlmm 255 0x2008>;
+ himax,rst-gpio = <&tlmm 8 0x00>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/input/touchscreen/synaptics_dsxv26_i2c.txt b/Documentation/devicetree/bindings/input/touchscreen/synaptics_dsxv26_i2c.txt
index b3d75a84..f7de07f 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/synaptics_dsxv26_i2c.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/synaptics_dsxv26_i2c.txt
@@ -28,6 +28,7 @@
- synaptics,reset-delay-ms : reset delay for controller (ms), default 100.
- synaptics,max-y-for-2d : maximal y value of the panel.
- synaptics,bus-lpm-cur-uA : I2C bus idle mode current setting.
+ - synaptics,fw-name : name of firmware .img file in /lib/firmware
- clock-names : Clock names used for secure touch. They are: "iface_clk", "core_clk"
- clocks : Defined if 'clock-names' DT property is defined. These clocks
are associated with the underlying I2C bus.
diff --git a/Documentation/devicetree/bindings/platform/msm/ssm.txt b/Documentation/devicetree/bindings/platform/msm/ssm.txt
deleted file mode 100644
index 7df3efd..0000000
--- a/Documentation/devicetree/bindings/platform/msm/ssm.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-* Qualcomm Technologies, Inc. Secure Service Module driver
-
-This module enables framework to which a client can register itself
-specifying different attributes and defining various permission levels
-associated with different combination of attribute values and mode of the system.
-
-Required properties:
-- compatible: Must be "qcom,ssm"
-
-Example:
- qcom,ssm {
- compatible = "qcom,ssm";
- };
\ No newline at end of file
diff --git a/Documentation/devicetree/bindings/power/qpnp-fg-gen3.txt b/Documentation/devicetree/bindings/power/qpnp-fg-gen3.txt
index 40251e0..a2f839b 100644
--- a/Documentation/devicetree/bindings/power/qpnp-fg-gen3.txt
+++ b/Documentation/devicetree/bindings/power/qpnp-fg-gen3.txt
@@ -417,6 +417,11 @@
Value type: <u32>
Definition: The minimum battery current for FG to enter into sync-sleep.
+- qcom,fg-disable-in-twm
+ Usage: optional
+ Value type: <empty>
+ Definition: A boolean property which disables FG during TWM entry.
+
==========================================================
Second Level Nodes - Peripherals managed by FG Gen3 driver
==========================================================
diff --git a/Documentation/devicetree/bindings/smcinvoke/smcinvoke.txt b/Documentation/devicetree/bindings/smcinvoke/smcinvoke.txt
new file mode 100644
index 0000000..22243f6
--- /dev/null
+++ b/Documentation/devicetree/bindings/smcinvoke/smcinvoke.txt
@@ -0,0 +1,34 @@
+* SMCInvoke driver to provide transport between TZ and Linux
+
+Required properties:
+- compatible : Should be "qcom,smcinvoke"
+- reg : should contain memory region address reserved for loading secure apps.
+- qcom, msm_bus,name: Should be "smcinvoke-noc"
+- qcom, msm_bus,num_cases: Depends on the use cases for bus scaling
+- qcom, msm_bus,num_paths: The paths for source and destination ports
+- qcom, msm_bus,vectors: Vectors for bus topology.
+- qcom,ce-opp-freq: indicates the CE operating frequency in Hz, changes from target to target.
+ - qcom,clock-support : indicates clocks are handled by smcinvoke (could be handled by RPM)
+
+Example:
+ qcom_smcinvoke: smcinvoke@88000000 {
+ compatible = "qcom,smcinvoke";
+ reg = <0x88000000 0x500000>;
+ qcom,clock-support;
+ qcom,msm-bus,name = "smcinvoke-noc";
+ qcom,msm-bus,num-cases = <4>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <47 512 0 0>,
+ <47 512 0 0>,
+ <47 512 120000 1200000>,
+ <47 512 393600 3936000>;
+ clocks = <&clock_gcc clk_crypto_clk_src>,
+ <&clock_gcc clk_gcc_crypto_clk>,
+ <&clock_gcc clk_gcc_crypto_ahb_clk>,
+ <&clock_gcc clk_gcc_crypto_axi_clk>;
+ clock-names = "core_clk_src", "core_clk",
+ "iface_clk", "bus_clk";
+ qcom,ce-opp-freq = <100000000>;
+ status = "ok";
+ };
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 26976f6..dc2b1a2 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -78,6 +78,7 @@
hisilicon Hisilicon Limited.
honeywell Honeywell
hp Hewlett Packard
+himax Himax Coroporation
i2se I2SE GmbH
ibm International Business Machines (IBM)
idt Integrated Device Technologies, Inc.
diff --git a/Documentation/filesystems/f2fs.txt b/Documentation/filesystems/f2fs.txt
index 36cd634..9342fde 100644
--- a/Documentation/filesystems/f2fs.txt
+++ b/Documentation/filesystems/f2fs.txt
@@ -169,13 +169,15 @@
passes down hints with its policy.
alloc_mode=%s Adjust block allocation policy, which supports "reuse"
and "default".
-fsync_mode=%s Control the policy of fsync. Currently supports "posix"
- and "strict". In "posix" mode, which is default, fsync
- will follow POSIX semantics and does a light operation
- to improve the filesystem performance. In "strict" mode,
- fsync will be heavy and behaves in line with xfs, ext4
- and btrfs, where xfstest generic/342 will pass, but the
- performance will regress.
+fsync_mode=%s Control the policy of fsync. Currently supports "posix",
+ "strict", and "nobarrier". In "posix" mode, which is
+ default, fsync will follow POSIX semantics and does a
+ light operation to improve the filesystem performance.
+ In "strict" mode, fsync will be heavy and behaves in line
+ with xfs, ext4 and btrfs, where xfstest generic/342 will
+ pass, but the performance will regress. "nobarrier" is
+ based on "posix", but doesn't issue flush command for
+ non-atomic files likewise "nobarrier" mount option.
test_dummy_encryption Enable dummy encryption, which provides a fake fscrypt
context. The fake fscrypt context is used by xfstests.
diff --git a/Makefile b/Makefile
index 981f93c..0fee178 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
VERSION = 3
PATCHLEVEL = 18
-SUBLEVEL = 107
+SUBLEVEL = 115
EXTRAVERSION =
NAME = Diseased Newt
@@ -214,7 +214,6 @@
export srctree objtree VPATH
-
# SUBARCH tells the usermode build what the underlying arch is. That is set
# first, and if a usermode build is happening, the "ARCH=um" on the command
# line overrides the setting of ARCH below. If a native build is happening,
@@ -1523,11 +1522,11 @@
# Clear a bunch of variables before executing the submake
tools/: FORCE
$(Q)mkdir -p $(objtree)/tools
- $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(filter --j% -j,$(MAKEFLAGS))" O=$(objtree) subdir=tools -C $(src)/tools/
+ $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(filter --j% -j,$(MAKEFLAGS))" O=$(O) subdir=tools -C $(src)/tools/
tools/%: FORCE
$(Q)mkdir -p $(objtree)/tools
- $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(filter --j% -j,$(MAKEFLAGS))" O=$(objtree) subdir=tools -C $(src)/tools/ $*
+ $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(filter --j% -j,$(MAKEFLAGS))" O=$(O) subdir=tools -C $(src)/tools/ $*
# Single targets
# ---------------------------------------------------------------------------
diff --git a/arch/alpha/include/asm/xchg.h b/arch/alpha/include/asm/xchg.h
index 0ca9724..7081e52 100644
--- a/arch/alpha/include/asm/xchg.h
+++ b/arch/alpha/include/asm/xchg.h
@@ -11,6 +11,10 @@
* Atomic exchange.
* Since it can be used to implement critical sections
* it must clobber "memory" (also for interrupts in UP).
+ *
+ * The leading and the trailing memory barriers guarantee that these
+ * operations are fully ordered.
+ *
*/
static inline unsigned long
@@ -18,6 +22,7 @@
{
unsigned long ret, tmp, addr64;
+ smp_mb();
__asm__ __volatile__(
" andnot %4,7,%3\n"
" insbl %1,%4,%1\n"
@@ -42,6 +47,7 @@
{
unsigned long ret, tmp, addr64;
+ smp_mb();
__asm__ __volatile__(
" andnot %4,7,%3\n"
" inswl %1,%4,%1\n"
@@ -66,6 +72,7 @@
{
unsigned long dummy;
+ smp_mb();
__asm__ __volatile__(
"1: ldl_l %0,%4\n"
" bis $31,%3,%1\n"
@@ -86,6 +93,7 @@
{
unsigned long dummy;
+ smp_mb();
__asm__ __volatile__(
"1: ldq_l %0,%4\n"
" bis $31,%3,%1\n"
@@ -127,10 +135,12 @@
* store NEW in MEM. Return the initial value in MEM. Success is
* indicated by comparing RETURN with OLD.
*
- * The memory barrier should be placed in SMP only when we actually
- * make the change. If we don't change anything (so if the returned
- * prev is equal to old) then we aren't acquiring anything new and
- * we don't need any memory barrier as far I can tell.
+ * The leading and the trailing memory barriers guarantee that these
+ * operations are fully ordered.
+ *
+ * The trailing memory barrier is placed in SMP unconditionally, in
+ * order to guarantee that dependency ordering is preserved when a
+ * dependency is headed by an unsuccessful operation.
*/
static inline unsigned long
@@ -138,6 +148,7 @@
{
unsigned long prev, tmp, cmp, addr64;
+ smp_mb();
__asm__ __volatile__(
" andnot %5,7,%4\n"
" insbl %1,%5,%1\n"
@@ -149,8 +160,8 @@
" or %1,%2,%2\n"
" stq_c %2,0(%4)\n"
" beq %2,3f\n"
- __ASM__MB
"2:\n"
+ __ASM__MB
".subsection 2\n"
"3: br 1b\n"
".previous"
@@ -165,6 +176,7 @@
{
unsigned long prev, tmp, cmp, addr64;
+ smp_mb();
__asm__ __volatile__(
" andnot %5,7,%4\n"
" inswl %1,%5,%1\n"
@@ -176,8 +188,8 @@
" or %1,%2,%2\n"
" stq_c %2,0(%4)\n"
" beq %2,3f\n"
- __ASM__MB
"2:\n"
+ __ASM__MB
".subsection 2\n"
"3: br 1b\n"
".previous"
@@ -192,6 +204,7 @@
{
unsigned long prev, cmp;
+ smp_mb();
__asm__ __volatile__(
"1: ldl_l %0,%5\n"
" cmpeq %0,%3,%1\n"
@@ -199,8 +212,8 @@
" mov %4,%1\n"
" stl_c %1,%2\n"
" beq %1,3f\n"
- __ASM__MB
"2:\n"
+ __ASM__MB
".subsection 2\n"
"3: br 1b\n"
".previous"
@@ -215,6 +228,7 @@
{
unsigned long prev, cmp;
+ smp_mb();
__asm__ __volatile__(
"1: ldq_l %0,%5\n"
" cmpeq %0,%3,%1\n"
@@ -222,8 +236,8 @@
" mov %4,%1\n"
" stq_c %1,%2\n"
" beq %1,3f\n"
- __ASM__MB
"2:\n"
+ __ASM__MB
".subsection 2\n"
"3: br 1b\n"
".previous"
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index e9e0284..93ff12f 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -24,19 +24,19 @@
#if defined(CONFIG_DEBUG_ICEDCC)
#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7)
- .macro loadsp, rb, tmp
+ .macro loadsp, rb, tmp1, tmp2
.endm
.macro writeb, ch, rb
mcr p14, 0, \ch, c0, c5, 0
.endm
#elif defined(CONFIG_CPU_XSCALE)
- .macro loadsp, rb, tmp
+ .macro loadsp, rb, tmp1, tmp2
.endm
.macro writeb, ch, rb
mcr p14, 0, \ch, c8, c0, 0
.endm
#else
- .macro loadsp, rb, tmp
+ .macro loadsp, rb, tmp1, tmp2
.endm
.macro writeb, ch, rb
mcr p14, 0, \ch, c1, c0, 0
@@ -52,7 +52,7 @@
.endm
#if defined(CONFIG_ARCH_SA1100)
- .macro loadsp, rb, tmp
+ .macro loadsp, rb, tmp1, tmp2
mov \rb, #0x80000000 @ physical base address
#ifdef CONFIG_DEBUG_LL_SER3
add \rb, \rb, #0x00050000 @ Ser3
@@ -61,8 +61,8 @@
#endif
.endm
#else
- .macro loadsp, rb, tmp
- addruart \rb, \tmp
+ .macro loadsp, rb, tmp1, tmp2
+ addruart \rb, \tmp1, \tmp2
.endm
#endif
#endif
@@ -1223,7 +1223,7 @@
b 1b
@ puts corrupts {r0, r1, r2, r3}
-puts: loadsp r3, r1
+puts: loadsp r3, r2, r1
1: ldrb r2, [r0], #1
teq r2, #0
moveq pc, lr
@@ -1240,8 +1240,8 @@
@ putc corrupts {r0, r1, r2, r3}
putc:
mov r2, r0
+ loadsp r3, r1, r0
mov r0, #0
- loadsp r3, r1
b 2b
@ memdump corrupts {r0, r1, r2, r3, r10, r11, r12, lr}
diff --git a/arch/arm/boot/dts/imx6qdl-wandboard.dtsi b/arch/arm/boot/dts/imx6qdl-wandboard.dtsi
index 6052ea7..5fb0916 100644
--- a/arch/arm/boot/dts/imx6qdl-wandboard.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-wandboard.dtsi
@@ -86,7 +86,6 @@
clocks = <&clks 201>;
VDDA-supply = <®_2p5v>;
VDDIO-supply = <®_3p3v>;
- lrclk-strength = <3>;
};
};
diff --git a/arch/arm/boot/dts/msm8909w-triton/apq8009w-triton-memory.dtsi b/arch/arm/boot/dts/msm8909w-triton/apq8009w-triton-memory.dtsi
index c279700..ccc044b 100644
--- a/arch/arm/boot/dts/msm8909w-triton/apq8009w-triton-memory.dtsi
+++ b/arch/arm/boot/dts/msm8909w-triton/apq8009w-triton-memory.dtsi
@@ -22,3 +22,14 @@
&peripheral_mem {
reg = <0x0 0x8a100000 0x0 0x0600000>;
};
+
+&reserved_mem {
+ linux,cma {
+ compatible = "shared-dma-pool";
+ alloc-ranges = <0 0x00000000 0 0xa0000000>;
+ reusable;
+ alignment = <0 0x400000>;
+ size = <0 0x1000000>;
+ linux,cma-default;
+ };
+};
diff --git a/arch/arm/boot/dts/msm8909w-triton/apq8009w-triton.dts b/arch/arm/boot/dts/msm8909w-triton/apq8009w-triton.dts
index 2fd0d92..24989c3 100644
--- a/arch/arm/boot/dts/msm8909w-triton/apq8009w-triton.dts
+++ b/arch/arm/boot/dts/msm8909w-triton/apq8009w-triton.dts
@@ -212,59 +212,6 @@
pinctrl-0 = <&uart_console_sleep>;
};
-/* Pinctrl dt nodes for interrupt and reset gpio for Synaptics controller */
-&ts_int_active {
- mux {
- pins = "gpio98";
- };
-
- config {
- pins = "gpio98";
- };
-};
-
-&ts_int_suspend {
- mux {
- pins = "gpio98";
- };
-
- config {
- pins = "gpio98";
- /delete-property/ bias-pull-down;
- bias-disable; /* No PULL */
- };
-};
-
-&ts_reset_active {
- mux {
- pins = "gpio16";
- };
-
- config {
- pins = "gpio16";
- };
-};
-
-&ts_reset_suspend {
- mux {
- pins = "gpio16";
- };
-
- config {
- pins = "gpio16";
- };
-};
-
-&ts_release {
- mux {
- pins = "gpio98", "gpio16";
- };
-
- config {
- pins = "gpio98", "gpio16";
- };
-};
-
&spi4_cs0_active {
mux {
pins = "gpio14";
diff --git a/arch/arm/boot/dts/msm8909w-triton/msm-triton-pm660.dtsi b/arch/arm/boot/dts/msm8909w-triton/msm-triton-pm660.dtsi
index 387baca..63dd0b1 100644
--- a/arch/arm/boot/dts/msm8909w-triton/msm-triton-pm660.dtsi
+++ b/arch/arm/boot/dts/msm8909w-triton/msm-triton-pm660.dtsi
@@ -469,6 +469,7 @@
qcom,fg-chg-term-current = <25>;
qcom,battery-thermal-coefficients = [d2 50 ff];
qcom,fg-rsense-sel = <1>;
+ qcom,fg-force-load-profile;
qcom,fg-auto-recharge-soc;
qcom,fg-recharge-soc-thr = <99>;
qcom,fg-cutoff-current = <40>;
diff --git a/arch/arm/boot/dts/msm8909w-triton/msm8909-triton-pinctrl.dtsi b/arch/arm/boot/dts/msm8909w-triton/msm8909-triton-pinctrl.dtsi
index 4687886..1c2b088 100644
--- a/arch/arm/boot/dts/msm8909w-triton/msm8909-triton-pinctrl.dtsi
+++ b/arch/arm/boot/dts/msm8909w-triton/msm8909-triton-pinctrl.dtsi
@@ -899,12 +899,12 @@
pmx_ts_int_active {
ts_int_active: ts_int_active {
mux {
- pins = "gpio13";
+ pins = "gpio98";
function = "gpio";
};
config {
- pins = "gpio13";
+ pins = "gpio98";
drive-strength = <8>;
bias-pull-up;
};
@@ -914,12 +914,12 @@
pmx_ts_int_suspend {
ts_int_suspend: ts_int_suspend {
mux {
- pins = "gpio13";
+ pins = "gpio98";
function = "gpio";
};
config {
- pins = "gpio13";
+ pins = "gpio98";
drive-strength = <2>;
bias-pull-down;
};
@@ -929,12 +929,12 @@
pmx_ts_reset_active {
ts_reset_active: ts_reset_active {
mux {
- pins = "gpio12";
+ pins = "gpio16";
function = "gpio";
};
config {
- pins = "gpio12";
+ pins = "gpio16";
drive-strength = <8>;
bias-pull-up;
};
@@ -944,12 +944,12 @@
pmx_ts_reset_suspend {
ts_reset_suspend: ts_reset_suspend {
mux {
- pins = "gpio12";
+ pins = "gpio16";
function = "gpio";
};
config {
- pins = "gpio12";
+ pins = "gpio16";
drive-strength = <2>;
bias-pull-down;
};
@@ -992,12 +992,12 @@
pmx_ts_release {
ts_release: ts_release {
mux {
- pins = "gpio13", "gpio12";
+ pins = "gpio98", "gpio16";
function = "gpio";
};
config {
- pins = "gpio13", "gpio12";
+ pins = "gpio98", "gpio16";
drive-strength = <2>;
bias-pull-down;
};
diff --git a/arch/arm/boot/dts/msm8909w-triton/msm8909-triton.dtsi b/arch/arm/boot/dts/msm8909w-triton/msm8909-triton.dtsi
index a603fa9e..66f5f15 100644
--- a/arch/arm/boot/dts/msm8909w-triton/msm8909-triton.dtsi
+++ b/arch/arm/boot/dts/msm8909w-triton/msm8909-triton.dtsi
@@ -120,14 +120,6 @@
fsmgr_flags = "wait,verify";
status = "ok";
};
- system {
- compatible = "android,system";
- dev = "/dev/block/platform/soc/7824900.sdhci/by-name/system";
- type = "ext4";
- mnt_flags = "ro,barrier=1,discard";
- fsmgr_flags = "wait,verify";
- status = "ok";
- };
};
};
};
@@ -138,7 +130,7 @@
ranges;
external_image_mem: external_image__region@0 {
- reg = <0x0 0x87a00000 0x0 0x0600000>;
+ reg = <0x0 0x87900000 0x0 0x0700000>;
compatible = "removed-dma-pool";
no-map;
};
@@ -1906,9 +1898,9 @@
qcom,ce-opp-freq = <100000000>;
};
- qcom_seecom: qseecom@87a00000 {
+ qcom_seecom: qseecom@87900000 {
compatible = "qcom,qseecom";
- reg = <0x87a00000 0x200000>;
+ reg = <0x87900000 0x300000>;
reg-names = "secapp-region";
qcom,disk-encrypt-pipe-pair = <2>;
qcom,hlos-ce-hw-instance = <0>;
diff --git a/arch/arm/boot/dts/msm8909w-triton/msm8909w-triton-pm660-mtp.dtsi b/arch/arm/boot/dts/msm8909w-triton/msm8909w-triton-pm660-mtp.dtsi
index c509516..c72431e 100644
--- a/arch/arm/boot/dts/msm8909w-triton/msm8909w-triton-pm660-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8909w-triton/msm8909w-triton-pm660-mtp.dtsi
@@ -365,4 +365,5 @@
qcom,fg-esr-timer-shutdown = <2048 2048>;
qcom,fg-esr-timer-asleep = <512 512>;
qcom,fg-sync-sleep-threshold-ma = <30>;
+ qcom,fg-disable-in-twm;
};
diff --git a/arch/arm/boot/dts/msm8909w-triton/msm8909w-triton.dtsi b/arch/arm/boot/dts/msm8909w-triton/msm8909w-triton.dtsi
index d44abe2..794de7f 100644
--- a/arch/arm/boot/dts/msm8909w-triton/msm8909w-triton.dtsi
+++ b/arch/arm/boot/dts/msm8909w-triton/msm8909w-triton.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -14,6 +14,31 @@
chosen {
bootargs="sched_enable_hmp=0";
};
+
+ firmware: firmware {
+ android {
+ compatible = "android,firmware";
+ fstab {
+ compatible = "android,fstab";
+ vendor_fstab: vendor {
+ compatible = "android,vendor";
+ dev = "/dev/block/platform/soc/7824900.sdhci/by-name/vendor";
+ type = "ext4";
+ mnt_flags = "ro,barrier=1,discard";
+ fsmgr_flags = "wait,verify";
+ status = "ok";
+ };
+ system_fstab: system {
+ compatible = "android,system";
+ dev = "/dev/block/platform/soc/7824900.sdhci/by-name/system";
+ type = "ext4";
+ mnt_flags = "ro,barrier=1,discard";
+ fsmgr_flags = "wait,verify";
+ status = "ok";
+ };
+ };
+ };
+ };
};
&soc {
diff --git a/arch/arm/boot/dts/qcom/apq8009-dragon.dtsi b/arch/arm/boot/dts/qcom/apq8009-dragon.dtsi
index 3e705bd..082a99d 100644
--- a/arch/arm/boot/dts/qcom/apq8009-dragon.dtsi
+++ b/arch/arm/boot/dts/qcom/apq8009-dragon.dtsi
@@ -17,9 +17,14 @@
#include "msm8909-pm8916-mtp.dtsi"
#include "apq8009-audio-external_codec.dtsi"
+&audio_codec_mtp {
+ status = "disabled";
+};
+
&soc {
- ext-codec {
- qcom,msm-mbhc-hphl-swh = <0>;
+ sound-9335 {
+ qcom,model = "apq8009-tashalite-snd-card-tdm";
+ qcom,tdm-i2s-switch-enable = <&msm_gpio 88 0>;
qcom,audio-routing =
"AIF4 VI", "MCLK",
"RX_BIAS", "MCLK",
@@ -38,16 +43,32 @@
"SpkrRight IN", "SPK2 OUT";
};
- sound-9335 {
- status = "disabled";
- };
-
i2c@78b8000 {
wcd9xxx_codec@d {
- status = "disabled";
+ qcom,wcd9xxx-mic-tristate;
+ qcom,cdc-reset-gpio = <&msm_gpio 23 0>;
+
+ cdc-vdd-buck-supply = <&wcd_vdd_buck_1p8>;
+ qcom,cdc-vdd-buck-voltage = <0 0>;
+ qcom,cdc-vdd-buck-current = <250000>;
+
+ cdc-buck-sido-supply = <&wcd_vdd_buck_1p8>;
+ qcom,cdc-buck-sido-voltage = <0 0>;
+ qcom,cdc-buck-sido-current = <250000>;
};
};
+ wcd_vdd_buck_1p8: wcd_vdd_buck_1p8 {
+ compatible = "regulator-fixed";
+ regulator-name = "wcd_vdd_buck_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ status = "ok";
+ enable-active-high;
+ gpio = <&pm8916_gpios 4 0>;
+ vin-supply = <&pm8916_s4>;
+ };
+
vph_pwr_vreg: vph_pwr_vreg {
compatible = "regulator-fixed";
status = "ok";
@@ -87,6 +108,31 @@
};
};
+&firmware {
+ android {
+ compatible = "android,firmware";
+ fstab {
+ compatible = "android,fstab";
+ vendor_fstab: vendor {
+ compatible = "android,vendor";
+ dev = "/dev/block/platform/soc/7824900.sdhci/by-name/vendor";
+ type = "ext4";
+ mnt_flags = "ro,barrier=1,discard";
+ fsmgr_flags = "wait,verify";
+ status = "ok";
+ };
+ system_fstab: system {
+ compatible = "android,system";
+ dev = "/dev/block/platform/soc/7824900.sdhci/by-name/system";
+ type = "ext4";
+ mnt_flags = "ro,barrier=1,discard";
+ fsmgr_flags = "wait,verify";
+ status = "ok";
+ };
+ };
+ };
+};
+
&msm_gpio {
sdc2_wlan_gpio_on: sdc2_wlan_gpio_on {
mux {
@@ -185,6 +231,17 @@
};
};
+&pm8916_gpios {
+ gpio@c300 {
+ qcom,mode = <1>; /* DIGITAL OUT */
+ qcom,pull = <1>; /* No Pull */
+ qcom,vin-sel = <2>; /* 1.8 */
+ qcom,src-sel = <0>; /* CONSTANT */
+ qcom,master-en = <1>; /* ENABLE GPIO */
+ status = "okay";
+ };
+};
+
&pm8916_bms {
status = "ok";
qcom,disable-bms;
diff --git a/arch/arm/boot/dts/qcom/apq8009-memory.dtsi b/arch/arm/boot/dts/qcom/apq8009-memory.dtsi
index 4b489bd..d9fe3ae 100644
--- a/arch/arm/boot/dts/qcom/apq8009-memory.dtsi
+++ b/arch/arm/boot/dts/qcom/apq8009-memory.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016, 2018 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -22,3 +22,18 @@
&peripheral_mem {
reg = <0x0 0x89e00000 0x0 0x0700000>;
};
+
+&qcom_seecom {
+ reg = <0x87a00000 0x200000>;
+};
+
+&reserved_mem {
+ linux,cma {
+ compatible = "shared-dma-pool";
+ alloc-ranges = <0 0x00000000 0 0xa0000000>;
+ reusable;
+ alignment = <0 0x400000>;
+ size = <0 0x1000000>;
+ linux,cma-default;
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/apq8009-mtp-wcd9326-excelpoint-refboard.dts b/arch/arm/boot/dts/qcom/apq8009-mtp-wcd9326-excelpoint-refboard.dts
index 63dca6e8..1982107f 100644
--- a/arch/arm/boot/dts/qcom/apq8009-mtp-wcd9326-excelpoint-refboard.dts
+++ b/arch/arm/boot/dts/qcom/apq8009-mtp-wcd9326-excelpoint-refboard.dts
@@ -178,7 +178,7 @@
label = "action";
gpios = <&msm_gpio 87 0x1>;
linux,input-type = <1>;
- linux,code = <315>;
+ linux,code = <148>;
debounce-interval = <15>;
};
@@ -398,7 +398,7 @@
interrupt-map-mask = <0xffffffff>;
interrupt-map = <0 &intc 0 125 0
1 &intc 0 221 0
- 2 &msm_gpio 38 0>;
+ 2 &msm_gpio 40 1>;
interrupt-names = "hc_irq", "pwr_irq", "sdiowakeup_irq";
qcom,vdd-voltage-level = <1800000 2950000>;
diff --git a/arch/arm/boot/dts/qcom/apq8009-mtp-wcd9326-refboard.dts b/arch/arm/boot/dts/qcom/apq8009-mtp-wcd9326-refboard.dts
index b1f6907..a1e31d3 100644
--- a/arch/arm/boot/dts/qcom/apq8009-mtp-wcd9326-refboard.dts
+++ b/arch/arm/boot/dts/qcom/apq8009-mtp-wcd9326-refboard.dts
@@ -251,7 +251,7 @@
interrupt-map-mask = <0xffffffff>;
interrupt-map = <0 &intc 0 125 0
1 &intc 0 221 0
- 2 &msm_gpio 38 0>;
+ 2 &msm_gpio 40 1>;
interrupt-names = "hc_irq", "pwr_irq", "sdiowakeup_irq";
qcom,vdd-voltage-level = <1800000 2950000>;
diff --git a/arch/arm/boot/dts/qcom/apq8009w-memory.dtsi b/arch/arm/boot/dts/qcom/apq8009w-memory.dtsi
index c279700..ccc044b 100644
--- a/arch/arm/boot/dts/qcom/apq8009w-memory.dtsi
+++ b/arch/arm/boot/dts/qcom/apq8009w-memory.dtsi
@@ -22,3 +22,14 @@
&peripheral_mem {
reg = <0x0 0x8a100000 0x0 0x0600000>;
};
+
+&reserved_mem {
+ linux,cma {
+ compatible = "shared-dma-pool";
+ alloc-ranges = <0 0x00000000 0 0xa0000000>;
+ reusable;
+ alignment = <0 0x400000>;
+ size = <0 0x1000000>;
+ linux,cma-default;
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/apq8053-lite-dragon.dtsi b/arch/arm/boot/dts/qcom/apq8053-lite-dragon.dtsi
index d3fb884..7e06fea7 100644
--- a/arch/arm/boot/dts/qcom/apq8053-lite-dragon.dtsi
+++ b/arch/arm/boot/dts/qcom/apq8053-lite-dragon.dtsi
@@ -391,7 +391,8 @@
2 &tlmm 114 0x1>;
interrupt-names = "hc_irq", "pwr_irq", "sdiowakeup_irq";
- qcom,clk-rates = <400000 20000000 25000000 50000000>;
+ qcom,clk-rates = <400000 20000000 25000000 50000000 100000000
+ 177770000>;
qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104";
status = "ok";
@@ -547,3 +548,28 @@
status = "disabled";
};
};
+
+&firmware {
+ android {
+ compatible = "android,firmware";
+ fstab {
+ compatible = "android,fstab";
+ vendor {
+ compatible = "android,vendor";
+ dev = "/dev/block/platform/soc/7824900.sdhci/by-name/vendor";
+ type = "ext4";
+ mnt_flags = "ro,barrier=1,discard";
+ fsmgr_flags = "wait";
+ status = "ok";
+ };
+ system {
+ compatible = "android,system";
+ dev = "/dev/block/platform/soc/7824900.sdhci/by-name/system";
+ type = "ext4";
+ mnt_flags = "ro,barrier=1,discard";
+ fsmgr_flags = "wait";
+ status = "ok";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/apq8053-lite.dtsi b/arch/arm/boot/dts/qcom/apq8053-lite.dtsi
index d9685d0..2adfc40 100644
--- a/arch/arm/boot/dts/qcom/apq8053-lite.dtsi
+++ b/arch/arm/boot/dts/qcom/apq8053-lite.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -118,3 +118,28 @@
};
};
};
+
+&firmware {
+ android {
+ compatible = "android,firmware";
+ fstab {
+ compatible = "android,fstab";
+ vendor {
+ compatible = "android,vendor";
+ dev = "/dev/block/platform/soc/7824900.sdhci/by-name/vendor";
+ type = "ext4";
+ mnt_flags = "ro,barrier=1,discard";
+ fsmgr_flags = "wait";
+ status = "ok";
+ };
+ system {
+ compatible = "android,system";
+ dev = "/dev/block/platform/soc/7824900.sdhci/by-name/system";
+ type = "ext4";
+ mnt_flags = "ro,barrier=1,discard";
+ fsmgr_flags = "wait";
+ status = "ok";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/apq8096-v2-auto-dragonboard.dts b/arch/arm/boot/dts/qcom/apq8096-v2-auto-dragonboard.dts
index c21b6d6..a30813f 100644
--- a/arch/arm/boot/dts/qcom/apq8096-v2-auto-dragonboard.dts
+++ b/arch/arm/boot/dts/qcom/apq8096-v2-auto-dragonboard.dts
@@ -30,7 +30,7 @@
compatible = "qcom,renesas,rh850";
reg = <0>;
interrupt-parent = <&tlmm>;
- interrupts = <127 0>;
+ interrupts = <127 2>;
spi-max-frequency = <5000000>;
qcom,clk-freq-mhz = <16000000>;
qcom,max-can-channels = <4>;
diff --git a/arch/arm/boot/dts/qcom/apq8096-v3-auto-adp.dts b/arch/arm/boot/dts/qcom/apq8096-v3-auto-adp.dts
index 74bb21e..0f021e0 100644
--- a/arch/arm/boot/dts/qcom/apq8096-v3-auto-adp.dts
+++ b/arch/arm/boot/dts/qcom/apq8096-v3-auto-adp.dts
@@ -30,7 +30,7 @@
compatible = "qcom,renesas,rh850";
reg = <0>;
interrupt-parent = <&tlmm>;
- interrupts = <122 0>;
+ interrupts = <122 2>;
spi-max-frequency = <5000000>;
qcom,clk-freq-mhz = <16000000>;
qcom,max-can-channels = <4>;
diff --git a/arch/arm/boot/dts/qcom/apq8096-v3-auto-cdp.dts b/arch/arm/boot/dts/qcom/apq8096-v3-auto-cdp.dts
index 82030c4..4e683f6 100644
--- a/arch/arm/boot/dts/qcom/apq8096-v3-auto-cdp.dts
+++ b/arch/arm/boot/dts/qcom/apq8096-v3-auto-cdp.dts
@@ -38,7 +38,7 @@
compatible = "qcom,renesas,rh850";
reg = <0>;
interrupt-parent = <&tlmm>;
- interrupts = <127 0>;
+ interrupts = <127 2>;
spi-max-frequency = <5000000>;
qcom,clk-freq-mhz = <16000000>;
qcom,max-can-channels = <4>;
diff --git a/arch/arm/boot/dts/qcom/apq8096-v3-auto-dragonboard.dts b/arch/arm/boot/dts/qcom/apq8096-v3-auto-dragonboard.dts
index cd02dac..2be4f89 100644
--- a/arch/arm/boot/dts/qcom/apq8096-v3-auto-dragonboard.dts
+++ b/arch/arm/boot/dts/qcom/apq8096-v3-auto-dragonboard.dts
@@ -30,7 +30,7 @@
compatible = "qcom,renesas,rh850";
reg = <0>;
interrupt-parent = <&tlmm>;
- interrupts = <127 0>;
+ interrupts = <127 2>;
spi-max-frequency = <5000000>;
qcom,clk-freq-mhz = <16000000>;
qcom,max-can-channels = <4>;
diff --git a/arch/arm/boot/dts/qcom/apq8096pro-auto-cdp.dts b/arch/arm/boot/dts/qcom/apq8096pro-auto-cdp.dts
index e2d4f2b..fa0da0c 100644
--- a/arch/arm/boot/dts/qcom/apq8096pro-auto-cdp.dts
+++ b/arch/arm/boot/dts/qcom/apq8096pro-auto-cdp.dts
@@ -30,7 +30,7 @@
compatible = "qcom,renesas,rh850";
reg = <0>;
interrupt-parent = <&tlmm>;
- interrupts = <127 0>;
+ interrupts = <127 2>;
spi-max-frequency = <5000000>;
qcom,clk-freq-mhz = <16000000>;
qcom,max-can-channels = <4>;
diff --git a/arch/arm/boot/dts/qcom/apq8096pro-v1.1-auto-adp.dts b/arch/arm/boot/dts/qcom/apq8096pro-v1.1-auto-adp.dts
index fdea81e..3ee3238 100644
--- a/arch/arm/boot/dts/qcom/apq8096pro-v1.1-auto-adp.dts
+++ b/arch/arm/boot/dts/qcom/apq8096pro-v1.1-auto-adp.dts
@@ -31,7 +31,7 @@
compatible = "qcom,renesas,rh850";
reg = <0>;
interrupt-parent = <&tlmm>;
- interrupts = <122 0>;
+ interrupts = <122 2>;
spi-max-frequency = <5000000>;
qcom,clk-freq-mhz = <16000000>;
qcom,max-can-channels = <4>;
diff --git a/arch/arm/boot/dts/qcom/apq8096pro-v1.1-auto-cdp.dts b/arch/arm/boot/dts/qcom/apq8096pro-v1.1-auto-cdp.dts
index d5eb603..15bd288 100644
--- a/arch/arm/boot/dts/qcom/apq8096pro-v1.1-auto-cdp.dts
+++ b/arch/arm/boot/dts/qcom/apq8096pro-v1.1-auto-cdp.dts
@@ -30,7 +30,7 @@
compatible = "qcom,renesas,rh850";
reg = <0>;
interrupt-parent = <&tlmm>;
- interrupts = <127 0>;
+ interrupts = <127 2>;
spi-max-frequency = <5000000>;
qcom,clk-freq-mhz = <16000000>;
qcom,max-can-channels = <4>;
diff --git a/arch/arm/boot/dts/qcom/dsi-panel-390p-auo-cmd.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-390p-auo-cmd.dtsi
index ea1f3e8..ab1440f 100644
--- a/arch/arm/boot/dts/qcom/dsi-panel-390p-auo-cmd.dtsi
+++ b/arch/arm/boot/dts/qcom/dsi-panel-390p-auo-cmd.dtsi
@@ -37,6 +37,7 @@
qcom,mdss-dsi-underflow-color = <0xff>;
qcom,mdss-dsi-border-color = <0>;
qcom,mdss-tear-check-frame-rate = <4500>;
+ qcom,mdss-dsi-idle-fps = <10>;
qcom,mdss-dsi-on-command = [
15 01 00 00 00 00 02 fe 01
15 01 00 00 00 00 02 0a f0
diff --git a/arch/arm/boot/dts/qcom/dsi-panel-auo-cx-qvga-cmd.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-auo-cx-qvga-cmd.dtsi
index 948033a..fd58159 100644
--- a/arch/arm/boot/dts/qcom/dsi-panel-auo-cx-qvga-cmd.dtsi
+++ b/arch/arm/boot/dts/qcom/dsi-panel-auo-cx-qvga-cmd.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -39,6 +39,8 @@
qcom,mdss-dsi-color-order = "rgb_swap_rgb";
qcom,mdss-dsi-underflow-color = <0xff>;
qcom,mdss-dsi-border-color = <0>;
+ qcom,mdss-dsi-panel-status-check-mode = "te_signal_check";
+ qcom,esd-check-enabled;
qcom,mdss-dsi-on-command = [
39 01 00 00 00 00 06 F0 55 AA 52 08 00
39 01 00 00 00 00 06 BD 03 20 14 4B 00
@@ -89,6 +91,15 @@
];
qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
+ qcom,mdss-dsi-idle-on-command = [
+ 05 01 00 00 00 00 01 39 /* Idle-Mode On */
+ ];
+ qcom,mdss-dsi-idle-on-command-state = "dsi_hs_mode";
+ qcom,mdss-dsi-idle-off-command = [
+ 05 01 00 00 00 00 01 38 /* Idle-Mode Off */
+ ];
+ qcom,mdss-dsi-idle-off-command-state = "dsi_hs_mode";
+ qcom,mdss-dsi-idle-fps = <30>;
qcom,mdss-dsi-traffic-mode = "burst_mode";
qcom,mdss-dsi-lane-map = "lane_map_0123";
qcom,mdss-dsi-bllp-eof-power-mode;
@@ -97,6 +108,7 @@
qcom,mdss-dsi-te-pin-select = <1>;
qcom,mdss-dsi-te-dcs-command = <1>;
qcom,mdss-dsi-te-using-te-pin;
+ /* qcom,mdss-dsi-te-check-enable; */
qcom,mdss-dsi-panel-timings = [5F 12 0A 00 32 34 10 16 0F 03 04 00];
qcom,mdss-dsi-t-clk-post = <0x05>;
qcom,mdss-dsi-t-clk-pre = <0x11>;
@@ -106,7 +118,7 @@
qcom,mdss-dsi-mdp-trigger = "none";
qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs";
qcom,mdss-dsi-reset-sequence = <1 20>, <0 20>, <1 20>;
- /* clk = totlaH * totalV * bpp* 66fps */
- qcom,mdss-dsi-panel-clockrate = <180905472>;
+ /* clk = totlaH * totalV * bpp* 84fps */
+ qcom,mdss-dsi-panel-clockrate = <230243328>;
};
};
diff --git a/arch/arm/boot/dts/qcom/dsi-panel-hx83100a-800p-video.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-hx83100a-800p-video.dtsi
index 9ad11c4..c5b7575 100644
--- a/arch/arm/boot/dts/qcom/dsi-panel-hx83100a-800p-video.dtsi
+++ b/arch/arm/boot/dts/qcom/dsi-panel-hx83100a-800p-video.dtsi
@@ -39,11 +39,6 @@
qcom,mdss-dsi-on-command = [
39 01 00 00 78 00 02 11 00
39 01 00 00 14 00 02 29 00
- 39 01 00 00 00 00 04 B9 83 10 0A
- 39 01 00 00 00 00 08 C9 1F 00 08 1E 81 1E 00
- 39 01 00 00 00 00 02 53 24
- 39 01 00 00 05 00 02 55 02
- 39 01 00 00 00 00 0A CA 40 3C 38 34 33 32 30 2C 28
];
qcom,mdss-dsi-off-command = [05 01 00 00 96 00 02 28 00
05 01 00 00 00 00 02 10 00];
diff --git a/arch/arm/boot/dts/qcom/mdm9607-mtp.dtsi b/arch/arm/boot/dts/qcom/mdm9607-mtp.dtsi
index 9fd54f7..e03677f 100644
--- a/arch/arm/boot/dts/qcom/mdm9607-mtp.dtsi
+++ b/arch/arm/boot/dts/qcom/mdm9607-mtp.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -60,7 +60,7 @@
spi-max-frequency = <4800000>;
reg = <0>;
interrupt-parent = <&tlmm_pinmux>;
- interrupts = <25 0>;
+ interrupts = <25 1>;
reset-gpio = <&tlmm_pinmux 11 0x1>;
pinctrl-names = "active", "sleep";
pinctrl-0 = <&can_rst_on>;
diff --git a/arch/arm/boot/dts/qcom/mdm9607-pinctrl.dtsi b/arch/arm/boot/dts/qcom/mdm9607-pinctrl.dtsi
index ea331a2..4acd040 100644
--- a/arch/arm/boot/dts/qcom/mdm9607-pinctrl.dtsi
+++ b/arch/arm/boot/dts/qcom/mdm9607-pinctrl.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -261,7 +261,7 @@
};
};
- bmi160_int1_default: bmi160_int1_default {
+ sensor_int1_default: sensor_int1_default {
mux {
pins = "gpio78";
function = "gpio";
@@ -273,7 +273,7 @@
};
};
- bmi160_int2_default: bmi160_int2_default {
+ sensor_int2_default: sensor_int2_default {
mux {
pins = "gpio79";
function = "gpio";
diff --git a/arch/arm/boot/dts/qcom/mdm9607-ttp.dts b/arch/arm/boot/dts/qcom/mdm9607-ttp.dts
index 88db317..097a21e 100644
--- a/arch/arm/boot/dts/qcom/mdm9607-ttp.dts
+++ b/arch/arm/boot/dts/qcom/mdm9607-ttp.dts
@@ -15,7 +15,7 @@
#include "mdm9607-mtp.dtsi"
/ {
- model = "Qualcomm Technologies, Inc. MDM 9206 TTP";
+ model = "Qualcomm Technologies, Inc. MDM 9607 TTP";
compatible = "qcom,mdm9607-ttp", "qcom,mdm9607", "qcom,ttp";
qcom,board-id = <0x1E 0>;
};
diff --git a/arch/arm/boot/dts/qcom/mdm9607.dtsi b/arch/arm/boot/dts/qcom/mdm9607.dtsi
index 071b8f6..48d0cb8 100644
--- a/arch/arm/boot/dts/qcom/mdm9607.dtsi
+++ b/arch/arm/boot/dts/qcom/mdm9607.dtsi
@@ -539,7 +539,7 @@
compatible = "bosch-sensortec,bmi160";
reg = <0x68>;
pinctrl-names = "default";
- pinctrl-0 = <&bmi160_int1_default &bmi160_int2_default>;
+ pinctrl-0 = <&sensor_int1_default &sensor_int2_default>;
interrupt-parent = <&tlmm_pinmux>;
interrupts = <78 0x2002>;
bmi,init-interval = <200>;
@@ -551,7 +551,7 @@
compatible = "inven,iam20680";
reg = <0x69>;
pinctrl-names = "default";
- pinctrl-0 = <&bmi160_int1_default &bmi160_int2_default>;
+ pinctrl-0 = <&sensor_int1_default &sensor_int2_default>;
interrupt-parent = <&tlmm_pinmux>;
interrupts = <78 IRQ_TYPE_EDGE_RISING>;
axis_map_x = <1>;
@@ -565,6 +565,15 @@
inven,read_only_slave_type = "none";
};
+ asm330@6b{
+ compatible = "st,asm330lhh";
+ reg = <0x6b>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sensor_int1_default &sensor_int2_default>;
+ interrupt-parent = <&tlmm_pinmux>;
+ interrupts = <78 IRQ_TYPE_EDGE_RISING>;
+ };
+
};
blsp1_uart3: uart@78b1000 {
@@ -1290,16 +1299,16 @@
qcom,mx-retention-min =
<RPM_SMD_REGULATOR_LEVEL_NOM_PLUS>;
vdd-mx-supply = <&mdm9607_l12_floor_level>;
- qcom,vdd-restriction-temp = <5>;
- qcom,vdd-restriction-temp-hysteresis = <10>;
+ qcom,vdd-restriction-temp = <10>;
+ qcom,vdd-restriction-temp-hysteresis = <15>;
vdd-dig-supply = <&mdm9607_s3_floor_level>;
qcom,therm-ddr-lm-info = <2 78 70>;
qcom,vdd-dig-rstr{
qcom,vdd-rstr-reg = "vdd-dig";
- qcom,levels = <RPM_SMD_REGULATOR_LEVEL_NOM_PLUS
- RPM_SMD_REGULATOR_LEVEL_TURBO
- RPM_SMD_REGULATOR_LEVEL_TURBO>;
+ qcom,levels = <RPM_SMD_REGULATOR_LEVEL_TURBO_NO_CPR
+ RPM_SMD_REGULATOR_LEVEL_BINNING
+ RPM_SMD_REGULATOR_LEVEL_BINNING>;
qcom,min-level = <RPM_SMD_REGULATOR_LEVEL_RETENTION>;
};
@@ -1738,6 +1747,26 @@
status = "ok";
};
+ qcom_smcinvoke: smcinvoke@88000000 {
+ compatible = "qcom,smcinvoke";
+ reg = <0x88000000 0x500000>;
+ qcom,clock-support;
+ qcom,msm-bus,name = "smcinvoke-noc";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <47 512 0 0>,
+ <47 512 393600 3936000>;
+ clocks = <&clock_gcc clk_crypto_clk_src>,
+ <&clock_gcc clk_gcc_crypto_clk>,
+ <&clock_gcc clk_gcc_crypto_ahb_clk>,
+ <&clock_gcc clk_gcc_crypto_axi_clk>;
+ clock-names = "core_clk_src", "core_clk",
+ "iface_clk", "bus_clk";
+ qcom,ce-opp-freq = <100000000>;
+ status = "ok";
+ };
+
qcom_tzlog: tz-log@8600720 {
compatible = "qcom,tz-log";
reg = <0x08600720 0x2000>;
diff --git a/arch/arm/boot/dts/qcom/mdm9650-ccard.dtsi b/arch/arm/boot/dts/qcom/mdm9650-ccard.dtsi
index 3ab6801..c32278a 100644
--- a/arch/arm/boot/dts/qcom/mdm9650-ccard.dtsi
+++ b/arch/arm/boot/dts/qcom/mdm9650-ccard.dtsi
@@ -613,7 +613,7 @@
reg = <0>;
spi-max-frequency = <9600000>;
interrupt-parent = <&tlmm_pinmux>;
- interrupts = <87 0>;
+ interrupts = <87 2>;
qcom,reset-gpio = <&tlmm_pinmux 89 0x1>;
qcom,clk-freq-mhz = <20000000>;
qcom,max-can-channels = <1>;
diff --git a/arch/arm/boot/dts/qcom/mdm9650-cv2x.dtsi b/arch/arm/boot/dts/qcom/mdm9650-cv2x.dtsi
index 5090150..037ac98 100644
--- a/arch/arm/boot/dts/qcom/mdm9650-cv2x.dtsi
+++ b/arch/arm/boot/dts/qcom/mdm9650-cv2x.dtsi
@@ -56,6 +56,15 @@
pps {
use-system-time-ts;
};
+
+ qcom,ipc_router_external_ap_xprt {
+ compatible = "qcom,ipc-router-mhi-dev-xprt";
+ qcom,out-chan-id = <20>;
+ qcom,in-chan-id = <21>;
+ qcom,xprt-remote = "external-ap";
+ qcom,xprt-linkid = <2>;
+ qcom,xprt-version = <1>;
+ };
};
&cnss_pcie {
diff --git a/arch/arm/boot/dts/qcom/mdm9650-pcie-ep-ttp.dts b/arch/arm/boot/dts/qcom/mdm9650-pcie-ep-ttp.dts
index 2577e43..f3645dc 100644
--- a/arch/arm/boot/dts/qcom/mdm9650-pcie-ep-ttp.dts
+++ b/arch/arm/boot/dts/qcom/mdm9650-pcie-ep-ttp.dts
@@ -13,7 +13,9 @@
/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
#include "mdm9650-v1.1-mtp.dtsi"
+
/ {
model = "Qualcomm Technologies, Inc. MDM 9650 PCIE EP TTP";
compatible = "qcom,mdm9650-ttp", "qcom,mdm9650", "qcom,ttp";
@@ -165,7 +167,8 @@
&pcie_ep {
status = "ok";
- mdm2apstatus-gpio = <&tlmm_pinmux 85 0>;
+ mdm2apstatus-gpio = <&tlmm_pinmux 64 GPIO_ACTIVE_LOW>;
+ clkreq-gpio = <&tlmm_pinmux 85 0>;
};
&pcie0 {
@@ -182,13 +185,40 @@
&pcie0_mdm2apstatus_default {
mux {
- pins = "gpio85";
+ pins = "gpio64";
function = "gpio";
};
config {
+ pins = "gpio64";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+};
+
+&pcie0_clkreq_default {
+ mux {
+ pins = "gpio85";
+ function = "gpio";
+ };
+ config {
pins = "gpio85";
drive-strength = <2>;
- bias-pull-down;
+ bias-pull-up;
+ };
+};
+
+&pmd9650_pon {
+ interrupts = <0x0 0x8 0x0>, <0x0 0x8 0x1>;
+ interrupt-names = "kpdpwr", "resin";
+ qcom,s3-src = "resin";
+
+ qcom,pon_2 {
+ qcom,pon-type = <1>;
+ qcom,support-reset = <1>;
+ qcom,s1-timer = <0>;
+ qcom,s2-timer = <2000>;
+ qcom,s2-type = <7>;
+ qcom,pull-up = <1>;
};
};
diff --git a/arch/arm/boot/dts/qcom/mdm9650-ttp.dts b/arch/arm/boot/dts/qcom/mdm9650-ttp.dts
index 8a951ff..5818a71 100644
--- a/arch/arm/boot/dts/qcom/mdm9650-ttp.dts
+++ b/arch/arm/boot/dts/qcom/mdm9650-ttp.dts
@@ -66,6 +66,41 @@
};
};
+&cnss_sdio {
+ status = "ok";
+};
+
+&sdhc_1 {
+ vdd-supply = <&sdc_vreg>;
+ vdd-io-supply = <&pmd9650_l7>;
+ qcom,vdd-io-voltage-level = <1800000 1800000>;
+ qcom,vdd-io-always-on;
+ qcom,vdd-io-current-level = <200 10000>;
+
+ qcom,clk-rates = <400000 20000000 25000000 50000000 100000000
+ 200000000>;
+ qcom,bus-width = <4>;
+ qcom,core_3_0v_support;
+ qcom,nonremovable;
+
+ pinctrl-names = "active", "sleep";
+ pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on
+ &sdc1_wlan_gpio_active>;
+ pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off
+ &sdc1_wlan_gpio_sleep>;
+ #address-cells = <0>;
+ interrupt-parent = <&sdhc_1>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 123 0
+ 1 &intc 0 138 0
+ 2 &tlmm_pinmux 93 0x4>;
+ interrupt-names = "hc_irq", "pwr_irq", "sdiowakeup_irq";
+
+ status = "ok";
+};
+
&usb3 {
cpe-gpio = <&tlmm_pinmux 87 0>;
};
diff --git a/arch/arm/boot/dts/qcom/mdm9650.dtsi b/arch/arm/boot/dts/qcom/mdm9650.dtsi
index d8fb6b6..551b343 100644
--- a/arch/arm/boot/dts/qcom/mdm9650.dtsi
+++ b/arch/arm/boot/dts/qcom/mdm9650.dtsi
@@ -22,7 +22,7 @@
<286 0x10000>, <283 0x10000>, <359 0x10000>;
interrupt-parent = <&intc>;
- reserved-memory {
+ reserved_mem: reserved-memory {
#address-cells = <1>;
#size-cells = <1>;
ranges;
diff --git a/arch/arm/boot/dts/qcom/msm8909.dtsi b/arch/arm/boot/dts/qcom/msm8909.dtsi
index fe1072a..5798970 100644
--- a/arch/arm/boot/dts/qcom/msm8909.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8909.dtsi
@@ -120,14 +120,6 @@
fsmgr_flags = "wait,verify";
status = "ok";
};
- system_fstab: system {
- compatible = "android,system";
- dev = "/dev/block/platform/soc/7824900.sdhci/by-name/system";
- type = "ext4";
- mnt_flags = "ro,barrier=1,discard";
- fsmgr_flags = "wait,verify";
- status = "ok";
- };
};
};
};
diff --git a/arch/arm/boot/dts/qcom/msm8909w-memory.dtsi b/arch/arm/boot/dts/qcom/msm8909w-memory.dtsi
index 975fbb9..17218e07 100644
--- a/arch/arm/boot/dts/qcom/msm8909w-memory.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8909w-memory.dtsi
@@ -22,3 +22,14 @@
&peripheral_mem {
reg = <0x0 0x8d000000 0x0 0x0600000>;
};
+
+&reserved_mem {
+ linux,cma {
+ compatible = "shared-dma-pool";
+ alloc-ranges = <0 0x00000000 0 0xa0000000>;
+ reusable;
+ alignment = <0 0x400000>;
+ size = <0 0x1000000>;
+ linux,cma-default;
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/msm8909w-pm660-mtp.dtsi b/arch/arm/boot/dts/qcom/msm8909w-pm660-mtp.dtsi
index 4b07795..c548a6b 100644
--- a/arch/arm/boot/dts/qcom/msm8909w-pm660-mtp.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8909w-pm660-mtp.dtsi
@@ -319,4 +319,9 @@
qcom,fg-esr-pulse-thresh-ma = <40>;
qcom,fg-esr-meas-curr-ma = <60>;
qcom,fg-cutoff-current = <50>;
+
+ qcom,fg-esr-timer-shutdown = <2048 2048>;
+ qcom,fg-esr-timer-asleep = <512 512>;
+ qcom,fg-sync-sleep-threshold-ma = <30>;
+ qcom,fg-disable-in-twm;
};
diff --git a/arch/arm/boot/dts/qcom/msm8909w.dtsi b/arch/arm/boot/dts/qcom/msm8909w.dtsi
index 02f3252..c5daaf0 100644
--- a/arch/arm/boot/dts/qcom/msm8909w.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8909w.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -14,6 +14,31 @@
chosen {
bootargs="sched_enable_hmp=0";
};
+
+ firmware: firmware {
+ android {
+ compatible = "android,firmware";
+ fstab {
+ compatible = "android,fstab";
+ vendor_fstab: vendor {
+ compatible = "android,vendor";
+ dev = "/dev/block/platform/soc/7824900.sdhci/by-name/vendor";
+ type = "ext4";
+ mnt_flags = "ro,barrier=1,discard";
+ fsmgr_flags = "wait,verify";
+ status = "ok";
+ };
+ system_fstab: system {
+ compatible = "android,system";
+ dev = "/dev/block/platform/soc/7824900.sdhci/by-name/system";
+ type = "ext4";
+ mnt_flags = "ro,barrier=1,discard";
+ fsmgr_flags = "wait,verify";
+ status = "ok";
+ };
+ };
+ };
+ };
};
&soc {
@@ -79,6 +104,10 @@
< 1267200 2929>;
};
};
+
+ ssc_sensors: qcom,msm-ssc-sensors {
+ compatible = "qcom,msm-ssc-sensors";
+ };
};
&qcom_crypto {
diff --git a/arch/arm/boot/dts/qcom/msm8917.dtsi b/arch/arm/boot/dts/qcom/msm8917.dtsi
index aad25c3..31e2c48 100644
--- a/arch/arm/boot/dts/qcom/msm8917.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8917.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -59,18 +59,9 @@
dev = "/dev/block/platform/soc/7824900.sdhci/by-name/vendor";
type = "ext4";
mnt_flags = "ro,barrier=1,discard";
- fsmgr_flags = "wait";
+ fsmgr_flags = "wait,verify";
status = "ok";
};
- system {
- compatible = "android,system";
- dev = "/dev/block/platform/soc/7824900.sdhci/by-name/system";
- type = "ext4";
- mnt_flags = "ro,barrier=1,discard";
- fsmgr_flags = "wait";
- status = "ok";
- };
-
};
};
};
@@ -117,6 +108,7 @@
reusable;
alignment = <0 0x400000>;
size = <0 0x7000000>;
+ status = "disabled";
};
qseecom_mem: qseecom_region@0 {
diff --git a/arch/arm/boot/dts/qcom/msm8920.dtsi b/arch/arm/boot/dts/qcom/msm8920.dtsi
index dac1405..32353f1 100644
--- a/arch/arm/boot/dts/qcom/msm8920.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8920.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -23,6 +23,10 @@
soc: soc { };
};
+&secure_mem {
+ status = "ok";
+};
+
&modem_mem {
reg = <0x0 0x86800000 0x0 0x6a00000>;
};
diff --git a/arch/arm/boot/dts/qcom/msm8937.dtsi b/arch/arm/boot/dts/qcom/msm8937.dtsi
index 7865dd07..1b2e654 100644
--- a/arch/arm/boot/dts/qcom/msm8937.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8937.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -35,18 +35,9 @@
dev = "/dev/block/platform/soc/7824900.sdhci/by-name/vendor";
type = "ext4";
mnt_flags = "ro,barrier=1,discard";
- fsmgr_flags = "wait";
+ fsmgr_flags = "wait,verify";
status = "ok";
};
- system {
- compatible = "android,system";
- dev = "/dev/block/platform/soc/7824900.sdhci/by-name/system";
- type = "ext4";
- mnt_flags = "ro,barrier=1,discard";
- fsmgr_flags = "wait";
- status = "ok";
- };
-
};
};
};
diff --git a/arch/arm/boot/dts/qcom/msm8953.dtsi b/arch/arm/boot/dts/qcom/msm8953.dtsi
index 2c523da..4aec523 100644
--- a/arch/arm/boot/dts/qcom/msm8953.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8953.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -36,18 +36,9 @@
dev = "/dev/block/platform/soc/7824900.sdhci/by-name/vendor";
type = "ext4";
mnt_flags = "ro,barrier=1,discard";
- fsmgr_flags = "wait";
+ fsmgr_flags = "wait,verify";
status = "ok";
};
- system {
- compatible = "android,system";
- dev = "/dev/block/platform/soc/7824900.sdhci/by-name/system";
- type = "ext4";
- mnt_flags = "ro,barrier=1,discard";
- fsmgr_flags = "wait";
- status = "ok";
- };
-
};
};
};
@@ -93,7 +84,7 @@
compatible = "shared-dma-pool";
reusable;
alignment = <0 0x400000>;
- size = <0 0x09800000>;
+ size = <0 0x0b400000>;
};
qseecom_mem: qseecom_region@0 {
@@ -1772,8 +1763,10 @@
sdhc_1: sdhci@7824900 {
compatible = "qcom,sdhci-msm";
- reg = <0x7824900 0x500>, <0x7824000 0x800>, <0x7824e00 0x200>;
- reg-names = "hc_mem", "core_mem", "cmdq_mem";
+ reg = <0x7824900 0x500>, <0x7824000 0x800>, <0x7824e00 0x200>,
+ <0x0119d000 0x4>;
+ reg-names = "hc_mem", "core_mem", "cmdq_mem",
+ "tlmm_mem";
interrupts = <0 123 0>, <0 138 0>;
interrupt-names = "hc_irq", "pwr_irq";
diff --git a/arch/arm/boot/dts/qcom/msm8996-v3-auto-adp.dts b/arch/arm/boot/dts/qcom/msm8996-v3-auto-adp.dts
index d4cf58f..4ff449a4 100644
--- a/arch/arm/boot/dts/qcom/msm8996-v3-auto-adp.dts
+++ b/arch/arm/boot/dts/qcom/msm8996-v3-auto-adp.dts
@@ -31,7 +31,7 @@
compatible = "qcom,renesas,rh850";
reg = <0>;
interrupt-parent = <&tlmm>;
- interrupts = <122 0>;
+ interrupts = <122 2>;
spi-max-frequency = <5000000>;
qcom,clk-freq-mhz = <16000000>;
qcom,max-can-channels = <4>;
diff --git a/arch/arm/boot/dts/qcom/msm8996-v3-auto-cdp.dts b/arch/arm/boot/dts/qcom/msm8996-v3-auto-cdp.dts
index 33daf9d..250ce92 100644
--- a/arch/arm/boot/dts/qcom/msm8996-v3-auto-cdp.dts
+++ b/arch/arm/boot/dts/qcom/msm8996-v3-auto-cdp.dts
@@ -43,7 +43,7 @@
compatible = "qcom,renesas,rh850";
reg = <0>;
interrupt-parent = <&tlmm>;
- interrupts = <127 0>;
+ interrupts = <127 2>;
spi-max-frequency = <5000000>;
qcom,clk-freq-mhz = <16000000>;
qcom,max-can-channels = <4>;
diff --git a/arch/arm/boot/dts/qcom/msm8996-v3-pm8004-agave-adp.dts b/arch/arm/boot/dts/qcom/msm8996-v3-pm8004-agave-adp.dts
index d84b0d7..cf1128b 100644
--- a/arch/arm/boot/dts/qcom/msm8996-v3-pm8004-agave-adp.dts
+++ b/arch/arm/boot/dts/qcom/msm8996-v3-pm8004-agave-adp.dts
@@ -28,7 +28,7 @@
compatible = "qcom,renesas,rh850";
reg = <0>;
interrupt-parent = <&tlmm>;
- interrupts = <122 0>;
+ interrupts = <122 2>;
spi-max-frequency = <5000000>;
qcom,clk-freq-mhz = <16000000>;
qcom,max-can-channels = <4>;
diff --git a/arch/arm/boot/dts/qcom/msm8996.dtsi b/arch/arm/boot/dts/qcom/msm8996.dtsi
index 7eaf564..4b5f522 100644
--- a/arch/arm/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996.dtsi
@@ -168,18 +168,9 @@
dev = "/dev/block/platform/soc/7464900.sdhci/by-name/vendor";
type = "ext4";
mnt_flags = "ro,barrier=1,discard";
- fsmgr_flags = "wait";
+ fsmgr_flags = "wait,verify";
status = "ok";
};
- system {
- compatible = "android,system";
- dev = "/dev/block/platform/soc/7464900.sdhci/by-name/system";
- type = "ext4";
- mnt_flags = "ro,barrier=1,discard";
- fsmgr_flags = "wait";
- status = "ok";
- };
-
};
};
};
diff --git a/arch/arm/boot/dts/qcom/msm8996pro-auto-adp.dts b/arch/arm/boot/dts/qcom/msm8996pro-auto-adp.dts
index 15b00af..91f9ab6 100644
--- a/arch/arm/boot/dts/qcom/msm8996pro-auto-adp.dts
+++ b/arch/arm/boot/dts/qcom/msm8996pro-auto-adp.dts
@@ -31,7 +31,7 @@
compatible = "qcom,renesas,rh850";
reg = <0>;
interrupt-parent = <&tlmm>;
- interrupts = <122 0>;
+ interrupts = <122 2>;
spi-max-frequency = <5000000>;
qcom,clk-freq-mhz = <16000000>;
qcom,max-can-channels = <4>;
diff --git a/arch/arm/boot/dts/qcom/msm8996pro-auto-cdp.dts b/arch/arm/boot/dts/qcom/msm8996pro-auto-cdp.dts
index 4a78a2f..a4c0a05 100644
--- a/arch/arm/boot/dts/qcom/msm8996pro-auto-cdp.dts
+++ b/arch/arm/boot/dts/qcom/msm8996pro-auto-cdp.dts
@@ -30,7 +30,7 @@
compatible = "qcom,renesas,rh850";
reg = <0>;
interrupt-parent = <&tlmm>;
- interrupts = <127 0>;
+ interrupts = <127 2>;
spi-max-frequency = <5000000>;
qcom,clk-freq-mhz = <16000000>;
qcom,max-can-channels = <4>;
diff --git a/arch/arm/boot/dts/qcom/msm8996pro-v1.1-auto-cdp.dts b/arch/arm/boot/dts/qcom/msm8996pro-v1.1-auto-cdp.dts
index d75f56d..13a0e91 100644
--- a/arch/arm/boot/dts/qcom/msm8996pro-v1.1-auto-cdp.dts
+++ b/arch/arm/boot/dts/qcom/msm8996pro-v1.1-auto-cdp.dts
@@ -30,7 +30,7 @@
compatible = "qcom,renesas,rh850";
reg = <0>;
interrupt-parent = <&tlmm>;
- interrupts = <127 0>;
+ interrupts = <127 2>;
spi-max-frequency = <5000000>;
qcom,clk-freq-mhz = <16000000>;
qcom,max-can-channels = <4>;
diff --git a/arch/arm/boot/dts/qcom/sdw2500-apq8009w-wtp.dts b/arch/arm/boot/dts/qcom/sdw2500-apq8009w-wtp.dts
index 4d64d6d..806f204 100644
--- a/arch/arm/boot/dts/qcom/sdw2500-apq8009w-wtp.dts
+++ b/arch/arm/boot/dts/qcom/sdw2500-apq8009w-wtp.dts
@@ -72,9 +72,7 @@
synaptics,max-y-for-2d = <389>;
synaptics,wakeup-gestures-en = <1>;
synaptics,resume-in-workqueue;
- synaptics,x-flip;
- synaptics,y-flip;
-
+ synaptics,fw-name = "PR1814809-s1222_30303032.img";
synaptics,reset-gpio = <&msm_gpio 31 0x0>;
synaptics,reset-delay-ms = <200>;
synaptics,reset-on-state = <0>;
@@ -297,12 +295,31 @@
};
};
-&system_fstab {
- fsmgr_flags = "wait";
-};
-
-&vendor_fstab {
- fsmgr_flags = "wait";
+&firmware {
+ android {
+ compatible = "android,firmware";
+ fstab {
+ compatible = "android,fstab";
+ vendor {
+ compatible = "android,vendor";
+ dev = "/dev/block/platform/soc/7824900.sdhci/
+ by-name/vendor";
+ type = "ext4";
+ mnt_flags = "ro,barrier=1,discard";
+ fsmgr_flags = "wait";
+ status = "ok";
+ };
+ system {
+ compatible = "android,system";
+ dev = "/dev/block/platform/soc/7824900.sdhci/
+ by-name/system";
+ type = "ext4";
+ mnt_flags = "ro,barrier=1,discard";
+ fsmgr_flags = "wait";
+ status = "ok";
+ };
+ };
+ };
};
&mdss_dsi0{
diff --git a/arch/arm/boot/dts/qcom/sdw2500-msm8909w-wtp.dts b/arch/arm/boot/dts/qcom/sdw2500-msm8909w-wtp.dts
index 0a84ea4..9b5d52a 100644
--- a/arch/arm/boot/dts/qcom/sdw2500-msm8909w-wtp.dts
+++ b/arch/arm/boot/dts/qcom/sdw2500-msm8909w-wtp.dts
@@ -74,9 +74,7 @@
synaptics,max-y-for-2d = <389>;
synaptics,wakeup-gestures-en = <1>;
synaptics,resume-in-workqueue;
- synaptics,x-flip;
- synaptics,y-flip;
-
+ synaptics,fw-name = "PR1814809-s1222_30303032.img";
synaptics,reset-gpio = <&msm_gpio 31 0x0>;
synaptics,reset-delay-ms = <200>;
synaptics,reset-on-state = <0>;
@@ -299,12 +297,31 @@
};
};
-&system_fstab {
- fsmgr_flags = "wait";
-};
-
-&vendor_fstab {
- fsmgr_flags = "wait";
+&firmware {
+ android {
+ compatible = "android,firmware";
+ fstab {
+ compatible = "android,fstab";
+ vendor {
+ compatible = "android,vendor";
+ dev = "/dev/block/platform/soc/7824900.sdhci/
+ by-name/vendor";
+ type = "ext4";
+ mnt_flags = "ro,barrier=1,discard";
+ fsmgr_flags = "wait";
+ status = "ok";
+ };
+ system {
+ compatible = "android,system";
+ dev = "/dev/block/platform/soc/7824900.sdhci/
+ by-name/system";
+ type = "ext4";
+ mnt_flags = "ro,barrier=1,discard";
+ fsmgr_flags = "wait";
+ status = "ok";
+ };
+ };
+ };
};
&mdss_dsi0{
diff --git a/arch/arm/boot/dts/qcom/sdw3100-apq8009w-wtp.dts b/arch/arm/boot/dts/qcom/sdw3100-apq8009w-wtp.dts
index 0ee4761..c5c7e59 100644
--- a/arch/arm/boot/dts/qcom/sdw3100-apq8009w-wtp.dts
+++ b/arch/arm/boot/dts/qcom/sdw3100-apq8009w-wtp.dts
@@ -56,8 +56,7 @@
synaptics,do-not-disable-regulators;
synaptics,wakeup-gestures-en;
synaptics,resume-in-workqueue;
- synaptics,x-flip;
- synaptics,y-flip;
+ synaptics,fw-name = "PR1814809-s1222_30303032.img";
/delete-property/ synaptics,reset-gpio;
/delete-property/ synaptics,display-coords;
/delete-property/ synaptics,panel-coords;
diff --git a/arch/arm/boot/dts/qcom/sdw3100-msm8909w-wtp.dts b/arch/arm/boot/dts/qcom/sdw3100-msm8909w-wtp.dts
index 47e855a..6af3bcd 100644
--- a/arch/arm/boot/dts/qcom/sdw3100-msm8909w-wtp.dts
+++ b/arch/arm/boot/dts/qcom/sdw3100-msm8909w-wtp.dts
@@ -58,8 +58,7 @@
synaptics,do-not-disable-regulators;
synaptics,wakeup-gestures-en;
synaptics,resume-in-workqueue;
- synaptics,x-flip;
- synaptics,y-flip;
+ synaptics,fw-name = "PR1814809-s1222_30303032.img";
/delete-property/ synaptics,reset-gpio;
/delete-property/ synaptics,display-coords;
/delete-property/ synaptics,panel-coords;
diff --git a/arch/arm/boot/dts/qcom/sdx20.dtsi b/arch/arm/boot/dts/qcom/sdx20.dtsi
index 3a9288e..f17bc90 100644
--- a/arch/arm/boot/dts/qcom/sdx20.dtsi
+++ b/arch/arm/boot/dts/qcom/sdx20.dtsi
@@ -39,6 +39,17 @@
reg = <0x88000000 0x7300000>;
};
+&reserved_mem {
+ linux,cma {
+ compatible = "shared-dma-pool";
+ alloc-ranges = <0 0x90000000>;
+ reusable;
+ alignment = <0x400000>;
+ size = <0xc00000>;
+ linux,cma-default;
+ };
+};
+
&soc {
/* SD card 2.95 V supply */
sdc_vreg: sdc_vreg {
diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi
index 4472fd9..34ad313 100644
--- a/arch/arm/boot/dts/socfpga.dtsi
+++ b/arch/arm/boot/dts/socfpga.dtsi
@@ -643,7 +643,7 @@
timer@fffec600 {
compatible = "arm,cortex-a9-twd-timer";
reg = <0xfffec600 0x100>;
- interrupts = <1 13 0xf04>;
+ interrupts = <1 13 0xf01>;
clocks = <&mpu_periph_clk>;
};
diff --git a/arch/arm/configs/mdm9607-perf_defconfig b/arch/arm/configs/mdm9607-perf_defconfig
index 6fe6ce5..0f33fd7 100644
--- a/arch/arm/configs/mdm9607-perf_defconfig
+++ b/arch/arm/configs/mdm9607-perf_defconfig
@@ -348,6 +348,7 @@
CONFIG_MSM_PIL_MSS_QDSP6V5=y
CONFIG_TRACER_PKT=y
CONFIG_MSM_BAM_DMUX=y
+CONFIG_QCOM_SMCINVOKE=y
CONFIG_IIO=y
CONFIG_IIO_BUFFER_CB=y
CONFIG_SENSORS_BMI160_IIO=y
@@ -357,6 +358,7 @@
CONFIG_INV_MPU_IIO_I2C=y
CONFIG_INV_MPU_IIO_SPI=y
CONFIG_INV_TESTING=y
+CONFIG_IIO_ST_ASM330LHH=y
CONFIG_CORESIGHT=y
CONFIG_CORESIGHT_EVENT=y
CONFIG_CORESIGHT_FUSE=y
diff --git a/arch/arm/configs/mdm9607_defconfig b/arch/arm/configs/mdm9607_defconfig
index 8f041a6..b16eb64 100644
--- a/arch/arm/configs/mdm9607_defconfig
+++ b/arch/arm/configs/mdm9607_defconfig
@@ -348,6 +348,7 @@
CONFIG_MSM_PIL_MSS_QDSP6V5=y
CONFIG_TRACER_PKT=y
CONFIG_MSM_BAM_DMUX=y
+CONFIG_QCOM_SMCINVOKE=y
CONFIG_IIO=y
CONFIG_IIO_BUFFER_CB=y
CONFIG_SENSORS_BMI160_IIO=y
@@ -357,6 +358,7 @@
CONFIG_INV_MPU_IIO_I2C=y
CONFIG_INV_MPU_IIO_SPI=y
CONFIG_INV_TESTING=y
+CONFIG_IIO_ST_ASM330LHH=y
CONFIG_CORESIGHT=y
CONFIG_CORESIGHT_EVENT=y
CONFIG_CORESIGHT_FUSE=y
diff --git a/arch/arm/configs/msm8909-perf_defconfig b/arch/arm/configs/msm8909-perf_defconfig
index 585f350..19214af 100644
--- a/arch/arm/configs/msm8909-perf_defconfig
+++ b/arch/arm/configs/msm8909-perf_defconfig
@@ -48,6 +48,7 @@
CONFIG_CMA=y
CONFIG_ZSMALLOC=y
CONFIG_BALANCE_ANON_FILE_RECLAIM=y
+CONFIG_PROCESS_RECLAIM=y
CONFIG_SECCOMP=y
CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE=y
CONFIG_AUTO_ZRELADDR=y
@@ -240,13 +241,6 @@
CONFIG_QSEECOM=y
CONFIG_UID_SYS_STATS=y
CONFIG_MSM_MCU_TIME_SYNC=y
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_CHR_DEV_SCH=y
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
-CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_MD=y
CONFIG_BLK_DEV_DM=y
CONFIG_DM_VERITY=y
@@ -380,28 +374,11 @@
CONFIG_SND_SOC=y
CONFIG_SND_SOC_MSM8909=y
CONFIG_UHID=y
-CONFIG_HID_APPLE=y
-CONFIG_HID_ELECOM=y
-CONFIG_HID_MAGICMOUSE=y
-CONFIG_HID_MICROSOFT=y
-CONFIG_HID_MULTITOUCH=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
CONFIG_USB_MON=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_MSM=y
CONFIG_USB_ACM=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_STORAGE_DATAFAB=y
-CONFIG_USB_STORAGE_FREECOM=y
-CONFIG_USB_STORAGE_ISD200=y
-CONFIG_USB_STORAGE_USBAT=y
-CONFIG_USB_STORAGE_SDDR09=y
-CONFIG_USB_STORAGE_SDDR55=y
-CONFIG_USB_STORAGE_JUMPSHOT=y
-CONFIG_USB_STORAGE_ALAUDA=y
-CONFIG_USB_STORAGE_ONETOUCH=y
-CONFIG_USB_STORAGE_KARMA=y
-CONFIG_USB_STORAGE_CYPRESS_ATACB=y
CONFIG_USB_SERIAL=y
CONFIG_USB_EHSET_TEST_FIXTURE=y
CONFIG_USB_GADGET=y
diff --git a/arch/arm/configs/msm8909_defconfig b/arch/arm/configs/msm8909_defconfig
index 0677078..ccffa6b 100644
--- a/arch/arm/configs/msm8909_defconfig
+++ b/arch/arm/configs/msm8909_defconfig
@@ -52,6 +52,7 @@
CONFIG_CMA=y
CONFIG_ZSMALLOC=y
CONFIG_BALANCE_ANON_FILE_RECLAIM=y
+CONFIG_PROCESS_RECLAIM=y
CONFIG_SECCOMP=y
CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE=y
CONFIG_AUTO_ZRELADDR=y
@@ -244,13 +245,6 @@
CONFIG_QSEECOM=y
CONFIG_UID_SYS_STATS=y
CONFIG_MSM_MCU_TIME_SYNC=y
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_CHR_DEV_SCH=y
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
-CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_MD=y
CONFIG_BLK_DEV_DM=y
CONFIG_DM_VERITY=y
@@ -399,18 +393,6 @@
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_MSM=y
CONFIG_USB_ACM=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_STORAGE_DATAFAB=y
-CONFIG_USB_STORAGE_FREECOM=y
-CONFIG_USB_STORAGE_ISD200=y
-CONFIG_USB_STORAGE_USBAT=y
-CONFIG_USB_STORAGE_SDDR09=y
-CONFIG_USB_STORAGE_SDDR55=y
-CONFIG_USB_STORAGE_JUMPSHOT=y
-CONFIG_USB_STORAGE_ALAUDA=y
-CONFIG_USB_STORAGE_ONETOUCH=y
-CONFIG_USB_STORAGE_KARMA=y
-CONFIG_USB_STORAGE_CYPRESS_ATACB=y
CONFIG_USB_SERIAL=y
CONFIG_USB_EHSET_TEST_FIXTURE=y
CONFIG_USB_GADGET=y
diff --git a/arch/arm/configs/msm8909w-1gb-perf_defconfig b/arch/arm/configs/msm8909w-1gb-perf_defconfig
index f7d2e6a..c00396f 100644
--- a/arch/arm/configs/msm8909w-1gb-perf_defconfig
+++ b/arch/arm/configs/msm8909w-1gb-perf_defconfig
@@ -72,9 +72,10 @@
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
+CONFIG_NET_IPVTI=y
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+CONFIG_INET_IPCOMP=y
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
CONFIG_IPV6=y
@@ -85,6 +86,7 @@
CONFIG_INET6_ESP=y
CONFIG_INET6_IPCOMP=y
CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_VTI=y
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_SUBTREES=y
CONFIG_NETFILTER=y
@@ -475,7 +477,7 @@
CONFIG_SECURITY_NETWORK=y
CONFIG_LSM_MMAP_MIN_ADDR=4096
CONFIG_SECURITY_SELINUX=y
-CONFIG_CRYPTO_GF128MUL=y
+CONFIG_CRYPTO_GCM=y
CONFIG_CRYPTO_AES_ARM_BS=y
CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y
CONFIG_ARM_CRYPTO=y
diff --git a/arch/arm/configs/msm8909w-1gb_defconfig b/arch/arm/configs/msm8909w-1gb_defconfig
index 3f4a7fb..c60dedb 100644
--- a/arch/arm/configs/msm8909w-1gb_defconfig
+++ b/arch/arm/configs/msm8909w-1gb_defconfig
@@ -76,9 +76,10 @@
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
+CONFIG_NET_IPVTI=y
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+CONFIG_INET_IPCOMP=y
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
CONFIG_IPV6=y
@@ -89,6 +90,7 @@
CONFIG_INET6_ESP=y
CONFIG_INET6_IPCOMP=y
CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_VTI=y
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_SUBTREES=y
CONFIG_NETFILTER=y
@@ -504,7 +506,7 @@
CONFIG_SECURITY_NETWORK=y
CONFIG_LSM_MMAP_MIN_ADDR=4096
CONFIG_SECURITY_SELINUX=y
-CONFIG_CRYPTO_SEQIV=y
+CONFIG_CRYPTO_GCM=y
CONFIG_CRYPTO_AES_ARM_BS=y
CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y
CONFIG_ARM_CRYPTO=y
diff --git a/arch/arm/configs/msm8909w-perf_defconfig b/arch/arm/configs/msm8909w-perf_defconfig
index 238e845..981c1ad 100644
--- a/arch/arm/configs/msm8909w-perf_defconfig
+++ b/arch/arm/configs/msm8909w-perf_defconfig
@@ -31,7 +31,7 @@
# CONFIG_SLUB_DEBUG is not set
CONFIG_PROFILING=y
CONFIG_OPROFILE=m
-CONFIG_CC_STACKPROTECTOR_REGULAR=y
+CONFIG_CC_STACKPROTECTOR_STRONG=y
CONFIG_ARCH_MMAP_RND_BITS=16
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
@@ -40,6 +40,7 @@
CONFIG_PARTITION_ADVANCED=y
CONFIG_ARCH_MSM=y
CONFIG_ARCH_MSM8909=y
+CONFIG_ARM_KERNMEM_PERMS=y
CONFIG_SMP=y
CONFIG_SCHED_MC=y
CONFIG_PREEMPT=y
@@ -77,9 +78,10 @@
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
+CONFIG_NET_IPVTI=y
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+CONFIG_INET_IPCOMP=y
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
CONFIG_INET_DIAG_DESTROY=y
@@ -91,6 +93,7 @@
CONFIG_INET6_ESP=y
CONFIG_INET6_IPCOMP=y
CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_VTI=y
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_SUBTREES=y
CONFIG_NETFILTER=y
@@ -488,9 +491,7 @@
CONFIG_LSM_MMAP_MIN_ADDR=4096
CONFIG_HARDENED_USERCOPY=y
CONFIG_SECURITY_SELINUX=y
-CONFIG_CRYPTO_GF128MUL=y
-CONFIG_CRYPTO_NULL=y
-CONFIG_CRYPTO_CTR=y
+CONFIG_CRYPTO_GCM=y
CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_AES_ARM_BS=y
diff --git a/arch/arm/configs/msm8909w_defconfig b/arch/arm/configs/msm8909w_defconfig
index bfa5d112..289d023 100644
--- a/arch/arm/configs/msm8909w_defconfig
+++ b/arch/arm/configs/msm8909w_defconfig
@@ -30,7 +30,7 @@
CONFIG_PROFILING=y
CONFIG_OPROFILE=m
CONFIG_KPROBES=y
-CONFIG_CC_STACKPROTECTOR_REGULAR=y
+CONFIG_CC_STACKPROTECTOR_STRONG=y
CONFIG_ARCH_MMAP_RND_BITS=16
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
@@ -42,6 +42,7 @@
CONFIG_PARTITION_ADVANCED=y
CONFIG_ARCH_MSM=y
CONFIG_ARCH_MSM8909=y
+CONFIG_ARM_KERNMEM_PERMS=y
CONFIG_SMP=y
CONFIG_SCHED_MC=y
CONFIG_PREEMPT=y
@@ -80,9 +81,10 @@
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
+CONFIG_NET_IPVTI=y
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+CONFIG_INET_IPCOMP=y
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
CONFIG_INET_DIAG_DESTROY=y
@@ -94,6 +96,7 @@
CONFIG_INET6_ESP=y
CONFIG_INET6_IPCOMP=y
CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_VTI=y
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_SUBTREES=y
CONFIG_NETFILTER=y
@@ -519,8 +522,7 @@
CONFIG_LSM_MMAP_MIN_ADDR=4096
CONFIG_HARDENED_USERCOPY=y
CONFIG_SECURITY_SELINUX=y
-CONFIG_CRYPTO_NULL=y
-CONFIG_CRYPTO_CTR=y
+CONFIG_CRYPTO_GCM=y
CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_AES_ARM_BS=y
diff --git a/arch/arm/configs/msm8937-perf_defconfig b/arch/arm/configs/msm8937-perf_defconfig
index 5efaa7b..e3fabe8 100644
--- a/arch/arm/configs/msm8937-perf_defconfig
+++ b/arch/arm/configs/msm8937-perf_defconfig
@@ -17,6 +17,8 @@
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
+CONFIG_MEMCG=y
+CONFIG_MEMCG_SWAP=y
CONFIG_CGROUP_SCHED=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_SCHED_HMP=y
@@ -97,6 +99,7 @@
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
+CONFIG_NET_IPVTI=y
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
CONFIG_INET_IPCOMP=y
@@ -111,6 +114,7 @@
CONFIG_INET6_ESP=y
CONFIG_INET6_IPCOMP=y
CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_VTI=y
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_SUBTREES=y
CONFIG_NETFILTER=y
@@ -240,6 +244,7 @@
CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
CONFIG_DMA_CMA=y
CONFIG_ZRAM=y
+CONFIG_ZRAM_LZ4_COMPRESS=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=8192
@@ -628,8 +633,7 @@
CONFIG_LSM_MMAP_MIN_ADDR=4096
CONFIG_HARDENED_USERCOPY=y
CONFIG_SECURITY_SELINUX=y
-CONFIG_CRYPTO_NULL=y
-CONFIG_CRYPTO_CTR=y
+CONFIG_CRYPTO_GCM=y
CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_AES_ARM_BS=y
diff --git a/arch/arm/configs/msm8937_defconfig b/arch/arm/configs/msm8937_defconfig
index 8117e38..cdaa8c3 100644
--- a/arch/arm/configs/msm8937_defconfig
+++ b/arch/arm/configs/msm8937_defconfig
@@ -17,6 +17,8 @@
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
+CONFIG_MEMCG=y
+CONFIG_MEMCG_SWAP=y
CONFIG_CGROUP_SCHED=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_SCHED_HMP=y
@@ -98,6 +100,7 @@
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
+CONFIG_NET_IPVTI=y
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
CONFIG_INET_IPCOMP=y
@@ -112,6 +115,7 @@
CONFIG_INET6_ESP=y
CONFIG_INET6_IPCOMP=y
CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_VTI=y
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_SUBTREES=y
CONFIG_NETFILTER=y
@@ -241,6 +245,7 @@
CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
CONFIG_DMA_CMA=y
CONFIG_ZRAM=y
+CONFIG_ZRAM_LZ4_COMPRESS=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=8192
@@ -679,8 +684,7 @@
CONFIG_LSM_MMAP_MIN_ADDR=4096
CONFIG_HARDENED_USERCOPY=y
CONFIG_SECURITY_SELINUX=y
-CONFIG_CRYPTO_NULL=y
-CONFIG_CRYPTO_CTR=y
+CONFIG_CRYPTO_GCM=y
CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_AES_ARM_BS=y
diff --git a/arch/arm/configs/msmcortex-perf_defconfig b/arch/arm/configs/msmcortex-perf_defconfig
index 9f89df30..228bd5c 100644
--- a/arch/arm/configs/msmcortex-perf_defconfig
+++ b/arch/arm/configs/msmcortex-perf_defconfig
@@ -307,6 +307,10 @@
CONFIG_TOUCHSCREEN_GEN_VKEYS=y
CONFIG_TOUCHSCREEN_FT5X06=y
CONFIG_TOUCHSCREEN_MAXIM_STI=y
+CONFIG_TOUCHSCREEN_HIMAX_CHIPSET=y
+CONFIG_TOUCHSCREEN_HIMAX_I2C=y
+CONFIG_TOUCHSCREEN_HIMAX_DEBUG=y
+CONFIG_HMX_DB=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_HBTP_INPUT=y
CONFIG_INPUT_KEYCHORD=y
diff --git a/arch/arm/configs/msmcortex_defconfig b/arch/arm/configs/msmcortex_defconfig
index cd4377e..18b6d17 100644
--- a/arch/arm/configs/msmcortex_defconfig
+++ b/arch/arm/configs/msmcortex_defconfig
@@ -307,6 +307,10 @@
CONFIG_TOUCHSCREEN_GEN_VKEYS=y
CONFIG_TOUCHSCREEN_FT5X06=y
CONFIG_TOUCHSCREEN_MAXIM_STI=y
+CONFIG_TOUCHSCREEN_HIMAX_CHIPSET=y
+CONFIG_TOUCHSCREEN_HIMAX_I2C=y
+CONFIG_TOUCHSCREEN_HIMAX_DEBUG=y
+CONFIG_HMX_DB=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_HBTP_INPUT=y
CONFIG_INPUT_UINPUT=y
diff --git a/arch/arm/configs/triton-perf_defconfig b/arch/arm/configs/triton-perf_defconfig
index f2cbf91..4af936f 100644
--- a/arch/arm/configs/triton-perf_defconfig
+++ b/arch/arm/configs/triton-perf_defconfig
@@ -31,7 +31,7 @@
# CONFIG_SLUB_DEBUG is not set
CONFIG_PROFILING=y
CONFIG_OPROFILE=m
-CONFIG_CC_STACKPROTECTOR_REGULAR=y
+CONFIG_CC_STACKPROTECTOR_STRONG=y
CONFIG_ARCH_MMAP_RND_BITS=16
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
@@ -43,6 +43,7 @@
CONFIG_PARTITION_ADVANCED=y
CONFIG_ARCH_MSM=y
CONFIG_ARCH_MSM8909=y
+CONFIG_ARM_KERNMEM_PERMS=y
CONFIG_SMP=y
CONFIG_SCHED_MC=y
CONFIG_PREEMPT=y
@@ -80,9 +81,10 @@
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
+CONFIG_NET_IPVTI=y
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+CONFIG_INET_IPCOMP=y
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
CONFIG_INET_DIAG_DESTROY=y
@@ -94,6 +96,7 @@
CONFIG_INET6_ESP=y
CONFIG_INET6_IPCOMP=y
CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_VTI=y
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_SUBTREES=y
CONFIG_NETFILTER=y
@@ -469,8 +472,8 @@
CONFIG_EXT4_FS_SECURITY=y
CONFIG_QUOTA=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
-CONFIG_QFMT_V2=y
# CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_QFMT_V2=y
CONFIG_FUSE_FS=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
@@ -493,11 +496,10 @@
CONFIG_LSM_MMAP_MIN_ADDR=4096
CONFIG_HARDENED_USERCOPY=y
CONFIG_SECURITY_SELINUX=y
-CONFIG_CRYPTO_GF128MUL=y
-CONFIG_CRYPTO_NULL=y
-CONFIG_CRYPTO_CTR=y
+CONFIG_CRYPTO_GCM=y
CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_AES_ARM_BS=y
CONFIG_CRYPTO_TWOFISH=y
CONFIG_CRYPTO_DEV_QCRYPTO=y
CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y
@@ -506,7 +508,6 @@
CONFIG_CRYPTO_SHA1_ARM_NEON=y
CONFIG_CRYPTO_SHA256_ARM=y
CONFIG_CRYPTO_SHA512_ARM_NEON=y
-CONFIG_CRYPTO_AES_ARM_BS=y
CONFIG_QMI_ENCDEC=y
CONFIG_PSTORE=y
CONFIG_PSTORE_CONSOLE=y
diff --git a/arch/arm/configs/triton_defconfig b/arch/arm/configs/triton_defconfig
index 5681301..070bbb4 100644
--- a/arch/arm/configs/triton_defconfig
+++ b/arch/arm/configs/triton_defconfig
@@ -30,7 +30,7 @@
CONFIG_PROFILING=y
CONFIG_OPROFILE=m
CONFIG_KPROBES=y
-CONFIG_CC_STACKPROTECTOR_REGULAR=y
+CONFIG_CC_STACKPROTECTOR_STRONG=y
CONFIG_ARCH_MMAP_RND_BITS=16
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
@@ -42,6 +42,7 @@
CONFIG_PARTITION_ADVANCED=y
CONFIG_ARCH_MSM=y
CONFIG_ARCH_MSM8909=y
+CONFIG_ARM_KERNMEM_PERMS=y
CONFIG_SMP=y
CONFIG_SCHED_MC=y
CONFIG_PREEMPT=y
@@ -80,9 +81,10 @@
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
+CONFIG_NET_IPVTI=y
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+CONFIG_INET_IPCOMP=y
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
CONFIG_INET_DIAG_DESTROY=y
@@ -94,6 +96,7 @@
CONFIG_INET6_ESP=y
CONFIG_INET6_IPCOMP=y
CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_VTI=y
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_SUBTREES=y
CONFIG_NETFILTER=y
@@ -476,8 +479,8 @@
CONFIG_EXT4_FS_SECURITY=y
CONFIG_QUOTA=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
-CONFIG_QFMT_V2=y
# CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_QFMT_V2=y
CONFIG_FUSE_FS=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
@@ -513,7 +516,7 @@
CONFIG_IPC_LOGGING=y
CONFIG_PANIC_ON_DATA_CORRUPTION=y
CONFIG_DEBUG_USER=y
-#CONFIG_FREE_PAGES_RDONLY=y
+CONFIG_FREE_PAGES_RDONLY=y
CONFIG_DEBUG_SET_MODULE_RONX=y
CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y
CONFIG_SECURITY=y
@@ -521,10 +524,10 @@
CONFIG_LSM_MMAP_MIN_ADDR=4096
CONFIG_HARDENED_USERCOPY=y
CONFIG_SECURITY_SELINUX=y
-CONFIG_CRYPTO_NULL=y
-CONFIG_CRYPTO_CTR=y
+CONFIG_CRYPTO_GCM=y
CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_AES_ARM_BS=y
CONFIG_CRYPTO_TWOFISH=y
CONFIG_CRYPTO_DEV_QCRYPTO=y
CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y
@@ -533,7 +536,6 @@
CONFIG_CRYPTO_SHA1_ARM_NEON=y
CONFIG_CRYPTO_SHA256_ARM=y
CONFIG_CRYPTO_SHA512_ARM_NEON=y
-CONFIG_CRYPTO_AES_ARM_BS=y
CONFIG_QMI_ENCDEC=y
CONFIG_PSTORE=y
CONFIG_PSTORE_CONSOLE=y
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 700369a..b73d9b8 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -495,4 +495,14 @@
#endif
.endm
+#ifdef CONFIG_KPROBES
+#define _ASM_NOKPROBE(entry) \
+ .pushsection "_kprobe_blacklist", "aw" ; \
+ .balign 4 ; \
+ .long entry; \
+ .popsection
+#else
+#define _ASM_NOKPROBE(entry)
+#endif
+
#endif /* __ASM_ASSEMBLER_H__ */
diff --git a/arch/arm/include/asm/kgdb.h b/arch/arm/include/asm/kgdb.h
index 0a9d5dd..6949c7d 100644
--- a/arch/arm/include/asm/kgdb.h
+++ b/arch/arm/include/asm/kgdb.h
@@ -76,7 +76,7 @@
#define KGDB_MAX_NO_CPUS 1
#define BUFMAX 400
-#define NUMREGBYTES (DBG_MAX_REG_NUM << 2)
+#define NUMREGBYTES (GDB_MAX_REGS << 2)
#define NUMCRITREGBYTES (32 << 2)
#define _R0 0
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index e167896..0fc3de7 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -19,6 +19,7 @@
#include <linux/uaccess.h>
#include <linux/hardirq.h>
#include <linux/kdebug.h>
+#include <linux/kprobes.h>
#include <linux/module.h>
#include <linux/kexec.h>
#include <linux/bug.h>
@@ -398,7 +399,8 @@
raw_spin_unlock_irqrestore(&undef_lock, flags);
}
-static int call_undef_hook(struct pt_regs *regs, unsigned int instr)
+static nokprobe_inline
+int call_undef_hook(struct pt_regs *regs, unsigned int instr)
{
struct undef_hook *hook;
unsigned long flags;
@@ -473,6 +475,7 @@
arm_notify_die("Oops - undefined instruction", regs, &info, 0, 6);
}
+NOKPROBE_SYMBOL(do_undefinstr)
/*
* Handle FIQ similarly to NMI on x86 systems.
diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S
index 8ecfd15..6ffa59e 100644
--- a/arch/arm/lib/getuser.S
+++ b/arch/arm/lib/getuser.S
@@ -38,6 +38,7 @@
mov r0, #0
ret lr
ENDPROC(__get_user_1)
+_ASM_NOKPROBE(__get_user_1)
ENTRY(__get_user_2)
check_uaccess r0, 2, r1, r2, __get_user_bad
@@ -58,6 +59,7 @@
mov r0, #0
ret lr
ENDPROC(__get_user_2)
+_ASM_NOKPROBE(__get_user_2)
ENTRY(__get_user_4)
check_uaccess r0, 4, r1, r2, __get_user_bad
@@ -65,6 +67,7 @@
mov r0, #0
ret lr
ENDPROC(__get_user_4)
+_ASM_NOKPROBE(__get_user_4)
ENTRY(__get_user_8)
check_uaccess r0, 8, r1, r2, __get_user_bad
@@ -78,6 +81,7 @@
mov r0, #0
ret lr
ENDPROC(__get_user_8)
+_ASM_NOKPROBE(__get_user_8)
#ifdef __ARMEB__
ENTRY(__get_user_32t_8)
@@ -91,6 +95,7 @@
mov r0, #0
ret lr
ENDPROC(__get_user_32t_8)
+_ASM_NOKPROBE(__get_user_32t_8)
ENTRY(__get_user_64t_1)
check_uaccess r0, 1, r1, r2, __get_user_bad8
@@ -98,6 +103,7 @@
mov r0, #0
ret lr
ENDPROC(__get_user_64t_1)
+_ASM_NOKPROBE(__get_user_64t_1)
ENTRY(__get_user_64t_2)
check_uaccess r0, 2, r1, r2, __get_user_bad8
@@ -114,6 +120,7 @@
mov r0, #0
ret lr
ENDPROC(__get_user_64t_2)
+_ASM_NOKPROBE(__get_user_64t_2)
ENTRY(__get_user_64t_4)
check_uaccess r0, 4, r1, r2, __get_user_bad8
@@ -121,6 +128,7 @@
mov r0, #0
ret lr
ENDPROC(__get_user_64t_4)
+_ASM_NOKPROBE(__get_user_64t_4)
#endif
__get_user_bad8:
@@ -131,6 +139,8 @@
ret lr
ENDPROC(__get_user_bad)
ENDPROC(__get_user_bad8)
+_ASM_NOKPROBE(__get_user_bad)
+_ASM_NOKPROBE(__get_user_bad8)
.pushsection __ex_table, "a"
.long 1b, __get_user_bad
diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c
index 06d63d5..86b51f3 100644
--- a/arch/arm/mach-davinci/board-dm355-evm.c
+++ b/arch/arm/mach-davinci/board-dm355-evm.c
@@ -18,6 +18,7 @@
#include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/clk.h>
+#include <linux/dm9000.h>
#include <linux/videodev2.h>
#include <media/tvp514x.h>
#include <linux/spi/spi.h>
@@ -170,11 +171,16 @@
},
};
+static struct dm9000_plat_data dm335evm_dm9000_platdata;
+
static struct platform_device dm355evm_dm9000 = {
.name = "dm9000",
.id = -1,
.resource = dm355evm_dm9000_rsrc,
.num_resources = ARRAY_SIZE(dm355evm_dm9000_rsrc),
+ .dev = {
+ .platform_data = &dm335evm_dm9000_platdata,
+ },
};
static struct tvp514x_platform_data tvp5146_pdata = {
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c
index ae129bc..91ed570 100644
--- a/arch/arm/mach-davinci/board-dm646x-evm.c
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -538,7 +538,7 @@
.outputs = dm6467_ch0_outputs,
.output_count = ARRAY_SIZE(dm6467_ch0_outputs),
},
- .card_name = "DM646x EVM",
+ .card_name = "DM646x EVM Video Display",
};
/**
@@ -696,6 +696,7 @@
.fid_pol = 0,
},
},
+ .card_name = "DM646x EVM Video Capture",
};
static void __init evm_init_video(void)
diff --git a/arch/arm/mach-keystone/pm_domain.c b/arch/arm/mach-keystone/pm_domain.c
index ca79dda..2c95d57 100644
--- a/arch/arm/mach-keystone/pm_domain.c
+++ b/arch/arm/mach-keystone/pm_domain.c
@@ -59,6 +59,7 @@
static struct pm_clk_notifier_block platform_domain_notifier = {
.pm_domain = &keystone_pm_domain,
+ .con_ids = { NULL },
};
static struct of_device_id of_keystone_table[] = {
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c
index 4f5fd4a..034b894 100644
--- a/arch/arm/mach-omap1/clock.c
+++ b/arch/arm/mach-omap1/clock.c
@@ -1031,17 +1031,17 @@
return -ENOMEM;
c->dent = d;
- d = debugfs_create_u8("usecount", S_IRUGO, c->dent, (u8 *)&c->usecount);
+ d = debugfs_create_u8("usecount", S_IRUGO, c->dent, &c->usecount);
if (!d) {
err = -ENOMEM;
goto err_out;
}
- d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate);
+ d = debugfs_create_ulong("rate", S_IRUGO, c->dent, &c->rate);
if (!d) {
err = -ENOMEM;
goto err_out;
}
- d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags);
+ d = debugfs_create_x8("flags", S_IRUGO, c->dent, &c->flags);
if (!d) {
err = -ENOMEM;
goto err_out;
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 58920bc..3d876bd 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -231,7 +231,7 @@
cpu_idle_poll_ctrl(false);
}
-static void omap_pm_finish(void)
+static void omap_pm_wake(void)
{
if (cpu_is_omap34xx())
omap_prcm_irq_complete();
@@ -241,7 +241,7 @@
.begin = omap_pm_begin,
.end = omap_pm_end,
.enter = omap_pm_enter,
- .finish = omap_pm_finish,
+ .wake = omap_pm_wake,
.valid = suspend_valid_only_mem,
};
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index db10169..609ecea 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -853,11 +853,8 @@
timer->irq = irq->start;
timer->pdev = pdev;
- /* Skip pm_runtime_enable for OMAP1 */
- if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) {
- pm_runtime_enable(dev);
- pm_runtime_irq_safe(dev);
- }
+ pm_runtime_enable(dev);
+ pm_runtime_irq_safe(dev);
if (!timer->reserved) {
pm_runtime_get_sync(dev);
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index ce5afcf..b82f23b 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -64,6 +64,7 @@
select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_GENERIC_DMA_COHERENT
+ select HAVE_HW_BREAKPOINT if PERF_EVENTS
select HAVE_IRQ_TIME_ACCOUNTING
select HAVE_MEMBLOCK
select HAVE_PATA_PLATFORM
@@ -85,6 +86,7 @@
select SPARSE_IRQ
select SYSCTL_EXCEPTION_TRACE
select HAVE_CONTEXT_TRACKING
+ select THREAD_INFO_IN_TASK
select MSM_JTAGV8 if CORESIGHT_ETMV4
help
ARM 64-bit (AArch64) Linux support.
diff --git a/arch/arm64/configs/msm8937-perf_defconfig b/arch/arm64/configs/msm8937-perf_defconfig
index e4cb940..b6401cf 100644
--- a/arch/arm64/configs/msm8937-perf_defconfig
+++ b/arch/arm64/configs/msm8937-perf_defconfig
@@ -96,6 +96,7 @@
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
+CONFIG_NET_IPVTI=y
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
CONFIG_INET_IPCOMP=y
@@ -110,6 +111,7 @@
CONFIG_INET6_ESP=y
CONFIG_INET6_IPCOMP=y
CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_VTI=y
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_SUBTREES=y
CONFIG_NETFILTER=y
@@ -642,8 +644,7 @@
CONFIG_LSM_MMAP_MIN_ADDR=4096
CONFIG_HARDENED_USERCOPY=y
CONFIG_SECURITY_SELINUX=y
-CONFIG_CRYPTO_NULL=y
-CONFIG_CRYPTO_CTR=y
+CONFIG_CRYPTO_GCM=y
CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_TWOFISH=y
diff --git a/arch/arm64/configs/msm8937_defconfig b/arch/arm64/configs/msm8937_defconfig
index 8c62bcb..1129f55 100644
--- a/arch/arm64/configs/msm8937_defconfig
+++ b/arch/arm64/configs/msm8937_defconfig
@@ -95,6 +95,7 @@
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
+CONFIG_NET_IPVTI=y
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
CONFIG_INET_IPCOMP=y
@@ -109,6 +110,7 @@
CONFIG_INET6_ESP=y
CONFIG_INET6_IPCOMP=y
CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_VTI=y
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_SUBTREES=y
CONFIG_NETFILTER=y
@@ -692,8 +694,7 @@
CONFIG_LSM_MMAP_MIN_ADDR=4096
CONFIG_HARDENED_USERCOPY=y
CONFIG_SECURITY_SELINUX=y
-CONFIG_CRYPTO_NULL=y
-CONFIG_CRYPTO_CTR=y
+CONFIG_CRYPTO_GCM=y
CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_TWOFISH=y
diff --git a/arch/arm64/configs/msmcortex-perf_defconfig b/arch/arm64/configs/msmcortex-perf_defconfig
index 0bbd744..6358968 100644
--- a/arch/arm64/configs/msmcortex-perf_defconfig
+++ b/arch/arm64/configs/msmcortex-perf_defconfig
@@ -92,6 +92,7 @@
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
+CONFIG_NET_IPVTI=y
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
CONFIG_INET_IPCOMP=y
@@ -106,6 +107,7 @@
CONFIG_INET6_ESP=y
CONFIG_INET6_IPCOMP=y
CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_VTI=y
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_SUBTREES=y
CONFIG_NETFILTER=y
@@ -620,8 +622,7 @@
CONFIG_LSM_MMAP_MIN_ADDR=4096
CONFIG_HARDENED_USERCOPY=y
CONFIG_SECURITY_SELINUX=y
-CONFIG_CRYPTO_NULL=y
-CONFIG_CRYPTO_CTR=y
+CONFIG_CRYPTO_GCM=y
CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_TWOFISH=y
diff --git a/arch/arm64/configs/msmcortex_defconfig b/arch/arm64/configs/msmcortex_defconfig
index 785df22..e1b3bcf 100644
--- a/arch/arm64/configs/msmcortex_defconfig
+++ b/arch/arm64/configs/msmcortex_defconfig
@@ -91,6 +91,7 @@
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
+CONFIG_NET_IPVTI=y
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
CONFIG_INET_IPCOMP=y
@@ -105,6 +106,7 @@
CONFIG_INET6_ESP=y
CONFIG_INET6_IPCOMP=y
CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_VTI=y
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_SUBTREES=y
CONFIG_NETFILTER=y
@@ -693,8 +695,7 @@
CONFIG_LSM_MMAP_MIN_ADDR=4096
CONFIG_HARDENED_USERCOPY=y
CONFIG_SECURITY_SELINUX=y
-CONFIG_CRYPTO_NULL=y
-CONFIG_CRYPTO_CTR=y
+CONFIG_CRYPTO_GCM=y
CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_TWOFISH=y
diff --git a/arch/arm64/include/asm/current.h b/arch/arm64/include/asm/current.h
new file mode 100644
index 0000000..2e61d21
--- /dev/null
+++ b/arch/arm64/include/asm/current.h
@@ -0,0 +1,27 @@
+#ifndef __ASM_CURRENT_H
+#define __ASM_CURRENT_H
+
+#include <linux/compiler.h>
+
+#include <asm/sysreg.h>
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+struct task_struct;
+
+static __always_inline struct task_struct *get_current(void)
+{
+ return (struct task_struct *)read_sysreg(sp_el0);
+}
+#define current get_current()
+#else
+#include <linux/thread_info.h>
+#define get_current() (current_thread_info()->task)
+#define current get_current()
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_CURRENT_H */
+
diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
index c78ede6..c6dec25 100644
--- a/arch/arm64/include/asm/smp.h
+++ b/arch/arm64/include/asm/smp.h
@@ -56,6 +56,9 @@
*/
struct secondary_data {
void *stack;
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ struct task_struct *task;
+#endif
};
extern struct secondary_data secondary_data;
extern void secondary_entry(void);
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index 7193434..756cbf1 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -46,15 +46,26 @@
struct thread_info {
unsigned long flags; /* low level flags */
mm_segment_t addr_limit; /* address limit */
+#ifndef CONFIG_THREAD_INFO_IN_TASK
struct task_struct *task; /* main task structure */
+#endif
struct exec_domain *exec_domain; /* execution domain */
#ifdef CONFIG_ARM64_SW_TTBR0_PAN
u64 ttbr0; /* saved TTBR0_EL1 */
#endif
int preempt_count; /* 0 => preemptable, <0 => bug */
+#ifndef CONFIG_THREAD_INFO_IN_TASK
int cpu; /* cpu */
+#endif
};
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+#define INIT_THREAD_INFO(tsk) \
+{ \
+ .preempt_count = INIT_PREEMPT_COUNT, \
+ .addr_limit = KERNEL_DS, \
+}
+#else
#define INIT_THREAD_INFO(tsk) \
{ \
.task = &tsk, \
@@ -65,7 +76,6 @@
}
#define init_thread_info (init_thread_union.thread_info)
-#define init_stack (init_thread_union.stack)
/*
* how to get the current stack pointer from C
@@ -88,6 +98,9 @@
return (struct thread_info *)sp_el0;
}
+#endif
+
+#define init_stack (init_thread_union.stack)
#define thread_saved_pc(tsk) \
((unsigned long)(tsk->thread.cpu_context.pc))
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index a865573..1e5c7d0 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -34,12 +34,17 @@
{
DEFINE(TSK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
BLANK();
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ DEFINE(TSK_TI_FLAGS, offsetof(struct task_struct, thread_info.flags));
+ DEFINE(TSK_TI_PREEMPT, offsetof(struct task_struct, thread_info.preempt_count));
+ DEFINE(TSK_TI_ADDR_LIMIT, offsetof(struct task_struct, thread_info.addr_limit));
+ DEFINE(TSK_STACK, offsetof(struct task_struct, stack));
+#else
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit));
- DEFINE(TI_TASK, offsetof(struct thread_info, task));
DEFINE(TI_EXEC_DOMAIN, offsetof(struct thread_info, exec_domain));
- DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
+#endif
#ifdef CONFIG_ARM64_SW_TTBR0_PAN
DEFINE(TSK_TI_TTBR0, offsetof(struct thread_info, ttbr0));
#endif
@@ -113,6 +118,11 @@
DEFINE(TZ_MINWEST, offsetof(struct timezone, tz_minuteswest));
DEFINE(TZ_DSTTIME, offsetof(struct timezone, tz_dsttime));
BLANK();
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ DEFINE(CPU_BOOT_STACK, offsetof(struct secondary_data, stack));
+ DEFINE(CPU_BOOT_TASK, offsetof(struct secondary_data, task));
+ BLANK();
+#endif
#ifdef CONFIG_KVM_ARM_HOST
DEFINE(VCPU_CONTEXT, offsetof(struct kvm_vcpu, arch.ctxt));
DEFINE(CPU_GP_REGS, offsetof(struct kvm_cpu_context, gp_regs));
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 709f8cf..07403f5 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -116,18 +116,31 @@
.if \el == 0
mrs x21, sp_el0
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ ldr_this_cpu tsk, __entry_task, x20 // Ensure MDSCR_EL1.SS is clear,
+ ldr x19, [tsk, #TSK_TI_FLAGS] // since we can unmask debug
+#else
mov tsk, sp
and tsk, tsk, #~(THREAD_SIZE - 1) // Ensure MDSCR_EL1.SS is clear,
ldr x19, [tsk, #TI_FLAGS] // since we can unmask debug
+#endif
disable_step_tsk x19, x20 // exceptions when scheduling.
.else
add x21, sp, #S_FRAME_SIZE
get_thread_info tsk
/* Save the task's original addr_limit and set USER_DS (TASK_SIZE_64) */
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ ldr x20, [tsk, #TSK_TI_ADDR_LIMIT]
+#else
ldr x20, [tsk, #TI_ADDR_LIMIT]
+#endif
str x20, [sp, #S_ORIG_ADDR_LIMIT]
mov x20, #TASK_SIZE_64
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ str x20, [tsk, #TSK_TI_ADDR_LIMIT]
+#else
str x20, [tsk, #TI_ADDR_LIMIT]
+#endif
ALTERNATIVE(nop, SET_PSTATE_UAO(0), ARM64_HAS_UAO, CONFIG_ARM64_UAO)
.endif /* \el == 0 */
mrs x22, elr_el1
@@ -189,7 +202,11 @@
.if \el != 0
/* Restore the task's original addr_limit. */
ldr x20, [sp, #S_ORIG_ADDR_LIMIT]
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ str x20, [tsk, #TSK_TI_ADDR_LIMIT]
+#else
str x20, [tsk, #TI_ADDR_LIMIT]
+#endif
/* No need to restore UAO, it will be restored from SPSR_EL1 */
.endif
@@ -487,9 +504,17 @@
#ifdef CONFIG_PREEMPT
get_thread_info tsk
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ ldr w24, [tsk, #TSK_TI_PREEMPT] // get preempt count
+#else
ldr w24, [tsk, #TI_PREEMPT] // get preempt count
+#endif
cbnz w24, 1f // preempt count != 0
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ ldr x0, [tsk, #TSK_TI_FLAGS] // get flags
+#else
ldr x0, [tsk, #TI_FLAGS] // get flags
+#endif
tbz x0, #TIF_NEED_RESCHED, 1f // needs rescheduling?
bl el1_preempt
1:
@@ -504,7 +529,11 @@
el1_preempt:
mov x24, lr
1: bl preempt_schedule_irq // irq en/disable is done inside
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ ldr x0, [tsk, #TSK_TI_FLAGS] // get new tasks TI_FLAGS
+#else
ldr x0, [tsk, #TI_FLAGS] // get new tasks TI_FLAGS
+#endif
tbnz x0, #TIF_NEED_RESCHED, 1b // needs rescheduling?
ret x24
#endif
@@ -771,8 +800,12 @@
mov v15.16b, v15.16b
#endif
mov sp, x9
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ msr sp_el0, x1
+#else
and x9, x9, #~(THREAD_SIZE - 1)
msr sp_el0, x9
+#endif
ret
ENDPROC(cpu_switch_to)
@@ -783,7 +816,11 @@
ret_fast_syscall:
disable_irq // disable interrupts
str x0, [sp, #S_X0] // returned x0
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ ldr x1, [tsk, #TSK_TI_FLAGS] // re-check for syscall tracing
+#else
ldr x1, [tsk, #TI_FLAGS] // re-check for syscall tracing
+#endif
and x2, x1, #_TIF_SYSCALL_WORK
cbnz x2, ret_fast_syscall_trace
and x2, x1, #_TIF_WORK_MASK
@@ -815,7 +852,11 @@
*/
ret_to_user:
disable_irq // disable interrupts
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ ldr x1, [tsk, #TSK_TI_FLAGS]
+#else
ldr x1, [tsk, #TI_FLAGS]
+#endif
and x2, x1, #_TIF_WORK_MASK
cbnz x2, work_pending
enable_step_tsk x1, x2
@@ -848,7 +889,11 @@
enable_dbg_and_irq
ct_user_exit 1
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ ldr x16, [tsk, #TSK_TI_FLAGS] // check for syscall hooks
+#else
ldr x16, [tsk, #TI_FLAGS] // check for syscall hooks
+#endif
tst x16, #_TIF_SYSCALL_WORK
b.ne __sys_trace
cmp scno, sc_nr // check upper syscall limit
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 517c821..e34584f 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -456,10 +456,18 @@
bl __pi_memset
dsb ishst // Make zero page visible to PTW
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ adrp x4, init_thread_union
+ add sp, x4, #THREAD_SIZE
+ adr_l x5, init_task
+ msr sp_el0, x5 // Save thread_info
+#else
adr_l sp, initial_sp, x4
mov x4, sp
and x4, x4, #~(THREAD_SIZE - 1)
msr sp_el0, x4 // Save thread_info
+#endif
+
str_l x21, __fdt_pointer, x5 // Save FDT pointer
str_l x24, memstart_addr, x6 // Save PHYS_OFFSET
mov x29, #0
@@ -642,10 +650,18 @@
ENDPROC(secondary_startup)
ENTRY(__secondary_switched)
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ adr_l x0, secondary_data
+ ldr x1, [x0, #CPU_BOOT_STACK] // get secondary_data.stack
+ mov sp, x1
+ ldr x2, [x0, #CPU_BOOT_TASK]
+ msr sp_el0, x2
+#else
ldr x0, [x21] // get secondary_data.stack
mov sp, x0
and x0, x0, #~(THREAD_SIZE - 1)
msr sp_el0, x0 // save thread_info
+#endif
mov x29, #0
b secondary_start_kernel
ENDPROC(__secondary_switched)
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index e21fd65..4db258a 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -44,6 +44,9 @@
#include <linux/personality.h>
#include <linux/notifier.h>
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+#include <linux/percpu.h>
+#endif
#include <asm/alternative.h>
#include <asm/compat.h>
#include <asm/cacheflush.h>
@@ -391,6 +394,22 @@
}
}
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+/*
+ * We store our current task in sp_el0, which is clobbered by userspace. Keep a
+ * shadow copy so that we can restore this upon entry from userspace.
+ *
+ * This is *only* for exception entry from EL0, and is not valid until we
+ * __switch_to() a user task.
+ */
+DEFINE_PER_CPU(struct task_struct *, __entry_task);
+
+static void entry_task_switch(struct task_struct *next)
+{
+ __this_cpu_write(__entry_task, next);
+}
+#endif
+
/*
* Thread switching.
*/
@@ -403,6 +422,9 @@
tls_thread_switch(next);
hw_breakpoint_thread_switch(next);
contextidr_thread_switch(next);
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ entry_task_switch(next);
+#endif
uao_thread_switch(next);
/*
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 95fcbd5..163e2bc 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -982,9 +982,7 @@
{
int ret;
u32 kdata;
- mm_segment_t old_fs = get_fs();
- set_fs(KERNEL_DS);
/* Watchpoint */
if (num < 0) {
ret = compat_ptrace_hbp_get(NT_ARM_HW_WATCH, tsk, num, &kdata);
@@ -995,7 +993,6 @@
} else {
ret = compat_ptrace_hbp_get(NT_ARM_HW_BREAK, tsk, num, &kdata);
}
- set_fs(old_fs);
if (!ret)
ret = put_user(kdata, data);
@@ -1008,7 +1005,6 @@
{
int ret;
u32 kdata = 0;
- mm_segment_t old_fs = get_fs();
if (num == 0)
return 0;
@@ -1017,12 +1013,10 @@
if (ret)
return ret;
- set_fs(KERNEL_DS);
if (num < 0)
ret = compat_ptrace_hbp_set(NT_ARM_HW_WATCH, tsk, num, &kdata);
else
ret = compat_ptrace_hbp_set(NT_ARM_HW_BREAK, tsk, num, &kdata);
- set_fs(old_fs);
return ret;
}
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 152ad0f..d51ae08 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -97,6 +97,9 @@
* We need to tell the secondary core where to find its stack and the
* page tables.
*/
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ secondary_data.task = idle;
+#endif
secondary_data.stack = task_stack_page(idle) + THREAD_START_SP;
__flush_dcache_area(&secondary_data, sizeof(secondary_data));
@@ -120,6 +123,9 @@
pr_err("CPU%u: failed to boot: %d\n", cpu, ret);
}
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ secondary_data.task = NULL;
+#endif
secondary_data.stack = NULL;
return ret;
diff --git a/arch/hexagon/include/asm/io.h b/arch/hexagon/include/asm/io.h
index 66f5e9a..7288e31 100644
--- a/arch/hexagon/include/asm/io.h
+++ b/arch/hexagon/include/asm/io.h
@@ -216,6 +216,12 @@
memcpy((void *) dst, src, count);
}
+static inline void memset_io(volatile void __iomem *addr, int value,
+ size_t size)
+{
+ memset((void __force *)addr, value, size);
+}
+
#define PCI_IO_ADDR (volatile void __iomem *)
/*
diff --git a/arch/hexagon/lib/checksum.c b/arch/hexagon/lib/checksum.c
index 8169f78..5d72fb9 100644
--- a/arch/hexagon/lib/checksum.c
+++ b/arch/hexagon/lib/checksum.c
@@ -201,3 +201,4 @@
memcpy(dst, src, len);
return csum_partial(dst, len, sum);
}
+EXPORT_SYMBOL(csum_partial_copy_nocheck);
diff --git a/arch/m68k/coldfire/device.c b/arch/m68k/coldfire/device.c
index 71ea4c0..8a2dc0a 100644
--- a/arch/m68k/coldfire/device.c
+++ b/arch/m68k/coldfire/device.c
@@ -135,7 +135,11 @@
.id = 0,
.num_resources = ARRAY_SIZE(mcf_fec0_resources),
.resource = mcf_fec0_resources,
- .dev.platform_data = FEC_PDATA,
+ .dev = {
+ .dma_mask = &mcf_fec0.dev.coherent_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = FEC_PDATA,
+ }
};
#ifdef MCFFEC_BASE1
@@ -167,7 +171,11 @@
.id = 1,
.num_resources = ARRAY_SIZE(mcf_fec1_resources),
.resource = mcf_fec1_resources,
- .dev.platform_data = FEC_PDATA,
+ .dev = {
+ .dma_mask = &mcf_fec1.dev.coherent_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = FEC_PDATA,
+ }
};
#endif /* MCFFEC_BASE1 */
#endif /* CONFIG_FEC */
diff --git a/arch/m68k/mm/kmap.c b/arch/m68k/mm/kmap.c
index 6e4955b..fcd52ce 100644
--- a/arch/m68k/mm/kmap.c
+++ b/arch/m68k/mm/kmap.c
@@ -88,7 +88,8 @@
for (p = &iolist ; (tmp = *p) ; p = &tmp->next) {
if (tmp->addr == addr) {
*p = tmp->next;
- __iounmap(tmp->addr, tmp->size);
+ /* remove gap added in get_io_area() */
+ __iounmap(tmp->addr, tmp->size - IO_SIZE);
kfree(tmp);
return;
}
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c
index c00585d..706bab3 100644
--- a/arch/mips/bcm47xx/setup.c
+++ b/arch/mips/bcm47xx/setup.c
@@ -269,6 +269,12 @@
*/
if (bcm47xx_bus.bcma.bus.chipinfo.id == BCMA_CHIP_ID_BCM4706)
cpu_wait = NULL;
+
+ /*
+ * BCM47XX Erratum "R10: PCIe Transactions Periodically Fail"
+ * Enable ExternalSync for sync instruction to take effect
+ */
+ set_c0_config7(MIPS_CONF7_ES);
break;
#endif
}
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index 933b50e..fdb3c97 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -375,6 +375,8 @@
BUG(); \
} \
\
+ /* prevent prefetching of coherent DMA data prematurely */ \
+ rmb(); \
return pfx##ioswab##bwlq(__mem, __val); \
}
@@ -410,6 +412,8 @@
__val = *__addr; \
slow; \
\
+ /* prevent prefetching of coherent DMA data prematurely */ \
+ rmb(); \
return pfx##ioswab##bwlq(__addr, __val); \
}
diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
index cd41e93..19e5142 100644
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -167,7 +167,7 @@
#define AR71XX_AHB_DIV_MASK 0x7
#define AR724X_PLL_REG_CPU_CONFIG 0x00
-#define AR724X_PLL_REG_PCIE_CONFIG 0x18
+#define AR724X_PLL_REG_PCIE_CONFIG 0x10
#define AR724X_PLL_DIV_SHIFT 0
#define AR724X_PLL_DIV_MASK 0x3ff
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index f38ca682..9655d0a 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -667,6 +667,8 @@
#define MIPS_CONF7_WII (_ULCAST_(1) << 31)
#define MIPS_CONF7_RPS (_ULCAST_(1) << 2)
+/* ExternalSync */
+#define MIPS_CONF7_ES (_ULCAST_(1) << 8)
#define MIPS_CONF7_IAR (_ULCAST_(1) << 10)
#define MIPS_CONF7_AR (_ULCAST_(1) << 16)
@@ -1863,6 +1865,7 @@
__BUILD_SET_C0(cause)
__BUILD_SET_C0(config)
__BUILD_SET_C0(config5)
+__BUILD_SET_C0(config7)
__BUILD_SET_C0(intcontrol)
__BUILD_SET_C0(intctl)
__BUILD_SET_C0(srsmap)
diff --git a/arch/mips/kernel/mcount.S b/arch/mips/kernel/mcount.S
index 2f7c734..0df911e 100644
--- a/arch/mips/kernel/mcount.S
+++ b/arch/mips/kernel/mcount.S
@@ -116,10 +116,20 @@
NESTED(_mcount, PT_SIZE, ra)
PTR_LA t1, ftrace_stub
PTR_L t2, ftrace_trace_function /* Prepare t2 for (1) */
- bne t1, t2, static_trace
+ beq t1, t2, fgraph_trace
nop
+ MCOUNT_SAVE_REGS
+
+ move a0, ra /* arg1: self return address */
+ jalr t2 /* (1) call *ftrace_trace_function */
+ move a1, AT /* arg2: parent's return address */
+
+ MCOUNT_RESTORE_REGS
+
+fgraph_trace:
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ PTR_LA t1, ftrace_stub
PTR_L t3, ftrace_graph_return
bne t1, t3, ftrace_graph_caller
nop
@@ -128,24 +138,11 @@
bne t1, t3, ftrace_graph_caller
nop
#endif
- b ftrace_stub
-#ifdef CONFIG_32BIT
- addiu sp, sp, 8
-#else
- nop
-#endif
-static_trace:
- MCOUNT_SAVE_REGS
-
- move a0, ra /* arg1: self return address */
- jalr t2 /* (1) call *ftrace_trace_function */
- move a1, AT /* arg2: parent's return address */
-
- MCOUNT_RESTORE_REGS
#ifdef CONFIG_32BIT
addiu sp, sp, 8
#endif
+
.globl ftrace_stub
ftrace_stub:
RETURN_BACK
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 8b19ef0..c1bd750 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -444,7 +444,7 @@
/*
* Copy the floating-point context to the supplied NT_PRFPREG buffer.
* Choose the appropriate helper for general registers, and then copy
- * the FCSR register separately.
+ * the FCSR and FIR registers separately.
*/
static int fpr_get(struct task_struct *target,
const struct user_regset *regset,
@@ -452,6 +452,7 @@
void *kbuf, void __user *ubuf)
{
const int fcr31_pos = NUM_FPU_REGS * sizeof(elf_fpreg_t);
+ const int fir_pos = fcr31_pos + sizeof(u32);
int err;
if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t))
@@ -464,6 +465,12 @@
err = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
&target->thread.fpu.fcr31,
fcr31_pos, fcr31_pos + sizeof(u32));
+ if (err)
+ return err;
+
+ err = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &boot_cpu_data.fpu_id,
+ fir_pos, fir_pos + sizeof(u32));
return err;
}
@@ -512,7 +519,8 @@
/*
* Copy the supplied NT_PRFPREG buffer to the floating-point context.
* Choose the appropriate helper for general registers, and then copy
- * the FCSR register separately.
+ * the FCSR register separately. Ignore the incoming FIR register
+ * contents though, as the register is read-only.
*
* We optimize for the case where `count % sizeof(elf_fpreg_t) == 0',
* which is supposed to have been guaranteed by the kernel before
@@ -526,6 +534,7 @@
const void *kbuf, const void __user *ubuf)
{
const int fcr31_pos = NUM_FPU_REGS * sizeof(elf_fpreg_t);
+ const int fir_pos = fcr31_pos + sizeof(u32);
u32 fcr31;
int err;
@@ -551,6 +560,11 @@
target->thread.fpu.fcr31 = fcr31 & ~FPU_CSR_ALL_X;
}
+ if (count > 0)
+ err = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
+ fir_pos,
+ fir_pos + sizeof(u32));
+
return err;
}
@@ -688,7 +702,7 @@
fregs = get_fpu_regs(child);
#ifdef CONFIG_32BIT
- if (test_thread_flag(TIF_32BIT_FPREGS)) {
+ if (test_tsk_thread_flag(child, TIF_32BIT_FPREGS)) {
/*
* The odd registers are actually the high
* order bits of the values stored in the even
@@ -699,7 +713,7 @@
break;
}
#endif
- tmp = get_fpr32(&fregs[addr - FPR_BASE], 0);
+ tmp = get_fpr64(&fregs[addr - FPR_BASE], 0);
break;
case PC:
tmp = regs->cp0_epc;
@@ -782,7 +796,7 @@
child->thread.fpu.fcr31 = 0;
}
#ifdef CONFIG_32BIT
- if (test_thread_flag(TIF_32BIT_FPREGS)) {
+ if (test_tsk_thread_flag(child, TIF_32BIT_FPREGS)) {
/*
* The odd registers are actually the high
* order bits of the values stored in the even
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c
index 283b5a1..d95117e 100644
--- a/arch/mips/kernel/ptrace32.c
+++ b/arch/mips/kernel/ptrace32.c
@@ -97,7 +97,7 @@
break;
}
fregs = get_fpu_regs(child);
- if (test_thread_flag(TIF_32BIT_FPREGS)) {
+ if (test_tsk_thread_flag(child, TIF_32BIT_FPREGS)) {
/*
* The odd registers are actually the high
* order bits of the values stored in the even
@@ -107,7 +107,7 @@
addr & 1);
break;
}
- tmp = get_fpr32(&fregs[addr - FPR_BASE], 0);
+ tmp = get_fpr64(&fregs[addr - FPR_BASE], 0);
break;
case PC:
tmp = regs->cp0_epc;
@@ -203,7 +203,7 @@
sizeof(child->thread.fpu));
child->thread.fpu.fcr31 = 0;
}
- if (test_thread_flag(TIF_32BIT_FPREGS)) {
+ if (test_tsk_thread_flag(child, TIF_32BIT_FPREGS)) {
/*
* The odd registers are actually the high
* order bits of the values stored in the even
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index 26059bf..8ac533c 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -39,7 +39,7 @@
{ "cache", VCPU_STAT(cache_exits), KVM_STAT_VCPU },
{ "signal", VCPU_STAT(signal_exits), KVM_STAT_VCPU },
{ "interrupt", VCPU_STAT(int_exits), KVM_STAT_VCPU },
- { "cop_unsuable", VCPU_STAT(cop_unusable_exits), KVM_STAT_VCPU },
+ { "cop_unusable", VCPU_STAT(cop_unusable_exits), KVM_STAT_VCPU },
{ "tlbmod", VCPU_STAT(tlbmod_exits), KVM_STAT_VCPU },
{ "tlbmiss_ld", VCPU_STAT(tlbmiss_ld_exits), KVM_STAT_VCPU },
{ "tlbmiss_st", VCPU_STAT(tlbmiss_st_exits), KVM_STAT_VCPU },
diff --git a/arch/mips/txx9/rbtx4939/setup.c b/arch/mips/txx9/rbtx4939/setup.c
index 2da5f25..e802259 100644
--- a/arch/mips/txx9/rbtx4939/setup.c
+++ b/arch/mips/txx9/rbtx4939/setup.c
@@ -186,7 +186,7 @@
#define RBTX4939_MAX_7SEGLEDS 8
-#if IS_ENABLED(CONFIG_LEDS_CLASS)
+#if IS_BUILTIN(CONFIG_LEDS_CLASS)
static u8 led_val[RBTX4939_MAX_7SEGLEDS];
struct rbtx4939_led_data {
struct led_classdev cdev;
@@ -262,7 +262,7 @@
static void __rbtx4939_7segled_putc(unsigned int pos, unsigned char val)
{
-#if IS_ENABLED(CONFIG_LEDS_CLASS)
+#if IS_BUILTIN(CONFIG_LEDS_CLASS)
unsigned long flags;
local_irq_save(flags);
/* bit7: reserved for LED class */
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
index 70e105d..d2d2946 100644
--- a/arch/parisc/kernel/time.c
+++ b/arch/parisc/kernel/time.c
@@ -246,7 +246,7 @@
}
module_init(rtc_init);
-void read_persistent_clock(struct timespec *ts)
+void read_persistent_clock64(struct timespec64 *ts)
{
static struct pdc_tod tod_data;
if (pdc_tod_read(&tod_data) == 0) {
diff --git a/arch/powerpc/include/asm/irq_work.h b/arch/powerpc/include/asm/irq_work.h
index 744fd54..1bcc849 100644
--- a/arch/powerpc/include/asm/irq_work.h
+++ b/arch/powerpc/include/asm/irq_work.h
@@ -5,5 +5,6 @@
{
return true;
}
+extern void arch_irq_work_raise(void);
#endif /* _ASM_POWERPC_IRQ_WORK_H */
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index e233c0f..8d64db1 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -521,6 +521,7 @@
* actually hit this code path.
*/
+ isync
slbie r6
slbie r6 /* Workaround POWER5 < DD2.1 issue */
slbmte r7,r0
diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
index 26d091a..791d4c3 100644
--- a/arch/powerpc/kernel/fadump.c
+++ b/arch/powerpc/kernel/fadump.c
@@ -1025,6 +1025,9 @@
init_fadump_mem_struct(&fdm,
be64_to_cpu(fdm_active->cpu_state_data.destination_address));
fadump_invalidate_dump(&fdm);
+ } else if (fw_dump.dump_registered) {
+ /* Un-register Firmware-assisted dump if it was registered. */
+ fadump_unregister_dump(&fdm);
}
}
diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c
index 1f7d84e..cc05fe8 100644
--- a/arch/powerpc/kernel/hw_breakpoint.c
+++ b/arch/powerpc/kernel/hw_breakpoint.c
@@ -174,8 +174,8 @@
if (cpu_has_feature(CPU_FTR_DAWR)) {
length_max = 512 ; /* 64 doublewords */
/* DAWR region can't cross 512 boundary */
- if ((bp->attr.bp_addr >> 10) !=
- ((bp->attr.bp_addr + bp->attr.bp_len - 1) >> 10))
+ if ((bp->attr.bp_addr >> 9) !=
+ ((bp->attr.bp_addr + bp->attr.bp_len - 1) >> 9))
return -EINVAL;
}
if (info->len >
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 93f200f..c8a62ee 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1004,6 +1004,7 @@
/* Create a new breakpoint request if one doesn't exist already */
hw_breakpoint_init(&attr);
attr.bp_addr = hw_brk.address;
+ attr.bp_len = 8;
arch_bp_generic_fields(hw_brk.type,
&attr.bp_type);
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 1362cd6..d4c368b 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -217,14 +217,6 @@
unsigned short maj;
unsigned short min;
- /* We only show online cpus: disable preempt (overzealous, I
- * knew) to prevent cpu going down. */
- preempt_disable();
- if (!cpu_online(cpu_id)) {
- preempt_enable();
- return 0;
- }
-
#ifdef CONFIG_SMP
pvr = per_cpu(cpu_pvr, cpu_id);
#else
@@ -329,9 +321,6 @@
#ifdef CONFIG_SMP
seq_printf(m, "\n");
#endif
-
- preempt_enable();
-
/* If this is the last cpu, print the summary */
if (cpumask_next(cpu_id, cpu_online_mask) >= nr_cpu_ids)
show_cpuinfo_summary(m);
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index e97c0e5..ef77f6e1 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -443,6 +443,16 @@
/* invalid entry */
continue;
+ /*
+ * BHRB rolling buffer could very much contain the kernel
+ * addresses at this point. Check the privileges before
+ * exporting it to userspace (avoid exposure of regions
+ * where we could have speculative execution)
+ */
+ if (perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN) &&
+ is_kernel_addr(addr))
+ continue;
+
/* Branches are read most recent first (ie. mfbhrb 0 is
* the most recent branch).
* There are two types of valid entries:
@@ -1183,6 +1193,7 @@
*/
write_mmcr0(cpuhw, val);
mb();
+ isync();
/*
* Disable instruction sampling if it was enabled
@@ -1191,12 +1202,26 @@
mtspr(SPRN_MMCRA,
cpuhw->mmcr[2] & ~MMCRA_SAMPLE_ENABLE);
mb();
+ isync();
}
cpuhw->disabled = 1;
cpuhw->n_added = 0;
ebb_switch_out(mmcr0);
+
+#ifdef CONFIG_PPC64
+ /*
+ * These are readable by userspace, may contain kernel
+ * addresses and are not switched by context switch, so clear
+ * them now to avoid leaking anything to userspace in general
+ * including to another process.
+ */
+ if (ppmu->flags & PPMU_ARCH_207S) {
+ mtspr(SPRN_SDAR, 0);
+ mtspr(SPRN_SIAR, 0);
+ }
+#endif
}
local_irq_restore(flags);
diff --git a/arch/powerpc/platforms/powernv/opal-nvram.c b/arch/powerpc/platforms/powernv/opal-nvram.c
index f3b2f6f..28da4f9 100644
--- a/arch/powerpc/platforms/powernv/opal-nvram.c
+++ b/arch/powerpc/platforms/powernv/opal-nvram.c
@@ -43,6 +43,10 @@
return count;
}
+/*
+ * This can be called in the panic path with interrupts off, so use
+ * mdelay in that case.
+ */
static ssize_t opal_nvram_write(char *buf, size_t count, loff_t *index)
{
s64 rc = OPAL_BUSY;
@@ -57,10 +61,16 @@
while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
rc = opal_write_nvram(__pa(buf), count, off);
if (rc == OPAL_BUSY_EVENT) {
- msleep(OPAL_BUSY_DELAY_MS);
+ if (in_interrupt() || irqs_disabled())
+ mdelay(OPAL_BUSY_DELAY_MS);
+ else
+ msleep(OPAL_BUSY_DELAY_MS);
opal_poll_events(NULL);
} else if (rc == OPAL_BUSY) {
- msleep(OPAL_BUSY_DELAY_MS);
+ if (in_interrupt() || irqs_disabled())
+ mdelay(OPAL_BUSY_DELAY_MS);
+ else
+ msleep(OPAL_BUSY_DELAY_MS);
}
}
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index bf6f77e..a72735c 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -627,7 +627,7 @@
int i;
u32 mask = 0;
- for (i = 0; i < min(32, NR_CPUS); ++i, cpumask >>= 1)
+ for (i = 0; i < min(32, NR_CPUS) && cpu_possible(i); ++i, cpumask >>= 1)
mask |= (cpumask & 1) << get_hard_smp_processor_id(i);
return mask;
}
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index 13047a4..5a9017b 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -255,7 +255,7 @@
mov.l @r8, r8
jsr @r8
nop
- bra __restore_all
+ bra ret_from_exception
nop
CFI_ENDPROC
diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h
index 4082749..f5b7db2 100644
--- a/arch/sparc/include/asm/atomic_64.h
+++ b/arch/sparc/include/asm/atomic_64.h
@@ -70,7 +70,11 @@
#define atomic64_add_negative(i, v) (atomic64_add_return(i, v) < 0)
#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
-#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+
+static inline int atomic_xchg(atomic_t *v, int new)
+{
+ return xchg(&v->counter, new);
+}
static inline int __atomic_add_unless(atomic_t *v, int a, int u)
{
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index 2da9cef..1e558d7 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -364,7 +364,8 @@
if (status != EFI_SUCCESS)
goto free_struct;
- memcpy(rom->romdata, pci->romimage, pci->romsize);
+ memcpy(rom->romdata, (void *)(unsigned long)pci->romimage,
+ pci->romsize);
return status;
free_struct:
@@ -470,7 +471,8 @@
if (status != EFI_SUCCESS)
goto free_struct;
- memcpy(rom->romdata, pci->romimage, pci->romsize);
+ memcpy(rom->romdata, (void *)(unsigned long)pci->romimage,
+ pci->romsize);
return status;
free_struct:
diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig
index 73299cd..263b026 100644
--- a/arch/x86/configs/x86_64_cuttlefish_defconfig
+++ b/arch/x86/configs/x86_64_cuttlefish_defconfig
@@ -11,6 +11,7 @@
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_CGROUPS=y
+CONFIG_CGROUP_DEBUG=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
@@ -53,6 +54,7 @@
CONFIG_PHYSICAL_ALIGN=0x1000000
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE="console=ttyS0 reboot=p"
+CONFIG_PM_AUTOSLEEP=y
CONFIG_PM_WAKELOCKS=y
CONFIG_PM_WAKELOCKS_LIMIT=0
# CONFIG_PM_WAKELOCKS_GC is not set
@@ -87,8 +89,8 @@
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
CONFIG_SYN_COOKIES=y
+CONFIG_NET_IPVTI=y
CONFIG_INET_ESP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
CONFIG_INET_DIAG_DESTROY=y
@@ -105,6 +107,7 @@
CONFIG_INET6_ESP=y
CONFIG_INET6_IPCOMP=y
CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_VTI=y
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_NETLABEL=y
CONFIG_NETFILTER=y
@@ -293,11 +296,11 @@
# CONFIG_DVB_TUNER_DIB0090 is not set
# CONFIG_VGA_ARB is not set
CONFIG_DRM=y
+CONFIG_FB=y
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_HIDRAW=y
CONFIG_UHID=y
-# CONFIG_HID_GENERIC is not set
CONFIG_HID_A4TECH=y
CONFIG_HID_ACRUX=y
CONFIG_HID_ACRUX_FF=y
@@ -361,9 +364,6 @@
CONFIG_USB_DUMMY_HCD=y
CONFIG_USB_CONFIGFS=y
CONFIG_USB_CONFIGFS_F_FS=y
-CONFIG_USB_CONFIGFS_F_ACC=y
-CONFIG_USB_CONFIGFS_UEVENT=y
-CONFIG_USB_CONFIGFS_F_MIDI=y
CONFIG_SWITCH=y
CONFIG_RTC_CLASS=y
# CONFIG_RTC_HCTOSYS is not set
@@ -405,6 +405,9 @@
CONFIG_PSTORE=y
CONFIG_PSTORE_CONSOLE=y
CONFIG_PSTORE_RAM=y
+CONFIG_F2FS_FS=y
+CONFIG_F2FS_FS_SECURITY=y
+CONFIG_F2FS_FS_ENCRYPTION=y
CONFIG_NLS_DEFAULT="utf8"
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ASCII=y
@@ -437,6 +440,8 @@
CONFIG_HARDENED_USERCOPY=y
CONFIG_SECURITY_SELINUX=y
# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
+CONFIG_CRYPTO_GCM=y
+CONFIG_CRYPTO_SHA512=y
CONFIG_CRYPTO_ANSI_CPRNG=y
CONFIG_ASYMMETRIC_KEY_TYPE=y
CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 9cc6b6f..2f68823 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -561,6 +561,9 @@
{ 0x5d, TLB_DATA_4K_4M, 256, " TLB_DATA 4 KByte and 4 MByte pages" },
{ 0x61, TLB_INST_4K, 48, " TLB_INST 4 KByte pages, full associative" },
{ 0x63, TLB_DATA_1G, 4, " TLB_DATA 1 GByte pages, 4-way set associative" },
+ { 0x6b, TLB_DATA_4K, 256, " TLB_DATA 4 KByte pages, 8-way associative" },
+ { 0x6c, TLB_DATA_2M_4M, 128, " TLB_DATA 2 MByte or 4 MByte pages, 8-way associative" },
+ { 0x6d, TLB_DATA_1G, 16, " TLB_DATA 1 GByte pages, fully associative" },
{ 0x76, TLB_INST_2M_4M, 8, " TLB_INST 2-MByte or 4-MByte pages, fully associative" },
{ 0xb0, TLB_INST_4K, 128, " TLB_INST 4 KByte pages, 4-way set associative" },
{ 0xb1, TLB_INST_2M_4M, 4, " TLB_INST 2M pages, 4-way, 8 entries or 4M pages, 4-way entries" },
diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c
index 72e8e31..348e454 100644
--- a/arch/x86/kernel/machine_kexec_32.c
+++ b/arch/x86/kernel/machine_kexec_32.c
@@ -70,12 +70,17 @@
static void machine_kexec_free_page_tables(struct kimage *image)
{
free_page((unsigned long)image->arch.pgd);
+ image->arch.pgd = NULL;
#ifdef CONFIG_X86_PAE
free_page((unsigned long)image->arch.pmd0);
+ image->arch.pmd0 = NULL;
free_page((unsigned long)image->arch.pmd1);
+ image->arch.pmd1 = NULL;
#endif
free_page((unsigned long)image->arch.pte0);
+ image->arch.pte0 = NULL;
free_page((unsigned long)image->arch.pte1);
+ image->arch.pte1 = NULL;
}
static int machine_kexec_alloc_page_tables(struct kimage *image)
@@ -92,7 +97,6 @@
!image->arch.pmd0 || !image->arch.pmd1 ||
#endif
!image->arch.pte0 || !image->arch.pte1) {
- machine_kexec_free_page_tables(image);
return -ENOMEM;
}
return 0;
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
index 0652c5b..7c16b11 100644
--- a/arch/x86/kernel/machine_kexec_64.c
+++ b/arch/x86/kernel/machine_kexec_64.c
@@ -34,8 +34,11 @@
static void free_transition_pgtable(struct kimage *image)
{
free_page((unsigned long)image->arch.pud);
+ image->arch.pud = NULL;
free_page((unsigned long)image->arch.pmd);
+ image->arch.pmd = NULL;
free_page((unsigned long)image->arch.pte);
+ image->arch.pte = NULL;
}
static int init_transition_pgtable(struct kimage *image, pgd_t *pgd)
@@ -76,7 +79,6 @@
set_pte(pte, pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL_EXEC));
return 0;
err:
- free_transition_pgtable(image);
return result;
}
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 668d8f2..a3edf72 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1290,6 +1290,7 @@
cpumask_clear(cpu_core_mask(cpu));
c->phys_proc_id = 0;
c->cpu_core_id = 0;
+ c->booted_cores = 0;
cpumask_clear_cpu(cpu, cpu_sibling_setup_mask);
}
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index a60950b..cd51f32 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2064,6 +2064,8 @@
return;
}
+ WARN_ON_ONCE(vmx->emulation_required);
+
if (kvm_exception_is_soft(nr)) {
vmcs_write32(VM_ENTRY_INSTRUCTION_LEN,
vmx->vcpu.arch.event_exit_inst_len);
@@ -5722,12 +5724,12 @@
goto out;
}
- if (err != EMULATE_DONE) {
- vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
- vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION;
- vcpu->run->internal.ndata = 0;
- return 0;
- }
+ if (err != EMULATE_DONE)
+ goto emulation_error;
+
+ if (vmx->emulation_required && !vmx->rmode.vm86_active &&
+ vcpu->arch.exception.pending)
+ goto emulation_error;
if (vcpu->arch.halt_request) {
vcpu->arch.halt_request = 0;
@@ -5743,6 +5745,12 @@
out:
return ret;
+
+emulation_error:
+ vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
+ vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION;
+ vcpu->run->internal.ndata = 0;
+ return 0;
}
static int __grow_ple_window(int val)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 2b756f9..2a084b0 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4025,13 +4025,14 @@
break;
}
case KVM_XEN_HVM_CONFIG: {
+ struct kvm_xen_hvm_config xhc;
r = -EFAULT;
- if (copy_from_user(&kvm->arch.xen_hvm_config, argp,
- sizeof(struct kvm_xen_hvm_config)))
+ if (copy_from_user(&xhc, argp, sizeof(xhc)))
goto out;
r = -EINVAL;
- if (kvm->arch.xen_hvm_config.flags)
+ if (xhc.flags)
goto out;
+ memcpy(&kvm->arch.xen_hvm_config, &xhc, sizeof(xhc));
r = 0;
break;
}
diff --git a/arch/x86/lib/cmdline.c b/arch/x86/lib/cmdline.c
index 422db00..49548be 100644
--- a/arch/x86/lib/cmdline.c
+++ b/arch/x86/lib/cmdline.c
@@ -21,12 +21,14 @@
* @option: option string to look for
*
* Returns the position of that @option (starts counting with 1)
- * or 0 on not found.
+ * or 0 on not found. @option will only be found if it is found
+ * as an entire word in @cmdline. For instance, if @option="car"
+ * then a cmdline which contains "cart" will not match.
*/
int cmdline_find_option_bool(const char *cmdline, const char *option)
{
char c;
- int len, pos = 0, wstart = 0;
+ int pos = 0, wstart = 0;
const char *opptr = NULL;
enum {
st_wordstart = 0, /* Start of word/after whitespace */
@@ -37,11 +39,14 @@
if (!cmdline)
return -1; /* No command line */
- len = min_t(int, strlen(cmdline), COMMAND_LINE_SIZE);
- if (!len)
+ if (!strlen(cmdline))
return 0;
- while (len--) {
+ /*
+ * This 'pos' check ensures we do not overrun
+ * a non-NULL-terminated 'cmdline'
+ */
+ while (pos < COMMAND_LINE_SIZE) {
c = *(char *)cmdline++;
pos++;
@@ -58,17 +63,26 @@
/* fall through */
case st_wordcmp:
- if (!*opptr)
+ if (!*opptr) {
+ /*
+ * We matched all the way to the end of the
+ * option we were looking for. If the
+ * command-line has a space _or_ ends, then
+ * we matched!
+ */
if (!c || myisspace(c))
return wstart;
else
state = st_wordskip;
- else if (!c)
+ } else if (!c) {
+ /*
+ * Hit the NULL terminator on the end of
+ * cmdline.
+ */
return 0;
- else if (c != *opptr++)
+ } else if (c != *opptr++) {
state = st_wordskip;
- else if (!len) /* last word and is matching */
- return wstart;
+ }
break;
case st_wordskip:
diff --git a/arch/x86/power/hibernate_32.c b/arch/x86/power/hibernate_32.c
index 291226b..77ac4e4 100644
--- a/arch/x86/power/hibernate_32.c
+++ b/arch/x86/power/hibernate_32.c
@@ -142,7 +142,7 @@
#endif
}
-int swsusp_arch_resume(void)
+asmlinkage int swsusp_arch_resume(void)
{
int error;
diff --git a/arch/x86/power/hibernate_64.c b/arch/x86/power/hibernate_64.c
index 009947d..0e0c773 100644
--- a/arch/x86/power/hibernate_64.c
+++ b/arch/x86/power/hibernate_64.c
@@ -78,7 +78,7 @@
return 0;
}
-int swsusp_arch_resume(void)
+asmlinkage int swsusp_arch_resume(void)
{
int error;
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 039d4e1..196f930 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -1246,8 +1246,6 @@
struct mmuext_op *op;
struct multicall_space mcs;
- trace_xen_mmu_flush_tlb_all(0);
-
preempt_disable();
mcs = xen_mc_entry(sizeof(*op));
@@ -1265,8 +1263,6 @@
struct mmuext_op *op;
struct multicall_space mcs;
- trace_xen_mmu_flush_tlb(0);
-
preempt_disable();
mcs = xen_mc_entry(sizeof(*op));
diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c
index 9d2f45f..148985f 100644
--- a/arch/xtensa/kernel/traps.c
+++ b/arch/xtensa/kernel/traps.c
@@ -280,7 +280,7 @@
info.si_errno = 0;
info.si_code = BUS_ADRALN;
info.si_addr = (void *) regs->excvaddr;
- force_sig_info(SIGSEGV, &info, current);
+ force_sig_info(SIGBUS, &info, current);
}
#endif
diff --git a/build.config.cuttlefish.x86_64 b/build.config.cuttlefish.x86_64
index fcc0815..753a715 100644
--- a/build.config.cuttlefish.x86_64
+++ b/build.config.cuttlefish.x86_64
@@ -11,3 +11,4 @@
vmlinux
System.map
"
+STOP_SHIP_TRACEPRINTK=1
diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c
index c305d41..bd5f14e 100644
--- a/crypto/pcrypt.c
+++ b/crypto/pcrypt.c
@@ -306,6 +306,14 @@
crypto_free_aead(ctx->child);
}
+static void pcrypt_free(struct crypto_instance *inst)
+{
+ struct pcrypt_instance_ctx *ctx = crypto_instance_ctx(inst);
+
+ crypto_drop_spawn(&ctx->spawn);
+ kfree(inst);
+}
+
static struct crypto_instance *pcrypt_alloc_instance(struct crypto_alg *alg)
{
struct crypto_instance *inst;
@@ -375,6 +383,7 @@
inst->alg.cra_aead.encrypt = pcrypt_aead_encrypt;
inst->alg.cra_aead.decrypt = pcrypt_aead_decrypt;
inst->alg.cra_aead.givencrypt = pcrypt_aead_givencrypt;
+ inst->tmpl->free = pcrypt_free;
out_put_alg:
crypto_mod_put(alg);
@@ -397,14 +406,6 @@
return ERR_PTR(-EINVAL);
}
-static void pcrypt_free(struct crypto_instance *inst)
-{
- struct pcrypt_instance_ctx *ctx = crypto_instance_ctx(inst);
-
- crypto_drop_spawn(&ctx->spawn);
- kfree(inst);
-}
-
static int pcrypt_cpumask_change_notify(struct notifier_block *self,
unsigned long val, void *data)
{
@@ -517,7 +518,6 @@
static struct crypto_template pcrypt_tmpl = {
.name = "pcrypt",
.alloc = pcrypt_alloc,
- .free = pcrypt_free,
.module = THIS_MODULE,
};
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c
index f148a05..970f954 100644
--- a/drivers/acpi/acpi_pad.c
+++ b/drivers/acpi/acpi_pad.c
@@ -117,6 +117,7 @@
cpumask_andnot(tmp, cpu_online_mask, pad_busy_cpus);
if (cpumask_empty(tmp)) {
mutex_unlock(&round_robin_lock);
+ free_cpumask_var(tmp);
return;
}
for_each_cpu(cpu, tmp) {
@@ -134,6 +135,8 @@
mutex_unlock(&round_robin_lock);
set_cpus_allowed_ptr(current, cpumask_of(preferred_cpu));
+
+ free_cpumask_var(tmp);
}
static void exit_round_robin(unsigned int tsk_index)
diff --git a/drivers/acpi/acpica/evevent.c b/drivers/acpi/acpica/evevent.c
index c7bffff..f535685 100644
--- a/drivers/acpi/acpica/evevent.c
+++ b/drivers/acpi/acpica/evevent.c
@@ -204,6 +204,7 @@
u32 fixed_status;
u32 fixed_enable;
u32 i;
+ acpi_status status;
ACPI_FUNCTION_NAME(ev_fixed_event_detect);
@@ -211,8 +212,12 @@
* Read the fixed feature status and enable registers, as all the cases
* depend on their values. Ignore errors here.
*/
- (void)acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, &fixed_status);
- (void)acpi_hw_register_read(ACPI_REGISTER_PM1_ENABLE, &fixed_enable);
+ status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, &fixed_status);
+ status |=
+ acpi_hw_register_read(ACPI_REGISTER_PM1_ENABLE, &fixed_enable);
+ if (ACPI_FAILURE(status)) {
+ return (int_status);
+ }
ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
"Fixed Event Block: Enable %08X Status %08X\n",
diff --git a/drivers/acpi/acpica/nseval.c b/drivers/acpi/acpica/nseval.c
index e634a05..1358c70 100644
--- a/drivers/acpi/acpica/nseval.c
+++ b/drivers/acpi/acpica/nseval.c
@@ -308,6 +308,14 @@
/* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */
status = AE_OK;
+ } else if (ACPI_FAILURE(status)) {
+
+ /* If return_object exists, delete it */
+
+ if (info->return_object) {
+ acpi_ut_remove_reference(info->return_object);
+ info->return_object = NULL;
+ }
}
ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index cfc8aba..59130ce 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -165,7 +165,7 @@
{
int ret;
- if (ignore_ppc) {
+ if (ignore_ppc || !pr->performance) {
/*
* Only when it is notification event, the _OST object
* will be evaluated. Otherwise it is skipped.
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index ac18149..cd589d0 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4188,6 +4188,10 @@
/* https://bugzilla.kernel.org/show_bug.cgi?id=15573 */
{ "C300-CTFDDAC128MAG", "0001", ATA_HORKAGE_NONCQ, },
+ /* Some Sandisk SSDs lock up hard with NCQ enabled. Reported on
+ SD7SN6S256G and SD8SN8U256G */
+ { "SanDisk SD[78]SN*G", NULL, ATA_HORKAGE_NONCQ, },
+
/* devices which puke on READ_NATIVE_MAX */
{ "HDS724040KLSA80", "KFAOA20N", ATA_HORKAGE_BROKEN_HPA, },
{ "WDC WD3200JD-00KLB0", "WD-WCAMR1130137", ATA_HORKAGE_BROKEN_HPA },
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 0550c76..9bdc1867 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -174,8 +174,8 @@
{ }
#endif /* CONFIG_PM */
-static void __ata_ehi_pushv_desc(struct ata_eh_info *ehi, const char *fmt,
- va_list args)
+static __printf(2, 0) void __ata_ehi_pushv_desc(struct ata_eh_info *ehi,
+ const char *fmt, va_list args)
{
ehi->desc_len += vscnprintf(ehi->desc + ehi->desc_len,
ATA_EH_DESC_LEN - ehi->desc_len,
diff --git a/drivers/ata/libata-zpodd.c b/drivers/ata/libata-zpodd.c
index f3a65a3..0ad96c6 100644
--- a/drivers/ata/libata-zpodd.c
+++ b/drivers/ata/libata-zpodd.c
@@ -34,7 +34,7 @@
static int eject_tray(struct ata_device *dev)
{
struct ata_taskfile tf;
- const char cdb[] = { GPCMD_START_STOP_UNIT,
+ static const char cdb[ATAPI_CDB_LEN] = { GPCMD_START_STOP_UNIT,
0, 0, 0,
0x02, /* LoEj */
0, 0, 0, 0, 0, 0, 0,
@@ -55,7 +55,7 @@
unsigned int ret;
struct rm_feature_desc *desc = (void *)(buf + 8);
struct ata_taskfile tf;
- char cdb[] = { GPCMD_GET_CONFIGURATION,
+ static const char cdb[] = { GPCMD_GET_CONFIGURATION,
2, /* only 1 feature descriptor requested */
0, 3, /* 3, removable medium feature */
0, 0, 0,/* reserved */
diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c
index 969c3c2..9b81309 100644
--- a/drivers/atm/zatm.c
+++ b/drivers/atm/zatm.c
@@ -1148,8 +1148,8 @@
}
-static unsigned char eprom_try_esi(struct atm_dev *dev, unsigned short cmd,
- int offset, int swap)
+static int eprom_try_esi(struct atm_dev *dev, unsigned short cmd, int offset,
+ int swap)
{
unsigned char buf[ZEPROM_SIZE];
struct zatm_dev *zatm_dev;
diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c
index 3b7c9f1..9c981f6 100644
--- a/drivers/block/paride/pcd.c
+++ b/drivers/block/paride/pcd.c
@@ -229,6 +229,8 @@
struct pcd_unit *cd = bdev->bd_disk->private_data;
int ret;
+ check_disk_change(bdev);
+
mutex_lock(&pcd_mutex);
ret = cdrom_open(&cd->info, bdev, mode);
mutex_unlock(&pcd_mutex);
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index 3922ce8..998991a 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -1153,9 +1153,6 @@
cd_dbg(CD_OPEN, "entering cdrom_open\n");
- /* open is event synchronization point, check events first */
- check_disk_change(bdev);
-
/* if this was a O_NONBLOCK open and we should honor the flags,
* do a quick open without drive/disc integrity checks. */
cdi->use_count++;
diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c
index 584bc31..e2808fe 100644
--- a/drivers/cdrom/gdrom.c
+++ b/drivers/cdrom/gdrom.c
@@ -497,6 +497,9 @@
static int gdrom_bdops_open(struct block_device *bdev, fmode_t mode)
{
int ret;
+
+ check_disk_change(bdev);
+
mutex_lock(&gdrom_mutex);
ret = cdrom_open(gd.cd_info, bdev, mode);
mutex_unlock(&gdrom_mutex);
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index 4977b14..6cf644b 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -1758,6 +1758,31 @@
static void fastrpc_mmap_add(struct fastrpc_mmap *map);
+static inline void get_fastrpc_ioctl_mmap_64(
+ struct fastrpc_ioctl_mmap_64 *mmap64,
+ struct fastrpc_ioctl_mmap *immap)
+{
+ immap->fd = mmap64->fd;
+ immap->flags = mmap64->flags;
+ immap->vaddrin = (uintptr_t)mmap64->vaddrin;
+ immap->size = mmap64->size;
+}
+
+static inline void put_fastrpc_ioctl_mmap_64(
+ struct fastrpc_ioctl_mmap_64 *mmap64,
+ struct fastrpc_ioctl_mmap *immap)
+{
+ mmap64->vaddrout = (uint64_t)immap->vaddrout;
+}
+
+static inline void get_fastrpc_ioctl_munmap_64(
+ struct fastrpc_ioctl_munmap_64 *munmap64,
+ struct fastrpc_ioctl_munmap *imunmap)
+{
+ imunmap->vaddrout = (uintptr_t)munmap64->vaddrout;
+ imunmap->size = munmap64->size;
+}
+
static int fastrpc_internal_munmap(struct fastrpc_file *fl,
struct fastrpc_ioctl_munmap *ud)
{
@@ -2203,9 +2228,15 @@
union {
struct fastrpc_ioctl_invoke_fd invokefd;
struct fastrpc_ioctl_mmap mmap;
+ struct fastrpc_ioctl_mmap_64 mmap64;
struct fastrpc_ioctl_munmap munmap;
+ struct fastrpc_ioctl_munmap_64 munmap64;
struct fastrpc_ioctl_init init;
} p;
+ union {
+ struct fastrpc_ioctl_mmap mmap;
+ struct fastrpc_ioctl_munmap munmap;
+ } i;
void *param = (char *)ioctl_param;
struct fastrpc_file *fl = (struct fastrpc_file *)file->private_data;
int size = 0, err = 0;
@@ -2248,24 +2279,27 @@
goto bail;
break;
case FASTRPC_IOCTL_MMAP_64:
- K_COPY_FROM_USER(err, 0, &p.mmap, param,
- sizeof(p.mmap));
+ K_COPY_FROM_USER(err, 0, &p.mmap64, param,
+ sizeof(p.mmap64));
if (err)
goto bail;
- VERIFY(err, 0 == (err = fastrpc_internal_mmap(fl, &p.mmap)));
+ get_fastrpc_ioctl_mmap_64(&p.mmap64, &i.mmap);
+ VERIFY(err, 0 == (err = fastrpc_internal_mmap(fl, &i.mmap)));
if (err)
goto bail;
- K_COPY_TO_USER(err, 0, param, &p.mmap, sizeof(p.mmap));
+ put_fastrpc_ioctl_mmap_64(&p.mmap64, &i.mmap);
+ K_COPY_TO_USER(err, 0, param, &p.mmap64, sizeof(p.mmap64));
if (err)
goto bail;
break;
case FASTRPC_IOCTL_MUNMAP_64:
- K_COPY_FROM_USER(err, 0, &p.munmap, param,
- sizeof(p.munmap));
+ K_COPY_FROM_USER(err, 0, &p.munmap64, param,
+ sizeof(p.munmap64));
if (err)
goto bail;
+ get_fastrpc_ioctl_munmap_64(&p.munmap64, &i.munmap);
VERIFY(err, 0 == (err = fastrpc_internal_munmap(fl,
- &p.munmap)));
+ &i.munmap)));
if (err)
goto bail;
break;
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
index a56ee9b..a5a0e13 100644
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -196,7 +196,7 @@
return 0;
}
-int uninorth_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
+static int uninorth_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
{
size_t i;
u32 *gp;
@@ -467,7 +467,7 @@
return 0;
}
-void null_cache_flush(void)
+static void null_cache_flush(void)
{
mb();
}
diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c
index 62b6e22..7c4ed8e 100644
--- a/drivers/char/diag/diag_masks.c
+++ b/drivers/char/diag/diag_masks.c
@@ -142,6 +142,9 @@
mutex_lock(&mask_info->lock);
for (i = 0; i < MAX_EQUIP_ID; i++, mask++) {
+ if (!mask->ptr)
+ continue;
+
if (equip_id != i && equip_id != ALL_EQUIP_ID)
continue;
@@ -168,10 +171,11 @@
}
mask_info->update_buf = temp;
mask_info->update_buf_len = header_len + mask_size;
+ buf = temp;
}
memcpy(buf, &ctrl_pkt, header_len);
- if (mask_size > 0)
+ if (mask_size > 0 && mask_size <= LOG_MASK_SIZE)
memcpy(buf + header_len, mask->ptr, mask_size);
mutex_unlock(&mask->lock);
@@ -255,9 +259,16 @@
} else {
mask_info->update_buf = temp;
mask_info->update_buf_len = temp_len;
+ buf = temp;
}
}
- memcpy(buf + sizeof(header), mask_info->ptr, num_bytes);
+ if (num_bytes > 0 && num_bytes < mask_info->mask_len)
+ memcpy(buf + sizeof(header), mask_info->ptr, num_bytes);
+ else {
+ pr_err("diag: num_bytes(%d) is not satisfying length condition\n",
+ num_bytes);
+ goto err;
+ }
write_len += num_bytes;
break;
default:
@@ -285,11 +296,12 @@
int temp_len = 0;
uint8_t *buf = NULL;
uint8_t *temp = NULL;
+ uint8_t msg_mask_tbl_count_local = 0;
uint32_t mask_size = 0;
struct diag_mask_info *mask_info = NULL;
struct diag_msg_mask_t *mask = NULL;
struct diag_ctrl_msg_mask header;
- uint8_t msg_mask_tbl_count_local;
+ struct diag_md_session_t *md_session_info = NULL;
if (peripheral >= NUM_PERIPHERALS)
return;
@@ -301,10 +313,11 @@
return;
}
- if (driver->md_session_mask != 0 &&
- (driver->md_session_mask & MD_PERIPHERAL_MASK(peripheral)))
+ if ((driver->md_session_mask != 0) &&
+ (driver->md_session_mask & MD_PERIPHERAL_MASK(peripheral))) {
+ md_session_info = driver->md_session_map[peripheral];
mask_info = driver->md_session_map[peripheral]->msg_mask;
- else
+ } else
mask_info = &msg_mask;
if (!mask_info)
@@ -317,7 +330,10 @@
return;
}
buf = mask_info->update_buf;
- msg_mask_tbl_count_local = driver->msg_mask_tbl_count;
+ if (md_session_info)
+ msg_mask_tbl_count_local = md_session_info->msg_mask_tbl_count;
+ else
+ msg_mask_tbl_count_local = driver->msg_mask_tbl_count;
mutex_unlock(&driver->msg_mask_lock);
mutex_lock(&mask_info->lock);
switch (mask_info->status) {
@@ -336,6 +352,8 @@
}
for (i = 0; i < msg_mask_tbl_count_local; i++, mask++) {
+ if (!mask->ptr)
+ continue;
mutex_lock(&driver->msg_mask_lock);
if (((mask->ssid_first > first) ||
(mask->ssid_last_tools < last)) && first != ALL_SSID) {
@@ -360,6 +378,7 @@
} else {
mask_info->update_buf = temp;
mask_info->update_buf_len = temp_len;
+ buf = temp;
pr_debug("diag: In %s, successfully reallocated msg_mask update buffer to len: %d\n",
__func__, mask_info->update_buf_len);
}
@@ -487,6 +506,7 @@
{
int i;
int write_len = 0;
+ uint8_t msg_mask_tbl_count = 0;
struct diag_msg_mask_t *mask_ptr = NULL;
struct diag_msg_ssid_query_t rsp;
struct diag_ssid_range_t ssid_range;
@@ -516,15 +536,17 @@
return 0;
}
mutex_lock(&driver->msg_mask_lock);
+ msg_mask_tbl_count = (info) ? info->msg_mask_tbl_count :
+ driver->msg_mask_tbl_count;
rsp.cmd_code = DIAG_CMD_MSG_CONFIG;
rsp.sub_cmd = DIAG_CMD_OP_GET_SSID_RANGE;
rsp.status = MSG_STATUS_SUCCESS;
rsp.padding = 0;
- rsp.count = driver->msg_mask_tbl_count;
+ rsp.count = msg_mask_tbl_count;
memcpy(dest_buf, &rsp, sizeof(rsp));
write_len += sizeof(rsp);
mask_ptr = (struct diag_msg_mask_t *)mask_info->ptr;
- for (i = 0; i < driver->msg_mask_tbl_count; i++, mask_ptr++) {
+ for (i = 0; i < msg_mask_tbl_count; i++, mask_ptr++) {
if (write_len + sizeof(ssid_range) > dest_len) {
pr_err("diag: In %s, Truncating response due to size limitations of rsp buffer\n",
__func__);
@@ -570,6 +592,8 @@
rsp.padding = 0;
build_mask = (struct diag_msg_mask_t *)msg_bt_mask.ptr;
for (i = 0; i < driver->bt_msg_mask_tbl_count; i++, build_mask++) {
+ if (!build_mask->ptr)
+ continue;
if (build_mask->ssid_first != req->ssid_first)
continue;
num_entries = req->ssid_last - req->ssid_first + 1;
@@ -601,6 +625,7 @@
int i;
int write_len = 0;
uint32_t mask_size = 0;
+ uint8_t msg_mask_tbl_count = 0;
struct diag_msg_mask_t *mask = NULL;
struct diag_build_mask_req_t *req = NULL;
struct diag_msg_build_mask_t rsp;
@@ -631,6 +656,8 @@
}
mutex_lock(&driver->msg_mask_lock);
+ msg_mask_tbl_count = (info) ? info->msg_mask_tbl_count :
+ driver->msg_mask_tbl_count;
req = (struct diag_build_mask_req_t *)src_buf;
rsp.cmd_code = DIAG_CMD_MSG_CONFIG;
rsp.sub_cmd = DIAG_CMD_OP_GET_MSG_MASK;
@@ -646,7 +673,9 @@
mutex_unlock(&driver->md_session_lock);
return -EINVAL;
}
- for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
+ for (i = 0; i < msg_mask_tbl_count; i++, mask++) {
+ if (!mask->ptr)
+ continue;
if ((req->ssid_first < mask->ssid_first) ||
(req->ssid_first > mask->ssid_last_tools)) {
continue;
@@ -683,6 +712,7 @@
struct diag_msg_mask_t *mask_next = NULL;
uint32_t *temp = NULL;
struct diag_md_session_t *info = NULL;
+ uint8_t msg_mask_tbl_count = 0;
mutex_lock(&driver->md_session_lock);
info = diag_md_session_get_pid(pid);
@@ -715,8 +745,12 @@
mutex_unlock(&driver->md_session_lock);
return -EINVAL;
}
- for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
- if (i < (driver->msg_mask_tbl_count - 1)) {
+ msg_mask_tbl_count = (info) ? info->msg_mask_tbl_count :
+ driver->msg_mask_tbl_count;
+ for (i = 0; i < msg_mask_tbl_count; i++, mask++) {
+ if (!mask->ptr)
+ continue;
+ if (i < (msg_mask_tbl_count - 1)) {
mask_next = mask;
mask_next++;
} else
@@ -818,6 +852,7 @@
struct diag_msg_mask_t *mask = NULL;
struct diag_mask_info *mask_info = NULL;
struct diag_md_session_t *info = NULL;
+ uint8_t msg_mask_tbl_count = 0;
mutex_lock(&driver->md_session_lock);
info = diag_md_session_get_pid(pid);
@@ -852,13 +887,17 @@
mutex_unlock(&driver->md_session_lock);
return -EINVAL;
}
+ msg_mask_tbl_count = (info) ? info->msg_mask_tbl_count :
+ driver->msg_mask_tbl_count;
mask_info->status = (req->rt_mask) ? DIAG_CTRL_MASK_ALL_ENABLED :
DIAG_CTRL_MASK_ALL_DISABLED;
- for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
- mutex_lock(&mask->lock);
- memset(mask->ptr, req->rt_mask,
- mask->range * sizeof(uint32_t));
- mutex_unlock(&mask->lock);
+ for (i = 0; i < msg_mask_tbl_count; i++, mask++) {
+ if (mask && mask->ptr) {
+ mutex_lock(&mask->lock);
+ memset(mask->ptr, req->rt_mask,
+ mask->range * sizeof(uint32_t));
+ mutex_unlock(&mask->lock);
+ }
}
mutex_unlock(&driver->msg_mask_lock);
mutex_unlock(&mask_info->lock);
@@ -1251,6 +1290,8 @@
mutex_lock(&mask_info->lock);
for (i = 0; i < MAX_EQUIP_ID && !status; i++, mask++) {
+ if (!mask || !mask->ptr)
+ continue;
if (mask->equip_id != req->equip_id)
continue;
mutex_lock(&mask->lock);
@@ -1371,9 +1412,11 @@
return -EINVAL;
}
for (i = 0; i < MAX_EQUIP_ID; i++, mask++) {
- mutex_lock(&mask->lock);
- memset(mask->ptr, 0, mask->range);
- mutex_unlock(&mask->lock);
+ if (mask && mask->ptr) {
+ mutex_lock(&mask->lock);
+ memset(mask->ptr, 0, mask->range);
+ mutex_unlock(&mask->lock);
+ }
}
mask_info->status = DIAG_CTRL_MASK_ALL_DISABLED;
mutex_unlock(&driver->md_session_lock);
@@ -1436,7 +1479,8 @@
mutex_lock(&msg_mask.lock);
mutex_lock(&driver->msg_mask_lock);
driver->msg_mask_tbl_count = MSG_MASK_TBL_CNT;
- for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
+ for (i = 0; (i < driver->msg_mask_tbl_count) && mask;
+ i++, mask++) {
range.ssid_first = msg_mask_tbl[i].ssid_first;
range.ssid_last = msg_mask_tbl[i].ssid_last;
err = diag_create_msg_mask_table_entry(mask, &range);
@@ -1461,7 +1505,8 @@
mutex_lock(&driver->msg_mask_lock);
driver->bt_msg_mask_tbl_count = MSG_MASK_TBL_CNT;
build_mask = (struct diag_msg_mask_t *)msg_bt_mask.ptr;
- for (i = 0; i < driver->bt_msg_mask_tbl_count; i++, build_mask++) {
+ for (i = 0; (i < driver->bt_msg_mask_tbl_count) && build_mask;
+ i++, build_mask++) {
range.ssid_first = msg_mask_tbl[i].ssid_first;
range.ssid_last = msg_mask_tbl[i].ssid_last;
err = diag_create_msg_mask_table_entry(build_mask, &range);
@@ -1584,7 +1629,7 @@
mutex_lock(&log_mask.lock);
mask = (struct diag_log_mask_t *)(log_mask.ptr);
- for (i = 0; i < MAX_EQUIP_ID; i++, mask++) {
+ for (i = 0; (i < MAX_EQUIP_ID) && mask; i++, mask++) {
mask->equip_id = i;
mask->num_items = LOG_GET_ITEM_NUM(log_code_last_tbl[i]);
mask->num_items_tools = mask->num_items;
@@ -1628,7 +1673,6 @@
}
kmemleak_not_leak(mask_info->update_buf);
}
- mutex_init(&mask_info->lock);
return 0;
}
@@ -1652,9 +1696,10 @@
struct diag_log_mask_t *src_mask = NULL;
struct diag_log_mask_t *dest_mask = NULL;
- if (!src)
+ if (!src || !dest)
return -EINVAL;
+ mutex_init(&dest->lock);
err = __diag_mask_init(dest, LOG_MASK_SIZE, APPS_BUF_SIZE);
if (err)
return err;
@@ -1717,9 +1762,11 @@
int err = 0;
int i;
+ mutex_init(&msg_mask.lock);
err = __diag_mask_init(&msg_mask, MSG_MASK_SIZE, APPS_BUF_SIZE);
if (err)
return err;
+
err = diag_create_msg_mask_table();
if (err) {
pr_err("diag: Unable to create msg masks, err: %d\n", err);
@@ -1734,7 +1781,8 @@
return 0;
}
-int diag_msg_mask_copy(struct diag_mask_info *dest, struct diag_mask_info *src)
+int diag_msg_mask_copy(struct diag_md_session_t *new_session,
+ struct diag_mask_info *dest, struct diag_mask_info *src)
{
int i;
int err = 0;
@@ -1745,17 +1793,25 @@
if (!src || !dest)
return -EINVAL;
- err = __diag_mask_init(dest, MSG_MASK_SIZE, APPS_BUF_SIZE);
- if (err)
- return err;
+ mutex_init(&dest->lock);
mutex_lock(&dest->lock);
mutex_lock(&driver->msg_mask_lock);
+ new_session->msg_mask_tbl_count =
+ driver->msg_mask_tbl_count;
+ err = __diag_mask_init(dest,
+ (new_session->msg_mask_tbl_count *
+ sizeof(struct diag_msg_mask_t)), APPS_BUF_SIZE);
+ if (err) {
+ mutex_unlock(&driver->msg_mask_lock);
+ mutex_unlock(&dest->lock);
+ return err;
+ }
src_mask = (struct diag_msg_mask_t *)src->ptr;
dest_mask = (struct diag_msg_mask_t *)dest->ptr;
dest->mask_len = src->mask_len;
dest->status = src->status;
- for (i = 0; i < driver->msg_mask_tbl_count; i++) {
+ for (i = 0; i < new_session->msg_mask_tbl_count; i++) {
range.ssid_first = src_mask->ssid_first;
range.ssid_last = src_mask->ssid_last;
err = diag_create_msg_mask_table_entry(dest_mask, &range);
@@ -1771,10 +1827,12 @@
return err;
}
-void diag_msg_mask_free(struct diag_mask_info *mask_info)
+void diag_msg_mask_free(struct diag_mask_info *mask_info,
+ struct diag_md_session_t *session_info)
{
int i;
struct diag_msg_mask_t *mask = NULL;
+ uint8_t msg_mask_tbl_count = 0;
if (!mask_info || !mask_info->ptr)
return;
@@ -1788,7 +1846,10 @@
mutex_unlock(&mask_info->lock);
return;
}
- for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
+ msg_mask_tbl_count = (session_info) ?
+ session_info->msg_mask_tbl_count :
+ driver->msg_mask_tbl_count;
+ for (i = 0; i < msg_mask_tbl_count; i++, mask++) {
kfree(mask->ptr);
mask->ptr = NULL;
}
@@ -1819,6 +1880,7 @@
int err = 0;
/* There is no need for update buffer for Build Time masks */
+ mutex_init(&msg_bt_mask.lock);
err = __diag_mask_init(&msg_bt_mask, MSG_MASK_SIZE, 0);
if (err)
return err;
@@ -1852,6 +1914,7 @@
int err = 0;
int i;
+ mutex_init(&log_mask.lock);
err = __diag_mask_init(&log_mask, LOG_MASK_SIZE, APPS_BUF_SIZE);
if (err)
return err;
@@ -1886,6 +1949,7 @@
int err = 0;
int i;
+ mutex_init(&event_mask.lock);
err = __diag_mask_init(&event_mask, EVENT_MASK_SIZE, APPS_BUF_SIZE);
if (err)
return err;
@@ -1907,6 +1971,7 @@
if (!src || !dest)
return -EINVAL;
+ mutex_init(&dest->lock);
err = __diag_mask_init(dest, EVENT_MASK_SIZE, APPS_BUF_SIZE);
if (err)
return err;
@@ -1946,6 +2011,7 @@
struct diag_mask_info *mask_info = NULL;
struct diag_msg_mask_t *mask = NULL;
unsigned char *ptr = NULL;
+ uint8_t msg_mask_tbl_count = 0;
if (!buf || count == 0)
return -EINVAL;
@@ -1978,7 +2044,11 @@
mutex_unlock(&mask_info->lock);
return -EINVAL;
}
- for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
+ msg_mask_tbl_count = (info) ? info->msg_mask_tbl_count :
+ driver->msg_mask_tbl_count;
+ for (i = 0; i < msg_mask_tbl_count; i++, mask++) {
+ if (!mask->ptr)
+ continue;
ptr = mask_info->update_buf;
len = 0;
mutex_lock(&mask->lock);
@@ -2053,6 +2123,8 @@
return -EINVAL;
}
for (i = 0; i < MAX_EQUIP_ID; i++, mask++) {
+ if (!mask->ptr)
+ continue;
ptr = mask_info->update_buf;
len = 0;
mutex_lock(&mask->lock);
diff --git a/drivers/char/diag/diag_masks.h b/drivers/char/diag/diag_masks.h
index 6edeee9..a736ff2 100644
--- a/drivers/char/diag/diag_masks.h
+++ b/drivers/char/diag/diag_masks.h
@@ -160,12 +160,13 @@
void diag_masks_exit(void);
int diag_log_mask_copy(struct diag_mask_info *dest,
struct diag_mask_info *src);
-int diag_msg_mask_copy(struct diag_mask_info *dest,
- struct diag_mask_info *src);
+int diag_msg_mask_copy(struct diag_md_session_t *new_session,
+ struct diag_mask_info *dest, struct diag_mask_info *src);
int diag_event_mask_copy(struct diag_mask_info *dest,
struct diag_mask_info *src);
void diag_log_mask_free(struct diag_mask_info *mask_info);
-void diag_msg_mask_free(struct diag_mask_info *mask_info);
+void diag_msg_mask_free(struct diag_mask_info *mask_info,
+ struct diag_md_session_t *session_info);
void diag_event_mask_free(struct diag_mask_info *mask_info);
int diag_process_apps_masks(unsigned char *buf, int len, int pid);
void diag_send_updates_peripheral(uint8_t peripheral);
diff --git a/drivers/char/diag/diag_memorydevice.c b/drivers/char/diag/diag_memorydevice.c
index aebeba8..51b937f 100644
--- a/drivers/char/diag/diag_memorydevice.c
+++ b/drivers/char/diag/diag_memorydevice.c
@@ -192,6 +192,7 @@
}
found = 0;
+ mutex_lock(&driver->diagchar_mutex);
for (i = 0; i < driver->num_clients && !found; i++) {
if ((driver->client_map[i].pid != pid) ||
(driver->client_map[i].pid == 0))
@@ -202,6 +203,7 @@
pr_debug("diag: wake up logging process\n");
wake_up_interruptible(&driver->wait_q);
}
+ mutex_unlock(&driver->diagchar_mutex);
if (!found)
return -EINVAL;
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index c5e642b..7852ea7 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -411,6 +411,7 @@
int pid;
int peripheral_mask;
uint8_t hdlc_disabled;
+ uint8_t msg_mask_tbl_count;
struct timer_list hdlc_reset_timer;
struct diag_mask_info *msg_mask;
struct diag_mask_info *log_mask;
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index e505fdf..75d425f 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -1253,7 +1253,8 @@
diag_log_mask_free(session_info->log_mask);
kfree(session_info->log_mask);
session_info->log_mask = NULL;
- diag_msg_mask_free(session_info->msg_mask);
+ diag_msg_mask_free(session_info->msg_mask,
+ session_info);
kfree(session_info->msg_mask);
session_info->msg_mask = NULL;
diag_event_mask_free(session_info->event_mask);
@@ -1326,7 +1327,9 @@
"return value of event copy. err %d\n", err);
goto fail_peripheral;
}
- err = diag_msg_mask_copy(new_session->msg_mask, &msg_mask);
+ new_session->msg_mask_tbl_count = 0;
+ err = diag_msg_mask_copy(new_session, new_session->msg_mask,
+ &msg_mask);
if (err) {
DIAG_LOG(DIAG_DEBUG_USERSPACE,
"return value of msg copy. err %d\n", err);
@@ -1362,7 +1365,8 @@
diag_event_mask_free(new_session->event_mask);
kfree(new_session->event_mask);
new_session->event_mask = NULL;
- diag_msg_mask_free(new_session->msg_mask);
+ diag_msg_mask_free(new_session->msg_mask,
+ new_session);
kfree(new_session->msg_mask);
new_session->msg_mask = NULL;
kfree(new_session);
@@ -1390,7 +1394,8 @@
diag_log_mask_free(session_info->log_mask);
kfree(session_info->log_mask);
session_info->log_mask = NULL;
- diag_msg_mask_free(session_info->msg_mask);
+ diag_msg_mask_free(session_info->msg_mask,
+ session_info);
kfree(session_info->msg_mask);
session_info->msg_mask = NULL;
diag_event_mask_free(session_info->event_mask);
diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c
index 124dde7..c8f3e8e 100644
--- a/drivers/char/diag/diagfwd_cntl.c
+++ b/drivers/char/diag/diagfwd_cntl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -404,8 +404,8 @@
header = (struct diag_ctrl_last_event_report *)ptr;
event_size = ((header->event_last_id / 8) + 1);
if (event_size >= driver->event_mask_size) {
- pr_debug("diag: In %s, receiving event mask size more that Apps can handle\n",
- __func__);
+ DIAG_LOG(DIAG_DEBUG_MASKS,
+ "diag: receiving event mask size more that Apps can handle\n");
temp = krealloc(driver->event_mask->ptr, event_size,
GFP_KERNEL);
if (!temp) {
@@ -519,6 +519,10 @@
mask_ptr = (struct diag_msg_mask_t *)msg_mask.ptr;
found = 0;
for (j = 0; j < driver->msg_mask_tbl_count; j++, mask_ptr++) {
+ if (!mask_ptr->ptr || !ssid_range) {
+ found = 1;
+ break;
+ }
if (mask_ptr->ssid_first != ssid_range->ssid_first)
continue;
mutex_lock(&mask_ptr->lock);
@@ -537,6 +541,8 @@
new_size = (driver->msg_mask_tbl_count + 1) *
sizeof(struct diag_msg_mask_t);
+ DIAG_LOG(DIAG_DEBUG_MASKS,
+ "diag: receiving msg mask size more that Apps can handle\n");
temp = krealloc(msg_mask.ptr, new_size, GFP_KERNEL);
if (!temp) {
pr_err("diag: In %s, Unable to add new ssid table to msg mask, ssid first: %d, last: %d\n",
@@ -545,6 +551,7 @@
continue;
}
msg_mask.ptr = temp;
+ mask_ptr = (struct diag_msg_mask_t *)msg_mask.ptr;
err = diag_create_msg_mask_table_entry(mask_ptr, ssid_range);
if (err) {
pr_err("diag: In %s, Unable to create a new msg mask table entry, first: %d last: %d err: %d\n",
@@ -584,6 +591,10 @@
num_items = range->ssid_last - range->ssid_first + 1;
for (i = 0; i < driver->bt_msg_mask_tbl_count; i++, build_mask++) {
+ if (!build_mask->ptr) {
+ found = 1;
+ break;
+ }
if (build_mask->ssid_first != range->ssid_first)
continue;
found = 1;
@@ -594,7 +605,8 @@
__func__);
}
dest_ptr = build_mask->ptr;
- for (j = 0; j < build_mask->range; j++, mask_ptr++, dest_ptr++)
+ for (j = 0; (j < build_mask->range) && mask_ptr && dest_ptr;
+ j++, mask_ptr++, dest_ptr++)
*(uint32_t *)dest_ptr |= *mask_ptr;
mutex_unlock(&build_mask->lock);
break;
@@ -602,8 +614,12 @@
if (found)
goto end;
+
new_size = (driver->bt_msg_mask_tbl_count + 1) *
sizeof(struct diag_msg_mask_t);
+ DIAG_LOG(DIAG_DEBUG_MASKS,
+ "diag: receiving build time mask size more that Apps can handle\n");
+
temp = krealloc(driver->build_time_mask->ptr, new_size, GFP_KERNEL);
if (!temp) {
pr_err("diag: In %s, unable to create a new entry for build time mask\n",
@@ -611,6 +627,7 @@
goto end;
}
driver->build_time_mask->ptr = temp;
+ build_mask = (struct diag_msg_mask_t *)driver->build_time_mask->ptr;
err = diag_create_msg_mask_table_entry(build_mask, range);
if (err) {
pr_err("diag: In %s, Unable to create a new msg mask table entry, err: %d\n",
diff --git a/drivers/char/diag/diagfwd_peripheral.c b/drivers/char/diag/diagfwd_peripheral.c
index 856e00f..3541b34 100644
--- a/drivers/char/diag/diagfwd_peripheral.c
+++ b/drivers/char/diag/diagfwd_peripheral.c
@@ -307,24 +307,26 @@
}
}
+ mutex_unlock(&fwd_info->data_mutex);
+ mutex_unlock(&driver->hdlc_disable_mutex);
+
if (write_len > 0) {
err = diag_mux_write(DIAG_LOCAL_PROC, write_buf, write_len,
temp_buf->ctxt);
if (err) {
pr_err_ratelimited("diag: In %s, unable to write to mux error: %d\n",
__func__, err);
- goto end;
+ goto end_write;
}
}
- mutex_unlock(&fwd_info->data_mutex);
- mutex_unlock(&driver->hdlc_disable_mutex);
diagfwd_queue_read(fwd_info);
return;
end:
- diag_ws_release();
mutex_unlock(&fwd_info->data_mutex);
mutex_unlock(&driver->hdlc_disable_mutex);
+end_write:
+ diag_ws_release();
if (temp_buf) {
diagfwd_write_done(fwd_info->peripheral, fwd_info->type,
GET_BUF_NUM(temp_buf->ctxt));
diff --git a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c
index 61e7161..84b5c74 100644
--- a/drivers/char/ipmi/ipmi_bt_sm.c
+++ b/drivers/char/ipmi/ipmi_bt_sm.c
@@ -522,11 +522,12 @@
if (status & BT_H_BUSY) /* clear a leftover H_BUSY */
BT_CONTROL(BT_H_BUSY);
+ bt->timeout = bt->BT_CAP_req2rsp;
+
/* Read BT capabilities if it hasn't been done yet */
if (!bt->BT_CAP_outreqs)
BT_STATE_CHANGE(BT_STATE_CAPABILITIES_BEGIN,
SI_SM_CALL_WITHOUT_DELAY);
- bt->timeout = bt->BT_CAP_req2rsp;
BT_SI_SM_RETURN(SI_SM_IDLE);
case BT_STATE_XACTION_START:
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 5480deb..a6f1ba7 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -1398,7 +1398,6 @@
{
char debugfs_name[16];
struct port *port;
- struct port_buffer *buf;
dev_t devt;
unsigned int nr_added_bufs;
int err;
@@ -1509,8 +1508,6 @@
return 0;
free_inbufs:
- while ((buf = virtqueue_detach_unused_buf(port->in_vq)))
- free_buf(buf, true);
free_device:
device_destroy(pdrvdata.class, port->dev->devt);
free_cdev:
@@ -1535,34 +1532,14 @@
static void remove_port_data(struct port *port)
{
- struct port_buffer *buf;
-
spin_lock_irq(&port->inbuf_lock);
/* Remove unused data this port might have received. */
discard_port_data(port);
spin_unlock_irq(&port->inbuf_lock);
- /* Remove buffers we queued up for the Host to send us data in. */
- do {
- spin_lock_irq(&port->inbuf_lock);
- buf = virtqueue_detach_unused_buf(port->in_vq);
- spin_unlock_irq(&port->inbuf_lock);
- if (buf)
- free_buf(buf, true);
- } while (buf);
-
spin_lock_irq(&port->outvq_lock);
reclaim_consumed_buffers(port);
spin_unlock_irq(&port->outvq_lock);
-
- /* Free pending buffers from the out-queue. */
- do {
- spin_lock_irq(&port->outvq_lock);
- buf = virtqueue_detach_unused_buf(port->out_vq);
- spin_unlock_irq(&port->outvq_lock);
- if (buf)
- free_buf(buf, true);
- } while (buf);
}
/*
@@ -1783,13 +1760,24 @@
spin_unlock(&portdev->c_ivq_lock);
}
+static void flush_bufs(struct virtqueue *vq, bool can_sleep)
+{
+ struct port_buffer *buf;
+ unsigned int len;
+
+ while ((buf = virtqueue_get_buf(vq, &len)))
+ free_buf(buf, can_sleep);
+}
+
static void out_intr(struct virtqueue *vq)
{
struct port *port;
port = find_port_by_vq(vq->vdev->priv, vq);
- if (!port)
+ if (!port) {
+ flush_bufs(vq, false);
return;
+ }
wake_up_interruptible(&port->waitqueue);
}
@@ -1800,8 +1788,10 @@
unsigned long flags;
port = find_port_by_vq(vq->vdev->priv, vq);
- if (!port)
+ if (!port) {
+ flush_bufs(vq, false);
return;
+ }
spin_lock_irqsave(&port->inbuf_lock, flags);
port->inbuf = get_inbuf(port);
@@ -1976,6 +1966,15 @@
static void remove_vqs(struct ports_device *portdev)
{
+ struct virtqueue *vq;
+
+ virtio_device_for_each_vq(portdev->vdev, vq) {
+ struct port_buffer *buf;
+
+ flush_bufs(vq, true);
+ while ((buf = virtqueue_detach_unused_buf(vq)))
+ free_buf(buf, true);
+ }
portdev->vdev->config->del_vqs(portdev->vdev);
kfree(portdev->in_vqs);
kfree(portdev->out_vqs);
diff --git a/drivers/clk/msm/Makefile b/drivers/clk/msm/Makefile
index 10ea16e..31fc277 100644
--- a/drivers/clk/msm/Makefile
+++ b/drivers/clk/msm/Makefile
@@ -53,3 +53,7 @@
obj-y += gdsc.o
obj-y += mdss/
+
+ifdef CONFIG_ARCH_MDM9607
+KBUILD_CFLAGS += -fno-cse-follow-jumps
+endif
diff --git a/drivers/clk/msm/clock-gcc-mdm9607.c b/drivers/clk/msm/clock-gcc-mdm9607.c
index 826fea0..1157d44 100644
--- a/drivers/clk/msm/clock-gcc-mdm9607.c
+++ b/drivers/clk/msm/clock-gcc-mdm9607.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2016, 2018, The Linux Foundation. All rights reserved.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
@@ -1826,6 +1826,10 @@
return PTR_ERR(vdd_stromer_pll.regulator[0]);
}
+ /* Use use_max_uv for vdd_dig and vdd_stromer_pll */
+ vdd_dig.use_max_uV = true;
+ vdd_stromer_pll.use_max_uV = true;
+
/*Vote for GPLL0 to turn on. Needed by acpuclock. */
regval = readl_relaxed(GCC_REG_BASE(APCS_GPLL_ENA_VOTE));
regval |= BIT(0);
diff --git a/drivers/clk/samsung/clk-exynos3250.c b/drivers/clk/samsung/clk-exynos3250.c
index 6e6cca3..55cab0d 100644
--- a/drivers/clk/samsung/clk-exynos3250.c
+++ b/drivers/clk/samsung/clk-exynos3250.c
@@ -740,7 +740,7 @@
PLL_36XX_RATE(144000000, 96, 2, 3, 0),
PLL_36XX_RATE( 96000000, 128, 2, 4, 0),
PLL_36XX_RATE( 84000000, 112, 2, 4, 0),
- PLL_36XX_RATE( 80000004, 106, 2, 4, 43691),
+ PLL_36XX_RATE( 80000003, 106, 2, 4, 43691),
PLL_36XX_RATE( 73728000, 98, 2, 4, 19923),
PLL_36XX_RATE( 67737598, 270, 3, 5, 62285),
PLL_36XX_RATE( 65535999, 174, 2, 5, 49982),
@@ -776,7 +776,7 @@
PLL_36XX_RATE(148352005, 98, 2, 3, 59070),
PLL_36XX_RATE(108000000, 144, 2, 4, 0),
PLL_36XX_RATE( 74250000, 99, 2, 4, 0),
- PLL_36XX_RATE( 74176002, 98, 3, 4, 59070),
+ PLL_36XX_RATE( 74176002, 98, 2, 4, 59070),
PLL_36XX_RATE( 54054000, 216, 3, 5, 14156),
PLL_36XX_RATE( 54000000, 144, 2, 5, 0),
{ /* sentinel */ }
diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c
index 70ec3d2..b42fbbe 100644
--- a/drivers/clk/samsung/clk-exynos5250.c
+++ b/drivers/clk/samsung/clk-exynos5250.c
@@ -700,13 +700,13 @@
/* sorted in descending order */
/* PLL_36XX_RATE(rate, m, p, s, k) */
PLL_36XX_RATE(192000000, 64, 2, 2, 0),
- PLL_36XX_RATE(180633600, 90, 3, 2, 20762),
+ PLL_36XX_RATE(180633605, 90, 3, 2, 20762),
PLL_36XX_RATE(180000000, 90, 3, 2, 0),
PLL_36XX_RATE(73728000, 98, 2, 4, 19923),
- PLL_36XX_RATE(67737600, 90, 2, 4, 20762),
+ PLL_36XX_RATE(67737602, 90, 2, 4, 20762),
PLL_36XX_RATE(49152000, 98, 3, 4, 19923),
- PLL_36XX_RATE(45158400, 90, 3, 4, 20762),
- PLL_36XX_RATE(32768000, 131, 3, 5, 4719),
+ PLL_36XX_RATE(45158401, 90, 3, 4, 20762),
+ PLL_36XX_RATE(32768001, 131, 3, 5, 4719),
{ },
};
diff --git a/drivers/clk/samsung/clk-exynos5260.c b/drivers/clk/samsung/clk-exynos5260.c
index 2527e39..e4330b7 100644
--- a/drivers/clk/samsung/clk-exynos5260.c
+++ b/drivers/clk/samsung/clk-exynos5260.c
@@ -102,7 +102,7 @@
PLL_36XX_RATE(480000000, 160, 2, 2, 0),
PLL_36XX_RATE(432000000, 144, 2, 2, 0),
PLL_36XX_RATE(400000000, 200, 3, 2, 0),
- PLL_36XX_RATE(394073130, 459, 7, 2, 49282),
+ PLL_36XX_RATE(394073128, 459, 7, 2, 49282),
PLL_36XX_RATE(333000000, 111, 2, 2, 0),
PLL_36XX_RATE(300000000, 100, 2, 2, 0),
PLL_36XX_RATE(266000000, 266, 3, 3, 0),
diff --git a/drivers/clk/samsung/clk-s3c2410.c b/drivers/clk/samsung/clk-s3c2410.c
index 5d2f034..6079247 100644
--- a/drivers/clk/samsung/clk-s3c2410.c
+++ b/drivers/clk/samsung/clk-s3c2410.c
@@ -170,7 +170,7 @@
PLL_35XX_RATE(226000000, 105, 1, 1),
PLL_35XX_RATE(210000000, 132, 2, 1),
/* 2410 common */
- PLL_35XX_RATE(203000000, 161, 3, 1),
+ PLL_35XX_RATE(202800000, 161, 3, 1),
PLL_35XX_RATE(192000000, 88, 1, 1),
PLL_35XX_RATE(186000000, 85, 1, 1),
PLL_35XX_RATE(180000000, 82, 1, 1),
@@ -180,18 +180,18 @@
PLL_35XX_RATE(147000000, 90, 2, 1),
PLL_35XX_RATE(135000000, 82, 2, 1),
PLL_35XX_RATE(124000000, 116, 1, 2),
- PLL_35XX_RATE(118000000, 150, 2, 2),
+ PLL_35XX_RATE(118500000, 150, 2, 2),
PLL_35XX_RATE(113000000, 105, 1, 2),
- PLL_35XX_RATE(101000000, 127, 2, 2),
+ PLL_35XX_RATE(101250000, 127, 2, 2),
PLL_35XX_RATE(90000000, 112, 2, 2),
- PLL_35XX_RATE(85000000, 105, 2, 2),
+ PLL_35XX_RATE(84750000, 105, 2, 2),
PLL_35XX_RATE(79000000, 71, 1, 2),
- PLL_35XX_RATE(68000000, 82, 2, 2),
- PLL_35XX_RATE(56000000, 142, 2, 3),
+ PLL_35XX_RATE(67500000, 82, 2, 2),
+ PLL_35XX_RATE(56250000, 142, 2, 3),
PLL_35XX_RATE(48000000, 120, 2, 3),
- PLL_35XX_RATE(51000000, 161, 3, 3),
+ PLL_35XX_RATE(50700000, 161, 3, 3),
PLL_35XX_RATE(45000000, 82, 1, 3),
- PLL_35XX_RATE(34000000, 82, 2, 3),
+ PLL_35XX_RATE(33750000, 82, 2, 3),
{ /* sentinel */ },
};
diff --git a/drivers/clocksource/fsl_ftm_timer.c b/drivers/clocksource/fsl_ftm_timer.c
index 454227d..de38aca 100644
--- a/drivers/clocksource/fsl_ftm_timer.c
+++ b/drivers/clocksource/fsl_ftm_timer.c
@@ -282,7 +282,7 @@
static unsigned long __init ftm_clk_init(struct device_node *np)
{
- unsigned long freq;
+ long freq;
freq = __ftm_clk_init(np, "ftm-evt-counter-en", "ftm-evt");
if (freq <= 0)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 19a9974..e57139d 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -1516,7 +1516,7 @@
/* Returns 1 if state was updated, 0 otherwise */
static int pl330_update(struct pl330_dmac *pl330)
{
- struct dma_pl330_desc *descdone, *tmp;
+ struct dma_pl330_desc *descdone;
unsigned long flags;
void __iomem *regs;
u32 val;
@@ -1592,7 +1592,9 @@
}
/* Now that we are in no hurry, do the callbacks */
- list_for_each_entry_safe(descdone, tmp, &pl330->req_done, rqd) {
+ while (!list_empty(&pl330->req_done)) {
+ descdone = list_first_entry(&pl330->req_done,
+ struct dma_pl330_desc, rqd);
list_del(&descdone->rqd);
spin_unlock_irqrestore(&pl330->lock, flags);
dma_pl330_rqcb(descdone, PL330_ERR_NONE);
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index f047d7c..437f5f0 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -1137,7 +1137,13 @@
return -ENOMEM;
offset = (void *)&desc->buffer - (void *)desc;
- desc->buffer_size = PAGE_SIZE - offset;
+ /*
+ * Some controllers, like JMicron ones, always issue 0x20-byte DMA reads
+ * for descriptors, even 0x10-byte ones. This can cause page faults when
+ * an IOMMU is in use and the oversized read crosses a page boundary.
+ * Work around this by always leaving at least 0x10 bytes of padding.
+ */
+ desc->buffer_size = PAGE_SIZE - offset - 0x10;
desc->buffer_bus = bus_addr + offset;
desc->used = 0;
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index 29f93bf..d021f52 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -15,7 +15,7 @@
* of and an antecedent to, SMBIOS, which stands for System
* Management BIOS. See further: http://www.dmtf.org/standards
*/
-static const char dmi_empty_string[] = " ";
+static const char dmi_empty_string[] = "";
static u16 __initdata dmi_ver;
/*
@@ -36,25 +36,21 @@
static const char * __init dmi_string_nosave(const struct dmi_header *dm, u8 s)
{
const u8 *bp = ((u8 *) dm) + dm->length;
+ const u8 *nsp;
if (s) {
- s--;
- while (s > 0 && *bp) {
+ while (--s > 0 && *bp)
bp += strlen(bp) + 1;
- s--;
- }
- if (*bp != 0) {
- size_t len = strlen(bp)+1;
- size_t cmp_len = len > 8 ? 8 : len;
-
- if (!memcmp(bp, dmi_empty_string, cmp_len))
- return dmi_empty_string;
+ /* Strings containing only spaces are considered empty */
+ nsp = bp;
+ while (*nsp == ' ')
+ nsp++;
+ if (*nsp != '\0')
return bp;
- }
}
- return "";
+ return dmi_empty_string;
}
static const char * __init dmi_string(const struct dmi_header *dm, u8 s)
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 6b5625e..88ceac0 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -209,6 +209,7 @@
return -ENOMEM;
filp->private_data = priv;
+ filp->f_mode |= FMODE_UNSIGNED_OFFSET;
priv->filp = filp;
priv->uid = current_euid();
priv->pid = get_pid(task_pid(current));
diff --git a/drivers/gpu/drm/exynos/regs-fimc.h b/drivers/gpu/drm/exynos/regs-fimc.h
index 3049613..d7cbe53 100644
--- a/drivers/gpu/drm/exynos/regs-fimc.h
+++ b/drivers/gpu/drm/exynos/regs-fimc.h
@@ -569,7 +569,7 @@
#define EXYNOS_CIIMGEFF_FIN_EMBOSSING (4 << 26)
#define EXYNOS_CIIMGEFF_FIN_SILHOUETTE (5 << 26)
#define EXYNOS_CIIMGEFF_FIN_MASK (7 << 26)
-#define EXYNOS_CIIMGEFF_PAT_CBCR_MASK ((0xff < 13) | (0xff < 0))
+#define EXYNOS_CIIMGEFF_PAT_CBCR_MASK ((0xff << 13) | (0xff << 0))
/* Real input DMA size register */
#define EXYNOS_CIREAL_ISIZE_AUTOLOAD_ENABLE (1 << 31)
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 7f39b8a..de6710f 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -768,6 +768,14 @@
DMI_EXACT_MATCH(DMI_BOARD_NAME, "D525MW"),
},
},
+ {
+ .callback = intel_no_lvds_dmi_callback,
+ .ident = "Radiant P845",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Radiant Systems Inc"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "P845"),
+ },
+ },
{ } /* terminating entry */
};
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
index b8520aa..c993ae2 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016, 2018 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -484,7 +484,7 @@
}
ctrl->hw.base = ptr;
- pr_debug("[%s] map dsi_ctrl registers to %p\n", ctrl->name,
+ pr_debug("[%s] map dsi_ctrl registers to %pK\n", ctrl->name,
ctrl->hw.base);
ptr = msm_ioremap(pdev, "mmss_misc", ctrl->name);
@@ -494,7 +494,7 @@
}
ctrl->hw.mmss_misc_base = ptr;
- pr_debug("[%s] map mmss_misc registers to %p\n", ctrl->name,
+ pr_debug("[%s] map mmss_misc registers to %pK\n", ctrl->name,
ctrl->hw.mmss_misc_base);
return rc;
}
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
index 7a8dd56..1af0a55 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016, 2018 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1469,7 +1469,7 @@
"qcom,bridge-name", &len);
if (!panel->dba_config.bridge_name || len <= 0) {
SDE_ERROR(
- "%s:%d Unable to read bridge_name, data=%p,len=%d\n",
+ "%s:%d Unable to read bridge_name, data=%pK,len=%d\n",
__func__, __LINE__, panel->dba_config.bridge_name, len);
rc = -EINVAL;
goto error;
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c b/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c
index 1ccbbe7..f7a7733 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016, 2018 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -93,7 +93,8 @@
phy->hw.base = ptr;
- pr_debug("[%s] map dsi_phy registers to %p\n", phy->name, phy->hw.base);
+ pr_debug("[%s] map dsi_phy registers to %pK\n",
+ phy->name, phy->hw.base);
return rc;
}
diff --git a/drivers/gpu/drm/msm/edp/edp.c b/drivers/gpu/drm/msm/edp/edp.c
index 0940e84..253e022f 100644
--- a/drivers/gpu/drm/msm/edp/edp.c
+++ b/drivers/gpu/drm/msm/edp/edp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2015, 2018 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -54,7 +54,7 @@
ret = -ENOMEM;
goto fail;
}
- DBG("eDP probed=%p", edp);
+ DBG("eDP probed=%pK", edp);
edp->pdev = pdev;
platform_set_drvdata(pdev, edp);
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 62e3047..63a1de5 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -2,7 +2,7 @@
* Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
*
- * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
@@ -99,7 +99,8 @@
}
if (reglog)
- printk(KERN_DEBUG "IO:region %s %p %08lx\n", dbgname, ptr, size);
+ pr_debug("IO:region %s %pK %08lx\n",
+ dbgname, ptr, size);
return ptr;
}
@@ -107,7 +108,7 @@
void msm_writel(u32 data, void __iomem *addr)
{
if (reglog)
- printk(KERN_DEBUG "IO:W %p %08x\n", addr, data);
+ pr_debug("IO:W %pK %08x\n", addr, data);
writel(data, addr);
}
@@ -115,7 +116,7 @@
{
u32 val = readl(addr);
if (reglog)
- printk(KERN_ERR "IO:R %p %08x\n", addr, val);
+ pr_debug("IO:R %pK %08x\n", addr, val);
return val;
}
@@ -598,7 +599,7 @@
struct msm_kms *kms = priv->kms;
if (!kms)
return -ENXIO;
- DBG("dev=%p, crtc=%u", dev, pipe);
+ DBG("dev=%pK crtc=%u", dev, pipe);
return vblank_ctrl_queue_work(priv, pipe, true);
}
@@ -608,7 +609,7 @@
struct msm_kms *kms = priv->kms;
if (!kms)
return;
- DBG("dev=%p, crtc=%u", dev, pipe);
+ DBG("dev=%pK, crtc=%u", dev, pipe);
vblank_ctrl_queue_work(priv, pipe, false);
}
diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c
index dca4de3..7b1a624 100644
--- a/drivers/gpu/drm/msm/msm_fb.c
+++ b/drivers/gpu/drm/msm/msm_fb.c
@@ -43,7 +43,7 @@
struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb);
int i, n = drm_format_num_planes(fb->pixel_format);
- DBG("destroy: FB ID: %d (%p)", fb->base.id, fb);
+ DBG("destroy: FB ID: %d (%pK)", fb->base.id, fb);
drm_framebuffer_cleanup(fb);
@@ -178,7 +178,7 @@
unsigned int hsub, vsub;
bool is_modified = false;
- DBG("create framebuffer: dev=%p, mode_cmd=%p (%dx%d@%4.4s)",
+ DBG("create framebuffer: dev=%pK, mode_cmd=%pK (%dx%d@%4.4s)",
dev, mode_cmd, mode_cmd->width, mode_cmd->height,
(char *)&mode_cmd->pixel_format);
@@ -261,7 +261,7 @@
goto fail;
}
- DBG("create: FB ID: %d (%p)", fb->base.id, fb);
+ DBG("create: FB ID: %d (%pK)", fb->base.id, fb);
return fb;
diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c
index e49df63..14cdd10 100644
--- a/drivers/gpu/drm/msm/msm_fbdev.c
+++ b/drivers/gpu/drm/msm/msm_fbdev.c
@@ -146,7 +146,7 @@
goto fail_unlock;
}
- DBG("fbi=%p, dev=%p", fbi, dev);
+ DBG("fbi=%pK, dev=%pK", fbi, dev);
fbdev->fb = fb;
helper->fb = fb;
@@ -167,7 +167,7 @@
fbi->fix.smem_start = paddr;
fbi->fix.smem_len = fbdev->bo->size;
- DBG("par=%p, %dx%d", fbi->par, fbi->var.xres, fbi->var.yres);
+ DBG("par=%pK, %dx%d", fbi->par, fbi->var.xres, fbi->var.yres);
DBG("allocated %dx%d fb", fbdev->fb->width, fbdev->fb->height);
mutex_unlock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 05ae5b7..69bd4c5 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -290,7 +290,7 @@
pfn = page_to_pfn(pages[pgoff]);
- VERB("Inserting %p pfn %lx, pa %lx", vmf->virtual_address,
+ VERB("Inserting %pK pfn %lx, pa %lx", vmf->virtual_address,
pfn, pfn << PAGE_SHIFT);
ret = vm_insert_mixed(vma, (unsigned long)vmf->virtual_address, pfn);
@@ -399,7 +399,7 @@
msm_obj->domain[id].sgt,
IOMMU_READ | IOMMU_NOEXEC);
if (ret) {
- DRM_ERROR("Unable to map phy buf=%p\n",
+ DRM_ERROR("Unable to map phy buf=%pK\n",
(void *)pa);
return ret;
}
@@ -414,7 +414,7 @@
msm_obj->domain[id].iova =
sg_dma_address(msm_obj->domain[id].sgt->sgl);
}
- DRM_DEBUG("iova=%p\n",
+ DRM_DEBUG("iova=%pK\n",
(void *)msm_obj->domain[id].iova);
} else {
WARN_ONCE(1, "physical address being used\n");
@@ -599,7 +599,7 @@
uint64_t off = drm_vma_node_start(&obj->vma_node);
WARN_ON(!mutex_is_locked(&dev->struct_mutex));
- seq_printf(m, "%08x: %c(r=%u,w=%u) %2d (%2d) %08llx %p %zu\n",
+ seq_printf(m, "%08x: %c(r=%u,w=%u) %2d (%2d) %08llx %pK %zu\n",
msm_obj->flags, is_active(msm_obj) ? 'A' : 'I',
msm_obj->read_timestamp, msm_obj->write_timestamp,
obj->name, obj->refcount.refcount.counter,
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c
index fd06bf8..b3e5827 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.c
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 2018 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1253,7 +1253,7 @@
sde_crtc_install_properties(crtc);
- SDE_DEBUG("%s: successfully initialized crtc=%p\n",
+ SDE_DEBUG("%s: successfully initialized crtc=%pK\n",
sde_crtc->name, crtc);
return crtc;
}
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_catalog.c b/drivers/gpu/drm/msm/sde/sde_hw_catalog.c
index 629ca37..1a5e0fa 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_catalog.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_catalog.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 2018 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -133,7 +133,7 @@
struct sde_mdss_cfg *cfg = NULL;
if (!dev || !dev->dev) {
- SDE_ERROR("dev=%p or dev->dev is NULL\n", dev);
+ SDE_ERROR("dev=%pK or dev->dev is NULL\n", dev);
return NULL;
}
diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c
index cffdaad..c013fc1 100644
--- a/drivers/gpu/drm/msm/sde/sde_plane.c
+++ b/drivers/gpu/drm/msm/sde/sde_plane.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2017, 2018 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1506,7 +1506,7 @@
struct sde_plane *sde_plane = to_sde_plane(plane);
if (!plane || !sde_plane) {
- SDE_ERROR("plane=%p or sde_plane=%p is NULL\n",
+ SDE_ERROR("plane=%pK or sde_plane=%pK is NULL\n",
plane, sde_plane);
return 0;
}
diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
index df402c9..412f028 100644
--- a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
+++ b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
@@ -364,11 +364,15 @@
struct tiler_block *tiler_reserve_2d(enum tiler_fmt fmt, uint16_t w,
uint16_t h, uint16_t align)
{
- struct tiler_block *block = kzalloc(sizeof(*block), GFP_KERNEL);
+ struct tiler_block *block;
u32 min_align = 128;
int ret;
unsigned long flags;
+ block = kzalloc(sizeof(*block), GFP_KERNEL);
+ if (!block)
+ return ERR_PTR(-ENOMEM);
+
BUG_ON(!validfmt(fmt));
/* convert width/height to slots */
diff --git a/drivers/gpu/msm/adreno_snapshot.c b/drivers/gpu/msm/adreno_snapshot.c
index ebcd38a..4e6a4a4 100644
--- a/drivers/gpu/msm/adreno_snapshot.c
+++ b/drivers/gpu/msm/adreno_snapshot.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -400,6 +400,8 @@
ibsize = rbptr[index + 3];
}
+ index = (index + 1) % KGSL_RB_DWORDS;
+
/* Don't parse known global IBs */
if (iommu_is_setstate_addr(device, ibaddr, ibsize))
continue;
@@ -410,9 +412,8 @@
parse_ib(device, snapshot, snapshot->process,
ibaddr, ibsize);
- }
-
- index = (index + 1) % KGSL_RB_DWORDS;
+ } else
+ index = (index + 1) % KGSL_RB_DWORDS;
}
}
diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c
index 8bf61d2..7192fa1 100644
--- a/drivers/hid/hid-debug.c
+++ b/drivers/hid/hid-debug.c
@@ -1150,6 +1150,8 @@
goto out;
if (list->tail > list->head) {
len = list->tail - list->head;
+ if (len > count)
+ len = count;
if (copy_to_user(buffer + ret, &list->hid_debug_buf[list->head], len)) {
ret = -EFAULT;
@@ -1159,6 +1161,8 @@
list->head += len;
} else {
len = HID_DEBUG_BUFSIZE - list->head;
+ if (len > count)
+ len = count;
if (copy_to_user(buffer, &list->hid_debug_buf[list->head], len)) {
ret = -EFAULT;
@@ -1166,7 +1170,9 @@
}
list->head = 0;
ret += len;
- goto copy_rest;
+ count -= len;
+ if (count > 0)
+ goto copy_rest;
}
}
diff --git a/drivers/hid/hid-roccat-kovaplus.c b/drivers/hid/hid-roccat-kovaplus.c
index 9660477..1073c0d 100644
--- a/drivers/hid/hid-roccat-kovaplus.c
+++ b/drivers/hid/hid-roccat-kovaplus.c
@@ -37,6 +37,8 @@
static void kovaplus_profile_activated(struct kovaplus_device *kovaplus,
uint new_profile_index)
{
+ if (new_profile_index >= ARRAY_SIZE(kovaplus->profile_settings))
+ return;
kovaplus->actual_profile = new_profile_index;
kovaplus->actual_cpi = kovaplus->profile_settings[new_profile_index].cpi_startup_level;
kovaplus->actual_x_sensitivity = kovaplus->profile_settings[new_profile_index].sensitivity_x;
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
index 7f2c1c3..2d86ac0 100644
--- a/drivers/hid/i2c-hid/i2c-hid.c
+++ b/drivers/hid/i2c-hid/i2c-hid.c
@@ -399,7 +399,7 @@
return;
}
- if ((ret_size > size) || (ret_size <= 2)) {
+ if ((ret_size > size) || (ret_size < 2)) {
dev_err(&ihid->client->dev, "%s: incomplete report (%d/%d)\n",
__func__, size, ret_size);
return;
diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c
index 3aa958b..8097a58 100644
--- a/drivers/hwmon/nct6775.c
+++ b/drivers/hwmon/nct6775.c
@@ -1286,7 +1286,7 @@
duty_is_dc = data->REG_PWM_MODE[i] &&
(nct6775_read_value(data, data->REG_PWM_MODE[i])
& data->PWM_MODE_MASK[i]);
- data->pwm_mode[i] = duty_is_dc;
+ data->pwm_mode[i] = !duty_is_dc;
fanmodecfg = nct6775_read_value(data, data->REG_FAN_MODE[i]);
for (j = 0; j < ARRAY_SIZE(data->REG_PWM); j++) {
@@ -2145,7 +2145,7 @@
struct nct6775_data *data = nct6775_update_device(dev);
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
- return sprintf(buf, "%d\n", !data->pwm_mode[sattr->index]);
+ return sprintf(buf, "%d\n", data->pwm_mode[sattr->index]);
}
static ssize_t
@@ -2166,9 +2166,9 @@
if (val > 1)
return -EINVAL;
- /* Setting DC mode is not supported for all chips/channels */
+ /* Setting DC mode (0) is not supported for all chips/channels */
if (data->REG_PWM_MODE[nr] == 0) {
- if (val)
+ if (!val)
return -EINVAL;
return count;
}
@@ -2177,7 +2177,7 @@
data->pwm_mode[nr] = val;
reg = nct6775_read_value(data, data->REG_PWM_MODE[nr]);
reg &= ~data->PWM_MODE_MASK[nr];
- if (val)
+ if (!val)
reg |= data->PWM_MODE_MASK[nr];
nct6775_write_value(data, data->REG_PWM_MODE[nr], reg);
mutex_unlock(&data->update_lock);
diff --git a/drivers/hwmon/pmbus/adm1275.c b/drivers/hwmon/pmbus/adm1275.c
index 60aad95..4876129 100644
--- a/drivers/hwmon/pmbus/adm1275.c
+++ b/drivers/hwmon/pmbus/adm1275.c
@@ -67,7 +67,7 @@
const struct adm1275_data *data = to_adm1275_data(info);
int ret = 0;
- if (page)
+ if (page > 0)
return -ENXIO;
switch (reg) {
@@ -144,7 +144,7 @@
{
int ret;
- if (page)
+ if (page > 0)
return -ENXIO;
switch (reg) {
diff --git a/drivers/hwmon/pmbus/max8688.c b/drivers/hwmon/pmbus/max8688.c
index f04454a..893df4d 100644
--- a/drivers/hwmon/pmbus/max8688.c
+++ b/drivers/hwmon/pmbus/max8688.c
@@ -44,7 +44,7 @@
{
int ret;
- if (page)
+ if (page > 0)
return -ENXIO;
switch (reg) {
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index 2f64273..fcf26f6 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -783,12 +783,16 @@
*/
if (of_device_is_compatible(np, "marvell,mv78230-i2c")) {
drv_data->offload_enabled = true;
- drv_data->errata_delay = true;
+ /* The delay is only needed in standard mode (100kHz) */
+ if (bus_freq <= 100000)
+ drv_data->errata_delay = true;
}
if (of_device_is_compatible(np, "marvell,mv78230-a0-i2c")) {
drv_data->offload_enabled = false;
- drv_data->errata_delay = true;
+ /* The delay is only needed in standard mode (100kHz) */
+ if (bus_freq <= 100000)
+ drv_data->errata_delay = true;
}
if (of_device_is_compatible(np, "allwinner,sun6i-a31-i2c"))
diff --git a/drivers/i2c/busses/i2c-pmcmsp.c b/drivers/i2c/busses/i2c-pmcmsp.c
index 177834e..27315d8 100644
--- a/drivers/i2c/busses/i2c-pmcmsp.c
+++ b/drivers/i2c/busses/i2c-pmcmsp.c
@@ -592,10 +592,10 @@
* TODO: We could potentially loop and retry in the case
* of MSP_TWI_XFER_TIMEOUT.
*/
- return -1;
+ return -EIO;
}
- return 0;
+ return num;
}
static u32 pmcmsptwi_i2c_func(struct i2c_adapter *adapter)
diff --git a/drivers/i2c/busses/i2c-viperboard.c b/drivers/i2c/busses/i2c-viperboard.c
index 7533fa3..d5f600c 100644
--- a/drivers/i2c/busses/i2c-viperboard.c
+++ b/drivers/i2c/busses/i2c-viperboard.c
@@ -341,7 +341,7 @@
}
mutex_unlock(&vb->lock);
}
- return 0;
+ return num;
error:
mutex_unlock(&vb->lock);
return error;
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 0b510ba..99cb9fa 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -1593,6 +1593,8 @@
struct cdrom_info *info;
int rc = -ENXIO;
+ check_disk_change(bdev);
+
mutex_lock(&ide_cd_mutex);
info = ide_cd_get(bdev->bd_disk);
if (!info)
diff --git a/drivers/iio/imu/Kconfig b/drivers/iio/imu/Kconfig
index e5c3521..e2d8826 100644
--- a/drivers/iio/imu/Kconfig
+++ b/drivers/iio/imu/Kconfig
@@ -31,6 +31,7 @@
source "drivers/iio/imu/inv_mpu/Kconfig"
source "drivers/iio/imu/inv_mpu9250/Kconfig"
source "drivers/iio/imu/inv_icm20602/Kconfig"
+source "drivers/iio/imu/st_asm330lhh/Kconfig"
endmenu
diff --git a/drivers/iio/imu/Makefile b/drivers/iio/imu/Makefile
index 0909b46..e265c37 100644
--- a/drivers/iio/imu/Makefile
+++ b/drivers/iio/imu/Makefile
@@ -19,3 +19,4 @@
obj-y += bmi160/
obj-y += inv_mpu/
obj-y += inv_mpu9250/
+obj-y += st_asm330lhh/
diff --git a/drivers/iio/imu/inv_mpu/iam20680/inv_mpu_core_20680.c b/drivers/iio/imu/inv_mpu/iam20680/inv_mpu_core_20680.c
index b429f57..7ffe693 100644
--- a/drivers/iio/imu/inv_mpu/iam20680/inv_mpu_core_20680.c
+++ b/drivers/iio/imu/inv_mpu/iam20680/inv_mpu_core_20680.c
@@ -311,6 +311,26 @@
return result;
}
+#ifdef CONFIG_ENABLE_ACC_GYRO_BUFFERING
+static inline int inv_check_acc_gyro_early_buff_enable_flag(
+ struct iio_dev *indio_dev)
+{
+ struct inv_mpu_state *st = iio_priv(indio_dev);
+
+ if (st->acc_buffer_inv_samples == true ||
+ st->gyro_buffer_inv_samples == true)
+ return 1;
+ else
+ return 0;
+}
+#else
+static inline int inv_check_acc_gyro_early_buff_enable_flag(
+ struct iio_dev *indio_dev)
+{
+ return 0;
+}
+#endif
+
/*
* inv_misc_attr_store() - calling this function
*/
@@ -321,6 +341,9 @@
struct iio_dev *indio_dev = dev_get_drvdata(dev);
int result;
+ if (inv_check_acc_gyro_early_buff_enable_flag(indio_dev))
+ return count;
+
mutex_lock(&indio_dev->mlock);
result = _misc_attr_store(dev, attr, buf, count);
mutex_unlock(&indio_dev->mlock);
@@ -351,6 +374,9 @@
int data, rate, ind;
int result;
+ if (inv_check_acc_gyro_early_buff_enable_flag(indio_dev))
+ return count;
+
result = kstrtoint(buf, 10, &data);
if (result)
return -EINVAL;
@@ -398,6 +424,9 @@
int data, on, ind;
int result;
+ if (inv_check_acc_gyro_early_buff_enable_flag(indio_dev))
+ return count;
+
result = kstrtoint(buf, 10, &data);
if (result)
return -EINVAL;
@@ -493,7 +522,7 @@
p1[0] = ((power_on_data >> 16) & 0xff);
p1[1] = ((power_on_data >> 24) & 0xff);
- if (st->bus_type == BUS_SPI) {
+ if (st->bus_type == BUS_IIO_SPI) {
struct spi_transfer power_on;
struct spi_message msg;
@@ -508,7 +537,7 @@
spi_message_add_tail(&power_on, &msg);
spi_sync(to_spi_device(st->dev), &msg);
- } else if (st->bus_type == BUS_I2C) {
+ } else if (st->bus_type == BUS_IIO_I2C) {
struct i2c_msg msgs[2];
p0[0] &= 0x7f;
@@ -717,7 +746,7 @@
return res;
mutex_unlock(&indio_dev->mlock);
- temp = (s32)be16_to_cpup((__be16 *)(data)) * 10000;
+ temp = (s16)be16_to_cpup((__be16 *)(data)) * 10000;
temp = temp / TEMP_SENSITIVITY + TEMP_OFFSET;
return snprintf(buf, MAX_WR_SZ, "%d %lld\n", temp, get_time_ns());
@@ -771,6 +800,169 @@
return count;
}
+#ifdef CONFIG_ENABLE_ACC_GYRO_BUFFERING
+static int inv_gyro_read_bootsampl(struct inv_mpu_state *st,
+ unsigned long enable_read)
+{
+ int i = 0;
+
+ if (enable_read) {
+ st->gyro_buffer_inv_samples = false;
+ for (i = 0; i < st->gyro_bufsample_cnt; i++) {
+ dev_dbg(st->dev, "gyro_cnt=%d,x=%d,y=%d,z=%d,tsec=%d,nsec=%lld\n",
+ i, st->inv_gyro_samplist[i]->xyz[0],
+ st->inv_gyro_samplist[i]->xyz[1],
+ st->inv_gyro_samplist[i]->xyz[2],
+ st->inv_gyro_samplist[i]->tsec,
+ st->inv_gyro_samplist[i]->tnsec);
+ input_report_abs(st->gyrobuf_dev, ABS_X,
+ st->inv_gyro_samplist[i]->xyz[0]);
+ input_report_abs(st->gyrobuf_dev, ABS_Y,
+ st->inv_gyro_samplist[i]->xyz[1]);
+ input_report_abs(st->gyrobuf_dev, ABS_Z,
+ st->inv_gyro_samplist[i]->xyz[2]);
+ input_report_abs(st->gyrobuf_dev, ABS_RX,
+ st->inv_gyro_samplist[i]->tsec);
+ input_report_abs(st->gyrobuf_dev, ABS_RY,
+ st->inv_gyro_samplist[i]->tnsec);
+ input_sync(st->gyrobuf_dev);
+ }
+ } else {
+ /* clean up */
+ if (st->gyro_bufsample_cnt != 0) {
+ for (i = 0; i < INV_GYRO_MAXSAMPLE; i++)
+ kmem_cache_free(st->inv_gyro_cachepool,
+ st->inv_gyro_samplist[i]);
+ kmem_cache_destroy(st->inv_gyro_cachepool);
+ st->gyro_bufsample_cnt = 0;
+ }
+
+ }
+ /*SYN_CONFIG indicates end of data*/
+ input_event(st->gyrobuf_dev, EV_SYN, SYN_CONFIG, 0xFFFFFFFF);
+ input_sync(st->gyrobuf_dev);
+ dev_dbg(st->dev, "End of gyro samples bufsample_cnt=%d\n",
+ st->gyro_bufsample_cnt);
+ return 0;
+}
+static int inv_acc_read_bootsampl(struct inv_mpu_state *st,
+ unsigned long enable_read)
+{
+ int i = 0;
+
+ if (enable_read) {
+ st->acc_buffer_inv_samples = false;
+ for (i = 0; i < st->acc_bufsample_cnt; i++) {
+ dev_dbg(st->dev, "acc_cnt=%d,x=%d,y=%d,z=%d,tsec=%d,nsec=%lld\n",
+ i, st->inv_acc_samplist[i]->xyz[0],
+ st->inv_acc_samplist[i]->xyz[1],
+ st->inv_acc_samplist[i]->xyz[2],
+ st->inv_acc_samplist[i]->tsec,
+ st->inv_acc_samplist[i]->tnsec);
+ input_report_abs(st->accbuf_dev, ABS_X,
+ st->inv_acc_samplist[i]->xyz[0]);
+ input_report_abs(st->accbuf_dev, ABS_Y,
+ st->inv_acc_samplist[i]->xyz[1]);
+ input_report_abs(st->accbuf_dev, ABS_Z,
+ st->inv_acc_samplist[i]->xyz[2]);
+ input_report_abs(st->accbuf_dev, ABS_RX,
+ st->inv_acc_samplist[i]->tsec);
+ input_report_abs(st->accbuf_dev, ABS_RY,
+ st->inv_acc_samplist[i]->tnsec);
+ input_sync(st->accbuf_dev);
+ }
+ } else {
+ /* clean up */
+ if (st->acc_bufsample_cnt != 0) {
+ for (i = 0; i < INV_ACC_MAXSAMPLE; i++)
+ kmem_cache_free(st->inv_acc_cachepool,
+ st->inv_acc_samplist[i]);
+ kmem_cache_destroy(st->inv_acc_cachepool);
+ st->acc_bufsample_cnt = 0;
+ }
+
+ }
+ /*SYN_CONFIG indicates end of data*/
+ input_event(st->accbuf_dev, EV_SYN, SYN_CONFIG, 0xFFFFFFFF);
+ input_sync(st->accbuf_dev);
+ dev_dbg(st->dev, "End of acc samples bufsample_cnt=%d\n",
+ st->acc_bufsample_cnt);
+ return 0;
+}
+
+static ssize_t read_gyro_boot_sample_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct inv_mpu_state *st = iio_priv(indio_dev);
+
+ return snprintf(buf, MAX_WR_SZ, "%d\n",
+ st->read_gyro_boot_sample);
+}
+
+static ssize_t read_gyro_boot_sample_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long enable = 0;
+
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct inv_mpu_state *st = iio_priv(indio_dev);
+
+ err = kstrtoul(buf, 10, &enable);
+ if (err)
+ return err;
+ if (enable > 1) {
+ err = dev_err(st->dev,
+ "Invalid value of input, input=%ld\n", enable);
+ return -EINVAL;
+ }
+ err = inv_gyro_read_bootsampl(st, enable);
+ if (err)
+ return err;
+ st->read_gyro_boot_sample = enable;
+ return count;
+
+}
+
+static ssize_t read_acc_boot_sample_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct inv_mpu_state *st = iio_priv(indio_dev);
+
+ return snprintf(buf, MAX_WR_SZ, "%d\n",
+ st->read_acc_boot_sample);
+}
+static ssize_t read_acc_boot_sample_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct inv_mpu_state *st = iio_priv(indio_dev);
+
+ unsigned long enable = 0;
+
+ err = kstrtoul(buf, 10, &enable);
+ if (err)
+ return err;
+ if (enable > 1) {
+ err = dev_err(st->dev,
+ "Invalid value of input, input=%ld\n", enable);
+ return -EINVAL;
+ }
+ err = inv_acc_read_bootsampl(st, enable);
+ if (err)
+ return err;
+ st->read_acc_boot_sample = enable;
+ return count;
+}
+#endif
+
static const struct iio_chan_spec inv_mpu_channels[] = {
IIO_CHAN_SOFT_TIMESTAMP(INV_MPU_SCAN_TIMESTAMP),
};
@@ -780,6 +972,12 @@
static DEVICE_ATTR(out_temperature, S_IRUGO | S_IWUSR,
inv_temperature_show, NULL);
static DEVICE_ATTR(misc_self_test, S_IRUGO | S_IWUSR, inv_self_test, NULL);
+#ifdef CONFIG_ENABLE_ACC_GYRO_BUFFERING
+static IIO_DEVICE_ATTR(read_acc_boot_sample, S_IRUGO | S_IWUSR,
+ read_acc_boot_sample_show, read_acc_boot_sample_store, SENSOR_L_ACCEL);
+static IIO_DEVICE_ATTR(read_gyro_boot_sample, S_IRUGO | S_IWUSR,
+ read_gyro_boot_sample_show, read_gyro_boot_sample_store, SENSOR_L_GYRO);
+#endif
static IIO_DEVICE_ATTR(info_anglvel_matrix, S_IRUGO, inv_attr_show, NULL,
ATTR_GYRO_MATRIX);
@@ -914,6 +1112,10 @@
#ifndef SUPPORT_ONLY_BASIC_FEATURES
&iio_dev_attr_in_power_on.dev_attr.attr,
#endif
+#ifdef CONFIG_ENABLE_ACC_GYRO_BUFFERING
+ &iio_dev_attr_read_acc_boot_sample.dev_attr.attr,
+ &iio_dev_attr_read_gyro_boot_sample.dev_attr.attr,
+#endif
&iio_dev_attr_in_accel_enable.dev_attr.attr,
&iio_dev_attr_in_accel_wake_enable.dev_attr.attr,
&iio_dev_attr_info_accel_matrix.dev_attr.attr,
diff --git a/drivers/iio/imu/inv_mpu/inv_mpu_i2c.c b/drivers/iio/imu/inv_mpu/inv_mpu_i2c.c
index e7838fc..3b14863 100644
--- a/drivers/iio/imu/inv_mpu/inv_mpu_i2c.c
+++ b/drivers/iio/imu/inv_mpu/inv_mpu_i2c.c
@@ -278,6 +278,212 @@
return res;
}
+#ifdef CONFIG_ENABLE_ACC_GYRO_BUFFERING
+static void inv_enable_acc_gyro(struct inv_mpu_state *st)
+{
+ struct iio_dev *indio_dev = iio_priv_to_dev(st);
+ int accel_hz = 100;
+ int gyro_hz = 100;
+
+ /**Enable the ACCEL**/
+ st->chip_config.accel_fs = ACCEL_FSR_2G;
+ inv_set_accel_sf(st);
+ st->trigger_state = MISC_TRIGGER;
+ set_inv_enable(indio_dev);
+
+ st->sensor_l[SENSOR_L_ACCEL].rate = accel_hz;
+ st->trigger_state = DATA_TRIGGER;
+ inv_check_sensor_on(st);
+ set_inv_enable(indio_dev);
+
+ st->sensor_l[SENSOR_L_ACCEL].on = 1;
+ st->trigger_state = RATE_TRIGGER;
+ inv_check_sensor_on(st);
+ set_inv_enable(indio_dev);
+
+ /**Enable the GYRO**/
+ st->chip_config.fsr = GYRO_FSR_250DPS;
+ inv_set_gyro_sf(st);
+ st->trigger_state = MISC_TRIGGER;
+ set_inv_enable(indio_dev);
+
+ st->sensor_l[SENSOR_L_GYRO].rate = gyro_hz;
+ st->trigger_state = DATA_TRIGGER;
+ inv_check_sensor_on(st);
+ set_inv_enable(indio_dev);
+
+ st->sensor_l[SENSOR_L_GYRO].on = 1;
+ st->trigger_state = RATE_TRIGGER;
+ inv_check_sensor_on(st);
+ set_inv_enable(indio_dev);
+}
+#else
+static void inv_enable_acc_gyro(struct inv_mpu_state *st)
+{
+}
+#endif
+
+#ifdef CONFIG_ENABLE_ACC_GYRO_BUFFERING
+static int inv_acc_gyro_early_buff_init(struct iio_dev *indio_dev)
+{
+ int i = 0, err = 0;
+ struct inv_mpu_state *st;
+
+ st = iio_priv(indio_dev);
+ st->acc_bufsample_cnt = 0;
+ st->gyro_bufsample_cnt = 0;
+ st->report_evt_cnt = 5;
+ st->max_buffer_time = 40;
+
+ st->inv_acc_cachepool = kmem_cache_create("acc_sensor_sample",
+ sizeof(struct inv_acc_sample),
+ 0,
+ SLAB_HWCACHE_ALIGN, NULL);
+ if (!st->inv_acc_cachepool) {
+ pr_err("inv_acc_cachepool cache create failed\n");
+ err = -ENOMEM;
+ goto clean_exit1;
+ }
+
+ for (i = 0; i < INV_ACC_MAXSAMPLE; i++) {
+ st->inv_acc_samplist[i] =
+ kmem_cache_alloc(st->inv_acc_cachepool,
+ GFP_KERNEL);
+ if (!st->inv_acc_samplist[i]) {
+ err = -ENOMEM;
+ goto clean_exit2;
+ }
+ }
+
+ st->inv_gyro_cachepool = kmem_cache_create("gyro_sensor_sample"
+ , sizeof(struct inv_gyro_sample), 0,
+ SLAB_HWCACHE_ALIGN, NULL);
+ if (!st->inv_gyro_cachepool) {
+ pr_err("inv_gyro_cachepool cache create failed\n");
+ err = -ENOMEM;
+ goto clean_exit3;
+ }
+
+ for (i = 0; i < INV_GYRO_MAXSAMPLE; i++) {
+ st->inv_gyro_samplist[i] =
+ kmem_cache_alloc(st->inv_gyro_cachepool,
+ GFP_KERNEL);
+ if (!st->inv_gyro_samplist[i]) {
+ err = -ENOMEM;
+ goto clean_exit4;
+ }
+ }
+
+ st->accbuf_dev = input_allocate_device();
+ if (!st->accbuf_dev) {
+ err = -ENOMEM;
+ pr_err("input device allocation failed\n");
+ goto clean_exit5;
+ }
+ st->accbuf_dev->name = "inv_accbuf";
+ st->accbuf_dev->id.bustype = BUS_I2C;
+ input_set_events_per_packet(st->accbuf_dev,
+ st->report_evt_cnt * INV_ACC_MAXSAMPLE);
+ set_bit(EV_ABS, st->accbuf_dev->evbit);
+ input_set_abs_params(st->accbuf_dev, ABS_X,
+ -G_MAX, G_MAX, 0, 0);
+ input_set_abs_params(st->accbuf_dev, ABS_Y,
+ -G_MAX, G_MAX, 0, 0);
+ input_set_abs_params(st->accbuf_dev, ABS_Z,
+ -G_MAX, G_MAX, 0, 0);
+ input_set_abs_params(st->accbuf_dev, ABS_RX,
+ -G_MAX, G_MAX, 0, 0);
+ input_set_abs_params(st->accbuf_dev, ABS_RY,
+ -G_MAX, G_MAX, 0, 0);
+ err = input_register_device(st->accbuf_dev);
+ if (err) {
+ pr_err("unable to register input device %s\n",
+ st->accbuf_dev->name);
+ goto clean_exit5;
+ }
+
+ st->gyrobuf_dev = input_allocate_device();
+ if (!st->gyrobuf_dev) {
+ err = -ENOMEM;
+ pr_err("input device allocation failed\n");
+ goto clean_exit6;
+ }
+ st->gyrobuf_dev->name = "inv_gyrobuf";
+ st->gyrobuf_dev->id.bustype = BUS_I2C;
+ input_set_events_per_packet(st->gyrobuf_dev,
+ st->report_evt_cnt * INV_GYRO_MAXSAMPLE);
+ set_bit(EV_ABS, st->gyrobuf_dev->evbit);
+ input_set_abs_params(st->gyrobuf_dev, ABS_X,
+ -G_MAX, G_MAX, 0, 0);
+ input_set_abs_params(st->gyrobuf_dev, ABS_Y,
+ -G_MAX, G_MAX, 0, 0);
+ input_set_abs_params(st->gyrobuf_dev, ABS_Z,
+ -G_MAX, G_MAX, 0, 0);
+ input_set_abs_params(st->gyrobuf_dev, ABS_RX,
+ -G_MAX, G_MAX, 0, 0);
+ input_set_abs_params(st->gyrobuf_dev, ABS_RY,
+ -G_MAX, G_MAX, 0, 0);
+ err = input_register_device(st->gyrobuf_dev);
+ if (err) {
+ pr_err("unable to register input device %s\n",
+ st->gyrobuf_dev->name);
+ goto clean_exit6;
+ }
+
+ st->acc_buffer_inv_samples = true;
+ st->gyro_buffer_inv_samples = true;
+ inv_enable_acc_gyro(st);
+
+ return 1;
+clean_exit6:
+ input_free_device(st->gyrobuf_dev);
+ input_unregister_device(st->accbuf_dev);
+clean_exit5:
+ input_free_device(st->accbuf_dev);
+clean_exit4:
+ for (i = 0; i < INV_GYRO_MAXSAMPLE; i++)
+ kmem_cache_free(st->inv_gyro_cachepool,
+ st->inv_gyro_samplist[i]);
+clean_exit3:
+ kmem_cache_destroy(st->inv_gyro_cachepool);
+clean_exit2:
+ for (i = 0; i < INV_ACC_MAXSAMPLE; i++)
+ kmem_cache_free(st->inv_acc_cachepool,
+ st->inv_acc_samplist[i]);
+clean_exit1:
+ kmem_cache_destroy(st->inv_acc_cachepool);
+ return 0;
+}
+static void inv_acc_gyro_input_cleanup(
+ struct iio_dev *indio_dev)
+{
+ int i = 0;
+ struct inv_mpu_state *st;
+
+ st = iio_priv(indio_dev);
+ input_free_device(st->accbuf_dev);
+ input_unregister_device(st->gyrobuf_dev);
+ input_free_device(st->gyrobuf_dev);
+ for (i = 0; i < INV_GYRO_MAXSAMPLE; i++)
+ kmem_cache_free(st->inv_gyro_cachepool,
+ st->inv_gyro_samplist[i]);
+ kmem_cache_destroy(st->inv_gyro_cachepool);
+ for (i = 0; i < INV_ACC_MAXSAMPLE; i++)
+ kmem_cache_free(st->inv_acc_cachepool,
+ st->inv_acc_samplist[i]);
+ kmem_cache_destroy(st->inv_acc_cachepool);
+}
+#else
+static int inv_acc_gyro_early_buff_init(struct iio_dev *indio_dev)
+{
+ return 1;
+}
+static void inv_acc_gyro_input_cleanup(
+ struct iio_dev *indio_dev)
+{
+}
+#endif
+
/*
* inv_mpu_probe() - probe function.
*/
@@ -318,7 +524,7 @@
st->mem_write = inv_i2c_mem_write;
st->mem_read = inv_i2c_mem_read;
st->dev = &client->dev;
- st->bus_type = BUS_I2C;
+ st->bus_type = BUS_IIO_I2C;
#ifdef CONFIG_OF
result = invensense_mpu_parse_dt(st->dev, &st->plat_data);
if (result)
@@ -420,6 +626,9 @@
#ifdef TIMER_BASED_BATCHING
pr_info("Timer based batching\n");
#endif
+ result = inv_acc_gyro_early_buff_init(indio_dev);
+ if (!result)
+ return -EIO;
return 0;
#ifdef KERNEL_VERSION_4_X
@@ -438,10 +647,10 @@
out_unreg_ring:
inv_mpu_unconfigure_ring(indio_dev);
out_free:
+ dev_err(st->dev, "%s failed %d\n", __func__, result);
iio_device_free(indio_dev);
out_no_free:
#endif
- dev_err(st->dev, "%s failed %d\n", __func__, result);
return -EIO;
}
@@ -479,6 +688,7 @@
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct inv_mpu_state *st = iio_priv(indio_dev);
+ inv_acc_gyro_input_cleanup(indio_dev);
#ifdef KERNEL_VERSION_4_X
devm_iio_device_unregister(st->dev, indio_dev);
#else
diff --git a/drivers/iio/imu/inv_mpu/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu/inv_mpu_iio.h
index 9e73165..444c85a 100644
--- a/drivers/iio/imu/inv_mpu/inv_mpu_iio.h
+++ b/drivers/iio/imu/inv_mpu/inv_mpu_iio.h
@@ -37,7 +37,9 @@
#include <linux/iio/sysfs.h>
#include <linux/iio/iio.h>
#include <linux/iio/kfifo_buf.h>
-
+#include <linux/input.h>
+#include <linux/ktime.h>
+#include <linux/slab.h>
#ifdef CONFIG_INV_MPU_IIO_ICM20648
#include "icm20648/dmp3Default.h"
#endif
@@ -131,9 +133,37 @@
#define COVARIANCE_SIZE 14
#define ACCEL_COVARIANCE_SIZE (COVARIANCE_SIZE * sizeof(int))
+#ifdef CONFIG_ENABLE_ACC_GYRO_BUFFERING
+#define INV_ACC_MAXSAMPLE 4000
+#define INV_GYRO_MAXSAMPLE 4000
+#define G_MAX 23920640
+struct inv_acc_sample {
+ int xyz[3];
+ unsigned int tsec;
+ unsigned long long tnsec;
+};
+struct inv_gyro_sample {
+ int xyz[3];
+ unsigned int tsec;
+ unsigned long long tnsec;
+};
+enum {
+ ACCEL_FSR_2G = 0,
+ ACCEL_FSR_4G = 1,
+ ACCEL_FSR_8G = 2,
+ ACCEL_FSR_16G = 3
+};
+enum {
+ GYRO_FSR_250DPS = 0,
+ GYRO_FSR_500DPS = 1,
+ GYRO_FSR_1000DPS = 2,
+ GYRO_FSR_2000DPS = 3
+};
+#endif
+
enum inv_bus_type {
- BUS_I2C = 0,
- BUS_SPI,
+ BUS_IIO_I2C = 0,
+ BUS_IIO_SPI,
};
struct inv_mpu_state;
@@ -825,6 +855,24 @@
u8 int_en_2;
u8 gesture_int_count;
u8 smplrt_div;
+#ifdef CONFIG_ENABLE_ACC_GYRO_BUFFERING
+ bool read_acc_boot_sample;
+ bool read_gyro_boot_sample;
+ int acc_bufsample_cnt;
+ int gyro_bufsample_cnt;
+ bool acc_buffer_inv_samples;
+ bool gyro_buffer_inv_samples;
+ struct kmem_cache *inv_acc_cachepool;
+ struct kmem_cache *inv_gyro_cachepool;
+ struct inv_acc_sample *inv_acc_samplist[INV_ACC_MAXSAMPLE];
+ struct inv_gyro_sample *inv_gyro_samplist[INV_GYRO_MAXSAMPLE];
+ ktime_t timestamp;
+ int max_buffer_time;
+ struct input_dev *accbuf_dev;
+ struct input_dev *gyrobuf_dev;
+ int report_evt_cnt;
+#endif
+
};
/**
diff --git a/drivers/iio/imu/inv_mpu/inv_mpu_ring.c b/drivers/iio/imu/inv_mpu/inv_mpu_ring.c
index 3e5bccbe..5dc19e6 100644
--- a/drivers/iio/imu/inv_mpu/inv_mpu_ring.c
+++ b/drivers/iio/imu/inv_mpu/inv_mpu_ring.c
@@ -297,6 +297,80 @@
inv_push_8bytes_buffer(st, hdr, t, out);
}
+#ifdef CONFIG_ENABLE_ACC_GYRO_BUFFERING
+static void store_acc_boot_sample(struct inv_mpu_state *st, u64 t,
+ s16 x, s16 y, s16 z)
+{
+ if (false == st->acc_buffer_inv_samples)
+ return;
+ st->timestamp.tv64 = t;
+ if (ktime_to_timespec(st->timestamp).tv_sec
+ < st->max_buffer_time) {
+ if (st->acc_bufsample_cnt < INV_ACC_MAXSAMPLE) {
+ st->inv_acc_samplist[st->
+ acc_bufsample_cnt]->xyz[0] = x;
+ st->inv_acc_samplist[st->
+ acc_bufsample_cnt]->xyz[1] = y;
+ st->inv_acc_samplist[st->
+ acc_bufsample_cnt]->xyz[2] = z;
+ st->inv_acc_samplist[st->
+ acc_bufsample_cnt]->tsec =
+ ktime_to_timespec(st
+ ->timestamp).tv_sec;
+ st->inv_acc_samplist[st->
+ acc_bufsample_cnt]->tnsec =
+ ktime_to_timespec(st
+ ->timestamp).tv_nsec;
+ st->acc_bufsample_cnt++;
+ }
+ } else {
+ dev_info(st->dev, "End of ACC buffering %d\n",
+ st->acc_bufsample_cnt);
+ st->acc_buffer_inv_samples = false;
+ }
+}
+static void store_gyro_boot_sample(struct inv_mpu_state *st, u64 t,
+ s16 x, s16 y, s16 z)
+{
+
+ if (false == st->gyro_buffer_inv_samples)
+ return;
+ st->timestamp.tv64 = t;
+ if (ktime_to_timespec(st->timestamp).tv_sec
+ < st->max_buffer_time) {
+ if (st->gyro_bufsample_cnt < INV_GYRO_MAXSAMPLE) {
+ st->inv_gyro_samplist[st->
+ gyro_bufsample_cnt]->xyz[0] = x;
+ st->inv_gyro_samplist[st->
+ gyro_bufsample_cnt]->xyz[1] = y;
+ st->inv_gyro_samplist[st->
+ gyro_bufsample_cnt]->xyz[2] = z;
+ st->inv_gyro_samplist[st->
+ gyro_bufsample_cnt]->tsec =
+ ktime_to_timespec(st->
+ timestamp).tv_sec;
+ st->inv_gyro_samplist[st->
+ gyro_bufsample_cnt]->tnsec =
+ ktime_to_timespec(st->
+ timestamp).tv_nsec;
+ st->gyro_bufsample_cnt++;
+ }
+ } else {
+ dev_info(st->dev, "End of GYRO buffering %d\n",
+ st->gyro_bufsample_cnt);
+ st->gyro_buffer_inv_samples = false;
+ }
+}
+#else
+static void store_acc_boot_sample(struct inv_mpu_state *st, u64 t,
+ s16 x, s16 y, s16 z)
+{
+}
+static void store_gyro_boot_sample(struct inv_mpu_state *st, u64 t,
+ s16 x, s16 y, s16 z)
+{
+}
+#endif
int inv_push_special_8bytes_buffer(struct inv_mpu_state *st,
u16 hdr, u64 t, s16 *d)
@@ -309,6 +383,7 @@
memcpy(&buf[2], &d[0], sizeof(d[0]));
for (j = 0; j < 2; j++)
memcpy(&buf[4 + j * 2], &d[j + 1], sizeof(d[j]));
+ store_gyro_boot_sample(st, t, d[0], d[1], d[2]);
iio_push_to_buffers(indio_dev, buf);
inv_push_timestamp(indio_dev, t);
@@ -399,7 +474,7 @@
for (j = 0; j < 2; j++)
memcpy(&buf[4 + j * 2], &d[j + 1],
sizeof(d[j]));
-
+ store_acc_boot_sample(st, t, d[0], d[1], d[2]);
iio_push_to_buffers(indio_dev, buf);
inv_push_timestamp(indio_dev, t);
st->sensor_l[ii].counter = 0;
diff --git a/drivers/iio/imu/inv_mpu/inv_mpu_spi.c b/drivers/iio/imu/inv_mpu/inv_mpu_spi.c
index fb91678..5199e62 100644
--- a/drivers/iio/imu/inv_mpu/inv_mpu_spi.c
+++ b/drivers/iio/imu/inv_mpu/inv_mpu_spi.c
@@ -177,7 +177,7 @@
&& !defined(CONFIG_INV_MPU_IIO_IAM20680)
st->i2c_dis = BIT_I2C_IF_DIS;
#endif
- st->bus_type = BUS_SPI;
+ st->bus_type = BUS_IIO_SPI;
spi_set_drvdata(spi, indio_dev);
indio_dev->dev.parent = &spi->dev;
indio_dev->name = id->name;
diff --git a/driver/iio/imu/st_asm330lhh/Kconfig b/drivers/iio/imu/st_asm330lhh/Kconfig
similarity index 100%
rename from driver/iio/imu/st_asm330lhh/Kconfig
rename to drivers/iio/imu/st_asm330lhh/Kconfig
diff --git a/driver/iio/imu/st_asm330lhh/Makefile b/drivers/iio/imu/st_asm330lhh/Makefile
similarity index 100%
rename from driver/iio/imu/st_asm330lhh/Makefile
rename to drivers/iio/imu/st_asm330lhh/Makefile
diff --git a/driver/iio/imu/st_asm330lhh/st_asm330lhh.h b/drivers/iio/imu/st_asm330lhh/st_asm330lhh.h
similarity index 100%
rename from driver/iio/imu/st_asm330lhh/st_asm330lhh.h
rename to drivers/iio/imu/st_asm330lhh/st_asm330lhh.h
diff --git a/driver/iio/imu/st_asm330lhh/st_asm330lhh_buffer.c b/drivers/iio/imu/st_asm330lhh/st_asm330lhh_buffer.c
similarity index 100%
rename from driver/iio/imu/st_asm330lhh/st_asm330lhh_buffer.c
rename to drivers/iio/imu/st_asm330lhh/st_asm330lhh_buffer.c
diff --git a/driver/iio/imu/st_asm330lhh/st_asm330lhh_core.c b/drivers/iio/imu/st_asm330lhh/st_asm330lhh_core.c
similarity index 100%
rename from driver/iio/imu/st_asm330lhh/st_asm330lhh_core.c
rename to drivers/iio/imu/st_asm330lhh/st_asm330lhh_core.c
diff --git a/driver/iio/imu/st_asm330lhh/st_asm330lhh_i2c.c b/drivers/iio/imu/st_asm330lhh/st_asm330lhh_i2c.c
similarity index 100%
rename from driver/iio/imu/st_asm330lhh/st_asm330lhh_i2c.c
rename to drivers/iio/imu/st_asm330lhh/st_asm330lhh_i2c.c
diff --git a/driver/iio/imu/st_asm330lhh/st_asm330lhh_spi.c b/drivers/iio/imu/st_asm330lhh/st_asm330lhh_spi.c
similarity index 100%
rename from driver/iio/imu/st_asm330lhh/st_asm330lhh_spi.c
rename to drivers/iio/imu/st_asm330lhh/st_asm330lhh_spi.c
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index e261a53..5edb09e 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -174,7 +174,11 @@
} else {
if (ucmd) {
qp->rq.wqe_cnt = ucmd->rq_wqe_count;
+ if (ucmd->rq_wqe_shift > BITS_PER_BYTE * sizeof(ucmd->rq_wqe_shift))
+ return -EINVAL;
qp->rq.wqe_shift = ucmd->rq_wqe_shift;
+ if ((1 << qp->rq.wqe_shift) / sizeof(struct mlx5_wqe_data_seg) < qp->wq_sig)
+ return -EINVAL;
qp->rq.max_gs = (1 << qp->rq.wqe_shift) / sizeof(struct mlx5_wqe_data_seg) - qp->wq_sig;
qp->rq.max_post = qp->rq.wqe_cnt;
} else {
@@ -3028,12 +3032,9 @@
int err;
err = mlx5_core_xrcd_dealloc(dev->mdev, xrcdn);
- if (err) {
+ if (err)
mlx5_ib_warn(dev, "failed to dealloc xrcdn 0x%x\n", xrcdn);
- return err;
- }
kfree(xrcd);
-
return 0;
}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index dce94ba..0e58a70 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -1644,6 +1644,9 @@
goto event_failed;
}
+ /* call event handler to ensure pkey in sync */
+ queue_work(ipoib_workqueue, &priv->flush_heavy);
+
result = register_netdev(priv->dev);
if (result) {
printk(KERN_WARNING "%s: couldn't register ipoib port %d; error %d\n",
diff --git a/drivers/input/sensors/smi130/Kconfig b/drivers/input/sensors/smi130/Kconfig
new file mode 100644
index 0000000..06e39dd
--- /dev/null
+++ b/drivers/input/sensors/smi130/Kconfig
@@ -0,0 +1,115 @@
+#
+# Makefile for Bosch sensors driver.
+#
+config BOSCH_DRIVER_LOG_FUNC
+ tristate "Bosch Sensortec driver smart log function support"
+ depends on (I2C || SPI_MASTER) && SYSFS
+ help
+ If you say yes here, you get support for smart log function in Bosch Sensortec driver.
+
+config SENSORS_BMA2X2
+ tristate "BMA2x2 acceleration sensor support"
+ depends on I2C
+ help
+ If you say yes here, you get support for Bosch Sensortec's
+ acceleration sensors BMA255/BMA254/BMA355/BMA250E/BMA222E/BMA280.
+
+config SENSORS_BMA2X2_ENABLE_INT1
+ tristate "BMA2X2 acceleration sensor interrupt INT1 support"
+ depends on SENSORS_BMA2X2
+ help
+ If you say yes here, you get INT1 support for Bosch Sensortec
+ acceleration sensors BMA255/BMA250E/BMA222E/BMA280.
+ Select it will disable interrupt INT2 support
+
+config SENSORS_BMA2X2_ENABLE_INT2
+ tristate "BMA2X2 acceleration sensor interrupt INT2 support"
+ depends on SENSORS_BMA2X2 && !SENSORS_BMA2X2_ENABLE_INT1
+ help
+ If you say yes here, you get INT2 support for Bosch Sensortec
+ acceleration sensors BMA255/BMA250E/BMA222E/BMA280.
+ Can only open if you do NOT open interrupt INT1 support
+
+config SIG_MOTION
+ tristate "support significant motion sensor function"
+ depends on SENSORS_BMA2X2 && ( SENSORS_BMA2X2_ENABLE_INT1 || SENSORS_BMA2X2_ENABLE_INT2)
+ help
+ If you say yes here, if you want to support Bosch significant motion sensor function
+
+config DOUBLE_TAP
+ tristate "support double tap sensor function"
+ depends on SENSORS_BMA2X2 && ( SENSORS_BMA2X2_ENABLE_INT1 || SENSORS_BMA2X2_ENABLE_INT2)
+ help
+ If you say yes here, you get support Bosch double tap sensor function
+
+config SENSORS_BMG
+ tristate "Bosch Gyroscope Sensor Driver"
+ depends on I2C
+ help
+ If you say yes here, you get support for Bosch Sensortec's
+ gyroscope sensor drivers of BMG160/SMI055/BMI058 e.t.c.
+
+
+config SENSORS_BMI058
+ tristate "BMI058 Sensor Support"
+ depends on (SENSORS_BMG || SENSORS_BMA2X2)
+ help
+ If you say yes here, you get support for Bosch Sensortec's
+ sensor driver of BMI058.
+
+config SENSORS_YAS537
+ tristate "YAS537 Magnetic Sensor Driver"
+ depends on I2C
+ help
+ If you say yes here, you get support for YAMAHA
+ sensor YAS537 Magnetic Sensor
+
+config SENSORS_BMM050
+ tristate "BMM050 Magnetic Sensor Driver"
+ depends on I2C
+ help
+ If you say yes here, you get support for Bosch Sensortec's
+ sensor BMM050 Magnetic Sensor
+
+config SENSORS_AKM09911
+ tristate "AKM09911 Mag Sensor Driver"
+ depends on I2C
+ help
+ If you say yes here, you get support AKM09911 Sensor support.
+
+config SENSORS_AKM09912
+ tristate "AKM09912 Mag Sensor Driver"
+ depends on I2C
+ help
+ If you say yes here, you get support AKM09912 Sensor support.
+
+config SENSORS_BMA420
+ tristate "BMA4XY Sensor Support"
+ depends on I2C || SPI_MASTER
+ help
+ If you say yes here, you get support for Bosch Sensortec's sensor driver of BMA420.
+config SENSORS_BMA421
+ tristate "BMA4XY Sensor Support"
+ depends on I2C || SPI_MASTER
+ help
+ If you say yes here, you get support for Bosch Sensortec's sensor driver of BMA421.
+config SENSORS_BMA422
+ tristate "BMA4XY Sensor Support"
+ depends on I2C || SPI_MASTER
+ help
+ If you say yes here, you get support for Bosch Sensortec's sensor driver of BMA422.
+config SENSORS_BMA455
+ tristate "BMA4XY Sensor Support"
+ depends on I2C || SPI_MASTER
+ help
+ If you say yes here, you get support for Bosch Sensortec's sensor driver of BMA455.
+
+config BMA4XY_MAG_INTERFACE_SUPPORT
+tristate "BMA4XY Sensor mag interface support"
+depends on SENSORS_BMA4XY
+ help
+ If you say yes here, you get support for Bosch Sensortec's
+ sensor driver of BMA4XY with mag sensor support.
+
+
+
diff --git a/drivers/input/sensors/smi130/Makefile b/drivers/input/sensors/smi130/Makefile
new file mode 100644
index 0000000..b374e00d
--- /dev/null
+++ b/drivers/input/sensors/smi130/Makefile
@@ -0,0 +1,36 @@
+#
+# Makefile for Bosch sensor driver.
+#
+
+obj-$(CONFIG_BOSCH_DRIVER_LOG_FUNC) += bs_log.o
+obj-y += boschclass.o
+ifeq ($(CONFIG_BOSCH_DRIVER_LOG_FUNC),y)
+ EXTRA_CFLAGS += -DBOSCH_DRIVER_LOG_FUNC
+endif
+
+
+
+obj-y += smi130_driver.o smi130.o
+ifeq ($(CONFIG_SMI130_MAG_INTERFACE_SUPPORT),y)
+ EXTRA_CFLAGS += -DSMI130_MAG_INTERFACE_SUPPORT
+endif
+ifeq ($(CONFIG_SENSORS_SMI130_ENABLE_INT1),y)
+ EXTRA_CFLAGS += -DSMI130_ENABLE_INT1
+endif
+
+ifeq ($(CONFIG_SENSORS_SMI130_ENABLE_INT2),y)
+ EXTRA_CFLAGS += -DSMI130_ENABLE_INT2
+endif
+
+obj-y += smi130_i2c.o
+
+EXTRA_CFLAGS += -DSMI_USE_BASIC_I2C_FUNC
+
+obj-$(CONFIG_SENSORS_SMI130_SPI) += smi130_spi.o
+
+
+
+
+
+
+
diff --git a/drivers/input/sensors/smi130/boschclass.c b/drivers/input/sensors/smi130/boschclass.c
new file mode 100644
index 0000000..cf2e496
--- /dev/null
+++ b/drivers/input/sensors/smi130/boschclass.c
@@ -0,0 +1,341 @@
+/*!
+ * @section LICENSE
+ * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved
+ *
+ * (C) Modification Copyright 2018 Robert Bosch Kft All Rights Reserved
+ *
+ * This software program is licensed subject to the GNU General
+ * Public License (GPL).Version 2,June 1991,
+ * available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * Special: Description of the Software:
+ *
+ * This software module (hereinafter called "Software") and any
+ * information on application-sheets (hereinafter called "Information") is
+ * provided free of charge for the sole purpose to support your application
+ * work.
+ *
+ * As such, the Software is merely an experimental software, not tested for
+ * safety in the field and only intended for inspiration for further development
+ * and testing. Any usage in a safety-relevant field of use (like automotive,
+ * seafaring, spacefaring, industrial plants etc.) was not intended, so there are
+ * no precautions for such usage incorporated in the Software.
+ *
+ * The Software is specifically designed for the exclusive use for Bosch
+ * Sensortec products by personnel who have special experience and training. Do
+ * not use this Software if you do not have the proper experience or training.
+ *
+ * This Software package is provided as is and without any expressed or
+ * implied warranties, including without limitation, the implied warranties of
+ * merchantability and fitness for a particular purpose.
+ *
+ * Bosch Sensortec and their representatives and agents deny any liability for
+ * the functional impairment of this Software in terms of fitness, performance
+ * and safety. Bosch Sensortec and their representatives and agents shall not be
+ * liable for any direct or indirect damages or injury, except as otherwise
+ * stipulated in mandatory applicable law.
+ * The Information provided is believed to be accurate and reliable. Bosch
+ * Sensortec assumes no responsibility for the consequences of use of such
+ * Information nor for any infringement of patents or other rights of third
+ * parties which may result from its use.
+ *
+ *------------------------------------------------------------------------------
+ * The following Product Disclaimer does not apply to the BSX4-HAL-4.1NoFusion Software
+ * which is licensed under the Apache License, Version 2.0 as stated above.
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Product Disclaimer
+ *
+ * Common:
+ *
+ * Assessment of Products Returned from Field
+ *
+ * Returned products are considered good if they fulfill the specifications /
+ * test data for 0-mileage and field listed in this document.
+ *
+ * Engineering Samples
+ *
+ * Engineering samples are marked with (e) or (E). Samples may vary from the
+ * valid technical specifications of the series product contained in this
+ * data sheet. Therefore, they are not intended or fit for resale to
+ * third parties or for use in end products. Their sole purpose is internal
+ * client testing. The testing of an engineering sample may in no way replace
+ * the testing of a series product. Bosch assumes no liability for the use
+ * of engineering samples. The purchaser shall indemnify Bosch from all claims
+ * arising from the use of engineering samples.
+ *
+ * Intended use
+ *
+ * Provided that SMI130 is used within the conditions (environment, application,
+ * installation, loads) as described in this TCD and the corresponding
+ * agreed upon documents, Bosch ensures that the product complies with
+ * the agreed properties. Agreements beyond this require
+ * the written approval by Bosch. The product is considered fit for the intended
+ * use when the product successfully has passed the tests
+ * in accordance with the TCD and agreed upon documents.
+ *
+ * It is the responsibility of the customer to ensure the proper application
+ * of the product in the overall system/vehicle.
+ *
+ * Bosch does not assume any responsibility for changes to the environment
+ * of the product that deviate from the TCD and the agreed upon documents
+ * as well as all applications not released by Bosch
+ *
+ * The resale and/or use of products are at the purchaser’s own risk and
+ * responsibility. The examination and testing of the SMI130
+ * is the sole responsibility of the purchaser.
+ *
+ * The purchaser shall indemnify Bosch from all third party claims
+ * arising from any product use not covered by the parameters of
+ * this product data sheet or not approved by Bosch and reimburse Bosch
+ * for all costs and damages in connection with such claims.
+ *
+ * The purchaser must monitor the market for the purchased products,
+ * particularly with regard to product safety, and inform Bosch without delay
+ * of all security relevant incidents.
+ *
+ * Application Examples and Hints
+ *
+ * With respect to any application examples, advice, normal values
+ * and/or any information regarding the application of the device,
+ * Bosch hereby disclaims any and all warranties and liabilities of any kind,
+ * including without limitation warranties of
+ * non-infringement of intellectual property rights or copyrights
+ * of any third party.
+ * The information given in this document shall in no event be regarded
+ * as a guarantee of conditions or characteristics. They are provided
+ * for illustrative purposes only and no evaluation regarding infringement
+ * of intellectual property rights or copyrights or regarding functionality,
+ * performance or error has been made.
+ *
+ * @filename boschclass.c
+ * @date 2015/11/17 13:44
+ * @Modification Date 2018/06/21 15:03
+ * @id "836294d"
+ * @version 1.5.9
+ *
+ * @brief
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+#include <linux/poll.h>
+#include <linux/mutex.h>
+#include <linux/rcupdate.h>
+#include <linux/compiler.h>
+#include <linux/compat.h>
+#include "boschclass.h"
+#include "bs_log.h"
+
+static LIST_HEAD(bosch_dev_list);
+
+/*
+ * bosch_mutex protects access to both bosch_dev_list and input_handler_list.
+ * This also causes bosch_[un]register_device and bosch_[un]register_handler
+ * be mutually exclusive which simplifies locking in drivers implementing
+ * input handlers.
+ */
+static DEFINE_MUTEX(bosch_mutex);
+
+
+static void bosch_dev_release(struct device *device)
+{
+ struct bosch_dev *dev = to_bosch_dev(device);
+ if (NULL != dev)
+ kfree(dev);
+ module_put(THIS_MODULE);
+}
+
+
+#ifdef CONFIG_PM
+static int bosch_dev_suspend(struct device *dev)
+{
+ return 0;
+}
+
+static int bosch_dev_resume(struct device *dev)
+{
+ return 0;
+}
+
+static const struct dev_pm_ops bosch_dev_pm_ops = {
+ .suspend = bosch_dev_suspend,
+ .resume = bosch_dev_resume,
+ .poweroff = bosch_dev_suspend,
+ .restore = bosch_dev_resume,
+};
+#endif /* CONFIG_PM */
+
+static const struct attribute_group *bosch_dev_attr_groups[] = {
+ NULL
+};
+
+static struct device_type bosch_dev_type = {
+ .groups = bosch_dev_attr_groups,
+ .release = bosch_dev_release,
+#ifdef CONFIG_PM
+ .pm = &bosch_dev_pm_ops,
+#endif
+};
+
+
+
+static char *bosch_devnode(struct device *dev, mode_t *mode)
+{
+ return kasprintf(GFP_KERNEL, "%s", dev_name(dev));
+}
+
+struct class bosch_class = {
+ .name = "bosch",
+ .owner = THIS_MODULE,
+ .devnode = (void*)bosch_devnode,
+ .dev_release = bosch_dev_release,
+};
+EXPORT_SYMBOL_GPL(bosch_class);
+
+/**
+ * bosch_allocate_device - allocate memory for new input device
+ *
+ * Returns prepared struct bosch_dev or NULL.
+ *
+ * NOTE: Use bosch_free_device() to free devices that have not been
+ * registered; bosch_unregister_device() should be used for already
+ * registered devices.
+ */
+struct bosch_dev *bosch_allocate_device(void)
+{
+ struct bosch_dev *dev;
+
+ dev = kzalloc(sizeof(struct bosch_dev), GFP_KERNEL);
+ if (dev) {
+ dev->dev.type = &bosch_dev_type;
+ dev->dev.class = &bosch_class;
+ device_initialize(&dev->dev);
+ mutex_init(&dev->mutex);
+ INIT_LIST_HEAD(&dev->node);
+ __module_get(THIS_MODULE);
+ }
+ return dev;
+}
+EXPORT_SYMBOL(bosch_allocate_device);
+
+
+
+/**
+ * bosch_free_device - free memory occupied by bosch_dev structure
+ * @dev: input device to free
+ *
+ * This function should only be used if bosch_register_device()
+ * was not called yet or if it failed. Once device was registered
+ * use bosch_unregister_device() and memory will be freed once last
+ * reference to the device is dropped.
+ *
+ * Device should be allocated by bosch_allocate_device().
+ *
+ * NOTE: If there are references to the input device then memory
+ * will not be freed until last reference is dropped.
+ */
+void bosch_free_device(struct bosch_dev *dev)
+{
+ if (dev)
+ bosch_put_device(dev);
+}
+EXPORT_SYMBOL(bosch_free_device);
+
+/**
+ * bosch_register_device - register device with input core
+ * @dev: device to be registered
+ *
+ * This function registers device with input core. The device must be
+ * allocated with bosch_allocate_device() and all it's capabilities
+ * set up before registering.
+ * If function fails the device must be freed with bosch_free_device().
+ * Once device has been successfully registered it can be unregistered
+ * with bosch_unregister_device(); bosch_free_device() should not be
+ * called in this case.
+ */
+int bosch_register_device(struct bosch_dev *dev)
+{
+ const char *path;
+ int error;
+
+
+ /*
+ * If delay and period are pre-set by the driver, then autorepeating
+ * is handled by the driver itself and we don't do it in input.c.
+ */
+ dev_set_name(&dev->dev, dev->name);
+
+ error = device_add(&dev->dev);
+ if (error)
+ return error;
+
+ path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
+ PINFO("%s as %s\n",
+ dev->name ? dev->name : "Unspecified device",
+ path ? path : "N/A");
+ kfree(path);
+ error = mutex_lock_interruptible(&bosch_mutex);
+ if (error) {
+ device_del(&dev->dev);
+ return error;
+ }
+
+ list_add_tail(&dev->node, &bosch_dev_list);
+
+ mutex_unlock(&bosch_mutex);
+ return 0;
+}
+EXPORT_SYMBOL(bosch_register_device);
+
+/**
+ * bosch_unregister_device - unregister previously registered device
+ * @dev: device to be unregistered
+ *
+ * This function unregisters an input device. Once device is unregistered
+ * the caller should not try to access it as it may get freed at any moment.
+ */
+void bosch_unregister_device(struct bosch_dev *dev)
+{
+ int ret = 0;
+ ret = mutex_lock_interruptible(&bosch_mutex);
+ if(ret){
+ return;
+ }
+
+ list_del_init(&dev->node);
+ mutex_unlock(&bosch_mutex);
+ device_unregister(&dev->dev);
+}
+EXPORT_SYMBOL(bosch_unregister_device);
+
+static int __init bosch_init(void)
+{
+ int err;
+ /*bosch class register*/
+ err = class_register(&bosch_class);
+ if (err) {
+ pr_err("unable to register bosch_dev class\n");
+ return err;
+ }
+ return err;
+}
+
+static void __exit bosch_exit(void)
+{
+ /*bosch class*/
+ class_unregister(&bosch_class);
+}
+
+/*subsys_initcall(bosch_init);*/
+
+MODULE_AUTHOR("contact@bosch-sensortec.com");
+MODULE_DESCRIPTION("BST CLASS CORE");
+MODULE_LICENSE("GPL V2");
+
+module_init(bosch_init);
+module_exit(bosch_exit);
diff --git a/drivers/input/sensors/smi130/boschclass.h b/drivers/input/sensors/smi130/boschclass.h
new file mode 100644
index 0000000..505f155
--- /dev/null
+++ b/drivers/input/sensors/smi130/boschclass.h
@@ -0,0 +1,81 @@
+/*!
+ * @section LICENSE
+ * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved
+ *
+ * (C) Modification Copyright 2018 Robert Bosch Kft All Rights Reserved
+ *
+ * This software program is licensed subject to the GNU General
+ * Public License (GPL).Version 2,June 1991,
+ * available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * @filename boschcalss.h
+ * @date 2015/11/17 13:44
+ * @Modification Date 2018/06/21 15:03
+ * @id "836294d"
+ * @version 1.5.9
+ *
+ * @brief
+ */
+
+#ifndef _BSTCLASS_H
+#define _BSTCLASS_H
+
+#ifdef __KERNEL__
+#include <linux/time.h>
+#include <linux/list.h>
+#else
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <linux/types.h>
+#endif
+
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/mod_devicetable.h>
+
+struct bosch_dev {
+ const char *name;
+
+ int (*open)(struct bosch_dev *dev);
+ void (*close)(struct bosch_dev *dev);
+ struct mutex mutex;
+ struct device dev;
+ struct list_head node;
+};
+
+#define to_bosch_dev(d) container_of(d, struct bosch_dev, dev)
+
+struct bosch_dev *bosch_allocate_device(void);
+void bosch_free_device(struct bosch_dev *dev);
+
+static inline struct bosch_dev *bosch_get_device(struct bosch_dev *dev)
+{
+ return dev ? to_bosch_dev(get_device(&dev->dev)) : NULL;
+}
+
+static inline void bosch_put_device(struct bosch_dev *dev)
+{
+ if (dev)
+ put_device(&dev->dev);
+}
+
+static inline void *bosch_get_drvdata(struct bosch_dev *dev)
+{
+ return dev_get_drvdata(&dev->dev);
+}
+
+static inline void bosch_set_drvdata(struct bosch_dev *dev, void *data)
+{
+ dev_set_drvdata(&dev->dev, data);
+}
+
+int __must_check bosch_register_device(struct bosch_dev *);
+void bosch_unregister_device(struct bosch_dev *);
+
+void bosch_reset_device(struct bosch_dev *);
+
+
+extern struct class bosch_class;
+
+#endif
diff --git a/drivers/input/sensors/smi130/bs_log.c b/drivers/input/sensors/smi130/bs_log.c
new file mode 100644
index 0000000..52db4c8
--- /dev/null
+++ b/drivers/input/sensors/smi130/bs_log.c
@@ -0,0 +1,53 @@
+/*!
+ * @section LICENSE
+ * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved
+ *
+ * (C) Modification Copyright 2018 Robert Bosch Kft All Rights Reserved
+ *
+ * This software program is licensed subject to the GNU General
+ * Public License (GPL).Version 2,June 1991,
+ * available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * @filename bs_log.c
+ * @date "Wed Sep 24 15:27:12 2014 +0800"
+ * @Modification Date "Thu June 21 15:03 2018 +0100"
+ * @id "e416c14"
+ *
+ * @brief
+ * The source file of BOSCH SENSOR LOG
+*/
+
+
+#ifdef __KERNEL__
+#include <linux/kernel.h>
+#include <linux/unistd.h>
+#include <linux/types.h>
+#else
+#include <unistd.h>
+#include <sys/types.h>
+#endif
+
+#include <linux/time.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#ifdef BOSCH_DRIVER_LOG_FUNC
+#define BSLOG_VAR_DEF
+#include "bs_log.h"
+
+void set_debug_log_level(uint8_t level)
+{
+ debug_log_level = level;
+}
+
+uint8_t get_debug_log_level(void)
+{
+ return debug_log_level;
+}
+
+EXPORT_SYMBOL(set_debug_log_level);
+EXPORT_SYMBOL(get_debug_log_level);
+
+#endif/*BOSCH_DRIVER_LOG_FUNC*/
+/*@}*/
diff --git a/drivers/input/sensors/smi130/bs_log.h b/drivers/input/sensors/smi130/bs_log.h
new file mode 100644
index 0000000..758ea0b
--- /dev/null
+++ b/drivers/input/sensors/smi130/bs_log.h
@@ -0,0 +1,174 @@
+/*!
+ * @section LICENSE
+ * (C) Copyright 2011~2016 Bosch Sensortec GmbH All Rights Reserved
+ *
+ * (C) Modification Copyright 2018 Robert Bosch Kft All Rights Reserved
+ *
+ * This software program is licensed subject to the GNU General
+ * Public License (GPL).Version 2,June 1991,
+ * available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * @filename bs_log.h
+ * @date "Sat Oct 11 16:12:16 2014 +0800"
+ * @Modification Date "Thu June 21 15:03 2018 +0100"
+ * @id "762cc9e"
+ *
+ * @brief
+ * The head file of BOSCH SENSOR LOG
+*/
+
+#ifndef __BS_LOG_H
+#define __BS_LOG_H
+
+#include <linux/kernel.h>
+
+/*! @ trace functions
+ @{*/
+/*! ERROR LOG LEVEL */
+#define LOG_LEVEL_E 3
+/*! NOTICE LOG LEVEL */
+#define LOG_LEVEL_N 5
+/*! INFORMATION LOG LEVEL */
+#define LOG_LEVEL_I 6
+/*! DEBUG LOG LEVEL */
+#define LOG_LEVEL_D 7
+/*! DEBUG_FWDL LOG LEVEL */
+#define LOG_LEVEL_DF 10
+/*! DEBUG_DATA LOG LEVEL */
+#define LOG_LEVEL_DA 15
+/*! ALL LOG LEVEL */
+#define LOG_LEVEL_A 20
+
+#ifndef MODULE_TAG
+/*! MODULE TAG DEFINATION */
+#define MODULE_TAG "<BS_LOG>"
+#endif
+
+#ifndef LOG_LEVEL
+/*! LOG LEVEL DEFINATION */
+#define LOG_LEVEL LOG_LEVEL_I
+#endif
+
+#ifdef BOSCH_DRIVER_LOG_FUNC
+ #ifdef BSLOG_VAR_DEF
+ uint8_t debug_log_level = LOG_LEVEL;
+ #else
+ extern uint8_t debug_log_level;
+ #endif
+
+ /*! print error message */
+ #define PERR(fmt, args...) do\
+ {\
+ if (debug_log_level >= LOG_LEVEL_E)\
+ printk(KERN_INFO "\n" "[E]" KERN_ERR MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args);\
+ } while (0)
+
+ /*! print notice message */
+ #define PNOTICE(fmt, args...) do\
+ {\
+ if (debug_log_level >= LOG_LEVEL_N)\
+ printk(KERN_INFO "\n" "[N]" KERN_NOTICE MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args);\
+ } while (0)
+
+ /*! print information message */
+ #define PINFO(fmt, args...) do\
+ {\
+ if (debug_log_level >= LOG_LEVEL_I)\
+ printk(KERN_INFO "\n" "[I]" KERN_INFO MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args);\
+ } while (0)
+
+ /*! print debug message */
+ #define PDEBUG(fmt, args...) do\
+ {\
+ if (debug_log_level >= LOG_LEVEL_D)\
+ printk(KERN_INFO "\n" "[D]" KERN_DEBUG MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args);\
+ } while (0)
+
+ /*! print debug fw download message */
+ #define PDEBUG_FWDL(fmt, args...) do\
+ {\
+ if (debug_log_level >= LOG_LEVEL_DF)\
+ printk(KERN_INFO "\n" "[DF]" KERN_DEBUG MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args);\
+ } while (0)
+
+ /*! print debug data log message */
+ #define PDEBUG_DLOG(fmt, args...) do\
+ {\
+ if (debug_log_level >= LOG_LEVEL_DA)\
+ printk(KERN_INFO "\n" "[DA]" KERN_DEBUG MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args);\
+ } while (0)
+
+ void set_debug_log_level(uint8_t level);
+ uint8_t get_debug_log_level(void);
+
+#else
+
+ #if (LOG_LEVEL >= LOG_LEVEL_E)
+ /*! print error message */
+ #define PERR(fmt, args...) \
+ printk(KERN_INFO "\n" "[E]" KERN_ERR MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args)
+ #else
+ /*! invalid message */
+ #define PERR(fmt, args...)
+ #endif
+
+ #if (LOG_LEVEL >= LOG_LEVEL_N)
+ /*! print notice message */
+ #define PNOTICE(fmt, args...) \
+ printk(KERN_INFO "\n" "[N]" KERN_NOTICE MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args)
+ #else
+ /*! invalid message */
+ #define PNOTICE(fmt, args...)
+ #endif
+
+ #if (LOG_LEVEL >= LOG_LEVEL_I)
+ /*! print information message */
+ #define PINFO(fmt, args...) printk(KERN_INFO "\n" "[I]" KERN_INFO MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args)
+ #else
+ /*! invalid message */
+ #define PINFO(fmt, args...)
+ #endif
+
+ #if (LOG_LEVEL >= LOG_LEVEL_D)
+ /*! print debug message */
+ #define PDEBUG(fmt, args...) printk(KERN_INFO "\n" "[D]" KERN_DEBUG MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args)
+ #else
+ /*! invalid message */
+ #define PDEBUG(fmt, args...)
+ #endif
+
+ #if (LOG_LEVEL >= LOG_LEVEL_DF)
+ /*! print debug fw download message */
+ #define PDEBUG_FWDL(fmt, args...) printk(KERN_INFO "\n" "[DF]" KERN_DEBUG MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args)
+ #else
+ /*! invalid message */
+ #define PDEBUG_FWDL(fmt, args...)
+ #endif
+
+ #if (LOG_LEVEL >= LOG_LEVEL_DA)
+ /*! print debug data log message */
+ #define PDEBUG_DLOG(fmt, args...) printk(KERN_INFO "\n" "[DA]" KERN_DEBUG MODULE_TAG \
+ "<%s><%d>" fmt "\n", __func__, __LINE__, ##args)
+ #else
+ /*! invalid message */
+ #define PDEBUG_DLOG(fmt, args...)
+ #endif
+
+ #define set_debug_log_level(level) {}
+ #define get_debug_log_level() (LOG_LEVEL)
+
+#endif
+
+#endif/*__BS_LOG_H*/
+/*@}*/
diff --git a/drivers/input/sensors/smi130/readme.md b/drivers/input/sensors/smi130/readme.md
new file mode 100644
index 0000000..4d49939
--- /dev/null
+++ b/drivers/input/sensors/smi130/readme.md
@@ -0,0 +1,148 @@
+# SMI130 sensor API
+
+## Introduction
+
+This package contains the Robert Bosch GmbH's SMI130 sensor driver (sensor API)
+
+## Version
+
+File | Version | Date
+----------------|---------|---------------
+smi130.h | 2.0.9 | 2018/06/21
+smi130.c | 2.0.9 | 2018/06/21
+smi130_spi.c | 1.3 | 2018/06/21
+smi130_i2c.c | 1.3 | 2018/06/21
+smi130_driver.h | 1.3 | 2018/06/21
+smi130_driver.c | 1.3 | 2018/06/21
+bs_log.h | | 2018/06/21
+bs_log.c | | 2018/06/21
+boschclass.h | 1.5.9 | 2018/06/21
+boschclass.c | 1.5.9 | 2018/06/21
+
+## File information
+
+* smi130.h : The head file of SMI130API
+* smi130.c : Sensor Driver for SMI130 sensor
+* smi130_spi.c : This file implements moudle function, which add the driver to SPI core.
+* smi130_i2c.c : This file implements moudle function, which add the driver to I2C core.
+* smi130_driver.h : The head file of SMI130 device driver core code
+* smi130_driver.c : This file implements the core code of SMI130 device driver
+* bs_log.h : The head file of BOSCH SENSOR LOG
+* bs_log.c : The source file of BOSCH SENSOR LOG
+* boschclass.h :
+* boschclass.c :
+
+## Supported sensor interface
+
+* SPI 4-wire
+* I2C
+
+## Copyright
+
+Copyright (C) 2016 - 2017 Bosch Sensortec GmbH
+Modification Copyright (C) 2018 Robert Bosch Kft All Rights Reserved
+
+This software program is licensed subject to the GNU General
+Public License (GPL).Version 2,June 1991,
+available at http://www.fsf.org/copyleft/gpl.html
+
+Special: Description of the Software:
+
+This software module (hereinafter called "Software") and any
+information on application-sheets (hereinafter called "Information") is
+provided free of charge for the sole purpose to support your application
+work.
+
+As such, the Software is merely an experimental software, not tested for
+safety in the field and only intended for inspiration for further development
+and testing. Any usage in a safety-relevant field of use (like automotive,
+seafaring, spacefaring, industrial plants etc.) was not intended, so there are
+no precautions for such usage incorporated in the Software.
+
+The Software is specifically designed for the exclusive use for Bosch
+Sensortec products by personnel who have special experience and training. Do
+not use this Software if you do not have the proper experience or training.
+
+This Software package is provided as is and without any expressed or
+implied warranties, including without limitation, the implied warranties of
+merchantability and fitness for a particular purpose.
+
+Bosch Sensortec and their representatives and agents deny any liability for
+the functional impairment of this Software in terms of fitness, performance
+and safety. Bosch Sensortec and their representatives and agents shall not be
+liable for any direct or indirect damages or injury, except as otherwise
+stipulated in mandatory applicable law.
+The Information provided is believed to be accurate and reliable. Bosch
+Sensortec assumes no responsibility for the consequences of use of such
+Information nor for any infringement of patents or other rights of third
+parties which may result from its use.
+
+------------------------------------------------------------------------------
+The following Product Disclaimer does not apply to the Kernel Driver
+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
+
+Product Disclaimer
+
+Common:
+
+Assessment of Products Returned from Field
+
+Returned products are considered good if they fulfill the specifications /
+test data for 0-mileage and field listed in this document.
+
+Engineering Samples
+
+Engineering samples are marked with (e) or (E). Samples may vary from the
+valid technical specifications of the series product contained in this
+data sheet. Therefore, they are not intended or fit for resale to
+third parties or for use in end products. Their sole purpose is internal
+client testing. The testing of an engineering sample may in no way replace
+the testing of a series product. Bosch assumes no liability for the use
+of engineering samples. The purchaser shall indemnify Bosch from all claims
+arising from the use of engineering samples.
+
+Intended use
+
+Provided that SMI130 is used within the conditions (environment, application,
+installation, loads) as described in this TCD and the corresponding
+agreed upon documents, Bosch ensures that the product complies with
+the agreed properties. Agreements beyond this require
+the written approval by Bosch. The product is considered fit for the intended
+use when the product successfully has passed the tests
+in accordance with the TCD and agreed upon documents.
+
+It is the responsibility of the customer to ensure the proper application
+of the product in the overall system/vehicle.
+
+Bosch does not assume any responsibility for changes to the environment
+of the product that deviate from the TCD and the agreed upon documents
+as well as all applications not released by Bosch
+
+The resale and/or use of products are at the purchaser’s own risk and
+responsibility. The examination and testing of the SMI130
+is the sole responsibility of the purchaser.
+
+The purchaser shall indemnify Bosch from all third party claims
+arising from any product use not covered by the parameters of
+this product data sheet or not approved by Bosch and reimburse Bosch
+for all costs and damages in connection with such claims.
+
+The purchaser must monitor the market for the purchased products,
+particularly with regard to product safety, and inform Bosch without delay
+of all security relevant incidents.
+
+Application Examples and Hints
+
+With respect to any application examples, advice, normal values
+and/or any information regarding the application of the device,
+Bosch hereby disclaims any and all warranties and liabilities of any kind,
+including without limitation warranties of
+non-infringement of intellectual property rights or copyrights
+of any third party.
+The information given in this document shall in no event be regarded
+as a guarantee of conditions or characteristics. They are provided
+for illustrative purposes only and no evaluation regarding infringement
+of intellectual property rights or copyrights or regarding functionality,
+performance or error has been made.
\ No newline at end of file
diff --git a/drivers/input/sensors/smi130/smi130.c b/drivers/input/sensors/smi130/smi130.c
new file mode 100644
index 0000000..995b7d6
--- /dev/null
+++ b/drivers/input/sensors/smi130/smi130.c
@@ -0,0 +1,18788 @@
+/*
+* @section LICENSE
+* (C) Copyright 2011~2018 Bosch Sensortec GmbH All Rights Reserved
+*
+* (C) Modification Copyright 2018 Robert Bosch Kft All Rights Reserved
+*
+* This software program is licensed subject to the GNU General
+* Public License (GPL).Version 2,June 1991,
+* available at http://www.fsf.org/copyleft/gpl.html
+
+*
+* @filename smi130.c
+* @Date: 2015/04/02
+* @Modification Date 2018/06/21 15:03
+* @id 836294d
+* @Revision: 2.0.9 $
+*
+* Usage: Sensor Driver for SMI130 sensor
+*
+* Special: Description of the Software:
+*
+* This software module (hereinafter called "Software") and any
+* information on application-sheets (hereinafter called "Information") is
+* provided free of charge for the sole purpose to support your application
+* work.
+*
+* As such, the Software is merely an experimental software, not tested for
+* safety in the field and only intended for inspiration for further development
+* and testing. Any usage in a safety-relevant field of use (like automotive,
+* seafaring, spacefaring, industrial plants etc.) was not intended, so there are
+* no precautions for such usage incorporated in the Software.
+*
+* The Software is specifically designed for the exclusive use for Bosch
+* Sensortec products by personnel who have special experience and training. Do
+* not use this Software if you do not have the proper experience or training.
+*
+* This Software package is provided as is and without any expressed or
+* implied warranties, including without limitation, the implied warranties of
+* merchantability and fitness for a particular purpose.
+*
+* Bosch Sensortec and their representatives and agents deny any liability for
+* the functional impairment of this Software in terms of fitness, performance
+* and safety. Bosch Sensortec and their representatives and agents shall not be
+* liable for any direct or indirect damages or injury, except as otherwise
+* stipulated in mandatory applicable law.
+* The Information provided is believed to be accurate and reliable. Bosch
+* Sensortec assumes no responsibility for the consequences of use of such
+* Information nor for any infringement of patents or other rights of third
+* parties which may result from its use.
+*
+*------------------------------------------------------------------------------
+* The following Product Disclaimer does not apply to the BSX4-HAL-4.1NoFusion Software
+* which is licensed under the Apache License, Version 2.0 as stated above.
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Product Disclaimer
+*
+* Common:
+*
+* Assessment of Products Returned from Field
+*
+* Returned products are considered good if they fulfill the specifications /
+* test data for 0-mileage and field listed in this document.
+*
+* Engineering Samples
+*
+* Engineering samples are marked with (e) or (E). Samples may vary from the
+* valid technical specifications of the series product contained in this
+* data sheet. Therefore, they are not intended or fit for resale to
+* third parties or for use in end products. Their sole purpose is internal
+* client testing. The testing of an engineering sample may in no way replace
+* the testing of a series product. Bosch assumes no liability for the use
+* of engineering samples. The purchaser shall indemnify Bosch from all claims
+* arising from the use of engineering samples.
+*
+* Intended use
+*
+* Provided that SMI130 is used within the conditions (environment, application,
+* installation, loads) as described in this TCD and the corresponding
+* agreed upon documents, Bosch ensures that the product complies with
+* the agreed properties. Agreements beyond this require
+* the written approval by Bosch. The product is considered fit for the intended
+* use when the product successfully has passed the tests
+* in accordance with the TCD and agreed upon documents.
+*
+* It is the responsibility of the customer to ensure the proper application
+* of the product in the overall system/vehicle.
+*
+* Bosch does not assume any responsibility for changes to the environment
+* of the product that deviate from the TCD and the agreed upon documents
+* as well as all applications not released by Bosch
+*
+* The resale and/or use of products are at the purchaser’s own risk and
+* responsibility. The examination and testing of the SMI130
+* is the sole responsibility of the purchaser.
+*
+* The purchaser shall indemnify Bosch from all third party claims
+* arising from any product use not covered by the parameters of
+* this product data sheet or not approved by Bosch and reimburse Bosch
+* for all costs and damages in connection with such claims.
+*
+* The purchaser must monitor the market for the purchased products,
+* particularly with regard to product safety, and inform Bosch without delay
+* of all security relevant incidents.
+*
+* Application Examples and Hints
+*
+* With respect to any application examples, advice, normal values
+* and/or any information regarding the application of the device,
+* Bosch hereby disclaims any and all warranties and liabilities of any kind,
+* including without limitation warranties of
+* non-infringement of intellectual property rights or copyrights
+* of any third party.
+* The information given in this document shall in no event be regarded
+* as a guarantee of conditions or characteristics. They are provided
+* for illustrative purposes only and no evaluation regarding infringement
+* of intellectual property rights or copyrights or regarding functionality,
+* performance or error has been made.
+*
+*
+**************************************************************************/
+/*! file <SMI130 >
+ brief <Sensor driver for SMI130>*/
+#include "smi130.h"
+#include <linux/kernel.h>
+
+/* user defined code to be added here ...*/
+struct smi130_t*p_smi130;
+/* used for reading the mag trim values for compensation*/
+struct trim_data_t mag_trim;
+/* 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 = SMI130_INIT_VALUE;
+/* used for reading the AKM compensating data*/
+struct bosch_akm_sensitivity_data_t akm_asa_data;
+/* Assign the fifo time*/
+u32 V_fifo_time_U32 = SMI130_INIT_VALUE;
+
+/* FIFO data read for 1024 bytes of data*/
+u8 v_fifo_data_u8[FIFO_FRAME] = {SMI130_INIT_VALUE};
+/* YAMAHA-YAS532*/
+/* value of coeff*/
+static const int yas532_version_ac_coef[] = {YAS532_VERSION_AC_COEF_X,
+YAS532_VERSION_AC_COEF_Y1, YAS532_VERSION_AC_COEF_Y2};
+/* used for reading the yas532 calibration data*/
+struct yas532_t yas532_data;
+/* 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 smi130 : structure pointer
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+* @note
+* While changing the parameter of the smi130_t
+* consider the following point:
+* Changing the reference value of the parameter
+* will changes the local copy or local reference
+* make sure your changes will not
+* affect the reference value of the parameter
+* (Better case don't change the reference value of the parameter)
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_init(struct smi130_t*smi130)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ u8 v_pmu_data_u8 = SMI130_INIT_VALUE;
+ /* assign smi130 ptr*/
+ p_smi130 = smi130;
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_CHIP_ID__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ /* read Chip Id*/
+ p_smi130->chip_id = v_data_u8;
+ /* To avoid gyro wakeup it is required to write 0x00 to 0x6C*/
+ com_rslt += smi130_write_reg(SMI130_USER_PMU_TRIGGER_ADDR,
+ &v_pmu_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ return com_rslt;
+}
+/*!
+* @brief
+* This API write the data to
+* the given register
+*
+*
+* @param v_addr_u8 -> Address of the register
+* @param v_data_u8 -> The data from the register
+* @param v_len_u8 -> no of bytes to read
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_write_reg(u8 v_addr_u8,
+u8*v_data_u8, u8 v_len_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write data from register*/
+ com_rslt =
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->dev_addr,
+ v_addr_u8, v_data_u8, v_len_u8);
+ }
+ return com_rslt;
+}
+/*!
+* @brief
+* This API reads the data from
+* the given register
+*
+*
+* @param v_addr_u8 -> Address of the register
+* @param v_data_u8 -> The data from the register
+* @param v_len_u8 -> no of bytes to read
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_reg(u8 v_addr_u8,
+u8*v_data_u8, u8 v_len_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* Read data from register*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ v_addr_u8, v_data_u8, v_len_u8);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API used to reads the fatal error
+* from the Register 0x02 bit 0
+* This flag will be reset only by power-on-reset and soft reset
+*
+*
+* @param v_fatal_err_u8 : The status of fatal error
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fatal_err(u8
+*v_fatal_err_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* reading the fatal error status*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FATAL_ERR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fatal_err_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FATAL_ERR);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API used to read the error code
+* from register 0x02 bit 1 to 4
+*
+*
+* @param v_err_code_u8 : The status of error codes
+* error_code | description
+* ------------|---------------
+* 0x00 |no error
+* 0x01 |ACC_CONF error (accel ODR and bandwidth not compatible)
+* 0x02 |GYR_CONF error (Gyroscope ODR and bandwidth not compatible)
+* 0x03 |Under sampling mode and interrupt uses pre filtered data
+* 0x04 |reserved
+* 0x05 |Selected trigger-readout offset in
+* - |MAG_IF greater than selected ODR
+* 0x06 |FIFO configuration error for header less mode
+* 0x07 |Under sampling mode and pre filtered data as FIFO source
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_err_code(u8
+*v_err_code_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_ERR_CODE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_err_code_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_ERR_CODE);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API Reads the i2c error code from the
+* Register 0x02 bit 5.
+* This error occurred in I2C master detected
+*
+* @param v_i2c_err_code_u8 : The status of i2c fail error
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_i2c_fail_err(u8
+*v_i2c_err_code_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_I2C_FAIL_ERR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_i2c_err_code_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_I2C_FAIL_ERR);
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API Reads the dropped command error
+* from the register 0x02 bit 6
+*
+*
+* @param v_drop_cmd_err_u8 : The status of drop command error
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_drop_cmd_err(u8
+*v_drop_cmd_err_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_DROP_CMD_ERR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_drop_cmd_err_u8 = SMI130_GET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_DROP_CMD_ERR);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the magnetometer data ready
+* interrupt not active.
+* It reads from the error register 0x0x2 bit 7
+*
+*
+*
+*
+* @param v_mag_data_rdy_err_u8 : The status of mag data ready interrupt
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_dada_rdy_err(
+u8*v_mag_data_rdy_err_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_MAG_DADA_RDY_ERR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_mag_data_rdy_err_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_MAG_DADA_RDY_ERR);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the error status
+* from the error register 0x02 bit 0 to 7
+*
+* @param v_mag_data_rdy_err_u8 : The status of mag data ready interrupt
+* @param v_fatal_er_u8r : The status of fatal error
+* @param v_err_code_u8 : The status of error code
+* @param v_i2c_fail_err_u8 : The status of I2C fail error
+* @param v_drop_cmd_err_u8 : The status of drop command error
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_error_status(u8*v_fatal_er_u8r,
+u8*v_err_code_u8, u8*v_i2c_fail_err_u8,
+u8*v_drop_cmd_err_u8, u8*v_mag_data_rdy_err_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the error codes*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_ERR_STAT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ /* fatal error*/
+ *v_fatal_er_u8r =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FATAL_ERR);
+ /* user error*/
+ *v_err_code_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_ERR_CODE);
+ /* i2c fail error*/
+ *v_i2c_fail_err_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_I2C_FAIL_ERR);
+ /* drop command error*/
+ *v_drop_cmd_err_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_DROP_CMD_ERR);
+ /* mag data ready error*/
+ *v_mag_data_rdy_err_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_MAG_DADA_RDY_ERR);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the magnetometer power mode from
+* PMU status register 0x03 bit 0 and 1
+*
+* @param v_mag_power_mode_stat_u8 : The value of mag power mode
+* mag_powermode | value
+* ------------------|----------
+* SUSPEND | 0x00
+* NORMAL | 0x01
+* LOW POWER | 0x02
+*
+*
+* @note The power mode of mag set by the 0x7E command register
+* @note using the function "smi130_set_command_register()"
+* value | mode
+* ---------|----------------
+* 0x18 | MAG_MODE_SUSPEND
+* 0x19 | MAG_MODE_NORMAL
+* 0x1A | MAG_MODE_LOWPOWER
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_power_mode_stat(u8
+*v_mag_power_mode_stat_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_MAG_POWER_MODE_STAT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_mag_power_mode_stat_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_MAG_POWER_MODE_STAT);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the gyroscope power mode from
+* PMU status register 0x03 bit 2 and 3
+*
+* @param v_gyro_power_mode_stat_u8 : The value of gyro power mode
+* gyro_powermode | value
+* ------------------|----------
+* SUSPEND | 0x00
+* NORMAL | 0x01
+* FAST POWER UP | 0x03
+*
+* @note The power mode of gyro set by the 0x7E command register
+* @note using the function "smi130_set_command_register()"
+* value | mode
+* ---------|----------------
+* 0x14 | GYRO_MODE_SUSPEND
+* 0x15 | GYRO_MODE_NORMAL
+* 0x17 | GYRO_MODE_FASTSTARTUP
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_power_mode_stat(u8
+*v_gyro_power_mode_stat_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_GYRO_POWER_MODE_STAT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_gyro_power_mode_stat_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_GYRO_POWER_MODE_STAT);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the accelerometer power mode from
+* PMU status register 0x03 bit 4 and 5
+*
+*
+* @param v_accel_power_mode_stat_u8 : The value of accel power mode
+* accel_powermode | value
+* ------------------|----------
+* SUSPEND | 0x00
+* NORMAL | 0x01
+* LOW POWER | 0x02
+*
+* @note The power mode of accel set by the 0x7E command register
+* @note using the function "smi130_set_command_register()"
+* value | mode
+* ---------|----------------
+* 0x11 | ACCEL_MODE_NORMAL
+* 0x12 | ACCEL_LOWPOWER
+* 0x10 | ACCEL_SUSPEND
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_power_mode_stat(u8
+*v_accel_power_mode_stat_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_ACCEL_POWER_MODE_STAT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_power_mode_stat_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_ACCEL_POWER_MODE_STAT);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API switch mag interface to normal mode
+* and confirm whether the mode switching done successfully or not
+*
+* @return results of bus communication function and current MAG_PMU result
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_interface_normal(void)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = SMI130_INIT_VALUE;
+ /* aim to check the result of switching mag normal*/
+ u8 v_try_times_u8 = SMI130_MAG_NOAMRL_SWITCH_TIMES;
+ u8 v_mag_pum_status_u8 = SMI130_INIT_VALUE;
+
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt = smi130_set_command_register(MAG_MODE_NORMAL);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ while (v_try_times_u8) {
+ com_rslt = smi130_get_mag_power_mode_stat(&v_mag_pum_status_u8);
+ if (v_mag_pum_status_u8 == MAG_INTERFACE_PMU_ENABLE)
+ break;
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ v_try_times_u8--;
+ }
+ if (v_mag_pum_status_u8 == MAG_INTERFACE_PMU_ENABLE)
+ com_rslt += SUCCESS;
+ else
+ com_rslt += E_SMI130_COMM_RES;
+
+ return com_rslt;
+}
+/*!
+* @brief This API reads magnetometer data X values
+* from the register 0x04 and 0x05
+* @brief The mag sensor data read form auxiliary mag
+*
+* @param v_mag_x_s16 : The value of mag x
+* @param v_sensor_select_u8 : Mag selection value
+* value | sensor
+* ---------|----------------
+* 0 | BMM150
+* 1 | AKM09911 or AKM09912
+*
+* @note For mag data output rate configuration use the following function
+* @note smi130_set_mag_output_data_rate()
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_mag_x(s16*v_mag_x_s16,
+u8 v_sensor_select_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the mag X lSB and MSB data
+ v_data_u8[0] - LSB
+ v_data_u8[1] - MSB*/
+ u8 v_data_u8[SMI130_MAG_X_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_sensor_select_u8) {
+ case BST_BMM:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_DATA_MAG_X_LSB__REG,
+ v_data_u8, SMI130_MAG_X_DATA_LENGTH);
+ /* X axis*/
+ v_data_u8[SMI130_MAG_X_LSB_BYTE] =
+ SMI130_GET_BITSLICE(v_data_u8[SMI130_MAG_X_LSB_BYTE],
+ SMI130_USER_DATA_MAG_X_LSB);
+ *v_mag_x_s16 = (s16)
+ ((((s32)((s8)v_data_u8[SMI130_MAG_X_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_05_BITS) |
+ (v_data_u8[SMI130_MAG_X_LSB_BYTE]));
+ break;
+ case BST_AKM:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_DATA_0_MAG_X_LSB__REG,
+ v_data_u8, SMI130_MAG_X_DATA_LENGTH);
+ *v_mag_x_s16 = (s16)
+ ((((s32)((s8)v_data_u8[SMI130_MAG_X_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[SMI130_MAG_X_LSB_BYTE]));
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads magnetometer data Y values
+* from the register 0x06 and 0x07
+* @brief The mag sensor data read form auxiliary mag
+*
+* @param v_mag_y_s16 : The value of mag y
+* @param v_sensor_select_u8 : Mag selection value
+* value | sensor
+* ---------|----------------
+* 0 | BMM150
+* 1 | AKM09911 or AKM09912
+*
+* @note For mag data output rate configuration use the following function
+* @note smi130_set_mag_output_data_rate()
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_mag_y(s16*v_mag_y_s16,
+u8 v_sensor_select_u8)
+{
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_OUT_OF_RANGE;
+ /* Array contains the mag Y lSB and MSB data
+ v_data_u8[0] - LSB
+ v_data_u8[1] - MSB*/
+ u8 v_data_u8[SMI130_MAG_Y_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_sensor_select_u8) {
+ case BST_BMM:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_DATA_MAG_Y_LSB__REG,
+ v_data_u8, SMI130_MAG_Y_DATA_LENGTH);
+ /*Y-axis lsb value shifting*/
+ v_data_u8[SMI130_MAG_Y_LSB_BYTE] =
+ SMI130_GET_BITSLICE(v_data_u8[SMI130_MAG_Y_LSB_BYTE],
+ SMI130_USER_DATA_MAG_Y_LSB);
+ *v_mag_y_s16 = (s16)
+ ((((s32)((s8)v_data_u8[SMI130_MAG_Y_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_05_BITS) |
+ (v_data_u8[SMI130_MAG_Y_LSB_BYTE]));
+ break;
+ case BST_AKM:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_DATA_2_MAG_Y_LSB__REG,
+ v_data_u8, SMI130_MAG_Y_DATA_LENGTH);
+ *v_mag_y_s16 = (s16)
+ ((((s32)((s8)v_data_u8[SMI130_MAG_Y_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[SMI130_MAG_Y_LSB_BYTE]));
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads magnetometer data Z values
+* from the register 0x08 and 0x09
+* @brief The mag sensor data read form auxiliary mag
+*
+* @param v_mag_z_s16 : The value of mag z
+* @param v_sensor_select_u8 : Mag selection value
+* value | sensor
+* ---------|----------------
+* 0 | BMM150
+* 1 | AKM09911 or AKM09912
+*
+* @note For mag data output rate configuration use the following function
+* @note smi130_set_mag_output_data_rate()
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_mag_z(s16*v_mag_z_s16,
+u8 v_sensor_select_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the mag Z lSB and MSB data
+ v_data_u8[0] - LSB
+ v_data_u8[1] - MSB*/
+ u8 v_data_u8[SMI130_MAG_Z_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_sensor_select_u8) {
+ case BST_BMM:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_DATA_MAG_Z_LSB__REG,
+ v_data_u8, SMI130_MAG_Z_DATA_LENGTH);
+ /*Z-axis lsb value shifting*/
+ v_data_u8[SMI130_MAG_Z_LSB_BYTE] =
+ SMI130_GET_BITSLICE(v_data_u8[SMI130_MAG_Z_LSB_BYTE],
+ SMI130_USER_DATA_MAG_Z_LSB);
+ *v_mag_z_s16 = (s16)
+ ((((s32)((s8)v_data_u8[SMI130_MAG_Z_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_07_BITS) |
+ (v_data_u8[SMI130_MAG_Z_LSB_BYTE]));
+ break;
+ case BST_AKM:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_DATA_4_MAG_Z_LSB__REG,
+ v_data_u8, SMI130_MAG_Z_DATA_LENGTH);
+ *v_mag_z_s16 = (s16)
+ ((((s32)((s8)v_data_u8[SMI130_MAG_Z_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) | (
+ v_data_u8[SMI130_MAG_Z_LSB_BYTE]));
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads magnetometer data RHALL values
+* from the register 0x0A and 0x0B
+*
+*
+* @param v_mag_r_s16 : The value of BMM150 r data
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_mag_r(s16*v_mag_r_s16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the mag R lSB and MSB data
+ v_data_u8[0] - LSB
+ v_data_u8[1] - MSB*/
+ u8 v_data_u8[SMI130_MAG_R_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_DATA_6_RHALL_LSB__REG,
+ v_data_u8, SMI130_MAG_R_DATA_LENGTH);
+ /*R-axis lsb value shifting*/
+ v_data_u8[SMI130_MAG_R_LSB_BYTE] =
+ SMI130_GET_BITSLICE(v_data_u8[SMI130_MAG_R_LSB_BYTE],
+ SMI130_USER_DATA_MAG_R_LSB);
+ *v_mag_r_s16 = (s16)
+ ((((s32)((s8)v_data_u8[SMI130_MAG_R_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_06_BITS) |
+ (v_data_u8[SMI130_MAG_R_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads magnetometer data X,Y,Z values
+* from the register 0x04 to 0x09
+*
+* @brief The mag sensor data read form auxiliary mag
+*
+* @param mag : The value of mag xyz data
+* @param v_sensor_select_u8 : Mag selection value
+* value | sensor
+* ---------|----------------
+* 0 | BMM150
+* 1 | AKM09911 or AKM09912
+*
+* @note For mag data output rate configuration use the following function
+* @note smi130_set_mag_output_data_rate()
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_mag_xyz(
+struct smi130_mag_t*mag, u8 v_sensor_select_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the mag XYZ lSB and MSB data
+ v_data_u8[0] - X-LSB
+ v_data_u8[1] - X-MSB
+ v_data_u8[0] - Y-LSB
+ v_data_u8[1] - Y-MSB
+ v_data_u8[0] - Z-LSB
+ v_data_u8[1] - Z-MSB
+ */
+ u8 v_data_u8[SMI130_MAG_XYZ_DATA_SIZE] = {
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_sensor_select_u8) {
+ case BST_BMM:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_DATA_MAG_X_LSB__REG,
+ v_data_u8, SMI130_MAG_XYZ_DATA_LENGTH);
+ /*X-axis lsb value shifting*/
+ v_data_u8[SMI130_DATA_FRAME_MAG_X_LSB_BYTE] =
+ SMI130_GET_BITSLICE(
+ v_data_u8[SMI130_DATA_FRAME_MAG_X_LSB_BYTE],
+ SMI130_USER_DATA_MAG_X_LSB);
+ /* Data X*/
+ mag->x = (s16)
+ ((((s32)((s8)v_data_u8[
+ SMI130_DATA_FRAME_MAG_X_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_05_BITS) |
+ (v_data_u8[SMI130_DATA_FRAME_MAG_X_LSB_BYTE]));
+ /* Data Y*/
+ /*Y-axis lsb value shifting*/
+ v_data_u8[SMI130_DATA_FRAME_MAG_Y_LSB_BYTE] =
+ SMI130_GET_BITSLICE(
+ v_data_u8[SMI130_DATA_FRAME_MAG_Y_LSB_BYTE],
+ SMI130_USER_DATA_MAG_Y_LSB);
+ mag->y = (s16)
+ ((((s32)((s8)v_data_u8[
+ SMI130_DATA_FRAME_MAG_Y_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_05_BITS) |
+ (v_data_u8[SMI130_DATA_FRAME_MAG_Y_LSB_BYTE]));
+
+ /* Data Z*/
+ /*Z-axis lsb value shifting*/
+ v_data_u8[SMI130_DATA_FRAME_MAG_Z_LSB_BYTE]
+ = SMI130_GET_BITSLICE(
+ v_data_u8[SMI130_DATA_FRAME_MAG_Z_LSB_BYTE],
+ SMI130_USER_DATA_MAG_Z_LSB);
+ mag->z = (s16)
+ ((((s32)((s8)v_data_u8[
+ SMI130_DATA_FRAME_MAG_Z_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_07_BITS) |
+ (v_data_u8[SMI130_DATA_FRAME_MAG_Z_LSB_BYTE]));
+ break;
+ case BST_AKM:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_DATA_0_MAG_X_LSB__REG,
+ v_data_u8, SMI130_MAG_XYZ_DATA_LENGTH);
+ /* Data X*/
+ mag->x = (s16)
+ ((((s32)((s8)v_data_u8[
+ SMI130_DATA_FRAME_MAG_X_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[SMI130_DATA_FRAME_MAG_X_LSB_BYTE]));
+ /* Data Y*/
+ mag->y = ((((s32)((s8)v_data_u8[
+ SMI130_DATA_FRAME_MAG_Y_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[SMI130_DATA_FRAME_MAG_Y_LSB_BYTE]));
+ /* Data Z*/
+ mag->z = (s16)
+ ((((s32)((s8)v_data_u8[
+ SMI130_DATA_FRAME_MAG_Z_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[SMI130_DATA_FRAME_MAG_Z_LSB_BYTE]));
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+ /*!*
+* @brief This API reads magnetometer data X,Y,Z,r
+* values from the register 0x04 to 0x0B
+*
+* @brief The mag sensor data read form auxiliary mag
+*
+* @param mag : The value of mag-BMM150 xyzr data
+*
+* @note For mag data output rate configuration use the following function
+* @note smi130_set_mag_output_data_rate()
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_mag_xyzr(
+struct smi130_mag_xyzr_t*mag)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8[SMI130_MAG_XYZR_DATA_SIZE] = {
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_DATA_MAG_X_LSB__REG,
+ v_data_u8, SMI130_MAG_XYZR_DATA_LENGTH);
+
+ /* Data X*/
+ /*X-axis lsb value shifting*/
+ v_data_u8[SMI130_DATA_FRAME_MAG_X_LSB_BYTE]
+ = SMI130_GET_BITSLICE(
+ v_data_u8[SMI130_DATA_FRAME_MAG_X_LSB_BYTE],
+ SMI130_USER_DATA_MAG_X_LSB);
+ mag->x = (s16)
+ ((((s32)((s8)v_data_u8[
+ SMI130_DATA_FRAME_MAG_X_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_05_BITS)
+ | (v_data_u8[SMI130_DATA_FRAME_MAG_X_LSB_BYTE]));
+ /* Data Y*/
+ /*Y-axis lsb value shifting*/
+ v_data_u8[SMI130_DATA_FRAME_MAG_Y_LSB_BYTE]
+ = SMI130_GET_BITSLICE(
+ v_data_u8[SMI130_DATA_FRAME_MAG_Y_LSB_BYTE],
+ SMI130_USER_DATA_MAG_Y_LSB);
+ mag->y = (s16)
+ ((((s32)((s8)v_data_u8[
+ SMI130_DATA_FRAME_MAG_Y_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_05_BITS)
+ | (v_data_u8[
+ SMI130_DATA_FRAME_MAG_Y_LSB_BYTE]));
+
+ /* Data Z*/
+ /*Z-axis lsb value shifting*/
+ v_data_u8[SMI130_DATA_FRAME_MAG_Z_LSB_BYTE]
+ = SMI130_GET_BITSLICE(
+ v_data_u8[SMI130_DATA_FRAME_MAG_Z_LSB_BYTE],
+ SMI130_USER_DATA_MAG_Z_LSB);
+ mag->z = (s16)
+ ((((s32)((s8)v_data_u8[
+ SMI130_DATA_FRAME_MAG_Z_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_07_BITS)
+ | (v_data_u8[SMI130_DATA_FRAME_MAG_Z_LSB_BYTE]));
+
+ /* RHall*/
+ /*R-axis lsb value shifting*/
+ v_data_u8[SMI130_DATA_FRAME_MAG_R_LSB_BYTE]
+ = SMI130_GET_BITSLICE(
+ v_data_u8[SMI130_DATA_FRAME_MAG_R_LSB_BYTE],
+ SMI130_USER_DATA_MAG_R_LSB);
+ mag->r = (s16)
+ ((((s32)((s8)v_data_u8[
+ SMI130_DATA_FRAME_MAG_R_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_06_BITS)
+ | (v_data_u8[SMI130_DATA_FRAME_MAG_R_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads gyro data X values
+* form the register 0x0C and 0x0D
+*
+*
+*
+*
+* @param v_gyro_x_s16 : The value of gyro x data
+*
+* @note Gyro Configuration use the following function
+* @note smi130_set_gyro_output_data_rate()
+* @note smi130_set_gyro_bw()
+* @note smi130_set_gyro_range()
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_gyro_x(s16*v_gyro_x_s16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the gyro X lSB and MSB data
+ v_data_u8[0] - LSB
+ v_data_u8[MSB_ONE] - MSB*/
+ u8 v_data_u8[SMI130_GYRO_X_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_DATA_8_GYRO_X_LSB__REG,
+ v_data_u8, SMI130_GYRO_DATA_LENGTH);
+
+ *v_gyro_x_s16 = (s16)
+ ((((s32)((s8)v_data_u8[SMI130_GYRO_X_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (v_data_u8[SMI130_GYRO_X_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads gyro data Y values
+* form the register 0x0E and 0x0F
+*
+*
+*
+*
+* @param v_gyro_y_s16 : The value of gyro y data
+*
+* @note Gyro Configuration use the following function
+* @note smi130_set_gyro_output_data_rate()
+* @note smi130_set_gyro_bw()
+* @note smi130_set_gyro_range()
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error result of communication routines
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_gyro_y(s16*v_gyro_y_s16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the gyro Y lSB and MSB data
+ v_data_u8[LSB_ZERO] - LSB
+ v_data_u8[MSB_ONE] - MSB*/
+ u8 v_data_u8[SMI130_GYRO_Y_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read gyro y data*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_DATA_10_GYRO_Y_LSB__REG,
+ v_data_u8, SMI130_GYRO_DATA_LENGTH);
+
+ *v_gyro_y_s16 = (s16)
+ ((((s32)((s8)v_data_u8[SMI130_GYRO_Y_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (v_data_u8[SMI130_GYRO_Y_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads gyro data Z values
+* form the register 0x10 and 0x11
+*
+*
+*
+*
+* @param v_gyro_z_s16 : The value of gyro z data
+*
+* @note Gyro Configuration use the following function
+* @note smi130_set_gyro_output_data_rate()
+* @note smi130_set_gyro_bw()
+* @note smi130_set_gyro_range()
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_gyro_z(s16*v_gyro_z_s16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the gyro Z lSB and MSB data
+ v_data_u8[LSB_ZERO] - LSB
+ v_data_u8[MSB_ONE] - MSB*/
+ u8 v_data_u8[SMI130_GYRO_Z_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read gyro z data*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_DATA_12_GYRO_Z_LSB__REG,
+ v_data_u8, SMI130_GYRO_DATA_LENGTH);
+
+ *v_gyro_z_s16 = (s16)
+ ((((s32)((s8)v_data_u8[SMI130_GYRO_Z_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (v_data_u8[SMI130_GYRO_Z_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads gyro data X,Y,Z values
+* from the register 0x0C to 0x11
+*
+*
+*
+*
+* @param gyro : The value of gyro xyz
+*
+* @note Gyro Configuration use the following function
+* @note smi130_set_gyro_output_data_rate()
+* @note smi130_set_gyro_bw()
+* @note smi130_set_gyro_range()
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_gyro_xyz(struct smi130_gyro_t*gyro)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the mag XYZ lSB and MSB data
+ v_data_u8[0] - X-LSB
+ v_data_u8[1] - X-MSB
+ v_data_u8[0] - Y-LSB
+ v_data_u8[1] - Y-MSB
+ v_data_u8[0] - Z-LSB
+ v_data_u8[1] - Z-MSB
+ */
+ u8 v_data_u8[SMI130_GYRO_XYZ_DATA_SIZE] = {
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the gyro xyz data*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_DATA_8_GYRO_X_LSB__REG,
+ v_data_u8, SMI130_GYRO_XYZ_DATA_LENGTH);
+
+ /* Data X*/
+ gyro->x = (s16)
+ ((((s32)((s8)v_data_u8[
+ SMI130_DATA_FRAME_GYRO_X_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (v_data_u8[SMI130_DATA_FRAME_GYRO_X_LSB_BYTE]));
+ /* Data Y*/
+ gyro->y = (s16)
+ ((((s32)((s8)v_data_u8[
+ SMI130_DATA_FRAME_GYRO_Y_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (v_data_u8[SMI130_DATA_FRAME_GYRO_Y_LSB_BYTE]));
+
+ /* Data Z*/
+ gyro->z = (s16)
+ ((((s32)((s8)v_data_u8[
+ SMI130_DATA_FRAME_GYRO_Z_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (v_data_u8[SMI130_DATA_FRAME_GYRO_Z_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads accelerometer data X values
+* form the register 0x12 and 0x13
+*
+*
+*
+*
+* @param v_accel_x_s16 : The value of accel x
+*
+* @note For accel configuration use the following functions
+* @note smi130_set_accel_output_data_rate()
+* @note smi130_set_accel_bw()
+* @note smi130_set_accel_under_sampling_parameter()
+* @note smi130_set_accel_range()
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_accel_x(s16*v_accel_x_s16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the accel X lSB and MSB data
+ v_data_u8[0] - LSB
+ v_data_u8[1] - MSB*/
+ u8 v_data_u8[SMI130_ACCEL_X_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_DATA_14_ACCEL_X_LSB__REG,
+ v_data_u8, SMI130_ACCEL_DATA_LENGTH);
+
+ *v_accel_x_s16 = (s16)
+ ((((s32)((s8)v_data_u8[SMI130_ACCEL_X_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (v_data_u8[SMI130_ACCEL_X_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads accelerometer data Y values
+* form the register 0x14 and 0x15
+*
+*
+*
+*
+* @param v_accel_y_s16 : The value of accel y
+*
+* @note For accel configuration use the following functions
+* @note smi130_set_accel_output_data_rate()
+* @note smi130_set_accel_bw()
+* @note smi130_set_accel_under_sampling_parameter()
+* @note smi130_set_accel_range()
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_accel_y(s16*v_accel_y_s16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the accel Y lSB and MSB data
+ v_data_u8[0] - LSB
+ v_data_u8[1] - MSB*/
+ u8 v_data_u8[SMI130_ACCEL_Y_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_DATA_16_ACCEL_Y_LSB__REG,
+ v_data_u8, SMI130_ACCEL_DATA_LENGTH);
+
+ *v_accel_y_s16 = (s16)
+ ((((s32)((s8)v_data_u8[SMI130_ACCEL_Y_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (v_data_u8[SMI130_ACCEL_Y_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads accelerometer data Z values
+* form the register 0x16 and 0x17
+*
+*
+*
+*
+* @param v_accel_z_s16 : The value of accel z
+*
+* @note For accel configuration use the following functions
+* @note smi130_set_accel_output_data_rate()
+* @note smi130_set_accel_bw()
+* @note smi130_set_accel_under_sampling_parameter()
+* @note smi130_set_accel_range()
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_accel_z(s16*v_accel_z_s16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the accel Z lSB and MSB data
+ a_data_u8r[LSB_ZERO] - LSB
+ a_data_u8r[MSB_ONE] - MSB*/
+ u8 a_data_u8r[SMI130_ACCEL_Z_DATA_SIZE] = {
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_DATA_18_ACCEL_Z_LSB__REG,
+ a_data_u8r, SMI130_ACCEL_DATA_LENGTH);
+
+ *v_accel_z_s16 = (s16)
+ ((((s32)((s8)a_data_u8r[SMI130_ACCEL_Z_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (a_data_u8r[SMI130_ACCEL_Z_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads accelerometer data X,Y,Z values
+* from the register 0x12 to 0x17
+*
+*
+*
+*
+* @param accel :The value of accel xyz
+*
+* @note For accel configuration use the following functions
+* @note smi130_set_accel_output_data_rate()
+* @note smi130_set_accel_bw()
+* @note smi130_set_accel_under_sampling_parameter()
+* @note smi130_set_accel_range()
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_accel_xyz(
+struct smi130_accel_t*accel)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the accel XYZ lSB and MSB data
+ a_data_u8r[0] - X-LSB
+ a_data_u8r[1] - X-MSB
+ a_data_u8r[0] - Y-LSB
+ a_data_u8r[1] - Y-MSB
+ a_data_u8r[0] - Z-LSB
+ a_data_u8r[1] - Z-MSB
+ */
+ u8 a_data_u8r[SMI130_ACCEL_XYZ_DATA_SIZE] = {
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_DATA_14_ACCEL_X_LSB__REG,
+ a_data_u8r, SMI130_ACCEL_XYZ_DATA_LENGTH);
+
+ /* Data X*/
+ accel->x = (s16)
+ ((((s32)((s8)a_data_u8r[
+ SMI130_DATA_FRAME_ACCEL_X_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (a_data_u8r[SMI130_DATA_FRAME_ACCEL_X_LSB_BYTE]));
+ /* Data Y*/
+ accel->y = (s16)
+ ((((s32)((s8)a_data_u8r[
+ SMI130_DATA_FRAME_ACCEL_Y_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (a_data_u8r[SMI130_DATA_FRAME_ACCEL_Y_LSB_BYTE]));
+
+ /* Data Z*/
+ accel->z = (s16)
+ ((((s32)((s8)a_data_u8r[
+ SMI130_DATA_FRAME_ACCEL_Z_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (a_data_u8r[SMI130_DATA_FRAME_ACCEL_Z_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads sensor_time from the register
+* 0x18 to 0x1A
+*
+*
+* @param v_sensor_time_u32 : The value of sensor time
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_sensor_time(u32*v_sensor_time_u32)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the sensor time it is 32 bit data
+ a_data_u8r[0] - sensor time
+ a_data_u8r[1] - sensor time
+ a_data_u8r[0] - sensor time
+ */
+ u8 a_data_u8r[SMI130_SENSOR_TIME_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_SENSORTIME_0_SENSOR_TIME_LSB__REG,
+ a_data_u8r, SMI130_SENSOR_TIME_LENGTH);
+
+ *v_sensor_time_u32 = (u32)
+ ((((u32)a_data_u8r[SMI130_SENSOR_TIME_MSB_BYTE])
+ << SMI130_SHIFT_BIT_POSITION_BY_16_BITS)
+ |(((u32)a_data_u8r[SMI130_SENSOR_TIME_XLSB_BYTE])
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (a_data_u8r[SMI130_SENSOR_TIME_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the Gyroscope self test
+* status from the register 0x1B bit 1
+*
+*
+* @param v_gyro_selftest_u8 : The value of gyro self test status
+* value | status
+* ---------|----------------
+* 0 | Gyroscope self test is running or failed
+* 1 | Gyroscope self test completed successfully
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_selftest(u8
+*v_gyro_selftest_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_STAT_GYRO_SELFTEST_OK__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_gyro_selftest_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_STAT_GYRO_SELFTEST_OK);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the status of
+* mag manual interface operation form the register 0x1B bit 2
+*
+*
+*
+* @param v_mag_manual_stat_u8 : The value of mag manual operation status
+* value | status
+* ---------|----------------
+* 0 | Indicates no manual magnetometer
+* - | interface operation is ongoing
+* 1 | Indicates manual magnetometer
+* - | interface operation is ongoing
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_manual_operation_stat(u8
+*v_mag_manual_stat_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read manual operation*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_STAT_MAG_MANUAL_OPERATION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_mag_manual_stat_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_STAT_MAG_MANUAL_OPERATION);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the fast offset compensation
+* status form the register 0x1B bit 3
+*
+*
+* @param v_foc_rdy_u8 : The status of fast compensation
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_foc_rdy(u8
+*v_foc_rdy_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the FOC status*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_STAT_FOC_RDY__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_foc_rdy_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_STAT_FOC_RDY);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API Reads the nvm_rdy status from the
+* resister 0x1B bit 4
+*
+*
+* @param v_nvm_rdy_u8 : The value of NVM ready status
+* value | status
+* ---------|----------------
+* 0 | NVM write operation in progress
+* 1 | NVM is ready to accept a new write trigger
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_nvm_rdy(u8
+*v_nvm_rdy_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the nvm ready status*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_STAT_NVM_RDY__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_nvm_rdy_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_STAT_NVM_RDY);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the status of mag data ready
+* from the register 0x1B bit 5
+* The status get reset when one mag data register is read out
+*
+* @param v_data_rdy_u8 : The value of mag data ready status
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_data_rdy_mag(u8
+*v_data_rdy_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_STAT_DATA_RDY_MAG__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_data_rdy_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_STAT_DATA_RDY_MAG);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the status of gyro data ready form the
+* register 0x1B bit 6
+* The status get reset when gyro data register read out
+*
+*
+* @param v_data_rdy_u8 : The value of gyro data ready
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_data_rdy(u8
+*v_data_rdy_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_STAT_DATA_RDY_GYRO__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_data_rdy_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_STAT_DATA_RDY_GYRO);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the status of accel data ready form the
+* register 0x1B bit 7
+* The status get reset when accel data register read out
+*
+*
+* @param v_data_rdy_u8 : The value of accel data ready status
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_data_rdy(u8
+*v_data_rdy_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /*reads the status of accel data ready*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_STAT_DATA_RDY_ACCEL__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_data_rdy_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_STAT_DATA_RDY_ACCEL);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the step detector interrupt status
+* from the register 0x1C bit 0
+* flag is associated with a specific interrupt function.
+* It is set when the single tab interrupt triggers. The
+* setting of INT_LATCH controls if the interrupt
+* signal and hence the
+* respective interrupt flag will be
+* permanently latched, temporarily latched
+* or not latched.
+*
+*
+*
+*
+* @param v_step_intr_u8 : The status of step detector interrupt
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_step_intr(u8
+*v_step_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_0_STEP_INTR__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_step_intr_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_0_STEP_INTR);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the
+* significant motion interrupt status
+* from the register 0x1C bit 1
+* flag is associated with a specific interrupt function.
+* It is set when the single tab interrupt triggers. The
+* setting of INT_LATCH controls if the interrupt
+* signal and hence the
+* respective interrupt flag will be
+* permanently latched, temporarily latched
+* or not latched.
+*
+*
+*
+*
+*
+* @param v_significant_intr_u8 : The status of step
+* motion interrupt
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_significant_intr(u8
+*v_significant_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_0_SIGNIFICANT_INTR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_significant_intr_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_0_SIGNIFICANT_INTR);
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API reads the any motion interrupt status
+* from the register 0x1C bit 2
+* flag is associated with a specific interrupt function.
+* It is set when the single tab interrupt triggers. The
+* setting of INT_LATCH controls if the interrupt
+* signal and hence the
+* respective interrupt flag will be
+* permanently latched, temporarily latched
+* or not latched.
+*
+*
+*
+* @param v_any_motion_intr_u8 : The status of any-motion interrupt
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_any_motion_intr(u8
+*v_any_motion_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_0_ANY_MOTION__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_any_motion_intr_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_0_ANY_MOTION);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the power mode trigger interrupt status
+* from the register 0x1C bit 3
+* flag is associated with a specific interrupt function.
+* It is set when the single tab interrupt triggers. The
+* setting of INT_LATCH controls if the interrupt
+* signal and hence the
+* respective interrupt flag will be
+* permanently latched, temporarily latched
+* or not latched.
+*
+*
+*
+*
+*
+* @param v_pmu_trigger_intr_u8 : The status of power mode trigger interrupt
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_pmu_trigger_intr(u8
+*v_pmu_trigger_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_0_PMU_TRIGGER__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_pmu_trigger_intr_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_0_PMU_TRIGGER);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the double tab status
+* from the register 0x1C bit 4
+* flag is associated with a specific interrupt function.
+* It is set when the single tab interrupt triggers. The
+* setting of INT_LATCH controls if the interrupt
+* signal and hence the
+* respective interrupt flag will be
+* permanently latched, temporarily latched
+* or not latched.
+*
+*
+*
+*
+* @param v_double_tap_intr_u8 :The status of double tab interrupt
+*
+* @note Double tap interrupt can be configured by the following functions
+* @note INTERRUPT MAPPING
+* @note smi130_set_intr_double_tap()
+* @note AXIS MAPPING
+* @note smi130_get_stat2_tap_first_x()
+* @note smi130_get_stat2_tap_first_y()
+* @note smi130_get_stat2_tap_first_z()
+* @note DURATION
+* @note smi130_set_intr_tap_durn()
+* @note THRESHOLD
+* @note smi130_set_intr_tap_thres()
+* @note TAP QUIET
+* @note smi130_set_intr_tap_quiet()
+* @note TAP SHOCK
+* @note smi130_set_intr_tap_shock()
+* @note TAP SOURCE
+* @note smi130_set_intr_tap_source()
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_double_tap_intr(u8
+*v_double_tap_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_0_DOUBLE_TAP_INTR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_double_tap_intr_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_0_DOUBLE_TAP_INTR);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the single tab status
+* from the register 0x1C bit 5
+* flag is associated with a specific interrupt function.
+* It is set when the single tab interrupt triggers. The
+* setting of INT_LATCH controls if the interrupt
+* signal and hence the
+* respective interrupt flag will be
+* permanently latched, temporarily latched
+* or not latched.
+*
+*
+*
+*
+* @param v_single_tap_intr_u8 :The status of single tap interrupt
+*
+* @note Single tap interrupt can be configured by the following functions
+* @note INTERRUPT MAPPING
+* @note smi130_set_intr_single_tap()
+* @note AXIS MAPPING
+* @note smi130_get_stat2_tap_first_x()
+* @note smi130_get_stat2_tap_first_y()
+* @note smi130_get_stat2_tap_first_z()
+* @note DURATION
+* @note smi130_set_intr_tap_durn()
+* @note THRESHOLD
+* @note smi130_set_intr_tap_thres()
+* @note TAP QUIET
+* @note smi130_set_intr_tap_quiet()
+* @note TAP SHOCK
+* @note smi130_set_intr_tap_shock()
+* @note TAP SOURCE
+* @note smi130_set_intr_tap_source()
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_single_tap_intr(u8
+*v_single_tap_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_0_SINGLE_TAP_INTR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_single_tap_intr_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_0_SINGLE_TAP_INTR);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the orient 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 smi130_get_stat0_orient_intr()
+* @note AXIS MAPPING
+* @note smi130_get_stat3_orient_xy()
+* @note smi130_get_stat3_orient_z()
+* @note smi130_set_intr_orient_axes_enable()
+* @note INTERRUPT MAPPING
+* @note smi130_set_intr_orient()
+* @note INTERRUPT OUTPUT
+* @note smi130_set_intr_orient_ud_enable()
+* @note THETA
+* @note smi130_set_intr_orient_theta()
+* @note HYSTERESIS
+* @note smi130_set_intr_orient_hyst()
+* @note BLOCKING
+* @note smi130_set_intr_orient_blocking()
+* @note MODE
+* @note smi130_set_intr_orient_mode()
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_orient_intr(u8
+*v_orient_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_0_ORIENT__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_orient_intr_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_0_ORIENT);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the flat interrupt status
+* from the register 0x1C bit 7
+* flag is associated with a specific interrupt function.
+* It is set when the flat interrupt triggers. The
+* setting of INT_LATCH controls if the
+* interrupt signal and hence the
+* respective interrupt flag will be
+* permanently latched, temporarily latched
+* or not latched.
+*
+*
+*
+*
+* @param v_flat_intr_u8 : The status of flat interrupt
+*
+* @note For flat configuration use the following functions
+* @note STATS
+* @note smi130_get_stat0_flat_intr()
+* @note smi130_get_stat3_flat()
+* @note INTERRUPT MAPPING
+* @note smi130_set_intr_flat()
+* @note THETA
+* @note smi130_set_intr_flat_theta()
+* @note HOLD TIME
+* @note smi130_set_intr_flat_hold()
+* @note HYSTERESIS
+* @note smi130_set_intr_flat_hyst()
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_flat_intr(u8
+*v_flat_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_0_FLAT__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_flat_intr_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_0_FLAT);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the high_g interrupt status
+* from the register 0x1D bit 2
+* flag is associated with a specific interrupt function.
+* It is set when the high g interrupt triggers. The
+* setting of INT_LATCH controls if the interrupt signal and hence the
+* respective interrupt flag will be permanently
+* latched, temporarily latched
+* or not latched.
+*
+*
+*
+*
+* @param v_high_g_intr_u8 : The status of high_g interrupt
+*
+* @note High_g interrupt configured by following functions
+* @note STATUS
+* @note smi130_get_stat1_high_g_intr()
+* @note AXIS MAPPING
+* @note smi130_get_stat3_high_g_first_x()
+* @note smi130_get_stat3_high_g_first_y()
+* @note smi130_get_stat3_high_g_first_z()
+* @note SIGN MAPPING
+* @note smi130_get_stat3_high_g_first_sign()
+* @note INTERRUPT MAPPING
+* @note smi130_set_intr_high_g()
+ * @note HYSTERESIS
+* @note smi130_set_intr_high_g_hyst()
+* @note DURATION
+* @note smi130_set_intr_high_g_durn()
+* @note THRESHOLD
+* @note smi130_set_intr_high_g_thres()
+* @note SOURCE
+* @note smi130_set_intr_low_high_source()
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat1_high_g_intr(u8
+*v_high_g_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_1_HIGH_G_INTR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_high_g_intr_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_1_HIGH_G_INTR);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the low g interrupt status
+* from the register 0x1D bit 3
+* flag is associated with a specific interrupt function.
+* It is set when the low g interrupt triggers. The
+* setting of INT_LATCH controls if the interrupt signal and hence the
+* respective interrupt flag will be
+* permanently latched, temporarily latched
+* or not latched.
+*
+*
+*
+*
+* @param v_low_g_intr_u8 : The status of low_g interrupt
+*
+* @note Low_g interrupt configured by following functions
+* @note STATUS
+* @note smi130_get_stat1_low_g_intr()
+* @note INTERRUPT MAPPING
+* @note smi130_set_intr_low_g()
+* @note SOURCE
+* @note smi130_set_intr_low_high_source()
+* @note DURATION
+* @note smi130_set_intr_low_g_durn()
+* @note THRESHOLD
+* @note smi130_set_intr_low_g_thres()
+* @note HYSTERESIS
+* @note smi130_set_intr_low_g_hyst()
+* @note MODE
+* @note smi130_set_intr_low_g_mode()
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat1_low_g_intr(u8
+*v_low_g_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_1_LOW_G_INTR__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_low_g_intr_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_1_LOW_G_INTR);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads data ready interrupt status
+* from the register 0x1D bit 4
+* flag is associated with a specific interrupt function.
+* It is set when the data ready interrupt triggers. The
+* setting of INT_LATCH controls if the interrupt signal and hence the
+* respective interrupt flag will be
+* permanently latched, temporarily latched
+* or not latched.
+*
+*
+*
+*
+* @param v_data_rdy_intr_u8 : The status of data ready interrupt
+*
+* @note Data ready interrupt configured by following functions
+* @note STATUS
+* @note smi130_get_stat1_data_rdy_intr()
+* @note INTERRUPT MAPPING
+* @note smi130_set_intr_data_rdy()
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat1_data_rdy_intr(u8
+*v_data_rdy_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_1_DATA_RDY_INTR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_data_rdy_intr_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_1_DATA_RDY_INTR);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads data ready FIFO full interrupt status
+* from the register 0x1D bit 5
+* flag is associated with a specific interrupt function.
+* It is set when the FIFO full interrupt triggers. The
+* setting of INT_LATCH controls if the
+* interrupt signal and hence the
+* respective interrupt flag will
+* be permanently latched, temporarily latched
+* or not latched.
+*
+*
+*
+*
+* @param v_fifo_full_intr_u8 : The status of fifo full interrupt
+*
+* @note FIFO full interrupt can be configured by following functions
+* @note smi130_set_intr_fifo_full()
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat1_fifo_full_intr(u8
+*v_fifo_full_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_1_FIFO_FULL_INTR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_full_intr_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_1_FIFO_FULL_INTR);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads data
+* ready FIFO watermark interrupt status
+* from the register 0x1D bit 6
+* flag is associated with a specific interrupt function.
+* It is set when the FIFO watermark interrupt triggers. The
+* setting of INT_LATCH controls if the
+* interrupt signal and hence the
+* respective interrupt flag will be
+* permanently latched, temporarily latched
+* or not latched.
+*
+*
+*
+*
+* @param v_fifo_wm_intr_u8 : The status of fifo water mark interrupt
+*
+* @note FIFO full interrupt can be configured by following functions
+* @note smi130_set_intr_fifo_wm()
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat1_fifo_wm_intr(u8
+*v_fifo_wm_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_1_FIFO_WM_INTR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_wm_intr_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_1_FIFO_WM_INTR);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads data ready no motion interrupt status
+* from the register 0x1D bit 7
+* flag is associated with a specific interrupt function.
+* It is set when the no motion interrupt triggers. The
+* setting of INT_LATCH controls if the interrupt signal and hence the
+* respective interrupt flag will be permanently
+* latched, temporarily latched
+* or not latched.
+*
+*
+*
+*
+* @param v_nomotion_intr_u8 : The status of no motion interrupt
+*
+* @note No motion interrupt can be configured by following function
+* @note STATUS
+* @note smi130_get_stat1_nomotion_intr()
+* @note INTERRUPT MAPPING
+* @note smi130_set_intr_nomotion()
+* @note DURATION
+* @note smi130_set_intr_slow_no_motion_durn()
+* @note THRESHOLD
+* @note smi130_set_intr_slow_no_motion_thres()
+* @note SLOW/NO MOTION SELECT
+* @note smi130_set_intr_slow_no_motion_select()
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat1_nomotion_intr(u8
+*v_nomotion_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the no motion interrupt*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_1_NOMOTION_INTR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_nomotion_intr_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_1_NOMOTION_INTR);
+ }
+ return com_rslt;
+}
+/*!
+*@brief This API reads the status of any motion first x
+* from the register 0x1E bit 0
+*
+*
+*@param v_anymotion_first_x_u8 : The status of any motion first x interrupt
+* value | status
+* -----------|-------------
+* 0 | not triggered
+* 1 | triggered by x axis
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_any_motion_first_x(u8
+*v_anymotion_first_x_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the any motion first x interrupt*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_X__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_anymotion_first_x_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_X);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the status of any motion first y interrupt
+* from the register 0x1E bit 1
+*
+*
+*
+*@param v_any_motion_first_y_u8 : The status of any motion first y interrupt
+* value | status
+* -----------|-------------
+* 0 | not triggered
+* 1 | triggered by y axis
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_any_motion_first_y(u8
+*v_any_motion_first_y_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the any motion first y interrupt*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_Y__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_any_motion_first_y_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_Y);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the status of any motion first z interrupt
+* from the register 0x1E bit 2
+*
+*
+*
+*
+*@param v_any_motion_first_z_u8 : The status of any motion first z interrupt
+* value | status
+* -----------|-------------
+* 0 | not triggered
+* 1 | triggered by y axis
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_any_motion_first_z(u8
+*v_any_motion_first_z_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the any motion first z interrupt*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_Z__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_any_motion_first_z_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_Z);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the any motion sign status from the
+* register 0x1E bit 3
+*
+*
+*
+*
+* @param v_anymotion_sign_u8 : The status of any motion sign
+* value | sign
+* -----------|-------------
+* 0 | positive
+* 1 | negative
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_any_motion_sign(u8
+*v_anymotion_sign_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read any motion sign interrupt status*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_2_ANY_MOTION_SIGN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_anymotion_sign_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_2_ANY_MOTION_SIGN);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the any motion tap first x status from the
+* register 0x1E bit 4
+*
+*
+*
+*
+* @param v_tap_first_x_u8 :The status of any motion tap first x
+* value | status
+* -----------|-------------
+* 0 | not triggered
+* 1 | triggered by x axis
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_tap_first_x(u8
+*v_tap_first_x_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read tap first x interrupt status*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_2_TAP_FIRST_X__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_tap_first_x_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_2_TAP_FIRST_X);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the tap first y interrupt status from the
+* register 0x1E bit 5
+*
+*
+*
+*
+* @param v_tap_first_y_u8 :The status of tap first y interrupt
+* value | status
+* -----------|-------------
+* 0 | not triggered
+* 1 | triggered by y axis
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_tap_first_y(u8
+*v_tap_first_y_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read tap first y interrupt status*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_2_TAP_FIRST_Y__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_tap_first_y_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_2_TAP_FIRST_Y);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the tap first z interrupt status from the
+* register 0x1E bit 6
+*
+*
+*
+*
+* @param v_tap_first_z_u8 :The status of tap first z interrupt
+* value | status
+* -----------|-------------
+* 0 | not triggered
+* 1 | triggered by z axis
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_tap_first_z(u8
+*v_tap_first_z_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read tap first z interrupt status*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_2_TAP_FIRST_Z__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_tap_first_z_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_2_TAP_FIRST_Z);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the tap sign status from the
+* register 0x1E bit 7
+*
+*
+*
+*
+* @param v_tap_sign_u8 : The status of tap sign
+* value | sign
+* -----------|-------------
+* 0 | positive
+* 1 | negative
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_tap_sign(u8
+*v_tap_sign_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read tap_sign interrupt status*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_2_TAP_SIGN__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_tap_sign_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_2_TAP_SIGN);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the high_g first x status from the
+* register 0x1F bit 0
+*
+*
+*
+*
+* @param v_high_g_first_x_u8 :The status of high_g first x
+* value | status
+* -----------|-------------
+* 0 | not triggered
+* 1 | triggered by x axis
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat3_high_g_first_x(u8
+*v_high_g_first_x_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read highg_x interrupt status*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_X__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_high_g_first_x_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_X);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the high_g first y status from the
+* register 0x1F bit 1
+*
+*
+*
+*
+* @param v_high_g_first_y_u8 : The status of high_g first y
+* value | status
+* -----------|-------------
+* 0 | not triggered
+* 1 | triggered by y axis
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat3_high_g_first_y(u8
+*v_high_g_first_y_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read highg_y interrupt status*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_Y__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_high_g_first_y_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_Y);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the high_g first z status from the
+* register 0x1F bit 3
+*
+*
+*
+*
+* @param v_high_g_first_z_u8 : The status of high_g first z
+* value | status
+* -----------|-------------
+* 0 | not triggered
+* 1 | triggered by z axis
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat3_high_g_first_z(u8
+*v_high_g_first_z_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read highg_z interrupt status*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_Z__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_high_g_first_z_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_Z);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the high sign status from the
+* register 0x1F bit 3
+*
+*
+*
+*
+* @param v_high_g_sign_u8 :The status of high sign
+* value | sign
+* -----------|-------------
+* 0 | positive
+* 1 | negative
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat3_high_g_sign(u8
+*v_high_g_sign_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read highg_sign interrupt status*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_3_HIGH_G_SIGN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_high_g_sign_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_3_HIGH_G_SIGN);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the status of orient_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
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat3_orient_xy(u8
+*v_orient_xy_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read orient plane xy interrupt status*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_3_ORIENT_XY__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_orient_xy_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_3_ORIENT_XY);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the status of orient 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
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat3_orient_z(u8
+*v_orient_z_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read orient z plane interrupt status*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_3_ORIENT_Z__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_orient_z_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_3_ORIENT_Z);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the flat status from the register
+* 0x1F bit 7
+*
+*
+* @param v_flat_u8 : The status of flat interrupt
+* value | status
+* -----------|-------------
+* 0x00 | non flat
+* 0x01 | flat position
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat3_flat(u8
+*v_flat_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read flat interrupt status*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_INTR_STAT_3_FLAT__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_flat_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_STAT_3_FLAT);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the temperature of the sensor
+* from the register 0x21 bit 0 to 7
+*
+*
+*
+* @param v_temp_s16 : The value of temperature
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_temp(s16
+*v_temp_s16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the temperature lSB and MSB data
+ v_data_u8[0] - LSB
+ v_data_u8[1] - MSB*/
+ u8 v_data_u8[SMI130_TEMP_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read temperature data*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_TEMP_LSB_VALUE__REG, v_data_u8,
+ SMI130_TEMP_DATA_LENGTH);
+ *v_temp_s16 =
+ (s16)(((s32)((s8) (v_data_u8[SMI130_TEMP_MSB_BYTE]) <<
+ SMI130_SHIFT_BIT_POSITION_BY_08_BITS))
+ | v_data_u8[SMI130_TEMP_LSB_BYTE]);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the of the sensor
+* form the register 0x23 and 0x24 bit 0 to 7 and 0 to 2
+* @brief this byte counter is updated each time a complete frame
+* was read or writtern
+*
+*
+* @param v_fifo_length_u32 : The value of fifo byte counter
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_fifo_length(u32*v_fifo_length_u32)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array contains the fifo length data
+ v_data_u8[0] - fifo length
+ v_data_u8[1] - fifo length*/
+ u8 a_data_u8r[SMI130_FIFO_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read fifo length*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_BYTE_COUNTER_LSB__REG, a_data_u8r,
+ SMI130_FIFO_DATA_LENGTH);
+
+ a_data_u8r[SMI130_FIFO_LENGTH_MSB_BYTE] =
+ SMI130_GET_BITSLICE(
+ a_data_u8r[SMI130_FIFO_LENGTH_MSB_BYTE],
+ SMI130_USER_FIFO_BYTE_COUNTER_MSB);
+
+ *v_fifo_length_u32 =
+ (u32)(((u32)((u8) (
+ a_data_u8r[SMI130_FIFO_LENGTH_MSB_BYTE]) <<
+ SMI130_SHIFT_BIT_POSITION_BY_08_BITS))
+ | a_data_u8r[SMI130_FIFO_LENGTH_LSB_BYTE]);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the fifo data of the sensor
+* from the register 0x24
+* @brief Data format depends on the setting of register FIFO_CONFIG
+*
+*
+*
+* @param v_fifodata_u8 : Pointer holding the fifo data
+* @param fifo_length_u16 : The value of fifo length maximum
+* 1024
+*
+* @note For reading FIFO data use the following functions
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_fifo_data(
+u8*v_fifodata_u8, u16 v_fifo_length_u16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read fifo data*/
+ com_rslt =
+ p_smi130->SMI130_BURST_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_DATA__REG,
+ v_fifodata_u8, v_fifo_length_u16);
+
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to get the
+* accel output date rate form the register 0x40 bit 0 to 3
+*
+*
+* @param v_output_data_rate_u8 :The value of accel output date rate
+* value | output data rate
+* -------|--------------------------
+* 0 | SMI130_ACCEL_OUTPUT_DATA_RATE_RESERVED
+* 1 | SMI130_ACCEL_OUTPUT_DATA_RATE_0_78HZ
+* 2 | SMI130_ACCEL_OUTPUT_DATA_RATE_1_56HZ
+* 3 | SMI130_ACCEL_OUTPUT_DATA_RATE_3_12HZ
+* 4 | SMI130_ACCEL_OUTPUT_DATA_RATE_6_25HZ
+* 5 | SMI130_ACCEL_OUTPUT_DATA_RATE_12_5HZ
+* 6 | SMI130_ACCEL_OUTPUT_DATA_RATE_25HZ
+* 7 | SMI130_ACCEL_OUTPUT_DATA_RATE_50HZ
+* 8 | SMI130_ACCEL_OUTPUT_DATA_RATE_100HZ
+* 9 | SMI130_ACCEL_OUTPUT_DATA_RATE_200HZ
+* 10 | SMI130_ACCEL_OUTPUT_DATA_RATE_400HZ
+* 11 | SMI130_ACCEL_OUTPUT_DATA_RATE_800HZ
+* 12 | SMI130_ACCEL_OUTPUT_DATA_RATE_1600HZ
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_output_data_rate(
+u8*v_output_data_rate_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the accel output data rate*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_output_data_rate_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to set the
+* accel output date rate form the register 0x40 bit 0 to 3
+*
+*
+* @param v_output_data_rate_u8 :The value of accel output date rate
+* value | output data rate
+* -------|--------------------------
+* 0 | SMI130_ACCEL_OUTPUT_DATA_RATE_RESERVED
+* 1 | SMI130_ACCEL_OUTPUT_DATA_RATE_0_78HZ
+* 2 | SMI130_ACCEL_OUTPUT_DATA_RATE_1_56HZ
+* 3 | SMI130_ACCEL_OUTPUT_DATA_RATE_3_12HZ
+* 4 | SMI130_ACCEL_OUTPUT_DATA_RATE_6_25HZ
+* 5 | SMI130_ACCEL_OUTPUT_DATA_RATE_12_5HZ
+* 6 | SMI130_ACCEL_OUTPUT_DATA_RATE_25HZ
+* 7 | SMI130_ACCEL_OUTPUT_DATA_RATE_50HZ
+* 8 | SMI130_ACCEL_OUTPUT_DATA_RATE_100HZ
+* 9 | SMI130_ACCEL_OUTPUT_DATA_RATE_200HZ
+* 10 | SMI130_ACCEL_OUTPUT_DATA_RATE_400HZ
+* 11 | SMI130_ACCEL_OUTPUT_DATA_RATE_800HZ
+* 12 | SMI130_ACCEL_OUTPUT_DATA_RATE_1600HZ
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_output_data_rate(
+u8 v_output_data_rate_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* accel output data rate selection*/
+ if ((v_output_data_rate_u8 != SMI130_INIT_VALUE) &&
+ (v_output_data_rate_u8 <= SMI130_MAX_ACCEL_OUTPUT_DATA_RATE)) {
+ /* write accel output data rate*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE,
+ v_output_data_rate_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to get the
+* accel bandwidth from the register 0x40 bit 4 to 6
+* @brief bandwidth parameter determines filter configuration(acc_us=0)
+* and averaging for under sampling mode(acc_us=1)
+*
+*
+* @param v_bw_u8 : The value of accel bandwidth
+*
+* @note accel bandwidth depends on under sampling parameter
+* @note under sampling parameter cab be set by the function
+* "SMI130_SET_ACCEL_UNDER_SAMPLING_PARAMETER"
+*
+* @note Filter configuration
+* accel_us | Filter configuration
+* -----------|---------------------
+* 0x00 | OSR4 mode
+* 0x01 | OSR2 mode
+* 0x02 | normal mode
+* 0x03 | CIC mode
+* 0x04 | Reserved
+* 0x05 | Reserved
+* 0x06 | Reserved
+* 0x07 | Reserved
+*
+* @note accel under sampling mode
+* accel_us | Under sampling mode
+* -----------|---------------------
+* 0x00 | no averaging
+* 0x01 | average 2 samples
+* 0x02 | average 4 samples
+* 0x03 | average 8 samples
+* 0x04 | average 16 samples
+* 0x05 | average 32 samples
+* 0x06 | average 64 samples
+* 0x07 | average 128 samples
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_bw(u8*v_bw_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the accel bandwidth*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_ACCEL_CONFIG_ACCEL_BW__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_bw_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_ACCEL_CONFIG_ACCEL_BW);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to set the
+* accel bandwidth from the register 0x40 bit 4 to 6
+* @brief bandwidth parameter determines filter configuration(acc_us=0)
+* and averaging for under sampling mode(acc_us=1)
+*
+*
+* @param v_bw_u8 : The value of accel bandwidth
+*
+* @note accel bandwidth depends on under sampling parameter
+* @note under sampling parameter cab be set by the function
+* "SMI130_SET_ACCEL_UNDER_SAMPLING_PARAMETER"
+*
+* @note Filter configuration
+* accel_us | Filter configuration
+* -----------|---------------------
+* 0x00 | OSR4 mode
+* 0x01 | OSR2 mode
+* 0x02 | normal mode
+* 0x03 | CIC mode
+* 0x04 | Reserved
+* 0x05 | Reserved
+* 0x06 | Reserved
+* 0x07 | Reserved
+*
+* @note accel under sampling mode
+* accel_us | Under sampling mode
+* -----------|---------------------
+* 0x00 | no averaging
+* 0x01 | average 2 samples
+* 0x02 | average 4 samples
+* 0x03 | average 8 samples
+* 0x04 | average 16 samples
+* 0x05 | average 32 samples
+* 0x06 | average 64 samples
+* 0x07 | average 128 samples
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_bw(u8 v_bw_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* select accel bandwidth*/
+ if (v_bw_u8 <= SMI130_MAX_ACCEL_BW) {
+ /* write accel bandwidth*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_ACCEL_CONFIG_ACCEL_BW__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_ACCEL_CONFIG_ACCEL_BW,
+ v_bw_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_ACCEL_CONFIG_ACCEL_BW__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to get the accel
+* under sampling parameter form the register 0x40 bit 7
+*
+*
+*
+*
+* @param v_accel_under_sampling_u8 : The value of accel under sampling
+* value | under_sampling
+* ----------|---------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_under_sampling_parameter(
+u8*v_accel_under_sampling_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the accel under sampling parameter*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_under_sampling_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to set the accel
+* under sampling parameter form the register 0x40 bit 7
+*
+*
+*
+*
+* @param v_accel_under_sampling_u8 : The value of accel under sampling
+* value | under_sampling
+* ----------|---------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_under_sampling_parameter(
+u8 v_accel_under_sampling_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_accel_under_sampling_u8 <= SMI130_MAX_UNDER_SAMPLING) {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ /* write the accel under sampling parameter*/
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING,
+ v_accel_under_sampling_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+}
+return com_rslt;
+}
+/*!
+* @brief This API is used to get the ranges
+* (g values) of the accel from the register 0x41 bit 0 to 3
+*
+*
+*
+*
+* @param v_range_u8 : The value of accel g range
+* value | g_range
+* ----------|-----------
+* 0x03 | SMI130_ACCEL_RANGE_2G
+* 0x05 | SMI130_ACCEL_RANGE_4G
+* 0x08 | SMI130_ACCEL_RANGE_8G
+* 0x0C | SMI130_ACCEL_RANGE_16G
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_range(
+u8*v_range_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the accel range*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_ACCEL_RANGE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_range_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_ACCEL_RANGE);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to set the ranges
+* (g values) of the accel from the register 0x41 bit 0 to 3
+*
+*
+*
+*
+* @param v_range_u8 : The value of accel g range
+* value | g_range
+* ----------|-----------
+* 0x03 | SMI130_ACCEL_RANGE_2G
+* 0x05 | SMI130_ACCEL_RANGE_4G
+* 0x08 | SMI130_ACCEL_RANGE_8G
+* 0x0C | SMI130_ACCEL_RANGE_16G
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_range(u8 v_range_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if ((v_range_u8 == SMI130_ACCEL_RANGE0) ||
+ (v_range_u8 == SMI130_ACCEL_RANGE1) ||
+ (v_range_u8 == SMI130_ACCEL_RANGE3) ||
+ (v_range_u8 == SMI130_ACCEL_RANGE4)) {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_ACCEL_RANGE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(
+ v_data_u8, SMI130_USER_ACCEL_RANGE,
+ v_range_u8);
+ /* write the accel range*/
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_ACCEL_RANGE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to get the
+* gyroscope output data rate from the register 0x42 bit 0 to 3
+*
+*
+*
+*
+* @param v_output_data_rate_u8 :The value of gyro output data rate
+* value | gyro output data rate
+* -----------|-----------------------------
+* 0x00 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+* 0x01 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+* 0x02 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+* 0x03 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+* 0x04 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+* 0x05 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+* 0x06 | SMI130_GYRO_OUTPUT_DATA_RATE_25HZ
+* 0x07 | SMI130_GYRO_OUTPUT_DATA_RATE_50HZ
+* 0x08 | SMI130_GYRO_OUTPUT_DATA_RATE_100HZ
+* 0x09 | SMI130_GYRO_OUTPUT_DATA_RATE_200HZ
+* 0x0A | SMI130_GYRO_OUTPUT_DATA_RATE_400HZ
+* 0x0B | SMI130_GYRO_OUTPUT_DATA_RATE_800HZ
+* 0x0C | SMI130_GYRO_OUTPUT_DATA_RATE_1600HZ
+* 0x0D | SMI130_GYRO_OUTPUT_DATA_RATE_3200HZ
+* 0x0E | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+* 0x0F | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_output_data_rate(
+u8*v_output_data_rate_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the gyro output data rate*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_GYRO_CONFIG_OUTPUT_DATA_RATE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_output_data_rate_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_GYRO_CONFIG_OUTPUT_DATA_RATE);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to set the
+* gyroscope output data rate from the register 0x42 bit 0 to 3
+*
+*
+*
+*
+* @param v_output_data_rate_u8 :The value of gyro output data rate
+* value | gyro output data rate
+* -----------|-----------------------------
+* 0x00 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+* 0x01 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+* 0x02 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+* 0x03 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+* 0x04 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+* 0x05 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+* 0x06 | SMI130_GYRO_OUTPUT_DATA_RATE_25HZ
+* 0x07 | SMI130_GYRO_OUTPUT_DATA_RATE_50HZ
+* 0x08 | SMI130_GYRO_OUTPUT_DATA_RATE_100HZ
+* 0x09 | SMI130_GYRO_OUTPUT_DATA_RATE_200HZ
+* 0x0A | SMI130_GYRO_OUTPUT_DATA_RATE_400HZ
+* 0x0B | SMI130_GYRO_OUTPUT_DATA_RATE_800HZ
+* 0x0C | SMI130_GYRO_OUTPUT_DATA_RATE_1600HZ
+* 0x0D | SMI130_GYRO_OUTPUT_DATA_RATE_3200HZ
+* 0x0E | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+* 0x0F | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_output_data_rate(
+u8 v_output_data_rate_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* select the gyro output data rate*/
+ if ((v_output_data_rate_u8 < SMI130_OUTPUT_DATA_RATE6) &&
+ (v_output_data_rate_u8 != SMI130_INIT_VALUE)
+ && (v_output_data_rate_u8 != SMI130_OUTPUT_DATA_RATE1)
+ && (v_output_data_rate_u8 != SMI130_OUTPUT_DATA_RATE2)
+ && (v_output_data_rate_u8 != SMI130_OUTPUT_DATA_RATE3)
+ && (v_output_data_rate_u8 != SMI130_OUTPUT_DATA_RATE4)
+ && (v_output_data_rate_u8 != SMI130_OUTPUT_DATA_RATE5)
+ && (v_output_data_rate_u8 != SMI130_OUTPUT_DATA_RATE6)
+ && (v_output_data_rate_u8 != SMI130_OUTPUT_DATA_RATE7)) {
+ /* write the gyro output data rate*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_GYRO_CONFIG_OUTPUT_DATA_RATE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_GYRO_CONFIG_OUTPUT_DATA_RATE,
+ v_output_data_rate_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_GYRO_CONFIG_OUTPUT_DATA_RATE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to get the
+* data of gyro from the register 0x42 bit 4 to 5
+*
+*
+*
+*
+* @param v_bw_u8 : The value of gyro bandwidth
+* value | gyro bandwidth
+* ----------|----------------
+* 0x00 | SMI130_GYRO_OSR4_MODE
+* 0x01 | SMI130_GYRO_OSR2_MODE
+* 0x02 | SMI130_GYRO_NORMAL_MODE
+* 0x03 | SMI130_GYRO_CIC_MODE
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_bw(u8*v_bw_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read gyro bandwidth*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_GYRO_CONFIG_BW__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_bw_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_GYRO_CONFIG_BW);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to set the
+* data of gyro from the register 0x42 bit 4 to 5
+*
+*
+*
+*
+* @param v_bw_u8 : The value of gyro bandwidth
+* value | gyro bandwidth
+* ----------|----------------
+* 0x00 | SMI130_GYRO_OSR4_MODE
+* 0x01 | SMI130_GYRO_OSR2_MODE
+* 0x02 | SMI130_GYRO_NORMAL_MODE
+* 0x03 | SMI130_GYRO_CIC_MODE
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_bw(u8 v_bw_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_bw_u8 <= SMI130_MAX_GYRO_BW) {
+ /* write the gyro bandwidth*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_GYRO_CONFIG_BW__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_GYRO_CONFIG_BW, v_bw_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_CONFIG_BW__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads the range
+* of gyro from the register 0x43 bit 0 to 2
+*
+* @param v_range_u8 : The value of gyro range
+* value | range
+* ----------|-------------------------------
+* 0x00 | SMI130_GYRO_RANGE_2000_DEG_SEC
+* 0x01 | SMI130_GYRO_RANGE_1000_DEG_SEC
+* 0x02 | SMI130_GYRO_RANGE_500_DEG_SEC
+* 0x03 | SMI130_GYRO_RANGE_250_DEG_SEC
+* 0x04 | SMI130_GYRO_RANGE_125_DEG_SEC
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_range(u8*v_range_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the gyro range*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_GYRO_RANGE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_range_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_GYRO_RANGE);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API set the range
+* of gyro from the register 0x43 bit 0 to 2
+*
+* @param v_range_u8 : The value of gyro range
+* value | range
+* ----------|-------------------------------
+* 0x00 | SMI130_GYRO_RANGE_2000_DEG_SEC
+* 0x01 | SMI130_GYRO_RANGE_1000_DEG_SEC
+* 0x02 | SMI130_GYRO_RANGE_500_DEG_SEC
+* 0x03 | SMI130_GYRO_RANGE_250_DEG_SEC
+* 0x04 | SMI130_GYRO_RANGE_125_DEG_SEC
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_range(u8 v_range_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_range_u8 <= SMI130_MAX_GYRO_RANGE) {
+ /* write the gyro range value*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_GYRO_RANGE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_GYRO_RANGE,
+ v_range_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_GYRO_RANGE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to get the
+* output data rate of magnetometer from the register 0x44 bit 0 to 3
+*
+*
+*
+*
+* @param v_output_data_rat_u8e : The value of mag output data rate
+* value | mag output data rate
+* ---------|---------------------------
+* 0x00 |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED
+* 0x01 |SMI130_MAG_OUTPUT_DATA_RATE_0_78HZ
+* 0x02 |SMI130_MAG_OUTPUT_DATA_RATE_1_56HZ
+* 0x03 |SMI130_MAG_OUTPUT_DATA_RATE_3_12HZ
+* 0x04 |SMI130_MAG_OUTPUT_DATA_RATE_6_25HZ
+* 0x05 |SMI130_MAG_OUTPUT_DATA_RATE_12_5HZ
+* 0x06 |SMI130_MAG_OUTPUT_DATA_RATE_25HZ
+* 0x07 |SMI130_MAG_OUTPUT_DATA_RATE_50HZ
+* 0x08 |SMI130_MAG_OUTPUT_DATA_RATE_100HZ
+* 0x09 |SMI130_MAG_OUTPUT_DATA_RATE_200HZ
+* 0x0A |SMI130_MAG_OUTPUT_DATA_RATE_400HZ
+* 0x0B |SMI130_MAG_OUTPUT_DATA_RATE_800HZ
+* 0x0C |SMI130_MAG_OUTPUT_DATA_RATE_1600HZ
+* 0x0D |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED0
+* 0x0E |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED1
+* 0x0F |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED2
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_output_data_rate(
+u8*v_output_data_rat_u8e)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the mag data output rate*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_MAG_CONFIG_OUTPUT_DATA_RATE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_output_data_rat_u8e = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_MAG_CONFIG_OUTPUT_DATA_RATE);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to set the
+* output data rate of magnetometer from the register 0x44 bit 0 to 3
+*
+*
+*
+*
+* @param v_output_data_rat_u8e : The value of mag output data rate
+* value | mag output data rate
+* ---------|---------------------------
+* 0x00 |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED
+* 0x01 |SMI130_MAG_OUTPUT_DATA_RATE_0_78HZ
+* 0x02 |SMI130_MAG_OUTPUT_DATA_RATE_1_56HZ
+* 0x03 |SMI130_MAG_OUTPUT_DATA_RATE_3_12HZ
+* 0x04 |SMI130_MAG_OUTPUT_DATA_RATE_6_25HZ
+* 0x05 |SMI130_MAG_OUTPUT_DATA_RATE_12_5HZ
+* 0x06 |SMI130_MAG_OUTPUT_DATA_RATE_25HZ
+* 0x07 |SMI130_MAG_OUTPUT_DATA_RATE_50HZ
+* 0x08 |SMI130_MAG_OUTPUT_DATA_RATE_100HZ
+* 0x09 |SMI130_MAG_OUTPUT_DATA_RATE_200HZ
+* 0x0A |SMI130_MAG_OUTPUT_DATA_RATE_400HZ
+* 0x0B |SMI130_MAG_OUTPUT_DATA_RATE_800HZ
+* 0x0C |SMI130_MAG_OUTPUT_DATA_RATE_1600HZ
+* 0x0D |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED0
+* 0x0E |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED1
+* 0x0F |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED2
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_output_data_rate(
+u8 v_output_data_rat_u8e)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* select the mag data output rate*/
+ if ((v_output_data_rat_u8e
+ <= SMI130_MAX_ACCEL_OUTPUT_DATA_RATE)
+ && (v_output_data_rat_u8e
+ != SMI130_OUTPUT_DATA_RATE0)
+ && (v_output_data_rat_u8e
+ != SMI130_OUTPUT_DATA_RATE6)
+ && (v_output_data_rat_u8e
+ != SMI130_OUTPUT_DATA_RATE7)) {
+ /* write the mag data output rate*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_MAG_CONFIG_OUTPUT_DATA_RATE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_MAG_CONFIG_OUTPUT_DATA_RATE,
+ v_output_data_rat_u8e);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_MAG_CONFIG_OUTPUT_DATA_RATE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API is used to read Down sampling
+* for gyro (2**downs_gyro) in the register 0x45 bit 0 to 2
+*
+*
+*
+*
+* @param v_fifo_down_gyro_u8 :The value of gyro fifo down
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_down_gyro(
+u8*v_fifo_down_gyro_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the gyro fifo down*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_DOWN_GYRO__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_down_gyro_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_DOWN_GYRO);
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API is used to set Down sampling
+* for gyro (2**downs_gyro) in the register 0x45 bit 0 to 2
+*
+*
+*
+*
+* @param v_fifo_down_gyro_u8 :The value of gyro fifo down
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_down_gyro(
+u8 v_fifo_down_gyro_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write the gyro fifo down*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_DOWN_GYRO__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_FIFO_DOWN_GYRO,
+ v_fifo_down_gyro_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FIFO_DOWN_GYRO__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to read gyro fifo filter data
+* from the register 0x45 bit 3
+*
+*
+*
+* @param v_gyro_fifo_filter_data_u8 :The value of gyro filter data
+* value | gyro_fifo_filter_data
+* ------------|-------------------------
+* 0x00 | Unfiltered data
+* 0x01 | Filtered data
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_fifo_filter_data(
+u8*v_gyro_fifo_filter_data_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the gyro fifo filter data*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_FILTER_GYRO__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_gyro_fifo_filter_data_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_FILTER_GYRO);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to set gyro fifo filter data
+* from the register 0x45 bit 3
+*
+*
+*
+* @param v_gyro_fifo_filter_data_u8 :The value of gyro filter data
+* value | gyro_fifo_filter_data
+* ------------|-------------------------
+* 0x00 | Unfiltered data
+* 0x01 | Filtered data
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_fifo_filter_data(
+u8 v_gyro_fifo_filter_data_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_gyro_fifo_filter_data_u8
+ <= SMI130_MAX_VALUE_FIFO_FILTER) {
+ /* write the gyro fifo filter data*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_FILTER_GYRO__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_FIFO_FILTER_GYRO,
+ v_gyro_fifo_filter_data_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FIFO_FILTER_GYRO__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to read Down sampling
+* for accel (2*downs_accel) from the register 0x45 bit 4 to 6
+*
+*
+*
+*
+* @param v_fifo_down_u8 :The value of accel fifo down
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_down_accel(
+u8*v_fifo_down_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the accel fifo down data*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_DOWN_ACCEL__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_down_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_DOWN_ACCEL);
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API is used to set Down sampling
+* for accel (2*downs_accel) from the register 0x45 bit 4 to 6
+*
+*
+*
+*
+* @param v_fifo_down_u8 :The value of accel fifo down
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_down_accel(
+u8 v_fifo_down_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write the accel fifo down data*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_DOWN_ACCEL__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_DOWN_ACCEL, v_fifo_down_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FIFO_DOWN_ACCEL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to read accel fifo filter data
+* from the register 0x45 bit 7
+*
+*
+*
+* @param v_accel_fifo_filter_u8 :The value of accel filter data
+* value | accel_fifo_filter_data
+* ------------|-------------------------
+* 0x00 | Unfiltered data
+* 0x01 | Filtered data
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_fifo_filter_data(
+u8*v_accel_fifo_filter_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the accel fifo filter data*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_FILTER_ACCEL__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_fifo_filter_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_FILTER_ACCEL);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to set accel fifo filter data
+* from the register 0x45 bit 7
+*
+*
+*
+* @param v_accel_fifo_filter_u8 :The value of accel filter data
+* value | accel_fifo_filter_data
+* ------------|-------------------------
+* 0x00 | Unfiltered data
+* 0x01 | Filtered data
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_fifo_filter_data(
+u8 v_accel_fifo_filter_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_accel_fifo_filter_u8 <= SMI130_MAX_VALUE_FIFO_FILTER) {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_FILTER_ACCEL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ /* write accel fifo filter data*/
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_FILTER_ACCEL,
+ v_accel_fifo_filter_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FIFO_FILTER_ACCEL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to Trigger an interrupt
+* when FIFO contains water mark level from the register 0x46 bit 0 to 7
+*
+*
+*
+* @param v_fifo_wm_u8 : The value of fifo water mark level
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_wm(
+u8*v_fifo_wm_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the fifo water mark level*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_WM__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_wm_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_WM);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to Trigger an interrupt
+* when FIFO contains water mark level from the register 0x46 bit 0 to 7
+*
+*
+*
+* @param v_fifo_wm_u8 : The value of fifo water mark level
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_wm(
+u8 v_fifo_wm_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write the fifo water mark level*/
+ com_rslt =
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_WM__REG,
+ &v_fifo_wm_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads fifo sensor time
+* frame after the last valid data frame form the register 0x47 bit 1
+*
+*
+*
+*
+* @param v_fifo_time_enable_u8 : The value of sensor time
+* value | fifo sensor time
+* ------------|-------------------------
+* 0x00 | do not return sensortime frame
+* 0x01 | return sensortime frame
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_time_enable(
+u8*v_fifo_time_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the fifo sensor time*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_TIME_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_time_enable_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_TIME_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API set fifo sensor time
+* frame after the last valid data frame form the register 0x47 bit 1
+*
+*
+*
+*
+* @param v_fifo_time_enable_u8 : The value of sensor time
+* value | fifo sensor time
+* ------------|-------------------------
+* 0x00 | do not return sensortime frame
+* 0x01 | return sensortime frame
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_time_enable(
+u8 v_fifo_time_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_fifo_time_enable_u8 <= SMI130_MAX_VALUE_FIFO_TIME) {
+ /* write the fifo sensor time*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_TIME_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_TIME_ENABLE,
+ v_fifo_time_enable_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FIFO_TIME_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads FIFO tag interrupt2 enable status
+* from the resister 0x47 bit 2
+*
+* @param v_fifo_tag_intr2_u8 : The value of fifo tag interrupt
+* value | fifo tag interrupt
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_tag_intr2_enable(
+u8*v_fifo_tag_intr2_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the fifo tag interrupt2*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_TAG_INTR2_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_tag_intr2_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_TAG_INTR2_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API set FIFO tag interrupt2 enable status
+* from the resister 0x47 bit 2
+*
+* @param v_fifo_tag_intr2_u8 : The value of fifo tag interrupt
+* value | fifo tag interrupt
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_tag_intr2_enable(
+u8 v_fifo_tag_intr2_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_fifo_tag_intr2_u8 <= SMI130_MAX_VALUE_FIFO_INTR) {
+ /* write the fifo tag interrupt2*/
+ com_rslt = smi130_set_input_enable(1,
+ v_fifo_tag_intr2_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_TAG_INTR2_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_TAG_INTR2_ENABLE,
+ v_fifo_tag_intr2_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FIFO_TAG_INTR2_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API get FIFO tag interrupt1 enable status
+* from the resister 0x47 bit 3
+*
+* @param v_fifo_tag_intr1_u8 :The value of fifo tag interrupt1
+* value | fifo tag interrupt
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_tag_intr1_enable(
+u8*v_fifo_tag_intr1_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read fifo tag interrupt*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_TAG_INTR1_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_tag_intr1_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_TAG_INTR1_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API set FIFO tag interrupt1 enable status
+* from the resister 0x47 bit 3
+*
+* @param v_fifo_tag_intr1_u8 :The value of fifo tag interrupt1
+* value | fifo tag interrupt
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_tag_intr1_enable(
+u8 v_fifo_tag_intr1_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_fifo_tag_intr1_u8 <= SMI130_MAX_VALUE_FIFO_INTR) {
+ /* write the fifo tag interrupt*/
+ com_rslt = smi130_set_input_enable(SMI130_INIT_VALUE,
+ v_fifo_tag_intr1_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_TAG_INTR1_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_TAG_INTR1_ENABLE,
+ v_fifo_tag_intr1_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FIFO_TAG_INTR1_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads FIFO frame
+* header enable from the register 0x47 bit 4
+*
+* @param v_fifo_header_u8 :The value of fifo header
+* value | fifo header
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_header_enable(
+u8*v_fifo_header_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read fifo header*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_HEADER_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_header_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_HEADER_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API set FIFO frame
+* header enable from the register 0x47 bit 4
+*
+* @param v_fifo_header_u8 :The value of fifo header
+* value | fifo header
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_header_enable(
+u8 v_fifo_header_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_fifo_header_u8 <= SMI130_MAX_VALUE_FIFO_HEADER) {
+ /* write the fifo header*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_HEADER_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_HEADER_ENABLE,
+ v_fifo_header_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FIFO_HEADER_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to read stored
+* magnetometer data in FIFO (all 3 axes) from the register 0x47 bit 5
+*
+* @param v_fifo_mag_u8 : The value of fifo mag enble
+* value | fifo mag
+* ----------|-------------------
+* 0x00 | no magnetometer data is stored
+* 0x01 | magnetometer data is stored
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_mag_enable(
+u8*v_fifo_mag_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the fifo mag enable*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_MAG_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_mag_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_MAG_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to set stored
+* magnetometer data in FIFO (all 3 axes) from the register 0x47 bit 5
+*
+* @param v_fifo_mag_u8 : The value of fifo mag enble
+* value | fifo mag
+* ----------|-------------------
+* 0x00 | no magnetometer data is stored
+* 0x01 | magnetometer data is stored
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_mag_enable(
+u8 v_fifo_mag_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_fifo_mag_u8 <= SMI130_MAX_VALUE_FIFO_MAG) {
+ /* write the fifo mag enable*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_FIFO_MAG_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_MAG_ENABLE,
+ v_fifo_mag_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_FIFO_MAG_ENABLE__REG,
+ &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to read stored
+* accel data in FIFO (all 3 axes) from the register 0x47 bit 6
+*
+* @param v_fifo_accel_u8 : The value of fifo accel enble
+* value | fifo accel
+* ----------|-------------------
+* 0x00 | no accel data is stored
+* 0x01 | accel data is stored
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_accel_enable(
+u8*v_fifo_accel_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the accel fifo enable*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_ACCEL_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_accel_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_ACCEL_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to set stored
+* accel data in FIFO (all 3 axes) from the register 0x47 bit 6
+*
+* @param v_fifo_accel_u8 : The value of fifo accel enble
+* value | fifo accel
+* ----------|-------------------
+* 0x00 | no accel data is stored
+* 0x01 | accel data is stored
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_accel_enable(
+u8 v_fifo_accel_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_fifo_accel_u8 <= SMI130_MAX_VALUE_FIFO_ACCEL) {
+ /* write the fifo mag enables*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_ACCEL_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_ACCEL_ENABLE, v_fifo_accel_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FIFO_ACCEL_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to read stored
+* gyro data in FIFO (all 3 axes) from the resister 0x47 bit 7
+*
+*
+* @param v_fifo_gyro_u8 : The value of fifo gyro enble
+* value | fifo gyro
+* ----------|-------------------
+* 0x00 | no gyro data is stored
+* 0x01 | gyro data is stored
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_gyro_enable(
+u8*v_fifo_gyro_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read fifo gyro enable*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_GYRO_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_fifo_gyro_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_GYRO_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to set stored
+* gyro data in FIFO (all 3 axes) from the resister 0x47 bit 7
+*
+*
+* @param v_fifo_gyro_u8 : The value of fifo gyro enble
+* value | fifo gyro
+* ----------|-------------------
+* 0x00 | no gyro data is stored
+* 0x01 | gyro data is stored
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_gyro_enable(
+u8 v_fifo_gyro_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_fifo_gyro_u8 <= SMI130_MAX_VALUE_FIFO_GYRO) {
+ /* write fifo gyro enable*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_FIFO_GYRO_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FIFO_GYRO_ENABLE, v_fifo_gyro_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FIFO_GYRO_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to read
+* I2C device address of auxiliary mag from the register 0x4B bit 1 to 7
+*
+*
+*
+*
+* @param v_i2c_device_addr_u8 : The value of mag I2C device address
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_i2c_device_addr(
+u8*v_i2c_device_addr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the mag I2C device address*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_I2C_DEVICE_ADDR__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_i2c_device_addr_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_I2C_DEVICE_ADDR);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to set
+* I2C device address of auxiliary mag from the register 0x4B bit 1 to 7
+*
+*
+*
+*
+* @param v_i2c_device_addr_u8 : The value of mag I2C device address
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_i2c_device_addr(
+u8 v_i2c_device_addr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write the mag I2C device address*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_I2C_DEVICE_ADDR__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_I2C_DEVICE_ADDR,
+ v_i2c_device_addr_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_I2C_DEVICE_ADDR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to read
+* Burst data length (1,2,6,8 byte) from the register 0x4C bit 0 to 1
+*
+*
+*
+*
+* @param v_mag_burst_u8 : The data of mag burst read lenth
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_burst(
+u8*v_mag_burst_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read mag burst mode length*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_MAG_BURST__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_mag_burst_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_MAG_BURST);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to set
+* Burst data length (1,2,6,8 byte) from the register 0x4C bit 0 to 1
+*
+*
+*
+*
+* @param v_mag_burst_u8 : The data of mag burst read lenth
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_burst(
+u8 v_mag_burst_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write mag burst mode length*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_MAG_BURST__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_MAG_BURST, v_mag_burst_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_MAG_BURST__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to read
+* trigger-readout offset in units of 2.5 ms. If set to zero,
+* the offset is maximum, i.e. after readout a trigger
+* is issued immediately. from the register 0x4C bit 2 to 5
+*
+*
+*
+*
+* @param v_mag_offset_u8 : The value of mag offset
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_offset(
+u8*v_mag_offset_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_MAG_OFFSET__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_mag_offset_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_MAG_OFFSET);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to set
+* trigger-readout offset in units of 2.5 ms. If set to zero,
+* the offset is maximum, i.e. after readout a trigger
+* is issued immediately. from the register 0x4C bit 2 to 5
+*
+*
+*
+*
+* @param v_mag_offset_u8 : The value of mag offset
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_offset(
+u8 v_mag_offset_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_MAG_OFFSET__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_MAG_OFFSET, v_mag_offset_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->dev_addr,
+ SMI130_USER_MAG_OFFSET__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+return com_rslt;
+}
+/*!
+* @brief This API is used to read
+* Enable register access on MAG_IF[2] or MAG_IF[3] writes.
+* This implies that the DATA registers are not updated with
+* magnetometer values. Accessing magnetometer requires
+* the magnetometer in normal mode in PMU_STATUS.
+* from the register 0x4C bit 7
+*
+*
+*
+* @param v_mag_manual_u8 : The value of mag manual enable
+* value | mag manual
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_manual_enable(
+u8*v_mag_manual_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read mag manual*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_MAG_MANUAL_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_mag_manual_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_MAG_MANUAL_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to set
+* Enable register access on MAG_IF[2] or MAG_IF[3] writes.
+* This implies that the DATA registers are not updated with
+* magnetometer values. Accessing magnetometer requires
+* the magnetometer in normal mode in PMU_STATUS.
+* from the register 0x4C bit 7
+*
+*
+*
+* @param v_mag_manual_u8 : The value of mag manual enable
+* value | mag manual
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_manual_enable(
+u8 v_mag_manual_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = SMI130_INIT_VALUE;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write the mag manual*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_MAG_MANUAL_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ if (com_rslt == SUCCESS) {
+ /* set the bit of mag manual enable*/
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_MAG_MANUAL_ENABLE, v_mag_manual_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->dev_addr,
+ SMI130_USER_MAG_MANUAL_ENABLE__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ if (com_rslt == SUCCESS)
+ p_smi130->mag_manual_enable = v_mag_manual_u8;
+ else
+ p_smi130->mag_manual_enable = E_SMI130_COMM_RES;
+ }
+return com_rslt;
+}
+/*!
+* @brief This API is used to read data
+* magnetometer address to read from the register 0x4D bit 0 to 7
+* @brief It used to provide mag read address of auxiliary mag
+*
+*
+*
+*
+* @param v_mag_read_addr_u8 : The value of address need to be read
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_read_addr(
+u8*v_mag_read_addr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the written address*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_READ_ADDR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_mag_read_addr_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_READ_ADDR);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to set
+* magnetometer write address from the register 0x4D bit 0 to 7
+* @brief mag write address writes the address of auxiliary mag to write
+*
+*
+*
+* @param v_mag_read_addr_u8:
+* The data of auxiliary mag address to write data
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_read_addr(
+u8 v_mag_read_addr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write the mag read address*/
+ com_rslt =
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->dev_addr,
+ SMI130_USER_READ_ADDR__REG, &v_mag_read_addr_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to read
+* magnetometer write address from the register 0x4E bit 0 to 7
+* @brief mag write address writes the address of auxiliary mag to write
+*
+*
+*
+* @param v_mag_write_addr_u8:
+* The data of auxiliary mag address to write data
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_write_addr(
+u8*v_mag_write_addr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the address of last written*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_WRITE_ADDR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_mag_write_addr_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_WRITE_ADDR);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to set
+* magnetometer write address from the register 0x4E bit 0 to 7
+* @brief mag write address writes the address of auxiliary mag to write
+*
+*
+*
+* @param v_mag_write_addr_u8:
+* The data of auxiliary mag address to write data
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_write_addr(
+u8 v_mag_write_addr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write the data of mag address to write data*/
+ com_rslt =
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->dev_addr,
+ SMI130_USER_WRITE_ADDR__REG, &v_mag_write_addr_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to read magnetometer write data
+* form the resister 0x4F bit 0 to 7
+* @brief This writes the data will be wrote to mag
+*
+*
+*
+* @param v_mag_write_data_u8: The value of mag data
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_write_data(
+u8*v_mag_write_data_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_WRITE_DATA__REG, &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_mag_write_data_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_WRITE_DATA);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to set magnetometer write data
+* form the resister 0x4F bit 0 to 7
+* @brief This writes the data will be wrote to mag
+*
+*
+*
+* @param v_mag_write_data_u8: The value of mag data
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_write_data(
+u8 v_mag_write_data_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt =
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->dev_addr,
+ SMI130_USER_WRITE_DATA__REG, &v_mag_write_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to read
+* interrupt enable from the register 0x50 bit 0 to 7
+*
+*
+*
+*
+* @param v_enable_u8 : Value to decided to select interrupt
+* v_enable_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_ANY_MOTION_X_ENABLE
+* 1 | SMI130_ANY_MOTION_Y_ENABLE
+* 2 | SMI130_ANY_MOTION_Z_ENABLE
+* 3 | SMI130_DOUBLE_TAP_ENABLE
+* 4 | SMI130_SINGLE_TAP_ENABLE
+* 5 | SMI130_ORIENT_ENABLE
+* 6 | SMI130_FLAT_ENABLE
+*
+* @param v_intr_enable_zero_u8 : The interrupt enable value
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_enable_0(
+u8 v_enable_u8, u8*v_intr_enable_zero_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* select interrupt to read*/
+ switch (v_enable_u8) {
+ case SMI130_ANY_MOTION_X_ENABLE:
+ /* read the any motion interrupt x data*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_zero_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE);
+ break;
+ case SMI130_ANY_MOTION_Y_ENABLE:
+ /* read the any motion interrupt y data*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_zero_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE);
+ break;
+ case SMI130_ANY_MOTION_Z_ENABLE:
+ /* read the any motion interrupt z data*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_zero_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE);
+ break;
+ case SMI130_DOUBLE_TAP_ENABLE:
+ /* read the double tap interrupt data*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_zero_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE);
+ break;
+ case SMI130_SINGLE_TAP_ENABLE:
+ /* read the single tap interrupt data*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_zero_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE);
+ break;
+ case SMI130_ORIENT_ENABLE:
+ /* read the orient interrupt data*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_ENABLE_0_ORIENT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_zero_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_0_ORIENT_ENABLE);
+ break;
+ case SMI130_FLAT_ENABLE:
+ /* read the flat interrupt data*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_ENABLE_0_FLAT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_zero_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_0_FLAT_ENABLE);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to set
+* interrupt enable from the register 0x50 bit 0 to 7
+*
+*
+*
+*
+* @param v_enable_u8 : Value to decided to select interrupt
+* v_enable_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_ANY_MOTION_X_ENABLE
+* 1 | SMI130_ANY_MOTION_Y_ENABLE
+* 2 | SMI130_ANY_MOTION_Z_ENABLE
+* 3 | SMI130_DOUBLE_TAP_ENABLE
+* 4 | SMI130_SINGLE_TAP_ENABLE
+* 5 | SMI130_ORIENT_ENABLE
+* 6 | SMI130_FLAT_ENABLE
+*
+* @param v_intr_enable_zero_u8 : The interrupt enable value
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_enable_0(
+u8 v_enable_u8, u8 v_intr_enable_zero_u8)
+{
+/* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_enable_u8) {
+ case SMI130_ANY_MOTION_X_ENABLE:
+ /* write any motion x*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE,
+ v_intr_enable_zero_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_ANY_MOTION_Y_ENABLE:
+ /* write any motion y*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE,
+ v_intr_enable_zero_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_ANY_MOTION_Z_ENABLE:
+ /* write any motion z*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE,
+ v_intr_enable_zero_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_DOUBLE_TAP_ENABLE:
+ /* write double tap*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE,
+ v_intr_enable_zero_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_SINGLE_TAP_ENABLE:
+ /* write single tap*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE,
+ v_intr_enable_zero_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_ORIENT_ENABLE:
+ /* write orient interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_ENABLE_0_ORIENT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_0_ORIENT_ENABLE,
+ v_intr_enable_zero_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_0_ORIENT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_FLAT_ENABLE:
+ /* write flat interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_ENABLE_0_FLAT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_0_FLAT_ENABLE,
+ v_intr_enable_zero_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_0_FLAT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+/*!
+* @brief This API is used to read
+* interrupt enable byte1 from the register 0x51 bit 0 to 6
+* @brief It read the high_g_x,high_g_y,high_g_z,low_g_enable
+* data ready, fifo full and fifo water mark.
+*
+*
+*
+* @param v_enable_u8 : The value of interrupt enable
+* @param v_enable_u8 : Value to decided to select interrupt
+* v_enable_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_HIGH_G_X_ENABLE
+* 1 | SMI130_HIGH_G_Y_ENABLE
+* 2 | SMI130_HIGH_G_Z_ENABLE
+* 3 | SMI130_LOW_G_ENABLE
+* 4 | SMI130_DATA_RDY_ENABLE
+* 5 | SMI130_FIFO_FULL_ENABLE
+* 6 | SMI130_FIFO_WM_ENABLE
+*
+* @param v_intr_enable_1_u8 : The interrupt enable value
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_enable_1(
+u8 v_enable_u8, u8*v_intr_enable_1_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_enable_u8) {
+ case SMI130_HIGH_G_X_ENABLE:
+ /* read high_g_x interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_1_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE);
+ break;
+ case SMI130_HIGH_G_Y_ENABLE:
+ /* read high_g_y interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_1_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE);
+ break;
+ case SMI130_HIGH_G_Z_ENABLE:
+ /* read high_g_z interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_1_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE);
+ break;
+ case SMI130_LOW_G_ENABLE:
+ /* read low_g interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_1_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_1_LOW_G_ENABLE);
+ break;
+ case SMI130_DATA_RDY_ENABLE:
+ /* read data ready interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_DATA_RDY_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_1_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_1_DATA_RDY_ENABLE);
+ break;
+ case SMI130_FIFO_FULL_ENABLE:
+ /* read fifo full interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_1_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE);
+ break;
+ case SMI130_FIFO_WM_ENABLE:
+ /* read fifo water mark interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_FIFO_WM_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_1_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_1_FIFO_WM_ENABLE);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to set
+* interrupt enable byte1 from the register 0x51 bit 0 to 6
+* @brief It read the high_g_x,high_g_y,high_g_z,low_g_enable
+* data ready, fifo full and fifo water mark.
+*
+*
+*
+* @param v_enable_u8 : The value of interrupt enable
+* @param v_enable_u8 : Value to decided to select interrupt
+* v_enable_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_HIGH_G_X_ENABLE
+* 1 | SMI130_HIGH_G_Y_ENABLE
+* 2 | SMI130_HIGH_G_Z_ENABLE
+* 3 | SMI130_LOW_G_ENABLE
+* 4 | SMI130_DATA_RDY_ENABLE
+* 5 | SMI130_FIFO_FULL_ENABLE
+* 6 | SMI130_FIFO_WM_ENABLE
+*
+* @param v_intr_enable_1_u8 : The interrupt enable value
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_enable_1(
+u8 v_enable_u8, u8 v_intr_enable_1_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_enable_u8) {
+ case SMI130_HIGH_G_X_ENABLE:
+ /* write high_g_x interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE,
+ v_intr_enable_1_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_HIGH_G_Y_ENABLE:
+ /* write high_g_y interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE,
+ v_intr_enable_1_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_HIGH_G_Z_ENABLE:
+ /* write high_g_z interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE,
+ v_intr_enable_1_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_LOW_G_ENABLE:
+ /* write low_g interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_1_LOW_G_ENABLE,
+ v_intr_enable_1_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_DATA_RDY_ENABLE:
+ /* write data ready interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_DATA_RDY_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_1_DATA_RDY_ENABLE,
+ v_intr_enable_1_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_DATA_RDY_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_FIFO_FULL_ENABLE:
+ /* write fifo full interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE,
+ v_intr_enable_1_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_FIFO_WM_ENABLE:
+ /* write fifo water mark interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_ENABLE_1_FIFO_WM_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_1_FIFO_WM_ENABLE,
+ v_intr_enable_1_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_1_FIFO_WM_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to read
+* interrupt enable byte2 from the register bit 0x52 bit 0 to 3
+* @brief It reads no motion x,y and z
+*
+*
+*
+* @param v_enable_u8: The value of interrupt enable
+* v_enable_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_NOMOTION_X_ENABLE
+* 1 | SMI130_NOMOTION_Y_ENABLE
+* 2 | SMI130_NOMOTION_Z_ENABLE
+*
+* @param v_intr_enable_2_u8 : The interrupt enable value
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_enable_2(
+u8 v_enable_u8, u8*v_intr_enable_2_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_enable_u8) {
+ case SMI130_NOMOTION_X_ENABLE:
+ /* read no motion x*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_2_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE);
+ break;
+ case SMI130_NOMOTION_Y_ENABLE:
+ /* read no motion y*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_2_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE);
+ break;
+ case SMI130_NOMOTION_Z_ENABLE:
+ /* read no motion z*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_enable_2_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to set
+* interrupt enable byte2 from the register bit 0x52 bit 0 to 3
+* @brief It reads no motion x,y and z
+*
+*
+*
+* @param v_enable_u8: The value of interrupt enable
+* v_enable_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_NOMOTION_X_ENABLE
+* 1 | SMI130_NOMOTION_Y_ENABLE
+* 2 | SMI130_NOMOTION_Z_ENABLE
+*
+* @param v_intr_enable_2_u8 : The interrupt enable value
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_enable_2(
+u8 v_enable_u8, u8 v_intr_enable_2_u8)
+{
+/* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_enable_u8) {
+ case SMI130_NOMOTION_X_ENABLE:
+ /* write no motion x*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE,
+ v_intr_enable_2_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_NOMOTION_Y_ENABLE:
+ /* write no motion y*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE,
+ v_intr_enable_2_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_NOMOTION_Z_ENABLE:
+ /* write no motion z*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE,
+ v_intr_enable_2_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+ /*!
+* @brief This API is used to read
+* interrupt enable step detector interrupt from
+* the register bit 0x52 bit 3
+*
+*
+*
+*
+* @param v_step_intr_u8 : The value of step detector interrupt enable
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_step_detector_enable(
+u8*v_step_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the step detector interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_step_intr_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE);
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API is used to set
+* interrupt enable step detector interrupt from
+* the register bit 0x52 bit 3
+*
+*
+*
+*
+* @param v_step_intr_u8 : The value of step detector interrupt enable
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_step_detector_enable(
+u8 v_step_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE,
+ v_step_intr_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief Configure trigger condition of interrupt1
+* and interrupt2 pin from the register 0x53
+* @brief interrupt1 - bit 0
+* @brief interrupt2 - bit 4
+*
+* @param v_channel_u8: The value of edge trigger selection
+* v_channel_u8 | Edge trigger
+* ---------------|---------------
+* 0 | SMI130_INTR1_EDGE_CTRL
+* 1 | SMI130_INTR2_EDGE_CTRL
+*
+* @param v_intr_edge_ctrl_u8 : The value of edge trigger enable
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_EDGE
+* 0x00 | SMI130_LEVEL
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_edge_ctrl(
+u8 v_channel_u8, u8*v_intr_edge_ctrl_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ case SMI130_INTR1_EDGE_CTRL:
+ /* read the edge trigger interrupt1*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_EDGE_CTRL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_edge_ctrl_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR1_EDGE_CTRL);
+ break;
+ case SMI130_INTR2_EDGE_CTRL:
+ /* read the edge trigger interrupt2*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_EDGE_CTRL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_edge_ctrl_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR2_EDGE_CTRL);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief Configure trigger condition of interrupt1
+* and interrupt2 pin from the register 0x53
+* @brief interrupt1 - bit 0
+* @brief interrupt2 - bit 4
+*
+* @param v_channel_u8: The value of edge trigger selection
+* v_channel_u8 | Edge trigger
+* ---------------|---------------
+* 0 | SMI130_INTR1_EDGE_CTRL
+* 1 | SMI130_INTR2_EDGE_CTRL
+*
+* @param v_intr_edge_ctrl_u8 : The value of edge trigger enable
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_EDGE
+* 0x00 | SMI130_LEVEL
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_edge_ctrl(
+u8 v_channel_u8, u8 v_intr_edge_ctrl_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ case SMI130_INTR1_EDGE_CTRL:
+ /* write the edge trigger interrupt1*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_EDGE_CTRL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR1_EDGE_CTRL,
+ v_intr_edge_ctrl_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_EDGE_CTRL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_EDGE_CTRL:
+ /* write the edge trigger interrupt2*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_EDGE_CTRL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR2_EDGE_CTRL,
+ v_intr_edge_ctrl_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_EDGE_CTRL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief API used for get the Configure level condition of interrupt1
+* and interrupt2 pin form the register 0x53
+* @brief interrupt1 - bit 1
+* @brief interrupt2 - bit 5
+*
+* @param v_channel_u8: The value of level condition selection
+* v_channel_u8 | level selection
+* ---------------|---------------
+* 0 | SMI130_INTR1_LEVEL
+* 1 | SMI130_INTR2_LEVEL
+*
+* @param v_intr_level_u8 : The value of level of interrupt enable
+* value | Behaviour
+* ----------|-------------------
+* 0x01 | SMI130_LEVEL_HIGH
+* 0x00 | SMI130_LEVEL_LOW
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_level(
+u8 v_channel_u8, u8*v_intr_level_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ case SMI130_INTR1_LEVEL:
+ /* read the interrupt1 level*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_LEVEL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_level_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR1_LEVEL);
+ break;
+ case SMI130_INTR2_LEVEL:
+ /* read the interrupt2 level*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_LEVEL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_level_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR2_LEVEL);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief API used for set the Configure level condition of interrupt1
+* and interrupt2 pin form the register 0x53
+* @brief interrupt1 - bit 1
+* @brief interrupt2 - bit 5
+*
+* @param v_channel_u8: The value of level condition selection
+* v_channel_u8 | level selection
+* ---------------|---------------
+* 0 | SMI130_INTR1_LEVEL
+* 1 | SMI130_INTR2_LEVEL
+*
+* @param v_intr_level_u8 : The value of level of interrupt enable
+* value | Behaviour
+* ----------|-------------------
+* 0x01 | SMI130_LEVEL_HIGH
+* 0x00 | SMI130_LEVEL_LOW
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_level(
+u8 v_channel_u8, u8 v_intr_level_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ case SMI130_INTR1_LEVEL:
+ /* write the interrupt1 level*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_LEVEL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR1_LEVEL, v_intr_level_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_LEVEL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_LEVEL:
+ /* write the interrupt2 level*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_LEVEL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR2_LEVEL, v_intr_level_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_LEVEL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief API used to get configured output enable of interrupt1
+* and interrupt2 from the register 0x53
+* @brief interrupt1 - bit 2
+* @brief interrupt2 - bit 6
+*
+*
+* @param v_channel_u8: The value of output type enable selection
+* v_channel_u8 | level selection
+* ---------------|---------------
+* 0 | SMI130_INTR1_OUTPUT_TYPE
+* 1 | SMI130_INTR2_OUTPUT_TYPE
+*
+* @param v_intr_output_type_u8 :
+* The value of output type of interrupt enable
+* value | Behaviour
+* ----------|-------------------
+* 0x01 | SMI130_OPEN_DRAIN
+* 0x00 | SMI130_PUSH_PULL
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_output_type(
+u8 v_channel_u8, u8*v_intr_output_type_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ case SMI130_INTR1_OUTPUT_TYPE:
+ /* read the output type of interrupt1*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_OUTPUT_TYPE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_output_type_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR1_OUTPUT_TYPE);
+ break;
+ case SMI130_INTR2_OUTPUT_TYPE:
+ /* read the output type of interrupt2*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_OUTPUT_TYPE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_output_type_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR2_OUTPUT_TYPE);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief API used to set output enable of interrupt1
+* and interrupt2 from the register 0x53
+* @brief interrupt1 - bit 2
+* @brief interrupt2 - bit 6
+*
+*
+* @param v_channel_u8: The value of output type enable selection
+* v_channel_u8 | level selection
+* ---------------|---------------
+* 0 | SMI130_INTR1_OUTPUT_TYPE
+* 1 | SMI130_INTR2_OUTPUT_TYPE
+*
+* @param v_intr_output_type_u8 :
+* The value of output type of interrupt enable
+* value | Behaviour
+* ----------|-------------------
+* 0x01 | SMI130_OPEN_DRAIN
+* 0x00 | SMI130_PUSH_PULL
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_output_type(
+u8 v_channel_u8, u8 v_intr_output_type_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ case SMI130_INTR1_OUTPUT_TYPE:
+ /* write the output type of interrupt1*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_OUTPUT_TYPE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR1_OUTPUT_TYPE,
+ v_intr_output_type_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_OUTPUT_TYPE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_OUTPUT_TYPE:
+ /* write the output type of interrupt2*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_OUTPUT_TYPE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR2_OUTPUT_TYPE,
+ v_intr_output_type_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_OUTPUT_TYPE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+* @brief API used to get the Output enable for interrupt1
+* and interrupt1 pin from the register 0x53
+* @brief interrupt1 - bit 3
+* @brief interrupt2 - bit 7
+*
+* @param v_channel_u8: The value of output enable selection
+* v_channel_u8 | level selection
+* ---------------|---------------
+* 0 | SMI130_INTR1_OUTPUT_TYPE
+* 1 | SMI130_INTR2_OUTPUT_TYPE
+*
+* @param v_output_enable_u8 :
+* The value of output enable of interrupt enable
+* value | Behaviour
+* ----------|-------------------
+* 0x01 | SMI130_INPUT
+* 0x00 | SMI130_OUTPUT
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_output_enable(
+u8 v_channel_u8, u8*v_output_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ case SMI130_INTR1_OUTPUT_ENABLE:
+ /* read the output enable of interrupt1*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_OUTPUT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_output_enable_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR1_OUTPUT_ENABLE);
+ break;
+ case SMI130_INTR2_OUTPUT_ENABLE:
+ /* read the output enable of interrupt2*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_OUTPUT_EN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_output_enable_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR2_OUTPUT_EN);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+* @brief API used to set the Output enable for interrupt1
+* and interrupt1 pin from the register 0x53
+* @brief interrupt1 - bit 3
+* @brief interrupt2 - bit 7
+*
+* @param v_channel_u8: The value of output enable selection
+* v_channel_u8 | level selection
+* ---------------|---------------
+* 0 | SMI130_INTR1_OUTPUT_TYPE
+* 1 | SMI130_INTR2_OUTPUT_TYPE
+*
+* @param v_output_enable_u8 :
+* The value of output enable of interrupt enable
+* value | Behaviour
+* ----------|-------------------
+* 0x01 | SMI130_INPUT
+* 0x00 | SMI130_OUTPUT
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_output_enable(
+u8 v_channel_u8, u8 v_output_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ case SMI130_INTR1_OUTPUT_ENABLE:
+ /* write the output enable of interrupt1*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_OUTPUT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR1_OUTPUT_ENABLE,
+ v_output_enable_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_OUTPUT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_OUTPUT_ENABLE:
+ /* write the output enable of interrupt2*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_OUTPUT_EN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR2_OUTPUT_EN,
+ v_output_enable_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_OUTPUT_EN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to get the latch duration
+* from the register 0x54 bit 0 to 3
+* @brief This latch selection is not applicable for data ready,
+* orientation and flat interrupts.
+*
+*
+*
+* @param v_latch_intr_u8 : The value of latch duration
+* Latch Duration | value
+* --------------------------------------|------------------
+* SMI130_LATCH_DUR_NONE | 0x00
+* SMI130_LATCH_DUR_312_5_MICRO_SEC | 0x01
+* SMI130_LATCH_DUR_625_MICRO_SEC | 0x02
+* SMI130_LATCH_DUR_1_25_MILLI_SEC | 0x03
+* SMI130_LATCH_DUR_2_5_MILLI_SEC | 0x04
+* SMI130_LATCH_DUR_5_MILLI_SEC | 0x05
+* SMI130_LATCH_DUR_10_MILLI_SEC | 0x06
+* SMI130_LATCH_DUR_20_MILLI_SEC | 0x07
+* SMI130_LATCH_DUR_40_MILLI_SEC | 0x08
+* SMI130_LATCH_DUR_80_MILLI_SEC | 0x09
+* SMI130_LATCH_DUR_160_MILLI_SEC | 0x0A
+* SMI130_LATCH_DUR_320_MILLI_SEC | 0x0B
+* SMI130_LATCH_DUR_640_MILLI_SEC | 0x0C
+* SMI130_LATCH_DUR_1_28_SEC | 0x0D
+* SMI130_LATCH_DUR_2_56_SEC | 0x0E
+* SMI130_LATCHED | 0x0F
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_latch_intr(
+u8*v_latch_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the latch duration value*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_LATCH__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_latch_intr_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_LATCH);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to set the latch duration
+* from the register 0x54 bit 0 to 3
+* @brief This latch selection is not applicable for data ready,
+* orientation and flat interrupts.
+*
+*
+*
+* @param v_latch_intr_u8 : The value of latch duration
+* Latch Duration | value
+* --------------------------------------|------------------
+* SMI130_LATCH_DUR_NONE | 0x00
+* SMI130_LATCH_DUR_312_5_MICRO_SEC | 0x01
+* SMI130_LATCH_DUR_625_MICRO_SEC | 0x02
+* SMI130_LATCH_DUR_1_25_MILLI_SEC | 0x03
+* SMI130_LATCH_DUR_2_5_MILLI_SEC | 0x04
+* SMI130_LATCH_DUR_5_MILLI_SEC | 0x05
+* SMI130_LATCH_DUR_10_MILLI_SEC | 0x06
+* SMI130_LATCH_DUR_20_MILLI_SEC | 0x07
+* SMI130_LATCH_DUR_40_MILLI_SEC | 0x08
+* SMI130_LATCH_DUR_80_MILLI_SEC | 0x09
+* SMI130_LATCH_DUR_160_MILLI_SEC | 0x0A
+* SMI130_LATCH_DUR_320_MILLI_SEC | 0x0B
+* SMI130_LATCH_DUR_640_MILLI_SEC | 0x0C
+* SMI130_LATCH_DUR_1_28_SEC | 0x0D
+* SMI130_LATCH_DUR_2_56_SEC | 0x0E
+* SMI130_LATCHED | 0x0F
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_latch_intr(u8 v_latch_intr_u8)
+{
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_latch_intr_u8 <= SMI130_MAX_LATCH_INTR) {
+ /* write the latch duration value*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_LATCH__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_LATCH, v_latch_intr_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_LATCH__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief API used to get input enable for interrupt1
+* and interrupt2 pin from the register 0x54
+* @brief interrupt1 - bit 4
+* @brief interrupt2 - bit 5
+*
+* @param v_channel_u8: The value of input enable selection
+* v_channel_u8 | input selection
+* ---------------|---------------
+* 0 | SMI130_INTR1_INPUT_ENABLE
+* 1 | SMI130_INTR2_INPUT_ENABLE
+*
+* @param v_input_en_u8 :
+* The value of input enable of interrupt enable
+* value | Behaviour
+* ----------|-------------------
+* 0x01 | SMI130_INPUT
+* 0x00 | SMI130_OUTPUT
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_input_enable(
+u8 v_channel_u8, u8*v_input_en_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* read input enable of interrup1 and interrupt2*/
+ case SMI130_INTR1_INPUT_ENABLE:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_INPUT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_input_en_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR1_INPUT_ENABLE);
+ break;
+ case SMI130_INTR2_INPUT_ENABLE:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_INPUT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_input_en_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR2_INPUT_ENABLE);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief API used to set input enable for interrupt1
+* and interrupt2 pin from the register 0x54
+* @brief interrupt1 - bit 4
+* @brief interrupt2 - bit 5
+*
+* @param v_channel_u8: The value of input enable selection
+* v_channel_u8 | input selection
+* ---------------|---------------
+* 0 | SMI130_INTR1_INPUT_ENABLE
+* 1 | SMI130_INTR2_INPUT_ENABLE
+*
+* @param v_input_en_u8 :
+* The value of input enable of interrupt enable
+* value | Behaviour
+* ----------|-------------------
+* 0x01 | SMI130_INPUT
+* 0x00 | SMI130_OUTPUT
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_input_enable(
+u8 v_channel_u8, u8 v_input_en_u8)
+{
+/* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* write input enable of interrup1 and interrupt2*/
+ case SMI130_INTR1_INPUT_ENABLE:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_INPUT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR1_INPUT_ENABLE, v_input_en_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR1_INPUT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_INPUT_ENABLE:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_INPUT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR2_INPUT_ENABLE, v_input_en_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR2_INPUT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+ /*!
+* @brief reads the Low g interrupt mapped to interrupt1
+* and interrupt2 from the register 0x55 and 0x57
+* @brief interrupt1 bit 0 in the register 0x55
+* @brief interrupt2 bit 0 in the register 0x57
+*
+*
+* @param v_channel_u8: The value of low_g selection
+* v_channel_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_INTR1_MAP_LOW_G
+* 1 | SMI130_INTR2_MAP_LOW_G
+*
+* @param v_intr_low_g_u8 : The value of low_g enable
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_low_g(
+u8 v_channel_u8, u8*v_intr_low_g_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* read the low_g interrupt*/
+ case SMI130_INTR1_MAP_LOW_G:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_LOW_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_low_g_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_LOW_G);
+ break;
+ case SMI130_INTR2_MAP_LOW_G:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_LOW_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_low_g_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_LOW_G);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+* @brief set the Low g interrupt mapped to interrupt1
+* and interrupt2 from the register 0x55 and 0x57
+* @brief interrupt1 bit 0 in the register 0x55
+* @brief interrupt2 bit 0 in the register 0x57
+*
+*
+* @param v_channel_u8: The value of low_g selection
+* v_channel_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_INTR1_MAP_LOW_G
+* 1 | SMI130_INTR2_MAP_LOW_G
+*
+* @param v_intr_low_g_u8 : The value of low_g enable
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_low_g(
+u8 v_channel_u8, u8 v_intr_low_g_u8)
+{
+/* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+u8 v_step_cnt_stat_u8 = SMI130_INIT_VALUE;
+u8 v_step_det_stat_u8 = SMI130_INIT_VALUE;
+
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* check the step detector interrupt enable status*/
+ com_rslt = smi130_get_step_detector_enable(&v_step_det_stat_u8);
+ /* disable the step detector interrupt*/
+ if (v_step_det_stat_u8 != SMI130_INIT_VALUE)
+ com_rslt += smi130_set_step_detector_enable(SMI130_INIT_VALUE);
+ /* check the step counter interrupt enable status*/
+ com_rslt += smi130_get_step_counter_enable(&v_step_cnt_stat_u8);
+ /* disable the step counter interrupt*/
+ if (v_step_cnt_stat_u8 != SMI130_INIT_VALUE)
+ com_rslt += smi130_set_step_counter_enable(
+ SMI130_INIT_VALUE);
+ switch (v_channel_u8) {
+ /* write the low_g interrupt*/
+ case SMI130_INTR1_MAP_LOW_G:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_LOW_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_LOW_G, v_intr_low_g_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_LOW_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_MAP_LOW_G:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_LOW_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_LOW_G, v_intr_low_g_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_LOW_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+/*!
+* @brief Reads the HIGH g interrupt mapped to interrupt1
+* and interrupt2 from the register 0x55 and 0x57
+* @brief interrupt1 bit 1 in the register 0x55
+* @brief interrupt2 bit 1 in the register 0x57
+*
+*
+* @param v_channel_u8: The value of high_g selection
+* v_channel_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_INTR1_MAP_HIGH_G
+* 1 | SMI130_INTR2_MAP_HIGH_G
+*
+* @param v_intr_high_g_u8 : The value of high_g enable
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_high_g(
+u8 v_channel_u8, u8*v_intr_high_g_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the high_g interrupt*/
+ switch (v_channel_u8) {
+ case SMI130_INTR1_MAP_HIGH_G:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_HIGH_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_high_g_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_HIGH_G);
+ break;
+ case SMI130_INTR2_MAP_HIGH_G:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_HIGH_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_high_g_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_HIGH_G);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief Write the HIGH g interrupt mapped to interrupt1
+* and interrupt2 from the register 0x55 and 0x57
+* @brief interrupt1 bit 1 in the register 0x55
+* @brief interrupt2 bit 1 in the register 0x57
+*
+*
+* @param v_channel_u8: The value of high_g selection
+* v_channel_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_INTR1_MAP_HIGH_G
+* 1 | SMI130_INTR2_MAP_HIGH_G
+*
+* @param v_intr_high_g_u8 : The value of high_g enable
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_high_g(
+u8 v_channel_u8, u8 v_intr_high_g_u8)
+{
+/* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* write the high_g interrupt*/
+ case SMI130_INTR1_MAP_HIGH_G:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_HIGH_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_HIGH_G, v_intr_high_g_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_HIGH_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_MAP_HIGH_G:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_HIGH_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_HIGH_G, v_intr_high_g_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_HIGH_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+/*!
+* @brief Reads the Any motion interrupt
+* interrupt mapped to interrupt1
+* and interrupt2 from the register 0x55 and 0x57
+* @brief interrupt1 bit 2 in the register 0x55
+* @brief interrupt2 bit 2 in the register 0x57
+*
+*
+* @param v_channel_u8: The value of any motion selection
+* v_channel_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_INTR1_MAP_ANY_MOTION
+* 1 | SMI130_INTR2_MAP_ANY_MOTION
+*
+* @param v_intr_any_motion_u8 : The value of any motion enable
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_any_motion(
+u8 v_channel_u8, u8*v_intr_any_motion_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* read the any motion interrupt*/
+ case SMI130_INTR1_MAP_ANY_MOTION:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_ANY_MOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_any_motion_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_ANY_MOTION);
+ break;
+ case SMI130_INTR2_MAP_ANY_MOTION:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_ANY_MOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_any_motion_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_ANY_MOTION);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief Write the Any motion interrupt
+* interrupt mapped to interrupt1
+* and interrupt2 from the register 0x55 and 0x57
+* @brief interrupt1 bit 2 in the register 0x55
+* @brief interrupt2 bit 2 in the register 0x57
+*
+*
+* @param v_channel_u8: The value of any motion selection
+* v_channel_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_INTR1_MAP_ANY_MOTION
+* 1 | SMI130_INTR2_MAP_ANY_MOTION
+*
+* @param v_intr_any_motion_u8 : The value of any motion enable
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_any_motion(
+u8 v_channel_u8, u8 v_intr_any_motion_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+u8 sig_mot_stat = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the status of significant motion interrupt*/
+ com_rslt = smi130_get_intr_significant_motion_select(&sig_mot_stat);
+ /* disable the significant motion interrupt*/
+ if (sig_mot_stat != SMI130_INIT_VALUE)
+ com_rslt += smi130_set_intr_significant_motion_select(
+ SMI130_INIT_VALUE);
+ switch (v_channel_u8) {
+ /* write the any motion interrupt*/
+ case SMI130_INTR1_MAP_ANY_MOTION:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_ANY_MOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_ANY_MOTION,
+ v_intr_any_motion_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_ANY_MOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_MAP_ANY_MOTION:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_ANY_MOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_ANY_MOTION,
+ v_intr_any_motion_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_ANY_MOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+/*!
+* @brief Reads the No motion interrupt
+* interrupt mapped to interrupt1
+* and interrupt2 from the register 0x55 and 0x57
+* @brief interrupt1 bit 3 in the register 0x55
+* @brief interrupt2 bit 3 in the register 0x57
+*
+*
+* @param v_channel_u8: The value of no motion selection
+* v_channel_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_INTR1_MAP_NOMO
+* 1 | SMI130_INTR2_MAP_NOMO
+*
+* @param v_intr_nomotion_u8 : The value of no motion enable
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_nomotion(
+u8 v_channel_u8, u8*v_intr_nomotion_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* read the no motion interrupt*/
+ case SMI130_INTR1_MAP_NOMO:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_NOMOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_nomotion_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_NOMOTION);
+ break;
+ case SMI130_INTR2_MAP_NOMO:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_NOMOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_nomotion_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_NOMOTION);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief Write the No motion interrupt
+* interrupt mapped to interrupt1
+* and interrupt2 from the register 0x55 and 0x57
+* @brief interrupt1 bit 3 in the register 0x55
+* @brief interrupt2 bit 3 in the register 0x57
+*
+*
+* @param v_channel_u8: The value of no motion selection
+* v_channel_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_INTR1_MAP_NOMO
+* 1 | SMI130_INTR2_MAP_NOMO
+*
+* @param v_intr_nomotion_u8 : The value of no motion enable
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_nomotion(
+u8 v_channel_u8, u8 v_intr_nomotion_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* write the no motion interrupt*/
+ case SMI130_INTR1_MAP_NOMO:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_NOMOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_NOMOTION,
+ v_intr_nomotion_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_NOMOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_MAP_NOMO:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_NOMOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_NOMOTION,
+ v_intr_nomotion_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_NOMOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+/*!
+* @brief Reads the Double Tap interrupt
+* interrupt mapped to interrupt1
+* and interrupt2 from the register 0x55 and 0x57
+* @brief interrupt1 bit 4 in the register 0x55
+* @brief interrupt2 bit 4 in the register 0x57
+*
+*
+* @param v_channel_u8: The value of double tap interrupt selection
+* v_channel_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_INTR1_MAP_DOUBLE_TAP
+* 1 | SMI130_INTR2_MAP_DOUBLE_TAP
+*
+* @param v_intr_double_tap_u8 : The value of double tap enable
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_double_tap(
+u8 v_channel_u8, u8*v_intr_double_tap_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ case SMI130_INTR1_MAP_DOUBLE_TAP:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_DOUBLE_TAP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_double_tap_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_DOUBLE_TAP);
+ break;
+ case SMI130_INTR2_MAP_DOUBLE_TAP:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_DOUBLE_TAP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_double_tap_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_DOUBLE_TAP);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief Write the Double Tap interrupt
+* interrupt mapped to interrupt1
+* and interrupt2 from the register 0x55 and 0x57
+* @brief interrupt1 bit 4 in the register 0x55
+* @brief interrupt2 bit 4 in the register 0x57
+*
+*
+* @param v_channel_u8: The value of double tap interrupt selection
+* v_channel_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_INTR1_MAP_DOUBLE_TAP
+* 1 | SMI130_INTR2_MAP_DOUBLE_TAP
+*
+* @param v_intr_double_tap_u8 : The value of double tap enable
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_double_tap(
+u8 v_channel_u8, u8 v_intr_double_tap_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* set the double tap interrupt*/
+ case SMI130_INTR1_MAP_DOUBLE_TAP:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_DOUBLE_TAP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_DOUBLE_TAP,
+ v_intr_double_tap_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_DOUBLE_TAP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_MAP_DOUBLE_TAP:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_DOUBLE_TAP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_DOUBLE_TAP,
+ v_intr_double_tap_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_DOUBLE_TAP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+/*!
+* @brief Reads the Single Tap interrupt
+* interrupt mapped to interrupt1
+* and interrupt2 from the register 0x55 and 0x57
+* @brief interrupt1 bit 5 in the register 0x55
+* @brief interrupt2 bit 5 in the register 0x57
+*
+*
+* @param v_channel_u8: The value of single tap interrupt selection
+* v_channel_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_INTR1_MAP_SINGLE_TAP
+* 1 | SMI130_INTR2_MAP_SINGLE_TAP
+*
+* @param v_intr_single_tap_u8 : The value of single tap enable
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_single_tap(
+u8 v_channel_u8, u8*v_intr_single_tap_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* reads the single tap interrupt*/
+ case SMI130_INTR1_MAP_SINGLE_TAP:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_SINGLE_TAP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_single_tap_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_SINGLE_TAP);
+ break;
+ case SMI130_INTR2_MAP_SINGLE_TAP:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_SINGLE_TAP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_single_tap_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_SINGLE_TAP);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief Write the Single Tap interrupt
+* interrupt mapped to interrupt1
+* and interrupt2 from the register 0x55 and 0x57
+* @brief interrupt1 bit 5 in the register 0x55
+* @brief interrupt2 bit 5 in the register 0x57
+*
+*
+* @param v_channel_u8: The value of single tap interrupt selection
+* v_channel_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_INTR1_MAP_SINGLE_TAP
+* 1 | SMI130_INTR2_MAP_SINGLE_TAP
+*
+* @param v_intr_single_tap_u8 : The value of single tap enable
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_single_tap(
+u8 v_channel_u8, u8 v_intr_single_tap_u8)
+{
+/* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* write the single tap interrupt*/
+ case SMI130_INTR1_MAP_SINGLE_TAP:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_SINGLE_TAP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_SINGLE_TAP,
+ v_intr_single_tap_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_SINGLE_TAP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_MAP_SINGLE_TAP:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_SINGLE_TAP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_SINGLE_TAP,
+ v_intr_single_tap_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_SINGLE_TAP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+/*!
+* @brief Reads the Orient interrupt
+* interrupt mapped to interrupt1
+* and interrupt2 from the register 0x55 and 0x57
+* @brief interrupt1 bit 6 in the register 0x55
+* @brief interrupt2 bit 6 in the register 0x57
+*
+*
+* @param v_channel_u8: The value of orient interrupt selection
+* v_channel_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_INTR1_MAP_ORIENT
+* 1 | SMI130_INTR2_MAP_ORIENT
+*
+* @param v_intr_orient_u8 : The value of orient enable
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_orient(
+u8 v_channel_u8, u8*v_intr_orient_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* read the orientation interrupt*/
+ case SMI130_INTR1_MAP_ORIENT:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_ORIENT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_orient_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_ORIENT);
+ break;
+ case SMI130_INTR2_MAP_ORIENT:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_ORIENT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_orient_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_ORIENT);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief Write the Orient interrupt
+* interrupt mapped to interrupt1
+* and interrupt2 from the register 0x55 and 0x57
+* @brief interrupt1 bit 6 in the register 0x55
+* @brief interrupt2 bit 6 in the register 0x57
+*
+*
+* @param v_channel_u8: The value of orient interrupt selection
+* v_channel_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_INTR1_MAP_ORIENT
+* 1 | SMI130_INTR2_MAP_ORIENT
+*
+* @param v_intr_orient_u8 : The value of orient enable
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_orient(
+u8 v_channel_u8, u8 v_intr_orient_u8)
+{
+/* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* write the orientation interrupt*/
+ case SMI130_INTR1_MAP_ORIENT:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_ORIENT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_ORIENT, v_intr_orient_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_ORIENT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_MAP_ORIENT:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_ORIENT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_ORIENT, v_intr_orient_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_ORIENT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+ /*!
+* @brief Reads the Flat interrupt
+* mapped to interrupt1
+* and interrupt2 from the register 0x55 and 0x57
+* @brief interrupt1 bit 7 in the register 0x55
+* @brief interrupt2 bit 7 in the register 0x57
+*
+*
+* @param v_channel_u8: The value of flat interrupt selection
+* v_channel_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_INTR1_MAP_FLAT
+* 1 | SMI130_INTR2_MAP_FLAT
+*
+* @param v_intr_flat_u8 : The value of flat enable
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_flat(
+u8 v_channel_u8, u8*v_intr_flat_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* read the flat interrupt*/
+ case SMI130_INTR1_MAP_FLAT:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_FLAT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_flat_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_FLAT);
+ break;
+ case SMI130_INTR2_MAP_FLAT:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_FLAT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_flat_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_FLAT);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+* @brief Write the Flat interrupt
+* mapped to interrupt1
+* and interrupt2 from the register 0x55 and 0x57
+* @brief interrupt1 bit 7 in the register 0x55
+* @brief interrupt2 bit 7 in the register 0x57
+*
+*
+* @param v_channel_u8: The value of flat interrupt selection
+* v_channel_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_INTR1_MAP_FLAT
+* 1 | SMI130_INTR2_MAP_FLAT
+*
+* @param v_intr_flat_u8 : The value of flat enable
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_flat(
+u8 v_channel_u8, u8 v_intr_flat_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* write the flat interrupt*/
+ case SMI130_INTR1_MAP_FLAT:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_0_INTR1_FLAT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_0_INTR1_FLAT,
+ v_intr_flat_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_MAP_0_INTR1_FLAT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_MAP_FLAT:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_2_INTR2_FLAT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_2_INTR2_FLAT,
+ v_intr_flat_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_MAP_2_INTR2_FLAT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief Reads PMU trigger interrupt mapped to interrupt1
+* and interrupt2 form the register 0x56 bit 0 and 4
+* @brief interrupt1 bit 0 in the register 0x56
+* @brief interrupt2 bit 4 in the register 0x56
+*
+*
+* @param v_channel_u8: The value of pmu trigger selection
+* v_channel_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_INTR1_MAP_PMUTRIG
+* 1 | SMI130_INTR2_MAP_PMUTRIG
+*
+* @param v_intr_pmu_trig_u8 : The value of pmu trigger enable
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_pmu_trig(
+u8 v_channel_u8, u8*v_intr_pmu_trig_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* read the pmu trigger interrupt*/
+ case SMI130_INTR1_MAP_PMUTRIG:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR1_PMU_TRIG__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_pmu_trig_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR1_PMU_TRIG);
+ break;
+ case SMI130_INTR2_MAP_PMUTRIG:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR2_PMU_TRIG__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_pmu_trig_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR2_PMU_TRIG);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief Write PMU trigger interrupt mapped to interrupt1
+* and interrupt2 form the register 0x56 bit 0 and 4
+* @brief interrupt1 bit 0 in the register 0x56
+* @brief interrupt2 bit 4 in the register 0x56
+*
+*
+* @param v_channel_u8: The value of pmu trigger selection
+* v_channel_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_INTR1_MAP_PMUTRIG
+* 1 | SMI130_INTR2_MAP_PMUTRIG
+*
+* @param v_intr_pmu_trig_u8 : The value of pmu trigger enable
+* value | trigger enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_pmu_trig(
+u8 v_channel_u8, u8 v_intr_pmu_trig_u8)
+{
+/* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* write the pmu trigger interrupt*/
+ case SMI130_INTR1_MAP_PMUTRIG:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR1_PMU_TRIG__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR1_PMU_TRIG,
+ v_intr_pmu_trig_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR1_PMU_TRIG__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_MAP_PMUTRIG:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR2_PMU_TRIG__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR2_PMU_TRIG,
+ v_intr_pmu_trig_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR2_PMU_TRIG__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+/*!
+* @brief Reads FIFO Full interrupt mapped to interrupt1
+* and interrupt2 form the register 0x56 bit 5 and 1
+* @brief interrupt1 bit 5 in the register 0x56
+* @brief interrupt2 bit 1 in the register 0x56
+*
+*
+* @param v_channel_u8: The value of fifo full interrupt selection
+* v_channel_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_INTR1_MAP_FIFO_FULL
+* 1 | SMI130_INTR2_MAP_FIFO_FULL
+*
+* @param v_intr_fifo_full_u8 : The value of fifo full interrupt enable
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_fifo_full(
+u8 v_channel_u8, u8*v_intr_fifo_full_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* read the fifo full interrupt*/
+ case SMI130_INTR1_MAP_FIFO_FULL:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR1_FIFO_FULL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_fifo_full_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR1_FIFO_FULL);
+ break;
+ case SMI130_INTR2_MAP_FIFO_FULL:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR2_FIFO_FULL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_fifo_full_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR2_FIFO_FULL);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief Write FIFO Full interrupt mapped to interrupt1
+* and interrupt2 form the register 0x56 bit 5 and 1
+* @brief interrupt1 bit 5 in the register 0x56
+* @brief interrupt2 bit 1 in the register 0x56
+*
+*
+* @param v_channel_u8: The value of fifo full interrupt selection
+* v_channel_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_INTR1_MAP_FIFO_FULL
+* 1 | SMI130_INTR2_MAP_FIFO_FULL
+*
+* @param v_intr_fifo_full_u8 : The value of fifo full interrupt enable
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_fifo_full(
+u8 v_channel_u8, u8 v_intr_fifo_full_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* write the fifo full interrupt*/
+ case SMI130_INTR1_MAP_FIFO_FULL:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR1_FIFO_FULL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR1_FIFO_FULL,
+ v_intr_fifo_full_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_MAP_1_INTR1_FIFO_FULL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_MAP_FIFO_FULL:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR2_FIFO_FULL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR2_FIFO_FULL,
+ v_intr_fifo_full_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_MAP_1_INTR2_FIFO_FULL__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief Reads FIFO Watermark interrupt mapped to interrupt1
+* and interrupt2 form the register 0x56 bit 6 and 2
+* @brief interrupt1 bit 6 in the register 0x56
+* @brief interrupt2 bit 2 in the register 0x56
+*
+*
+* @param v_channel_u8: The value of fifo Watermark interrupt selection
+* v_channel_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_INTR1_MAP_FIFO_WM
+* 1 | SMI130_INTR2_MAP_FIFO_WM
+*
+* @param v_intr_fifo_wm_u8 : The value of fifo Watermark interrupt enable
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_fifo_wm(
+u8 v_channel_u8, u8*v_intr_fifo_wm_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* read the fifo water mark interrupt*/
+ case SMI130_INTR1_MAP_FIFO_WM:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR1_FIFO_WM__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_fifo_wm_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR1_FIFO_WM);
+ break;
+ case SMI130_INTR2_MAP_FIFO_WM:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR2_FIFO_WM__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_fifo_wm_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR2_FIFO_WM);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief Write FIFO Watermark interrupt mapped to interrupt1
+* and interrupt2 form the register 0x56 bit 6 and 2
+* @brief interrupt1 bit 6 in the register 0x56
+* @brief interrupt2 bit 2 in the register 0x56
+*
+*
+* @param v_channel_u8: The value of fifo Watermark interrupt selection
+* v_channel_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_INTR1_MAP_FIFO_WM
+* 1 | SMI130_INTR2_MAP_FIFO_WM
+*
+* @param v_intr_fifo_wm_u8 : The value of fifo Watermark interrupt enable
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_fifo_wm(
+u8 v_channel_u8, u8 v_intr_fifo_wm_u8)
+{
+/* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /* write the fifo water mark interrupt*/
+ case SMI130_INTR1_MAP_FIFO_WM:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR1_FIFO_WM__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR1_FIFO_WM,
+ v_intr_fifo_wm_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_MAP_1_INTR1_FIFO_WM__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_MAP_FIFO_WM:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR2_FIFO_WM__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR2_FIFO_WM,
+ v_intr_fifo_wm_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr,
+ SMI130_USER_INTR_MAP_1_INTR2_FIFO_WM__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief Reads Data Ready interrupt mapped to interrupt1
+* and interrupt2 form the register 0x56
+* @brief interrupt1 bit 7 in the register 0x56
+* @brief interrupt2 bit 3 in the register 0x56
+*
+*
+* @param v_channel_u8: The value of data ready interrupt selection
+* v_channel_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_INTR1_MAP_DATA_RDY
+* 1 | SMI130_INTR2_MAP_DATA_RDY
+*
+* @param v_intr_data_rdy_u8 : The value of data ready interrupt enable
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_data_rdy(
+u8 v_channel_u8, u8*v_intr_data_rdy_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /*Read Data Ready interrupt*/
+ case SMI130_INTR1_MAP_DATA_RDY:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR1_DATA_RDY__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_data_rdy_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR1_DATA_RDY);
+ break;
+ case SMI130_INTR2_MAP_DATA_RDY:
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR2_DATA_RDY__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_data_rdy_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR2_DATA_RDY);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief Write Data Ready interrupt mapped to interrupt1
+* and interrupt2 form the register 0x56
+* @brief interrupt1 bit 7 in the register 0x56
+* @brief interrupt2 bit 3 in the register 0x56
+*
+*
+* @param v_channel_u8: The value of data ready interrupt selection
+* v_channel_u8 | interrupt
+* ---------------|---------------
+* 0 | SMI130_INTR1_MAP_DATA_RDY
+* 1 | SMI130_INTR2_MAP_DATA_RDY
+*
+* @param v_intr_data_rdy_u8 : The value of data ready interrupt enable
+* value | interrupt enable
+* ----------|-------------------
+* 0x01 | SMI130_ENABLE
+* 0x00 | SMI130_DISABLE
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_data_rdy(
+u8 v_channel_u8, u8 v_intr_data_rdy_u8)
+{
+/* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ switch (v_channel_u8) {
+ /*Write Data Ready interrupt*/
+ case SMI130_INTR1_MAP_DATA_RDY:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR1_DATA_RDY__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR1_DATA_RDY,
+ v_intr_data_rdy_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR1_DATA_RDY__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ case SMI130_INTR2_MAP_DATA_RDY:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR2_DATA_RDY__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MAP_1_INTR2_DATA_RDY,
+ v_intr_data_rdy_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(p_smi130->
+ dev_addr, SMI130_USER_INTR_MAP_1_INTR2_DATA_RDY__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+}
+return com_rslt;
+}
+ /*!
+* @brief This API reads data source for the interrupt
+* engine for the single and double tap interrupts from the register
+* 0x58 bit 3
+*
+*
+* @param v_tap_source_u8 : The value of the tap source
+* value | Description
+* ----------|-------------------
+* 0x01 | UNFILTER_DATA
+* 0x00 | FILTER_DATA
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_tap_source(u8*v_tap_source_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the tap source interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_DATA_0_INTR_TAP_SOURCE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_tap_source_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_DATA_0_INTR_TAP_SOURCE);
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API write data source for the interrupt
+* engine for the single and double tap interrupts from the register
+* 0x58 bit 3
+*
+*
+* @param v_tap_source_u8 : The value of the tap source
+* value | Description
+* ----------|-------------------
+* 0x01 | UNFILTER_DATA
+* 0x00 | FILTER_DATA
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_tap_source(
+u8 v_tap_source_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_tap_source_u8 <= SMI130_MAX_VALUE_SOURCE_INTR) {
+ /* write the tap source interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_DATA_0_INTR_TAP_SOURCE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_DATA_0_INTR_TAP_SOURCE,
+ v_tap_source_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_DATA_0_INTR_TAP_SOURCE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API Reads Data source for the
+* interrupt engine for the low and high g interrupts
+* from the register 0x58 bit 7
+*
+* @param v_low_high_source_u8 : The value of the tap source
+* value | Description
+* ----------|-------------------
+* 0x01 | UNFILTER_DATA
+* 0x00 | FILTER_DATA
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_low_high_source(
+u8*v_low_high_source_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the high_low_g source interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_low_high_source_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write Data source for the
+* interrupt engine for the low and high g interrupts
+* from the register 0x58 bit 7
+*
+* @param v_low_high_source_u8 : The value of the tap source
+* value | Description
+* ----------|-------------------
+* 0x01 | UNFILTER_DATA
+* 0x00 | FILTER_DATA
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_low_high_source(
+u8 v_low_high_source_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_low_high_source_u8 <= SMI130_MAX_VALUE_SOURCE_INTR) {
+ /* write the high_low_g source interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE,
+ v_low_high_source_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+}
+return com_rslt;
+}
+ /*!
+* @brief This API reads Data source for the
+* interrupt engine for the nomotion and anymotion interrupts
+* from the register 0x59 bit 7
+*
+* @param v_motion_source_u8 :
+* The value of the any/no motion interrupt source
+* value | Description
+* ----------|-------------------
+* 0x01 | UNFILTER_DATA
+* 0x00 | FILTER_DATA
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_motion_source(
+u8*v_motion_source_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the any/no motion interrupt */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_DATA_1_INTR_MOTION_SOURCE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_motion_source_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_DATA_1_INTR_MOTION_SOURCE);
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API write Data source for the
+* interrupt engine for the nomotion and anymotion interrupts
+* from the register 0x59 bit 7
+*
+* @param v_motion_source_u8 :
+* The value of the any/no motion interrupt source
+* value | Description
+* ----------|-------------------
+* 0x01 | UNFILTER_DATA
+* 0x00 | FILTER_DATA
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_motion_source(
+u8 v_motion_source_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_motion_source_u8 <= SMI130_MAX_VALUE_SOURCE_INTR) {
+ /* write the any/no motion interrupt */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_DATA_1_INTR_MOTION_SOURCE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_DATA_1_INTR_MOTION_SOURCE,
+ v_motion_source_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_DATA_1_INTR_MOTION_SOURCE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API is used to read the low_g duration from register
+* 0x5A bit 0 to 7
+*
+*
+*
+*
+* @param v_low_g_durn_u8 : The value of low_g duration
+*
+* @note Low_g duration trigger trigger delay according to
+* "(v_low_g_durn_u8* 2.5)ms" in a range from 2.5ms to 640ms.
+* the default corresponds delay is 20ms
+* @note When low_g data source of interrupt is unfiltered
+* the sensor must not be in low power mode
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_low_g_durn(
+u8*v_low_g_durn_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the low_g interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_0_INTR_LOW_DURN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_low_g_durn_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_LOWHIGH_0_INTR_LOW_DURN);
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API is used to write the low_g duration from register
+* 0x5A bit 0 to 7
+*
+*
+*
+*
+* @param v_low_g_durn_u8 : The value of low_g duration
+*
+* @note Low_g duration trigger trigger delay according to
+* "(v_low_g_durn_u8* 2.5)ms" in a range from 2.5ms to 640ms.
+* the default corresponds delay is 20ms
+* @note When low_g data source of interrupt is unfiltered
+* the sensor must not be in low power mode
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_low_g_durn(u8 v_low_g_durn_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write the low_g interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_0_INTR_LOW_DURN__REG,
+ &v_low_g_durn_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to read Threshold
+* definition for the low-g interrupt from the register 0x5B bit 0 to 7
+*
+*
+*
+*
+* @param v_low_g_thres_u8 : The value of low_g threshold
+*
+* @note Low_g interrupt trigger threshold according to
+* (v_low_g_thres_u8* 7.81)mg for v_low_g_thres_u8 > 0
+* 3.91 mg for v_low_g_thres_u8 = 0
+* The threshold range is form 3.91mg to 2.000mg
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_low_g_thres(
+u8*v_low_g_thres_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read low_g threshold*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_1_INTR_LOW_THRES__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_low_g_thres_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_LOWHIGH_1_INTR_LOW_THRES);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to write Threshold
+* definition for the low-g interrupt from the register 0x5B bit 0 to 7
+*
+*
+*
+*
+* @param v_low_g_thres_u8 : The value of low_g threshold
+*
+* @note Low_g interrupt trigger threshold according to
+* (v_low_g_thres_u8* 7.81)mg for v_low_g_thres_u8 > 0
+* 3.91 mg for v_low_g_thres_u8 = 0
+* The threshold range is form 3.91mg to 2.000mg
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_low_g_thres(
+u8 v_low_g_thres_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write low_g threshold*/
+ com_rslt = p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_1_INTR_LOW_THRES__REG,
+ &v_low_g_thres_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API Reads Low-g interrupt hysteresis
+* from the register 0x5C bit 0 to 1
+*
+* @param v_low_hyst_u8 :The value of low_g hysteresis
+*
+* @note Low_g hysteresis calculated by v_low_hyst_u8*125 mg
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_low_g_hyst(
+u8*v_low_hyst_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read low_g hysteresis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_low_hyst_u8 = SMI130_GET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST);
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API write Low-g interrupt hysteresis
+* from the register 0x5C bit 0 to 1
+*
+* @param v_low_hyst_u8 :The value of low_g hysteresis
+*
+* @note Low_g hysteresis calculated by v_low_hyst_u8*125 mg
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_low_g_hyst(
+u8 v_low_hyst_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write low_g hysteresis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST,
+ v_low_hyst_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads Low-g interrupt mode
+* from the register 0x5C bit 2
+*
+* @param v_low_g_mode_u8 : The value of low_g mode
+* Value | Description
+* ----------|-----------------
+* 0 | single-axis
+* 1 | axis-summing
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_low_g_mode(u8*v_low_g_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /*read Low-g interrupt mode*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_low_g_mode_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write Low-g interrupt mode
+* from the register 0x5C bit 2
+*
+* @param v_low_g_mode_u8 : The value of low_g mode
+* Value | Description
+* ----------|-----------------
+* 0 | single-axis
+* 1 | axis-summing
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_low_g_mode(
+u8 v_low_g_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_low_g_mode_u8 <= SMI130_MAX_VALUE_LOW_G_MODE) {
+ /*write Low-g interrupt mode*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE,
+ v_low_g_mode_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads High-g interrupt hysteresis
+* from the register 0x5C bit 6 and 7
+*
+* @param v_high_g_hyst_u8 : The value of high hysteresis
+*
+* @note High_g hysteresis changes according to accel g range
+* accel g range can be set by the function ""
+* accel_range | high_g hysteresis
+* ----------------|---------------------
+* 2g | high_hy*125 mg
+* 4g | high_hy*250 mg
+* 8g | high_hy*500 mg
+* 16g | high_hy*1000 mg
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_high_g_hyst(
+u8*v_high_g_hyst_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read high_g hysteresis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_high_g_hyst_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write High-g interrupt hysteresis
+* from the register 0x5C bit 6 and 7
+*
+* @param v_high_g_hyst_u8 : The value of high hysteresis
+*
+* @note High_g hysteresis changes according to accel g range
+* accel g range can be set by the function ""
+* accel_range | high_g hysteresis
+* ----------------|---------------------
+* 2g | high_hy*125 mg
+* 4g | high_hy*250 mg
+* 8g | high_hy*500 mg
+* 16g | high_hy*1000 mg
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_high_g_hyst(
+u8 v_high_g_hyst_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write high_g hysteresis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST,
+ v_high_g_hyst_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+return com_rslt;
+}
+/*!
+* @brief This API is used to read Delay
+* time definition for the high-g interrupt from the register
+* 0x5D bit 0 to 7
+*
+*
+*
+* @param v_high_g_durn_u8 : The value of high duration
+*
+* @note High_g interrupt delay triggered according to
+* v_high_g_durn_u8* 2.5ms in a range from 2.5ms to 640ms
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_high_g_durn(
+u8*v_high_g_durn_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read high_g duration*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_3_INTR_HIGH_G_DURN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_high_g_durn_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_LOWHIGH_3_INTR_HIGH_G_DURN);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to write Delay
+* time definition for the high-g interrupt from the register
+* 0x5D bit 0 to 7
+*
+*
+*
+* @param v_high_g_durn_u8 : The value of high duration
+*
+* @note High_g interrupt delay triggered according to
+* v_high_g_durn_u8* 2.5ms in a range from 2.5ms to 640ms
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_high_g_durn(
+u8 v_high_g_durn_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write high_g duration*/
+ com_rslt = p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_3_INTR_HIGH_G_DURN__REG,
+ &v_high_g_durn_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to read Threshold
+* definition for the high-g interrupt from the register 0x5E 0 to 7
+*
+*
+*
+*
+* @param v_high_g_thres_u8 : Pointer holding the value of Threshold
+* @note High_g threshold changes according to accel g range
+* accel g range can be set by the function ""
+* accel_range | high_g threshold
+* ----------------|---------------------
+* 2g | v_high_g_thres_u8*7.81 mg
+* 4g | v_high_g_thres_u8*15.63 mg
+* 8g | v_high_g_thres_u8*31.25 mg
+* 16g | v_high_g_thres_u8*62.5 mg
+* @note when v_high_g_thres_u8 = 0
+* accel_range | high_g threshold
+* ----------------|---------------------
+* 2g | 3.91 mg
+* 4g | 7.81 mg
+* 8g | 15.63 mg
+* 16g | 31.25 mg
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_high_g_thres(
+u8*v_high_g_thres_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_4_INTR_HIGH_THRES__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_high_g_thres_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_LOWHIGH_4_INTR_HIGH_THRES);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to write Threshold
+* definition for the high-g interrupt from the register 0x5E 0 to 7
+*
+*
+*
+*
+* @param v_high_g_thres_u8 : Pointer holding the value of Threshold
+* @note High_g threshold changes according to accel g range
+* accel g range can be set by the function ""
+* accel_range | high_g threshold
+* ----------------|---------------------
+* 2g | v_high_g_thres_u8*7.81 mg
+* 4g | v_high_g_thres_u8*15.63 mg
+* 8g | v_high_g_thres_u8*31.25 mg
+* 16g | v_high_g_thres_u8*62.5 mg
+* @note when v_high_g_thres_u8 = 0
+* accel_range | high_g threshold
+* ----------------|---------------------
+* 2g | 3.91 mg
+* 4g | 7.81 mg
+* 8g | 15.63 mg
+* 16g | 31.25 mg
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_high_g_thres(
+u8 v_high_g_thres_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ com_rslt = p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_LOWHIGH_4_INTR_HIGH_THRES__REG,
+ &v_high_g_thres_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads any motion duration
+* from the register 0x5F bit 0 and 1
+*
+* @param v_any_motion_durn_u8 : The value of any motion duration
+*
+* @note Any motion duration can be calculated by "v_any_motion_durn_u8 + 1"
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_any_motion_durn(
+u8*v_any_motion_durn_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read any motion duration*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_any_motion_durn_u8 = SMI130_GET_BITSLICE
+ (v_data_u8,
+ SMI130_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write any motion duration
+* from the register 0x5F bit 0 and 1
+*
+* @param v_any_motion_durn_u8 : The value of any motion duration
+*
+* @note Any motion duration can be calculated by "v_any_motion_durn_u8 + 1"
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_any_motion_durn(
+u8 v_any_motion_durn_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write any motion duration*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN,
+ v_any_motion_durn_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API read Slow/no-motion
+* interrupt trigger delay duration from the register 0x5F bit 2 to 7
+*
+* @param v_slow_no_motion_u8 :The value of slow no motion duration
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+* @note
+* @note v_slow_no_motion_u8(5:4)=0b00 ->
+* [v_slow_no_motion_u8(3:0) + 1]* 1.28s (1.28s-20.48s)
+* @note v_slow_no_motion_u8(5:4)=1 ->
+* [v_slow_no_motion_u8(3:0)+5]* 5.12s (25.6s-102.4s)
+* @note v_slow_no_motion_u8(5)='1' ->
+* [(v_slow_no_motion_u8:0)+11]* 10.24s (112.64s-430.08s);
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_slow_no_motion_durn(
+u8*v_slow_no_motion_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read slow no motion duration*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_slow_no_motion_u8 = SMI130_GET_BITSLICE
+ (v_data_u8,
+ SMI130_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN);
+ }
+return com_rslt;
+}
+ /*!
+* @brief This API write Slow/no-motion
+* interrupt trigger delay duration from the register 0x5F bit 2 to 7
+*
+* @param v_slow_no_motion_u8 :The value of slow no motion duration
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+* @note
+* @note v_slow_no_motion_u8(5:4)=0b00 ->
+* [v_slow_no_motion_u8(3:0) + 1]* 1.28s (1.28s-20.48s)
+* @note v_slow_no_motion_u8(5:4)=1 ->
+* [v_slow_no_motion_u8(3:0)+5]* 5.12s (25.6s-102.4s)
+* @note v_slow_no_motion_u8(5)='1' ->
+* [(v_slow_no_motion_u8:0)+11]* 10.24s (112.64s-430.08s);
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_slow_no_motion_durn(
+u8 v_slow_no_motion_u8)
+{
+/* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write slow no motion duration*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE
+ (v_data_u8,
+ SMI130_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN,
+ v_slow_no_motion_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+}
+return com_rslt;
+}
+/*!
+* @brief This API is used to read threshold
+* definition for the any-motion interrupt
+* from the register 0x60 bit 0 to 7
+*
+*
+* @param v_any_motion_thres_u8 : The value of any motion threshold
+*
+* @note any motion threshold changes according to accel g range
+* accel g range can be set by the function ""
+* accel_range | any motion threshold
+* ----------------|---------------------
+* 2g | v_any_motion_thres_u8*3.91 mg
+* 4g | v_any_motion_thres_u8*7.81 mg
+* 8g | v_any_motion_thres_u8*15.63 mg
+* 16g | v_any_motion_thres_u8*31.25 mg
+* @note when v_any_motion_thres_u8 = 0
+* accel_range | any motion threshold
+* ----------------|---------------------
+* 2g | 1.95 mg
+* 4g | 3.91 mg
+* 8g | 7.81 mg
+* 16g | 15.63 mg
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_any_motion_thres(
+u8*v_any_motion_thres_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read any motion threshold*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_MOTION_1_INTR_ANY_MOTION_THRES__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_any_motion_thres_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MOTION_1_INTR_ANY_MOTION_THRES);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to write threshold
+* definition for the any-motion interrupt
+* from the register 0x60 bit 0 to 7
+*
+*
+* @param v_any_motion_thres_u8 : The value of any motion threshold
+*
+* @note any motion threshold changes according to accel g range
+* accel g range can be set by the function ""
+* accel_range | any motion threshold
+* ----------------|---------------------
+* 2g | v_any_motion_thres_u8*3.91 mg
+* 4g | v_any_motion_thres_u8*7.81 mg
+* 8g | v_any_motion_thres_u8*15.63 mg
+* 16g | v_any_motion_thres_u8*31.25 mg
+* @note when v_any_motion_thres_u8 = 0
+* accel_range | any motion threshold
+* ----------------|---------------------
+* 2g | 1.95 mg
+* 4g | 3.91 mg
+* 8g | 7.81 mg
+* 16g | 15.63 mg
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_any_motion_thres(
+u8 v_any_motion_thres_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write any motion threshold*/
+ com_rslt = p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_MOTION_1_INTR_ANY_MOTION_THRES__REG,
+ &v_any_motion_thres_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API is used to read threshold
+* for the slow/no-motion interrupt
+* from the register 0x61 bit 0 to 7
+*
+*
+*
+*
+* @param v_slow_no_motion_thres_u8 : The value of slow no motion threshold
+* @note slow no motion threshold changes according to accel g range
+* accel g range can be set by the function ""
+* accel_range | slow no motion threshold
+* ----------------|---------------------
+* 2g | v_slow_no_motion_thres_u8*3.91 mg
+* 4g | v_slow_no_motion_thres_u8*7.81 mg
+* 8g | v_slow_no_motion_thres_u8*15.63 mg
+* 16g | v_slow_no_motion_thres_u8*31.25 mg
+* @note when v_slow_no_motion_thres_u8 = 0
+* accel_range | slow no motion threshold
+* ----------------|---------------------
+* 2g | 1.95 mg
+* 4g | 3.91 mg
+* 8g | 7.81 mg
+* 16g | 15.63 mg
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_slow_no_motion_thres(
+u8*v_slow_no_motion_thres_u8)
+{
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read slow no motion threshold*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_MOTION_2_INTR_SLOW_NO_MOTION_THRES__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_slow_no_motion_thres_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MOTION_2_INTR_SLOW_NO_MOTION_THRES);
+ }
+return com_rslt;
+}
+ /*!
+* @brief This API is used to write threshold
+* for the slow/no-motion interrupt
+* from the register 0x61 bit 0 to 7
+*
+*
+*
+*
+* @param v_slow_no_motion_thres_u8 : The value of slow no motion threshold
+* @note slow no motion threshold changes according to accel g range
+* accel g range can be set by the function ""
+* accel_range | slow no motion threshold
+* ----------------|---------------------
+* 2g | v_slow_no_motion_thres_u8*3.91 mg
+* 4g | v_slow_no_motion_thres_u8*7.81 mg
+* 8g | v_slow_no_motion_thres_u8*15.63 mg
+* 16g | v_slow_no_motion_thres_u8*31.25 mg
+* @note when v_slow_no_motion_thres_u8 = 0
+* accel_range | slow no motion threshold
+* ----------------|---------------------
+* 2g | 1.95 mg
+* 4g | 3.91 mg
+* 8g | 7.81 mg
+* 16g | 15.63 mg
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_slow_no_motion_thres(
+u8 v_slow_no_motion_thres_u8)
+{
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write slow no motion threshold*/
+ com_rslt = p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_MOTION_2_INTR_SLOW_NO_MOTION_THRES__REG,
+ &v_slow_no_motion_thres_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+return com_rslt;
+}
+ /*!
+* @brief This API is used to read
+* the slow/no-motion selection from the register 0x62 bit 0
+*
+*
+*
+*
+* @param v_intr_slow_no_motion_select_u8 :
+* The value of slow/no-motion select
+* value | Behaviour
+* ----------|-------------------
+* 0x00 | SLOW_MOTION
+* 0x01 | NO_MOTION
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_slow_no_motion_select(
+u8*v_intr_slow_no_motion_select_u8)
+{
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read slow no motion select*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_slow_no_motion_select_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT);
+ }
+return com_rslt;
+}
+ /*!
+* @brief This API is used to write
+* the slow/no-motion selection from the register 0x62 bit 0
+*
+*
+*
+*
+* @param v_intr_slow_no_motion_select_u8 :
+* The value of slow/no-motion select
+* value | Behaviour
+* ----------|-------------------
+* 0x00 | SLOW_MOTION
+* 0x01 | NO_MOTION
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_slow_no_motion_select(
+u8 v_intr_slow_no_motion_select_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+} else {
+if (v_intr_slow_no_motion_select_u8 <= SMI130_MAX_VALUE_NO_MOTION) {
+ /* write slow no motion select*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT,
+ v_intr_slow_no_motion_select_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+} else {
+com_rslt = E_SMI130_OUT_OF_RANGE;
+}
+}
+return com_rslt;
+}
+ /*!
+* @brief This API is used to select
+* the significant or any motion interrupt from the register 0x62 bit 1
+*
+*
+*
+*
+* @param v_intr_significant_motion_select_u8 :
+* the value of significant or any motion interrupt selection
+* value | Behaviour
+* ----------|-------------------
+* 0x00 | ANY_MOTION
+* 0x01 | SIGNIFICANT_MOTION
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_significant_motion_select(
+u8*v_intr_significant_motion_select_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the significant or any motion interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_SIGNIFICATION_MOTION_SELECT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_intr_significant_motion_select_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_SIGNIFICATION_MOTION_SELECT);
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API is used to write, select
+* the significant or any motion interrupt from the register 0x62 bit 1
+*
+*
+*
+*
+* @param v_intr_significant_motion_select_u8 :
+* the value of significant or any motion interrupt selection
+* value | Behaviour
+* ----------|-------------------
+* 0x00 | ANY_MOTION
+* 0x01 | SIGNIFICANT_MOTION
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_significant_motion_select(
+u8 v_intr_significant_motion_select_u8)
+{
+/* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_intr_significant_motion_select_u8 <=
+ SMI130_MAX_VALUE_SIGNIFICANT_MOTION) {
+ /* write the significant or any motion interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_SIGNIFICATION_MOTION_SELECT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_SIGNIFICATION_MOTION_SELECT,
+ v_intr_significant_motion_select_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_SIGNIFICATION_MOTION_SELECT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+}
+return com_rslt;
+}
+ /*!
+* @brief This API is used to read
+* the significant skip time from the register 0x62 bit 2 and 3
+*
+*
+*
+*
+* @param v_int_sig_mot_skip_u8 : the value of significant skip time
+* value | Behaviour
+* ----------|-------------------
+* 0x00 | skip time 1.5 seconds
+* 0x01 | skip time 3 seconds
+* 0x02 | skip time 6 seconds
+* 0x03 | skip time 12 seconds
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_significant_motion_skip(
+u8*v_int_sig_mot_skip_u8)
+{
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read significant skip time*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_SIGNIFICANT_MOTION_SKIP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_int_sig_mot_skip_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_SIGNIFICANT_MOTION_SKIP);
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API is used to write
+* the significant skip time from the register 0x62 bit 2 and 3
+*
+*
+*
+*
+* @param v_int_sig_mot_skip_u8 : the value of significant skip time
+* value | Behaviour
+* ----------|-------------------
+* 0x00 | skip time 1.5 seconds
+* 0x01 | skip time 3 seconds
+* 0x02 | skip time 6 seconds
+* 0x03 | skip time 12 seconds
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_significant_motion_skip(
+u8 v_int_sig_mot_skip_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_int_sig_mot_skip_u8 <= SMI130_MAX_UNDER_SIG_MOTION) {
+ /* write significant skip time*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_SIGNIFICANT_MOTION_SKIP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_SIGNIFICANT_MOTION_SKIP,
+ v_int_sig_mot_skip_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_SIGNIFICANT_MOTION_SKIP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API is used to read
+* the significant proof time from the register 0x62 bit 4 and 5
+*
+*
+*
+*
+* @param v_significant_motion_proof_u8 :
+* the value of significant proof time
+* value | Behaviour
+* ----------|-------------------
+* 0x00 | proof time 0.25 seconds
+* 0x01 | proof time 0.5 seconds
+* 0x02 | proof time 1 seconds
+* 0x03 | proof time 2 seconds
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_significant_motion_proof(
+u8*v_significant_motion_proof_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read significant proof time*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_SIGNIFICANT_MOTION_PROOF__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_significant_motion_proof_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_SIGNIFICANT_MOTION_PROOF);
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API is used to write
+* the significant proof time from the register 0x62 bit 4 and 5
+*
+*
+*
+*
+* @param v_significant_motion_proof_u8 :
+* the value of significant proof time
+* value | Behaviour
+* ----------|-------------------
+* 0x00 | proof time 0.25 seconds
+* 0x01 | proof time 0.5 seconds
+* 0x02 | proof time 1 seconds
+* 0x03 | proof time 2 seconds
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_significant_motion_proof(
+u8 v_significant_motion_proof_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_significant_motion_proof_u8
+ <= SMI130_MAX_UNDER_SIG_MOTION) {
+ /* write significant proof time*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_SIGNIFICANT_MOTION_PROOF__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_SIGNIFICANT_MOTION_PROOF,
+ v_significant_motion_proof_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_SIGNIFICANT_MOTION_PROOF__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to get the tap duration
+* from the register 0x63 bit 0 to 2
+*
+*
+*
+* @param v_tap_durn_u8 : The value of tap duration
+* value | Behaviour
+* ----------|-------------------
+* 0x00 | SMI130_TAP_DURN_50MS
+* 0x01 | SMI130_TAP_DURN_100MS
+* 0x03 | SMI130_TAP_DURN_150MS
+* 0x04 | SMI130_TAP_DURN_200MS
+* 0x05 | SMI130_TAP_DURN_250MS
+* 0x06 | SMI130_TAP_DURN_375MS
+* 0x07 | SMI130_TAP_DURN_700MS
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_tap_durn(
+u8*v_tap_durn_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read tap duration*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_DURN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_tap_durn_u8 = SMI130_GET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_DURN);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API is used to write the tap duration
+* from the register 0x63 bit 0 to 2
+*
+*
+*
+* @param v_tap_durn_u8 : The value of tap duration
+* value | Behaviour
+* ----------|-------------------
+* 0x00 | SMI130_TAP_DURN_50MS
+* 0x01 | SMI130_TAP_DURN_100MS
+* 0x03 | SMI130_TAP_DURN_150MS
+* 0x04 | SMI130_TAP_DURN_200MS
+* 0x05 | SMI130_TAP_DURN_250MS
+* 0x06 | SMI130_TAP_DURN_375MS
+* 0x07 | SMI130_TAP_DURN_700MS
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_tap_durn(
+u8 v_tap_durn_u8)
+{
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_tap_durn_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_tap_durn_u8 <= SMI130_MAX_TAP_TURN) {
+ switch (v_tap_durn_u8) {
+ case SMI130_TAP_DURN_50MS:
+ v_data_tap_durn_u8 = SMI130_TAP_DURN_50MS;
+ break;
+ case SMI130_TAP_DURN_100MS:
+ v_data_tap_durn_u8 = SMI130_TAP_DURN_100MS;
+ break;
+ case SMI130_TAP_DURN_150MS:
+ v_data_tap_durn_u8 = SMI130_TAP_DURN_150MS;
+ break;
+ case SMI130_TAP_DURN_200MS:
+ v_data_tap_durn_u8 = SMI130_TAP_DURN_200MS;
+ break;
+ case SMI130_TAP_DURN_250MS:
+ v_data_tap_durn_u8 = SMI130_TAP_DURN_250MS;
+ break;
+ case SMI130_TAP_DURN_375MS:
+ v_data_tap_durn_u8 = SMI130_TAP_DURN_375MS;
+ break;
+ case SMI130_TAP_DURN_500MS:
+ v_data_tap_durn_u8 = SMI130_TAP_DURN_500MS;
+ break;
+ case SMI130_TAP_DURN_700MS:
+ v_data_tap_durn_u8 = SMI130_TAP_DURN_700MS;
+ break;
+ default:
+ break;
+ }
+ /* write tap duration*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_DURN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_DURN,
+ v_data_tap_durn_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_DURN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API read the
+* tap shock duration from the register 0x63 bit 2
+*
+* @param v_tap_shock_u8 :The value of tap shock
+* value | Behaviour
+* ----------|-------------------
+* 0x00 | SMI130_TAP_SHOCK_50MS
+* 0x01 | SMI130_TAP_SHOCK_75MS
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_tap_shock(
+u8*v_tap_shock_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read tap shock duration*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_SHOCK__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_tap_shock_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_SHOCK);
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API write the
+* tap shock duration from the register 0x63 bit 2
+*
+* @param v_tap_shock_u8 :The value of tap shock
+* value | Behaviour
+* ----------|-------------------
+* 0x00 | SMI130_TAP_SHOCK_50MS
+* 0x01 | SMI130_TAP_SHOCK_75MS
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_tap_shock(u8 v_tap_shock_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_tap_shock_u8 <= SMI130_MAX_VALUE_TAP_SHOCK) {
+ /* write tap shock duration*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_SHOCK__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_SHOCK,
+ v_tap_shock_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_SHOCK__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API read
+* tap quiet duration from the register 0x63 bit 7
+*
+*
+* @param v_tap_quiet_u8 : The value of tap quiet
+* value | Behaviour
+* ----------|-------------------
+* 0x00 | SMI130_TAP_QUIET_30MS
+* 0x01 | SMI130_TAP_QUIET_20MS
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_tap_quiet(
+u8*v_tap_quiet_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read tap quiet duration*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_QUIET__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_tap_quiet_u8 = SMI130_GET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_QUIET);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write
+* tap quiet duration from the register 0x63 bit 7
+*
+*
+* @param v_tap_quiet_u8 : The value of tap quiet
+* value | Behaviour
+* ----------|-------------------
+* 0x00 | SMI130_TAP_QUIET_30MS
+* 0x01 | SMI130_TAP_QUIET_20MS
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_tap_quiet(u8 v_tap_quiet_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_tap_quiet_u8 <= SMI130_MAX_VALUE_TAP_QUIET) {
+ /* write tap quiet duration*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_QUIET__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_QUIET,
+ v_tap_quiet_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_TAP_0_INTR_TAP_QUIET__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API read Threshold of the
+* single/double tap interrupt from the register 0x64 bit 0 to 4
+*
+*
+* @param v_tap_thres_u8 : The value of single/double tap threshold
+*
+* @note single/double tap threshold changes according to accel g range
+* accel g range can be set by the function ""
+* accel_range | single/double tap threshold
+* ----------------|---------------------
+* 2g | ((v_tap_thres_u8 + 1)* 62.5)mg
+* 4g | ((v_tap_thres_u8 + 1)* 125)mg
+* 8g | ((v_tap_thres_u8 + 1)* 250)mg
+* 16g | ((v_tap_thres_u8 + 1)* 500)mg
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_tap_thres(
+u8*v_tap_thres_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read tap threshold*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_TAP_1_INTR_TAP_THRES__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_tap_thres_u8 = SMI130_GET_BITSLICE
+ (v_data_u8,
+ SMI130_USER_INTR_TAP_1_INTR_TAP_THRES);
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API write Threshold of the
+* single/double tap interrupt from the register 0x64 bit 0 to 4
+*
+*
+* @param v_tap_thres_u8 : The value of single/double tap threshold
+*
+* @note single/double tap threshold changes according to accel g range
+* accel g range can be set by the function ""
+* accel_range | single/double tap threshold
+* ----------------|---------------------
+* 2g | ((v_tap_thres_u8 + 1)* 62.5)mg
+* 4g | ((v_tap_thres_u8 + 1)* 125)mg
+* 8g | ((v_tap_thres_u8 + 1)* 250)mg
+* 16g | ((v_tap_thres_u8 + 1)* 500)mg
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_tap_thres(
+u8 v_tap_thres_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write tap threshold*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_TAP_1_INTR_TAP_THRES__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_TAP_1_INTR_TAP_THRES,
+ v_tap_thres_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_TAP_1_INTR_TAP_THRES__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API read the threshold for 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
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_orient_mode(
+u8*v_orient_mode_u8)
+{
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read orientation threshold*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_MODE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_orient_mode_u8 = SMI130_GET_BITSLICE
+ (v_data_u8,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_MODE);
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API write the threshold for 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
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_orient_mode(
+u8 v_orient_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_orient_mode_u8 <= SMI130_MAX_ORIENT_MODE) {
+ /* write orientation threshold*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_MODE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_MODE,
+ v_orient_mode_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_MODE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API read the orient 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
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_orient_blocking(
+u8*v_orient_blocking_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read orient blocking mode*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_orient_blocking_u8 = SMI130_GET_BITSLICE
+ (v_data_u8,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write the orient 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
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_orient_blocking(
+u8 v_orient_blocking_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_orient_blocking_u8 <= SMI130_MAX_ORIENT_BLOCKING) {
+ /* write orient blocking mode*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING,
+ v_orient_blocking_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+}
+return com_rslt;
+}
+/*!
+* @brief This API read Orient interrupt
+* hysteresis, from the register 0x64 bit 4 to 7
+*
+*
+*
+* @param v_orient_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
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_orient_hyst(
+u8*v_orient_hyst_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read orient hysteresis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_HYST__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_orient_hyst_u8 = SMI130_GET_BITSLICE
+ (v_data_u8,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_HYST);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write Orient interrupt
+* hysteresis, from the register 0x64 bit 4 to 7
+*
+*
+*
+* @param v_orient_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
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_orient_hyst(
+u8 v_orient_hyst_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write orient hysteresis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_HYST__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_HYST,
+ v_orient_hyst_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_HYST__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API read Orient
+* blocking angle (0 to 44.8) from the register 0x66 bit 0 to 5
+*
+* @param v_orient_theta_u8 : The value of Orient blocking angle
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_orient_theta(
+u8*v_orient_theta_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read Orient blocking angle*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_THETA__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_orient_theta_u8 = SMI130_GET_BITSLICE
+ (v_data_u8,
+ SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_THETA);
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API write Orient
+* blocking angle (0 to 44.8) from the register 0x66 bit 0 to 5
+*
+* @param v_orient_theta_u8 : The value of Orient blocking angle
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_orient_theta(
+u8 v_orient_theta_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_orient_theta_u8 <= SMI130_MAX_ORIENT_THETA) {
+ /* write Orient blocking angle*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_THETA__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_THETA,
+ v_orient_theta_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_THETA__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+}
+return com_rslt;
+}
+/*!
+* @brief This API read orient 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
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_orient_ud_enable(
+u8*v_orient_ud_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read orient up/down enable*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_orient_ud_u8 = SMI130_GET_BITSLICE
+ (v_data_u8,
+ SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write orient 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
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_orient_ud_enable(
+u8 v_orient_ud_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_orient_ud_u8 <= SMI130_MAX_VALUE_ORIENT_UD) {
+ /* write orient up/down enable*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE,
+ v_orient_ud_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+}
+return com_rslt;
+}
+ /*!
+* @brief This API read 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
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_orient_axes_enable(
+u8*v_orient_axes_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read orientation axes changes */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_orient_axes_u8 = SMI130_GET_BITSLICE
+ (v_data_u8,
+ SMI130_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
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_orient_axes_enable(
+u8 v_orient_axes_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_orient_axes_u8 <= SMI130_MAX_VALUE_ORIENT_AXES) {
+ /*write orientation axes changes */
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX,
+ v_orient_axes_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+}
+return com_rslt;
+}
+ /*!
+* @brief This API read Flat angle (0 to 44.8) for flat interrupt
+* from the register 0x67 bit 0 to 5
+*
+* @param v_flat_theta_u8 : The value of flat angle
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_flat_theta(
+u8*v_flat_theta_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read Flat angle*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_FLAT_0_INTR_FLAT_THETA__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_flat_theta_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_FLAT_0_INTR_FLAT_THETA);
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API write Flat angle (0 to 44.8) for flat interrupt
+* from the register 0x67 bit 0 to 5
+*
+* @param v_flat_theta_u8 : The value of flat angle
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_flat_theta(
+u8 v_flat_theta_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_flat_theta_u8 <= SMI130_MAX_FLAT_THETA) {
+ /* write Flat angle*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_FLAT_0_INTR_FLAT_THETA__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_FLAT_0_INTR_FLAT_THETA,
+ v_flat_theta_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_FLAT_0_INTR_FLAT_THETA__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API read Flat interrupt hold time;
+* from the register 0x68 bit 4 and 5
+*
+* @param v_flat_hold_u8 : The value of flat hold time
+* value | Behaviour
+* ----------|-------------------
+* 0x00 | 0ms
+* 0x01 | 512ms
+* 0x01 | 1024ms
+* 0x01 | 2048ms
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_flat_hold(
+u8*v_flat_hold_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read flat hold time*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_FLAT_1_INTR_FLAT_HOLD__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_flat_hold_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_FLAT_1_INTR_FLAT_HOLD);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write Flat interrupt hold time;
+* from the register 0x68 bit 4 and 5
+*
+* @param v_flat_hold_u8 : The value of flat hold time
+* value | Behaviour
+* ----------|-------------------
+* 0x00 | 0ms
+* 0x01 | 512ms
+* 0x01 | 1024ms
+* 0x01 | 2048ms
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_flat_hold(
+u8 v_flat_hold_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_flat_hold_u8 <= SMI130_MAX_FLAT_HOLD) {
+ /* write flat hold time*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_FLAT_1_INTR_FLAT_HOLD__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_FLAT_1_INTR_FLAT_HOLD,
+ v_flat_hold_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_FLAT_1_INTR_FLAT_HOLD__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API read flat interrupt hysteresis
+* from the register 0x68 bit 0 to 3
+*
+* @param v_flat_hyst_u8 : The value of flat hysteresis
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_flat_hyst(
+u8*v_flat_hyst_u8)
+{
+ /* variable used to return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the flat hysteresis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_INTR_FLAT_1_INTR_FLAT_HYST__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_flat_hyst_u8 = SMI130_GET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_INTR_FLAT_1_INTR_FLAT_HYST);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write flat interrupt hysteresis
+* from the register 0x68 bit 0 to 3
+*
+* @param v_flat_hyst_u8 : The value of flat hysteresis
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_flat_hyst(
+u8 v_flat_hyst_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_flat_hyst_u8 <= SMI130_MAX_FLAT_HYST) {
+ /* read the flat hysteresis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_FLAT_1_INTR_FLAT_HYST__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_INTR_FLAT_1_INTR_FLAT_HYST,
+ v_flat_hyst_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_INTR_FLAT_1_INTR_FLAT_HYST__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API read accel offset compensation
+* target value for z-axis from the register 0x69 bit 0 and 1
+*
+* @param v_foc_accel_z_u8 : the value of accel offset compensation z axis
+* value | Behaviour
+* ----------|-------------------
+* 0x00 | disable
+* 0x01 | +1g
+* 0x01 | -1g
+* 0x01 | 0g
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_foc_accel_z(u8*v_foc_accel_z_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the accel offset compensation for z axis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_Z__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_foc_accel_z_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FOC_ACCEL_Z);
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API write accel offset compensation
+* target value for z-axis from the register 0x69 bit 0 and 1
+*
+* @param v_foc_accel_z_u8 : the value of accel offset compensation z axis
+* value | Behaviour
+* ----------|-------------------
+* 0x00 | disable
+* 0x01 | +1g
+* 0x01 | -1g
+* 0x01 | 0g
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_foc_accel_z(
+u8 v_foc_accel_z_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write the accel offset compensation for z axis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_Z__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FOC_ACCEL_Z,
+ v_foc_accel_z_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_Z__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API read accel offset compensation
+* target value for y-axis
+* from the register 0x69 bit 2 and 3
+*
+* @param v_foc_accel_y_u8 : the value of accel offset compensation y axis
+* value | Behaviour
+* ----------|-------------------
+* 0x00 | disable
+* 0x01 | +1g
+* 0x01 | -1g
+* 0x01 | 0g
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_foc_accel_y(u8*v_foc_accel_y_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the accel offset compensation for y axis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_Y__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_foc_accel_y_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FOC_ACCEL_Y);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write accel offset compensation
+* target value for y-axis
+* from the register 0x69 bit 2 and 3
+*
+* @param v_foc_accel_y_u8 : the value of accel offset compensation y axis
+* value | Behaviour
+* ----------|-------------------
+* 0x00 | disable
+* 0x01 | +1g
+* 0x02 | -1g
+* 0x03 | 0g
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_foc_accel_y(u8 v_foc_accel_y_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_foc_accel_y_u8 <= SMI130_MAX_ACCEL_FOC) {
+ /* write the accel offset compensation for y axis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_Y__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FOC_ACCEL_Y,
+ v_foc_accel_y_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_Y__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API read accel offset compensation
+* target value for x-axis is
+* from the register 0x69 bit 4 and 5
+*
+* @param v_foc_accel_x_u8 : the value of accel offset compensation x axis
+* value | Behaviour
+* ----------|-------------------
+* 0x00 | disable
+* 0x01 | +1g
+* 0x02 | -1g
+* 0x03 | 0g
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_foc_accel_x(u8*v_foc_accel_x_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the accel offset compensation for x axis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_X__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_foc_accel_x_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FOC_ACCEL_X);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write accel offset compensation
+* target value for x-axis is
+* from the register 0x69 bit 4 and 5
+*
+* @param v_foc_accel_x_u8 : the value of accel offset compensation x axis
+* value | Behaviour
+* ----------|-------------------
+* 0x00 | disable
+* 0x01 | +1g
+* 0x01 | -1g
+* 0x01 | 0g
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_foc_accel_x(u8 v_foc_accel_x_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_foc_accel_x_u8 <= SMI130_MAX_ACCEL_FOC) {
+ /* write the accel offset compensation for x axis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_X__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FOC_ACCEL_X,
+ v_foc_accel_x_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_X__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API writes accel fast offset compensation
+* from the register 0x69 bit 0 to 5
+* @brief This API writes each axis individually
+* FOC_X_AXIS - bit 4 and 5
+* FOC_Y_AXIS - bit 2 and 3
+* FOC_Z_AXIS - bit 0 and 1
+*
+* @param v_foc_accel_u8: The value of accel offset compensation
+* value | Behaviour
+* ----------|-------------------
+* 0x00 | disable
+* 0x01 | +1g
+* 0x01 | -1g
+* 0x01 | 0g
+*
+* @param v_axis_u8: The value of accel offset axis selection
+ * value | axis
+* ----------|-------------------
+* 0 | FOC_X_AXIS
+* 1 | FOC_Y_AXIS
+* 2 | FOC_Z_AXIS
+*
+* @param v_accel_offset_s8: The accel offset value
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_foc_trigger(u8 v_axis_u8,
+u8 v_foc_accel_u8, s8*v_accel_offset_s8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+s8 v_status_s8 = SUCCESS;
+u8 v_timeout_u8 = SMI130_INIT_VALUE;
+s8 v_foc_accel_offset_x_s8 = SMI130_INIT_VALUE;
+s8 v_foc_accel_offset_y_s8 = SMI130_INIT_VALUE;
+s8 v_foc_accel_offset_z_s8 = SMI130_INIT_VALUE;
+u8 focstatus = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+} else {
+ v_status_s8 = smi130_set_accel_offset_enable(
+ ACCEL_OFFSET_ENABLE);
+ if (v_status_s8 == SUCCESS) {
+ switch (v_axis_u8) {
+ case FOC_X_AXIS:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_X__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FOC_ACCEL_X,
+ v_foc_accel_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_X__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ /* trigger the
+ FOC need to write
+ 0x03 in the register 0x7e*/
+ com_rslt +=
+ smi130_set_command_register(
+ START_FOC_ACCEL_GYRO);
+
+ com_rslt +=
+ smi130_get_foc_rdy(&focstatus);
+ if ((com_rslt != SUCCESS) ||
+ (focstatus != SMI130_FOC_STAT_HIGH)) {
+ while ((com_rslt != SUCCESS) ||
+ (focstatus != SMI130_FOC_STAT_HIGH
+ && v_timeout_u8 <
+ SMI130_MAXIMUM_TIMEOUT)) {
+ p_smi130->delay_msec(
+ SMI130_DELAY_SETTLING_TIME);
+ com_rslt = smi130_get_foc_rdy(
+ &focstatus);
+ v_timeout_u8++;
+ }
+ }
+ if ((com_rslt == SUCCESS) &&
+ (focstatus == SMI130_FOC_STAT_HIGH)) {
+ com_rslt +=
+ smi130_get_accel_offset_compensation_xaxis(
+ &v_foc_accel_offset_x_s8);
+ *v_accel_offset_s8 =
+ v_foc_accel_offset_x_s8;
+ }
+ break;
+ case FOC_Y_AXIS:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_Y__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FOC_ACCEL_Y,
+ v_foc_accel_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_Y__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ /* trigger the FOC
+ need to write 0x03
+ in the register 0x7e*/
+ com_rslt +=
+ smi130_set_command_register(
+ START_FOC_ACCEL_GYRO);
+
+ com_rslt +=
+ smi130_get_foc_rdy(&focstatus);
+ if ((com_rslt != SUCCESS) ||
+ (focstatus != SMI130_FOC_STAT_HIGH)) {
+ while ((com_rslt != SUCCESS) ||
+ (focstatus != SMI130_FOC_STAT_HIGH
+ && v_timeout_u8 <
+ SMI130_MAXIMUM_TIMEOUT)) {
+ p_smi130->delay_msec(
+ SMI130_DELAY_SETTLING_TIME);
+ com_rslt = smi130_get_foc_rdy(
+ &focstatus);
+ v_timeout_u8++;
+ }
+ }
+ if ((com_rslt == SUCCESS) &&
+ (focstatus == SMI130_FOC_STAT_HIGH)) {
+ com_rslt +=
+ smi130_get_accel_offset_compensation_yaxis(
+ &v_foc_accel_offset_y_s8);
+ *v_accel_offset_s8 =
+ v_foc_accel_offset_y_s8;
+ }
+ break;
+ case FOC_Z_AXIS:
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_Z__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FOC_ACCEL_Z,
+ v_foc_accel_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_Z__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ /* trigger the FOC need to write
+ 0x03 in the register 0x7e*/
+ com_rslt +=
+ smi130_set_command_register(
+ START_FOC_ACCEL_GYRO);
+
+ com_rslt +=
+ smi130_get_foc_rdy(&focstatus);
+ if ((com_rslt != SUCCESS) ||
+ (focstatus != SMI130_FOC_STAT_HIGH)) {
+ while ((com_rslt != SUCCESS) ||
+ (focstatus != SMI130_FOC_STAT_HIGH
+ && v_timeout_u8 <
+ SMI130_MAXIMUM_TIMEOUT)) {
+ p_smi130->delay_msec(
+ SMI130_DELAY_SETTLING_TIME);
+ com_rslt = smi130_get_foc_rdy(
+ &focstatus);
+ v_timeout_u8++;
+ }
+ }
+ if ((com_rslt == SUCCESS) &&
+ (focstatus == SMI130_FOC_STAT_HIGH)) {
+ com_rslt +=
+ smi130_get_accel_offset_compensation_zaxis(
+ &v_foc_accel_offset_z_s8);
+ *v_accel_offset_s8 =
+ v_foc_accel_offset_z_s8;
+ }
+ break;
+ default:
+ break;
+ }
+ } else {
+ com_rslt = ERROR;
+ }
+}
+return com_rslt;
+}
+/*!
+* @brief This API write fast accel offset compensation
+* it writes all axis together.To the register 0x69 bit 0 to 5
+* FOC_X_AXIS - bit 4 and 5
+* FOC_Y_AXIS - bit 2 and 3
+* FOC_Z_AXIS - bit 0 and 1
+*
+* @param v_foc_accel_x_u8: The value of accel offset x compensation
+* value | Behaviour
+* ----------|-------------------
+* 0x00 | disable
+* 0x01 | +1g
+* 0x01 | -1g
+* 0x01 | 0g
+*
+* @param v_foc_accel_y_u8: The value of accel offset y compensation
+* value | Behaviour
+* ----------|-------------------
+* 0x00 | disable
+* 0x01 | +1g
+* 0x01 | -1g
+* 0x01 | 0g
+*
+* @param v_foc_accel_z_u8: The value of accel offset z compensation
+* value | Behaviour
+* ----------|-------------------
+* 0x00 | disable
+* 0x01 | +1g
+* 0x01 | -1g
+* 0x01 | 0g
+*
+* @param v_accel_off_x_s8: The value of accel offset x axis
+* @param v_accel_off_y_s8: The value of accel offset y axis
+* @param v_accel_off_z_s8: The value of accel offset z axis
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_accel_foc_trigger_xyz(u8 v_foc_accel_x_u8,
+u8 v_foc_accel_y_u8, u8 v_foc_accel_z_u8, s8*v_accel_off_x_s8,
+s8*v_accel_off_y_s8, s8*v_accel_off_z_s8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 focx = SMI130_INIT_VALUE;
+u8 focy = SMI130_INIT_VALUE;
+u8 focz = SMI130_INIT_VALUE;
+s8 v_foc_accel_offset_x_s8 = SMI130_INIT_VALUE;
+s8 v_foc_accel_offset_y_s8 = SMI130_INIT_VALUE;
+s8 v_foc_accel_offset_z_s8 = SMI130_INIT_VALUE;
+u8 v_status_s8 = SUCCESS;
+u8 v_timeout_u8 = SMI130_INIT_VALUE;
+u8 focstatus = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ v_status_s8 = smi130_set_accel_offset_enable(
+ ACCEL_OFFSET_ENABLE);
+ if (v_status_s8 == SUCCESS) {
+ /* foc x axis*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_X__REG,
+ &focx, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ focx = SMI130_SET_BITSLICE(focx,
+ SMI130_USER_FOC_ACCEL_X,
+ v_foc_accel_x_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_X__REG,
+ &focx, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ /* foc y axis*/
+ com_rslt +=
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_Y__REG,
+ &focy, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ focy = SMI130_SET_BITSLICE(focy,
+ SMI130_USER_FOC_ACCEL_Y,
+ v_foc_accel_y_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_Y__REG,
+ &focy, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ /* foc z axis*/
+ com_rslt +=
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_Z__REG,
+ &focz, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ focz = SMI130_SET_BITSLICE(focz,
+ SMI130_USER_FOC_ACCEL_Z,
+ v_foc_accel_z_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_ACCEL_Z__REG,
+ &focz, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ /* trigger the FOC need to
+ write 0x03 in the register 0x7e*/
+ com_rslt += smi130_set_command_register(
+ START_FOC_ACCEL_GYRO);
+
+ com_rslt += smi130_get_foc_rdy(
+ &focstatus);
+ if ((com_rslt != SUCCESS) ||
+ (focstatus != SMI130_FOC_STAT_HIGH)) {
+ while ((com_rslt != SUCCESS) ||
+ (focstatus != SMI130_FOC_STAT_HIGH
+ && v_timeout_u8 <
+ SMI130_MAXIMUM_TIMEOUT)) {
+ p_smi130->delay_msec(
+ SMI130_DELAY_SETTLING_TIME);
+ com_rslt = smi130_get_foc_rdy(
+ &focstatus);
+ v_timeout_u8++;
+ }
+ }
+ if ((com_rslt == SUCCESS) &&
+ (focstatus == SMI130_GEN_READ_WRITE_DATA_LENGTH)) {
+ com_rslt +=
+ smi130_get_accel_offset_compensation_xaxis(
+ &v_foc_accel_offset_x_s8);
+ *v_accel_off_x_s8 =
+ v_foc_accel_offset_x_s8;
+ com_rslt +=
+ smi130_get_accel_offset_compensation_yaxis(
+ &v_foc_accel_offset_y_s8);
+ *v_accel_off_y_s8 =
+ v_foc_accel_offset_y_s8;
+ com_rslt +=
+ smi130_get_accel_offset_compensation_zaxis(
+ &v_foc_accel_offset_z_s8);
+ *v_accel_off_z_s8 =
+ v_foc_accel_offset_z_s8;
+ }
+ } else {
+ com_rslt = ERROR;
+ }
+ }
+return com_rslt;
+}
+/*!
+* @brief This API read gyro fast offset enable
+* from the register 0x69 bit 6
+*
+* @param v_foc_gyro_u8 : The value of gyro fast offset enable
+* value | Description
+* ----------|-------------
+* 0 | fast offset compensation disabled
+* 1 | fast offset compensation enabled
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_foc_gyro_enable(
+u8*v_foc_gyro_u8)
+{
+ /* used for return the status of bus communication*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the gyro fast offset enable*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_FOC_GYRO_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_foc_gyro_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_FOC_GYRO_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write gyro fast offset enable
+* from the register 0x69 bit 6
+*
+* @param v_foc_gyro_u8 : The value of gyro fast offset enable
+* value | Description
+* ----------|-------------
+* 0 | fast offset compensation disabled
+* 1 | fast offset compensation enabled
+*
+* @param v_gyro_off_x_s16 : The value of gyro fast offset x axis data
+* @param v_gyro_off_y_s16 : The value of gyro fast offset y axis data
+* @param v_gyro_off_z_s16 : The value of gyro fast offset z axis data
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_foc_gyro_enable(
+u8 v_foc_gyro_u8, s16*v_gyro_off_x_s16,
+s16*v_gyro_off_y_s16, s16*v_gyro_off_z_s16)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+u8 v_status_s8 = SUCCESS;
+u8 v_timeout_u8 = SMI130_INIT_VALUE;
+s16 offsetx = SMI130_INIT_VALUE;
+s16 offsety = SMI130_INIT_VALUE;
+s16 offsetz = SMI130_INIT_VALUE;
+u8 focstatus = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ v_status_s8 = smi130_set_gyro_offset_enable(
+ GYRO_OFFSET_ENABLE);
+ if (v_status_s8 == SUCCESS) {
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_FOC_GYRO_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_FOC_GYRO_ENABLE,
+ v_foc_gyro_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_FOC_GYRO_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ /* trigger the FOC need to write 0x03
+ in the register 0x7e*/
+ com_rslt += smi130_set_command_register
+ (START_FOC_ACCEL_GYRO);
+
+ com_rslt += smi130_get_foc_rdy(&focstatus);
+ if ((com_rslt != SUCCESS) ||
+ (focstatus != SMI130_FOC_STAT_HIGH)) {
+ while ((com_rslt != SUCCESS) ||
+ (focstatus != SMI130_FOC_STAT_HIGH
+ && v_timeout_u8 <
+ SMI130_MAXIMUM_TIMEOUT)) {
+ p_smi130->delay_msec(
+ SMI130_DELAY_SETTLING_TIME);
+ com_rslt = smi130_get_foc_rdy(
+ &focstatus);
+ v_timeout_u8++;
+ }
+ }
+ if ((com_rslt == SUCCESS) &&
+ (focstatus == SMI130_FOC_STAT_HIGH)) {
+ com_rslt +=
+ smi130_get_gyro_offset_compensation_xaxis
+ (&offsetx);
+ *v_gyro_off_x_s16 = offsetx;
+
+ com_rslt +=
+ smi130_get_gyro_offset_compensation_yaxis
+ (&offsety);
+ *v_gyro_off_y_s16 = offsety;
+
+ com_rslt +=
+ smi130_get_gyro_offset_compensation_zaxis(
+ &offsetz);
+ *v_gyro_off_z_s16 = offsetz;
+ }
+ } else {
+ com_rslt = ERROR;
+ }
+ }
+return com_rslt;
+}
+ /*!
+* @brief This API read NVM program enable
+* from the register 0x6A bit 1
+*
+* @param v_nvm_prog_u8 : The value of NVM program enable
+* Value | Description
+* --------|-------------
+* 0 | DISABLE
+* 1 | ENABLE
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_nvm_prog_enable(
+u8*v_nvm_prog_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read NVM program*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_CONFIG_NVM_PROG_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_nvm_prog_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_CONFIG_NVM_PROG_ENABLE);
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API write NVM program enable
+* from the register 0x6A bit 1
+*
+* @param v_nvm_prog_u8 : The value of NVM program enable
+* Value | Description
+* --------|-------------
+* 0 | DISABLE
+* 1 | ENABLE
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_nvm_prog_enable(
+u8 v_nvm_prog_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_nvm_prog_u8 <= SMI130_MAX_VALUE_NVM_PROG) {
+ /* write the NVM program*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_CONFIG_NVM_PROG_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_CONFIG_NVM_PROG_ENABLE,
+ v_nvm_prog_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_CONFIG_NVM_PROG_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API read to configure SPI
+* Interface Mode for primary and OIS interface
+* from the register 0x6B bit 0
+*
+* @param v_spi3_u8 : The value of SPI mode selection
+* Value | Description
+* --------|-------------
+* 0 | SPI 4-wire mode
+* 1 | SPI 3-wire mode
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_spi3(
+u8*v_spi3_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read SPI mode*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_IF_CONFIG_SPI3__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_spi3_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_IF_CONFIG_SPI3);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write to configure SPI
+* Interface Mode for primary and OIS interface
+* from the register 0x6B bit 0
+*
+* @param v_spi3_u8 : The value of SPI mode selection
+* Value | Description
+* --------|-------------
+* 0 | SPI 4-wire mode
+* 1 | SPI 3-wire mode
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_spi3(
+u8 v_spi3_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_spi3_u8 <= SMI130_MAX_VALUE_SPI3) {
+ /* write SPI mode*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_IF_CONFIG_SPI3__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_IF_CONFIG_SPI3,
+ v_spi3_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_IF_CONFIG_SPI3__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API read I2C Watchdog timer
+* from the register 0x70 bit 1
+*
+* @param v_i2c_wdt_u8 : The value of I2C watch dog timer
+* Value | Description
+* --------|-------------
+* 0 | I2C watchdog v_timeout_u8 after 1 ms
+* 1 | I2C watchdog v_timeout_u8 after 50 ms
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_i2c_wdt_select(
+u8*v_i2c_wdt_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read I2C watch dog timer*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_IF_CONFIG_I2C_WDT_SELECT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_i2c_wdt_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_IF_CONFIG_I2C_WDT_SELECT);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write I2C Watchdog timer
+* from the register 0x70 bit 1
+*
+* @param v_i2c_wdt_u8 : The value of I2C watch dog timer
+* Value | Description
+* --------|-------------
+* 0 | I2C watchdog v_timeout_u8 after 1 ms
+* 1 | I2C watchdog v_timeout_u8 after 50 ms
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_i2c_wdt_select(
+u8 v_i2c_wdt_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_i2c_wdt_u8 <= SMI130_MAX_VALUE_I2C_WDT) {
+ /* write I2C watch dog timer*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_IF_CONFIG_I2C_WDT_SELECT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_IF_CONFIG_I2C_WDT_SELECT,
+ v_i2c_wdt_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_IF_CONFIG_I2C_WDT_SELECT__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API read I2C watchdog enable
+* from the register 0x70 bit 2
+*
+* @param v_i2c_wdt_u8 : The value of I2C watchdog enable
+* Value | Description
+* --------|-------------
+* 0 | DISABLE
+* 1 | ENABLE
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_i2c_wdt_enable(
+u8*v_i2c_wdt_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read i2c watch dog eneble*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_IF_CONFIG_I2C_WDT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_i2c_wdt_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_IF_CONFIG_I2C_WDT_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write I2C watchdog enable
+* from the register 0x70 bit 2
+*
+* @param v_i2c_wdt_u8 : The value of I2C watchdog enable
+* Value | Description
+* --------|-------------
+* 0 | DISABLE
+* 1 | ENABLE
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_i2c_wdt_enable(
+u8 v_i2c_wdt_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_i2c_wdt_u8 <= SMI130_MAX_VALUE_I2C_WDT) {
+ /* write i2c watch dog eneble*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_IF_CONFIG_I2C_WDT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_IF_CONFIG_I2C_WDT_ENABLE,
+ v_i2c_wdt_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_IF_CONFIG_I2C_WDT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API read I2C interface configuration(if) moe
+* from the register 0x6B bit 4 and 5
+*
+* @param v_if_mode_u8 : The value of interface configuration mode
+* Value | Description
+* --------|-------------
+* 0x00 | Primary interface:autoconfig / secondary interface:off
+* 0x01 | Primary interface:I2C / secondary interface:OIS
+* 0x02 | Primary interface:autoconfig/secondary interface:Magnetometer
+* 0x03 | Reserved
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_if_mode(
+u8*v_if_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read if mode*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_IF_CONFIG_IF_MODE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_if_mode_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_IF_CONFIG_IF_MODE);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write I2C interface configuration(if) moe
+* from the register 0x6B bit 4 and 5
+*
+* @param v_if_mode_u8 : The value of interface configuration mode
+* Value | Description
+* --------|-------------
+* 0x00 | Primary interface:autoconfig / secondary interface:off
+* 0x01 | Primary interface:I2C / secondary interface:OIS
+* 0x02 | Primary interface:autoconfig/secondary interface:Magnetometer
+* 0x03 | Reserved
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_if_mode(
+u8 v_if_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_if_mode_u8 <= SMI130_MAX_IF_MODE) {
+ /* write if mode*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_IF_CONFIG_IF_MODE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_IF_CONFIG_IF_MODE,
+ v_if_mode_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_IF_CONFIG_IF_MODE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API read gyro sleep trigger
+* from the register 0x6C bit 0 to 2
+*
+* @param v_gyro_sleep_trigger_u8 : The value of gyro sleep trigger
+* Value | Description
+* --------|-------------
+* 0x00 | nomotion: no / Not INT1 pin: no / INT2 pin: no
+* 0x01 | nomotion: no / Not INT1 pin: no / INT2 pin: yes
+* 0x02 | nomotion: no / Not INT1 pin: yes / INT2 pin: no
+* 0x03 | nomotion: no / Not INT1 pin: yes / INT2 pin: yes
+* 0x04 | nomotion: yes / Not INT1 pin: no / INT2 pin: no
+* 0x05 | anymotion: yes / Not INT1 pin: no / INT2 pin: yes
+* 0x06 | anymotion: yes / Not INT1 pin: yes / INT2 pin: no
+* 0x07 | anymotion: yes / Not INT1 pin: yes / INT2 pin: yes
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_sleep_trigger(
+u8*v_gyro_sleep_trigger_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read gyro sleep trigger*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_SLEEP_TRIGGER__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_gyro_sleep_trigger_u8 =
+ SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_GYRO_SLEEP_TRIGGER);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write gyro sleep trigger
+* from the register 0x6C bit 0 to 2
+*
+* @param v_gyro_sleep_trigger_u8 : The value of gyro sleep trigger
+* Value | Description
+* --------|-------------
+* 0x00 | nomotion: no / Not INT1 pin: no / INT2 pin: no
+* 0x01 | nomotion: no / Not INT1 pin: no / INT2 pin: yes
+* 0x02 | nomotion: no / Not INT1 pin: yes / INT2 pin: no
+* 0x03 | nomotion: no / Not INT1 pin: yes / INT2 pin: yes
+* 0x04 | nomotion: yes / Not INT1 pin: no / INT2 pin: no
+* 0x05 | anymotion: yes / Not INT1 pin: no / INT2 pin: yes
+* 0x06 | anymotion: yes / Not INT1 pin: yes / INT2 pin: no
+* 0x07 | anymotion: yes / Not INT1 pin: yes / INT2 pin: yes
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_sleep_trigger(
+u8 v_gyro_sleep_trigger_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_gyro_sleep_trigger_u8 <= SMI130_MAX_GYRO_SLEEP_TIGGER) {
+ /* write gyro sleep trigger*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_SLEEP_TRIGGER__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_GYRO_SLEEP_TRIGGER,
+ v_gyro_sleep_trigger_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_SLEEP_TRIGGER__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API read gyro wakeup trigger
+* from the register 0x6C bit 3 and 4
+*
+* @param v_gyro_wakeup_trigger_u8 : The value of gyro wakeup trigger
+* Value | Description
+* --------|-------------
+* 0x00 | anymotion: no / INT1 pin: no
+* 0x01 | anymotion: no / INT1 pin: yes
+* 0x02 | anymotion: yes / INT1 pin: no
+* 0x03 | anymotion: yes / INT1 pin: yes
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_wakeup_trigger(
+u8*v_gyro_wakeup_trigger_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read gyro wakeup trigger*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_WAKEUP_TRIGGER__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_gyro_wakeup_trigger_u8 = SMI130_GET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_GYRO_WAKEUP_TRIGGER);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write gyro wakeup trigger
+* from the register 0x6C bit 3 and 4
+*
+* @param v_gyro_wakeup_trigger_u8 : The value of gyro wakeup trigger
+* Value | Description
+* --------|-------------
+* 0x00 | anymotion: no / INT1 pin: no
+* 0x01 | anymotion: no / INT1 pin: yes
+* 0x02 | anymotion: yes / INT1 pin: no
+* 0x03 | anymotion: yes / INT1 pin: yes
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_wakeup_trigger(
+u8 v_gyro_wakeup_trigger_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_gyro_wakeup_trigger_u8
+ <= SMI130_MAX_GYRO_WAKEUP_TRIGGER) {
+ /* write gyro wakeup trigger*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_WAKEUP_TRIGGER__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_GYRO_WAKEUP_TRIGGER,
+ v_gyro_wakeup_trigger_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_WAKEUP_TRIGGER__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API read Target state for gyro sleep mode
+* from the register 0x6C bit 5
+*
+* @param v_gyro_sleep_state_u8 : The value of gyro sleep mode
+* Value | Description
+* --------|-------------
+* 0x00 | Sleep transition to fast wake up state
+* 0x01 | Sleep transition to suspend state
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_sleep_state(
+u8*v_gyro_sleep_state_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read gyro sleep state*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_SLEEP_STATE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_gyro_sleep_state_u8 = SMI130_GET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_GYRO_SLEEP_STATE);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write Target state for gyro sleep mode
+* from the register 0x6C bit 5
+*
+* @param v_gyro_sleep_state_u8 : The value of gyro sleep mode
+* Value | Description
+* --------|-------------
+* 0x00 | Sleep transition to fast wake up state
+* 0x01 | Sleep transition to suspend state
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_sleep_state(
+u8 v_gyro_sleep_state_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_gyro_sleep_state_u8 <= SMI130_MAX_VALUE_SLEEP_STATE) {
+ /* write gyro sleep state*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_SLEEP_STATE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_GYRO_SLEEP_STATE,
+ v_gyro_sleep_state_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_SLEEP_STATE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API read gyro wakeup interrupt
+* from the register 0x6C bit 6
+*
+* @param v_gyro_wakeup_intr_u8 : The valeu of gyro wakeup interrupt
+* Value | Description
+* --------|-------------
+* 0x00 | DISABLE
+* 0x01 | ENABLE
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_wakeup_intr(
+u8*v_gyro_wakeup_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read gyro wakeup interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_WAKEUP_INTR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_gyro_wakeup_intr_u8 = SMI130_GET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_GYRO_WAKEUP_INTR);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write gyro wakeup interrupt
+* from the register 0x6C bit 6
+*
+* @param v_gyro_wakeup_intr_u8 : The valeu of gyro wakeup interrupt
+* Value | Description
+* --------|-------------
+* 0x00 | DISABLE
+* 0x01 | ENABLE
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_wakeup_intr(
+u8 v_gyro_wakeup_intr_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_gyro_wakeup_intr_u8 <= SMI130_MAX_VALUE_WAKEUP_INTR) {
+ /* write gyro wakeup interrupt*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_WAKEUP_INTR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_GYRO_WAKEUP_INTR,
+ v_gyro_wakeup_intr_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_WAKEUP_INTR__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API read accel select axis to be self-test
+*
+* @param v_accel_selftest_axis_u8 :
+* The value of accel self test axis selection
+* Value | Description
+* --------|-------------
+* 0x00 | disabled
+* 0x01 | x-axis
+* 0x02 | y-axis
+* 0x03 | z-axis
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_selftest_axis(
+u8*v_accel_selftest_axis_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read accel self test axis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_ACCEL_SELFTEST_AXIS__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_selftest_axis_u8 = SMI130_GET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_ACCEL_SELFTEST_AXIS);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write accel select axis to be self-test
+*
+* @param v_accel_selftest_axis_u8 :
+* The value of accel self test axis selection
+* Value | Description
+* --------|-------------
+* 0x00 | disabled
+* 0x01 | x-axis
+* 0x02 | y-axis
+* 0x03 | z-axis
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_selftest_axis(
+u8 v_accel_selftest_axis_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_accel_selftest_axis_u8
+ <= SMI130_MAX_ACCEL_SELFTEST_AXIS) {
+ /* write accel self test axis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_ACCEL_SELFTEST_AXIS__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_ACCEL_SELFTEST_AXIS,
+ v_accel_selftest_axis_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_ACCEL_SELFTEST_AXIS__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API read accel self test axis sign
+* from the register 0x6D bit 2
+*
+* @param v_accel_selftest_sign_u8: The value of accel self test axis sign
+* Value | Description
+* --------|-------------
+* 0x00 | negative
+* 0x01 | positive
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_selftest_sign(
+u8*v_accel_selftest_sign_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read accel self test axis sign*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_ACCEL_SELFTEST_SIGN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_selftest_sign_u8 = SMI130_GET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_ACCEL_SELFTEST_SIGN);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write accel self test axis sign
+* from the register 0x6D bit 2
+*
+* @param v_accel_selftest_sign_u8: The value of accel self test axis sign
+* Value | Description
+* --------|-------------
+* 0x00 | negative
+* 0x01 | positive
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_selftest_sign(
+u8 v_accel_selftest_sign_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_accel_selftest_sign_u8 <=
+ SMI130_MAX_VALUE_SELFTEST_SIGN) {
+ /* write accel self test axis sign*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_ACCEL_SELFTEST_SIGN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_ACCEL_SELFTEST_SIGN,
+ v_accel_selftest_sign_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_ACCEL_SELFTEST_SIGN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API read accel self test amplitude
+* from the register 0x6D bit 3
+* select amplitude of the selftest deflection:
+*
+* @param v_accel_selftest_amp_u8 : The value of accel self test amplitude
+* Value | Description
+* --------|-------------
+* 0x00 | LOW
+* 0x01 | HIGH
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_selftest_amp(
+u8*v_accel_selftest_amp_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read self test amplitude*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_SELFTEST_AMP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_selftest_amp_u8 = SMI130_GET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_SELFTEST_AMP);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write accel self test amplitude
+* from the register 0x6D bit 3
+* select amplitude of the selftest deflection:
+*
+* @param v_accel_selftest_amp_u8 : The value of accel self test amplitude
+* Value | Description
+* --------|-------------
+* 0x00 | LOW
+* 0x01 | HIGH
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_selftest_amp(
+u8 v_accel_selftest_amp_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_accel_selftest_amp_u8 <=
+ SMI130_MAX_VALUE_SELFTEST_AMP) {
+ /* write self test amplitude*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_SELFTEST_AMP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_SELFTEST_AMP,
+ v_accel_selftest_amp_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_SELFTEST_AMP__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API read gyro self test trigger
+*
+* @param v_gyro_selftest_start_u8: The value of gyro self test start
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_selftest_start(
+u8*v_gyro_selftest_start_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read gyro self test start*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_SELFTEST_START__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_gyro_selftest_start_u8 = SMI130_GET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_GYRO_SELFTEST_START);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write gyro self test trigger
+*
+* @param v_gyro_selftest_start_u8: The value of gyro self test start
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_selftest_start(
+u8 v_gyro_selftest_start_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_gyro_selftest_start_u8 <=
+ SMI130_MAX_VALUE_SELFTEST_START) {
+ /* write gyro self test start*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_SELFTEST_START__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_GYRO_SELFTEST_START,
+ v_gyro_selftest_start_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_GYRO_SELFTEST_START__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API read primary interface selection I2C or SPI
+* from the register 0x70 bit 0
+*
+* @param v_spi_enable_u8: The value of Interface selection
+* Value | Description
+* --------|-------------
+* 0x00 | I2C Enable
+* 0x01 | I2C DISBALE
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_spi_enable(u8*v_spi_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read interface section*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_NV_CONFIG_SPI_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_spi_enable_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_NV_CONFIG_SPI_ENABLE);
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API write primary interface selection I2C or SPI
+* from the register 0x70 bit 0
+*
+* @param v_spi_enable_u8: The value of Interface selection
+* Value | Description
+* --------|-------------
+* 0x00 | I2C Enable
+* 0x01 | I2C DISBALE
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_spi_enable(u8 v_spi_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write interface section*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_NV_CONFIG_SPI_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_NV_CONFIG_SPI_ENABLE,
+ v_spi_enable_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_NV_CONFIG_SPI_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API read the spare zero
+* form register 0x70 bit 3
+*
+*
+* @param v_spare0_trim_u8: The value of spare zero
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_spare0_trim(u8*v_spare0_trim_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read spare zero*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_NV_CONFIG_SPARE0__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_spare0_trim_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_NV_CONFIG_SPARE0);
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API write the spare zero
+* form register 0x70 bit 3
+*
+*
+* @param v_spare0_trim_u8: The value of spare zero
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_spare0_trim(u8 v_spare0_trim_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write spare zero*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_NV_CONFIG_SPARE0__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_NV_CONFIG_SPARE0,
+ v_spare0_trim_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_NV_CONFIG_SPARE0__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API read the NVM counter
+* form register 0x70 bit 4 to 7
+*
+*
+* @param v_nvm_counter_u8: The value of NVM counter
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_nvm_counter(u8*v_nvm_counter_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read NVM counter*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_NV_CONFIG_NVM_COUNTER__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_nvm_counter_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_NV_CONFIG_NVM_COUNTER);
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API write the NVM counter
+* form register 0x70 bit 4 to 7
+*
+*
+* @param v_nvm_counter_u8: The value of NVM counter
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_nvm_counter(
+u8 v_nvm_counter_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write NVM counter*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_NV_CONFIG_NVM_COUNTER__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_NV_CONFIG_NVM_COUNTER,
+ v_nvm_counter_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_NV_CONFIG_NVM_COUNTER__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API read accel manual offset compensation of x axis
+* from the register 0x71 bit 0 to 7
+*
+*
+*
+* @param v_accel_off_x_s8:
+* The value of accel manual offset compensation of x axis
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_offset_compensation_xaxis(
+s8*v_accel_off_x_s8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read accel manual offset compensation of x axis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_0_ACCEL_OFF_X__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_off_x_s8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_OFFSET_0_ACCEL_OFF_X);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write accel manual offset compensation of x axis
+* from the register 0x71 bit 0 to 7
+*
+*
+*
+* @param v_accel_off_x_s8:
+* The value of accel manual offset compensation of x axis
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_offset_compensation_xaxis(
+s8 v_accel_off_x_s8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+u8 v_status_s8 = SUCCESS;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* enable accel offset*/
+ v_status_s8 = smi130_set_accel_offset_enable(
+ ACCEL_OFFSET_ENABLE);
+ if (v_status_s8 == SUCCESS) {
+ /* write accel manual offset compensation of x axis*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_0_ACCEL_OFF_X__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_OFFSET_0_ACCEL_OFF_X,
+ v_accel_off_x_s8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_0_ACCEL_OFF_X__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = ERROR;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API read accel manual offset compensation of y axis
+* from the register 0x72 bit 0 to 7
+*
+*
+*
+* @param v_accel_off_y_s8:
+* The value of accel manual offset compensation of y axis
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_offset_compensation_yaxis(
+s8*v_accel_off_y_s8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read accel manual offset compensation of y axis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_1_ACCEL_OFF_Y__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_off_y_s8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_OFFSET_1_ACCEL_OFF_Y);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write accel manual offset compensation of y axis
+* from the register 0x72 bit 0 to 7
+*
+*
+*
+* @param v_accel_off_y_s8:
+* The value of accel manual offset compensation of y axis
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_offset_compensation_yaxis(
+s8 v_accel_off_y_s8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+u8 v_status_s8 = SUCCESS;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* enable accel offset*/
+ v_status_s8 = smi130_set_accel_offset_enable(
+ ACCEL_OFFSET_ENABLE);
+ if (v_status_s8 == SUCCESS) {
+ /* write accel manual offset compensation of y axis*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_1_ACCEL_OFF_Y__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(
+ v_data_u8,
+ SMI130_USER_OFFSET_1_ACCEL_OFF_Y,
+ v_accel_off_y_s8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_1_ACCEL_OFF_Y__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = ERROR;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API read accel manual offset compensation of z axis
+* from the register 0x73 bit 0 to 7
+*
+*
+*
+* @param v_accel_off_z_s8:
+* The value of accel manual offset compensation of z axis
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_offset_compensation_zaxis(
+s8*v_accel_off_z_s8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read accel manual offset compensation of z axis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_2_ACCEL_OFF_Z__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_off_z_s8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_OFFSET_2_ACCEL_OFF_Z);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write accel manual offset compensation of z axis
+* from the register 0x73 bit 0 to 7
+*
+*
+*
+* @param v_accel_off_z_s8:
+* The value of accel manual offset compensation of z axis
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_offset_compensation_zaxis(
+s8 v_accel_off_z_s8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ u8 v_status_s8 = SUCCESS;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* enable accel offset*/
+ v_status_s8 = smi130_set_accel_offset_enable(
+ ACCEL_OFFSET_ENABLE);
+ if (v_status_s8 == SUCCESS) {
+ /* write accel manual offset
+ compensation of z axis*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_2_ACCEL_OFF_Z__REG,
+ &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_OFFSET_2_ACCEL_OFF_Z,
+ v_accel_off_z_s8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_2_ACCEL_OFF_Z__REG,
+ &v_data_u8,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = ERROR;
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API read gyro manual offset compensation of x axis
+* from the register 0x74 bit 0 to 7 and 0x77 bit 0 and 1
+*
+*
+*
+* @param v_gyro_off_x_s16:
+* The value of gyro manual offset compensation of x axis
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_offset_compensation_xaxis(
+s16*v_gyro_off_x_s16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data1_u8r = SMI130_INIT_VALUE;
+ u8 v_data2_u8r = SMI130_INIT_VALUE;
+ s16 v_data3_u8r, v_data4_u8r = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read gyro offset x*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_3_GYRO_OFF_X__REG,
+ &v_data1_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data1_u8r = SMI130_GET_BITSLICE(v_data1_u8r,
+ SMI130_USER_OFFSET_3_GYRO_OFF_X);
+ com_rslt += p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_GYRO_OFF_X__REG,
+ &v_data2_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data2_u8r = SMI130_GET_BITSLICE(v_data2_u8r,
+ SMI130_USER_OFFSET_6_GYRO_OFF_X);
+ v_data3_u8r = v_data2_u8r
+ << SMI130_SHIFT_BIT_POSITION_BY_14_BITS;
+ v_data4_u8r = v_data1_u8r
+ << SMI130_SHIFT_BIT_POSITION_BY_06_BITS;
+ v_data3_u8r = v_data3_u8r | v_data4_u8r;
+ *v_gyro_off_x_s16 = v_data3_u8r
+ >> SMI130_SHIFT_BIT_POSITION_BY_06_BITS;
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write gyro manual offset compensation of x axis
+* from the register 0x74 bit 0 to 7 and 0x77 bit 0 and 1
+*
+*
+*
+* @param v_gyro_off_x_s16:
+* The value of gyro manual offset compensation of x axis
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_offset_compensation_xaxis(
+s16 v_gyro_off_x_s16)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data1_u8r, v_data2_u8r = SMI130_INIT_VALUE;
+u16 v_data3_u8r = SMI130_INIT_VALUE;
+u8 v_status_s8 = SUCCESS;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write gyro offset x*/
+ v_status_s8 = smi130_set_gyro_offset_enable(
+ GYRO_OFFSET_ENABLE);
+ if (v_status_s8 == SUCCESS) {
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_3_GYRO_OFF_X__REG,
+ &v_data2_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data1_u8r =
+ ((s8) (v_gyro_off_x_s16 &
+ SMI130_GYRO_MANUAL_OFFSET_0_7));
+ v_data2_u8r = SMI130_SET_BITSLICE(
+ v_data2_u8r,
+ SMI130_USER_OFFSET_3_GYRO_OFF_X,
+ v_data1_u8r);
+ /* write 0x74 bit 0 to 7*/
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_3_GYRO_OFF_X__REG,
+ &v_data2_u8r,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ com_rslt += p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_GYRO_OFF_X__REG,
+ &v_data2_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data3_u8r =
+ (u16) (v_gyro_off_x_s16 &
+ SMI130_GYRO_MANUAL_OFFSET_8_9);
+ v_data1_u8r = (u8)(v_data3_u8r
+ >> SMI130_SHIFT_BIT_POSITION_BY_08_BITS);
+ v_data2_u8r = SMI130_SET_BITSLICE(
+ v_data2_u8r,
+ SMI130_USER_OFFSET_6_GYRO_OFF_X,
+ v_data1_u8r);
+ /* write 0x77 bit 0 and 1*/
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_GYRO_OFF_X__REG,
+ &v_data2_u8r,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ return ERROR;
+ }
+ }
+return com_rslt;
+}
+/*!
+* @brief This API read gyro manual offset compensation of y axis
+* from the register 0x75 bit 0 to 7 and 0x77 bit 2 and 3
+*
+*
+*
+* @param v_gyro_off_y_s16:
+* The value of gyro manual offset compensation of y axis
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_offset_compensation_yaxis(
+s16*v_gyro_off_y_s16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data1_u8r = SMI130_INIT_VALUE;
+ u8 v_data2_u8r = SMI130_INIT_VALUE;
+ s16 v_data3_u8r, v_data4_u8r = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read gyro offset y*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_4_GYRO_OFF_Y__REG,
+ &v_data1_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data1_u8r = SMI130_GET_BITSLICE(v_data1_u8r,
+ SMI130_USER_OFFSET_4_GYRO_OFF_Y);
+ com_rslt += p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_GYRO_OFF_Y__REG,
+ &v_data2_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data2_u8r = SMI130_GET_BITSLICE(v_data2_u8r,
+ SMI130_USER_OFFSET_6_GYRO_OFF_Y);
+ v_data3_u8r = v_data2_u8r
+ << SMI130_SHIFT_BIT_POSITION_BY_14_BITS;
+ v_data4_u8r = v_data1_u8r
+ << SMI130_SHIFT_BIT_POSITION_BY_06_BITS;
+ v_data3_u8r = v_data3_u8r | v_data4_u8r;
+ *v_gyro_off_y_s16 = v_data3_u8r
+ >> SMI130_SHIFT_BIT_POSITION_BY_06_BITS;
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write gyro manual offset compensation of y axis
+* from the register 0x75 bit 0 to 7 and 0x77 bit 2 and 3
+*
+*
+*
+* @param v_gyro_off_y_s16:
+* The value of gyro manual offset compensation of y axis
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_offset_compensation_yaxis(
+s16 v_gyro_off_y_s16)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data1_u8r, v_data2_u8r = SMI130_INIT_VALUE;
+u16 v_data3_u8r = SMI130_INIT_VALUE;
+u8 v_status_s8 = SUCCESS;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* enable gyro offset bit*/
+ v_status_s8 = smi130_set_gyro_offset_enable(
+ GYRO_OFFSET_ENABLE);
+ /* write gyro offset y*/
+ if (v_status_s8 == SUCCESS) {
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_OFFSET_4_GYRO_OFF_Y__REG,
+ &v_data2_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data1_u8r =
+ ((s8) (v_gyro_off_y_s16 &
+ SMI130_GYRO_MANUAL_OFFSET_0_7));
+ v_data2_u8r = SMI130_SET_BITSLICE(
+ v_data2_u8r,
+ SMI130_USER_OFFSET_4_GYRO_OFF_Y,
+ v_data1_u8r);
+ /* write 0x75 bit 0 to 7*/
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_OFFSET_4_GYRO_OFF_Y__REG,
+ &v_data2_u8r,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ com_rslt += p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_GYRO_OFF_Y__REG,
+ &v_data2_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data3_u8r =
+ (u16) (v_gyro_off_y_s16 &
+ SMI130_GYRO_MANUAL_OFFSET_8_9);
+ v_data1_u8r = (u8)(v_data3_u8r
+ >> SMI130_SHIFT_BIT_POSITION_BY_08_BITS);
+ v_data2_u8r = SMI130_SET_BITSLICE(
+ v_data2_u8r,
+ SMI130_USER_OFFSET_6_GYRO_OFF_Y,
+ v_data1_u8r);
+ /* write 0x77 bit 2 and 3*/
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_GYRO_OFF_Y__REG,
+ &v_data2_u8r,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ return ERROR;
+ }
+ }
+return com_rslt;
+}
+/*!
+* @brief This API read gyro manual offset compensation of z axis
+* from the register 0x76 bit 0 to 7 and 0x77 bit 4 and 5
+*
+*
+*
+* @param v_gyro_off_z_s16:
+* The value of gyro manual offset compensation of z axis
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_offset_compensation_zaxis(
+s16*v_gyro_off_z_s16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data1_u8r = SMI130_INIT_VALUE;
+ u8 v_data2_u8r = SMI130_INIT_VALUE;
+ s16 v_data3_u8r, v_data4_u8r = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read gyro manual offset z axis*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_OFFSET_5_GYRO_OFF_Z__REG,
+ &v_data1_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data1_u8r = SMI130_GET_BITSLICE
+ (v_data1_u8r,
+ SMI130_USER_OFFSET_5_GYRO_OFF_Z);
+ com_rslt +=
+ p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_GYRO_OFF_Z__REG,
+ &v_data2_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data2_u8r = SMI130_GET_BITSLICE(
+ v_data2_u8r,
+ SMI130_USER_OFFSET_6_GYRO_OFF_Z);
+ v_data3_u8r = v_data2_u8r
+ << SMI130_SHIFT_BIT_POSITION_BY_14_BITS;
+ v_data4_u8r = v_data1_u8r
+ << SMI130_SHIFT_BIT_POSITION_BY_06_BITS;
+ v_data3_u8r = v_data3_u8r | v_data4_u8r;
+ *v_gyro_off_z_s16 = v_data3_u8r
+ >> SMI130_SHIFT_BIT_POSITION_BY_06_BITS;
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write gyro manual offset compensation of z axis
+* from the register 0x76 bit 0 to 7 and 0x77 bit 4 and 5
+*
+*
+*
+* @param v_gyro_off_z_s16:
+* The value of gyro manual offset compensation of z axis
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_offset_compensation_zaxis(
+s16 v_gyro_off_z_s16)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data1_u8r, v_data2_u8r = SMI130_INIT_VALUE;
+u16 v_data3_u8r = SMI130_INIT_VALUE;
+u8 v_status_s8 = SUCCESS;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* enable gyro offset*/
+ v_status_s8 = smi130_set_gyro_offset_enable(
+ GYRO_OFFSET_ENABLE);
+ /* write gyro manual offset z axis*/
+ if (v_status_s8 == SUCCESS) {
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_OFFSET_5_GYRO_OFF_Z__REG,
+ &v_data2_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data1_u8r =
+ ((u8) (v_gyro_off_z_s16 &
+ SMI130_GYRO_MANUAL_OFFSET_0_7));
+ v_data2_u8r = SMI130_SET_BITSLICE(
+ v_data2_u8r,
+ SMI130_USER_OFFSET_5_GYRO_OFF_Z,
+ v_data1_u8r);
+ /* write 0x76 bit 0 to 7*/
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_OFFSET_5_GYRO_OFF_Z__REG,
+ &v_data2_u8r,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ com_rslt += p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_GYRO_OFF_Z__REG,
+ &v_data2_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data3_u8r =
+ (u16) (v_gyro_off_z_s16 &
+ SMI130_GYRO_MANUAL_OFFSET_8_9);
+ v_data1_u8r = (u8)(v_data3_u8r
+ >> SMI130_SHIFT_BIT_POSITION_BY_08_BITS);
+ v_data2_u8r = SMI130_SET_BITSLICE(
+ v_data2_u8r,
+ SMI130_USER_OFFSET_6_GYRO_OFF_Z,
+ v_data1_u8r);
+ /* write 0x77 bit 4 and 5*/
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_GYRO_OFF_Z__REG,
+ &v_data2_u8r,
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ return ERROR;
+ }
+ }
+return com_rslt;
+}
+/*!
+* @brief This API read the accel offset enable bit
+* from the register 0x77 bit 6
+*
+*
+*
+* @param v_accel_off_enable_u8: The value of accel offset enable
+* value | Description
+* ----------|--------------
+* 0x01 | ENABLE
+* 0x00 | DISABLE
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_offset_enable(
+u8*v_accel_off_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read accel offset enable*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_ACCEL_OFF_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_accel_off_enable_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_OFFSET_6_ACCEL_OFF_ENABLE);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write the accel offset enable bit
+* from the register 0x77 bit 6
+*
+*
+*
+* @param v_accel_off_enable_u8: The value of accel offset enable
+* value | Description
+* ----------|--------------
+* 0x01 | ENABLE
+* 0x00 | DISABLE
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_offset_enable(
+u8 v_accel_off_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write accel offset enable*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_ACCEL_OFF_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_OFFSET_6_ACCEL_OFF_ENABLE,
+ v_accel_off_enable_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_ACCEL_OFF_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API read the accel offset enable bit
+* from the register 0x77 bit 7
+*
+*
+*
+* @param v_gyro_off_enable_u8: The value of gyro offset enable
+* value | Description
+* ----------|--------------
+* 0x01 | ENABLE
+* 0x00 | DISABLE
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_offset_enable(
+u8*v_gyro_off_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read gyro offset*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_GYRO_OFF_EN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_gyro_off_enable_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_OFFSET_6_GYRO_OFF_EN);
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API write the accel offset enable bit
+* from the register 0x77 bit 7
+*
+*
+*
+* @param v_gyro_off_enable_u8: The value of gyro offset enable
+* value | Description
+* ----------|--------------
+* 0x01 | ENABLE
+* 0x00 | DISABLE
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_offset_enable(
+u8 v_gyro_off_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write gyro offset*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_GYRO_OFF_EN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 = SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_OFFSET_6_GYRO_OFF_EN,
+ v_gyro_off_enable_u8);
+ com_rslt += p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_OFFSET_6_GYRO_OFF_EN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API reads step counter value
+* form the register 0x78 and 0x79
+*
+*
+*
+*
+* @param v_step_cnt_s16 : The value of step counter
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_step_count(u16*v_step_cnt_s16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* array having the step counter LSB and MSB data
+ v_data_u8[0] - LSB
+ v_data_u8[1] - MSB*/
+ u8 a_data_u8r[SMI130_STEP_COUNT_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE};
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read step counter*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_STEP_COUNT_LSB__REG,
+ a_data_u8r, SMI130_STEP_COUNTER_LENGTH);
+
+ *v_step_cnt_s16 = (s16)
+ ((((s32)((s8)a_data_u8r[SMI130_STEP_COUNT_MSB_BYTE]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (a_data_u8r[SMI130_STEP_COUNT_LSB_BYTE]));
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API Reads
+* step counter configuration
+* from the register 0x7A bit 0 to 7
+* and from the register 0x7B bit 0 to 2 and 4 to 7
+*
+*
+* @param v_step_config_u16 : The value of step configuration
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_step_config(
+u16*v_step_config_u16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data1_u8r = SMI130_INIT_VALUE;
+ u8 v_data2_u8r = SMI130_INIT_VALUE;
+ u16 v_data3_u8r = SMI130_INIT_VALUE;
+ /* Read the 0 to 7 bit*/
+ com_rslt =
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_STEP_CONFIG_ZERO__REG,
+ &v_data1_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ /* Read the 8 to 10 bit*/
+ com_rslt +=
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_STEP_CONFIG_ONE_CNF1__REG,
+ &v_data2_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data2_u8r = SMI130_GET_BITSLICE(v_data2_u8r,
+ SMI130_USER_STEP_CONFIG_ONE_CNF1);
+ v_data3_u8r = ((u16)((((u32)
+ ((u8)v_data2_u8r))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) | (v_data1_u8r)));
+ /* Read the 11 to 14 bit*/
+ com_rslt +=
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_STEP_CONFIG_ONE_CNF2__REG,
+ &v_data1_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data1_u8r = SMI130_GET_BITSLICE(v_data1_u8r,
+ SMI130_USER_STEP_CONFIG_ONE_CNF2);
+ *v_step_config_u16 = ((u16)((((u32)
+ ((u8)v_data1_u8r))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) | (v_data3_u8r)));
+
+ return com_rslt;
+}
+ /*!
+* @brief This API write
+* step counter configuration
+* from the register 0x7A bit 0 to 7
+* and from the register 0x7B bit 0 to 2 and 4 to 7
+*
+*
+* @param v_step_config_u16 :
+* the value of Enable step configuration
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_step_config(
+u16 v_step_config_u16)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data1_u8r = SMI130_INIT_VALUE;
+ u8 v_data2_u8r = SMI130_INIT_VALUE;
+ u16 v_data3_u16 = SMI130_INIT_VALUE;
+
+ /* write the 0 to 7 bit*/
+ v_data1_u8r = (u8)(v_step_config_u16 &
+ SMI130_STEP_CONFIG_0_7);
+ p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_STEP_CONFIG_ZERO__REG,
+ &v_data1_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ /* write the 8 to 10 bit*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_STEP_CONFIG_ONE_CNF1__REG,
+ &v_data2_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data3_u16 = (u16) (v_step_config_u16 &
+ SMI130_STEP_CONFIG_8_10);
+ v_data1_u8r = (u8)(v_data3_u16
+ >> SMI130_SHIFT_BIT_POSITION_BY_08_BITS);
+ v_data2_u8r = SMI130_SET_BITSLICE(v_data2_u8r,
+ SMI130_USER_STEP_CONFIG_ONE_CNF1, v_data1_u8r);
+ p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_STEP_CONFIG_ONE_CNF1__REG,
+ &v_data2_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ /* write the 11 to 14 bit*/
+ com_rslt += p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_STEP_CONFIG_ONE_CNF2__REG,
+ &v_data2_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data3_u16 = (u16) (v_step_config_u16 &
+ SMI130_STEP_CONFIG_11_14);
+ v_data1_u8r = (u8)(v_data3_u16
+ >> SMI130_SHIFT_BIT_POSITION_BY_12_BITS);
+ v_data2_u8r = SMI130_SET_BITSLICE(v_data2_u8r,
+ SMI130_USER_STEP_CONFIG_ONE_CNF2, v_data1_u8r);
+ p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_STEP_CONFIG_ONE_CNF2__REG,
+ &v_data2_u8r, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+
+ return com_rslt;
+}
+ /*!
+* @brief This API read enable step counter
+* from the register 0x7B bit 3
+*
+*
+* @param v_step_counter_u8 : The value of step counter enable
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_step_counter_enable(
+u8*v_step_counter_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the step counter*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_step_counter_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE);
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API write enable step counter
+* from the register 0x7B bit 3
+*
+*
+* @param v_step_counter_u8 : The value of step counter enable
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_step_counter_enable(u8 v_step_counter_u8)
+{
+/* variable used for return the status of communication result*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+/* check the p_smi130 structure as NULL*/
+if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+} else {
+ if (v_step_counter_u8 <= SMI130_MAX_GYRO_STEP_COUNTER) {
+ /* write the step counter*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE,
+ v_step_counter_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+}
+ return com_rslt;
+}
+ /*!
+* @brief This API set Step counter modes
+*
+*
+* @param v_step_mode_u8 : The value of step counter mode
+* value | mode
+* ----------|-----------
+* 0 | SMI130_STEP_NORMAL_MODE
+* 1 | SMI130_STEP_SENSITIVE_MODE
+* 2 | SMI130_STEP_ROBUST_MODE
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_step_mode(u8 v_step_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+
+ switch (v_step_mode_u8) {
+ case SMI130_STEP_NORMAL_MODE:
+ com_rslt = smi130_set_step_config(
+ STEP_CONFIG_NORMAL);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ break;
+ case SMI130_STEP_SENSITIVE_MODE:
+ com_rslt = smi130_set_step_config(
+ STEP_CONFIG_SENSITIVE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ break;
+ case SMI130_STEP_ROBUST_MODE:
+ com_rslt = smi130_set_step_config(
+ STEP_CONFIG_ROBUST);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+
+ return com_rslt;
+}
+/*!
+* @brief This API used to trigger the signification motion
+* interrupt
+*
+*
+* @param v_significant_u8 : The value of interrupt selection
+* value | interrupt
+* ----------|-----------
+* 0 | SMI130_MAP_INTR1
+* 1 | SMI130_MAP_INTR2
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_map_significant_motion_intr(
+u8 v_significant_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_sig_motion_u8 = SMI130_INIT_VALUE;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ u8 v_any_motion_intr1_stat_u8 = SMI130_ENABLE_ANY_MOTION_INTR1;
+ u8 v_any_motion_intr2_stat_u8 = SMI130_ENABLE_ANY_MOTION_INTR2;
+ u8 v_any_motion_axis_stat_u8 = SMI130_ENABLE_ANY_MOTION_AXIS;
+ /* enable the significant motion interrupt*/
+ com_rslt = smi130_get_intr_significant_motion_select(&v_sig_motion_u8);
+ if (v_sig_motion_u8 != SMI130_SIG_MOTION_STAT_HIGH)
+ com_rslt += smi130_set_intr_significant_motion_select(
+ SMI130_SIG_MOTION_INTR_ENABLE);
+ switch (v_significant_u8) {
+ case SMI130_MAP_INTR1:
+ /* interrupt*/
+ com_rslt += smi130_read_reg(
+ SMI130_USER_INTR_MAP_0_INTR1_ANY_MOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data_u8 |= v_any_motion_intr1_stat_u8;
+ /* map the signification interrupt to any-motion interrupt1*/
+ com_rslt += smi130_write_reg(
+ SMI130_USER_INTR_MAP_0_INTR1_ANY_MOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* axis*/
+ com_rslt = smi130_read_reg(SMI130_USER_INTR_ENABLE_0_ADDR,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data_u8 |= v_any_motion_axis_stat_u8;
+ com_rslt += smi130_write_reg(
+ SMI130_USER_INTR_ENABLE_0_ADDR,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ break;
+
+ case SMI130_MAP_INTR2:
+ /* map the signification interrupt to any-motion interrupt2*/
+ com_rslt += smi130_read_reg(
+ SMI130_USER_INTR_MAP_2_INTR2_ANY_MOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data_u8 |= v_any_motion_intr2_stat_u8;
+ com_rslt += smi130_write_reg(
+ SMI130_USER_INTR_MAP_2_INTR2_ANY_MOTION__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* axis*/
+ com_rslt = smi130_read_reg(SMI130_USER_INTR_ENABLE_0_ADDR,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data_u8 |= v_any_motion_axis_stat_u8;
+ com_rslt += smi130_write_reg(
+ SMI130_USER_INTR_ENABLE_0_ADDR,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ break;
+
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+
+ }
+ return com_rslt;
+}
+/*!
+* @brief This API used to trigger the step detector
+* interrupt
+*
+*
+* @param v_step_detector_u8 : The value of interrupt selection
+* value | interrupt
+* ----------|-----------
+* 0 | SMI130_MAP_INTR1
+* 1 | SMI130_MAP_INTR2
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_map_step_detector_intr(
+u8 v_step_detector_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_step_det_u8 = SMI130_INIT_VALUE;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ u8 v_low_g_intr_u81_stat_u8 = SMI130_LOW_G_INTR_STAT;
+ u8 v_low_g_intr_u82_stat_u8 = SMI130_LOW_G_INTR_STAT;
+ u8 v_low_g_enable_u8 = SMI130_ENABLE_LOW_G;
+ /* read the v_status_s8 of step detector interrupt*/
+ com_rslt = smi130_get_step_detector_enable(&v_step_det_u8);
+ if (v_step_det_u8 != SMI130_STEP_DET_STAT_HIGH)
+ com_rslt += smi130_set_step_detector_enable(
+ SMI130_STEP_DETECT_INTR_ENABLE);
+ switch (v_step_detector_u8) {
+ case SMI130_MAP_INTR1:
+ com_rslt += smi130_read_reg(
+ SMI130_USER_INTR_MAP_0_INTR1_LOW_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data_u8 |= v_low_g_intr_u81_stat_u8;
+ /* map the step detector interrupt
+ to Low-g interrupt 1*/
+ com_rslt += smi130_write_reg(
+ SMI130_USER_INTR_MAP_0_INTR1_LOW_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* Enable the Low-g interrupt*/
+ com_rslt = smi130_read_reg(
+ SMI130_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data_u8 |= v_low_g_enable_u8;
+ com_rslt += smi130_write_reg(
+ SMI130_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ break;
+ case SMI130_MAP_INTR2:
+ /* map the step detector interrupt
+ to Low-g interrupt 1*/
+ com_rslt += smi130_read_reg(
+ SMI130_USER_INTR_MAP_2_INTR2_LOW_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data_u8 |= v_low_g_intr_u82_stat_u8;
+
+ com_rslt += smi130_write_reg(
+ SMI130_USER_INTR_MAP_2_INTR2_LOW_G__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* Enable the Low-g interrupt*/
+ com_rslt = smi130_read_reg(
+ SMI130_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_data_u8 |= v_low_g_enable_u8;
+ com_rslt += smi130_write_reg(
+ SMI130_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API used to clear the step counter interrupt
+* interrupt
+*
+*
+* @param : None
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_clear_step_counter(void)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* clear the step counter*/
+ com_rslt = smi130_set_command_register(RESET_STEP_COUNTER);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+
+ return com_rslt;
+
+}
+ /*!
+* @brief This API writes value to the register 0x7E bit 0 to 7
+*
+*
+* @param v_command_reg_u8 : The value to write command register
+* value | Description
+* ---------|--------------------------------------------------------
+* 0x00 | Reserved
+* 0x03 | Starts fast offset calibration for the accel and gyro
+* 0x10 | Sets the PMU mode for the Accelerometer to suspend
+* 0x11 | Sets the PMU mode for the Accelerometer to normal
+* 0x12 | Sets the PMU mode for the Accelerometer Lowpower
+* 0x14 | Sets the PMU mode for the Gyroscope to suspend
+* 0x15 | Sets the PMU mode for the Gyroscope to normal
+* 0x16 | Reserved
+* 0x17 | Sets the PMU mode for the Gyroscope to fast start-up
+* 0x18 | Sets the PMU mode for the Magnetometer to suspend
+* 0x19 | Sets the PMU mode for the Magnetometer to normal
+* 0x1A | Sets the PMU mode for the Magnetometer to Lowpower
+* 0xB0 | Clears all data in the FIFO
+* 0xB1 | Resets the interrupt engine
+* 0xB2 | step_cnt_clr Clears the step counter
+* 0xB6 | Triggers a reset
+* 0x37 | See extmode_en_last
+* 0x9A | See extmode_en_last
+* 0xC0 | Enable the extended mode
+* 0xC4 | Erase NVM cell
+* 0xC8 | Load NVM cell
+* 0xF0 | Reset acceleration data path
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_command_register(u8 v_command_reg_u8)
+{
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write command register*/
+ com_rslt = p_smi130->SMI130_BUS_WRITE_FUNC(
+ p_smi130->dev_addr,
+ SMI130_CMD_COMMANDS__REG,
+ &v_command_reg_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API read target page from the register 0x7F bit 4 and 5
+*
+* @param v_target_page_u8: The value of target page
+* value | page
+* ---------|-----------
+* 0 | User data/configure page
+* 1 | Chip level trim/test page
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_target_page(u8*v_target_page_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the page*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_CMD_TARGET_PAGE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_target_page_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_CMD_TARGET_PAGE);
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API write target page from the register 0x7F bit 4 and 5
+*
+* @param v_target_page_u8: The value of target page
+* value | page
+* ---------|-----------
+* 0 | User data/configure page
+* 1 | Chip level trim/test page
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_target_page(u8 v_target_page_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_target_page_u8 <= SMI130_MAX_TARGET_PAGE) {
+ /* write the page*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_CMD_TARGET_PAGE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_CMD_TARGET_PAGE,
+ v_target_page_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_CMD_TARGET_PAGE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API read page enable from the register 0x7F bit 7
+*
+*
+*
+* @param v_page_enable_u8: The value of page enable
+* value | page
+* ---------|-----------
+* 0 | DISABLE
+* 1 | ENABLE
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_paging_enable(u8*v_page_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the page enable*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_CMD_PAGING_EN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_page_enable_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_CMD_PAGING_EN);
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API write page enable from the register 0x7F bit 7
+*
+*
+*
+* @param v_page_enable_u8: The value of page enable
+* value | page
+* ---------|-----------
+* 0 | DISABLE
+* 1 | ENABLE
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_paging_enable(
+u8 v_page_enable_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ if (v_page_enable_u8 <= SMI130_MAX_VALUE_PAGE) {
+ /* write the page enable*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_CMD_PAGING_EN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_CMD_PAGING_EN,
+ v_page_enable_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_CMD_PAGING_EN__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ } else {
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ }
+ }
+ return com_rslt;
+}
+ /*!
+* @brief This API read
+* pull up configuration from the register 0X85 bit 4 an 5
+*
+*
+*
+* @param v_control_pullup_u8: The value of pull up register
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_pullup_configuration(
+u8*v_control_pullup_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read pull up value*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC(
+ p_smi130->dev_addr,
+ SMI130_COM_C_TRIM_FIVE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ *v_control_pullup_u8 = SMI130_GET_BITSLICE(v_data_u8,
+ SMI130_COM_C_TRIM_FIVE);
+ }
+ return com_rslt;
+
+}
+ /*!
+* @brief This API write
+* pull up configuration from the register 0X85 bit 4 an 5
+*
+*
+*
+* @param v_control_pullup_u8: The value of pull up register
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_pullup_configuration(
+u8 v_control_pullup_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* write pull up value*/
+ com_rslt = p_smi130->SMI130_BUS_READ_FUNC
+ (p_smi130->dev_addr,
+ SMI130_COM_C_TRIM_FIVE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ if (com_rslt == SUCCESS) {
+ v_data_u8 =
+ SMI130_SET_BITSLICE(v_data_u8,
+ SMI130_COM_C_TRIM_FIVE,
+ v_control_pullup_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_WRITE_FUNC
+ (p_smi130->dev_addr,
+ SMI130_COM_C_TRIM_FIVE__REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ }
+ }
+ return com_rslt;
+}
+
+/*!
+* @brief This function used for read the compensated value of mag
+* Before start reading the mag compensated data's
+* make sure the following two points are addressed
+* @note
+* 1. Make sure the mag interface is enabled or not,
+* by using the smi130_get_if_mode() function.
+* If mag interface is not enabled set the value of 0x02
+* to the function smi130_get_if_mode(0x02)
+* @note
+* 2. And also confirm the secondary-interface power mode
+* is not in the SUSPEND mode.
+* by using the function smi130_get_mag_pmu_status().
+* If the secondary-interface power mode is in SUSPEND mode
+* set the value of 0x19(NORMAL mode)by using the
+* smi130_set_command_register(0x19) function.
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bmm150_mag_compensate_xyz(
+struct smi130_mag_xyz_s32_t*mag_comp_xyz)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ struct smi130_mag_xyzr_t mag_xyzr;
+ com_rslt = smi130_read_mag_xyzr(&mag_xyzr);
+ if (com_rslt)
+ return com_rslt;
+ /* Compensation for X axis*/
+ mag_comp_xyz->x = smi130_bmm150_mag_compensate_X(
+ mag_xyzr.x, mag_xyzr.r);
+
+ /* Compensation for Y axis*/
+ mag_comp_xyz->y = smi130_bmm150_mag_compensate_Y(
+ mag_xyzr.y, mag_xyzr.r);
+
+ /* Compensation for Z axis*/
+ mag_comp_xyz->z = smi130_bmm150_mag_compensate_Z(
+ mag_xyzr.z, mag_xyzr.r);
+
+ return com_rslt;
+}
+
+/*!
+* @brief This function used for read the compensated value of mag
+* Before start reading the mag compensated data's
+* make sure the following two points are addressed
+* @note
+* 1. Make sure the mag interface is enabled or not,
+* by using the smi130_get_if_mode() function.
+* If mag interface is not enabled set the value of 0x02
+* to the function smi130_get_if_mode(0x02)
+* @note
+* 2. And also confirm the secondary-interface power mode
+* is not in the SUSPEND mode.
+* by using the function smi130_get_mag_pmu_status().
+* If the secondary-interface power mode is in SUSPEND mode
+* set the value of 0x19(NORMAL mode)by using the
+* smi130_set_command_register(0x19) function.
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bmm150_mag_compensate_xyz_raw(
+struct smi130_mag_xyz_s32_t*mag_comp_xyz, struct smi130_mag_xyzr_t mag_xyzr)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+
+ /* Compensation for X axis*/
+ mag_comp_xyz->x = smi130_bmm150_mag_compensate_X(
+ mag_xyzr.x, mag_xyzr.r);
+
+ /* Compensation for Y axis*/
+ mag_comp_xyz->y = smi130_bmm150_mag_compensate_Y(
+ mag_xyzr.y, mag_xyzr.r);
+
+ /* Compensation for Z axis*/
+ mag_comp_xyz->z = smi130_bmm150_mag_compensate_Z(
+ mag_xyzr.z, mag_xyzr.r);
+
+ return com_rslt;
+}
+/*!
+* @brief This API used to get the compensated BMM150-X data
+* the out put of X as s32
+* Before start reading the mag compensated X data
+* make sure the following two points are addressed
+* @note
+* 1. Make sure the mag interface is enabled or not,
+* by using the smi130_get_if_mode() function.
+* If mag interface is not enabled set the value of 0x02
+* to the function smi130_get_if_mode(0x02)
+* @note
+* 2. And also confirm the secondary-interface power mode
+* is not in the SUSPEND mode.
+* by using the function smi130_get_mag_pmu_status().
+* If the secondary-interface power mode is in SUSPEND mode
+* set the value of 0x19(NORMAL mode)by using the
+* smi130_set_command_register(0x19) function.
+*
+*
+*
+* @param v_mag_data_x_s16 : The value of mag raw X data
+* @param v_data_r_u16 : The value of mag R data
+*
+* @return results of compensated X data value output as s32
+*
+*/
+s32 smi130_bmm150_mag_compensate_X(s16 v_mag_data_x_s16, u16 v_data_r_u16)
+{
+s32 inter_retval = SMI130_INIT_VALUE;
+/* no overflow*/
+if (v_mag_data_x_s16 != SMI130_MAG_FLIP_OVERFLOW_ADCVAL) {
+ if ((v_data_r_u16 != 0)
+ && (mag_trim.dig_xyz1 != 0)) {
+ inter_retval = ((s32)(((u16)
+ ((((s32)mag_trim.dig_xyz1)
+ << SMI130_SHIFT_BIT_POSITION_BY_14_BITS)/
+ (v_data_r_u16 != 0 ?
+ v_data_r_u16 : mag_trim.dig_xyz1))) -
+ ((u16)0x4000)));
+ } else {
+ inter_retval = SMI130_MAG_OVERFLOW_OUTPUT;
+ return inter_retval;
+ }
+ inter_retval = ((s32)((((s32)v_mag_data_x_s16)*
+ ((((((((s32)mag_trim.dig_xy2)*
+ ((((s32)inter_retval)*
+ ((s32)inter_retval))
+ >> SMI130_SHIFT_BIT_POSITION_BY_07_BITS)) +
+ (((s32)inter_retval)*
+ ((s32)(((s16)mag_trim.dig_xy1)
+ << SMI130_SHIFT_BIT_POSITION_BY_07_BITS))))
+ >> SMI130_SHIFT_BIT_POSITION_BY_09_BITS) +
+ ((s32)0x100000))*
+ ((s32)(((s16)mag_trim.dig_x2) +
+ ((s16)0xA0))))
+ >> SMI130_SHIFT_BIT_POSITION_BY_12_BITS))
+ >> SMI130_SHIFT_BIT_POSITION_BY_13_BITS)) +
+ (((s16)mag_trim.dig_x1)
+ << SMI130_SHIFT_BIT_POSITION_BY_03_BITS);
+ /* check the overflow output*/
+ if (inter_retval == (s32)SMI130_MAG_OVERFLOW_OUTPUT)
+ inter_retval = SMI130_MAG_OVERFLOW_OUTPUT_S32;
+} else {
+ /* overflow*/
+ inter_retval = SMI130_MAG_OVERFLOW_OUTPUT;
+}
+return inter_retval;
+}
+/*!
+* @brief This API used to get the compensated BMM150-Y data
+* the out put of Y as s32
+* Before start reading the mag compensated Y data
+* make sure the following two points are addressed
+* @note
+* 1. Make sure the mag interface is enabled or not,
+* by using the smi130_get_if_mode() function.
+* If mag interface is not enabled set the value of 0x02
+* to the function smi130_get_if_mode(0x02)
+* @note
+* 2. And also confirm the secondary-interface power mode
+* is not in the SUSPEND mode.
+* by using the function smi130_get_mag_pmu_status().
+* If the secondary-interface power mode is in SUSPEND mode
+* set the value of 0x19(NORMAL mode)by using the
+* smi130_set_command_register(0x19) function.
+*
+*
+*
+* @param v_mag_data_y_s16 : The value of mag raw Y data
+* @param v_data_r_u16 : The value of mag R data
+*
+* @return results of compensated Y data value output as s32
+*/
+s32 smi130_bmm150_mag_compensate_Y(s16 v_mag_data_y_s16, u16 v_data_r_u16)
+{
+s32 inter_retval = SMI130_INIT_VALUE;
+/* no overflow*/
+if (v_mag_data_y_s16 != SMI130_MAG_FLIP_OVERFLOW_ADCVAL) {
+ if ((v_data_r_u16 != 0)
+ && (mag_trim.dig_xyz1 != 0)) {
+ inter_retval = ((s32)(((u16)(((
+ (s32)mag_trim.dig_xyz1)
+ << SMI130_SHIFT_BIT_POSITION_BY_14_BITS) /
+ (v_data_r_u16 != 0 ?
+ v_data_r_u16 : mag_trim.dig_xyz1))) -
+ ((u16)0x4000)));
+ } else {
+ inter_retval = SMI130_MAG_OVERFLOW_OUTPUT;
+ return inter_retval;
+ }
+ inter_retval = ((s32)((((s32)v_mag_data_y_s16)* ((((((((s32)
+ mag_trim.dig_xy2)* ((((s32) inter_retval)*
+ ((s32)inter_retval)) >> SMI130_SHIFT_BIT_POSITION_BY_07_BITS))
+ + (((s32)inter_retval)*
+ ((s32)(((s16)mag_trim.dig_xy1)
+ << SMI130_SHIFT_BIT_POSITION_BY_07_BITS))))
+ >> SMI130_SHIFT_BIT_POSITION_BY_09_BITS) +
+ ((s32)0x100000))
+ * ((s32)(((s16)mag_trim.dig_y2)
+ + ((s16)0xA0))))
+ >> SMI130_SHIFT_BIT_POSITION_BY_12_BITS))
+ >> SMI130_SHIFT_BIT_POSITION_BY_13_BITS)) +
+ (((s16)mag_trim.dig_y1)
+ << SMI130_SHIFT_BIT_POSITION_BY_03_BITS);
+ /* check the overflow output*/
+ if (inter_retval == (s32)SMI130_MAG_OVERFLOW_OUTPUT)
+ inter_retval = SMI130_MAG_OVERFLOW_OUTPUT_S32;
+} else {
+ /* overflow*/
+ inter_retval = SMI130_MAG_OVERFLOW_OUTPUT;
+}
+return inter_retval;
+}
+/*!
+* @brief This API used to get the compensated BMM150-Z data
+* the out put of Z as s32
+* Before start reading the mag compensated Z data
+* make sure the following two points are addressed
+* @note
+* 1. Make sure the mag interface is enabled or not,
+* by using the smi130_get_if_mode() function.
+* If mag interface is not enabled set the value of 0x02
+* to the function smi130_get_if_mode(0x02)
+* @note
+* 2. And also confirm the secondary-interface power mode
+* is not in the SUSPEND mode.
+* by using the function smi130_get_mag_pmu_status().
+* If the secondary-interface power mode is in SUSPEND mode
+* set the value of 0x19(NORMAL mode)by using the
+* smi130_set_command_register(0x19) function.
+*
+*
+*
+* @param v_mag_data_z_s16 : The value of mag raw Z data
+* @param v_data_r_u16 : The value of mag R data
+*
+* @return results of compensated Z data value output as s32
+*/
+s32 smi130_bmm150_mag_compensate_Z(s16 v_mag_data_z_s16, u16 v_data_r_u16)
+{
+ s32 retval = SMI130_INIT_VALUE;
+
+ if (v_mag_data_z_s16 != SMI130_MAG_HALL_OVERFLOW_ADCVAL) {
+ if ((v_data_r_u16 != 0)
+ && (mag_trim.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))
+ << SMI130_SHIFT_BIT_POSITION_BY_15_BITS) -
+ ((((s32)mag_trim.dig_z3)*
+ ((s32)(((s16)v_data_r_u16) -
+ ((s16)mag_trim.dig_xyz1))))
+ >> SMI130_SHIFT_BIT_POSITION_BY_02_BITS))/
+ (mag_trim.dig_z2 +
+ ((s16)(((((s32)mag_trim.dig_z1)*
+ ((((s16)v_data_r_u16)
+ << SMI130_SHIFT_BIT_POSITION_BY_01_BIT))) +
+ (1 << SMI130_SHIFT_BIT_POSITION_BY_15_BITS))
+ >> SMI130_SHIFT_BIT_POSITION_BY_16_BITS))));
+ }
+ } else {
+ retval = SMI130_MAG_OVERFLOW_OUTPUT;
+ }
+ return retval;
+}
+ /*!
+* @brief This function used for initialize the bmm150 sensor
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bmm150_mag_interface_init(void)
+{
+ /* This variable used for provide the communication
+ results*/
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = SMI130_INIT_VALUE;
+ u8 v_pull_value_u8 = SMI130_INIT_VALUE;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ /* accel operation mode to normal*/
+ com_rslt = smi130_set_command_register(ACCEL_MODE_NORMAL);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* write the mag power mode as NORMAL*/
+ com_rslt += smi130_set_mag_interface_normal();
+
+ /* register 0x7E write the 0x37, 0x9A and 0x30*/
+ com_rslt += smi130_set_command_register(SMI130_COMMAND_REG_ONE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_command_register(SMI130_COMMAND_REG_TWO);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_command_register(SMI130_COMMAND_REG_THREE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /*switch the page1*/
+ com_rslt += smi130_set_target_page(SMI130_WRITE_TARGET_PAGE1);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_target_page(&v_data_u8);
+ com_rslt += smi130_set_paging_enable(SMI130_WRITE_ENABLE_PAGE1);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_paging_enable(&v_data_u8);
+ /* enable the pullup configuration from
+ the register 0x05 bit 4 and 5 as 10*/
+ smi130_get_pullup_configuration(&v_pull_value_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ v_pull_value_u8 = v_pull_value_u8 | SMI130_PULL_UP_DATA;
+ com_rslt += smi130_set_pullup_configuration(v_pull_value_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /*switch the page0*/
+ com_rslt += smi130_set_target_page(SMI130_WRITE_TARGET_PAGE0);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_target_page(&v_data_u8);
+ /* Write the BMM150 i2c address*/
+ com_rslt += smi130_set_i2c_device_addr(SMI130_AUX_BMM150_I2C_ADDRESS);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* enable the mag interface to manual mode*/
+ com_rslt += smi130_set_mag_manual_enable(SMI130_MANUAL_ENABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_mag_manual_enable(&v_data_u8);
+ /*Enable the MAG interface*/
+ com_rslt += smi130_set_if_mode(SMI130_ENABLE_MAG_IF_MODE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_if_mode(&v_data_u8);
+ /* Mag normal mode*/
+ com_rslt += smi130_bmm150_mag_wakeup();
+ printk(KERN_INFO "com_rslt:%d, <%s><%d>\n",
+ com_rslt, __func__, __LINE__);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* Read the BMM150 device id is 0x32*/
+ /*com_rslt += smi130_set_mag_read_addr(SMI130_BMM150_CHIP_ID);*/
+ /*p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);*/
+ /*com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);*/
+ /**v_chip_id_u8 = v_data_u8;*/
+ /*p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);*/
+ /* write the power mode register*/
+ com_rslt += smi130_set_mag_write_data(SMI130_BMM_POWER_MODE_REG);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /*write 0x4C register to write set power mode to normal*/
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_POWE_MODE_REG);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* read the mag trim values*/
+ com_rslt += smi130_read_bmm150_mag_trim();
+ 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 = SMI130_MANUAL_ENABLE;
+ /* write the XY and Z repetitions*/
+ com_rslt += smi130_set_bmm150_mag_presetmode(
+ SMI130_MAG_PRESETMODE_REGULAR);
+ printk(KERN_INFO "com_rslt:%d, <%s><%d>\n",
+ com_rslt, __func__, __LINE__);
+ /* To avoid the auto mode enable when manual mode operation running*/
+ V_bmm150_maual_auto_condition_u8 = SMI130_MANUAL_DISABLE;
+ /* Set the power mode of mag as force mode*/
+ /* The data have to write for the register
+ It write the value in the register 0x4F*/
+ com_rslt += smi130_set_mag_write_data(SMI130_BMM150_FORCE_MODE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ printk(KERN_INFO "com_rslt:%d, <%s><%d>\n",
+ com_rslt, __func__, __LINE__);
+ /* write into power mode register*/
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_POWE_MODE_REG);
+ /* write the mag v_data_bw_u8 as 25Hz*/
+ com_rslt += smi130_set_mag_output_data_rate(
+ SMI130_MAG_OUTPUT_DATA_RATE_25HZ);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+
+ /* When mag interface is auto mode - The mag read address
+ starts the register 0x42*/
+ com_rslt += smi130_set_mag_read_addr(
+ SMI130_BMM150_DATA_REG);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* enable mag interface to auto mode*/
+ com_rslt += smi130_set_mag_manual_enable(SMI130_MANUAL_DISABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_mag_manual_enable(&v_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+
+ return com_rslt;
+}
+ /*!
+* @brief This function used for set the mag power control
+* bit enable
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bmm150_mag_wakeup(void)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = SMI130_INIT_VALUE;
+ u8 v_try_times_u8 = SMI130_BMM150_MAX_RETRY_WAKEUP;
+ u8 v_power_control_bit_u8 = SMI130_INIT_VALUE;
+ u8 i = SMI130_INIT_VALUE;
+
+ for (i = SMI130_INIT_VALUE; i < v_try_times_u8; i++) {
+ com_rslt = smi130_set_mag_write_data(SMI130_BMM150_POWER_ON);
+ p_smi130->delay_msec(SMI130_BMM150_WAKEUP_DELAY1);
+ /*write 0x4B register to enable power control bit*/
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_POWE_CONTROL_REG);
+ p_smi130->delay_msec(SMI130_BMM150_WAKEUP_DELAY2);
+ com_rslt += smi130_set_mag_read_addr(
+ SMI130_BMM150_POWE_CONTROL_REG);
+ /* 0x04 is secondary read mag x lsb register*/
+ p_smi130->delay_msec(SMI130_BMM150_WAKEUP_DELAY3);
+ com_rslt += smi130_read_reg(SMI130_USER_DATA_0_ADDR,
+ &v_power_control_bit_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ v_power_control_bit_u8 = SMI130_BMM150_SET_POWER_CONTROL
+ & v_power_control_bit_u8;
+ if (v_power_control_bit_u8 == SMI130_BMM150_POWER_ON)
+ break;
+ }
+ com_rslt = (i >= v_try_times_u8) ?
+ SMI130_BMM150_POWER_ON_FAIL : SMI130_BMM150_POWER_ON_SUCCESS;
+ return com_rslt;
+}
+ /*!
+* @brief This function used for set the magnetometer
+* power mode.
+* @note
+* Before set the mag power mode
+* make sure the following two point is addressed
+* Make sure the mag interface is enabled or not,
+* by using the smi130_get_if_mode() function.
+* If mag interface is not enabled set the value of 0x02
+* to the function smi130_get_if_mode(0x02)
+*
+* @param v_mag_sec_if_pow_mode_u8 : The value of mag power mode
+* value | mode
+* ----------|------------
+* 0 | SMI130_MAG_FORCE_MODE
+* 1 | SMI130_MAG_SUSPEND_MODE
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_bmm150_mag_and_secondary_if_power_mode(
+u8 v_mag_sec_if_pow_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = SMI130_INIT_VALUE;
+ /* set the accel power mode to NORMAL*/
+ com_rslt = smi130_set_command_register(ACCEL_MODE_NORMAL);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_smi130->mag_manual_enable, __func__, __LINE__);
+ /* set mag interface manual mode*/
+ if (p_smi130->mag_manual_enable != SMI130_MANUAL_ENABLE) {
+ com_rslt += smi130_set_mag_manual_enable(
+ SMI130_MANUAL_ENABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ }
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_smi130->mag_manual_enable, __func__, __LINE__);
+
+ switch (v_mag_sec_if_pow_mode_u8) {
+ case SMI130_MAG_FORCE_MODE:
+ /* set the secondary mag power mode as NORMAL*/
+ com_rslt += smi130_set_mag_interface_normal();
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_smi130->mag_manual_enable, __func__, __LINE__);
+ /* set the mag power mode as FORCE mode*/
+ com_rslt += smi130_bmm150_mag_set_power_mode(FORCE_MODE);
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_smi130->mag_manual_enable, __func__, __LINE__);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ break;
+ case SMI130_MAG_SUSPEND_MODE:
+ /* set the mag power mode as SUSPEND mode*/
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_smi130->mag_manual_enable, __func__, __LINE__);
+ com_rslt += smi130_bmm150_mag_set_power_mode(SUSPEND_MODE);
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_smi130->mag_manual_enable, __func__, __LINE__);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* set the secondary mag power mode as SUSPEND*/
+ com_rslt += smi130_set_command_register(MAG_MODE_SUSPEND);
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_smi130->mag_manual_enable, __func__, __LINE__);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ if (p_smi130->mag_manual_enable == SMI130_MANUAL_ENABLE) {
+ /* set mag interface auto mode*/
+ com_rslt += smi130_set_mag_manual_enable(
+ SMI130_MANUAL_DISABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ }
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_smi130->mag_manual_enable, __func__, __LINE__);
+ return com_rslt;
+}
+/*!
+* @brief This function used for set the magnetometer
+* power mode.
+* @note
+* Before set the mag power mode
+* make sure the following two points are addressed
+* @note
+* 1. Make sure the mag interface is enabled or not,
+* by using the smi130_get_if_mode() function.
+* If mag interface is not enabled set the value of 0x02
+* to the function smi130_get_if_mode(0x02)
+* @note
+* 2. And also confirm the secondary-interface power mode
+* is not in the SUSPEND mode.
+* by using the function smi130_get_mag_pmu_status().
+* If the secondary-interface power mode is in SUSPEND mode
+* set the value of 0x19(NORMAL mode)by using the
+* smi130_set_command_register(0x19) function.
+*
+* @param v_mag_pow_mode_u8 : The value of mag power mode
+* value | mode
+* ----------|------------
+* 0 | FORCE_MODE
+* 1 | SUSPEND_MODE
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bmm150_mag_set_power_mode(
+u8 v_mag_pow_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = SMI130_INIT_VALUE;
+ u8 manual_enable_status = 0;
+ /* set mag interface manual mode*/
+ if (p_smi130->mag_manual_enable != SMI130_MANUAL_ENABLE) {
+ com_rslt = smi130_set_mag_manual_enable(
+ SMI130_MANUAL_ENABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_get_mag_manual_enable(&manual_enable_status);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ printk(KERN_INFO "1com_rslt:%d, manual:%d, manual_read:%d\n",
+ com_rslt, p_smi130->mag_manual_enable, manual_enable_status);
+ }
+ printk(KERN_INFO "2com_rslt:%d, manual:%d, manual_read:%d\n",
+ com_rslt, p_smi130->mag_manual_enable, manual_enable_status);
+
+ switch (v_mag_pow_mode_u8) {
+ case FORCE_MODE:
+ /* Set the power control bit enabled*/
+ com_rslt = smi130_bmm150_mag_wakeup();
+ /* write the mag power mode as FORCE mode*/
+ com_rslt += smi130_set_mag_write_data(
+ SMI130_BMM150_FORCE_MODE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_POWE_MODE_REG);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* To avoid the auto mode enable when manual
+ mode operation running*/
+ V_bmm150_maual_auto_condition_u8 = SMI130_MANUAL_ENABLE;
+ /* set the preset mode*/
+ com_rslt += smi130_set_bmm150_mag_presetmode(
+ SMI130_MAG_PRESETMODE_REGULAR);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* To avoid the auto mode enable when manual
+ mode operation running*/
+ V_bmm150_maual_auto_condition_u8 = SMI130_MANUAL_DISABLE;
+ /* set the mag read address to data registers*/
+ com_rslt += smi130_set_mag_read_addr(
+ SMI130_BMM150_DATA_REG);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ break;
+ case SUSPEND_MODE:
+ printk(KERN_INFO "3com_rslt:%d, manual:%d, read_manual:%d\n",
+ com_rslt, p_smi130->mag_manual_enable, manual_enable_status);
+ /* Set the power mode of mag as suspend mode*/
+ com_rslt += smi130_set_mag_write_data(
+ SMI130_BMM150_POWER_OFF);
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_smi130->mag_manual_enable, __func__, __LINE__);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_POWE_CONTROL_REG);
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_smi130->mag_manual_enable, __func__, __LINE__);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ printk(KERN_INFO "4com_rslt:%d, manual:%d, manual_read:%d\n",
+ com_rslt, p_smi130->mag_manual_enable, manual_enable_status);
+ /* set mag interface auto mode*/
+ if (p_smi130->mag_manual_enable == SMI130_MANUAL_ENABLE) {
+ com_rslt += smi130_set_mag_manual_enable(
+ SMI130_MANUAL_DISABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_get_mag_manual_enable(&manual_enable_status);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ }
+ printk(KERN_INFO "5com_rslt:%d, manual:%d, manual_read:%d\n",
+ com_rslt, p_smi130->mag_manual_enable, manual_enable_status);
+ return com_rslt;
+}
+/*!
+* @brief This API used to set the pre-set modes of bmm150
+* The pre-set mode setting is depend on data rate and xy and z repetitions
+*
+* @note
+* Before set the mag preset mode
+* make sure the following two points are addressed
+* @note
+* 1. Make sure the mag interface is enabled or not,
+* by using the smi130_get_if_mode() function.
+* If mag interface is not enabled set the value of 0x02
+* to the function smi130_get_if_mode(0x02)
+* @note
+* 2. And also confirm the secondary-interface power mode
+* is not in the SUSPEND mode.
+* by using the function smi130_get_mag_pmu_status().
+* If the secondary-interface power mode is in SUSPEND mode
+* set the value of 0x19(NORMAL mode)by using the
+* smi130_set_command_register(0x19) function.
+*
+*
+* @param v_mode_u8: The value of pre-set mode selection value
+* value | pre_set mode
+* ----------|------------
+* 1 | SMI130_MAG_PRESETMODE_LOWPOWER
+* 2 | SMI130_MAG_PRESETMODE_REGULAR
+* 3 | SMI130_MAG_PRESETMODE_HIGHACCURACY
+* 4 | SMI130_MAG_PRESETMODE_ENHANCED
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_bmm150_mag_presetmode(u8 v_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ switch (v_mode_u8) {
+ case SMI130_MAG_PRESETMODE_LOWPOWER:
+ /* write the XY and Z repetitions*/
+ /* The v_data_u8 have to write for the register
+ It write the value in the register 0x4F*/
+ com_rslt = smi130_set_mag_write_data(
+ SMI130_MAG_LOWPOWER_REPXY);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_XY_REP);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* write the Z repetitions*/
+ /* The v_data_u8 have to write for the register
+ It write the value in the register 0x4F*/
+ com_rslt += smi130_set_mag_write_data(
+ SMI130_MAG_LOWPOWER_REPZ);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_Z_REP);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* set the mag v_data_u8 rate as 10 to the register 0x4C*/
+ com_rslt += smi130_set_mag_write_data(
+ SMI130_MAG_LOWPOWER_DR);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_POWE_MODE_REG);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ break;
+ case SMI130_MAG_PRESETMODE_REGULAR:
+ /* write the XY and Z repetitions*/
+ /* The v_data_u8 have to write for the register
+ It write the value in the register 0x4F*/
+ com_rslt = smi130_set_mag_write_data(
+ SMI130_MAG_REGULAR_REPXY);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_XY_REP);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* write the Z repetitions*/
+ /* The v_data_u8 have to write for the register
+ It write the value in the register 0x4F*/
+ com_rslt += smi130_set_mag_write_data(
+ SMI130_MAG_REGULAR_REPZ);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_Z_REP);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* set the mag v_data_u8 rate as 10 to the register 0x4C*/
+ com_rslt += smi130_set_mag_write_data(
+ SMI130_MAG_REGULAR_DR);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_POWE_MODE_REG);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ break;
+ case SMI130_MAG_PRESETMODE_HIGHACCURACY:
+ /* write the XY and Z repetitions*/
+ /* The v_data_u8 have to write for the register
+ It write the value in the register 0x4F*/
+ com_rslt = smi130_set_mag_write_data(
+ SMI130_MAG_HIGHACCURACY_REPXY);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_XY_REP);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* write the Z repetitions*/
+ /* The v_data_u8 have to write for the register
+ It write the value in the register 0x4F*/
+ com_rslt += smi130_set_mag_write_data(
+ SMI130_MAG_HIGHACCURACY_REPZ);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_Z_REP);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* set the mag v_data_u8 rate as 20 to the register 0x4C*/
+ com_rslt += smi130_set_mag_write_data(
+ SMI130_MAG_HIGHACCURACY_DR);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_POWE_MODE_REG);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ break;
+ case SMI130_MAG_PRESETMODE_ENHANCED:
+ /* write the XY and Z repetitions*/
+ /* The v_data_u8 have to write for the register
+ It write the value in the register 0x4F*/
+ com_rslt = smi130_set_mag_write_data(
+ SMI130_MAG_ENHANCED_REPXY);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_XY_REP);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* write the Z repetitions*/
+ /* The v_data_u8 have to write for the register
+ It write the value in the register 0x4F*/
+ com_rslt += smi130_set_mag_write_data(
+ SMI130_MAG_ENHANCED_REPZ);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_Z_REP);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* set the mag v_data_u8 rate as 10 to the register 0x4C*/
+ com_rslt += smi130_set_mag_write_data(
+ SMI130_MAG_ENHANCED_DR);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_BMM150_POWE_MODE_REG);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+
+ return com_rslt;
+}
+ /*!
+* @brief This function used for read the trim values of magnetometer
+*
+* @note
+* Before reading the mag trimming values
+* make sure the following two points are addressed
+* @note
+* 1. Make sure the mag interface is enabled or not,
+* by using the smi130_get_if_mode() function.
+* If mag interface is not enabled set the value of 0x02
+* to the function smi130_get_if_mode(0x02)
+* @note
+* 2. And also confirm the secondary-interface power mode
+* is not in the SUSPEND mode.
+* by using the function smi130_get_mag_pmu_status().
+* If the secondary-interface power mode is in SUSPEND mode
+* set the value of 0x19(NORMAL mode)by using the
+* smi130_set_command_register(0x19) function.
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_bmm150_mag_trim(void)
+{
+ /* This variable used for provide the communication
+ results*/
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array holding the bmm150 trim data
+ */
+ u8 v_data_u8[SMI130_MAG_TRIM_DATA_SIZE] = {
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE};
+ /* read dig_x1 value*/
+ com_rslt = smi130_set_mag_read_addr(
+ SMI130_MAG_DIG_X1);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_X1],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ mag_trim.dig_x1 = v_data_u8[SMI130_BMM150_DIG_X1];
+ /* read dig_y1 value*/
+ com_rslt += smi130_set_mag_read_addr(
+ SMI130_MAG_DIG_Y1);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_Y1],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ mag_trim.dig_y1 = v_data_u8[SMI130_BMM150_DIG_Y1];
+
+ /* read dig_x2 value*/
+ com_rslt += smi130_set_mag_read_addr(
+ SMI130_MAG_DIG_X2);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_X2],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ mag_trim.dig_x2 = v_data_u8[SMI130_BMM150_DIG_X2];
+ /* read dig_y2 value*/
+ com_rslt += smi130_set_mag_read_addr(
+ SMI130_MAG_DIG_Y2);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_Y3],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ mag_trim.dig_y2 = v_data_u8[SMI130_BMM150_DIG_Y3];
+
+ /* read dig_xy1 value*/
+ com_rslt += smi130_set_mag_read_addr(
+ SMI130_MAG_DIG_XY1);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_XY1],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ mag_trim.dig_xy1 = v_data_u8[SMI130_BMM150_DIG_XY1];
+ /* read dig_xy2 value*/
+ com_rslt += smi130_set_mag_read_addr(
+ SMI130_MAG_DIG_XY2);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is v_mag_x_s16 ls register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_XY2],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ mag_trim.dig_xy2 = v_data_u8[SMI130_BMM150_DIG_XY2];
+
+ /* read dig_z1 lsb value*/
+ com_rslt += smi130_set_mag_read_addr(
+ SMI130_MAG_DIG_Z1_LSB);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_Z1_LSB],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* read dig_z1 msb value*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_MAG_DIG_Z1_MSB);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is v_mag_x_s16 msb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_Z1_MSB],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ mag_trim.dig_z1 =
+ (u16)((((u32)((u8)v_data_u8[SMI130_BMM150_DIG_Z1_MSB]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[SMI130_BMM150_DIG_Z1_LSB]));
+
+ /* read dig_z2 lsb value*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_MAG_DIG_Z2_LSB);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_Z2_LSB],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* read dig_z2 msb value*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_MAG_DIG_Z2_MSB);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is v_mag_x_s16 msb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_Z2_MSB],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ mag_trim.dig_z2 =
+ (s16)((((s32)((s8)v_data_u8[SMI130_BMM150_DIG_Z2_MSB]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[SMI130_BMM150_DIG_Z2_LSB]));
+
+ /* read dig_z3 lsb value*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_MAG_DIG_Z3_LSB);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_DIG_Z3_LSB],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* read dig_z3 msb value*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_MAG_DIG_Z3_MSB);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is v_mag_x_s16 msb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_DIG_Z3_MSB],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ mag_trim.dig_z3 =
+ (s16)((((s32)((s8)v_data_u8[SMI130_BMM150_DIG_DIG_Z3_MSB]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[SMI130_BMM150_DIG_DIG_Z3_LSB]));
+
+ /* read dig_z4 lsb value*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_MAG_DIG_Z4_LSB);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_DIG_Z4_LSB],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* read dig_z4 msb value*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_MAG_DIG_Z4_MSB);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is v_mag_x_s16 msb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_DIG_Z4_MSB],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ mag_trim.dig_z4 =
+ (s16)((((s32)((s8)v_data_u8[SMI130_BMM150_DIG_DIG_Z4_MSB]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[SMI130_BMM150_DIG_DIG_Z4_LSB]));
+
+ /* read dig_xyz1 lsb value*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_MAG_DIG_XYZ1_LSB);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_DIG_XYZ1_LSB],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* read dig_xyz1 msb value*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_MAG_DIG_XYZ1_MSB);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is v_mag_x_s16 msb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[SMI130_BMM150_DIG_DIG_XYZ1_MSB],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ mag_trim.dig_xyz1 =
+ (u16)((((u32)((u8)v_data_u8[SMI130_BMM150_DIG_DIG_XYZ1_MSB]))
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) |
+ (v_data_u8[SMI130_BMM150_DIG_DIG_XYZ1_LSB]));
+
+ return com_rslt;
+}
+ /*!
+* @brief This function used for initialize
+* the AKM09911 and AKM09912 sensor
+*
+*
+* @param v_akm_i2c_address_u8: The value of device address
+* AKM sensor | Slave address
+* --------------|---------------------
+* AKM09911 | AKM09911_I2C_ADDR_1
+* - | and AKM09911_I2C_ADDR_2
+* AKM09912 | AKM09912_I2C_ADDR_1
+* - | AKM09912_I2C_ADDR_2
+* - | AKM09912_I2C_ADDR_3
+* - | AKM09912_I2C_ADDR_4
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_akm_mag_interface_init(
+u8 v_akm_i2c_address_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_pull_value_u8 = SMI130_INIT_VALUE;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ u8 v_akm_chip_id_u8 = SMI130_INIT_VALUE;
+ /* accel operation mode to normal*/
+ com_rslt = smi130_set_command_register(ACCEL_MODE_NORMAL);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_command_register(MAG_MODE_NORMAL);
+ p_smi130->delay_msec(SMI130_AKM_INIT_DELAY);
+ smi130_get_mag_power_mode_stat(&v_data_u8);
+ /* register 0x7E write the 0x37, 0x9A and 0x30*/
+ com_rslt += smi130_set_command_register(SMI130_COMMAND_REG_ONE);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_command_register(SMI130_COMMAND_REG_TWO);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_command_register(SMI130_COMMAND_REG_THREE);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /*switch the page1*/
+ com_rslt += smi130_set_target_page(SMI130_WRITE_TARGET_PAGE1);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_target_page(&v_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_paging_enable(SMI130_WRITE_ENABLE_PAGE1);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_paging_enable(&v_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* enable the pullup configuration from
+ the register 0x05 bit 4 and 5 to 10*/
+ smi130_get_pullup_configuration(&v_pull_value_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ v_pull_value_u8 = v_pull_value_u8 | SMI130_PULL_UP_DATA;
+ com_rslt += smi130_set_pullup_configuration(v_pull_value_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+
+ /*switch the page0*/
+ com_rslt += smi130_set_target_page(SMI130_WRITE_TARGET_PAGE0);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_target_page(&v_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* Write the AKM09911 0r AKM09912 i2c address*/
+ com_rslt += smi130_set_i2c_device_addr(v_akm_i2c_address_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* enable the mag interface to manual mode*/
+ com_rslt += smi130_set_mag_manual_enable(SMI130_MANUAL_ENABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_mag_manual_enable(&v_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /*Enable the MAG interface*/
+ com_rslt += smi130_set_if_mode(SMI130_ENABLE_MAG_IF_MODE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_if_mode(&v_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+
+ /* Set the AKM Fuse ROM mode*/
+ /* Set value for fuse ROM mode*/
+ com_rslt += smi130_set_mag_write_data(AKM_FUSE_ROM_MODE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* AKM mode address is 0x31*/
+ com_rslt += smi130_set_mag_write_addr(AKM_POWER_MODE_REG);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* Read the Fuse ROM v_data_u8 from registers
+ 0x60,0x61 and 0x62*/
+ /* ASAX v_data_u8*/
+ com_rslt += smi130_read_bosch_akm_sensitivity_data();
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* read the device id of the AKM sensor
+ if device id is 0x05 - AKM09911
+ if device id is 0x04 - AKM09912*/
+ com_rslt += smi130_set_mag_read_addr(AKM09912_CHIP_ID_REG);
+ /* 0x04 is mag_x lsb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_akm_chip_id_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ printk(KERN_INFO "smi130,addr:0x%x, akm_chip_id:0x%x",
+ v_akm_i2c_address_u8, v_akm_chip_id_u8);
+ /* Set value power down mode mode*/
+ com_rslt += smi130_set_mag_write_data(AKM_POWER_DOWN_MODE_DATA);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* AKM mode address is 0x31*/
+ com_rslt += smi130_set_mag_write_addr(AKM_POWER_MODE_REG);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* Set AKM Force mode*/
+ com_rslt += smi130_set_mag_write_data(
+ AKM_SINGLE_MEASUREMENT_MODE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* AKM mode address is 0x31*/
+ com_rslt += smi130_set_mag_write_addr(AKM_POWER_MODE_REG);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* Set the AKM read xyz v_data_u8 address*/
+ com_rslt += smi130_set_mag_read_addr(AKM_DATA_REGISTER);
+ /* write the mag v_data_bw_u8 as 25Hz*/
+ com_rslt += smi130_set_mag_output_data_rate(
+ SMI130_MAG_OUTPUT_DATA_RATE_25HZ);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* Enable mag interface to auto mode*/
+ com_rslt += smi130_set_mag_manual_enable(SMI130_MANUAL_DISABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_mag_manual_enable(&v_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+
+ return com_rslt;
+}
+ /*!
+* @brief This function used for read the sensitivity data of
+* AKM09911 and AKM09912
+*
+* @note Before reading the mag sensitivity values
+* make sure the following two points are addressed
+* @note 1. Make sure the mag interface is enabled or not,
+* by using the smi130_get_if_mode() function.
+* If mag interface is not enabled set the value of 0x02
+* to the function smi130_get_if_mode(0x02)
+* @note 2. And also confirm the secondary-interface power mode
+* is not in the SUSPEND mode.
+* by using the function smi130_get_mag_pmu_status().
+* If the secondary-interface power mode is in SUSPEND mode
+* set the value of 0x19(NORMAL mode)by using the
+* smi130_set_command_register(0x19) function.
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_bosch_akm_sensitivity_data(void)
+{
+ /* This variable used for provide the communication
+ results*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array holding the sensitivity ax,ay and az data*/
+ u8 v_data_u8[SMI130_AKM_SENSITIVITY_DATA_SIZE] = {
+ SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ /* read asax value*/
+ com_rslt = smi130_set_mag_read_addr(SMI130_BST_AKM_ASAX);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[AKM_ASAX],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ akm_asa_data.asax = v_data_u8[AKM_ASAX];
+ /* read asay value*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_BST_AKM_ASAY);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[AKM_ASAY],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ akm_asa_data.asay = v_data_u8[AKM_ASAY];
+ /* read asaz value*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_BST_AKM_ASAZ);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[AKM_ASAZ],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ akm_asa_data.asaz = v_data_u8[AKM_ASAZ];
+
+ return com_rslt;
+}
+/*!
+* @brief This API used to get the compensated X data
+* of AKM09911 the out put of X as s32
+* @note Before start reading the mag compensated X data
+* make sure the following two points are addressed
+* @note 1. Make sure the mag interface is enabled or not,
+* by using the smi130_get_if_mode() function.
+* If mag interface is not enabled set the value of 0x02
+* to the function smi130_get_if_mode(0x02)
+* @note 2. And also confirm the secondary-interface power mode
+* is not in the SUSPEND mode.
+* by using the function smi130_get_mag_pmu_status().
+* If the secondary-interface power mode is in SUSPEND mode
+* set the value of 0x19(NORMAL mode)by using the
+* smi130_set_command_register(0x19) function.
+*
+*
+* @param v_bosch_akm_x_s16 : The value of X data
+*
+* @return results of compensated X data value output as s32
+*
+*/
+s32 smi130_bosch_akm09911_compensate_X(s16 v_bosch_akm_x_s16)
+{
+ /*Return value of AKM x compensated v_data_u8*/
+ s32 retval = SMI130_INIT_VALUE;
+ /* Convert raw v_data_u8 into compensated v_data_u8*/
+ retval = (v_bosch_akm_x_s16*
+ ((akm_asa_data.asax/AKM09911_SENSITIVITY_DIV) +
+ SMI130_GEN_READ_WRITE_DATA_LENGTH));
+ return retval;
+}
+/*!
+* @brief This API used to get the compensated Y data
+* of AKM09911 the out put of Y as s32
+* @note Before start reading the mag compensated Y data
+* make sure the following two points are addressed
+* @note 1. Make sure the mag interface is enabled or not,
+* by using the smi130_get_if_mode() function.
+* If mag interface is not enabled set the value of 0x02
+* to the function smi130_get_if_mode(0x02)
+* @note 2. And also confirm the secondary-interface power mode
+* is not in the SUSPEND mode.
+* by using the function smi130_get_mag_pmu_status().
+* If the secondary-interface power mode is in SUSPEND mode
+* set the value of 0x19(NORMAL mode)by using the
+* smi130_set_command_register(0x19) function.
+*
+*
+* @param v_bosch_akm_y_s16 : The value of Y data
+*
+* @return results of compensated Y data value output as s32
+*
+*/
+s32 smi130_bosch_akm09911_compensate_Y(s16 v_bosch_akm_y_s16)
+{
+ /*Return value of AKM y compensated v_data_u8*/
+ s32 retval = SMI130_INIT_VALUE;
+ /* Convert raw v_data_u8 into compensated v_data_u8*/
+ retval = (v_bosch_akm_y_s16*
+ ((akm_asa_data.asay/AKM09911_SENSITIVITY_DIV) +
+ SMI130_GEN_READ_WRITE_DATA_LENGTH));
+ return retval;
+}
+/*!
+* @brief This API used to get the compensated Z data
+* of AKM09911 the out put of Z as s32
+* @note Before start reading the mag compensated Z data
+* make sure the following two points are addressed
+* @note 1. Make sure the mag interface is enabled or not,
+* by using the smi130_get_if_mode() function.
+* If mag interface is not enabled set the value of 0x02
+* to the function smi130_get_if_mode(0x02)
+* @note 2. And also confirm the secondary-interface power mode
+* is not in the SUSPEND mode.
+* by using the function smi130_get_mag_pmu_status().
+* If the secondary-interface power mode is in SUSPEND mode
+* set the value of 0x19(NORMAL mode)by using the
+* smi130_set_command_register(0x19) function.
+*
+*
+* @param v_bosch_akm_z_s16 : The value of Z data
+*
+* @return results of compensated Z data value output as s32
+*
+*/
+s32 smi130_bosch_akm09911_compensate_Z(s16 v_bosch_akm_z_s16)
+{
+ /*Return value of AKM z compensated v_data_u8*/
+ s32 retval = SMI130_INIT_VALUE;
+ /* Convert raw v_data_u8 into compensated v_data_u8*/
+ retval = (v_bosch_akm_z_s16*
+ ((akm_asa_data.asaz/AKM09911_SENSITIVITY_DIV) +
+ SMI130_GEN_READ_WRITE_DATA_LENGTH));
+ return retval;
+}
+/*!
+* @brief This API used to get the compensated X data
+* of AKM09912 the out put of X as s32
+* @note Before start reading the mag compensated X data
+* make sure the following two points are addressed
+* @note 1. Make sure the mag interface is enabled or not,
+* by using the smi130_get_if_mode() function.
+* If mag interface is not enabled set the value of 0x02
+* to the function smi130_get_if_mode(0x02)
+* @note 2. And also confirm the secondary-interface power mode
+* is not in the SUSPEND mode.
+* by using the function smi130_get_mag_pmu_status().
+* If the secondary-interface power mode is in SUSPEND mode
+* set the value of 0x19(NORMAL mode)by using the
+* smi130_set_command_register(0x19) function.
+*
+*
+* @param v_bosch_akm_x_s16 : The value of X data
+*
+* @return results of compensated X data value output as s32
+*
+*/
+s32 smi130_bosch_akm09912_compensate_X(s16 v_bosch_akm_x_s16)
+{
+ /*Return value of AKM x compensated data*/
+ s32 retval = SMI130_INIT_VALUE;
+ /* Convert raw data into compensated data*/
+ retval = v_bosch_akm_x_s16*
+ (akm_asa_data.asax + AKM09912_SENSITIVITY)
+ / AKM09912_SENSITIVITY_DIV;
+ return retval;
+}
+/*!
+* @brief This API used to get the compensated Y data
+* of AKM09912 the out put of Y as s32
+* @note Before start reading the mag compensated Y data
+* make sure the following two points are addressed
+* @note 1. Make sure the mag interface is enabled or not,
+* by using the smi130_get_if_mode() function.
+* If mag interface is not enabled set the value of 0x02
+* to the function smi130_get_if_mode(0x02)
+* @note 2. And also confirm the secondary-interface power mode
+* is not in the SUSPEND mode.
+* by using the function smi130_get_mag_pmu_status().
+* If the secondary-interface power mode is in SUSPEND mode
+* set the value of 0x19(NORMAL mode)by using the
+* smi130_set_command_register(0x19) function.
+*
+*
+* @param v_bosch_akm_y_s16 : The value of Y data
+*
+* @return results of compensated Y data value output as s32
+*
+*/
+s32 smi130_bosch_akm09912_compensate_Y(s16 v_bosch_akm_y_s16)
+{
+ /*Return value of AKM y compensated data*/
+ s32 retval = SMI130_INIT_VALUE;
+ /* Convert raw data into compensated data*/
+ retval = v_bosch_akm_y_s16*
+ (akm_asa_data.asax + AKM09912_SENSITIVITY)
+ / AKM09912_SENSITIVITY_DIV;
+ return retval;
+}
+/*!
+* @brief This API used to get the compensated Z data
+* of AKM09912 the out put of Z as s32
+* @note Before start reading the mag compensated Z data
+* make sure the following two points are addressed
+* @note 1. Make sure the mag interface is enabled or not,
+* by using the smi130_get_if_mode() function.
+* If mag interface is not enabled set the value of 0x02
+* to the function smi130_get_if_mode(0x02)
+* @note 2. And also confirm the secondary-interface power mode
+* is not in the SUSPEND mode.
+* by using the function smi130_get_mag_pmu_status().
+* If the secondary-interface power mode is in SUSPEND mode
+* set the value of 0x19(NORMAL mode)by using the
+* smi130_set_command_register(0x19) function.
+*
+*
+* @param v_bosch_akm_z_s16 : The value of Z data
+*
+* @return results of compensated Z data value output as s32
+*
+*/
+s32 smi130_bosch_akm09912_compensate_Z(s16 v_bosch_akm_z_s16)
+{
+ /*Return value of AKM z compensated data*/
+ s32 retval = SMI130_INIT_VALUE;
+ /* Convert raw data into compensated data*/
+ retval = v_bosch_akm_z_s16*
+ (akm_asa_data.asax + AKM09912_SENSITIVITY)
+ / AKM09912_SENSITIVITY_DIV;
+ return retval;
+}
+ /*!
+* @brief This function used for read the compensated value of
+* AKM09911
+* @note Before start reading the mag compensated data's
+* make sure the following two points are addressed
+* @note 1. Make sure the mag interface is enabled or not,
+* by using the smi130_get_if_mode() function.
+* If mag interface is not enabled set the value of 0x02
+* to the function smi130_get_if_mode(0x02)
+* @note 2. And also confirm the secondary-interface power mode
+* is not in the SUSPEND mode.
+* by using the function smi130_get_mag_pmu_status().
+* If the secondary-interface power mode is in SUSPEND mode
+* set the value of 0x19(NORMAL mode)by using the
+* smi130_set_command_register(0x19) function.
+
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_akm09911_compensate_xyz(
+struct smi130_mag_xyz_s32_t*bosch_akm_xyz)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ struct smi130_mag_t mag_xyz;
+
+ com_rslt = smi130_read_mag_xyz(&mag_xyz, BST_AKM);
+ /* Compensation for X axis*/
+ bosch_akm_xyz->x = smi130_bosch_akm09911_compensate_X(mag_xyz.x);
+
+ /* Compensation for Y axis*/
+ bosch_akm_xyz->y = smi130_bosch_akm09911_compensate_Y(mag_xyz.y);
+
+ /* Compensation for Z axis*/
+ bosch_akm_xyz->z = smi130_bosch_akm09911_compensate_Z(mag_xyz.z);
+
+ return com_rslt;
+}
+ /*!
+* @brief This function used for read the compensated value of
+* AKM09912
+* @note Before start reading the mag compensated data's
+* make sure the following two points are addressed
+* @note 1. Make sure the mag interface is enabled or not,
+* by using the smi130_get_if_mode() function.
+* If mag interface is not enabled set the value of 0x02
+* to the function smi130_get_if_mode(0x02)
+* @note 2. And also confirm the secondary-interface power mode
+* is not in the SUSPEND mode.
+* by using the function smi130_get_mag_pmu_status().
+* If the secondary-interface power mode is in SUSPEND mode
+* set the value of 0x19(NORMAL mode)by using the
+* smi130_set_command_register(0x19) function.
+
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_akm09912_compensate_xyz(
+struct smi130_mag_xyz_s32_t*bosch_akm_xyz)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ struct smi130_mag_t mag_xyz;
+
+ com_rslt = smi130_read_mag_xyz(&mag_xyz, BST_AKM);
+ printk(KERN_INFO "akm09912_raw_x:%d, %d, %d, <%s>,<%d>",
+ mag_xyz.x, mag_xyz.y, mag_xyz.z, __func__, __LINE__);
+ /* Compensation for X axis*/
+ bosch_akm_xyz->x = smi130_bosch_akm09912_compensate_X(mag_xyz.x);
+
+ /* Compensation for Y axis*/
+ bosch_akm_xyz->y = smi130_bosch_akm09912_compensate_Y(mag_xyz.y);
+
+ /* Compensation for Z axis*/
+ bosch_akm_xyz->z = smi130_bosch_akm09912_compensate_Z(mag_xyz.z);
+ return com_rslt;
+}
+ /*!
+* @brief This function used for read the compensated value of
+* AKM09912
+* @note Before start reading the mag compensated data's
+* make sure the following two points are addressed
+* @note 1. Make sure the mag interface is enabled or not,
+* by using the smi130_get_if_mode() function.
+* If mag interface is not enabled set the value of 0x02
+* to the function smi130_get_if_mode(0x02)
+* @note 2. And also confirm the secondary-interface power mode
+* is not in the SUSPEND mode.
+* by using the function smi130_get_mag_pmu_status().
+* If the secondary-interface power mode is in SUSPEND mode
+* set the value of 0x19(NORMAL mode)by using the
+* smi130_set_command_register(0x19) function.
+
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_akm09912_compensate_xyz_raw(
+struct smi130_mag_xyz_s32_t*bosch_akm_xyz)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Compensation for X axis*/
+ bosch_akm_xyz->x = smi130_bosch_akm09912_compensate_X(bosch_akm_xyz->x);
+
+ /* Compensation for Y axis*/
+ bosch_akm_xyz->y = smi130_bosch_akm09912_compensate_Y(bosch_akm_xyz->y);
+
+ /* Compensation for Z axis*/
+ bosch_akm_xyz->z = smi130_bosch_akm09912_compensate_Z(bosch_akm_xyz->z);
+
+ return com_rslt;
+}
+/*!
+* @brief This function used for set the AKM09911 and AKM09912
+* power mode.
+* @note Before set the AKM power mode
+* make sure the following two points are addressed
+* @note 1. Make sure the mag interface is enabled or not,
+* by using the smi130_get_if_mode() function.
+* If mag interface is not enabled set the value of 0x02
+* to the function smi130_get_if_mode(0x02)
+* @note 2. And also confirm the secondary-interface power mode
+* is not in the SUSPEND mode.
+* by using the function smi130_get_mag_pmu_status().
+* If the secondary-interface power mode is in SUSPEND mode
+* set the value of 0x19(NORMAL mode)by using the
+* smi130_set_command_register(0x19) function.
+*
+* @param v_akm_pow_mode_u8 : The value of akm power mode
+* value | Description
+* ---------|--------------------
+* 0 | AKM_POWER_DOWN_MODE
+* 1 | AKM_SINGLE_MEAS_MODE
+* 2 | FUSE_ROM_MODE
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_akm_set_powermode(
+u8 v_akm_pow_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = SMI130_INIT_VALUE;
+ /* set mag interface manual mode*/
+ if (p_smi130->mag_manual_enable != SMI130_MANUAL_ENABLE) {
+ com_rslt = smi130_set_mag_manual_enable(
+ SMI130_MANUAL_ENABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ }
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s>\n",
+ com_rslt, p_smi130->mag_manual_enable, __func__);
+ switch (v_akm_pow_mode_u8) {
+ case AKM_POWER_DOWN_MODE:
+ /* Set the power mode of AKM as power down mode*/
+ com_rslt += smi130_set_mag_write_data(AKM_POWER_DOWN_MODE_DATA);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(AKM_POWER_MODE_REG);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ break;
+ case AKM_SINGLE_MEAS_MODE:
+ /* Set the power mode of AKM as
+ single measurement mode*/
+ com_rslt += smi130_set_mag_write_data
+ (AKM_SINGLE_MEASUREMENT_MODE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(AKM_POWER_MODE_REG);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_read_addr(AKM_DATA_REGISTER);
+ break;
+ case FUSE_ROM_MODE:
+ /* Set the power mode of AKM as
+ Fuse ROM mode*/
+ com_rslt += smi130_set_mag_write_data(AKM_FUSE_ROM_MODE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(AKM_POWER_MODE_REG);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* Sensitivity v_data_u8*/
+ com_rslt += smi130_read_bosch_akm_sensitivity_data();
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* power down mode*/
+ com_rslt += smi130_set_mag_write_data(AKM_POWER_DOWN_MODE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(AKM_POWER_MODE_REG);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ /* set mag interface auto mode*/
+ if (p_smi130->mag_manual_enable == SMI130_MANUAL_ENABLE) {
+ com_rslt += smi130_set_mag_manual_enable(
+ SMI130_MANUAL_DISABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ }
+ printk(KERN_INFO "com_rslt:%d, manual:%d, <%s><%d>\n",
+ com_rslt, p_smi130->mag_manual_enable, __func__, __LINE__);
+ return com_rslt;
+}
+ /*!
+* @brief This function used for set the magnetometer
+* power mode of AKM09911 and AKM09912
+* @note Before set the mag power mode
+* make sure the following two point is addressed
+* Make sure the mag interface is enabled or not,
+* by using the smi130_get_if_mode() function.
+* If mag interface is not enabled set the value of 0x02
+* to the function smi130_get_if_mode(0x02)
+*
+* @param v_mag_sec_if_pow_mode_u8 : The value of secondary if power mode
+* value | Description
+* ---------|--------------------
+* 0 | SMI130_MAG_FORCE_MODE
+* 1 | SMI130_MAG_SUSPEND_MODE
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_bosch_akm_and_secondary_if_powermode(
+u8 v_mag_sec_if_pow_mode_u8)
+{
+ /* variable used for return the status of communication result*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* accel operation mode to normal*/
+ com_rslt = smi130_set_command_register(ACCEL_MODE_NORMAL);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* set mag interface manual mode*/
+ if (p_smi130->mag_manual_enable != SMI130_MANUAL_ENABLE) {
+ com_rslt = smi130_set_mag_manual_enable(
+ SMI130_MANUAL_ENABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ }
+ printk(KERN_ERR "com_rslt:%d, manual:%d,after setacc normal mode\n",
+ com_rslt, p_smi130->mag_manual_enable);
+ switch (v_mag_sec_if_pow_mode_u8) {
+ case SMI130_MAG_FORCE_MODE:
+ /* set the secondary mag power mode as NORMAL*/
+ com_rslt += smi130_set_mag_interface_normal();
+ /* set the akm power mode as single measurement mode*/
+ com_rslt += smi130_bosch_akm_set_powermode(AKM_SINGLE_MEAS_MODE);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_read_addr(AKM_DATA_REGISTER);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ break;
+ case SMI130_MAG_SUSPEND_MODE:
+ /* set the akm power mode as power down mode*/
+ com_rslt += smi130_bosch_akm_set_powermode(AKM_POWER_DOWN_MODE);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* set the secondary mag power mode as SUSPEND*/
+ com_rslt += smi130_set_command_register(MAG_MODE_SUSPEND);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ break;
+ default:
+ com_rslt = E_SMI130_OUT_OF_RANGE;
+ break;
+ }
+ /* set mag interface auto mode*/
+ if (p_smi130->mag_manual_enable == SMI130_MANUAL_ENABLE)
+ com_rslt += smi130_set_mag_manual_enable(
+ SMI130_MANUAL_DISABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ return com_rslt;
+}
+/*!
+* @brief This function used for read the YAMAH-YAS532 init
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yamaha_yas532_mag_interface_init(
+void)
+{
+ /* This variable used for provide the communication
+ results*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ u8 v_pull_value_u8 = SMI130_INIT_VALUE;
+ u8 v_data_u8 = SMI130_INIT_VALUE;
+ u8 i = SMI130_INIT_VALUE;
+ /* accel operation mode to normal*/
+ com_rslt = smi130_set_command_register(ACCEL_MODE_NORMAL);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* write mag power mode as NORMAL*/
+ com_rslt += smi130_set_mag_interface_normal();
+ /* register 0x7E write the 0x37, 0x9A and 0x30*/
+ com_rslt += smi130_set_command_register(SMI130_COMMAND_REG_ONE);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_command_register(SMI130_COMMAND_REG_TWO);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_command_register(SMI130_COMMAND_REG_THREE);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /*switch the page1*/
+ com_rslt += smi130_set_target_page(SMI130_WRITE_TARGET_PAGE1);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_target_page(&v_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_paging_enable(SMI130_WRITE_ENABLE_PAGE1);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_paging_enable(&v_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* enable the pullup configuration from
+ the register 0x05 bit 4 and 5 as 10*/
+ smi130_get_pullup_configuration(&v_pull_value_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ v_pull_value_u8 = v_pull_value_u8 | SMI130_PULL_UP_DATA;
+ com_rslt += smi130_set_pullup_configuration(v_pull_value_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /*switch the page0*/
+ com_rslt += smi130_set_target_page(SMI130_WRITE_TARGET_PAGE0);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_target_page(&v_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* Write the YAS532 i2c address*/
+ com_rslt += smi130_set_i2c_device_addr(SMI130_AUX_YAS532_I2C_ADDRESS);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* enable the mag interface to manual mode*/
+ com_rslt += smi130_set_mag_manual_enable(SMI130_MANUAL_ENABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_mag_manual_enable(&v_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /*Enable the MAG interface*/
+ com_rslt += smi130_set_if_mode(SMI130_ENABLE_MAG_IF_MODE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_if_mode(&v_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ v_data_u8 = SMI130_MANUAL_DISABLE;
+ /* Read the YAS532 device id is 0x02*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_YAS_DEVICE_ID_REG);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* Read the YAS532 calibration data*/
+ com_rslt += smi130_bosch_yamaha_yas532_calib_values();
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* Assign the data acquisition mode*/
+ yas532_data.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 = SMI130_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 += smi130_bosch_yas532_set_initial_values();
+ /* write the mag v_data_bw_u8 as 25Hz*/
+ com_rslt += smi130_set_mag_output_data_rate(
+ SMI130_MAG_OUTPUT_DATA_RATE_25HZ);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* Enable mag interface to auto mode*/
+ com_rslt += smi130_set_mag_manual_enable(
+ SMI130_MANUAL_DISABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ smi130_get_mag_manual_enable(&v_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+
+ return com_rslt;
+}
+/*!
+* @brief This function used to set the YAS532 initial values
+*
+*
+ * @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas532_set_initial_values(void)
+{
+/* This variable used for provide the communication
+ results*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* write testr1 as 0x00*/
+ com_rslt = smi130_set_mag_write_data(
+ SMI130_YAS532_WRITE_TESTR1);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(SMI130_YAS532_TESTR1);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* write testr2 as 0x00*/
+ com_rslt += smi130_set_mag_write_data(
+ SMI130_YAS532_WRITE_TESTR2);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(SMI130_YAS532_TESTR2);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* write Rcoil as 0x00*/
+ com_rslt += smi130_set_mag_write_data(
+ SMI130_YAS532_WRITE_RCOIL);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(SMI130_YAS532_RCOIL);
+ p_smi130->delay_msec(SMI130_YAS532_SET_INITIAL_VALUE_DELAY);
+ /* check the valid offset*/
+ if (is_valid_offset(yas532_data.v_hard_offset_s8)) {
+ com_rslt += smi130_bosch_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
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas532_magnetic_measure_set_offset(
+void)
+{
+ /* This variable used for provide the communication
+ results*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* used for offset value set to the offset register*/
+ s8 v_hard_offset_s8[SMI130_HARD_OFFSET_DATA_SIZE] = {
+ SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ /* offset correction factors*/
+ static const u8 v_correct_u8[SMI130_YAS_CORRECT_DATA_SIZE] = {
+ 16, 8, 4, 2, 1};
+ /* used for the temperature*/
+ u16 v_temp_u16 = SMI130_INIT_VALUE;
+ /* used for the xy1y2 read*/
+ u16 v_xy1y2_u16[SMI130_YAS_XY1Y2_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ /* local flag for assign the values*/
+ s32 v_flag_s32[SMI130_YAS_FLAG_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ u8 i, j, v_busy_u8, v_overflow_u8 = SMI130_INIT_VALUE;
+
+ for (i = 0; i < 5; i++) {
+ /* set the offset values*/
+ com_rslt = smi130_bosch_yas532_set_offset(v_hard_offset_s8);
+ /* read the sensor data*/
+ com_rslt += smi130_bosch_yas532_normal_measurement_data(
+ SMI130_YAS532_ACQ_START, &v_busy_u8, &v_temp_u16,
+ v_xy1y2_u16, &v_overflow_u8);
+ /* check the sensor busy status*/
+ if (v_busy_u8)
+ return E_SMI130_BUSY;
+ /* calculate the magnetic correction with
+ offset and assign the values
+ to the offset register*/
+ for (j = 0; j < 3; j++) {
+ if (YAS532_DATA_CENTER == v_xy1y2_u16[j])
+ v_flag_s32[j] = 0;
+ if (YAS532_DATA_CENTER < v_xy1y2_u16[j])
+ v_flag_s32[j] = 1;
+ if (v_xy1y2_u16[j] < YAS532_DATA_CENTER)
+ v_flag_s32[j] = -1;
+ }
+ for (j = 0; j < 3; j++) {
+ if (v_flag_s32[j])
+ v_hard_offset_s8[j] = (s8)(v_hard_offset_s8[j]
+ + v_flag_s32[j]* v_correct_u8[i]);
+ }
+ }
+ /* set the offset*/
+ com_rslt += smi130_bosch_yas532_set_offset(v_hard_offset_s8);
+ return com_rslt;
+}
+/*!
+* @brief This function used for read the
+* YAMAHA YAS532 calibration data
+*
+*
+ * @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yamaha_yas532_calib_values(void)
+{
+ /* This variable used for provide the communication
+ results*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array holding the YAS532 calibration values*/
+ u8 v_data_u8[SMI130_YAS532_CALIB_DATA_SIZE] = {
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ /* Read the DX value*/
+ com_rslt = smi130_set_mag_read_addr(SMI130_YAS532_CALIB_CX);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* 0x04 is secondary read mag x lsb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[0], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ yas532_data.calib_yas532.cx = (s32)((v_data_u8[0]
+ * 10) - 1280);
+ /* Read the DY1 value*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_YAS532_CALIB_CY1);
+ /* 0x04 is secondary read mag x lsb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[1], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ yas532_data.calib_yas532.cy1 =
+ (s32)((v_data_u8[1]* 10) - 1280);
+ /* Read the DY2 value*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_YAS532_CALIB_CY2);
+ /* 0x04 is secondary read mag x lsb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[2], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ yas532_data.calib_yas532.cy2 =
+ (s32)((v_data_u8[2]* 10) - 1280);
+ /* Read the D2 and D3 value*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_YAS532_CALIB1);
+ /* 0x04 is secondary read mag x lsb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[3], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ yas532_data.calib_yas532.a2 =
+ (s32)(((v_data_u8[3] >>
+ SMI130_SHIFT_BIT_POSITION_BY_02_BITS)
+ & 0x03F) - 32);
+ /* Read the D3 and D4 value*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_YAS532_CALIB2);
+ /* 0x04 is secondary read mag x lsb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[4], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ /* calculate a3*/
+ yas532_data.calib_yas532.a3 = (s32)((((v_data_u8[3] <<
+ SMI130_SHIFT_BIT_POSITION_BY_02_BITS) & 0x0C) |
+ ((v_data_u8[4]
+ >> SMI130_SHIFT_BIT_POSITION_BY_06_BITS)
+ & 0x03)) - 8);
+ /* calculate a4*/
+ yas532_data.calib_yas532.a4 = (s32)((v_data_u8[4]
+ & 0x3F) - 32);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* Read the D5 and D6 value*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_YAS532_CALIB3);
+ /* 0x04 is secondary read mag x lsb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[5], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ /* calculate a5*/
+ yas532_data.calib_yas532.a5 =
+ (s32)(((v_data_u8[5]
+ >> SMI130_SHIFT_BIT_POSITION_BY_02_BITS)
+ & 0x3F) + 38);
+ /* Read the D6 and D7 value*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_YAS532_CALIB4);
+ /* 0x04 is secondary read mag x lsb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[6], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ /* calculate a6*/
+ yas532_data.calib_yas532.a6 =
+ (s32)((((v_data_u8[5]
+ << SMI130_SHIFT_BIT_POSITION_BY_04_BITS)
+ & 0x30) | ((v_data_u8[6] >>
+ SMI130_SHIFT_BIT_POSITION_BY_04_BITS)
+ & 0x0F)) - 32);
+ /* Read the D7 and D8 value*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_YAS532_CALIB5);
+ /* 0x04 is secondary read mag x lsb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[7], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ /* calculate a7*/
+ yas532_data.calib_yas532.a7 = (s32)((((v_data_u8[6]
+ << SMI130_SHIFT_BIT_POSITION_BY_03_BITS)
+ & 0x78) |
+ ((v_data_u8[7]
+ >> SMI130_SHIFT_BIT_POSITION_BY_05_BITS) &
+ 0x07)) - 64);
+ /* Read the D8 and D9 value*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_YAS532_CLAIB6);
+ /* 0x04 is secondary read mag x lsb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[8], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ /* calculate a8*/
+ yas532_data.calib_yas532.a8 = (s32)((((v_data_u8[7] <<
+ SMI130_GEN_READ_WRITE_DATA_LENGTH) & 0x3E) |
+ ((v_data_u8[8] >>
+ SMI130_SHIFT_BIT_POSITION_BY_07_BITS) & 0x01)) -
+ 32);
+
+ /* Read the D8 and D9 value*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_YAS532_CALIB7);
+ /* 0x04 is secondary read mag x lsb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[9], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ /* calculate a9*/
+ yas532_data.calib_yas532.a9 = (s32)(((v_data_u8[8] <<
+ SMI130_GEN_READ_WRITE_DATA_LENGTH) & 0xFE) |
+ ((v_data_u8[9] >>
+ SMI130_SHIFT_BIT_POSITION_BY_07_BITS) & 0x01));
+ /* calculate k*/
+ yas532_data.calib_yas532.k = (s32)((v_data_u8[9] >>
+ SMI130_SHIFT_BIT_POSITION_BY_02_BITS) & 0x1F);
+ /* Read the value from register 0x9A*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_YAS532_CALIB8);
+ /* 0x04 is secondary read mag x lsb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[10],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ /* Read the value from register 0x9B*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_YAS532_CALIIB9);
+ /* 0x04 is secondary read mag x lsb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[11],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ /* Read the value from register 0x9C*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_YAS532_CALIB10);
+ /* 0x04 is secondary read mag x lsb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[12],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ /* Read the value from register 0x9D*/
+ com_rslt += smi130_set_mag_read_addr(SMI130_YAS532_CALIB11);
+ /* 0x04 is secondary read mag x lsb register*/
+ com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+ &v_data_u8[13],
+ SMI130_GEN_READ_WRITE_DATA_LENGTH);
+ /* Calculate the fxy1y2 and rxy1y1*/
+ yas532_data.calib_yas532.fxy1y2[0] =
+ (u8)(((v_data_u8[10]
+ & 0x01)
+ << SMI130_SHIFT_BIT_POSITION_BY_01_BIT)
+ | ((v_data_u8[11] >>
+ SMI130_SHIFT_BIT_POSITION_BY_07_BITS) & 0x01));
+ yas532_data.calib_yas532.rxy1y2[0] =
+ ((s8)(((v_data_u8[10]
+ >> SMI130_SHIFT_BIT_POSITION_BY_01_BIT) & 0x3F)
+ << SMI130_SHIFT_BIT_POSITION_BY_02_BITS))
+ >> SMI130_SHIFT_BIT_POSITION_BY_02_BITS;
+ yas532_data.calib_yas532.fxy1y2[1] =
+ (u8)(((v_data_u8[11] & 0x01)
+ << SMI130_SHIFT_BIT_POSITION_BY_01_BIT)
+ | ((v_data_u8[12] >>
+ SMI130_SHIFT_BIT_POSITION_BY_07_BITS) & 0x01));
+ yas532_data.calib_yas532.rxy1y2[1] =
+ ((s8)(((v_data_u8[11]
+ >> SMI130_SHIFT_BIT_POSITION_BY_01_BIT) & 0x3F)
+ << SMI130_SHIFT_BIT_POSITION_BY_02_BITS))
+ >> SMI130_SHIFT_BIT_POSITION_BY_02_BITS;
+ yas532_data.calib_yas532.fxy1y2[2] =
+ (u8)(((v_data_u8[12] & 0x01)
+ << SMI130_SHIFT_BIT_POSITION_BY_01_BIT)
+ | ((v_data_u8[13]
+ >> SMI130_SHIFT_BIT_POSITION_BY_07_BITS) & 0x01));
+ yas532_data.calib_yas532.rxy1y2[2] =
+ ((s8)(((v_data_u8[12]
+ >> SMI130_SHIFT_BIT_POSITION_BY_01_BIT) & 0x3F)
+ << SMI130_SHIFT_BIT_POSITION_BY_02_BITS))
+ >> SMI130_SHIFT_BIT_POSITION_BY_02_BITS;
+
+ return com_rslt;
+}
+/*!
+* @brief This function used for calculate the
+* YAS532 read the linear data
+*
+*
+ * @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas532_xy1y2_to_linear(
+u16*v_xy1y2_u16, s32*xy1y2_linear)
+{
+ /* This variable used for provide the communication
+ results*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = SUCCESS;
+ static const u16 v_calib_data[] = {
+ 3721, 3971, 4221, 4471};
+ u8 i = SMI130_INIT_VALUE;
+
+ for (i = 0; i < 3; i++)
+ xy1y2_linear[i] = v_xy1y2_u16[i] -
+ v_calib_data[yas532_data.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
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas532_normal_measurement_data(
+u8 v_acquisition_command_u8, u8*v_busy_u8,
+u16*v_temp_u16, u16*v_xy1y2_u16, u8*v_overflow_u8)
+{
+ /* This variable used for provide the communication
+ results*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = SMI130_INIT_VALUE;
+ /* Array holding the YAS532 xyy1 data*/
+ u8 v_data_u8[SMI130_YAS_XY1Y2T_DATA_SIZE] = {
+ SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ u8 i = SMI130_INIT_VALUE;
+ /* check the p_smi130 structure as NULL*/
+ if (p_smi130 == SMI130_NULL) {
+ return E_SMI130_NULL_PTR;
+ } else {
+ /* read the sensor data*/
+ com_rslt = smi130_bosch_yas532_acquisition_command_register(
+ v_acquisition_command_u8);
+ com_rslt +=
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_DATA_MAG_X_LSB__REG,
+ v_data_u8, SMI130_MAG_YAS_DATA_LENGTH);
+ /* read the xyy1 data*/
+ *v_busy_u8 =
+ ((v_data_u8[0]
+ >> SMI130_SHIFT_BIT_POSITION_BY_07_BITS) & 0x01);
+ *v_temp_u16 =
+ (u16)((((s32)v_data_u8[0]
+ << SMI130_SHIFT_BIT_POSITION_BY_03_BITS)
+ & 0x3F8) | ((v_data_u8[1]
+ >> SMI130_SHIFT_BIT_POSITION_BY_05_BITS) & 0x07));
+ v_xy1y2_u16[0] =
+ (u16)((((s32)v_data_u8[2]
+ << SMI130_SHIFT_BIT_POSITION_BY_06_BITS) & 0x1FC0)
+ | ((v_data_u8[3] >>
+ SMI130_SHIFT_BIT_POSITION_BY_02_BITS) & 0x3F));
+ v_xy1y2_u16[1] =
+ (u16)((((s32)v_data_u8[4]
+ << SMI130_SHIFT_BIT_POSITION_BY_06_BITS)
+ & 0x1FC0)
+ | ((v_data_u8[5]
+ >> SMI130_SHIFT_BIT_POSITION_BY_02_BITS) & 0x3F));
+ v_xy1y2_u16[2] =
+ (u16)((((s32)v_data_u8[6]
+ << SMI130_SHIFT_BIT_POSITION_BY_06_BITS)
+ & 0x1FC0)
+ | ((v_data_u8[7]
+ >> SMI130_SHIFT_BIT_POSITION_BY_02_BITS) & 0x3F));
+ *v_overflow_u8 = 0;
+ for (i = 0; i < 3; i++) {
+ if (v_xy1y2_u16[i] == YAS532_DATA_OVERFLOW)
+ *v_overflow_u8 |= (1 << (i* 2));
+ if (v_xy1y2_u16[i] == YAS532_DATA_UNDERFLOW)
+ *v_overflow_u8 |= (1 << (i* 2 + 1));
+ }
+ }
+ return com_rslt;
+}
+/*!
+* @brief This function used for YAS532 sensor data
+* @param v_acquisition_command_u8 : the value of CMDR
+* acquisition_command | operation
+* ---------------------|-------------------------
+* 0x17 | turn on the acquisition coil
+* - | set direction of the coil
+* _ | (x and y as minus(-))
+* _ | Deferred acquisition mode
+* 0x07 | turn on the acquisition coil
+* _ | set direction of the coil
+* _ | (x and y as minus(-))
+* _ | Normal acquisition mode
+* 0x11 | turn OFF the acquisition coil
+* _ | set direction of the coil
+* _ | (x and y as plus(+))
+* _ | Deferred acquisition mode
+* 0x01 | turn OFF the acquisition coil
+* _ | set direction of the coil
+* _ | (x and y as plus(+))
+* _ | Normal acquisition mode
+*
+* @param xyz_data : the vector xyz output
+* @param v_overflow_s8 : the value of overflow
+* @param v_temp_correction_u8 : the value of temperate correction enable
+*
+*
+ * @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas532_measurement_xyz_data(
+struct yas532_vector*xyz_data, u8*v_overflow_s8, u8 v_temp_correction_u8,
+u8 v_acquisition_command_u8)
+{
+ /* This variable used for provide the communication
+ results*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = SMI130_INIT_VALUE;
+ /* Array holding the linear calculation output*/
+ s32 v_xy1y2_linear_s32[SMI130_YAS_XY1Y2_DATA_SIZE] = {
+ SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ /* Array holding the temperature data*/
+ s32 v_xyz_tmp_s32[SMI130_YAS_TEMP_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ s32 tmp = SMI130_INIT_VALUE;
+ s32 sx, sy1, sy2, sy, sz = SMI130_INIT_VALUE;
+ u8 i, v_busy_u8 = SMI130_INIT_VALUE;
+ u16 v_temp_u16 = SMI130_INIT_VALUE;
+ /* Array holding the xyy1 sensor raw data*/
+ u16 v_xy1y2_u16[SMI130_YAS_XY1Y2_DATA_SIZE] = {SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ #if YAS532_MAG_LOG < YAS532_MAG_TEMPERATURE_LOG
+ s32 sum = SMI130_INIT_VALUE;
+ #endif
+ *v_overflow_s8 = SMI130_INIT_VALUE;
+ switch (yas532_data.measure_state) {
+ case YAS532_MAG_STATE_INIT_COIL:
+ if (p_smi130->mag_manual_enable != SMI130_MANUAL_ENABLE)
+ com_rslt = smi130_set_mag_manual_enable(
+ SMI130_MANUAL_ENABLE);
+ /* write Rcoil*/
+ com_rslt += smi130_set_mag_write_data(
+ SMI130_YAS_DISABLE_RCOIL);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(SMI130_YAS532_RCOIL);
+ p_smi130->delay_msec(SMI130_YAS532_MEASUREMENT_DELAY);
+ if (!yas532_data.overflow && is_valid_offset(
+ yas532_data.v_hard_offset_s8))
+ yas532_data.measure_state = 0;
+ break;
+ case YAS532_MAG_STATE_MEASURE_OFFSET:
+ com_rslt = smi130_bosch_yas532_magnetic_measure_set_offset();
+ yas532_data.measure_state = 0;
+ break;
+ default:
+ break;
+ }
+ /* Read sensor data*/
+ com_rslt += smi130_bosch_yas532_normal_measurement_data(
+ v_acquisition_command_u8, &v_busy_u8, &v_temp_u16,
+ v_xy1y2_u16, v_overflow_s8);
+ /* Calculate the linear data*/
+ com_rslt += smi130_bosch_yas532_xy1y2_to_linear(v_xy1y2_u16,
+ v_xy1y2_linear_s32);
+ /* Calculate temperature correction*/
+ #if YAS532_MAG_LOG < YAS532_MAG_TEMPERATURE_LOG
+ yas532_data.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 != SMI130_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
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas532_acquisition_command_register(
+u8 v_command_reg_data_u8)
+{
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+
+ if (p_smi130->mag_manual_enable != SMI130_MANUAL_ENABLE)
+ com_rslt = smi130_set_mag_manual_enable(
+ SMI130_MANUAL_ENABLE);
+
+ com_rslt = smi130_set_mag_write_data(v_command_reg_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* YAMAHA YAS532-0x82*/
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_YAS532_COMMAND_REGISTER);
+ p_smi130->delay_msec(SMI130_YAS_ACQ_COMMAND_DELAY);
+ com_rslt += smi130_set_mag_read_addr(
+ SMI130_YAS532_DATA_REGISTER);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+
+ if (p_smi130->mag_manual_enable == SMI130_MANUAL_ENABLE)
+ com_rslt += smi130_set_mag_manual_enable(SMI130_MANUAL_DISABLE);
+
+ return com_rslt;
+
+}
+/*!
+* @brief This function used write offset of YAS532
+*
+* @param p_offset_s8 : The value of offset to write
+*
+*
+ * @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas532_set_offset(
+const s8*p_offset_s8)
+{
+ /* This variable used for provide the communication
+ results*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+
+ if (p_smi130->mag_manual_enable != SMI130_MANUAL_ENABLE)
+ com_rslt = smi130_set_mag_manual_enable(SMI130_MANUAL_ENABLE);
+ p_smi130->delay_msec(SMI130_YAS532_OFFSET_DELAY);
+
+ /* Write offset X data*/
+ com_rslt = smi130_set_mag_write_data(p_offset_s8[0]);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* YAS532 offset x write*/
+ com_rslt += smi130_set_mag_write_addr(SMI130_YAS532_OFFSET_X);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+
+ /* Write offset Y data*/
+ com_rslt = smi130_set_mag_write_data(p_offset_s8[1]);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* YAS532 offset y write*/
+ com_rslt += smi130_set_mag_write_addr(SMI130_YAS532_OFFSET_Y);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+
+ /* Write offset Z data*/
+ com_rslt = smi130_set_mag_write_data(p_offset_s8[2]);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* YAS532 offset z write*/
+ com_rslt += smi130_set_mag_write_addr(SMI130_YAS532_OFFSET_Z);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ set_vector(yas532_data.v_hard_offset_s8, p_offset_s8);
+
+ if (p_smi130->mag_manual_enable == SMI130_MANUAL_ENABLE)
+ com_rslt = smi130_set_mag_manual_enable(SMI130_MANUAL_DISABLE);
+ return com_rslt;
+}
+/*!
+* @brief This function used to init the YAMAH-YAS537
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yamaha_yas537_mag_interface_init(
+void)
+{
+/* This variable used for provide the communication
+results*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+u8 v_pull_value_u8 = SMI130_INIT_VALUE;
+u8 v_data_u8 = SMI130_INIT_VALUE;
+u8 i = SMI130_INIT_VALUE;
+/* accel operation mode to normal*/
+com_rslt = smi130_set_command_register(ACCEL_MODE_NORMAL);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* write mag power mode as NORMAL*/
+com_rslt += smi130_set_mag_interface_normal();
+/* register 0x7E write the 0x37, 0x9A and 0x30*/
+com_rslt += smi130_set_command_register(SMI130_COMMAND_REG_ONE);
+p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+com_rslt += smi130_set_command_register(SMI130_COMMAND_REG_TWO);
+p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+com_rslt += smi130_set_command_register(SMI130_COMMAND_REG_THREE);
+p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+/*switch the page1*/
+com_rslt += smi130_set_target_page(SMI130_WRITE_TARGET_PAGE1);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+smi130_get_target_page(&v_data_u8);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+com_rslt += smi130_set_paging_enable(SMI130_WRITE_ENABLE_PAGE1);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+smi130_get_paging_enable(&v_data_u8);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* enable the pullup configuration from
+the register 0x05 bit 4 and 5 as 10*/
+smi130_get_pullup_configuration(&v_pull_value_u8);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+v_pull_value_u8 = v_pull_value_u8 | SMI130_PULL_UP_DATA;
+com_rslt += smi130_set_pullup_configuration(v_pull_value_u8);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/*switch the page0*/
+com_rslt += smi130_set_target_page(SMI130_WRITE_TARGET_PAGE0);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+smi130_get_target_page(&v_data_u8);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* Write the YAS532 i2c address*/
+com_rslt += smi130_set_i2c_device_addr(SMI130_YAS537_I2C_ADDRESS);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* enable the mag interface to manual mode*/
+com_rslt += smi130_set_mag_manual_enable(SMI130_MANUAL_ENABLE);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+smi130_get_mag_manual_enable(&v_data_u8);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/*Enable the MAG interface*/
+com_rslt += smi130_set_if_mode(SMI130_ENABLE_MAG_IF_MODE);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+smi130_get_if_mode(&v_data_u8);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+v_data_u8 = SMI130_MANUAL_DISABLE;
+/* Read the YAS537 device id*/
+com_rslt += smi130_set_mag_read_addr(SMI130_YAS_DEVICE_ID_REG);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&v_data_u8, SMI130_GEN_READ_WRITE_DATA_LENGTH);
+yas537_data.dev_id = v_data_u8;
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* Read the YAS532 calibration data*/
+com_rslt +=
+smi130_bosch_yamaha_yas537_calib_values(
+SMI130_GEN_READ_WRITE_DATA_LENGTH);
+p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+/* set the mode to NORMAL*/
+yas537_data.measure_state = YAS537_MAG_STATE_NORMAL;
+/* set the transform to zero*/
+yas537_data.transform = SMI130_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 += smi130_set_mag_output_data_rate(
+SMI130_MAG_OUTPUT_DATA_RATE_25HZ);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* Enable mag interface to auto mode*/
+com_rslt += smi130_set_mag_manual_enable(
+SMI130_MANUAL_DISABLE);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+smi130_get_mag_manual_enable(&v_data_u8);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+return com_rslt;
+}
+/*!
+* @brief This function used for read the
+* YAMAHA YAS537 calibration data
+*
+*
+* @param v_rcoil_u8 : The value of r coil
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yamaha_yas537_calib_values(
+u8 v_rcoil_u8)
+{
+/* This variable used for provide the communication
+results*/
+SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+/* Array holding the YAS532 calibration values*/
+u8 a_data_u8[SMI130_YAS537_CALIB_DATA_SIZE] = {
+SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+};
+static const u8 v_avrr_u8[] = {0x50, 0x60, 0x70};
+u8 v_cal_valid_u8 = SMI130_INIT_VALUE, i;
+/* write soft reset as 0x02*/
+com_rslt = smi130_set_mag_write_data(
+YAS537_SRSTR_DATA);
+p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+com_rslt += smi130_set_mag_write_addr(YAS537_REG_SRSTR);
+p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+/* Read the DX value*/
+com_rslt = smi130_set_mag_read_addr(YAS537_REG_CALR_C0);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register*/
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[0], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the DY1 value*/
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_C1);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register*/
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[1], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the DY2 value*/
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_C2);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register*/
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[2], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the D2 value*/
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_C3);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register*/
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[3], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the D3 value*/
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_C4);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register*/
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[4], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the D4 value*/
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_C5);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register*/
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[5], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the D5 value*/
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_C6);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register*/
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[6], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the D6 value*/
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_C7);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register*/
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[7], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the D7 value*/
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_C8);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register*/
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[8], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the D8 value*/
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_C9);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register*/
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[9], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the D9 value*/
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_CA);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register*/
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[10], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the RX value*/
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_CB);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register*/
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[11], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the RY1 value*/
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_CC);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register*/
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[12], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the RY2 value*/
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_CD);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register*/
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[13], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the RY2 value*/
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_CE);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register*/
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[14], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the CHF value*/
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_CF);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register*/
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[15], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* Read the VER value*/
+com_rslt += smi130_set_mag_read_addr(YAS537_REG_CALR_DO);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+/* 0x04 is secondary read mag x lsb register*/
+com_rslt += smi130_read_reg(SMI130_MAG_DATA_READ_REG,
+&a_data_u8[16], SMI130_GEN_READ_WRITE_DATA_LENGTH);
+/* get the calib ver*/
+yas537_data.calib_yas537.ver =
+(a_data_u8[16] >> SMI130_SHIFT_BIT_POSITION_BY_06_BITS);
+for (i = 0; i < 17; i++) {
+ if (((i < 16 && a_data_u8[i]) != 0))
+ v_cal_valid_u8 = 1;
+ if ((i < 16 &&
+ (a_data_u8[i] & 0x3F)) != 0)
+ v_cal_valid_u8 = 1;
+}
+if (!v_cal_valid_u8)
+ return ERROR;
+if (yas537_data.calib_yas537.ver == 0) {
+ for (i = 0; i < 17; i++) {
+ if (i < 12) {
+ /* write offset*/
+ com_rslt += smi130_set_mag_write_data(
+ a_data_u8[i]);
+ p_smi130->delay_msec(
+ SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ YAS537_REG_MTCR + i);
+ p_smi130->delay_msec(
+ SMI130_GEN_READ_WRITE_DELAY);
+ } else if (i < 15) {
+ /* write offset correction*/
+ com_rslt += smi130_set_mag_write_data(
+ a_data_u8[i]);
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr((
+ (YAS537_REG_OXR + i) - 12));
+ p_smi130->delay_msec(
+ SMI130_GEN_READ_WRITE_DELAY);
+ yas537_data.hard_offset[i - 12]
+ = a_data_u8[i];
+ } else {
+ /* write offset correction*/
+ com_rslt += smi130_set_mag_write_data(
+ a_data_u8[i]);
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr((
+ (YAS537_REG_OXR + i) - 11));
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ }
+
+}
+} else if (yas537_data.calib_yas537.ver == 1) {
+ for (i = 0; i < 3; i++) {
+ /* write offset*/
+ com_rslt += smi130_set_mag_write_data(
+ a_data_u8[i]);
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ YAS537_REG_MTCR + i);
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ if (com_rslt == SUCCESS) {
+ /* write offset*/
+ com_rslt += smi130_set_mag_write_data(
+ a_data_u8[i + 12]);
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ YAS537_REG_OXR + i);
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ yas537_data.hard_offset[i] =
+ a_data_u8[i + 12];
+ } else {
+ com_rslt = ERROR;
+ }
+ }
+ /* write offset*/
+ com_rslt += smi130_set_mag_write_data(
+ ((a_data_u8[i] & 0xE0) | 0x10));
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(
+ YAS537_REG_MTCR + i);
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* write offset*/
+ com_rslt += smi130_set_mag_write_data(
+ ((a_data_u8[15]
+ >> SMI130_SHIFT_BIT_POSITION_BY_03_BITS)
+ & 0x1E));
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(YAS537_REG_HCKR);
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* write offset*/
+ com_rslt += smi130_set_mag_write_data(
+ ((a_data_u8[15] << 1) & 0x1E));
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(YAS537_REG_LCKR);
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ /* write offset*/
+ com_rslt += smi130_set_mag_write_data(
+ (a_data_u8[16] & 0x3F));
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(YAS537_REG_OCR);
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+
+ /* Assign the calibration values*/
+ /* a2*/
+ yas537_data.calib_yas537.a2 =
+ ((((a_data_u8[3]
+ << SMI130_SHIFT_BIT_POSITION_BY_02_BITS)
+ & 0x7C)
+ | (a_data_u8[4]
+ >> SMI130_SHIFT_BIT_POSITION_BY_06_BITS)) - 64);
+ /* a3*/
+ yas537_data.calib_yas537.a3 =
+ ((((a_data_u8[4] << SMI130_SHIFT_BIT_POSITION_BY_01_BIT)
+ & 0x7E)
+ | (a_data_u8[5]
+ >> SMI130_SHIFT_BIT_POSITION_BY_07_BITS)) - 64);
+ /* a4*/
+ yas537_data.calib_yas537.a4 =
+ ((((a_data_u8[5]
+ << SMI130_SHIFT_BIT_POSITION_BY_01_BIT)
+ & 0xFE)
+ | (a_data_u8[6]
+ >> SMI130_SHIFT_BIT_POSITION_BY_07_BITS))
+ - 128);
+ /* a5*/
+ yas537_data.calib_yas537.a5 =
+ ((((a_data_u8[6]
+ << SMI130_SHIFT_BIT_POSITION_BY_02_BITS)
+ & 0x1FC)
+ | (a_data_u8[7]
+ >> SMI130_SHIFT_BIT_POSITION_BY_06_BITS))
+ - 112);
+ /* a6*/
+ yas537_data.calib_yas537.a6 =
+ ((((a_data_u8[7]
+ << SMI130_SHIFT_BIT_POSITION_BY_01_BIT)
+ & 0x7E)
+ | (a_data_u8[8]
+ >> SMI130_SHIFT_BIT_POSITION_BY_07_BITS)) - 64);
+ /* a7*/
+ yas537_data.calib_yas537.a7 =
+ ((((a_data_u8[8]
+ << SMI130_SHIFT_BIT_POSITION_BY_01_BIT)
+ & 0xFE)
+ | (a_data_u8[9]
+ >> SMI130_SHIFT_BIT_POSITION_BY_07_BITS))
+ - 128);
+ /* a8*/
+ yas537_data.calib_yas537.a8 = ((a_data_u8[9] &
+ 0x7F) - 64);
+ /* a9*/
+ yas537_data.calib_yas537.a9 = ((((a_data_u8[10]
+ << SMI130_SHIFT_BIT_POSITION_BY_01_BIT) & 0x1FE)
+ | (a_data_u8[11]
+ >> SMI130_SHIFT_BIT_POSITION_BY_07_BITS))
+ - 112);
+ /* k*/
+ yas537_data.calib_yas537.k = (
+ a_data_u8[11] & 0x7F);
+ } else {
+ return ERROR;
+ }
+/* write A/D converter*/
+com_rslt += smi130_set_mag_write_data(
+YAS537_WRITE_A_D_CONVERTER);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+com_rslt += smi130_set_mag_write_addr(YAS537_REG_ADCCALR);
+p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+/* write A/D converter second register*/
+com_rslt += smi130_set_mag_write_data(
+YAS537_WRITE_A_D_CONVERTER2);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+com_rslt += smi130_set_mag_write_addr(YAS537_REG_ADCCALR_ONE);
+p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+/* write temperature calibration register*/
+com_rslt += smi130_set_mag_write_data(YAS537_WRITE_TEMP_CALIB);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+com_rslt += smi130_set_mag_write_addr(YAS537_REG_TRMR);
+p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+/* write average filter register*/
+com_rslt += smi130_set_mag_write_data(
+v_avrr_u8[yas537_data.average]);
+p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+com_rslt += smi130_set_mag_write_addr(YAS537_REG_AVRR);
+p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+if (v_rcoil_u8) {
+ /* write average; filter register*/
+ com_rslt += smi130_set_mag_write_data(
+ YAS537_WRITE_FILTER);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(YAS537_REG_CONFR);
+ p_smi130->delay_msec(
+ SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+}
+
+return com_rslt;
+
+}
+/*!
+* @brief This function used for YAS537 write data acquisition
+* command register write
+* @param v_command_reg_data_u8 : the value of data acquisition
+* acquisition_command | operation
+* ---------------------|-------------------------
+* 0x17 | turn on the acquisition coil
+* - | set direction of the coil
+* _ | (x and y as minus(-))
+* _ | Deferred acquisition mode
+* 0x07 | turn on the acquisition coil
+* _ | set direction of the coil
+* _ | (x and y as minus(-))
+* _ | Normal acquisition mode
+* 0x11 | turn OFF the acquisition coil
+* _ | set direction of the coil
+* _ | (x and y as plus(+))
+* _ | Deferred acquisition mode
+* 0x01 | turn OFF the acquisition coil
+* _ | set direction of the coil
+* _ | (x and y as plus(+))
+* _ | Normal acquisition mode
+*
+*
+*
+ * @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas537_acquisition_command_register(
+u8 v_command_reg_data_u8)
+{
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+
+ if (p_smi130->mag_manual_enable != SMI130_MANUAL_ENABLE)
+ com_rslt = smi130_set_mag_manual_enable(
+ SMI130_MANUAL_ENABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+
+ com_rslt = smi130_set_mag_write_data(v_command_reg_data_u8);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ /* YAMAHA YAS532-0x82*/
+ com_rslt += smi130_set_mag_write_addr(
+ SMI130_REG_YAS537_CMDR);
+ /* set the mode to RECORD*/
+ yas537_data.measure_state = YAS537_MAG_STATE_RECORD_DATA;
+ p_smi130->delay_msec(SMI130_YAS_ACQ_COMMAND_DELAY);
+ com_rslt += smi130_set_mag_read_addr(
+ YAS537_REG_TEMPERATURE_0);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+
+ if (p_smi130->mag_manual_enable == SMI130_MANUAL_ENABLE)
+ com_rslt += smi130_set_mag_manual_enable(
+ SMI130_MANUAL_DISABLE);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+
+ return com_rslt;
+
+}
+/*!
+* @brief This function used for read the
+* YAMAHA YAS537 xy1y2 data
+*
+* @param xy1y2: The value of raw xy1y2 data
+* @param xyz: The value of xyz data
+*
+*
+* @return None
+*
+*
+*/
+static void xy1y2_to_xyz(u16*xy1y2, s32*xyz)
+{
+ xyz[0] = ((xy1y2[0] - 8192)
+ * 300);
+ xyz[1] = (((xy1y2[1] - xy1y2[2])
+ * 1732) / 10);
+ xyz[2] = (((-xy1y2[2] - xy1y2[2])
+ + 16384)* 300);
+}
+/*!
+* @brief This function used for read the
+* YAMAHA YAS537 xy1y2 data
+*
+* @param v_coil_stat_u8: The value of R coil status
+* @param v_busy_u8: The value of busy status
+* @param v_temperature_u16: The value of temperature
+* @param xy1y2: The value of raw xy1y2 data
+* @param v_ouflow_u8: The value of overflow
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yamaha_yas537_read_xy1y2_data(
+u8*v_coil_stat_u8, u8*v_busy_u8,
+u16*v_temperature_u16, u16*xy1y2, u8*v_ouflow_u8)
+{
+ /* This variable used for provide the communication
+ results*/
+ SMI130_RETURN_FUNCTION_TYPE com_rslt = E_SMI130_COMM_RES;
+ /* Array holding the YAS532 calibration values*/
+ u8 a_data_u8[SMI130_YAS_XY1Y2T_DATA_SIZE] = {
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE,
+ };
+ u8 i = SMI130_INIT_VALUE;
+ s32 a_h_s32[SMI130_YAS_H_DATA_SIZE] = {
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ s32 a_s_s32[SMI130_YAS_S_DATA_SIZE] = {
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ /* set command register*/
+ com_rslt = smi130_bosch_yas537_acquisition_command_register(
+ YAS537_SET_COMMAND_REGISTER);
+ /* read the yas537 sensor data of xy1y2*/
+ com_rslt +=
+ p_smi130->SMI130_BUS_READ_FUNC(p_smi130->dev_addr,
+ SMI130_USER_DATA_MAG_X_LSB__REG,
+ a_data_u8, SMI130_MAG_YAS_DATA_LENGTH);
+ /* read the busy flag*/
+ *v_busy_u8 = a_data_u8[2]
+ >> SMI130_SHIFT_BIT_POSITION_BY_07_BITS;
+ /* read the coil status*/
+ *v_coil_stat_u8 =
+ ((a_data_u8[2] >>
+ SMI130_SHIFT_BIT_POSITION_BY_06_BITS) & 0X01);
+ /* read temperature data*/
+ *v_temperature_u16 = (u16)((a_data_u8[0]
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) | a_data_u8[1]);
+ /* read x data*/
+ xy1y2[0] = (u16)(((a_data_u8[2] &
+ 0x3F)
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | (a_data_u8[3]));
+ /* read y1 data*/
+ xy1y2[1] = (u16)((a_data_u8[4]
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | a_data_u8[5]);
+ /* read y2 data*/
+ xy1y2[2] = (u16)((a_data_u8[6]
+ << SMI130_SHIFT_BIT_POSITION_BY_08_BITS)
+ | a_data_u8[7]);
+ for (i = 0; i < 3; i++)
+ yas537_data.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 SMI130_RETURN_FUNCTION_TYPE invalid_magnetic_field(
+u16*v_cur_u16, u16*v_last_u16)
+{
+ s16 invalid_thresh[] = {1500, 1500, 1500};
+ u8 i = SMI130_INIT_VALUE;
+
+ for (i = 0; i < 3; i++)
+ if (invalid_thresh[i] < ABS(v_cur_u16[i] - v_last_u16[i]))
+ return 1;
+ return 0;
+}
+/*!
+* @brief This function used for read the
+* YAMAHA YAS537 xy1y2 data
+*
+* @param v_ouflow_u8: The value of overflow
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yamaha_yas537_measure_xyz_data(
+u8*v_ouflow_u8, struct yas_vector*vector_xyz)
+{
+ s32 a_xyz_tmp_s32[SMI130_YAS_TEMP_DATA_SIZE] = {
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ u8 i = SMI130_INIT_VALUE;
+ s8 com_rslt = SMI130_INIT_VALUE;
+ u8 v_busy_u8 = SMI130_INIT_VALUE;
+ u8 v_rcoil_u8 = SMI130_INIT_VALUE;
+ u16 v_temperature_u16 = SMI130_INIT_VALUE;
+ u16 a_xy1y2_u16[SMI130_YAS_XY1Y2_DATA_SIZE] = {
+ SMI130_INIT_VALUE, SMI130_INIT_VALUE, SMI130_INIT_VALUE};
+ *v_ouflow_u8 = 0;
+ /* read the yas537 xy1y2 data*/
+ com_rslt = smi130_bosch_yamaha_yas537_read_xy1y2_data(
+ &v_rcoil_u8, &v_busy_u8,
+ &v_temperature_u16, a_xy1y2_u16, v_ouflow_u8);
+ /* linear calculation*/
+ xy1y2_to_xyz(a_xy1y2_u16, vector_xyz->yas537_vector_xyz);
+ if (yas537_data.transform != SMI130_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_smi130->mag_manual_enable != SMI130_MANUAL_ENABLE)
+ com_rslt = smi130_set_mag_manual_enable(
+ SMI130_MANUAL_ENABLE);
+ com_rslt += smi130_set_mag_write_data(YAS537_WRITE_CONFR);
+ p_smi130->delay_msec(SMI130_GEN_READ_WRITE_DELAY);
+ com_rslt += smi130_set_mag_write_addr(YAS537_REG_CONFR);
+ p_smi130->delay_msec(SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY);
+ yas537_data.measure_state = YAS537_MAG_STATE_RECORD_DATA;
+ if (p_smi130->mag_manual_enable == SMI130_MANUAL_ENABLE)
+ com_rslt = smi130_set_mag_manual_enable(
+ SMI130_MANUAL_DISABLE);
+ break;
+ case YAS537_MAG_STATE_RECORD_DATA:
+ if (v_rcoil_u8)
+ break;
+ yas537_set_vector(yas537_data.last_after_rcoil, a_xy1y2_u16);
+ yas537_data.measure_state = YAS537_MAG_STATE_NORMAL;
+ break;
+ case YAS537_MAG_STATE_NORMAL:
+ if (SMI130_INIT_VALUE < v_ouflow_u8
+ || invalid_magnetic_field(a_xy1y2_u16,
+ yas537_data.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
+* smi130_t structure
+*
+* @return the reference and values of smi130_t
+*
+*
+*/
+struct smi130_t*smi130_get_ptr(void)
+{
+ return p_smi130;
+}
diff --git a/drivers/input/sensors/smi130/smi130.h b/drivers/input/sensors/smi130/smi130.h
new file mode 100644
index 0000000..fe2032b
--- /dev/null
+++ b/drivers/input/sensors/smi130/smi130.h
@@ -0,0 +1,11848 @@
+/*
+****************************************************************************
+* Copyright (C) 2014 Bosch Sensortec GmbH
+*
+* (C) Modification Copyright 2018 Robert Bosch Kft All Rights Reserved
+*
+* smi130.h
+* @Date : 2015/04/02
+* @Modification Date 2018/06/21 15:03
+* @id 836294d
+* Revision : 2.0.9 $
+* @brief
+* The head file of SMI130API
+*
+* Special: Description of the Software:
+*
+* This software module (hereinafter called "Software") and any
+* information on application-sheets (hereinafter called "Information") is
+* provided free of charge for the sole purpose to support your application
+* work.
+*
+* As such, the Software is merely an experimental software, not tested for
+* safety in the field and only intended for inspiration for further development
+* and testing. Any usage in a safety-relevant field of use (like automotive,
+* seafaring, spacefaring, industrial plants etc.) was not intended, so there are
+* no precautions for such usage incorporated in the Software.
+*
+* The Software is specifically designed for the exclusive use for Bosch
+* Sensortec products by personnel who have special experience and training. Do
+* not use this Software if you do not have the proper experience or training.
+*
+* This Software package is provided as is and without any expressed or
+* implied warranties, including without limitation, the implied warranties of
+* merchantability and fitness for a particular purpose.
+*
+* Bosch Sensortec and their representatives and agents deny any liability for
+* the functional impairment of this Software in terms of fitness, performance
+* and safety. Bosch Sensortec and their representatives and agents shall not be
+* liable for any direct or indirect damages or injury, except as otherwise
+* stipulated in mandatory applicable law.
+* The Information provided is believed to be accurate and reliable. Bosch
+* Sensortec assumes no responsibility for the consequences of use of such
+* Information nor for any infringement of patents or other rights of third
+* parties which may result from its use.
+*
+*------------------------------------------------------------------------------
+* The following Product Disclaimer does not apply to the BSX4-HAL-4.1NoFusion Software
+* which is licensed under the Apache License, Version 2.0 as stated above.
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Product Disclaimer
+*
+* Common:
+*
+* Assessment of Products Returned from Field
+*
+* Returned products are considered good if they fulfill the specifications /
+* test data for 0-mileage and field listed in this document.
+*
+* Engineering Samples
+*
+* Engineering samples are marked with (e) or (E). Samples may vary from the
+* valid technical specifications of the series product contained in this
+* data sheet. Therefore, they are not intended or fit for resale to
+* third parties or for use in end products. Their sole purpose is internal
+* client testing. The testing of an engineering sample may in no way replace
+* the testing of a series product. Bosch assumes no liability for the use
+* of engineering samples. The purchaser shall indemnify Bosch from all claims
+* arising from the use of engineering samples.
+*
+* Intended use
+*
+* Provided that SMI130 is used within the conditions (environment, application,
+* installation, loads) as described in this TCD and the corresponding
+* agreed upon documents, Bosch ensures that the product complies with
+* the agreed properties. Agreements beyond this require
+* the written approval by Bosch. The product is considered fit for the intended
+* use when the product successfully has passed the tests
+* in accordance with the TCD and agreed upon documents.
+*
+* It is the responsibility of the customer to ensure the proper application
+* of the product in the overall system/vehicle.
+*
+* Bosch does not assume any responsibility for changes to the environment
+* of the product that deviate from the TCD and the agreed upon documents
+* as well as all applications not released by Bosch
+*
+* The resale and/or use of products are at the purchaser’s own risk and
+* responsibility. The examination and testing of the SMI130
+* is the sole responsibility of the purchaser.
+*
+* The purchaser shall indemnify Bosch from all third party claims
+* arising from any product use not covered by the parameters of
+* this product data sheet or not approved by Bosch and reimburse Bosch
+* for all costs and damages in connection with such claims.
+*
+* The purchaser must monitor the market for the purchased products,
+* particularly with regard to product safety, and inform Bosch without delay
+* of all security relevant incidents.
+*
+* Application Examples and Hints
+*
+* With respect to any application examples, advice, normal values
+* and/or any information regarding the application of the device,
+* Bosch hereby disclaims any and all warranties and liabilities of any kind,
+* including without limitation warranties of
+* non-infringement of intellectual property rights or copyrights
+* of any third party.
+* The information given in this document shall in no event be regarded
+* as a guarantee of conditions or characteristics. They are provided
+* for illustrative purposes only and no evaluation regarding infringement
+* of intellectual property rights or copyrights or regarding functionality,
+* performance or error has been made.
+*
+*
+**************************************************************************/
+/*! \file smi130.h
+ \brief SMI130 Sensor Driver Support Header File */
+/* user defined code to be added here ... */
+#ifndef __SMI130_H__
+#define __SMI130_H__
+
+/*!
+* @brief The following definition uses for define the data types
+*
+* @note While porting the API please consider the following
+* @note Please check the version of C standard
+* @note Are you using Linux platform
+*/
+
+/*!
+* @brief For the Linux platform support
+* Please use the types.h for your data types definitions
+*/
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+
+#else /* ! __KERNEL__ */
+/**********************************************************
+* These definition uses for define the C
+* standard version data types
+***********************************************************/
+# if !defined(__STDC_VERSION__)
+
+/************************************************
+ * compiler is C11 C standard
+************************************************/
+#if (__STDC_VERSION__ == 201112L)
+
+/************************************************/
+#include <stdint.h>
+/************************************************/
+
+/*unsigned integer types*/
+#define u8 uint8_t
+#define u16 uint16_t
+#define u32 uint32_t
+#define u64 uint64_t
+
+/*signed integer types*/
+#define s8 int8_t
+#define s16 int16_t
+#define s32 int32_t
+#define s64 int64_t
+/************************************************
+ * compiler is C99 C standard
+************************************************/
+
+#elif (__STDC_VERSION__ == 199901L)
+
+/* stdint.h is a C99 supported c library.
+which is used to fixed the integer size*/
+/************************************************/
+#include <stdint.h>
+/************************************************/
+
+/*unsigned integer types*/
+#define u8 uint8_t
+#define u16 uint16_t
+#define u32 uint32_t
+#define u64 uint64_t
+
+/*signed integer types*/
+#define s8 int8_t
+#define s16 int16_t
+#define s32 int32_t
+#define s64 int64_t
+/************************************************
+ * compiler is C89 or other C standard
+************************************************/
+#else /* !defined(__STDC_VERSION__) */
+/* By default it is defined as 32 bit machine configuration*/
+/* define the definition based on your machine configuration*/
+/* define the data types based on your
+ machine/compiler/controller configuration*/
+#define MACHINE_32_BIT
+
+/* If your machine support 16 bit
+define the MACHINE_16_BIT*/
+#ifdef MACHINE_16_BIT
+#include <limits.h>
+/*signed integer types*/
+#define s8 signed char
+#define s16 signed short int
+#define s32 signed long int
+
+#if defined(LONG_MAX) && LONG_MAX == 0x7fffffffffffffffL
+#define s64 long int
+#define u64 unsigned long int
+#elif defined(LLONG_MAX) && (LLONG_MAX == 0x7fffffffffffffffLL)
+#define s64 long long int
+#define u64 unsigned long long int
+#else
+#warning Either the correct data type for signed 64 bit integer \
+could not be found, or 64 bit integers are not supported in your environment.
+#warning If 64 bit integers are supported on your platform, \
+please set s64 manually.
+#endif
+
+/*unsigned integer types*/
+#define u8 unsigned char
+#define u16 unsigned short int
+#define u32 unsigned long int
+
+/* If your machine support 32 bit
+define the MACHINE_32_BIT*/
+#elif defined MACHINE_32_BIT
+/*signed integer types*/
+#define s8 signed char
+#define s16 signed short int
+#define s32 signed int
+#define s64 signed long long int
+
+/*unsigned integer types*/
+#define u8 unsigned char
+#define u16 unsigned short int
+#define u32 unsigned int
+#define u64 unsigned long long int
+
+/* If your machine support 64 bit
+define the MACHINE_64_BIT*/
+#elif defined MACHINE_64_BIT
+/*signed integer types*/
+#define s8 signed char
+#define s16 signed short int
+#define s32 signed int
+#define s64 signed long int
+
+/*unsigned integer types*/
+#define u8 unsigned char
+#define u16 unsigned short int
+#define u32 unsigned int
+#define u64 unsigned long int
+
+#else
+#warning The data types defined above which not supported \
+define the data types manually
+#endif
+#endif
+
+/*** This else will execute for the compilers
+ * which are not supported the C standards
+ * Like C89/C99/C11***/
+#else
+/* By default it is defined as 32 bit machine configuration*/
+/* define the definition based on your machine configuration*/
+/* define the data types based on your
+ machine/compiler/controller configuration*/
+#define MACHINE_32_BIT
+
+/* If your machine support 16 bit
+define the MACHINE_16_BIT*/
+#ifdef MACHINE_16_BIT
+#include <limits.h>
+/*signed integer types*/
+#define s8 signed char
+#define s16 signed short int
+#define s32 signed long int
+
+#if defined(LONG_MAX) && LONG_MAX == 0x7fffffffffffffffL
+#define s64 long int
+#define u64 unsigned long int
+#elif defined(LLONG_MAX) && (LLONG_MAX == 0x7fffffffffffffffLL)
+#define s64 long long int
+#define u64 unsigned long long int
+#else
+#warning Either the correct data type for signed 64 bit integer \
+could not be found, or 64 bit integers are not supported in your environment.
+#warning If 64 bit integers are supported on your platform, \
+please set s64 manually.
+#endif
+
+/*unsigned integer types*/
+#define u8 unsigned char
+#define u16 unsigned short int
+#define u32 unsigned long int
+
+/* If your machine support 32 bit
+define the MACHINE_32_BIT*/
+#elif defined MACHINE_32_BIT
+/*signed integer types*/
+#define s8 signed char
+#define s16 signed short int
+#define s32 signed int
+#define s64 signed long long int
+
+/*unsigned integer types*/
+#define u8 unsigned char
+#define u16 unsigned short int
+#define u32 unsigned int
+#define u64 unsigned long long int
+
+/* If your machine support 64 bit
+define the MACHINE_64_BIT*/
+#elif defined MACHINE_64_BIT
+/*signed integer types*/
+#define s8 signed char
+#define s16 signed short int
+#define s32 signed int
+#define s64 signed long int
+
+/*unsigned integer types*/
+#define u8 unsigned char
+#define u16 unsigned short int
+#define u32 unsigned int
+#define u64 unsigned long int
+
+#else
+#warning The data types defined above which not supported \
+define the data types manually
+#endif
+#endif
+#endif
+/***************************************************************/
+/**\name BUS READ AND WRITE FUNCTION POINTERS */
+/***************************************************************/
+/*!
+ @brief Define the calling convention of YOUR bus communication routine.
+ @note This includes types of parameters. This example shows the
+ configuration for an SPI bus link.
+
+ If your communication function looks like this:
+
+ write_my_bus_xy(u8 device_addr, u8 register_addr,
+ u8 * data, u8 length);
+
+ The SMI130_WR_FUNC_PTR would equal:
+
+ SMI130_WR_FUNC_PTR s8 (* bus_write)(u8,
+ u8, u8 *, u8)
+
+ Parameters can be mixed as needed refer to the
+ @ref SMI130_BUS_WRITE_FUNC macro.
+
+
+*/
+#define SMI130_WR_FUNC_PTR s8 (*bus_write)(u8, u8,\
+u8 *, u8)
+/**< link macro between API function calls and bus write function
+ @note The bus write function can change since this is a
+ system dependant issue.
+
+ If the bus_write parameter calling order is like: reg_addr,
+ reg_data, wr_len it would be as it is here.
+
+ If the parameters are differently ordered or your communication
+ function like I2C need to know the device address,
+ you can change this macro accordingly.
+
+
+ SMI130_BUS_WRITE_FUNC(dev_addr, reg_addr, reg_data, wr_len)\
+ bus_write(dev_addr, reg_addr, reg_data, wr_len)
+
+ This macro lets all API functions call YOUR communication routine in a
+ way that equals your definition in the
+ @ref SMI130_WR_FUNC_PTR definition.
+
+*/
+#define SMI130_BUS_WRITE_FUNC(dev_addr, reg_addr, reg_data, wr_len)\
+ bus_write(dev_addr, reg_addr, reg_data, wr_len)
+
+/**< Define the calling convention of YOUR bus communication routine.
+ @note This includes types of parameters. This example shows the
+ configuration for an SPI bus link.
+
+ If your communication function looks like this:
+
+ read_my_bus_xy(u8 device_addr, u8 register_addr,
+ u8 * data, u8 length);
+
+ The SMI130_RD_FUNC_PTR would equal:
+
+ SMI130_RD_FUNC_PTR s8 (* bus_read)(u8,
+ u8, u8 *, u8)
+
+ Parameters can be mixed as needed refer to the
+ refer SMI130_BUS_READ_FUNC macro.
+
+*/
+#define SMI130_SPI_RD_MASK (0x80) /* for spi read transactions on SPI the
+ MSB has to be set */
+#define SMI130_RD_FUNC_PTR s8 (*bus_read)(u8,\
+ u8, u8 *, u8)
+
+#define SMI130_BRD_FUNC_PTR s8 \
+(*burst_read)(u8, u8, u8 *, u32)
+
+/**< link macro between API function calls and bus read function
+ @note The bus write function can change since this is a
+ system dependant issue.
+
+ If the bus_read parameter calling order is like: reg_addr,
+ reg_data, wr_len it would be as it is here.
+
+ If the parameters are differently ordered or your communication
+ function like I2C need to know the device address,
+ you can change this macro accordingly.
+
+
+ SMI130_BUS_READ_FUNC(dev_addr, reg_addr, reg_data, wr_len)\
+ bus_read(dev_addr, reg_addr, reg_data, wr_len)
+
+ This macro lets all API functions call YOUR communication routine in a
+ way that equals your definition in the
+ refer SMI130_WR_FUNC_PTR definition.
+
+ @note: this macro also includes the "MSB='1'
+ for reading SMI130 addresses.
+
+*/
+#define SMI130_BUS_READ_FUNC(dev_addr, reg_addr, reg_data, r_len)\
+ bus_read(dev_addr, reg_addr, reg_data, r_len)
+
+#define SMI130_BURST_READ_FUNC(device_addr, \
+register_addr, register_data, rd_len)\
+burst_read(device_addr, register_addr, register_data, rd_len)
+
+
+#define SMI130_MDELAY_DATA_TYPE u32
+
+/***************************************************************/
+/**\name BUS READ AND WRITE FUNCTION POINTERS */
+/***************************************************************/
+#define SMI130_I2C_ADDR1 0x68 /**< I2C Address needs to be changed */
+#define SMI130_I2C_ADDR2 0x18 /**< I2C Address needs to be changed */
+#define SMI130_AUX_BMM150_I2C_ADDRESS (0x10)
+#define SMI130_AUX_YAS532_I2C_ADDRESS (0x2E)
+/**< I2C address of YAS532*/
+#define SMI130_AKM09911_I2C_ADDRESS 0x0C/**< I2C address of AKM09911*/
+/**< I2C address of AKM09911*/
+#define SMI130_AUX_AKM09911_I2C_ADDR_2 (0x0D)
+/**< I2C address of AKM09911*/
+#define SMI130_AUX_AKM09912_I2C_ADDR_1 (0x0C)
+/**< I2C address of AKM09912*/
+#define SMI130_AUX_AKM09912_I2C_ADDR_2 (0x0D)
+/**< I2C address of AKM09912*/
+#define SMI130_AUX_AKM09912_I2C_ADDR_3 (0x0E)
+/**< I2C address of AKM09912*/
+#define SMI130_AKM09912_I2C_ADDRESS 0x0F/**< I2C address of akm09912*/
+
+#define SMI130_YAS532_I2C_ADDRESS 0x2E/**< I2C address of YAS532*/
+/*******************************************/
+/**\name CONSTANTS */
+/******************************************/
+#define SMI130_INIT_VALUE (0)
+#define SMI130_GEN_READ_WRITE_DATA_LENGTH (1)
+#define SMI130_MAXIMUM_TIMEOUT (10)
+/* output data rate condition check*/
+#define SMI130_OUTPUT_DATA_RATE0 (0)
+#define SMI130_OUTPUT_DATA_RATE1 (1)
+#define SMI130_OUTPUT_DATA_RATE2 (2)
+#define SMI130_OUTPUT_DATA_RATE3 (3)
+#define SMI130_OUTPUT_DATA_RATE4 (4)
+#define SMI130_OUTPUT_DATA_RATE5 (5)
+#define SMI130_OUTPUT_DATA_RATE6 (14)
+#define SMI130_OUTPUT_DATA_RATE7 (15)
+/* accel range check*/
+#define SMI130_ACCEL_RANGE0 (3)
+#define SMI130_ACCEL_RANGE1 (5)
+#define SMI130_ACCEL_RANGE3 (8)
+#define SMI130_ACCEL_RANGE4 (12)
+/* check the status of registers*/
+#define SMI130_FOC_STAT_HIGH (1)
+#define SMI130_SIG_MOTION_STAT_HIGH (1)
+#define SMI130_STEP_DET_STAT_HIGH (1)
+
+/*condition check for reading and writing data*/
+#define SMI130_MAX_VALUE_SIGNIFICANT_MOTION (1)
+#define SMI130_MAX_VALUE_FIFO_FILTER (1)
+#define SMI130_MAX_VALUE_FIFO_TIME (1)
+#define SMI130_MAX_VALUE_FIFO_INTR (1)
+#define SMI130_MAX_VALUE_FIFO_HEADER (1)
+#define SMI130_MAX_VALUE_FIFO_MAG (1)
+#define SMI130_MAX_VALUE_FIFO_ACCEL (1)
+#define SMI130_MAX_VALUE_FIFO_GYRO (1)
+#define SMI130_MAX_VALUE_SOURCE_INTR (1)
+#define SMI130_MAX_VALUE_LOW_G_MODE (1)
+#define SMI130_MAX_VALUE_NO_MOTION (1)
+#define SMI130_MAX_VALUE_TAP_SHOCK (1)
+#define SMI130_MAX_VALUE_TAP_QUIET (1)
+#define SMI130_MAX_VALUE_ORIENT_UD (1)
+#define SMI130_MAX_VALUE_ORIENT_AXES (1)
+#define SMI130_MAX_VALUE_NVM_PROG (1)
+#define SMI130_MAX_VALUE_SPI3 (1)
+#define SMI130_MAX_VALUE_PAGE (1)
+#define SMI130_MAX_VALUE_I2C_WDT (1)
+#define SMI130_MAX_VALUE_SLEEP_STATE (1)
+#define SMI130_MAX_VALUE_WAKEUP_INTR (1)
+#define SMI130_MAX_VALUE_SELFTEST_SIGN (1)
+#define SMI130_MAX_VALUE_SELFTEST_AMP (1)
+#define SMI130_MAX_VALUE_SELFTEST_START (1)
+#define SMI130_MAX_GYRO_WAKEUP_TRIGGER (3)
+#define SMI130_MAX_ACCEL_SELFTEST_AXIS (3)
+#define SMI130_MAX_GYRO_STEP_COUNTER (1)
+#define SMI130_MAX_GYRO_BW (3)
+#define SMI130_MAX_ACCEL_BW (7)
+#define SMI130_MAX_ORIENT_MODE (3)
+#define SMI130_MAX_ORIENT_BLOCKING (3)
+#define SMI130_MAX_FLAT_HOLD (3)
+#define SMI130_MAX_ACCEL_FOC (3)
+#define SMI130_MAX_IF_MODE (3)
+#define SMI130_MAX_TARGET_PAGE (3)
+#define SMI130_MAX_GYRO_RANGE (4)
+#define SMI130_MAX_GYRO_SLEEP_TIGGER (7)
+#define SMI130_MAX_TAP_TURN (7)
+#define SMI130_MAX_UNDER_SAMPLING (1)
+#define SMI130_MAX_UNDER_SIG_MOTION (3)
+#define SMI130_MAX_ACCEL_OUTPUT_DATA_RATE (12)
+#define SMI130_MAX_LATCH_INTR (15)
+#define SMI130_MAX_FLAT_HYST (15)
+#define SMI130_MAX_ORIENT_THETA (63)
+#define SMI130_MAX_FLAT_THETA (63)
+
+/* FIFO index definitions*/
+#define SMI130_FIFO_X_LSB_DATA (0)
+#define SMI130_FIFO_X_MSB_DATA (1)
+#define SMI130_FIFO_Y_LSB_DATA (2)
+#define SMI130_FIFO_Y_MSB_DATA (3)
+#define SMI130_FIFO_Z_LSB_DATA (4)
+#define SMI130_FIFO_Z_MSB_DATA (5)
+#define SMI130_FIFO_R_LSB_DATA (6)
+#define SMI130_FIFO_R_MSB_DATA (7)
+/* FIFO gyro definition*/
+#define SMI130_GA_FIFO_G_X_LSB (0)
+#define SMI130_GA_FIFO_G_X_MSB (1)
+#define SMI130_GA_FIFO_G_Y_LSB (2)
+#define SMI130_GA_FIFO_G_Y_MSB (3)
+#define SMI130_GA_FIFO_G_Z_LSB (4)
+#define SMI130_GA_FIFO_G_Z_MSB (5)
+#define SMI130_GA_FIFO_A_X_LSB (6)
+#define SMI130_GA_FIFO_A_X_MSB (7)
+#define SMI130_GA_FIFO_A_Y_LSB (8)
+#define SMI130_GA_FIFO_A_Y_MSB (9)
+#define SMI130_GA_FIFO_A_Z_LSB (10)
+#define SMI130_GA_FIFO_A_Z_MSB (11)
+/* FIFO mag/gyro/accel definition*/
+#define SMI130_MGA_FIFO_M_X_LSB (0)
+#define SMI130_MGA_FIFO_M_X_MSB (1)
+#define SMI130_MGA_FIFO_M_Y_LSB (2)
+#define SMI130_MGA_FIFO_M_Y_MSB (3)
+#define SMI130_MGA_FIFO_M_Z_LSB (4)
+#define SMI130_MGA_FIFO_M_Z_MSB (5)
+#define SMI130_MGA_FIFO_M_R_LSB (6)
+#define SMI130_MGA_FIFO_M_R_MSB (7)
+#define SMI130_MGA_FIFO_G_X_LSB (8)
+#define SMI130_MGA_FIFO_G_X_MSB (9)
+#define SMI130_MGA_FIFO_G_Y_LSB (10)
+#define SMI130_MGA_FIFO_G_Y_MSB (11)
+#define SMI130_MGA_FIFO_G_Z_LSB (12)
+#define SMI130_MGA_FIFO_G_Z_MSB (13)
+#define SMI130_MGA_FIFO_A_X_LSB (14)
+#define SMI130_MGA_FIFO_A_X_MSB (15)
+#define SMI130_MGA_FIFO_A_Y_LSB (16)
+#define SMI130_MGA_FIFO_A_Y_MSB (17)
+#define SMI130_MGA_FIFO_A_Z_LSB (18)
+#define SMI130_MGA_FIFO_A_Z_MSB (19)
+/* FIFO mag definition*/
+#define SMI130_MA_FIFO_M_X_LSB (0)
+#define SMI130_MA_FIFO_M_X_MSB (1)
+#define SMI130_MA_FIFO_M_Y_LSB (2)
+#define SMI130_MA_FIFO_M_Y_MSB (3)
+#define SMI130_MA_FIFO_M_Z_LSB (4)
+#define SMI130_MA_FIFO_M_Z_MSB (5)
+#define SMI130_MA_FIFO_M_R_LSB (6)
+#define SMI130_MA_FIFO_M_R_MSB (7)
+#define SMI130_MA_FIFO_A_X_LSB (8)
+#define SMI130_MA_FIFO_A_X_MSB (9)
+#define SMI130_MA_FIFO_A_Y_LSB (10)
+#define SMI130_MA_FIFO_A_Y_MSB (11)
+#define SMI130_MA_FIFO_A_Z_LSB (12)
+#define SMI130_MA_FIFO_A_Z_MSB (13)
+/* FIFO mag/gyro definition*/
+#define SMI130_MG_FIFO_M_X_LSB (0)
+#define SMI130_MG_FIFO_M_X_MSB (1)
+#define SMI130_MG_FIFO_M_Y_LSB (2)
+#define SMI130_MG_FIFO_M_Y_MSB (3)
+#define SMI130_MG_FIFO_M_Z_LSB (4)
+#define SMI130_MG_FIFO_M_Z_MSB (5)
+#define SMI130_MG_FIFO_M_R_LSB (6)
+#define SMI130_MG_FIFO_M_R_MSB (7)
+#define SMI130_MG_FIFO_G_X_LSB (8)
+#define SMI130_MG_FIFO_G_X_MSB (9)
+#define SMI130_MG_FIFO_G_Y_LSB (10)
+#define SMI130_MG_FIFO_G_Y_MSB (11)
+#define SMI130_MG_FIFO_G_Z_LSB (12)
+#define SMI130_MG_FIFO_G_Z_MSB (13)
+/* FIFO length definitions*/
+#define SMI130_FIFO_SENSOR_TIME_LSB (0)
+#define SMI130_FIFO_SENSOR_TIME_XLSB (1)
+#define SMI130_FIFO_SENSOR_TIME_MSB (2)
+#define SMI130_FIFO_SENSOR_TIME_LENGTH (3)
+#define SMI130_FIFO_A_LENGTH (6)
+#define SMI130_FIFO_G_LENGTH (6)
+#define SMI130_FIFO_M_LENGTH (8)
+#define SMI130_FIFO_AG_LENGTH (12)
+#define SMI130_FIFO_AMG_LENGTH (20)
+#define SMI130_FIFO_MA_OR_MG_LENGTH (14)
+
+/* bus read and write length for mag, accel and gyro*/
+#define SMI130_MAG_X_DATA_LENGTH (2)
+#define SMI130_MAG_Y_DATA_LENGTH (2)
+#define SMI130_MAG_Z_DATA_LENGTH (2)
+#define SMI130_MAG_R_DATA_LENGTH (2)
+#define SMI130_MAG_XYZ_DATA_LENGTH (6)
+#define SMI130_MAG_XYZR_DATA_LENGTH (8)
+#define SMI130_MAG_YAS_DATA_LENGTH (8)
+#define SMI130_GYRO_DATA_LENGTH (2)
+#define SMI130_GYRO_XYZ_DATA_LENGTH (6)
+#define SMI130_ACCEL_DATA_LENGTH (2)
+#define SMI130_ACCEL_XYZ_DATA_LENGTH (6)
+#define SMI130_TEMP_DATA_LENGTH (2)
+#define SMI130_FIFO_DATA_LENGTH (2)
+#define SMI130_STEP_COUNTER_LENGTH (2)
+#define SMI130_SENSOR_TIME_LENGTH (3)
+
+/* Delay definitions*/
+#define SMI130_SEC_INTERFACE_GEN_READ_WRITE_DELAY (5)
+#define SMI130_BMM150_WAKEUP_DELAY1 (2)
+#define SMI130_BMM150_WAKEUP_DELAY2 (3)
+#define SMI130_BMM150_WAKEUP_DELAY3 (1)
+#define SMI130_YAS532_OFFSET_DELAY (2)
+#define SMI130_GEN_READ_WRITE_DELAY (1)
+#define SMI130_YAS532_MEASUREMENT_DELAY (25)
+#define SMI130_YAS_ACQ_COMMAND_DELAY (50)
+#define SMI130_YAS532_SET_INITIAL_VALUE_DELAY (200)
+#define SMI130_AKM_INIT_DELAY (60)
+/****************************************************/
+/**\name ARRAY SIZE DEFINITIONS */
+/***************************************************/
+#define SMI130_ACCEL_X_DATA_SIZE (2)
+#define SMI130_ACCEL_Y_DATA_SIZE (2)
+#define SMI130_ACCEL_Z_DATA_SIZE (2)
+#define SMI130_ACCEL_XYZ_DATA_SIZE (6)
+
+#define SMI130_GYRO_X_DATA_SIZE (2)
+#define SMI130_GYRO_Y_DATA_SIZE (2)
+#define SMI130_GYRO_Z_DATA_SIZE (2)
+#define SMI130_GYRO_XYZ_DATA_SIZE (6)
+
+#define SMI130_MAG_X_DATA_SIZE (2)
+#define SMI130_MAG_Y_DATA_SIZE (2)
+#define SMI130_MAG_Z_DATA_SIZE (2)
+#define SMI130_MAG_R_DATA_SIZE (2)
+#define SMI130_MAG_XYZ_DATA_SIZE (6)
+#define SMI130_MAG_XYZR_DATA_SIZE (8)
+#define SMI130_MAG_TRIM_DATA_SIZE (16)
+
+
+#define SMI130_TEMP_DATA_SIZE (2)
+#define SMI130_FIFO_DATA_SIZE (2)
+#define SMI130_STEP_COUNT_DATA_SIZE (2)
+
+#define SMI130_SENSOR_TIME_DATA_SIZE (3)
+#define SMI130_AKM_SENSITIVITY_DATA_SIZE (3)
+#define SMI130_HARD_OFFSET_DATA_SIZE (3)
+#define SMI130_YAS_XY1Y2_DATA_SIZE (3)
+#define SMI130_YAS_FLAG_DATA_SIZE (3)
+#define SMI130_YAS_TEMP_DATA_SIZE (3)
+#define SMI130_YAS_H_DATA_SIZE (3)
+#define SMI130_YAS_S_DATA_SIZE (3)
+#define SMI130_YAS_CORRECT_DATA_SIZE (5)
+#define SMI130_YAS_XY1Y2T_DATA_SIZE (8)
+#define SMI130_YAS537_CALIB_DATA_SIZE (17)
+#define SMI130_YAS532_CALIB_DATA_SIZE (14)
+/****************************************************/
+/**\name ARRAY PARAMETER DEFINITIONS */
+/***************************************************/
+#define SMI130_SENSOR_TIME_MSB_BYTE (2)
+#define SMI130_SENSOR_TIME_XLSB_BYTE (1)
+#define SMI130_SENSOR_TIME_LSB_BYTE (0)
+
+#define SMI130_MAG_X_LSB_BYTE (0)
+#define SMI130_MAG_X_MSB_BYTE (1)
+#define SMI130_MAG_Y_LSB_BYTE (0)
+#define SMI130_MAG_Y_MSB_BYTE (1)
+#define SMI130_MAG_Z_LSB_BYTE (0)
+#define SMI130_MAG_Z_MSB_BYTE (1)
+#define SMI130_MAG_R_LSB_BYTE (0)
+#define SMI130_MAG_R_MSB_BYTE (1)
+#define SMI130_DATA_FRAME_MAG_X_LSB_BYTE (0)
+#define SMI130_DATA_FRAME_MAG_X_MSB_BYTE (1)
+#define SMI130_DATA_FRAME_MAG_Y_LSB_BYTE (2)
+#define SMI130_DATA_FRAME_MAG_Y_MSB_BYTE (3)
+#define SMI130_DATA_FRAME_MAG_Z_LSB_BYTE (4)
+#define SMI130_DATA_FRAME_MAG_Z_MSB_BYTE (5)
+#define SMI130_DATA_FRAME_MAG_R_LSB_BYTE (6)
+#define SMI130_DATA_FRAME_MAG_R_MSB_BYTE (7)
+
+#define SMI130_GYRO_X_LSB_BYTE (0)
+#define SMI130_GYRO_X_MSB_BYTE (1)
+#define SMI130_GYRO_Y_LSB_BYTE (0)
+#define SMI130_GYRO_Y_MSB_BYTE (1)
+#define SMI130_GYRO_Z_LSB_BYTE (0)
+#define SMI130_GYRO_Z_MSB_BYTE (1)
+#define SMI130_DATA_FRAME_GYRO_X_LSB_BYTE (0)
+#define SMI130_DATA_FRAME_GYRO_X_MSB_BYTE (1)
+#define SMI130_DATA_FRAME_GYRO_Y_LSB_BYTE (2)
+#define SMI130_DATA_FRAME_GYRO_Y_MSB_BYTE (3)
+#define SMI130_DATA_FRAME_GYRO_Z_LSB_BYTE (4)
+#define SMI130_DATA_FRAME_GYRO_Z_MSB_BYTE (5)
+
+#define SMI130_ACCEL_X_LSB_BYTE (0)
+#define SMI130_ACCEL_X_MSB_BYTE (1)
+#define SMI130_ACCEL_Y_LSB_BYTE (0)
+#define SMI130_ACCEL_Y_MSB_BYTE (1)
+#define SMI130_ACCEL_Z_LSB_BYTE (0)
+#define SMI130_ACCEL_Z_MSB_BYTE (1)
+#define SMI130_DATA_FRAME_ACCEL_X_LSB_BYTE (0)
+#define SMI130_DATA_FRAME_ACCEL_X_MSB_BYTE (1)
+#define SMI130_DATA_FRAME_ACCEL_Y_LSB_BYTE (2)
+#define SMI130_DATA_FRAME_ACCEL_Y_MSB_BYTE (3)
+#define SMI130_DATA_FRAME_ACCEL_Z_LSB_BYTE (4)
+#define SMI130_DATA_FRAME_ACCEL_Z_MSB_BYTE (5)
+
+#define SMI130_TEMP_LSB_BYTE (0)
+#define SMI130_TEMP_MSB_BYTE (1)
+
+#define SMI130_FIFO_LENGTH_LSB_BYTE (0)
+#define SMI130_FIFO_LENGTH_MSB_BYTE (1)
+
+#define SMI130_STEP_COUNT_LSB_BYTE (0)
+#define SMI130_STEP_COUNT_MSB_BYTE (1)
+/****************************************************/
+/**\name ERROR CODES */
+/***************************************************/
+
+#define E_SMI130_NULL_PTR ((s8)-127)
+#define E_SMI130_COMM_RES ((s8)-1)
+#define E_SMI130_OUT_OF_RANGE ((s8)-2)
+#define E_SMI130_BUSY ((s8)-3)
+#define SUCCESS ((u8)0)
+#define ERROR ((s8)-1)
+
+/* Constants */
+#define SMI130_NULL (0)
+#define SMI130_DELAY_SETTLING_TIME (5)
+/*This refers SMI130 return type as s8 */
+#define SMI130_RETURN_FUNCTION_TYPE s8
+/****************************************************/
+/**\name REGISTER DEFINITIONS */
+/***************************************************/
+/*******************/
+/**\name CHIP ID */
+/*******************/
+#define SMI130_USER_CHIP_ID_ADDR (0x00)
+/*******************/
+/**\name ERROR STATUS */
+/*******************/
+#define SMI130_USER_ERROR_ADDR (0X02)
+/*******************/
+/**\name POWER MODE STATUS */
+/*******************/
+#define SMI130_USER_PMU_STAT_ADDR (0X03)
+/*******************/
+/**\name MAG DATA REGISTERS */
+/*******************/
+#define SMI130_USER_DATA_0_ADDR (0X04)
+#define SMI130_USER_DATA_1_ADDR (0X05)
+#define SMI130_USER_DATA_2_ADDR (0X06)
+#define SMI130_USER_DATA_3_ADDR (0X07)
+#define SMI130_USER_DATA_4_ADDR (0X08)
+#define SMI130_USER_DATA_5_ADDR (0X09)
+#define SMI130_USER_DATA_6_ADDR (0X0A)
+#define SMI130_USER_DATA_7_ADDR (0X0B)
+/*******************/
+/**\name GYRO DATA REGISTERS */
+/*******************/
+#define SMI130_USER_DATA_8_ADDR (0X0C)
+#define SMI130_USER_DATA_9_ADDR (0X0D)
+#define SMI130_USER_DATA_10_ADDR (0X0E)
+#define SMI130_USER_DATA_11_ADDR (0X0F)
+#define SMI130_USER_DATA_12_ADDR (0X10)
+#define SMI130_USER_DATA_13_ADDR (0X11)
+#define SMI130_USER_DATA_14_ADDR (0X12)
+#define SMI130_USER_DATA_15_ADDR (0X13)
+/*******************/
+/**\name ACCEL DATA REGISTERS */
+/*******************/
+#define SMI130_USER_DATA_16_ADDR (0X14)
+#define SMI130_USER_DATA_17_ADDR (0X15)
+#define SMI130_USER_DATA_18_ADDR (0X16)
+#define SMI130_USER_DATA_19_ADDR (0X17)
+/*******************/
+/**\name SENSOR TIME REGISTERS */
+/*******************/
+#define SMI130_USER_SENSORTIME_0_ADDR (0X18)
+#define SMI130_USER_SENSORTIME_1_ADDR (0X19)
+#define SMI130_USER_SENSORTIME_2_ADDR (0X1A)
+/*******************/
+/**\name STATUS REGISTER FOR SENSOR STATUS FLAG */
+/*******************/
+#define SMI130_USER_STAT_ADDR (0X1B)
+/*******************/
+/**\name INTERRUPY STATUS REGISTERS */
+/*******************/
+#define SMI130_USER_INTR_STAT_0_ADDR (0X1C)
+#define SMI130_USER_INTR_STAT_1_ADDR (0X1D)
+#define SMI130_USER_INTR_STAT_2_ADDR (0X1E)
+#define SMI130_USER_INTR_STAT_3_ADDR (0X1F)
+/*******************/
+/**\name TEMPERATURE REGISTERS */
+/*******************/
+#define SMI130_USER_TEMPERATURE_0_ADDR (0X20)
+#define SMI130_USER_TEMPERATURE_1_ADDR (0X21)
+/*******************/
+/**\name FIFO REGISTERS */
+/*******************/
+#define SMI130_USER_FIFO_LENGTH_0_ADDR (0X22)
+#define SMI130_USER_FIFO_LENGTH_1_ADDR (0X23)
+#define SMI130_USER_FIFO_DATA_ADDR (0X24)
+/***************************************************/
+/**\name ACCEL CONFIG REGISTERS FOR ODR, BANDWIDTH AND UNDERSAMPLING*/
+/******************************************************/
+#define SMI130_USER_ACCEL_CONFIG_ADDR (0X40)
+/*******************/
+/**\name ACCEL RANGE */
+/*******************/
+#define SMI130_USER_ACCEL_RANGE_ADDR (0X41)
+/***************************************************/
+/**\name GYRO CONFIG REGISTERS FOR ODR AND BANDWIDTH */
+/******************************************************/
+#define SMI130_USER_GYRO_CONFIG_ADDR (0X42)
+/*******************/
+/**\name GYRO RANGE */
+/*******************/
+#define SMI130_USER_GYRO_RANGE_ADDR (0X43)
+/***************************************************/
+/**\name MAG CONFIG REGISTERS FOR ODR*/
+/******************************************************/
+#define SMI130_USER_MAG_CONFIG_ADDR (0X44)
+/***************************************************/
+/**\name REGISTER FOR GYRO AND ACCEL DOWNSAMPLING RATES FOR FIFO*/
+/******************************************************/
+#define SMI130_USER_FIFO_DOWN_ADDR (0X45)
+/***************************************************/
+/**\name FIFO CONFIG REGISTERS*/
+/******************************************************/
+#define SMI130_USER_FIFO_CONFIG_0_ADDR (0X46)
+#define SMI130_USER_FIFO_CONFIG_1_ADDR (0X47)
+/***************************************************/
+/**\name MAG INTERFACE REGISTERS*/
+/******************************************************/
+#define SMI130_USER_MAG_IF_0_ADDR (0X4B)
+#define SMI130_USER_MAG_IF_1_ADDR (0X4C)
+#define SMI130_USER_MAG_IF_2_ADDR (0X4D)
+#define SMI130_USER_MAG_IF_3_ADDR (0X4E)
+#define SMI130_USER_MAG_IF_4_ADDR (0X4F)
+/***************************************************/
+/**\name INTERRUPT ENABLE REGISTERS*/
+/******************************************************/
+#define SMI130_USER_INTR_ENABLE_0_ADDR (0X50)
+#define SMI130_USER_INTR_ENABLE_1_ADDR (0X51)
+#define SMI130_USER_INTR_ENABLE_2_ADDR (0X52)
+#define SMI130_USER_INTR_OUT_CTRL_ADDR (0X53)
+/***************************************************/
+/**\name LATCH DURATION REGISTERS*/
+/******************************************************/
+#define SMI130_USER_INTR_LATCH_ADDR (0X54)
+/***************************************************/
+/**\name MAP INTERRUPT 1 and 2 REGISTERS*/
+/******************************************************/
+#define SMI130_USER_INTR_MAP_0_ADDR (0X55)
+#define SMI130_USER_INTR_MAP_1_ADDR (0X56)
+#define SMI130_USER_INTR_MAP_2_ADDR (0X57)
+/***************************************************/
+/**\name DATA SOURCE REGISTERS*/
+/******************************************************/
+#define SMI130_USER_INTR_DATA_0_ADDR (0X58)
+#define SMI130_USER_INTR_DATA_1_ADDR (0X59)
+/***************************************************/
+/**\name
+INTERRUPT THRESHOLD, HYSTERESIS, DURATION, MODE CONFIGURATION REGISTERS*/
+/******************************************************/
+#define SMI130_USER_INTR_LOWHIGH_0_ADDR (0X5A)
+#define SMI130_USER_INTR_LOWHIGH_1_ADDR (0X5B)
+#define SMI130_USER_INTR_LOWHIGH_2_ADDR (0X5C)
+#define SMI130_USER_INTR_LOWHIGH_3_ADDR (0X5D)
+#define SMI130_USER_INTR_LOWHIGH_4_ADDR (0X5E)
+#define SMI130_USER_INTR_MOTION_0_ADDR (0X5F)
+#define SMI130_USER_INTR_MOTION_1_ADDR (0X60)
+#define SMI130_USER_INTR_MOTION_2_ADDR (0X61)
+#define SMI130_USER_INTR_MOTION_3_ADDR (0X62)
+#define SMI130_USER_INTR_TAP_0_ADDR (0X63)
+#define SMI130_USER_INTR_TAP_1_ADDR (0X64)
+#define SMI130_USER_INTR_ORIENT_0_ADDR (0X65)
+#define SMI130_USER_INTR_ORIENT_1_ADDR (0X66)
+#define SMI130_USER_INTR_FLAT_0_ADDR (0X67)
+#define SMI130_USER_INTR_FLAT_1_ADDR (0X68)
+/***************************************************/
+/**\name FAST OFFSET CONFIGURATION REGISTER*/
+/******************************************************/
+#define SMI130_USER_FOC_CONFIG_ADDR (0X69)
+/***************************************************/
+/**\name MISCELLANEOUS CONFIGURATION REGISTER*/
+/******************************************************/
+#define SMI130_USER_CONFIG_ADDR (0X6A)
+/***************************************************/
+/**\name SERIAL INTERFACE SETTINGS REGISTER*/
+/******************************************************/
+#define SMI130_USER_IF_CONFIG_ADDR (0X6B)
+/***************************************************/
+/**\name GYRO POWER MODE TRIGGER REGISTER */
+/******************************************************/
+#define SMI130_USER_PMU_TRIGGER_ADDR (0X6C)
+/***************************************************/
+/**\name SELF_TEST REGISTER*/
+/******************************************************/
+#define SMI130_USER_SELF_TEST_ADDR (0X6D)
+/***************************************************/
+/**\name SPI,I2C SELECTION REGISTER*/
+/******************************************************/
+#define SMI130_USER_NV_CONFIG_ADDR (0x70)
+/***************************************************/
+/**\name ACCEL AND GYRO OFFSET REGISTERS*/
+/******************************************************/
+#define SMI130_USER_OFFSET_0_ADDR (0X71)
+#define SMI130_USER_OFFSET_1_ADDR (0X72)
+#define SMI130_USER_OFFSET_2_ADDR (0X73)
+#define SMI130_USER_OFFSET_3_ADDR (0X74)
+#define SMI130_USER_OFFSET_4_ADDR (0X75)
+#define SMI130_USER_OFFSET_5_ADDR (0X76)
+#define SMI130_USER_OFFSET_6_ADDR (0X77)
+/***************************************************/
+/**\name STEP COUNTER INTERRUPT REGISTERS*/
+/******************************************************/
+#define SMI130_USER_STEP_COUNT_0_ADDR (0X78)
+#define SMI130_USER_STEP_COUNT_1_ADDR (0X79)
+/***************************************************/
+/**\name STEP COUNTER CONFIGURATION REGISTERS*/
+/******************************************************/
+#define SMI130_USER_STEP_CONFIG_0_ADDR (0X7A)
+#define SMI130_USER_STEP_CONFIG_1_ADDR (0X7B)
+/***************************************************/
+/**\name COMMAND REGISTER*/
+/******************************************************/
+#define SMI130_CMD_COMMANDS_ADDR (0X7E)
+/***************************************************/
+/**\name PAGE REGISTERS*/
+/******************************************************/
+#define SMI130_CMD_EXT_MODE_ADDR (0X7F)
+#define SMI130_COM_C_TRIM_FIVE_ADDR (0X05)
+
+/****************************************************/
+/**\name SHIFT VALUE DEFINITION */
+/***************************************************/
+#define SMI130_SHIFT_BIT_POSITION_BY_01_BIT (1)
+#define SMI130_SHIFT_BIT_POSITION_BY_02_BITS (2)
+#define SMI130_SHIFT_BIT_POSITION_BY_03_BITS (3)
+#define SMI130_SHIFT_BIT_POSITION_BY_04_BITS (4)
+#define SMI130_SHIFT_BIT_POSITION_BY_05_BITS (5)
+#define SMI130_SHIFT_BIT_POSITION_BY_06_BITS (6)
+#define SMI130_SHIFT_BIT_POSITION_BY_07_BITS (7)
+#define SMI130_SHIFT_BIT_POSITION_BY_08_BITS (8)
+#define SMI130_SHIFT_BIT_POSITION_BY_09_BITS (9)
+#define SMI130_SHIFT_BIT_POSITION_BY_12_BITS (12)
+#define SMI130_SHIFT_BIT_POSITION_BY_13_BITS (13)
+#define SMI130_SHIFT_BIT_POSITION_BY_14_BITS (14)
+#define SMI130_SHIFT_BIT_POSITION_BY_15_BITS (15)
+#define SMI130_SHIFT_BIT_POSITION_BY_16_BITS (16)
+
+/****************************************************/
+/**\name DEFINITIONS USED FOR YAMAHA-YAS532 */
+/***************************************************/
+#define YAS532_MAG_STATE_NORMAL (0)
+#define YAS532_MAG_STATE_INIT_COIL (1)
+#define YAS532_MAG_STATE_MEASURE_OFFSET (2)
+#define YAS532_MAG_INITCOIL_TIMEOUT (1000)
+#define YAS532_MAG_NOTRANS_POSITION (3)
+#define YAS532_DEFAULT_SENSOR_DELAY (50)
+#define YAS532_DATA_OVERFLOW (8190)
+#define YAS532_DATA_UNDERFLOW (0)
+#define YAS532_MAG_LOG (20)
+#define YAS532_MAG_TEMPERATURE_LOG (10)
+#define YAS532_TEMP20DEGREE_TYPICAL (390)
+#define YAS532_VERSION_AC_COEF_X (850)
+#define YAS532_VERSION_AC_COEF_Y1 (750)
+#define YAS532_VERSION_AC_COEF_Y2 (750)
+#define YAS532_DATA_CENTER (4096)
+/****************************************************/
+/**\name YAMAHA-YAS532 OFFSET DEFINITION */
+/***************************************************/
+static const s8 INVALID_OFFSET[] = {0x7f, 0x7f, 0x7f};
+#define set_vector(to, from) \
+ {int _l; for (_l = 0; _l < 3; _l++) (to)[_l] = (from)[_l]; }
+#define is_valid_offset(a) \
+ (((a)[0] <= 31) && ((a)[1] <= 31) && ((a)[2] <= 31) \
+ && (-31 <= (a)[0]) && (-31 <= (a)[1]) && (-31 <= (a)[2]))
+
+/**************************************************/
+/**\name YAS532 CALIB DATA DEFINITIONS */
+/*************************************************/
+
+
+/* register address of YAS532*/
+#define SMI130_YAS532_TESTR1 (0x88)
+#define SMI130_YAS532_TESTR2 (0x89)
+#define SMI130_YAS532_RCOIL (0x81)
+#define SMI130_YAS532_COMMAND_REGISTER (0x82)
+#define SMI130_YAS532_DATA_REGISTER (0xB0)
+/* calib data register definition*/
+#define SMI130_YAS532_CALIB_CX (0x90)
+#define SMI130_YAS532_CALIB_CY1 (0x91)
+#define SMI130_YAS532_CALIB_CY2 (0x92)
+#define SMI130_YAS532_CALIB1 (0x93)
+#define SMI130_YAS532_CALIB2 (0x94)
+#define SMI130_YAS532_CALIB3 (0x95)
+#define SMI130_YAS532_CALIB4 (0x96)
+#define SMI130_YAS532_CALIB5 (0x97)
+#define SMI130_YAS532_CLAIB6 (0x98)
+#define SMI130_YAS532_CALIB7 (0x99)
+#define SMI130_YAS532_CALIB8 (0x9A)
+#define SMI130_YAS532_CALIIB9 (0x9B)
+#define SMI130_YAS532_CALIB10 (0x9C)
+#define SMI130_YAS532_CALIB11 (0x9D)
+/* offset definition */
+#define SMI130_YAS532_OFFSET_X (0x85)
+#define SMI130_YAS532_OFFSET_Y (0x86)
+#define SMI130_YAS532_OFFSET_Z (0x87)
+/* data to write register for yas532*/
+#define SMI130_YAS532_WRITE_TESTR1 (0x00)
+#define SMI130_YAS532_WRITE_TESTR2 (0x00)
+#define SMI130_YAS532_WRITE_RCOIL (0x00)
+/**************************************************/
+/**\name YAS537 DEFINITION */
+/*************************************************/
+
+#define YAS537_SRSTR_DATA (0x02)
+#define YAS537_WRITE_A_D_CONVERTER (0x03)
+#define YAS537_WRITE_A_D_CONVERTER2 (0xF8)
+#define YAS537_WRITE_FILTER (0x08)
+#define YAS537_WRITE_CONFR (0x08)
+#define YAS537_WRITE_TEMP_CALIB (0xFF)
+#define YAS537_SET_COMMAND_REGISTER (0x01)
+
+/**************************************************/
+/**\name YAS537 REGISTER DEFINITION */
+/*************************************************/
+#define YAS537_REG_SRSTR (0x90)
+#define YAS537_REG_CALR_C0 (0xC0)
+#define YAS537_REG_CALR_C1 (0xC1)
+#define YAS537_REG_CALR_C2 (0xC2)
+#define YAS537_REG_CALR_C3 (0xC3)
+#define YAS537_REG_CALR_C4 (0xC4)
+#define YAS537_REG_CALR_C5 (0xC5)
+#define YAS537_REG_CALR_C6 (0xC6)
+#define YAS537_REG_CALR_C7 (0xC7)
+#define YAS537_REG_CALR_C8 (0xC8)
+#define YAS537_REG_CALR_C9 (0xC9)
+#define YAS537_REG_CALR_CA (0xCA)
+#define YAS537_REG_CALR_CB (0xCB)
+#define YAS537_REG_CALR_CC (0xCC)
+#define YAS537_REG_CALR_CD (0xCD)
+#define YAS537_REG_CALR_CE (0xCE)
+#define YAS537_REG_CALR_CF (0xCF)
+#define YAS537_REG_CALR_DO (0xD0)
+#define YAS537_REG_MTCR (0x93)
+#define YAS537_REG_CONFR (0x82)
+#define SMI130_REG_YAS537_CMDR (0x81)
+#define YAS537_REG_OXR (0x84)
+#define YAS537_REG_AVRR (0x87)
+#define YAS537_REG_HCKR (0x88)
+#define YAS537_REG_LCKR (0x89)
+#define YAS537_REG_ADCCALR (0x91)
+#define YAS537_REG_ADCCALR_ONE (0x92)
+#define YAS537_REG_OCR (0x9E)
+#define YAS537_REG_TRMR (0x9F)
+#define YAS537_REG_TEMPERATURE_0 (0xB0)
+#define YAS537_REG_TEMPERATURE_1 (0xB1)
+#define YAS537_REG_DATA_X_0 (0xB2)
+#define YAS537_REG_DATA_X_1 (0xB3)
+#define YAS537_REG_DATA_Y1_0 (0xB4)
+#define YAS537_REG_DATA_Y1_1 (0xB5)
+#define YAS537_REG_DATA_Y2_0 (0xB6)
+#define YAS537_REG_DATA_Y2_1 (0xB7)
+#define YAS537_MAG_STATE_NORMAL (0)
+#define YAS537_MAG_STATE_INIT_COIL (1)
+#define YAS537_MAG_STATE_RECORD_DATA (2)
+#define YAS537_DATA_UNDERFLOW (0)
+#define YAS537_DATA_OVERFLOW (16383)
+/****************************************************/
+/**\name YAS537_set vector */
+/***************************************************/
+#define yas537_set_vector(to, from) \
+ {int _l; for (_l = 0; _l < 3; _l++) (to)[_l] = (from)[_l]; }
+
+#ifndef ABS
+#define ABS(a) ((a) > 0 ? (a) : -(a)) /*!< Absolute value */
+#endif
+/****************************************************/
+/**\name AKM09911 AND AKM09912 DEFINITION */
+/***************************************************/
+#define AKM09912_SENSITIVITY_DIV (256)
+#define AKM09912_SENSITIVITY (128)
+#define AKM09911_SENSITIVITY_DIV (128)
+#define AKM_ASAX (0)
+#define AKM_ASAY (1)
+#define AKM_ASAZ (2)
+#define AKM_POWER_DOWN_MODE_DATA (0x00)
+#define AKM_FUSE_ROM_MODE (0x1F)
+#define AKM_POWER_MODE_REG (0x31)
+#define AKM_SINGLE_MEASUREMENT_MODE (0x01)
+#define AKM_DATA_REGISTER (0x11)
+/*! AKM09912 Register definition */
+#define AKM09912_CHIP_ID_REG (0x01)
+/****************************************************/
+/**\name BMM150 DEFINITION */
+/***************************************************/
+#define SMI130_BMM150_SET_POWER_CONTROL (0x01)
+#define SMI130_BMM150_MAX_RETRY_WAKEUP (5)
+#define SMI130_BMM150_POWER_ON (0x01)
+#define SMI130_BMM150_POWER_OFF (0x00)
+#define SMI130_BMM150_FORCE_MODE (0x02)
+#define SMI130_BMM150_POWER_ON_SUCCESS (0)
+#define SMI130_BMM150_POWER_ON_FAIL ((s8)-1)
+
+#define SMI130_BMM150_DIG_X1 (0)
+#define SMI130_BMM150_DIG_Y1 (1)
+#define SMI130_BMM150_DIG_X2 (2)
+#define SMI130_BMM150_DIG_Y3 (3)
+#define SMI130_BMM150_DIG_XY1 (4)
+#define SMI130_BMM150_DIG_XY2 (5)
+#define SMI130_BMM150_DIG_Z1_LSB (6)
+#define SMI130_BMM150_DIG_Z1_MSB (7)
+#define SMI130_BMM150_DIG_Z2_LSB (8)
+#define SMI130_BMM150_DIG_Z2_MSB (9)
+#define SMI130_BMM150_DIG_DIG_Z3_LSB (10)
+#define SMI130_BMM150_DIG_DIG_Z3_MSB (11)
+#define SMI130_BMM150_DIG_DIG_Z4_LSB (12)
+#define SMI130_BMM150_DIG_DIG_Z4_MSB (13)
+#define SMI130_BMM150_DIG_DIG_XYZ1_LSB (14)
+#define SMI130_BMM150_DIG_DIG_XYZ1_MSB (15)
+
+/**************************************************************/
+/**\name STRUCTURE DEFINITIONS */
+/**************************************************************/
+/*!
+* @brief smi130 structure
+* This structure holds all relevant information about smi130
+*/
+struct smi130_t {
+u8 chip_id;/**< chip id of SMI130 */
+u8 dev_addr;/**< device address of SMI130 */
+s8 mag_manual_enable;/**< used for check the mag manual/auto mode status */
+SMI130_WR_FUNC_PTR;/**< bus write function pointer */
+SMI130_RD_FUNC_PTR;/**< bus read function pointer */
+SMI130_BRD_FUNC_PTR;/**< burst write function pointer */
+void (*delay_msec)(SMI130_MDELAY_DATA_TYPE);/**< delay function pointer */
+};
+/*!
+ * @brief Structure containing bmm150 and akm09911
+ * magnetometer values for x,y and
+ * z-axis in s16
+ */
+struct smi130_mag_t {
+s16 x;/**< BMM150 and AKM09911 and AKM09912 X raw data*/
+s16 y;/**< BMM150 and AKM09911 and AKM09912 Y raw data*/
+s16 z;/**< BMM150 and AKM09911 and AKM09912 Z raw data*/
+};
+/*!
+ * @brief Structure containing bmm150 xyz data and temperature
+ */
+struct smi130_mag_xyzr_t {
+s16 x;/**< BMM150 X raw data*/
+s16 y;/**< BMM150 Y raw data*/
+s16 z;/**<BMM150 Z raw data*/
+u16 r;/**<BMM150 R raw data*/
+};
+/*!
+ * @brief Structure containing gyro xyz data
+ */
+struct smi130_gyro_t {
+s16 x;/**<gyro X data*/
+s16 y;/**<gyro Y data*/
+s16 z;/**<gyro Z data*/
+};
+/*!
+ * @brief Structure containing accel xyz data
+ */
+struct smi130_accel_t {
+s16 x;/**<accel X data*/
+s16 y;/**<accel Y data*/
+s16 z;/**<accel Z data*/
+};
+/*!
+ * @brief Structure bmm150 mag compensated data with s32 output
+ */
+struct smi130_mag_xyz_s32_t {
+s16 x;/**<BMM150 X compensated data*/
+s16 y;/**<BMM150 Y compensated data*/
+s16 z;/**<BMM150 Z compensated data*/
+};
+/*!
+ * @brief Structure bmm150 mag trim data
+ */
+struct trim_data_t {
+s8 dig_x1;/**<BMM150 trim x1 data*/
+s8 dig_y1;/**<BMM150 trim y1 data*/
+
+s8 dig_x2;/**<BMM150 trim x2 data*/
+s8 dig_y2;/**<BMM150 trim y2 data*/
+
+u16 dig_z1;/**<BMM150 trim z1 data*/
+s16 dig_z2;/**<BMM150 trim z2 data*/
+s16 dig_z3;/**<BMM150 trim z3 data*/
+s16 dig_z4;/**<BMM150 trim z4 data*/
+
+u8 dig_xy1;/**<BMM150 trim xy1 data*/
+s8 dig_xy2;/**<BMM150 trim xy2 data*/
+
+u16 dig_xyz1;/**<BMM150 trim xyz1 data*/
+};
+
+/*!
+* @brief Structure for reading AKM compensating data
+*/
+struct bosch_akm_sensitivity_data_t {
+u8 asax;/**<AKM09911 and AKM09912 X sensitivity data*/
+u8 asay;/**<AKM09911 and AKM09912 Y sensitivity data*/
+u8 asaz;/**<AKM09911 and AKM09912 Z sensitivity data*/
+};
+/*!
+* @brief YAMAHA-YAS532 struct
+* Calibration YAS532 data struct
+*/
+struct bosch_yas532_calib_data_t {
+s32 cx;/**<YAS532 calib cx data */
+s32 cy1;/**<YAS532 calib cy1 data */
+s32 cy2;/**<YAS532 calib cy2 data */
+s32 a2;/**<YAS532 calib a2 data */
+s32 a3;/**<YAS532 calib a3 data */
+s32 a4;/**<YAS532 calib a4 data */
+s32 a5;/**<YAS532 calib a5 data */
+s32 a6;/**<YAS532 calib a6 data */
+s32 a7;/**<YAS532 calib a7 data */
+s32 a8;/**<YAS532 calib a8 data */
+s32 a9;/**<YAS532 calib a9 data */
+s32 k;/**<YAS532 calib k data */
+s8 rxy1y2[3];/**<YAS532 calib rxy1y2 data */
+u8 fxy1y2[3];/**<YAS532 calib fxy1y2 data */
+};
+/*!
+* @brief YAS532 Temperature structure
+*/
+#if YAS532_MAG_LOG < YAS532_MAG_TEMPERATURE_LOG
+struct yas_temp_filter_t {
+u16 log[YAS532_MAG_TEMPERATURE_LOG];/**<YAS532 temp log array */
+u8 num;/**< used for increment the index */
+u8 idx;/**< used for increment the index */
+};
+#endif
+/*!
+* @brief YAS532 sensor initialization
+*/
+struct yas532_t {
+struct bosch_yas532_calib_data_t calib_yas532;/**< calib data */
+s8 measure_state;/**< update measure state */
+s8 v_hard_offset_s8[3];/**< offset write array*/
+s32 coef[3];/**< co efficient data */
+s8 overflow;/**< over flow condition check */
+u8 dev_id;/**< device id information */
+const s8 *transform;/**< transform condition check */
+#if YAS532_MAG_LOG < YAS532_MAG_TEMPERATURE_LOG
+struct yas_temp_filter_t temp_data;/**< temp data */
+#endif
+u16 last_raw[4];/**< raw data */
+};
+/*!
+* @brief Used for reading the YAS532 XYZ data
+*/
+struct yas532_vector {
+s32 yas532_vector_xyz[3];/**< YAS532 compensated xyz data*/
+};
+/**
+ * @struct yas_vector
+ * @brief Stores the sensor data
+ */
+struct yas_vector {
+ s32 yas537_vector_xyz[3]; /*!< vector data */
+};
+/*!
+* @brief YAMAHA-YAS532 struct
+* Calibration YAS532 data struct
+*/
+struct bosch_yas537_calib_data_t {
+s8 a2;/**<YAS532 calib a2 data */
+s8 a3;/**<YAS532 calib a3 data */
+s8 a4;/**<YAS532 calib a4 data */
+s16 a5;/**<YAS532 calib a5 data */
+s8 a6;/**<YAS532 calib a6 data */
+s8 a7;/**<YAS532 calib a7 data */
+s8 a8;/**<YAS532 calib a8 data */
+s16 a9;/**<YAS532 calib a9 data */
+u8 k;/**<YAS532 calib k data */
+u8 ver;/**<YAS532 calib ver data*/
+};
+/*!
+* @brief YAS537 sensor initialization
+*/
+struct yas537_t {
+struct bosch_yas537_calib_data_t calib_yas537;/**< calib data */
+s8 measure_state;/**< update measure state */
+s8 hard_offset[3];/**< offset write array*/
+u16 last_after_rcoil[3];/**< rcoil write array*/
+s32 coef[3];/**< co efficient data */
+s8 overflow;/**< over flow condition check */
+u8 dev_id;/**< device id information */
+u8 average;/**<average selection for offset configuration*/
+const s8 *transform;/**< transform condition check */
+u16 last_raw[4];/**< raw data */
+struct yas_vector xyz; /*!< X, Y, Z measurement data of the sensor */
+};
+/**************************************************************/
+/**\name USER DATA REGISTERS DEFINITION START */
+/**************************************************************/
+
+/**************************************************************/
+/**\name CHIP ID LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* Chip ID Description - Reg Addr --> (0x00), Bit --> 0...7 */
+#define SMI130_USER_CHIP_ID__POS (0)
+#define SMI130_USER_CHIP_ID__MSK (0xFF)
+#define SMI130_USER_CHIP_ID__LEN (8)
+#define SMI130_USER_CHIP_ID__REG (SMI130_USER_CHIP_ID_ADDR)
+/**************************************************************/
+/**\name ERROR STATUS LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* Error Description - Reg Addr --> (0x02), Bit --> 0 */
+#define SMI130_USER_ERR_STAT__POS (0)
+#define SMI130_USER_ERR_STAT__LEN (8)
+#define SMI130_USER_ERR_STAT__MSK (0xFF)
+#define SMI130_USER_ERR_STAT__REG (SMI130_USER_ERROR_ADDR)
+
+#define SMI130_USER_FATAL_ERR__POS (0)
+#define SMI130_USER_FATAL_ERR__LEN (1)
+#define SMI130_USER_FATAL_ERR__MSK (0x01)
+#define SMI130_USER_FATAL_ERR__REG (SMI130_USER_ERROR_ADDR)
+
+/* Error Description - Reg Addr --> (0x02), Bit --> 1...4 */
+#define SMI130_USER_ERR_CODE__POS (1)
+#define SMI130_USER_ERR_CODE__LEN (4)
+#define SMI130_USER_ERR_CODE__MSK (0x1E)
+#define SMI130_USER_ERR_CODE__REG (SMI130_USER_ERROR_ADDR)
+
+/* Error Description - Reg Addr --> (0x02), Bit --> 5 */
+#define SMI130_USER_I2C_FAIL_ERR__POS (5)
+#define SMI130_USER_I2C_FAIL_ERR__LEN (1)
+#define SMI130_USER_I2C_FAIL_ERR__MSK (0x20)
+#define SMI130_USER_I2C_FAIL_ERR__REG (SMI130_USER_ERROR_ADDR)
+
+/* Error Description - Reg Addr --> (0x02), Bit --> 6 */
+#define SMI130_USER_DROP_CMD_ERR__POS (6)
+#define SMI130_USER_DROP_CMD_ERR__LEN (1)
+#define SMI130_USER_DROP_CMD_ERR__MSK (0x40)
+#define SMI130_USER_DROP_CMD_ERR__REG (SMI130_USER_ERROR_ADDR)
+/**************************************************************/
+/**\name MAG DATA READY LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* Error Description - Reg Addr --> (0x02), Bit --> 7 */
+#define SMI130_USER_MAG_DADA_RDY_ERR__POS (7)
+#define SMI130_USER_MAG_DADA_RDY_ERR__LEN (1)
+#define SMI130_USER_MAG_DADA_RDY_ERR__MSK (0x80)
+#define SMI130_USER_MAG_DADA_RDY_ERR__REG (SMI130_USER_ERROR_ADDR)
+/**************************************************************/
+/**\name MAG POWER MODE LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* PMU_Status Description of MAG - Reg Addr --> (0x03), Bit --> 1..0 */
+#define SMI130_USER_MAG_POWER_MODE_STAT__POS (0)
+#define SMI130_USER_MAG_POWER_MODE_STAT__LEN (2)
+#define SMI130_USER_MAG_POWER_MODE_STAT__MSK (0x03)
+#define SMI130_USER_MAG_POWER_MODE_STAT__REG \
+(SMI130_USER_PMU_STAT_ADDR)
+/**************************************************************/
+/**\name GYRO POWER MODE LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* PMU_Status Description of GYRO - Reg Addr --> (0x03), Bit --> 3...2 */
+#define SMI130_USER_GYRO_POWER_MODE_STAT__POS (2)
+#define SMI130_USER_GYRO_POWER_MODE_STAT__LEN (2)
+#define SMI130_USER_GYRO_POWER_MODE_STAT__MSK (0x0C)
+#define SMI130_USER_GYRO_POWER_MODE_STAT__REG \
+(SMI130_USER_PMU_STAT_ADDR)
+/**************************************************************/
+/**\name ACCEL POWER MODE LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* PMU_Status Description of ACCEL - Reg Addr --> (0x03), Bit --> 5...4 */
+#define SMI130_USER_ACCEL_POWER_MODE_STAT__POS (4)
+#define SMI130_USER_ACCEL_POWER_MODE_STAT__LEN (2)
+#define SMI130_USER_ACCEL_POWER_MODE_STAT__MSK (0x30)
+#define SMI130_USER_ACCEL_POWER_MODE_STAT__REG \
+(SMI130_USER_PMU_STAT_ADDR)
+/**************************************************************/
+/**\name MAG DATA XYZ LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* Mag_X(LSB) Description - Reg Addr --> (0x04), Bit --> 0...7 */
+#define SMI130_USER_DATA_0_MAG_X_LSB__POS (0)
+#define SMI130_USER_DATA_0_MAG_X_LSB__LEN (8)
+#define SMI130_USER_DATA_0_MAG_X_LSB__MSK (0xFF)
+#define SMI130_USER_DATA_0_MAG_X_LSB__REG (SMI130_USER_DATA_0_ADDR)
+
+/* Mag_X(LSB) Description - Reg Addr --> (0x04), Bit --> 3...7 */
+#define SMI130_USER_DATA_MAG_X_LSB__POS (3)
+#define SMI130_USER_DATA_MAG_X_LSB__LEN (5)
+#define SMI130_USER_DATA_MAG_X_LSB__MSK (0xF8)
+#define SMI130_USER_DATA_MAG_X_LSB__REG (SMI130_USER_DATA_0_ADDR)
+
+/* Mag_X(MSB) Description - Reg Addr --> (0x05), Bit --> 0...7 */
+#define SMI130_USER_DATA_1_MAG_X_MSB__POS (0)
+#define SMI130_USER_DATA_1_MAG_X_MSB__LEN (8)
+#define SMI130_USER_DATA_1_MAG_X_MSB__MSK (0xFF)
+#define SMI130_USER_DATA_1_MAG_X_MSB__REG (SMI130_USER_DATA_1_ADDR)
+
+/* Mag_Y(LSB) Description - Reg Addr --> (0x06), Bit --> 0...7 */
+#define SMI130_USER_DATA_2_MAG_Y_LSB__POS (0)
+#define SMI130_USER_DATA_2_MAG_Y_LSB__LEN (8)
+#define SMI130_USER_DATA_2_MAG_Y_LSB__MSK (0xFF)
+#define SMI130_USER_DATA_2_MAG_Y_LSB__REG (SMI130_USER_DATA_2_ADDR)
+
+/* Mag_Y(LSB) Description - Reg Addr --> (0x06), Bit --> 3...7 */
+#define SMI130_USER_DATA_MAG_Y_LSB__POS (3)
+#define SMI130_USER_DATA_MAG_Y_LSB__LEN (5)
+#define SMI130_USER_DATA_MAG_Y_LSB__MSK (0xF8)
+#define SMI130_USER_DATA_MAG_Y_LSB__REG (SMI130_USER_DATA_2_ADDR)
+
+/* Mag_Y(MSB) Description - Reg Addr --> (0x07), Bit --> 0...7 */
+#define SMI130_USER_DATA_3_MAG_Y_MSB__POS (0)
+#define SMI130_USER_DATA_3_MAG_Y_MSB__LEN (8)
+#define SMI130_USER_DATA_3_MAG_Y_MSB__MSK (0xFF)
+#define SMI130_USER_DATA_3_MAG_Y_MSB__REG (SMI130_USER_DATA_3_ADDR)
+
+/* Mag_Z(LSB) Description - Reg Addr --> (0x08), Bit --> 0...7 */
+#define SMI130_USER_DATA_4_MAG_Z_LSB__POS (0)
+#define SMI130_USER_DATA_4_MAG_Z_LSB__LEN (8)
+#define SMI130_USER_DATA_4_MAG_Z_LSB__MSK (0xFF)
+#define SMI130_USER_DATA_4_MAG_Z_LSB__REG (SMI130_USER_DATA_4_ADDR)
+
+/* Mag_X(LSB) Description - Reg Addr --> (0x08), Bit --> 3...7 */
+#define SMI130_USER_DATA_MAG_Z_LSB__POS (1)
+#define SMI130_USER_DATA_MAG_Z_LSB__LEN (7)
+#define SMI130_USER_DATA_MAG_Z_LSB__MSK (0xFE)
+#define SMI130_USER_DATA_MAG_Z_LSB__REG (SMI130_USER_DATA_4_ADDR)
+
+/* Mag_Z(MSB) Description - Reg Addr --> (0x09), Bit --> 0...7 */
+#define SMI130_USER_DATA_5_MAG_Z_MSB__POS (0)
+#define SMI130_USER_DATA_5_MAG_Z_MSB__LEN (8)
+#define SMI130_USER_DATA_5_MAG_Z_MSB__MSK (0xFF)
+#define SMI130_USER_DATA_5_MAG_Z_MSB__REG (SMI130_USER_DATA_5_ADDR)
+
+/* RHALL(LSB) Description - Reg Addr --> (0x0A), Bit --> 0...7 */
+#define SMI130_USER_DATA_6_RHALL_LSB__POS (0)
+#define SMI130_USER_DATA_6_RHALL_LSB__LEN (8)
+#define SMI130_USER_DATA_6_RHALL_LSB__MSK (0xFF)
+#define SMI130_USER_DATA_6_RHALL_LSB__REG (SMI130_USER_DATA_6_ADDR)
+
+/* Mag_R(LSB) Description - Reg Addr --> (0x0A), Bit --> 3...7 */
+#define SMI130_USER_DATA_MAG_R_LSB__POS (2)
+#define SMI130_USER_DATA_MAG_R_LSB__LEN (6)
+#define SMI130_USER_DATA_MAG_R_LSB__MSK (0xFC)
+#define SMI130_USER_DATA_MAG_R_LSB__REG (SMI130_USER_DATA_6_ADDR)
+
+/* RHALL(MSB) Description - Reg Addr --> (0x0B), Bit --> 0...7 */
+#define SMI130_USER_DATA_7_RHALL_MSB__POS (0)
+#define SMI130_USER_DATA_7_RHALL_MSB__LEN (8)
+#define SMI130_USER_DATA_7_RHALL_MSB__MSK (0xFF)
+#define SMI130_USER_DATA_7_RHALL_MSB__REG (SMI130_USER_DATA_7_ADDR)
+/**************************************************************/
+/**\name GYRO DATA XYZ LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* GYR_X (LSB) Description - Reg Addr --> (0x0C), Bit --> 0...7 */
+#define SMI130_USER_DATA_8_GYRO_X_LSB__POS (0)
+#define SMI130_USER_DATA_8_GYRO_X_LSB__LEN (8)
+#define SMI130_USER_DATA_8_GYRO_X_LSB__MSK (0xFF)
+#define SMI130_USER_DATA_8_GYRO_X_LSB__REG (SMI130_USER_DATA_8_ADDR)
+
+/* GYR_X (MSB) Description - Reg Addr --> (0x0D), Bit --> 0...7 */
+#define SMI130_USER_DATA_9_GYRO_X_MSB__POS (0)
+#define SMI130_USER_DATA_9_GYRO_X_MSB__LEN (8)
+#define SMI130_USER_DATA_9_GYRO_X_MSB__MSK (0xFF)
+#define SMI130_USER_DATA_9_GYRO_X_MSB__REG (SMI130_USER_DATA_9_ADDR)
+
+/* GYR_Y (LSB) Description - Reg Addr --> 0x0E, Bit --> 0...7 */
+#define SMI130_USER_DATA_10_GYRO_Y_LSB__POS (0)
+#define SMI130_USER_DATA_10_GYRO_Y_LSB__LEN (8)
+#define SMI130_USER_DATA_10_GYRO_Y_LSB__MSK (0xFF)
+#define SMI130_USER_DATA_10_GYRO_Y_LSB__REG (SMI130_USER_DATA_10_ADDR)
+
+/* GYR_Y (MSB) Description - Reg Addr --> (0x0F), Bit --> 0...7 */
+#define SMI130_USER_DATA_11_GYRO_Y_MSB__POS (0)
+#define SMI130_USER_DATA_11_GYRO_Y_MSB__LEN (8)
+#define SMI130_USER_DATA_11_GYRO_Y_MSB__MSK (0xFF)
+#define SMI130_USER_DATA_11_GYRO_Y_MSB__REG (SMI130_USER_DATA_11_ADDR)
+
+/* GYR_Z (LSB) Description - Reg Addr --> (0x10), Bit --> 0...7 */
+#define SMI130_USER_DATA_12_GYRO_Z_LSB__POS (0)
+#define SMI130_USER_DATA_12_GYRO_Z_LSB__LEN (8)
+#define SMI130_USER_DATA_12_GYRO_Z_LSB__MSK (0xFF)
+#define SMI130_USER_DATA_12_GYRO_Z_LSB__REG (SMI130_USER_DATA_12_ADDR)
+
+/* GYR_Z (MSB) Description - Reg Addr --> (0x11), Bit --> 0...7 */
+#define SMI130_USER_DATA_13_GYRO_Z_MSB__POS (0)
+#define SMI130_USER_DATA_13_GYRO_Z_MSB__LEN (8)
+#define SMI130_USER_DATA_13_GYRO_Z_MSB__MSK (0xFF)
+#define SMI130_USER_DATA_13_GYRO_Z_MSB__REG (SMI130_USER_DATA_13_ADDR)
+/**************************************************************/
+/**\name ACCEL DATA XYZ LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* ACC_X (LSB) Description - Reg Addr --> (0x12), Bit --> 0...7 */
+#define SMI130_USER_DATA_14_ACCEL_X_LSB__POS (0)
+#define SMI130_USER_DATA_14_ACCEL_X_LSB__LEN (8)
+#define SMI130_USER_DATA_14_ACCEL_X_LSB__MSK (0xFF)
+#define SMI130_USER_DATA_14_ACCEL_X_LSB__REG (SMI130_USER_DATA_14_ADDR)
+
+/* ACC_X (MSB) Description - Reg Addr --> 0x13, Bit --> 0...7 */
+#define SMI130_USER_DATA_15_ACCEL_X_MSB__POS (0)
+#define SMI130_USER_DATA_15_ACCEL_X_MSB__LEN (8)
+#define SMI130_USER_DATA_15_ACCEL_X_MSB__MSK (0xFF)
+#define SMI130_USER_DATA_15_ACCEL_X_MSB__REG (SMI130_USER_DATA_15_ADDR)
+
+/* ACC_Y (LSB) Description - Reg Addr --> (0x14), Bit --> 0...7 */
+#define SMI130_USER_DATA_16_ACCEL_Y_LSB__POS (0)
+#define SMI130_USER_DATA_16_ACCEL_Y_LSB__LEN (8)
+#define SMI130_USER_DATA_16_ACCEL_Y_LSB__MSK (0xFF)
+#define SMI130_USER_DATA_16_ACCEL_Y_LSB__REG (SMI130_USER_DATA_16_ADDR)
+
+/* ACC_Y (MSB) Description - Reg Addr --> (0x15), Bit --> 0...7 */
+#define SMI130_USER_DATA_17_ACCEL_Y_MSB__POS (0)
+#define SMI130_USER_DATA_17_ACCEL_Y_MSB__LEN (8)
+#define SMI130_USER_DATA_17_ACCEL_Y_MSB__MSK (0xFF)
+#define SMI130_USER_DATA_17_ACCEL_Y_MSB__REG (SMI130_USER_DATA_17_ADDR)
+
+/* ACC_Z (LSB) Description - Reg Addr --> 0x16, Bit --> 0...7 */
+#define SMI130_USER_DATA_18_ACCEL_Z_LSB__POS (0)
+#define SMI130_USER_DATA_18_ACCEL_Z_LSB__LEN (8)
+#define SMI130_USER_DATA_18_ACCEL_Z_LSB__MSK (0xFF)
+#define SMI130_USER_DATA_18_ACCEL_Z_LSB__REG (SMI130_USER_DATA_18_ADDR)
+
+/* ACC_Z (MSB) Description - Reg Addr --> (0x17), Bit --> 0...7 */
+#define SMI130_USER_DATA_19_ACCEL_Z_MSB__POS (0)
+#define SMI130_USER_DATA_19_ACCEL_Z_MSB__LEN (8)
+#define SMI130_USER_DATA_19_ACCEL_Z_MSB__MSK (0xFF)
+#define SMI130_USER_DATA_19_ACCEL_Z_MSB__REG (SMI130_USER_DATA_19_ADDR)
+/**************************************************************/
+/**\name SENSOR TIME LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* SENSORTIME_0 (LSB) Description - Reg Addr --> (0x18), Bit --> 0...7 */
+#define SMI130_USER_SENSORTIME_0_SENSOR_TIME_LSB__POS (0)
+#define SMI130_USER_SENSORTIME_0_SENSOR_TIME_LSB__LEN (8)
+#define SMI130_USER_SENSORTIME_0_SENSOR_TIME_LSB__MSK (0xFF)
+#define SMI130_USER_SENSORTIME_0_SENSOR_TIME_LSB__REG \
+ (SMI130_USER_SENSORTIME_0_ADDR)
+
+/* SENSORTIME_1 (MSB) Description - Reg Addr --> (0x19), Bit --> 0...7 */
+#define SMI130_USER_SENSORTIME_1_SENSOR_TIME_MSB__POS (0)
+#define SMI130_USER_SENSORTIME_1_SENSOR_TIME_MSB__LEN (8)
+#define SMI130_USER_SENSORTIME_1_SENSOR_TIME_MSB__MSK (0xFF)
+#define SMI130_USER_SENSORTIME_1_SENSOR_TIME_MSB__REG \
+ (SMI130_USER_SENSORTIME_1_ADDR)
+
+/* SENSORTIME_2 (MSB) Description - Reg Addr --> (0x1A), Bit --> 0...7 */
+#define SMI130_USER_SENSORTIME_2_SENSOR_TIME_MSB__POS (0)
+#define SMI130_USER_SENSORTIME_2_SENSOR_TIME_MSB__LEN (8)
+#define SMI130_USER_SENSORTIME_2_SENSOR_TIME_MSB__MSK (0xFF)
+#define SMI130_USER_SENSORTIME_2_SENSOR_TIME_MSB__REG \
+ (SMI130_USER_SENSORTIME_2_ADDR)
+/**************************************************************/
+/**\name GYRO SELF TEST LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* Status Description - Reg Addr --> 0x1B, Bit --> 1 */
+#define SMI130_USER_STAT_GYRO_SELFTEST_OK__POS (1)
+#define SMI130_USER_STAT_GYRO_SELFTEST_OK__LEN (1)
+#define SMI130_USER_STAT_GYRO_SELFTEST_OK__MSK (0x02)
+#define SMI130_USER_STAT_GYRO_SELFTEST_OK__REG \
+ (SMI130_USER_STAT_ADDR)
+/**************************************************************/
+/**\name MAG MANUAL OPERATION LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* Status Description - Reg Addr --> 0x1B, Bit --> 2 */
+#define SMI130_USER_STAT_MAG_MANUAL_OPERATION__POS (2)
+#define SMI130_USER_STAT_MAG_MANUAL_OPERATION__LEN (1)
+#define SMI130_USER_STAT_MAG_MANUAL_OPERATION__MSK (0x04)
+#define SMI130_USER_STAT_MAG_MANUAL_OPERATION__REG \
+ (SMI130_USER_STAT_ADDR)
+/**************************************************************/
+/**\name FOC STATUS LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* Status Description - Reg Addr --> 0x1B, Bit --> 3 */
+#define SMI130_USER_STAT_FOC_RDY__POS (3)
+#define SMI130_USER_STAT_FOC_RDY__LEN (1)
+#define SMI130_USER_STAT_FOC_RDY__MSK (0x08)
+#define SMI130_USER_STAT_FOC_RDY__REG (SMI130_USER_STAT_ADDR)
+/**************************************************************/
+/**\name NVM READY LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* Status Description - Reg Addr --> 0x1B, Bit --> 4 */
+#define SMI130_USER_STAT_NVM_RDY__POS (4)
+#define SMI130_USER_STAT_NVM_RDY__LEN (1)
+#define SMI130_USER_STAT_NVM_RDY__MSK (0x10)
+#define SMI130_USER_STAT_NVM_RDY__REG (SMI130_USER_STAT_ADDR)
+/**************************************************************/
+/**\name DATA READY LENGTH, POSITION AND MASK FOR ACCEL, MAG AND GYRO*/
+/**************************************************************/
+/* Status Description - Reg Addr --> 0x1B, Bit --> 5 */
+#define SMI130_USER_STAT_DATA_RDY_MAG__POS (5)
+#define SMI130_USER_STAT_DATA_RDY_MAG__LEN (1)
+#define SMI130_USER_STAT_DATA_RDY_MAG__MSK (0x20)
+#define SMI130_USER_STAT_DATA_RDY_MAG__REG (SMI130_USER_STAT_ADDR)
+
+/* Status Description - Reg Addr --> 0x1B, Bit --> 6 */
+#define SMI130_USER_STAT_DATA_RDY_GYRO__POS (6)
+#define SMI130_USER_STAT_DATA_RDY_GYRO__LEN (1)
+#define SMI130_USER_STAT_DATA_RDY_GYRO__MSK (0x40)
+#define SMI130_USER_STAT_DATA_RDY_GYRO__REG (SMI130_USER_STAT_ADDR)
+
+/* Status Description - Reg Addr --> 0x1B, Bit --> 7 */
+#define SMI130_USER_STAT_DATA_RDY_ACCEL__POS (7)
+#define SMI130_USER_STAT_DATA_RDY_ACCEL__LEN (1)
+#define SMI130_USER_STAT_DATA_RDY_ACCEL__MSK (0x80)
+#define SMI130_USER_STAT_DATA_RDY_ACCEL__REG (SMI130_USER_STAT_ADDR)
+/**************************************************************/
+/**\name INTERRUPT STATUS LENGTH, POSITION AND MASK */
+/**************************************************************/
+/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 0 */
+#define SMI130_USER_INTR_STAT_0_STEP_INTR__POS (0)
+#define SMI130_USER_INTR_STAT_0_STEP_INTR__LEN (1)
+#define SMI130_USER_INTR_STAT_0_STEP_INTR__MSK (0x01)
+#define SMI130_USER_INTR_STAT_0_STEP_INTR__REG \
+ (SMI130_USER_INTR_STAT_0_ADDR)
+/**************************************************************/
+/**\name SIGNIFICANT INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 1 */
+#define SMI130_USER_INTR_STAT_0_SIGNIFICANT_INTR__POS (1)
+#define SMI130_USER_INTR_STAT_0_SIGNIFICANT_INTR__LEN (1)
+#define SMI130_USER_INTR_STAT_0_SIGNIFICANT_INTR__MSK (0x02)
+#define SMI130_USER_INTR_STAT_0_SIGNIFICANT_INTR__REG \
+ (SMI130_USER_INTR_STAT_0_ADDR)
+/**************************************************************/
+/**\name ANY_MOTION INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 2 */
+#define SMI130_USER_INTR_STAT_0_ANY_MOTION__POS (2)
+#define SMI130_USER_INTR_STAT_0_ANY_MOTION__LEN (1)
+#define SMI130_USER_INTR_STAT_0_ANY_MOTION__MSK (0x04)
+#define SMI130_USER_INTR_STAT_0_ANY_MOTION__REG \
+ (SMI130_USER_INTR_STAT_0_ADDR)
+/**************************************************************/
+/**\name PMU TRIGGER INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 3 */
+#define SMI130_USER_INTR_STAT_0_PMU_TRIGGER__POS 3
+#define SMI130_USER_INTR_STAT_0_PMU_TRIGGER__LEN (1)
+#define SMI130_USER_INTR_STAT_0_PMU_TRIGGER__MSK (0x08)
+#define SMI130_USER_INTR_STAT_0_PMU_TRIGGER__REG \
+ (SMI130_USER_INTR_STAT_0_ADDR)
+/**************************************************************/
+/**\name DOUBLE TAP INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 4 */
+#define SMI130_USER_INTR_STAT_0_DOUBLE_TAP_INTR__POS 4
+#define SMI130_USER_INTR_STAT_0_DOUBLE_TAP_INTR__LEN (1)
+#define SMI130_USER_INTR_STAT_0_DOUBLE_TAP_INTR__MSK (0x10)
+#define SMI130_USER_INTR_STAT_0_DOUBLE_TAP_INTR__REG \
+ (SMI130_USER_INTR_STAT_0_ADDR)
+/**************************************************************/
+/**\name SINGLE TAP INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 5 */
+#define SMI130_USER_INTR_STAT_0_SINGLE_TAP_INTR__POS 5
+#define SMI130_USER_INTR_STAT_0_SINGLE_TAP_INTR__LEN (1)
+#define SMI130_USER_INTR_STAT_0_SINGLE_TAP_INTR__MSK (0x20)
+#define SMI130_USER_INTR_STAT_0_SINGLE_TAP_INTR__REG \
+ (SMI130_USER_INTR_STAT_0_ADDR)
+/**************************************************************/
+/**\name ORIENT INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 6 */
+#define SMI130_USER_INTR_STAT_0_ORIENT__POS (6)
+#define SMI130_USER_INTR_STAT_0_ORIENT__LEN (1)
+#define SMI130_USER_INTR_STAT_0_ORIENT__MSK (0x40)
+#define SMI130_USER_INTR_STAT_0_ORIENT__REG \
+ (SMI130_USER_INTR_STAT_0_ADDR)
+/**************************************************************/
+/**\name FLAT INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_0 Description - Reg Addr --> 0x1C, Bit --> 7 */
+#define SMI130_USER_INTR_STAT_0_FLAT__POS (7)
+#define SMI130_USER_INTR_STAT_0_FLAT__LEN (1)
+#define SMI130_USER_INTR_STAT_0_FLAT__MSK (0x80)
+#define SMI130_USER_INTR_STAT_0_FLAT__REG \
+ (SMI130_USER_INTR_STAT_0_ADDR)
+/**************************************************************/
+/**\name HIGH_G INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_1 Description - Reg Addr --> 0x1D, Bit --> 2 */
+#define SMI130_USER_INTR_STAT_1_HIGH_G_INTR__POS (2)
+#define SMI130_USER_INTR_STAT_1_HIGH_G_INTR__LEN (1)
+#define SMI130_USER_INTR_STAT_1_HIGH_G_INTR__MSK (0x04)
+#define SMI130_USER_INTR_STAT_1_HIGH_G_INTR__REG \
+ (SMI130_USER_INTR_STAT_1_ADDR)
+/**************************************************************/
+/**\name LOW_G INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_1 Description - Reg Addr --> 0x1D, Bit --> 3 */
+#define SMI130_USER_INTR_STAT_1_LOW_G_INTR__POS (3)
+#define SMI130_USER_INTR_STAT_1_LOW_G_INTR__LEN (1)
+#define SMI130_USER_INTR_STAT_1_LOW_G_INTR__MSK (0x08)
+#define SMI130_USER_INTR_STAT_1_LOW_G_INTR__REG \
+ (SMI130_USER_INTR_STAT_1_ADDR)
+/**************************************************************/
+/**\name DATA READY INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_1 Description - Reg Addr --> 0x1D, Bit --> 4 */
+#define SMI130_USER_INTR_STAT_1_DATA_RDY_INTR__POS (4)
+#define SMI130_USER_INTR_STAT_1_DATA_RDY_INTR__LEN (1)
+#define SMI130_USER_INTR_STAT_1_DATA_RDY_INTR__MSK (0x10)
+#define SMI130_USER_INTR_STAT_1_DATA_RDY_INTR__REG \
+ (SMI130_USER_INTR_STAT_1_ADDR)
+/**************************************************************/
+/**\name FIFO FULL INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_1 Description - Reg Addr --> 0x1D, Bit --> 5 */
+#define SMI130_USER_INTR_STAT_1_FIFO_FULL_INTR__POS (5)
+#define SMI130_USER_INTR_STAT_1_FIFO_FULL_INTR__LEN (1)
+#define SMI130_USER_INTR_STAT_1_FIFO_FULL_INTR__MSK (0x20)
+#define SMI130_USER_INTR_STAT_1_FIFO_FULL_INTR__REG \
+ (SMI130_USER_INTR_STAT_1_ADDR)
+/**************************************************************/
+/**\name FIFO WATERMARK INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_1 Description - Reg Addr --> 0x1D, Bit --> 6 */
+#define SMI130_USER_INTR_STAT_1_FIFO_WM_INTR__POS (6)
+#define SMI130_USER_INTR_STAT_1_FIFO_WM_INTR__LEN (1)
+#define SMI130_USER_INTR_STAT_1_FIFO_WM_INTR__MSK (0x40)
+#define SMI130_USER_INTR_STAT_1_FIFO_WM_INTR__REG \
+ (SMI130_USER_INTR_STAT_1_ADDR)
+/**************************************************************/
+/**\name NO MOTION INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_1 Description - Reg Addr --> 0x1D, Bit --> 7 */
+#define SMI130_USER_INTR_STAT_1_NOMOTION_INTR__POS (7)
+#define SMI130_USER_INTR_STAT_1_NOMOTION_INTR__LEN (1)
+#define SMI130_USER_INTR_STAT_1_NOMOTION_INTR__MSK (0x80)
+#define SMI130_USER_INTR_STAT_1_NOMOTION_INTR__REG \
+ (SMI130_USER_INTR_STAT_1_ADDR)
+/**************************************************************/
+/**\name ANY MOTION-XYZ AXIS INTERRUPT STATUS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 0 */
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_X__POS (0)
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_X__LEN (1)
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_X__MSK (0x01)
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_X__REG \
+ (SMI130_USER_INTR_STAT_2_ADDR)
+
+/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 1 */
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_Y__POS (1)
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_Y__LEN (1)
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_Y__MSK (0x02)
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_Y__REG \
+ (SMI130_USER_INTR_STAT_2_ADDR)
+
+/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 2 */
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_Z__POS (2)
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_Z__LEN (1)
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_Z__MSK (0x04)
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_Z__REG \
+ (SMI130_USER_INTR_STAT_2_ADDR)
+/**************************************************************/
+/**\name ANY MOTION SIGN LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 3 */
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_SIGN__POS (3)
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_SIGN__LEN (1)
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_SIGN__MSK (0x08)
+#define SMI130_USER_INTR_STAT_2_ANY_MOTION_SIGN__REG \
+ (SMI130_USER_INTR_STAT_2_ADDR)
+/**************************************************************/
+/**\name TAP_XYZ AND SIGN LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 4 */
+#define SMI130_USER_INTR_STAT_2_TAP_FIRST_X__POS (4)
+#define SMI130_USER_INTR_STAT_2_TAP_FIRST_X__LEN (1)
+#define SMI130_USER_INTR_STAT_2_TAP_FIRST_X__MSK (0x10)
+#define SMI130_USER_INTR_STAT_2_TAP_FIRST_X__REG \
+ (SMI130_USER_INTR_STAT_2_ADDR)
+
+/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 5 */
+#define SMI130_USER_INTR_STAT_2_TAP_FIRST_Y__POS (5)
+#define SMI130_USER_INTR_STAT_2_TAP_FIRST_Y__LEN (1)
+#define SMI130_USER_INTR_STAT_2_TAP_FIRST_Y__MSK (0x20)
+#define SMI130_USER_INTR_STAT_2_TAP_FIRST_Y__REG \
+ (SMI130_USER_INTR_STAT_2_ADDR)
+
+/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 6 */
+#define SMI130_USER_INTR_STAT_2_TAP_FIRST_Z__POS (6)
+#define SMI130_USER_INTR_STAT_2_TAP_FIRST_Z__LEN (1)
+#define SMI130_USER_INTR_STAT_2_TAP_FIRST_Z__MSK (0x40)
+#define SMI130_USER_INTR_STAT_2_TAP_FIRST_Z__REG \
+ (SMI130_USER_INTR_STAT_2_ADDR)
+
+/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 7 */
+#define SMI130_USER_INTR_STAT_2_TAP_SIGN__POS (7)
+#define SMI130_USER_INTR_STAT_2_TAP_SIGN__LEN (1)
+#define SMI130_USER_INTR_STAT_2_TAP_SIGN__MSK (0x80)
+#define SMI130_USER_INTR_STAT_2_TAP_SIGN__REG \
+ (SMI130_USER_INTR_STAT_2_ADDR)
+/**************************************************************/
+/**\name INTERRUPT SATAUS FOR WHOLE 0x1E LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_2 Description - Reg Addr --> 0x1E, Bit --> 0...7 */
+#define SMI130_USER_INTR_STAT_2__POS (0)
+#define SMI130_USER_INTR_STAT_2__LEN (8)
+#define SMI130_USER_INTR_STAT_2__MSK (0xFF)
+#define SMI130_USER_INTR_STAT_2__REG \
+ (SMI130_USER_INTR_STAT_2_ADDR)
+/**************************************************************/
+/**\name HIGH_G-XYZ AND SIGN LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_3 Description - Reg Addr --> (0x1F), Bit --> 0 */
+#define SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_X__POS (0)
+#define SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_X__LEN (1)
+#define SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_X__MSK (0x01)
+#define SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_X__REG \
+ (SMI130_USER_INTR_STAT_3_ADDR)
+
+/* Int_Status_3 Description - Reg Addr --> 0x1E, Bit --> 1 */
+#define SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_Y__POS (1)
+#define SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_Y__LEN (1)
+#define SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_Y__MSK (0x02)
+#define SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_Y__REG \
+ (SMI130_USER_INTR_STAT_3_ADDR)
+
+/* Int_Status_3 Description - Reg Addr --> (0x1F), Bit --> 2 */
+#define SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_Z__POS (2)
+#define SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_Z__LEN (1)
+#define SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_Z__MSK (0x04)
+#define SMI130_USER_INTR_STAT_3_HIGH_G_FIRST_Z__REG \
+ (SMI130_USER_INTR_STAT_3_ADDR)
+
+/* Int_Status_3 Description - Reg Addr --> (0x1F), Bit --> 3 */
+#define SMI130_USER_INTR_STAT_3_HIGH_G_SIGN__POS (3)
+#define SMI130_USER_INTR_STAT_3_HIGH_G_SIGN__LEN (1)
+#define SMI130_USER_INTR_STAT_3_HIGH_G_SIGN__MSK (0x08)
+#define SMI130_USER_INTR_STAT_3_HIGH_G_SIGN__REG \
+ (SMI130_USER_INTR_STAT_3_ADDR)
+/**************************************************************/
+/**\name ORIENT XY and Z AXIS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_3 Description - Reg Addr --> (0x1F), Bit --> 4...5 */
+#define SMI130_USER_INTR_STAT_3_ORIENT_XY__POS (4)
+#define SMI130_USER_INTR_STAT_3_ORIENT_XY__LEN (2)
+#define SMI130_USER_INTR_STAT_3_ORIENT_XY__MSK (0x30)
+#define SMI130_USER_INTR_STAT_3_ORIENT_XY__REG \
+ (SMI130_USER_INTR_STAT_3_ADDR)
+
+/* Int_Status_3 Description - Reg Addr --> (0x1F), Bit --> 6 */
+#define SMI130_USER_INTR_STAT_3_ORIENT_Z__POS (6)
+#define SMI130_USER_INTR_STAT_3_ORIENT_Z__LEN (1)
+#define SMI130_USER_INTR_STAT_3_ORIENT_Z__MSK (0x40)
+#define SMI130_USER_INTR_STAT_3_ORIENT_Z__REG \
+ (SMI130_USER_INTR_STAT_3_ADDR)
+/**************************************************************/
+/**\name FLAT LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_3 Description - Reg Addr --> (0x1F), Bit --> 7 */
+#define SMI130_USER_INTR_STAT_3_FLAT__POS (7)
+#define SMI130_USER_INTR_STAT_3_FLAT__LEN (1)
+#define SMI130_USER_INTR_STAT_3_FLAT__MSK (0x80)
+#define SMI130_USER_INTR_STAT_3_FLAT__REG \
+ (SMI130_USER_INTR_STAT_3_ADDR)
+/**************************************************************/
+/**\name (0x1F) LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Status_3 Description - Reg Addr --> (0x1F), Bit --> 0...7 */
+#define SMI130_USER_INTR_STAT_3__POS (0)
+#define SMI130_USER_INTR_STAT_3__LEN (8)
+#define SMI130_USER_INTR_STAT_3__MSK (0xFF)
+#define SMI130_USER_INTR_STAT_3__REG \
+ (SMI130_USER_INTR_STAT_3_ADDR)
+/**************************************************************/
+/**\name TEMPERATURE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Temperature Description - LSB Reg Addr --> (0x20), Bit --> 0...7 */
+#define SMI130_USER_TEMP_LSB_VALUE__POS (0)
+#define SMI130_USER_TEMP_LSB_VALUE__LEN (8)
+#define SMI130_USER_TEMP_LSB_VALUE__MSK (0xFF)
+#define SMI130_USER_TEMP_LSB_VALUE__REG \
+ (SMI130_USER_TEMPERATURE_0_ADDR)
+
+/* Temperature Description - LSB Reg Addr --> 0x21, Bit --> 0...7 */
+#define SMI130_USER_TEMP_MSB_VALUE__POS (0)
+#define SMI130_USER_TEMP_MSB_VALUE__LEN (8)
+#define SMI130_USER_TEMP_MSB_VALUE__MSK (0xFF)
+#define SMI130_USER_TEMP_MSB_VALUE__REG \
+ (SMI130_USER_TEMPERATURE_1_ADDR)
+/**************************************************************/
+/**\name FIFO BYTE COUNTER LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Length0 Description - Reg Addr --> 0x22, Bit --> 0...7 */
+#define SMI130_USER_FIFO_BYTE_COUNTER_LSB__POS (0)
+#define SMI130_USER_FIFO_BYTE_COUNTER_LSB__LEN (8)
+#define SMI130_USER_FIFO_BYTE_COUNTER_LSB__MSK (0xFF)
+#define SMI130_USER_FIFO_BYTE_COUNTER_LSB__REG \
+ (SMI130_USER_FIFO_LENGTH_0_ADDR)
+
+/*Fifo_Length1 Description - Reg Addr --> 0x23, Bit --> 0...2 */
+#define SMI130_USER_FIFO_BYTE_COUNTER_MSB__POS (0)
+#define SMI130_USER_FIFO_BYTE_COUNTER_MSB__LEN 3
+#define SMI130_USER_FIFO_BYTE_COUNTER_MSB__MSK (0x07)
+#define SMI130_USER_FIFO_BYTE_COUNTER_MSB__REG \
+ (SMI130_USER_FIFO_LENGTH_1_ADDR)
+
+/**************************************************************/
+/**\name FIFO DATA LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Data Description - Reg Addr --> 0x24, Bit --> 0...7 */
+#define SMI130_USER_FIFO_DATA__POS (0)
+#define SMI130_USER_FIFO_DATA__LEN (8)
+#define SMI130_USER_FIFO_DATA__MSK (0xFF)
+#define SMI130_USER_FIFO_DATA__REG (SMI130_USER_FIFO_DATA_ADDR)
+
+/**************************************************************/
+/**\name ACCEL CONFIGURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Acc_Conf Description - Reg Addr --> (0x40), Bit --> 0...3 */
+#define SMI130_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE__POS (0)
+#define SMI130_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE__LEN (4)
+#define SMI130_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE__MSK (0x0F)
+#define SMI130_USER_ACCEL_CONFIG_OUTPUT_DATA_RATE__REG \
+(SMI130_USER_ACCEL_CONFIG_ADDR)
+
+/* Acc_Conf Description - Reg Addr --> (0x40), Bit --> 4...6 */
+#define SMI130_USER_ACCEL_CONFIG_ACCEL_BW__POS (4)
+#define SMI130_USER_ACCEL_CONFIG_ACCEL_BW__LEN (3)
+#define SMI130_USER_ACCEL_CONFIG_ACCEL_BW__MSK (0x70)
+#define SMI130_USER_ACCEL_CONFIG_ACCEL_BW__REG (SMI130_USER_ACCEL_CONFIG_ADDR)
+
+/* Acc_Conf Description - Reg Addr --> (0x40), Bit --> 7 */
+#define SMI130_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING__POS (7)
+#define SMI130_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING__LEN (1)
+#define SMI130_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING__MSK (0x80)
+#define SMI130_USER_ACCEL_CONFIG_ACCEL_UNDER_SAMPLING__REG \
+(SMI130_USER_ACCEL_CONFIG_ADDR)
+
+/* Acc_Range Description - Reg Addr --> 0x41, Bit --> 0...3 */
+#define SMI130_USER_ACCEL_RANGE__POS (0)
+#define SMI130_USER_ACCEL_RANGE__LEN (4)
+#define SMI130_USER_ACCEL_RANGE__MSK (0x0F)
+#define SMI130_USER_ACCEL_RANGE__REG \
+(SMI130_USER_ACCEL_RANGE_ADDR)
+/**************************************************************/
+/**\name GYRO CONFIGURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Gyro_Conf Description - Reg Addr --> (0x42), Bit --> 0...3 */
+#define SMI130_USER_GYRO_CONFIG_OUTPUT_DATA_RATE__POS (0)
+#define SMI130_USER_GYRO_CONFIG_OUTPUT_DATA_RATE__LEN (4)
+#define SMI130_USER_GYRO_CONFIG_OUTPUT_DATA_RATE__MSK (0x0F)
+#define SMI130_USER_GYRO_CONFIG_OUTPUT_DATA_RATE__REG \
+(SMI130_USER_GYRO_CONFIG_ADDR)
+
+/* Gyro_Conf Description - Reg Addr --> (0x42), Bit --> 4...5 */
+#define SMI130_USER_GYRO_CONFIG_BW__POS (4)
+#define SMI130_USER_GYRO_CONFIG_BW__LEN (2)
+#define SMI130_USER_GYRO_CONFIG_BW__MSK (0x30)
+#define SMI130_USER_GYRO_CONFIG_BW__REG \
+(SMI130_USER_GYRO_CONFIG_ADDR)
+
+/* Gyr_Range Description - Reg Addr --> 0x43, Bit --> 0...2 */
+#define SMI130_USER_GYRO_RANGE__POS (0)
+#define SMI130_USER_GYRO_RANGE__LEN (3)
+#define SMI130_USER_GYRO_RANGE__MSK (0x07)
+#define SMI130_USER_GYRO_RANGE__REG (SMI130_USER_GYRO_RANGE_ADDR)
+/**************************************************************/
+/**\name MAG CONFIGURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Mag_Conf Description - Reg Addr --> (0x44), Bit --> 0...3 */
+#define SMI130_USER_MAG_CONFIG_OUTPUT_DATA_RATE__POS (0)
+#define SMI130_USER_MAG_CONFIG_OUTPUT_DATA_RATE__LEN (4)
+#define SMI130_USER_MAG_CONFIG_OUTPUT_DATA_RATE__MSK (0x0F)
+#define SMI130_USER_MAG_CONFIG_OUTPUT_DATA_RATE__REG \
+(SMI130_USER_MAG_CONFIG_ADDR)
+/**************************************************************/
+/**\name FIFO DOWNS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Downs Description - Reg Addr --> 0x45, Bit --> 0...2 */
+#define SMI130_USER_FIFO_DOWN_GYRO__POS (0)
+#define SMI130_USER_FIFO_DOWN_GYRO__LEN (3)
+#define SMI130_USER_FIFO_DOWN_GYRO__MSK (0x07)
+#define SMI130_USER_FIFO_DOWN_GYRO__REG (SMI130_USER_FIFO_DOWN_ADDR)
+/**************************************************************/
+/**\name FIFO FILTER FOR ACCEL AND GYRO LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_filt Description - Reg Addr --> 0x45, Bit --> 3 */
+#define SMI130_USER_FIFO_FILTER_GYRO__POS (3)
+#define SMI130_USER_FIFO_FILTER_GYRO__LEN (1)
+#define SMI130_USER_FIFO_FILTER_GYRO__MSK (0x08)
+#define SMI130_USER_FIFO_FILTER_GYRO__REG (SMI130_USER_FIFO_DOWN_ADDR)
+
+/* Fifo_Downs Description - Reg Addr --> 0x45, Bit --> 4...6 */
+#define SMI130_USER_FIFO_DOWN_ACCEL__POS (4)
+#define SMI130_USER_FIFO_DOWN_ACCEL__LEN (3)
+#define SMI130_USER_FIFO_DOWN_ACCEL__MSK (0x70)
+#define SMI130_USER_FIFO_DOWN_ACCEL__REG (SMI130_USER_FIFO_DOWN_ADDR)
+
+/* Fifo_FILT Description - Reg Addr --> 0x45, Bit --> 7 */
+#define SMI130_USER_FIFO_FILTER_ACCEL__POS (7)
+#define SMI130_USER_FIFO_FILTER_ACCEL__LEN (1)
+#define SMI130_USER_FIFO_FILTER_ACCEL__MSK (0x80)
+#define SMI130_USER_FIFO_FILTER_ACCEL__REG (SMI130_USER_FIFO_DOWN_ADDR)
+/**************************************************************/
+/**\name FIFO WATER MARK LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Config_0 Description - Reg Addr --> 0x46, Bit --> 0...7 */
+#define SMI130_USER_FIFO_WM__POS (0)
+#define SMI130_USER_FIFO_WM__LEN (8)
+#define SMI130_USER_FIFO_WM__MSK (0xFF)
+#define SMI130_USER_FIFO_WM__REG (SMI130_USER_FIFO_CONFIG_0_ADDR)
+/**************************************************************/
+/**\name FIFO TIME LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Config_1 Description - Reg Addr --> 0x47, Bit --> 1 */
+#define SMI130_USER_FIFO_TIME_ENABLE__POS (1)
+#define SMI130_USER_FIFO_TIME_ENABLE__LEN (1)
+#define SMI130_USER_FIFO_TIME_ENABLE__MSK (0x02)
+#define SMI130_USER_FIFO_TIME_ENABLE__REG (SMI130_USER_FIFO_CONFIG_1_ADDR)
+/**************************************************************/
+/**\name FIFO TAG INTERRUPT LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Config_1 Description - Reg Addr --> 0x47, Bit --> 2 */
+#define SMI130_USER_FIFO_TAG_INTR2_ENABLE__POS (2)
+#define SMI130_USER_FIFO_TAG_INTR2_ENABLE__LEN (1)
+#define SMI130_USER_FIFO_TAG_INTR2_ENABLE__MSK (0x04)
+#define SMI130_USER_FIFO_TAG_INTR2_ENABLE__REG (SMI130_USER_FIFO_CONFIG_1_ADDR)
+
+/* Fifo_Config_1 Description - Reg Addr --> 0x47, Bit --> 3 */
+#define SMI130_USER_FIFO_TAG_INTR1_ENABLE__POS (3)
+#define SMI130_USER_FIFO_TAG_INTR1_ENABLE__LEN (1)
+#define SMI130_USER_FIFO_TAG_INTR1_ENABLE__MSK (0x08)
+#define SMI130_USER_FIFO_TAG_INTR1_ENABLE__REG (SMI130_USER_FIFO_CONFIG_1_ADDR)
+/**************************************************************/
+/**\name FIFO HEADER LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Config_1 Description - Reg Addr --> 0x47, Bit --> 4 */
+#define SMI130_USER_FIFO_HEADER_ENABLE__POS (4)
+#define SMI130_USER_FIFO_HEADER_ENABLE__LEN (1)
+#define SMI130_USER_FIFO_HEADER_ENABLE__MSK (0x10)
+#define SMI130_USER_FIFO_HEADER_ENABLE__REG \
+(SMI130_USER_FIFO_CONFIG_1_ADDR)
+/**************************************************************/
+/**\name FIFO MAG ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Config_1 Description - Reg Addr --> 0x47, Bit --> 5 */
+#define SMI130_USER_FIFO_MAG_ENABLE__POS (5)
+#define SMI130_USER_FIFO_MAG_ENABLE__LEN (1)
+#define SMI130_USER_FIFO_MAG_ENABLE__MSK (0x20)
+#define SMI130_USER_FIFO_MAG_ENABLE__REG \
+(SMI130_USER_FIFO_CONFIG_1_ADDR)
+/**************************************************************/
+/**\name FIFO ACCEL ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Config_1 Description - Reg Addr --> 0x47, Bit --> 6 */
+#define SMI130_USER_FIFO_ACCEL_ENABLE__POS (6)
+#define SMI130_USER_FIFO_ACCEL_ENABLE__LEN (1)
+#define SMI130_USER_FIFO_ACCEL_ENABLE__MSK (0x40)
+#define SMI130_USER_FIFO_ACCEL_ENABLE__REG \
+(SMI130_USER_FIFO_CONFIG_1_ADDR)
+/**************************************************************/
+/**\name FIFO GYRO ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Fifo_Config_1 Description - Reg Addr --> 0x47, Bit --> 7 */
+#define SMI130_USER_FIFO_GYRO_ENABLE__POS (7)
+#define SMI130_USER_FIFO_GYRO_ENABLE__LEN (1)
+#define SMI130_USER_FIFO_GYRO_ENABLE__MSK (0x80)
+#define SMI130_USER_FIFO_GYRO_ENABLE__REG \
+(SMI130_USER_FIFO_CONFIG_1_ADDR)
+
+/**************************************************************/
+/**\name MAG I2C ADDRESS SELECTION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+
+/* Mag_IF_0 Description - Reg Addr --> 0x4b, Bit --> 1...7 */
+#define SMI130_USER_I2C_DEVICE_ADDR__POS (1)
+#define SMI130_USER_I2C_DEVICE_ADDR__LEN (7)
+#define SMI130_USER_I2C_DEVICE_ADDR__MSK (0xFE)
+#define SMI130_USER_I2C_DEVICE_ADDR__REG (SMI130_USER_MAG_IF_0_ADDR)
+/**************************************************************/
+/**\name MAG CONFIGURATION FOR SECONDARY
+ INTERFACE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Mag_IF_1 Description - Reg Addr --> 0x4c, Bit --> 0...1 */
+#define SMI130_USER_MAG_BURST__POS (0)
+#define SMI130_USER_MAG_BURST__LEN (2)
+#define SMI130_USER_MAG_BURST__MSK (0x03)
+#define SMI130_USER_MAG_BURST__REG (SMI130_USER_MAG_IF_1_ADDR)
+
+/* Mag_IF_1 Description - Reg Addr --> 0x4c, Bit --> 2...5 */
+#define SMI130_USER_MAG_OFFSET__POS (2)
+#define SMI130_USER_MAG_OFFSET__LEN (4)
+#define SMI130_USER_MAG_OFFSET__MSK (0x3C)
+#define SMI130_USER_MAG_OFFSET__REG (SMI130_USER_MAG_IF_1_ADDR)
+
+/* Mag_IF_1 Description - Reg Addr --> 0x4c, Bit --> 7 */
+#define SMI130_USER_MAG_MANUAL_ENABLE__POS (7)
+#define SMI130_USER_MAG_MANUAL_ENABLE__LEN (1)
+#define SMI130_USER_MAG_MANUAL_ENABLE__MSK (0x80)
+#define SMI130_USER_MAG_MANUAL_ENABLE__REG \
+(SMI130_USER_MAG_IF_1_ADDR)
+
+/* Mag_IF_2 Description - Reg Addr --> 0x4d, Bit -->0... 7 */
+#define SMI130_USER_READ_ADDR__POS (0)
+#define SMI130_USER_READ_ADDR__LEN (8)
+#define SMI130_USER_READ_ADDR__MSK (0xFF)
+#define SMI130_USER_READ_ADDR__REG (SMI130_USER_MAG_IF_2_ADDR)
+
+/* Mag_IF_3 Description - Reg Addr --> 0x4e, Bit -->0... 7 */
+#define SMI130_USER_WRITE_ADDR__POS (0)
+#define SMI130_USER_WRITE_ADDR__LEN (8)
+#define SMI130_USER_WRITE_ADDR__MSK (0xFF)
+#define SMI130_USER_WRITE_ADDR__REG (SMI130_USER_MAG_IF_3_ADDR)
+
+/* Mag_IF_4 Description - Reg Addr --> 0x4f, Bit -->0... 7 */
+#define SMI130_USER_WRITE_DATA__POS (0)
+#define SMI130_USER_WRITE_DATA__LEN (8)
+#define SMI130_USER_WRITE_DATA__MSK (0xFF)
+#define SMI130_USER_WRITE_DATA__REG (SMI130_USER_MAG_IF_4_ADDR)
+/**************************************************************/
+/**\name ANY MOTION XYZ AXIS ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_0 Description - Reg Addr --> 0x50, Bit -->0 */
+#define SMI130_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE__POS (0)
+#define SMI130_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE__MSK (0x01)
+#define SMI130_USER_INTR_ENABLE_0_ANY_MOTION_X_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_0_ADDR)
+
+/* Int_En_0 Description - Reg Addr --> 0x50, Bit -->1 */
+#define SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE__POS (1)
+#define SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE__MSK (0x02)
+#define SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Y_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_0_ADDR)
+
+/* Int_En_0 Description - Reg Addr --> 0x50, Bit -->2 */
+#define SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE__POS (2)
+#define SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE__MSK (0x04)
+#define SMI130_USER_INTR_ENABLE_0_ANY_MOTION_Z_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_0_ADDR)
+/**************************************************************/
+/**\name DOUBLE TAP ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_0 Description - Reg Addr --> 0x50, Bit -->4 */
+#define SMI130_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE__POS (4)
+#define SMI130_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE__MSK (0x10)
+#define SMI130_USER_INTR_ENABLE_0_DOUBLE_TAP_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_0_ADDR)
+/**************************************************************/
+/**\name SINGLE TAP ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_0 Description - Reg Addr --> 0x50, Bit -->5 */
+#define SMI130_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE__POS (5)
+#define SMI130_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE__MSK (0x20)
+#define SMI130_USER_INTR_ENABLE_0_SINGLE_TAP_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_0_ADDR)
+/**************************************************************/
+/**\name ORIENT ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_0 Description - Reg Addr --> 0x50, Bit -->6 */
+#define SMI130_USER_INTR_ENABLE_0_ORIENT_ENABLE__POS (6)
+#define SMI130_USER_INTR_ENABLE_0_ORIENT_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_0_ORIENT_ENABLE__MSK (0x40)
+#define SMI130_USER_INTR_ENABLE_0_ORIENT_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_0_ADDR)
+/**************************************************************/
+/**\name FLAT ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_0 Description - Reg Addr --> 0x50, Bit -->7 */
+#define SMI130_USER_INTR_ENABLE_0_FLAT_ENABLE__POS (7)
+#define SMI130_USER_INTR_ENABLE_0_FLAT_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_0_FLAT_ENABLE__MSK (0x80)
+#define SMI130_USER_INTR_ENABLE_0_FLAT_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_0_ADDR)
+/**************************************************************/
+/**\name HIGH_G XYZ ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_1 Description - Reg Addr --> (0x51), Bit -->0 */
+#define SMI130_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE__POS (0)
+#define SMI130_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE__MSK (0x01)
+#define SMI130_USER_INTR_ENABLE_1_HIGH_G_X_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_1_ADDR)
+
+/* Int_En_1 Description - Reg Addr --> (0x51), Bit -->1 */
+#define SMI130_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE__POS (1)
+#define SMI130_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE__MSK (0x02)
+#define SMI130_USER_INTR_ENABLE_1_HIGH_G_Y_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_1_ADDR)
+
+/* Int_En_1 Description - Reg Addr --> (0x51), Bit -->2 */
+#define SMI130_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE__POS (2)
+#define SMI130_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE__MSK (0x04)
+#define SMI130_USER_INTR_ENABLE_1_HIGH_G_Z_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_1_ADDR)
+/**************************************************************/
+/**\name LOW_G ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_1 Description - Reg Addr --> (0x51), Bit -->3 */
+#define SMI130_USER_INTR_ENABLE_1_LOW_G_ENABLE__POS (3)
+#define SMI130_USER_INTR_ENABLE_1_LOW_G_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_1_LOW_G_ENABLE__MSK (0x08)
+#define SMI130_USER_INTR_ENABLE_1_LOW_G_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_1_ADDR)
+/**************************************************************/
+/**\name DATA READY ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_1 Description - Reg Addr --> (0x51), Bit -->4 */
+#define SMI130_USER_INTR_ENABLE_1_DATA_RDY_ENABLE__POS (4)
+#define SMI130_USER_INTR_ENABLE_1_DATA_RDY_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_1_DATA_RDY_ENABLE__MSK (0x10)
+#define SMI130_USER_INTR_ENABLE_1_DATA_RDY_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_1_ADDR)
+/**************************************************************/
+/**\name FIFO FULL AND WATER MARK ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_1 Description - Reg Addr --> (0x51), Bit -->5 */
+#define SMI130_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE__POS (5)
+#define SMI130_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE__MSK (0x20)
+#define SMI130_USER_INTR_ENABLE_1_FIFO_FULL_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_1_ADDR)
+
+/* Int_En_1 Description - Reg Addr --> (0x51), Bit -->6 */
+#define SMI130_USER_INTR_ENABLE_1_FIFO_WM_ENABLE__POS (6)
+#define SMI130_USER_INTR_ENABLE_1_FIFO_WM_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_1_FIFO_WM_ENABLE__MSK (0x40)
+#define SMI130_USER_INTR_ENABLE_1_FIFO_WM_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_1_ADDR)
+/**************************************************************/
+/**\name NO MOTION XYZ ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_2 Description - Reg Addr --> (0x52), Bit -->0 */
+#define SMI130_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE__POS (0)
+#define SMI130_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE__MSK (0x01)
+#define SMI130_USER_INTR_ENABLE_2_NOMOTION_X_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_2_ADDR)
+
+/* Int_En_2 Description - Reg Addr --> (0x52), Bit -->1 */
+#define SMI130_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE__POS (1)
+#define SMI130_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE__MSK (0x02)
+#define SMI130_USER_INTR_ENABLE_2_NOMOTION_Y_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_2_ADDR)
+
+/* Int_En_2 Description - Reg Addr --> (0x52), Bit -->2 */
+#define SMI130_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE__POS (2)
+#define SMI130_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE__MSK (0x04)
+#define SMI130_USER_INTR_ENABLE_2_NOMOTION_Z_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_2_ADDR)
+/**************************************************************/
+/**\name STEP DETECTOR ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_En_2 Description - Reg Addr --> (0x52), Bit -->3 */
+#define SMI130_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE__POS (3)
+#define SMI130_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE__MSK (0x08)
+#define SMI130_USER_INTR_ENABLE_2_STEP_DETECTOR_ENABLE__REG \
+(SMI130_USER_INTR_ENABLE_2_ADDR)
+/**************************************************************/
+/**\name EDGE CONTROL ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->0 */
+#define SMI130_USER_INTR1_EDGE_CTRL__POS (0)
+#define SMI130_USER_INTR1_EDGE_CTRL__LEN (1)
+#define SMI130_USER_INTR1_EDGE_CTRL__MSK (0x01)
+#define SMI130_USER_INTR1_EDGE_CTRL__REG \
+(SMI130_USER_INTR_OUT_CTRL_ADDR)
+/**************************************************************/
+/**\name LEVEL CONTROL ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->1 */
+#define SMI130_USER_INTR1_LEVEL__POS (1)
+#define SMI130_USER_INTR1_LEVEL__LEN (1)
+#define SMI130_USER_INTR1_LEVEL__MSK (0x02)
+#define SMI130_USER_INTR1_LEVEL__REG \
+(SMI130_USER_INTR_OUT_CTRL_ADDR)
+/**************************************************************/
+/**\name OUTPUT TYPE ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->2 */
+#define SMI130_USER_INTR1_OUTPUT_TYPE__POS (2)
+#define SMI130_USER_INTR1_OUTPUT_TYPE__LEN (1)
+#define SMI130_USER_INTR1_OUTPUT_TYPE__MSK (0x04)
+#define SMI130_USER_INTR1_OUTPUT_TYPE__REG \
+(SMI130_USER_INTR_OUT_CTRL_ADDR)
+/**************************************************************/
+/**\name OUTPUT TYPE ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->3 */
+#define SMI130_USER_INTR1_OUTPUT_ENABLE__POS (3)
+#define SMI130_USER_INTR1_OUTPUT_ENABLE__LEN (1)
+#define SMI130_USER_INTR1_OUTPUT_ENABLE__MSK (0x08)
+#define SMI130_USER_INTR1_OUTPUT_ENABLE__REG \
+(SMI130_USER_INTR_OUT_CTRL_ADDR)
+/**************************************************************/
+/**\name EDGE CONTROL ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->4 */
+#define SMI130_USER_INTR2_EDGE_CTRL__POS (4)
+#define SMI130_USER_INTR2_EDGE_CTRL__LEN (1)
+#define SMI130_USER_INTR2_EDGE_CTRL__MSK (0x10)
+#define SMI130_USER_INTR2_EDGE_CTRL__REG \
+(SMI130_USER_INTR_OUT_CTRL_ADDR)
+/**************************************************************/
+/**\name LEVEL CONTROL ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->5 */
+#define SMI130_USER_INTR2_LEVEL__POS (5)
+#define SMI130_USER_INTR2_LEVEL__LEN (1)
+#define SMI130_USER_INTR2_LEVEL__MSK (0x20)
+#define SMI130_USER_INTR2_LEVEL__REG \
+(SMI130_USER_INTR_OUT_CTRL_ADDR)
+/**************************************************************/
+/**\name OUTPUT TYPE ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->6 */
+#define SMI130_USER_INTR2_OUTPUT_TYPE__POS (6)
+#define SMI130_USER_INTR2_OUTPUT_TYPE__LEN (1)
+#define SMI130_USER_INTR2_OUTPUT_TYPE__MSK (0x40)
+#define SMI130_USER_INTR2_OUTPUT_TYPE__REG \
+(SMI130_USER_INTR_OUT_CTRL_ADDR)
+
+/* Int_Out_Ctrl Description - Reg Addr --> 0x53, Bit -->7 */
+#define SMI130_USER_INTR2_OUTPUT_EN__POS (7)
+#define SMI130_USER_INTR2_OUTPUT_EN__LEN (1)
+#define SMI130_USER_INTR2_OUTPUT_EN__MSK (0x80)
+#define SMI130_USER_INTR2_OUTPUT_EN__REG \
+(SMI130_USER_INTR_OUT_CTRL_ADDR)
+/**************************************************************/
+/**\name LATCH INTERRUPT LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Latch Description - Reg Addr --> 0x54, Bit -->0...3 */
+#define SMI130_USER_INTR_LATCH__POS (0)
+#define SMI130_USER_INTR_LATCH__LEN (4)
+#define SMI130_USER_INTR_LATCH__MSK (0x0F)
+#define SMI130_USER_INTR_LATCH__REG (SMI130_USER_INTR_LATCH_ADDR)
+/**************************************************************/
+/**\name INPUT ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Latch Description - Reg Addr --> 0x54, Bit -->4 */
+#define SMI130_USER_INTR1_INPUT_ENABLE__POS (4)
+#define SMI130_USER_INTR1_INPUT_ENABLE__LEN (1)
+#define SMI130_USER_INTR1_INPUT_ENABLE__MSK (0x10)
+#define SMI130_USER_INTR1_INPUT_ENABLE__REG \
+(SMI130_USER_INTR_LATCH_ADDR)
+
+/* Int_Latch Description - Reg Addr --> 0x54, Bit -->5*/
+#define SMI130_USER_INTR2_INPUT_ENABLE__POS (5)
+#define SMI130_USER_INTR2_INPUT_ENABLE__LEN (1)
+#define SMI130_USER_INTR2_INPUT_ENABLE__MSK (0x20)
+#define SMI130_USER_INTR2_INPUT_ENABLE__REG \
+(SMI130_USER_INTR_LATCH_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF LOW_G LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_0 Description - Reg Addr --> 0x55, Bit -->0 */
+#define SMI130_USER_INTR_MAP_0_INTR1_LOW_G__POS (0)
+#define SMI130_USER_INTR_MAP_0_INTR1_LOW_G__LEN (1)
+#define SMI130_USER_INTR_MAP_0_INTR1_LOW_G__MSK (0x01)
+#define SMI130_USER_INTR_MAP_0_INTR1_LOW_G__REG (SMI130_USER_INTR_MAP_0_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF HIGH_G LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_0 Description - Reg Addr --> 0x55, Bit -->1 */
+#define SMI130_USER_INTR_MAP_0_INTR1_HIGH_G__POS (1)
+#define SMI130_USER_INTR_MAP_0_INTR1_HIGH_G__LEN (1)
+#define SMI130_USER_INTR_MAP_0_INTR1_HIGH_G__MSK (0x02)
+#define SMI130_USER_INTR_MAP_0_INTR1_HIGH_G__REG \
+(SMI130_USER_INTR_MAP_0_ADDR)
+/**************************************************************/
+/**\name INTERRUPT MAPPIONG OF ANY MOTION_G LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_0 Description - Reg Addr --> 0x55, Bit -->2 */
+#define SMI130_USER_INTR_MAP_0_INTR1_ANY_MOTION__POS (2)
+#define SMI130_USER_INTR_MAP_0_INTR1_ANY_MOTION__LEN (1)
+#define SMI130_USER_INTR_MAP_0_INTR1_ANY_MOTION__MSK (0x04)
+#define SMI130_USER_INTR_MAP_0_INTR1_ANY_MOTION__REG \
+(SMI130_USER_INTR_MAP_0_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF NO MOTION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_0 Description - Reg Addr --> 0x55, Bit -->3 */
+#define SMI130_USER_INTR_MAP_0_INTR1_NOMOTION__POS (3)
+#define SMI130_USER_INTR_MAP_0_INTR1_NOMOTION__LEN (1)
+#define SMI130_USER_INTR_MAP_0_INTR1_NOMOTION__MSK (0x08)
+#define SMI130_USER_INTR_MAP_0_INTR1_NOMOTION__REG (SMI130_USER_INTR_MAP_0_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF DOUBLE TAP LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_0 Description - Reg Addr --> 0x55, Bit -->4 */
+#define SMI130_USER_INTR_MAP_0_INTR1_DOUBLE_TAP__POS (4)
+#define SMI130_USER_INTR_MAP_0_INTR1_DOUBLE_TAP__LEN (1)
+#define SMI130_USER_INTR_MAP_0_INTR1_DOUBLE_TAP__MSK (0x10)
+#define SMI130_USER_INTR_MAP_0_INTR1_DOUBLE_TAP__REG \
+(SMI130_USER_INTR_MAP_0_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF SINGLE TAP LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_0 Description - Reg Addr --> 0x55, Bit -->5 */
+#define SMI130_USER_INTR_MAP_0_INTR1_SINGLE_TAP__POS (5)
+#define SMI130_USER_INTR_MAP_0_INTR1_SINGLE_TAP__LEN (1)
+#define SMI130_USER_INTR_MAP_0_INTR1_SINGLE_TAP__MSK (0x20)
+#define SMI130_USER_INTR_MAP_0_INTR1_SINGLE_TAP__REG \
+(SMI130_USER_INTR_MAP_0_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF ORIENT LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_0 Description - Reg Addr --> 0x55, Bit -->6 */
+#define SMI130_USER_INTR_MAP_0_INTR1_ORIENT__POS (6)
+#define SMI130_USER_INTR_MAP_0_INTR1_ORIENT__LEN (1)
+#define SMI130_USER_INTR_MAP_0_INTR1_ORIENT__MSK (0x40)
+#define SMI130_USER_INTR_MAP_0_INTR1_ORIENT__REG \
+(SMI130_USER_INTR_MAP_0_ADDR)
+/**************************************************************/
+/**\name INTERRUPT MAPPIONG OF FLAT LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_0 Description - Reg Addr --> 0x56, Bit -->7 */
+#define SMI130_USER_INTR_MAP_0_INTR1_FLAT__POS (7)
+#define SMI130_USER_INTR_MAP_0_INTR1_FLAT__LEN (1)
+#define SMI130_USER_INTR_MAP_0_INTR1_FLAT__MSK (0x80)
+#define SMI130_USER_INTR_MAP_0_INTR1_FLAT__REG (SMI130_USER_INTR_MAP_0_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF PMU TRIGGER LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->0 */
+#define SMI130_USER_INTR_MAP_1_INTR2_PMU_TRIG__POS (0)
+#define SMI130_USER_INTR_MAP_1_INTR2_PMU_TRIG__LEN (1)
+#define SMI130_USER_INTR_MAP_1_INTR2_PMU_TRIG__MSK (0x01)
+#define SMI130_USER_INTR_MAP_1_INTR2_PMU_TRIG__REG (SMI130_USER_INTR_MAP_1_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF FIFO FULL AND
+ WATER MARK LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->1 */
+#define SMI130_USER_INTR_MAP_1_INTR2_FIFO_FULL__POS (1)
+#define SMI130_USER_INTR_MAP_1_INTR2_FIFO_FULL__LEN (1)
+#define SMI130_USER_INTR_MAP_1_INTR2_FIFO_FULL__MSK (0x02)
+#define SMI130_USER_INTR_MAP_1_INTR2_FIFO_FULL__REG \
+(SMI130_USER_INTR_MAP_1_ADDR)
+
+/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->2 */
+#define SMI130_USER_INTR_MAP_1_INTR2_FIFO_WM__POS (2)
+#define SMI130_USER_INTR_MAP_1_INTR2_FIFO_WM__LEN (1)
+#define SMI130_USER_INTR_MAP_1_INTR2_FIFO_WM__MSK (0x04)
+#define SMI130_USER_INTR_MAP_1_INTR2_FIFO_WM__REG \
+(SMI130_USER_INTR_MAP_1_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF DATA READY LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->3 */
+#define SMI130_USER_INTR_MAP_1_INTR2_DATA_RDY__POS (3)
+#define SMI130_USER_INTR_MAP_1_INTR2_DATA_RDY__LEN (1)
+#define SMI130_USER_INTR_MAP_1_INTR2_DATA_RDY__MSK (0x08)
+#define SMI130_USER_INTR_MAP_1_INTR2_DATA_RDY__REG \
+(SMI130_USER_INTR_MAP_1_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF PMU TRIGGER LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->4 */
+#define SMI130_USER_INTR_MAP_1_INTR1_PMU_TRIG__POS (4)
+#define SMI130_USER_INTR_MAP_1_INTR1_PMU_TRIG__LEN (1)
+#define SMI130_USER_INTR_MAP_1_INTR1_PMU_TRIG__MSK (0x10)
+#define SMI130_USER_INTR_MAP_1_INTR1_PMU_TRIG__REG (SMI130_USER_INTR_MAP_1_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF FIFO FULL AND
+ WATER MARK LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->5 */
+#define SMI130_USER_INTR_MAP_1_INTR1_FIFO_FULL__POS (5)
+#define SMI130_USER_INTR_MAP_1_INTR1_FIFO_FULL__LEN (1)
+#define SMI130_USER_INTR_MAP_1_INTR1_FIFO_FULL__MSK (0x20)
+#define SMI130_USER_INTR_MAP_1_INTR1_FIFO_FULL__REG \
+(SMI130_USER_INTR_MAP_1_ADDR)
+
+/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->6 */
+#define SMI130_USER_INTR_MAP_1_INTR1_FIFO_WM__POS (6)
+#define SMI130_USER_INTR_MAP_1_INTR1_FIFO_WM__LEN (1)
+#define SMI130_USER_INTR_MAP_1_INTR1_FIFO_WM__MSK (0x40)
+#define SMI130_USER_INTR_MAP_1_INTR1_FIFO_WM__REG \
+(SMI130_USER_INTR_MAP_1_ADDR)
+/**************************************************************/
+/**\name INTERRUPT1 MAPPIONG OF DATA READY LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_1 Description - Reg Addr --> 0x56, Bit -->7 */
+#define SMI130_USER_INTR_MAP_1_INTR1_DATA_RDY__POS (7)
+#define SMI130_USER_INTR_MAP_1_INTR1_DATA_RDY__LEN (1)
+#define SMI130_USER_INTR_MAP_1_INTR1_DATA_RDY__MSK (0x80)
+#define SMI130_USER_INTR_MAP_1_INTR1_DATA_RDY__REG \
+(SMI130_USER_INTR_MAP_1_ADDR)
+/**************************************************************/
+/**\name INTERRUPT2 MAPPIONG OF LOW_G LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->0 */
+#define SMI130_USER_INTR_MAP_2_INTR2_LOW_G__POS (0)
+#define SMI130_USER_INTR_MAP_2_INTR2_LOW_G__LEN (1)
+#define SMI130_USER_INTR_MAP_2_INTR2_LOW_G__MSK (0x01)
+#define SMI130_USER_INTR_MAP_2_INTR2_LOW_G__REG (SMI130_USER_INTR_MAP_2_ADDR)
+/**************************************************************/
+/**\name INTERRUPT2 MAPPIONG OF HIGH_G LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->1 */
+#define SMI130_USER_INTR_MAP_2_INTR2_HIGH_G__POS (1)
+#define SMI130_USER_INTR_MAP_2_INTR2_HIGH_G__LEN (1)
+#define SMI130_USER_INTR_MAP_2_INTR2_HIGH_G__MSK (0x02)
+#define SMI130_USER_INTR_MAP_2_INTR2_HIGH_G__REG \
+(SMI130_USER_INTR_MAP_2_ADDR)
+/**************************************************************/
+/**\name INTERRUPT2 MAPPIONG OF ANY MOTION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->2 */
+#define SMI130_USER_INTR_MAP_2_INTR2_ANY_MOTION__POS (2)
+#define SMI130_USER_INTR_MAP_2_INTR2_ANY_MOTION__LEN (1)
+#define SMI130_USER_INTR_MAP_2_INTR2_ANY_MOTION__MSK (0x04)
+#define SMI130_USER_INTR_MAP_2_INTR2_ANY_MOTION__REG \
+(SMI130_USER_INTR_MAP_2_ADDR)
+/**************************************************************/
+/**\name INTERRUPT2 MAPPIONG OF NO MOTION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->3 */
+#define SMI130_USER_INTR_MAP_2_INTR2_NOMOTION__POS (3)
+#define SMI130_USER_INTR_MAP_2_INTR2_NOMOTION__LEN (1)
+#define SMI130_USER_INTR_MAP_2_INTR2_NOMOTION__MSK (0x08)
+#define SMI130_USER_INTR_MAP_2_INTR2_NOMOTION__REG (SMI130_USER_INTR_MAP_2_ADDR)
+/**************************************************************/
+/**\name INTERRUPT2 MAPPIONG OF DOUBLE TAP LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->4 */
+#define SMI130_USER_INTR_MAP_2_INTR2_DOUBLE_TAP__POS (4)
+#define SMI130_USER_INTR_MAP_2_INTR2_DOUBLE_TAP__LEN (1)
+#define SMI130_USER_INTR_MAP_2_INTR2_DOUBLE_TAP__MSK (0x10)
+#define SMI130_USER_INTR_MAP_2_INTR2_DOUBLE_TAP__REG \
+(SMI130_USER_INTR_MAP_2_ADDR)
+/**************************************************************/
+/**\name INTERRUPT2 MAPPIONG OF SINGLE TAP LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->5 */
+#define SMI130_USER_INTR_MAP_2_INTR2_SINGLE_TAP__POS (5)
+#define SMI130_USER_INTR_MAP_2_INTR2_SINGLE_TAP__LEN (1)
+#define SMI130_USER_INTR_MAP_2_INTR2_SINGLE_TAP__MSK (0x20)
+#define SMI130_USER_INTR_MAP_2_INTR2_SINGLE_TAP__REG \
+(SMI130_USER_INTR_MAP_2_ADDR)
+/**************************************************************/
+/**\name INTERRUPT2 MAPPIONG OF ORIENT LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->6 */
+#define SMI130_USER_INTR_MAP_2_INTR2_ORIENT__POS (6)
+#define SMI130_USER_INTR_MAP_2_INTR2_ORIENT__LEN (1)
+#define SMI130_USER_INTR_MAP_2_INTR2_ORIENT__MSK (0x40)
+#define SMI130_USER_INTR_MAP_2_INTR2_ORIENT__REG \
+(SMI130_USER_INTR_MAP_2_ADDR)
+/**************************************************************/
+/**\name INTERRUPT2 MAPPIONG OF FLAT LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Map_2 Description - Reg Addr --> 0x57, Bit -->7 */
+#define SMI130_USER_INTR_MAP_2_INTR2_FLAT__POS (7)
+#define SMI130_USER_INTR_MAP_2_INTR2_FLAT__LEN (1)
+#define SMI130_USER_INTR_MAP_2_INTR2_FLAT__MSK (0x80)
+#define SMI130_USER_INTR_MAP_2_INTR2_FLAT__REG (SMI130_USER_INTR_MAP_2_ADDR)
+
+/**************************************************************/
+/**\name TAP SOURCE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Data_0 Description - Reg Addr --> 0x58, Bit --> 3 */
+#define SMI130_USER_INTR_DATA_0_INTR_TAP_SOURCE__POS (3)
+#define SMI130_USER_INTR_DATA_0_INTR_TAP_SOURCE__LEN (1)
+#define SMI130_USER_INTR_DATA_0_INTR_TAP_SOURCE__MSK (0x08)
+#define SMI130_USER_INTR_DATA_0_INTR_TAP_SOURCE__REG \
+(SMI130_USER_INTR_DATA_0_ADDR)
+
+/**************************************************************/
+/**\name HIGH SOURCE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Data_0 Description - Reg Addr --> 0x58, Bit --> 7 */
+#define SMI130_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE__POS (7)
+#define SMI130_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE__LEN (1)
+#define SMI130_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE__MSK (0x80)
+#define SMI130_USER_INTR_DATA_0_INTR_LOW_HIGH_SOURCE__REG \
+(SMI130_USER_INTR_DATA_0_ADDR)
+
+/**************************************************************/
+/**\name MOTION SOURCE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Data_1 Description - Reg Addr --> 0x59, Bit --> 7 */
+#define SMI130_USER_INTR_DATA_1_INTR_MOTION_SOURCE__POS (7)
+#define SMI130_USER_INTR_DATA_1_INTR_MOTION_SOURCE__LEN (1)
+#define SMI130_USER_INTR_DATA_1_INTR_MOTION_SOURCE__MSK (0x80)
+#define SMI130_USER_INTR_DATA_1_INTR_MOTION_SOURCE__REG \
+ (SMI130_USER_INTR_DATA_1_ADDR)
+/**************************************************************/
+/**\name LOW HIGH DURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_LowHigh_0 Description - Reg Addr --> 0x5a, Bit --> 0...7 */
+#define SMI130_USER_INTR_LOWHIGH_0_INTR_LOW_DURN__POS (0)
+#define SMI130_USER_INTR_LOWHIGH_0_INTR_LOW_DURN__LEN (8)
+#define SMI130_USER_INTR_LOWHIGH_0_INTR_LOW_DURN__MSK (0xFF)
+#define SMI130_USER_INTR_LOWHIGH_0_INTR_LOW_DURN__REG \
+ (SMI130_USER_INTR_LOWHIGH_0_ADDR)
+/**************************************************************/
+/**\name LOW THRESHOLD LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_LowHigh_1 Description - Reg Addr --> 0x5b, Bit --> 0...7 */
+#define SMI130_USER_INTR_LOWHIGH_1_INTR_LOW_THRES__POS (0)
+#define SMI130_USER_INTR_LOWHIGH_1_INTR_LOW_THRES__LEN (8)
+#define SMI130_USER_INTR_LOWHIGH_1_INTR_LOW_THRES__MSK (0xFF)
+#define SMI130_USER_INTR_LOWHIGH_1_INTR_LOW_THRES__REG \
+ (SMI130_USER_INTR_LOWHIGH_1_ADDR)
+/**************************************************************/
+/**\name LOW HYSTERESIS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_LowHigh_2 Description - Reg Addr --> 0x5c, Bit --> 0...1 */
+#define SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST__POS (0)
+#define SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST__LEN (2)
+#define SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST__MSK (0x03)
+#define SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_HYST__REG \
+ (SMI130_USER_INTR_LOWHIGH_2_ADDR)
+/**************************************************************/
+/**\name LOW MODE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_LowHigh_2 Description - Reg Addr --> 0x5c, Bit --> 2 */
+#define SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE__POS (2)
+#define SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE__LEN (1)
+#define SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE__MSK (0x04)
+#define SMI130_USER_INTR_LOWHIGH_2_INTR_LOW_G_MODE__REG \
+ (SMI130_USER_INTR_LOWHIGH_2_ADDR)
+/**************************************************************/
+/**\name HIGH_G HYSTERESIS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_LowHigh_2 Description - Reg Addr --> 0x5c, Bit --> 6...7 */
+#define SMI130_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST__POS (6)
+#define SMI130_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST__LEN (2)
+#define SMI130_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST__MSK (0xC0)
+#define SMI130_USER_INTR_LOWHIGH_2_INTR_HIGH_G_HYST__REG \
+ (SMI130_USER_INTR_LOWHIGH_2_ADDR)
+/**************************************************************/
+/**\name HIGH_G DURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_LowHigh_3 Description - Reg Addr --> 0x5d, Bit --> 0...7 */
+#define SMI130_USER_INTR_LOWHIGH_3_INTR_HIGH_G_DURN__POS (0)
+#define SMI130_USER_INTR_LOWHIGH_3_INTR_HIGH_G_DURN__LEN (8)
+#define SMI130_USER_INTR_LOWHIGH_3_INTR_HIGH_G_DURN__MSK (0xFF)
+#define SMI130_USER_INTR_LOWHIGH_3_INTR_HIGH_G_DURN__REG \
+ (SMI130_USER_INTR_LOWHIGH_3_ADDR)
+/**************************************************************/
+/**\name HIGH_G THRESHOLD LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_LowHigh_4 Description - Reg Addr --> 0x5e, Bit --> 0...7 */
+#define SMI130_USER_INTR_LOWHIGH_4_INTR_HIGH_THRES__POS (0)
+#define SMI130_USER_INTR_LOWHIGH_4_INTR_HIGH_THRES__LEN (8)
+#define SMI130_USER_INTR_LOWHIGH_4_INTR_HIGH_THRES__MSK (0xFF)
+#define SMI130_USER_INTR_LOWHIGH_4_INTR_HIGH_THRES__REG \
+ (SMI130_USER_INTR_LOWHIGH_4_ADDR)
+/**************************************************************/
+/**\name ANY MOTION DURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Motion_0 Description - Reg Addr --> 0x5f, Bit --> 0...1 */
+#define SMI130_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN__POS (0)
+#define SMI130_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN__LEN (2)
+#define SMI130_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN__MSK (0x03)
+#define SMI130_USER_INTR_MOTION_0_INTR_ANY_MOTION_DURN__REG \
+ (SMI130_USER_INTR_MOTION_0_ADDR)
+/**************************************************************/
+/**\name SLOW/NO MOTION DURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+ /* Int_Motion_0 Description - Reg Addr --> 0x5f, Bit --> 2...7 */
+#define SMI130_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN__POS (2)
+#define SMI130_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN__LEN (6)
+#define SMI130_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN__MSK (0xFC)
+#define SMI130_USER_INTR_MOTION_0_INTR_SLOW_NO_MOTION_DURN__REG \
+ (SMI130_USER_INTR_MOTION_0_ADDR)
+/**************************************************************/
+/**\name ANY MOTION THRESHOLD LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Motion_1 Description - Reg Addr --> (0x60), Bit --> 0...7 */
+#define SMI130_USER_INTR_MOTION_1_INTR_ANY_MOTION_THRES__POS (0)
+#define SMI130_USER_INTR_MOTION_1_INTR_ANY_MOTION_THRES__LEN (8)
+#define SMI130_USER_INTR_MOTION_1_INTR_ANY_MOTION_THRES__MSK (0xFF)
+#define SMI130_USER_INTR_MOTION_1_INTR_ANY_MOTION_THRES__REG \
+ (SMI130_USER_INTR_MOTION_1_ADDR)
+/**************************************************************/
+/**\name SLOW/NO MOTION THRESHOLD LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Motion_2 Description - Reg Addr --> 0x61, Bit --> 0...7 */
+#define SMI130_USER_INTR_MOTION_2_INTR_SLOW_NO_MOTION_THRES__POS (0)
+#define SMI130_USER_INTR_MOTION_2_INTR_SLOW_NO_MOTION_THRES__LEN (8)
+#define SMI130_USER_INTR_MOTION_2_INTR_SLOW_NO_MOTION_THRES__MSK (0xFF)
+#define SMI130_USER_INTR_MOTION_2_INTR_SLOW_NO_MOTION_THRES__REG \
+ (SMI130_USER_INTR_MOTION_2_ADDR)
+/**************************************************************/
+/**\name SLOW/NO MOTION SELECT LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Motion_3 Description - Reg Addr --> (0x62), Bit --> 0 */
+#define SMI130_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT__POS (0)
+#define SMI130_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT__LEN (1)
+#define SMI130_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT__MSK (0x01)
+#define SMI130_USER_INTR_MOTION_3_INTR_SLOW_NO_MOTION_SELECT__REG \
+(SMI130_USER_INTR_MOTION_3_ADDR)
+/**************************************************************/
+/**\name SIGNIFICANT MOTION SELECT LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Motion_3 Description - Reg Addr --> (0x62), Bit --> 1 */
+#define SMI130_USER_INTR_SIGNIFICATION_MOTION_SELECT__POS (1)
+#define SMI130_USER_INTR_SIGNIFICATION_MOTION_SELECT__LEN (1)
+#define SMI130_USER_INTR_SIGNIFICATION_MOTION_SELECT__MSK (0x02)
+#define SMI130_USER_INTR_SIGNIFICATION_MOTION_SELECT__REG \
+ (SMI130_USER_INTR_MOTION_3_ADDR)
+
+/* Int_Motion_3 Description - Reg Addr --> (0x62), Bit --> 3..2 */
+#define SMI130_USER_INTR_SIGNIFICANT_MOTION_SKIP__POS (2)
+#define SMI130_USER_INTR_SIGNIFICANT_MOTION_SKIP__LEN (2)
+#define SMI130_USER_INTR_SIGNIFICANT_MOTION_SKIP__MSK (0x0C)
+#define SMI130_USER_INTR_SIGNIFICANT_MOTION_SKIP__REG \
+ (SMI130_USER_INTR_MOTION_3_ADDR)
+
+/* Int_Motion_3 Description - Reg Addr --> (0x62), Bit --> 5..4 */
+#define SMI130_USER_INTR_SIGNIFICANT_MOTION_PROOF__POS (4)
+#define SMI130_USER_INTR_SIGNIFICANT_MOTION_PROOF__LEN (2)
+#define SMI130_USER_INTR_SIGNIFICANT_MOTION_PROOF__MSK (0x30)
+#define SMI130_USER_INTR_SIGNIFICANT_MOTION_PROOF__REG \
+ (SMI130_USER_INTR_MOTION_3_ADDR)
+/**************************************************************/
+/**\name TAP DURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* INT_TAP_0 Description - Reg Addr --> (0x63), Bit --> 0..2*/
+#define SMI130_USER_INTR_TAP_0_INTR_TAP_DURN__POS (0)
+#define SMI130_USER_INTR_TAP_0_INTR_TAP_DURN__LEN (3)
+#define SMI130_USER_INTR_TAP_0_INTR_TAP_DURN__MSK (0x07)
+#define SMI130_USER_INTR_TAP_0_INTR_TAP_DURN__REG \
+(SMI130_USER_INTR_TAP_0_ADDR)
+/**************************************************************/
+/**\name TAP SHOCK LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Tap_0 Description - Reg Addr --> (0x63), Bit --> 6 */
+#define SMI130_USER_INTR_TAP_0_INTR_TAP_SHOCK__POS (6)
+#define SMI130_USER_INTR_TAP_0_INTR_TAP_SHOCK__LEN (1)
+#define SMI130_USER_INTR_TAP_0_INTR_TAP_SHOCK__MSK (0x40)
+#define SMI130_USER_INTR_TAP_0_INTR_TAP_SHOCK__REG (SMI130_USER_INTR_TAP_0_ADDR)
+/**************************************************************/
+/**\name TAP QUIET LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Tap_0 Description - Reg Addr --> (0x63), Bit --> 7 */
+#define SMI130_USER_INTR_TAP_0_INTR_TAP_QUIET__POS (7)
+#define SMI130_USER_INTR_TAP_0_INTR_TAP_QUIET__LEN (1)
+#define SMI130_USER_INTR_TAP_0_INTR_TAP_QUIET__MSK (0x80)
+#define SMI130_USER_INTR_TAP_0_INTR_TAP_QUIET__REG (SMI130_USER_INTR_TAP_0_ADDR)
+/**************************************************************/
+/**\name TAP THRESHOLD LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Tap_1 Description - Reg Addr --> (0x64), Bit --> 0...4 */
+#define SMI130_USER_INTR_TAP_1_INTR_TAP_THRES__POS (0)
+#define SMI130_USER_INTR_TAP_1_INTR_TAP_THRES__LEN (5)
+#define SMI130_USER_INTR_TAP_1_INTR_TAP_THRES__MSK (0x1F)
+#define SMI130_USER_INTR_TAP_1_INTR_TAP_THRES__REG (SMI130_USER_INTR_TAP_1_ADDR)
+/**************************************************************/
+/**\name ORIENT MODE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Orient_0 Description - Reg Addr --> (0x65), Bit --> 0...1 */
+#define SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_MODE__POS (0)
+#define SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_MODE__LEN (2)
+#define SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_MODE__MSK (0x03)
+#define SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_MODE__REG \
+ (SMI130_USER_INTR_ORIENT_0_ADDR)
+/**************************************************************/
+/**\name ORIENT BLOCKING LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Orient_0 Description - Reg Addr --> (0x65), Bit --> 2...3 */
+#define SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING__POS (2)
+#define SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING__LEN (2)
+#define SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING__MSK (0x0C)
+#define SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_BLOCKING__REG \
+ (SMI130_USER_INTR_ORIENT_0_ADDR)
+/**************************************************************/
+/**\name ORIENT HYSTERESIS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Orient_0 Description - Reg Addr --> (0x65), Bit --> 4...7 */
+#define SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_HYST__POS (4)
+#define SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_HYST__LEN (4)
+#define SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_HYST__MSK (0xF0)
+#define SMI130_USER_INTR_ORIENT_0_INTR_ORIENT_HYST__REG \
+ (SMI130_USER_INTR_ORIENT_0_ADDR)
+/**************************************************************/
+/**\name ORIENT THETA LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Orient_1 Description - Reg Addr --> 0x66, Bit --> 0...5 */
+#define SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_THETA__POS (0)
+#define SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_THETA__LEN (6)
+#define SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_THETA__MSK (0x3F)
+#define SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_THETA__REG \
+ (SMI130_USER_INTR_ORIENT_1_ADDR)
+/**************************************************************/
+/**\name ORIENT UD LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Orient_1 Description - Reg Addr --> 0x66, Bit --> 6 */
+#define SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE__POS (6)
+#define SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE__LEN (1)
+#define SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE__MSK (0x40)
+#define SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_UD_ENABLE__REG \
+ (SMI130_USER_INTR_ORIENT_1_ADDR)
+/**************************************************************/
+/**\name ORIENT AXIS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Orient_1 Description - Reg Addr --> 0x66, Bit --> 7 */
+#define SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX__POS (7)
+#define SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX__LEN (1)
+#define SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX__MSK (0x80)
+#define SMI130_USER_INTR_ORIENT_1_INTR_ORIENT_AXES_EX__REG \
+ (SMI130_USER_INTR_ORIENT_1_ADDR)
+/**************************************************************/
+/**\name FLAT THETA LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Flat_0 Description - Reg Addr --> 0x67, Bit --> 0...5 */
+#define SMI130_USER_INTR_FLAT_0_INTR_FLAT_THETA__POS (0)
+#define SMI130_USER_INTR_FLAT_0_INTR_FLAT_THETA__LEN (6)
+#define SMI130_USER_INTR_FLAT_0_INTR_FLAT_THETA__MSK (0x3F)
+#define SMI130_USER_INTR_FLAT_0_INTR_FLAT_THETA__REG \
+ (SMI130_USER_INTR_FLAT_0_ADDR)
+/**************************************************************/
+/**\name FLAT HYSTERESIS LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Flat_1 Description - Reg Addr --> (0x68), Bit --> 0...3 */
+#define SMI130_USER_INTR_FLAT_1_INTR_FLAT_HYST__POS (0)
+#define SMI130_USER_INTR_FLAT_1_INTR_FLAT_HYST__LEN (4)
+#define SMI130_USER_INTR_FLAT_1_INTR_FLAT_HYST__MSK (0x0F)
+#define SMI130_USER_INTR_FLAT_1_INTR_FLAT_HYST__REG \
+(SMI130_USER_INTR_FLAT_1_ADDR)
+/**************************************************************/
+/**\name FLAT HOLD LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Int_Flat_1 Description - Reg Addr --> (0x68), Bit --> 4...5 */
+#define SMI130_USER_INTR_FLAT_1_INTR_FLAT_HOLD__POS (4)
+#define SMI130_USER_INTR_FLAT_1_INTR_FLAT_HOLD__LEN (2)
+#define SMI130_USER_INTR_FLAT_1_INTR_FLAT_HOLD__MSK (0x30)
+#define SMI130_USER_INTR_FLAT_1_INTR_FLAT_HOLD__REG \
+(SMI130_USER_INTR_FLAT_1_ADDR)
+/**************************************************************/
+/**\name FOC ACCEL XYZ LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Foc_Conf Description - Reg Addr --> (0x69), Bit --> 0...1 */
+#define SMI130_USER_FOC_ACCEL_Z__POS (0)
+#define SMI130_USER_FOC_ACCEL_Z__LEN (2)
+#define SMI130_USER_FOC_ACCEL_Z__MSK (0x03)
+#define SMI130_USER_FOC_ACCEL_Z__REG (SMI130_USER_FOC_CONFIG_ADDR)
+
+/* Foc_Conf Description - Reg Addr --> (0x69), Bit --> 2...3 */
+#define SMI130_USER_FOC_ACCEL_Y__POS (2)
+#define SMI130_USER_FOC_ACCEL_Y__LEN (2)
+#define SMI130_USER_FOC_ACCEL_Y__MSK (0x0C)
+#define SMI130_USER_FOC_ACCEL_Y__REG (SMI130_USER_FOC_CONFIG_ADDR)
+
+/* Foc_Conf Description - Reg Addr --> (0x69), Bit --> 4...5 */
+#define SMI130_USER_FOC_ACCEL_X__POS (4)
+#define SMI130_USER_FOC_ACCEL_X__LEN (2)
+#define SMI130_USER_FOC_ACCEL_X__MSK (0x30)
+#define SMI130_USER_FOC_ACCEL_X__REG (SMI130_USER_FOC_CONFIG_ADDR)
+/**************************************************************/
+/**\name FOC GYRO LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Foc_Conf Description - Reg Addr --> (0x69), Bit --> 6 */
+#define SMI130_USER_FOC_GYRO_ENABLE__POS (6)
+#define SMI130_USER_FOC_GYRO_ENABLE__LEN (1)
+#define SMI130_USER_FOC_GYRO_ENABLE__MSK (0x40)
+#define SMI130_USER_FOC_GYRO_ENABLE__REG \
+(SMI130_USER_FOC_CONFIG_ADDR)
+/**************************************************************/
+/**\name NVM PROGRAM LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* CONF Description - Reg Addr --> (0x6A), Bit --> 1 */
+#define SMI130_USER_CONFIG_NVM_PROG_ENABLE__POS (1)
+#define SMI130_USER_CONFIG_NVM_PROG_ENABLE__LEN (1)
+#define SMI130_USER_CONFIG_NVM_PROG_ENABLE__MSK (0x02)
+#define SMI130_USER_CONFIG_NVM_PROG_ENABLE__REG \
+(SMI130_USER_CONFIG_ADDR)
+
+/*IF_CONF Description - Reg Addr --> (0x6B), Bit --> 0 */
+
+#define SMI130_USER_IF_CONFIG_SPI3__POS (0)
+#define SMI130_USER_IF_CONFIG_SPI3__LEN (1)
+#define SMI130_USER_IF_CONFIG_SPI3__MSK (0x01)
+#define SMI130_USER_IF_CONFIG_SPI3__REG \
+(SMI130_USER_IF_CONFIG_ADDR)
+
+/*IF_CONF Description - Reg Addr --> (0x6B), Bit --> 5..4 */
+#define SMI130_USER_IF_CONFIG_IF_MODE__POS (4)
+#define SMI130_USER_IF_CONFIG_IF_MODE__LEN (2)
+#define SMI130_USER_IF_CONFIG_IF_MODE__MSK (0x30)
+#define SMI130_USER_IF_CONFIG_IF_MODE__REG \
+(SMI130_USER_IF_CONFIG_ADDR)
+/**************************************************************/
+/**\name GYRO SLEEP CONFIGURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Pmu_Trigger Description - Reg Addr --> 0x6c, Bit --> 0...2 */
+#define SMI130_USER_GYRO_SLEEP_TRIGGER__POS (0)
+#define SMI130_USER_GYRO_SLEEP_TRIGGER__LEN (3)
+#define SMI130_USER_GYRO_SLEEP_TRIGGER__MSK (0x07)
+#define SMI130_USER_GYRO_SLEEP_TRIGGER__REG (SMI130_USER_PMU_TRIGGER_ADDR)
+
+/* Pmu_Trigger Description - Reg Addr --> 0x6c, Bit --> 3...4 */
+#define SMI130_USER_GYRO_WAKEUP_TRIGGER__POS (3)
+#define SMI130_USER_GYRO_WAKEUP_TRIGGER__LEN (2)
+#define SMI130_USER_GYRO_WAKEUP_TRIGGER__MSK (0x18)
+#define SMI130_USER_GYRO_WAKEUP_TRIGGER__REG (SMI130_USER_PMU_TRIGGER_ADDR)
+
+/* Pmu_Trigger Description - Reg Addr --> 0x6c, Bit --> 5 */
+#define SMI130_USER_GYRO_SLEEP_STATE__POS (5)
+#define SMI130_USER_GYRO_SLEEP_STATE__LEN (1)
+#define SMI130_USER_GYRO_SLEEP_STATE__MSK (0x20)
+#define SMI130_USER_GYRO_SLEEP_STATE__REG (SMI130_USER_PMU_TRIGGER_ADDR)
+
+/* Pmu_Trigger Description - Reg Addr --> 0x6c, Bit --> 6 */
+#define SMI130_USER_GYRO_WAKEUP_INTR__POS (6)
+#define SMI130_USER_GYRO_WAKEUP_INTR__LEN (1)
+#define SMI130_USER_GYRO_WAKEUP_INTR__MSK (0x40)
+#define SMI130_USER_GYRO_WAKEUP_INTR__REG (SMI130_USER_PMU_TRIGGER_ADDR)
+/**************************************************************/
+/**\name ACCEL SELF TEST LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Self_Test Description - Reg Addr --> 0x6d, Bit --> 0...1 */
+#define SMI130_USER_ACCEL_SELFTEST_AXIS__POS (0)
+#define SMI130_USER_ACCEL_SELFTEST_AXIS__LEN (2)
+#define SMI130_USER_ACCEL_SELFTEST_AXIS__MSK (0x03)
+#define SMI130_USER_ACCEL_SELFTEST_AXIS__REG (SMI130_USER_SELF_TEST_ADDR)
+
+/* Self_Test Description - Reg Addr --> 0x6d, Bit --> 2 */
+#define SMI130_USER_ACCEL_SELFTEST_SIGN__POS (2)
+#define SMI130_USER_ACCEL_SELFTEST_SIGN__LEN (1)
+#define SMI130_USER_ACCEL_SELFTEST_SIGN__MSK (0x04)
+#define SMI130_USER_ACCEL_SELFTEST_SIGN__REG (SMI130_USER_SELF_TEST_ADDR)
+
+/* Self_Test Description - Reg Addr --> 0x6d, Bit --> 3 */
+#define SMI130_USER_SELFTEST_AMP__POS (3)
+#define SMI130_USER_SELFTEST_AMP__LEN (1)
+#define SMI130_USER_SELFTEST_AMP__MSK (0x08)
+#define SMI130_USER_SELFTEST_AMP__REG (SMI130_USER_SELF_TEST_ADDR)
+/**************************************************************/
+/**\name GYRO SELF TEST LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Self_Test Description - Reg Addr --> 0x6d, Bit --> 4 */
+#define SMI130_USER_GYRO_SELFTEST_START__POS (4)
+#define SMI130_USER_GYRO_SELFTEST_START__LEN (1)
+#define SMI130_USER_GYRO_SELFTEST_START__MSK (0x10)
+#define SMI130_USER_GYRO_SELFTEST_START__REG \
+(SMI130_USER_SELF_TEST_ADDR)
+/**************************************************************/
+/**\name NV_CONFIG LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* NV_CONF Description - Reg Addr --> (0x70), Bit --> 0 */
+#define SMI130_USER_NV_CONFIG_SPI_ENABLE__POS (0)
+#define SMI130_USER_NV_CONFIG_SPI_ENABLE__LEN (1)
+#define SMI130_USER_NV_CONFIG_SPI_ENABLE__MSK (0x01)
+#define SMI130_USER_NV_CONFIG_SPI_ENABLE__REG (SMI130_USER_NV_CONFIG_ADDR)
+
+/*IF_CONF Description - Reg Addr --> (0x70), Bit --> 1 */
+#define SMI130_USER_IF_CONFIG_I2C_WDT_SELECT__POS (1)
+#define SMI130_USER_IF_CONFIG_I2C_WDT_SELECT__LEN (1)
+#define SMI130_USER_IF_CONFIG_I2C_WDT_SELECT__MSK (0x02)
+#define SMI130_USER_IF_CONFIG_I2C_WDT_SELECT__REG \
+(SMI130_USER_NV_CONFIG_ADDR)
+
+/*IF_CONF Description - Reg Addr --> (0x70), Bit --> 2 */
+#define SMI130_USER_IF_CONFIG_I2C_WDT_ENABLE__POS (2)
+#define SMI130_USER_IF_CONFIG_I2C_WDT_ENABLE__LEN (1)
+#define SMI130_USER_IF_CONFIG_I2C_WDT_ENABLE__MSK (0x04)
+#define SMI130_USER_IF_CONFIG_I2C_WDT_ENABLE__REG \
+(SMI130_USER_NV_CONFIG_ADDR)
+
+/* NV_CONF Description - Reg Addr --> (0x70), Bit --> 3 */
+#define SMI130_USER_NV_CONFIG_SPARE0__POS (3)
+#define SMI130_USER_NV_CONFIG_SPARE0__LEN (1)
+#define SMI130_USER_NV_CONFIG_SPARE0__MSK (0x08)
+#define SMI130_USER_NV_CONFIG_SPARE0__REG (SMI130_USER_NV_CONFIG_ADDR)
+
+/* NV_CONF Description - Reg Addr --> (0x70), Bit --> 4...7 */
+#define SMI130_USER_NV_CONFIG_NVM_COUNTER__POS (4)
+#define SMI130_USER_NV_CONFIG_NVM_COUNTER__LEN (4)
+#define SMI130_USER_NV_CONFIG_NVM_COUNTER__MSK (0xF0)
+#define SMI130_USER_NV_CONFIG_NVM_COUNTER__REG (SMI130_USER_NV_CONFIG_ADDR)
+/**************************************************************/
+/**\name ACCEL MANUAL OFFSET LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Offset_0 Description - Reg Addr --> (0x71), Bit --> 0...7 */
+#define SMI130_USER_OFFSET_0_ACCEL_OFF_X__POS (0)
+#define SMI130_USER_OFFSET_0_ACCEL_OFF_X__LEN (8)
+#define SMI130_USER_OFFSET_0_ACCEL_OFF_X__MSK (0xFF)
+#define SMI130_USER_OFFSET_0_ACCEL_OFF_X__REG (SMI130_USER_OFFSET_0_ADDR)
+
+/* Offset_1 Description - Reg Addr --> 0x72, Bit --> 0...7 */
+#define SMI130_USER_OFFSET_1_ACCEL_OFF_Y__POS (0)
+#define SMI130_USER_OFFSET_1_ACCEL_OFF_Y__LEN (8)
+#define SMI130_USER_OFFSET_1_ACCEL_OFF_Y__MSK (0xFF)
+#define SMI130_USER_OFFSET_1_ACCEL_OFF_Y__REG (SMI130_USER_OFFSET_1_ADDR)
+
+/* Offset_2 Description - Reg Addr --> 0x73, Bit --> 0...7 */
+#define SMI130_USER_OFFSET_2_ACCEL_OFF_Z__POS (0)
+#define SMI130_USER_OFFSET_2_ACCEL_OFF_Z__LEN (8)
+#define SMI130_USER_OFFSET_2_ACCEL_OFF_Z__MSK (0xFF)
+#define SMI130_USER_OFFSET_2_ACCEL_OFF_Z__REG (SMI130_USER_OFFSET_2_ADDR)
+/**************************************************************/
+/**\name GYRO MANUAL OFFSET LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Offset_3 Description - Reg Addr --> 0x74, Bit --> 0...7 */
+#define SMI130_USER_OFFSET_3_GYRO_OFF_X__POS (0)
+#define SMI130_USER_OFFSET_3_GYRO_OFF_X__LEN (8)
+#define SMI130_USER_OFFSET_3_GYRO_OFF_X__MSK (0xFF)
+#define SMI130_USER_OFFSET_3_GYRO_OFF_X__REG (SMI130_USER_OFFSET_3_ADDR)
+
+/* Offset_4 Description - Reg Addr --> 0x75, Bit --> 0...7 */
+#define SMI130_USER_OFFSET_4_GYRO_OFF_Y__POS (0)
+#define SMI130_USER_OFFSET_4_GYRO_OFF_Y__LEN (8)
+#define SMI130_USER_OFFSET_4_GYRO_OFF_Y__MSK (0xFF)
+#define SMI130_USER_OFFSET_4_GYRO_OFF_Y__REG (SMI130_USER_OFFSET_4_ADDR)
+
+/* Offset_5 Description - Reg Addr --> 0x76, Bit --> 0...7 */
+#define SMI130_USER_OFFSET_5_GYRO_OFF_Z__POS (0)
+#define SMI130_USER_OFFSET_5_GYRO_OFF_Z__LEN (8)
+#define SMI130_USER_OFFSET_5_GYRO_OFF_Z__MSK (0xFF)
+#define SMI130_USER_OFFSET_5_GYRO_OFF_Z__REG (SMI130_USER_OFFSET_5_ADDR)
+
+
+/* Offset_6 Description - Reg Addr --> 0x77, Bit --> 0..1 */
+#define SMI130_USER_OFFSET_6_GYRO_OFF_X__POS (0)
+#define SMI130_USER_OFFSET_6_GYRO_OFF_X__LEN (2)
+#define SMI130_USER_OFFSET_6_GYRO_OFF_X__MSK (0x03)
+#define SMI130_USER_OFFSET_6_GYRO_OFF_X__REG (SMI130_USER_OFFSET_6_ADDR)
+
+/* Offset_6 Description - Reg Addr --> 0x77, Bit --> 2...3 */
+#define SMI130_USER_OFFSET_6_GYRO_OFF_Y__POS (2)
+#define SMI130_USER_OFFSET_6_GYRO_OFF_Y__LEN (2)
+#define SMI130_USER_OFFSET_6_GYRO_OFF_Y__MSK (0x0C)
+#define SMI130_USER_OFFSET_6_GYRO_OFF_Y__REG (SMI130_USER_OFFSET_6_ADDR)
+
+/* Offset_6 Description - Reg Addr --> 0x77, Bit --> 4...5 */
+#define SMI130_USER_OFFSET_6_GYRO_OFF_Z__POS (4)
+#define SMI130_USER_OFFSET_6_GYRO_OFF_Z__LEN (2)
+#define SMI130_USER_OFFSET_6_GYRO_OFF_Z__MSK (0x30)
+#define SMI130_USER_OFFSET_6_GYRO_OFF_Z__REG (SMI130_USER_OFFSET_6_ADDR)
+/**************************************************************/
+/**\name ACCEL OFFSET ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Offset_6 Description - Reg Addr --> 0x77, Bit --> 6 */
+#define SMI130_USER_OFFSET_6_ACCEL_OFF_ENABLE__POS (6)
+#define SMI130_USER_OFFSET_6_ACCEL_OFF_ENABLE__LEN (1)
+#define SMI130_USER_OFFSET_6_ACCEL_OFF_ENABLE__MSK (0x40)
+#define SMI130_USER_OFFSET_6_ACCEL_OFF_ENABLE__REG \
+(SMI130_USER_OFFSET_6_ADDR)
+/**************************************************************/
+/**\name GYRO OFFSET ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Offset_6 Description - Reg Addr --> 0x77, Bit --> 7 */
+#define SMI130_USER_OFFSET_6_GYRO_OFF_EN__POS (7)
+#define SMI130_USER_OFFSET_6_GYRO_OFF_EN__LEN (1)
+#define SMI130_USER_OFFSET_6_GYRO_OFF_EN__MSK (0x80)
+#define SMI130_USER_OFFSET_6_GYRO_OFF_EN__REG (SMI130_USER_OFFSET_6_ADDR)
+/**************************************************************/
+/**\name STEP COUNTER LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* STEP_CNT_0 Description - Reg Addr --> 0x78, Bit --> 0 to 7 */
+#define SMI130_USER_STEP_COUNT_LSB__POS (0)
+#define SMI130_USER_STEP_COUNT_LSB__LEN (7)
+#define SMI130_USER_STEP_COUNT_LSB__MSK (0xFF)
+#define SMI130_USER_STEP_COUNT_LSB__REG (SMI130_USER_STEP_COUNT_0_ADDR)
+
+/* STEP_CNT_1 Description - Reg Addr --> 0x79, Bit --> 0 to 7 */
+#define SMI130_USER_STEP_COUNT_MSB__POS (0)
+#define SMI130_USER_STEP_COUNT_MSB__LEN (7)
+#define SMI130_USER_STEP_COUNT_MSB__MSK (0xFF)
+#define SMI130_USER_STEP_COUNT_MSB__REG (SMI130_USER_STEP_COUNT_1_ADDR)
+/**************************************************************/
+/**\name STEP COUNTER CONFIGURATION LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* STEP_CONFIG_0 Description - Reg Addr --> 0x7A, Bit --> 0 to 7 */
+#define SMI130_USER_STEP_CONFIG_ZERO__POS (0)
+#define SMI130_USER_STEP_CONFIG_ZERO__LEN (7)
+#define SMI130_USER_STEP_CONFIG_ZERO__MSK (0xFF)
+#define SMI130_USER_STEP_CONFIG_ZERO__REG \
+(SMI130_USER_STEP_CONFIG_0_ADDR)
+
+
+/* STEP_CONFIG_1 Description - Reg Addr --> 0x7B, Bit --> 0 to 2 and
+4 to 7 */
+#define SMI130_USER_STEP_CONFIG_ONE_CNF1__POS (0)
+#define SMI130_USER_STEP_CONFIG_ONE_CNF1__LEN (3)
+#define SMI130_USER_STEP_CONFIG_ONE_CNF1__MSK (0x07)
+#define SMI130_USER_STEP_CONFIG_ONE_CNF1__REG \
+(SMI130_USER_STEP_CONFIG_1_ADDR)
+
+#define SMI130_USER_STEP_CONFIG_ONE_CNF2__POS (4)
+#define SMI130_USER_STEP_CONFIG_ONE_CNF2__LEN (4)
+#define SMI130_USER_STEP_CONFIG_ONE_CNF2__MSK (0xF0)
+#define SMI130_USER_STEP_CONFIG_ONE_CNF2__REG \
+(SMI130_USER_STEP_CONFIG_1_ADDR)
+/**************************************************************/
+/**\name STEP COUNTER ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* STEP_CONFIG_1 Description - Reg Addr --> 0x7B, Bit --> 0 to 2 */
+#define SMI130_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE__POS (3)
+#define SMI130_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE__LEN (1)
+#define SMI130_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE__MSK (0x08)
+#define SMI130_USER_STEP_CONFIG_1_STEP_COUNT_ENABLE__REG \
+(SMI130_USER_STEP_CONFIG_1_ADDR)
+
+/* USER REGISTERS DEFINITION END */
+/**************************************************************************/
+/* CMD REGISTERS DEFINITION START */
+/**************************************************************/
+/**\name COMMAND REGISTER LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Command description address - Reg Addr --> 0x7E, Bit --> 0....7 */
+#define SMI130_CMD_COMMANDS__POS (0)
+#define SMI130_CMD_COMMANDS__LEN (8)
+#define SMI130_CMD_COMMANDS__MSK (0xFF)
+#define SMI130_CMD_COMMANDS__REG (SMI130_CMD_COMMANDS_ADDR)
+/**************************************************************/
+/**\name PAGE ENABLE LENGTH, POSITION AND MASK*/
+/**************************************************************/
+/* Target page address - Reg Addr --> 0x7F, Bit --> 4....5 */
+#define SMI130_CMD_TARGET_PAGE__POS (4)
+#define SMI130_CMD_TARGET_PAGE__LEN (2)
+#define SMI130_CMD_TARGET_PAGE__MSK (0x30)
+#define SMI130_CMD_TARGET_PAGE__REG (SMI130_CMD_EXT_MODE_ADDR)
+
+/* Target page address - Reg Addr --> 0x7F, Bit --> 4....5 */
+#define SMI130_CMD_PAGING_EN__POS (7)
+#define SMI130_CMD_PAGING_EN__LEN (1)
+#define SMI130_CMD_PAGING_EN__MSK (0x80)
+#define SMI130_CMD_PAGING_EN__REG (SMI130_CMD_EXT_MODE_ADDR)
+
+/* Target page address - Reg Addr --> 0x7F, Bit --> 4....5 */
+#define SMI130_COM_C_TRIM_FIVE__POS (0)
+#define SMI130_COM_C_TRIM_FIVE__LEN (8)
+#define SMI130_COM_C_TRIM_FIVE__MSK (0xFF)
+#define SMI130_COM_C_TRIM_FIVE__REG (SMI130_COM_C_TRIM_FIVE_ADDR)
+
+/**************************************************************************/
+/* CMD REGISTERS DEFINITION END */
+
+/**************************************************/
+/**\name FIFO FRAME COUNT DEFINITION */
+/*************************************************/
+#define FIFO_FRAME (1024)
+#define FIFO_CONFIG_CHECK1 (0x00)
+#define FIFO_CONFIG_CHECK2 (0x80)
+/**************************************************/
+/**\name MAG SENSOR SELECT */
+/*************************************************/
+#define BST_BMM (0)
+#define BST_AKM (1)
+#define SMI130_YAS537_I2C_ADDRESS (0x2E)
+/**************************************************/
+/**\name ACCEL RANGE */
+/*************************************************/
+#define SMI130_ACCEL_RANGE_2G (0X03)
+#define SMI130_ACCEL_RANGE_4G (0X05)
+#define SMI130_ACCEL_RANGE_8G (0X08)
+#define SMI130_ACCEL_RANGE_16G (0X0C)
+/**************************************************/
+/**\name ACCEL ODR */
+/*************************************************/
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_RESERVED (0x00)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_0_78HZ (0x01)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_1_56HZ (0x02)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_3_12HZ (0x03)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_6_25HZ (0x04)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_12_5HZ (0x05)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_25HZ (0x06)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_50HZ (0x07)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_100HZ (0x08)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_200HZ (0x09)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_400HZ (0x0A)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_800HZ (0x0B)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_1600HZ (0x0C)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_RESERVED0 (0x0D)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_RESERVED1 (0x0E)
+#define SMI130_ACCEL_OUTPUT_DATA_RATE_RESERVED2 (0x0F)
+/**************************************************/
+/**\name ACCEL BANDWIDTH PARAMETER */
+/*************************************************/
+#define SMI130_ACCEL_OSR4_AVG1 (0x00)
+#define SMI130_ACCEL_OSR2_AVG2 (0x01)
+#define SMI130_ACCEL_NORMAL_AVG4 (0x02)
+#define SMI130_ACCEL_CIC_AVG8 (0x03)
+#define SMI130_ACCEL_RES_AVG16 (0x04)
+#define SMI130_ACCEL_RES_AVG32 (0x05)
+#define SMI130_ACCEL_RES_AVG64 (0x06)
+#define SMI130_ACCEL_RES_AVG128 (0x07)
+/**************************************************/
+/**\name GYRO ODR */
+/*************************************************/
+#define SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED (0x00)
+#define SMI130_GYRO_OUTPUT_DATA_RATE_25HZ (0x06)
+#define SMI130_GYRO_OUTPUT_DATA_RATE_50HZ (0x07)
+#define SMI130_GYRO_OUTPUT_DATA_RATE_100HZ (0x08)
+#define SMI130_GYRO_OUTPUT_DATA_RATE_200HZ (0x09)
+#define SMI130_GYRO_OUTPUT_DATA_RATE_400HZ (0x0A)
+#define SMI130_GYRO_OUTPUT_DATA_RATE_800HZ (0x0B)
+#define SMI130_GYRO_OUTPUT_DATA_RATE_1600HZ (0x0C)
+#define SMI130_GYRO_OUTPUT_DATA_RATE_3200HZ (0x0D)
+/**************************************************/
+/**\name GYRO BANDWIDTH PARAMETER */
+/*************************************************/
+#define SMI130_GYRO_OSR4_MODE (0x00)
+#define SMI130_GYRO_OSR2_MODE (0x01)
+#define SMI130_GYRO_NORMAL_MODE (0x02)
+#define SMI130_GYRO_CIC_MODE (0x03)
+/**************************************************/
+/**\name GYROSCOPE RANGE PARAMETER */
+/*************************************************/
+#define SMI130_GYRO_RANGE_2000_DEG_SEC (0x00)
+#define SMI130_GYRO_RANGE_1000_DEG_SEC (0x01)
+#define SMI130_GYRO_RANGE_500_DEG_SEC (0x02)
+#define SMI130_GYRO_RANGE_250_DEG_SEC (0x03)
+#define SMI130_GYRO_RANGE_125_DEG_SEC (0x04)
+/**************************************************/
+/**\name MAG ODR */
+/*************************************************/
+#define SMI130_MAG_OUTPUT_DATA_RATE_RESERVED (0x00)
+#define SMI130_MAG_OUTPUT_DATA_RATE_0_78HZ (0x01)
+#define SMI130_MAG_OUTPUT_DATA_RATE_1_56HZ (0x02)
+#define SMI130_MAG_OUTPUT_DATA_RATE_3_12HZ (0x03)
+#define SMI130_MAG_OUTPUT_DATA_RATE_6_25HZ (0x04)
+#define SMI130_MAG_OUTPUT_DATA_RATE_12_5HZ (0x05)
+#define SMI130_MAG_OUTPUT_DATA_RATE_25HZ (0x06)
+#define SMI130_MAG_OUTPUT_DATA_RATE_50HZ (0x07)
+#define SMI130_MAG_OUTPUT_DATA_RATE_100HZ (0x08)
+#define SMI130_MAG_OUTPUT_DATA_RATE_200HZ (0x09)
+#define SMI130_MAG_OUTPUT_DATA_RATE_400HZ (0x0A)
+#define SMI130_MAG_OUTPUT_DATA_RATE_800HZ (0x0B)
+#define SMI130_MAG_OUTPUT_DATA_RATE_1600HZ (0x0C)
+#define SMI130_MAG_OUTPUT_DATA_RATE_RESERVED0 (0x0D)
+#define SMI130_MAG_OUTPUT_DATA_RATE_RESERVED1 (0x0E)
+#define SMI130_MAG_OUTPUT_DATA_RATE_RESERVED2 (0x0F)
+
+/**************************************************/
+/**\name ENABLE/DISABLE SELECTIONS */
+/*************************************************/
+
+/* Enable accel and gyro offset */
+#define ACCEL_OFFSET_ENABLE (0x01)
+#define GYRO_OFFSET_ENABLE (0x01)
+
+/* command register definition */
+#define START_FOC_ACCEL_GYRO (0X03)
+
+ /* INT ENABLE 1 */
+#define SMI130_ANY_MOTION_X_ENABLE (0)
+#define SMI130_ANY_MOTION_Y_ENABLE (1)
+#define SMI130_ANY_MOTION_Z_ENABLE (2)
+#define SMI130_DOUBLE_TAP_ENABLE (4)
+#define SMI130_SINGLE_TAP_ENABLE (5)
+#define SMI130_ORIENT_ENABLE (6)
+#define SMI130_FLAT_ENABLE (7)
+
+/* INT ENABLE 1 */
+#define SMI130_HIGH_G_X_ENABLE (0)
+#define SMI130_HIGH_G_Y_ENABLE (1)
+#define SMI130_HIGH_G_Z_ENABLE (2)
+#define SMI130_LOW_G_ENABLE (3)
+#define SMI130_DATA_RDY_ENABLE (4)
+#define SMI130_FIFO_FULL_ENABLE (5)
+#define SMI130_FIFO_WM_ENABLE (6)
+
+/* INT ENABLE 2 */
+#define SMI130_NOMOTION_X_ENABLE (0)
+#define SMI130_NOMOTION_Y_ENABLE (1)
+#define SMI130_NOMOTION_Z_ENABLE (2)
+#define SMI130_STEP_DETECTOR_EN (3)
+
+/* FOC axis selection for accel*/
+#define FOC_X_AXIS (0)
+#define FOC_Y_AXIS (1)
+#define FOC_Z_AXIS (2)
+
+/* IN OUT CONTROL */
+#define SMI130_INTR1_EDGE_CTRL (0)
+#define SMI130_INTR2_EDGE_CTRL (1)
+#define SMI130_INTR1_LEVEL (0)
+#define SMI130_INTR2_LEVEL (1)
+#define SMI130_INTR1_OUTPUT_TYPE (0)
+#define SMI130_INTR2_OUTPUT_TYPE (1)
+#define SMI130_INTR1_OUTPUT_ENABLE (0)
+#define SMI130_INTR2_OUTPUT_ENABLE (1)
+
+#define SMI130_INTR1_INPUT_ENABLE (0)
+#define SMI130_INTR2_INPUT_ENABLE (1)
+
+/* INTERRUPT MAPS */
+#define SMI130_INTR1_MAP_LOW_G (0)
+#define SMI130_INTR2_MAP_LOW_G (1)
+#define SMI130_INTR1_MAP_HIGH_G (0)
+#define SMI130_INTR2_MAP_HIGH_G (1)
+#define SMI130_INTR1_MAP_ANY_MOTION (0)
+#define SMI130_INTR2_MAP_ANY_MOTION (1)
+#define SMI130_INTR1_MAP_NOMO (0)
+#define SMI130_INTR2_MAP_NOMO (1)
+#define SMI130_INTR1_MAP_DOUBLE_TAP (0)
+#define SMI130_INTR2_MAP_DOUBLE_TAP (1)
+#define SMI130_INTR1_MAP_SINGLE_TAP (0)
+#define SMI130_INTR2_MAP_SINGLE_TAP (1)
+#define SMI130_INTR1_MAP_ORIENT (0)
+#define SMI130_INTR2_MAP_ORIENT (1)
+#define SMI130_INTR1_MAP_FLAT (0)
+#define SMI130_INTR2_MAP_FLAT (1)
+#define SMI130_INTR1_MAP_DATA_RDY (0)
+#define SMI130_INTR2_MAP_DATA_RDY (1)
+#define SMI130_INTR1_MAP_FIFO_WM (0)
+#define SMI130_INTR2_MAP_FIFO_WM (1)
+#define SMI130_INTR1_MAP_FIFO_FULL (0)
+#define SMI130_INTR2_MAP_FIFO_FULL (1)
+#define SMI130_INTR1_MAP_PMUTRIG (0)
+#define SMI130_INTR2_MAP_PMUTRIG (1)
+
+/* Interrupt mapping*/
+#define SMI130_MAP_INTR1 (0)
+#define SMI130_MAP_INTR2 (1)
+/**************************************************/
+/**\name TAP DURATION */
+/*************************************************/
+#define SMI130_TAP_DURN_50MS (0x00)
+#define SMI130_TAP_DURN_100MS (0x01)
+#define SMI130_TAP_DURN_150MS (0x02)
+#define SMI130_TAP_DURN_200MS (0x03)
+#define SMI130_TAP_DURN_250MS (0x04)
+#define SMI130_TAP_DURN_375MS (0x05)
+#define SMI130_TAP_DURN_500MS (0x06)
+#define SMI130_TAP_DURN_700MS (0x07)
+/**************************************************/
+/**\name TAP SHOCK */
+/*************************************************/
+#define SMI130_TAP_SHOCK_50MS (0x00)
+#define SMI130_TAP_SHOCK_75MS (0x01)
+/**************************************************/
+/**\name TAP QUIET */
+/*************************************************/
+#define SMI130_TAP_QUIET_30MS (0x00)
+#define SMI130_TAP_QUIET_20MS (0x01)
+/**************************************************/
+/**\name STEP DETECTION SELECTION MODES */
+/*************************************************/
+#define SMI130_STEP_NORMAL_MODE (0)
+#define SMI130_STEP_SENSITIVE_MODE (1)
+#define SMI130_STEP_ROBUST_MODE (2)
+/**************************************************/
+/**\name STEP CONFIGURATION SELECT MODE */
+/*************************************************/
+#define STEP_CONFIG_NORMAL (0X315)
+#define STEP_CONFIG_SENSITIVE (0X2D)
+#define STEP_CONFIG_ROBUST (0X71D)
+/**************************************************/
+/**\name BMM150 TRIM DATA DEFINITIONS */
+/*************************************************/
+#define SMI130_MAG_DIG_X1 (0x5D)
+#define SMI130_MAG_DIG_Y1 (0x5E)
+#define SMI130_MAG_DIG_Z4_LSB (0x62)
+#define SMI130_MAG_DIG_Z4_MSB (0x63)
+#define SMI130_MAG_DIG_X2 (0x64)
+#define SMI130_MAG_DIG_Y2 (0x65)
+#define SMI130_MAG_DIG_Z2_LSB (0x68)
+#define SMI130_MAG_DIG_Z2_MSB (0x69)
+#define SMI130_MAG_DIG_Z1_LSB (0x6A)
+#define SMI130_MAG_DIG_Z1_MSB (0x6B)
+#define SMI130_MAG_DIG_XYZ1_LSB (0x6C)
+#define SMI130_MAG_DIG_XYZ1_MSB (0x6D)
+#define SMI130_MAG_DIG_Z3_LSB (0x6E)
+#define SMI130_MAG_DIG_Z3_MSB (0x6F)
+#define SMI130_MAG_DIG_XY2 (0x70)
+#define SMI130_MAG_DIG_XY1 (0x71)
+/**************************************************/
+/**\name BMM150 PRE-SET MODE DEFINITIONS */
+/*************************************************/
+#define SMI130_MAG_PRESETMODE_LOWPOWER (1)
+#define SMI130_MAG_PRESETMODE_REGULAR (2)
+#define SMI130_MAG_PRESETMODE_HIGHACCURACY (3)
+#define SMI130_MAG_PRESETMODE_ENHANCED (4)
+/**************************************************/
+/**\name BMM150 PRESET MODES - DATA RATES */
+/*************************************************/
+#define SMI130_MAG_LOWPOWER_DR (0x02)
+#define SMI130_MAG_REGULAR_DR (0x02)
+#define SMI130_MAG_HIGHACCURACY_DR (0x2A)
+#define SMI130_MAG_ENHANCED_DR (0x02)
+/**************************************************/
+/**\name BMM150 PRESET MODES - REPETITIONS-XY RATES */
+/*************************************************/
+#define SMI130_MAG_LOWPOWER_REPXY (1)
+#define SMI130_MAG_REGULAR_REPXY (4)
+#define SMI130_MAG_HIGHACCURACY_REPXY (23)
+#define SMI130_MAG_ENHANCED_REPXY (7)
+/**************************************************/
+/**\name BMM150 PRESET MODES - REPETITIONS-Z RATES */
+/*************************************************/
+#define SMI130_MAG_LOWPOWER_REPZ (2)
+#define SMI130_MAG_REGULAR_REPZ (14)
+#define SMI130_MAG_HIGHACCURACY_REPZ (82)
+#define SMI130_MAG_ENHANCED_REPZ (26)
+#define SMI130_MAG_NOAMRL_SWITCH_TIMES (5)
+#define MAG_INTERFACE_PMU_ENABLE (1)
+#define MAG_INTERFACE_PMU_DISABLE (0)
+/**************************************************/
+/**\name USED FOR MAG OVERFLOW CHECK FOR BMM150 */
+/*************************************************/
+#define SMI130_MAG_OVERFLOW_OUTPUT ((s16)-32768)
+#define SMI130_MAG_OVERFLOW_OUTPUT_S32 ((s32)(-2147483647-1))
+#define SMI130_MAG_NEGATIVE_SATURATION_Z ((s16)-32767)
+#define SMI130_MAG_POSITIVE_SATURATION_Z ((u16)32767)
+#define SMI130_MAG_FLIP_OVERFLOW_ADCVAL ((s16)-4096)
+#define SMI130_MAG_HALL_OVERFLOW_ADCVAL ((s16)-16384)
+/**************************************************/
+/**\name BMM150 REGISTER DEFINITION */
+/*************************************************/
+#define SMI130_BMM150_CHIP_ID (0x40)
+#define SMI130_BMM150_POWE_CONTROL_REG (0x4B)
+#define SMI130_BMM150_POWE_MODE_REG (0x4C)
+#define SMI130_BMM150_DATA_REG (0x42)
+#define SMI130_BMM150_XY_REP (0x51)
+#define SMI130_BMM150_Z_REP (0x52)
+/**************************************************/
+/**\name AKM COMPENSATING DATA REGISTERS */
+/*************************************************/
+#define SMI130_BST_AKM_ASAX (0x60)
+#define SMI130_BST_AKM_ASAY (0x61)
+#define SMI130_BST_AKM_ASAZ (0x62)
+/**************************************************/
+/**\name AKM POWER MODE SELECTION */
+/*************************************************/
+#define AKM_POWER_DOWN_MODE (0)
+#define AKM_SINGLE_MEAS_MODE (1)
+#define FUSE_ROM_MODE (2)
+/**************************************************/
+/**\name SECONDARY_MAG POWER MODE SELECTION */
+/*************************************************/
+#define SMI130_MAG_FORCE_MODE (0)
+#define SMI130_MAG_SUSPEND_MODE (1)
+/**************************************************/
+/**\name MAG POWER MODE SELECTION */
+/*************************************************/
+#define FORCE_MODE (0)
+#define SUSPEND_MODE (1)
+#define NORMAL_MODE (2)
+#define MAG_SUSPEND_MODE (1)
+/**************************************************/
+/**\name FIFO CONFIGURATIONS */
+/*************************************************/
+#define FIFO_HEADER_ENABLE (0x01)
+#define FIFO_MAG_ENABLE (0x01)
+#define FIFO_ACCEL_ENABLE (0x01)
+#define FIFO_GYRO_ENABLE (0x01)
+#define FIFO_TIME_ENABLE (0x01)
+#define FIFO_STOPONFULL_ENABLE (0x01)
+#define FIFO_WM_INTERRUPT_ENABLE (0x01)
+#define SMI130_FIFO_INDEX_LENGTH (1)
+#define SMI130_FIFO_TAG_INTR_MASK (0xFC)
+
+/**************************************************/
+/**\name ACCEL POWER MODE */
+/*************************************************/
+#define ACCEL_MODE_NORMAL (0x11)
+#define ACCEL_LOWPOWER (0X12)
+#define ACCEL_SUSPEND (0X10)
+/**************************************************/
+/**\name GYRO POWER MODE */
+/*************************************************/
+#define GYRO_MODE_SUSPEND (0x14)
+#define GYRO_MODE_NORMAL (0x15)
+#define GYRO_MODE_FASTSTARTUP (0x17)
+/**************************************************/
+/**\name MAG POWER MODE */
+/*************************************************/
+#define MAG_MODE_SUSPEND (0x18)
+#define MAG_MODE_NORMAL (0x19)
+#define MAG_MODE_LOWPOWER (0x1A)
+/**************************************************/
+/**\name ENABLE/DISABLE BIT VALUES */
+/*************************************************/
+#define SMI130_ENABLE (0x01)
+#define SMI130_DISABLE (0x00)
+/**************************************************/
+/**\name INTERRUPT EDGE TRIGGER ENABLE */
+/*************************************************/
+#define SMI130_EDGE (0x01)
+#define SMI130_LEVEL (0x00)
+/**************************************************/
+/**\name INTERRUPT LEVEL ENABLE */
+/*************************************************/
+#define SMI130_LEVEL_LOW (0x00)
+#define SMI130_LEVEL_HIGH (0x01)
+/**************************************************/
+/**\name INTERRUPT OUTPUT ENABLE */
+/*************************************************/
+#define SMI130_OPEN_DRAIN (0x01)
+#define SMI130_PUSH_PULL (0x00)
+
+/* interrupt output enable*/
+#define SMI130_INPUT (0x01)
+#define SMI130_OUTPUT (0x00)
+
+/**************************************************/
+/**\name INTERRUPT TAP SOURCE ENABLE */
+/*************************************************/
+#define FILTER_DATA (0x00)
+#define UNFILTER_DATA (0x01)
+/**************************************************/
+/**\name SLOW MOTION/ NO MOTION SELECT */
+/*************************************************/
+#define SLOW_MOTION (0x00)
+#define NO_MOTION (0x01)
+/**************************************************/
+/**\name SIGNIFICANT MOTION SELECTION */
+/*************************************************/
+#define ANY_MOTION (0x00)
+#define SIGNIFICANT_MOTION (0x01)
+/**************************************************/
+/**\name LATCH DURATION */
+/*************************************************/
+#define SMI130_LATCH_DUR_NONE (0x00)
+#define SMI130_LATCH_DUR_312_5_MICRO_SEC (0x01)
+#define SMI130_LATCH_DUR_625_MICRO_SEC (0x02)
+#define SMI130_LATCH_DUR_1_25_MILLI_SEC (0x03)
+#define SMI130_LATCH_DUR_2_5_MILLI_SEC (0x04)
+#define SMI130_LATCH_DUR_5_MILLI_SEC (0x05)
+#define SMI130_LATCH_DUR_10_MILLI_SEC (0x06)
+#define SMI130_LATCH_DUR_20_MILLI_SEC (0x07)
+#define SMI130_LATCH_DUR_40_MILLI_SEC (0x08)
+#define SMI130_LATCH_DUR_80_MILLI_SEC (0x09)
+#define SMI130_LATCH_DUR_160_MILLI_SEC (0x0A)
+#define SMI130_LATCH_DUR_320_MILLI_SEC (0x0B)
+#define SMI130_LATCH_DUR_640_MILLI_SEC (0x0C)
+#define SMI130_LATCH_DUR_1_28_SEC (0x0D)
+#define SMI130_LATCH_DUR_2_56_SEC (0x0E)
+#define SMI130_LATCHED (0x0F)
+/**************************************************/
+/**\name GYRO OFFSET MASK DEFINITION */
+/*************************************************/
+#define SMI130_GYRO_MANUAL_OFFSET_0_7 (0x00FF)
+#define SMI130_GYRO_MANUAL_OFFSET_8_9 (0x0300)
+/**************************************************/
+/**\name STEP CONFIGURATION MASK DEFINITION */
+/*************************************************/
+#define SMI130_STEP_CONFIG_0_7 (0x00FF)
+#define SMI130_STEP_CONFIG_8_10 (0x0700)
+#define SMI130_STEP_CONFIG_11_14 (0xF000)
+/**************************************************/
+/**\name DEFINITION USED FOR DIFFERENT WRITE */
+/*************************************************/
+#define SMI130_WRITE_TARGET_PAGE0 (0x00)
+#define SMI130_WRITE_TARGET_PAGE1 (0x01)
+#define SMI130_WRITE_ENABLE_PAGE1 (0x01)
+#define SMI130_MANUAL_DISABLE (0x00)
+#define SMI130_MANUAL_ENABLE (0x01)
+#define SMI130_YAS_DISABLE_RCOIL (0x00)
+#define SMI130_ENABLE_MAG_IF_MODE (0x02)
+#define SMI130_ENABLE_ANY_MOTION_INTR1 (0x04)
+#define SMI130_ENABLE_ANY_MOTION_INTR2 (0x04)
+#define SMI130_MAG_DATA_READ_REG (0x04)
+#define SMI130_BMM_POWER_MODE_REG (0x06)
+#define SMI130_ENABLE_ANY_MOTION_AXIS (0x07)
+#define SMI130_ENABLE_LOW_G (0x08)
+#define SMI130_YAS532_ACQ_START (0x11)
+#define SMI130_YAS_DEVICE_ID_REG (0x80)
+#define SMI130_FIFO_GYRO_ENABLE (0x80)
+#define SMI130_SIG_MOTION_INTR_ENABLE (0x01)
+#define SMI130_STEP_DETECT_INTR_ENABLE (0x01)
+#define SMI130_LOW_G_INTR_STAT (0x01)
+#define SMI130_PULL_UP_DATA (0x30)
+#define SMI130_FIFO_M_G_A_ENABLE (0xE0)
+#define SMI130_FIFO_M_G_ENABLE (0xA0)
+#define SMI130_FIFO_M_A_ENABLE (0x60)
+#define SMI130_FIFO_G_A_ENABLE (0xC0)
+#define SMI130_FIFO_A_ENABLE (0x40)
+#define SMI130_FIFO_M_ENABLE (0x20)
+/**************************************************/
+/**\name MAG INIT DEFINITION */
+/*************************************************/
+#define SMI130_COMMAND_REG_ONE (0x37)
+#define SMI130_COMMAND_REG_TWO (0x9A)
+#define SMI130_COMMAND_REG_THREE (0xC0)
+#define RESET_STEP_COUNTER (0xB2)
+/**************************************************/
+/**\name BIT SLICE GET AND SET FUNCTIONS */
+/*************************************************/
+#define SMI130_GET_BITSLICE(regvar, bitname)\
+ ((regvar & bitname##__MSK) >> bitname##__POS)
+
+
+#define SMI130_SET_BITSLICE(regvar, bitname, val)\
+ ((regvar & ~bitname##__MSK) | \
+ ((val<<bitname##__POS)&bitname##__MSK))
+
+/**************************************************/
+/**\name FUNCTION DECLARATIONS */
+/*************************************************/
+/**************************************************/
+/**\name FUNCTION FOR SMI130 INITIALIZE */
+/*************************************************/
+/*!
+ * @brief
+ * This function is used for initialize
+ * bus read and bus write functions
+ * assign the chip id and device address
+ * chip id is read in the register 0x00 bit from 0 to 7
+ *
+ * @param smi130 : structure pointer
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ * @note
+ * While changing the parameter of the smi130_t
+ * consider the following point:
+ * Changing the reference value of the parameter
+ * will changes the local copy or local reference
+ * make sure your changes will not
+ * affect the reference value of the parameter
+ * (Better case don't change the reference value of the parameter)
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_init(struct smi130_t *smi130);
+/**************************************************/
+/**\name FUNCTION FOR READ AND WRITE REGISTERS */
+/*************************************************/
+/*!
+ * @brief
+ * This API write the data to
+ * the given register
+ *
+ *
+ * @param v_addr_u8 -> Address of the register
+ * @param v_data_u8 -> The data from the register
+ * @param v_len_u8 -> no of bytes to read
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_write_reg(u8 v_addr_u8,
+u8 *v_data_u8, u8 v_len_u8);
+/*!
+ * @brief
+ * This API reads the data from
+ * the given register
+ *
+ *
+ * @param v_addr_u8 -> Address of the register
+ * @param v_data_u8 -> The data from the register
+ * @param v_len_u8 -> no of bytes to read
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_read_reg(u8 v_addr_u8,
+u8 *v_data_u8, u8 v_len_u8);
+/**************************************************/
+/**\name FUNCTION FOR ERROR CODES */
+/*************************************************/
+/*!
+ * @brief This API used to reads the fatal error
+ * from the Register 0x02 bit 0
+ * This flag will be reset only by power-on-reset and soft reset
+ *
+ *
+ * @param v_fatal_err_u8 : The status of fatal error
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fatal_err(u8
+*v_fatal_err_u8);
+/*!
+ * @brief This API used to read the error code
+ * from register 0x02 bit 1 to 4
+ *
+ *
+ * @param v_err_code_u8 : The status of error codes
+ * error_code | description
+ * ------------|---------------
+ * 0x00 |no error
+ * 0x01 |ACC_CONF error (accel ODR and bandwidth not compatible)
+ * 0x02 |GYR_CONF error (Gyroscope ODR and bandwidth not compatible)
+ * 0x03 |Under sampling mode and interrupt uses pre filtered data
+ * 0x04 |reserved
+ * 0x05 |Selected trigger-readout offset in
+ * - |MAG_IF greater than selected ODR
+ * 0x06 |FIFO configuration error for header less mode
+ * 0x07 |Under sampling mode and pre filtered data as FIFO source
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_err_code(u8
+*v_error_code_u8);
+/*!
+ * @brief This API Reads the i2c error code from the
+ * Register 0x02 bit 5.
+ * This error occurred in I2C master detected
+ *
+ * @param v_i2c_err_code_u8 : The status of i2c fail error
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_i2c_fail_err(u8
+*v_i2c_error_code_u8);
+ /*!
+ * @brief This API Reads the dropped command error
+ * from the register 0x02 bit 6
+ *
+ *
+ * @param v_drop_cmd_err_u8 : The status of drop command error
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_drop_cmd_err(u8
+*v_drop_cmd_err_u8);
+/*!
+ * @brief This API reads the magnetometer data ready
+ * interrupt not active.
+ * It reads from the error register 0x0x2 bit 7
+ *
+ *
+ *
+ *
+ * @param v_mag_data_rdy_err_u8 : The status of mag data ready interrupt
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_dada_rdy_err(u8
+*v_mag_data_rdy_err_u8);
+/*!
+ * @brief This API reads the error status
+ * from the error register 0x02 bit 0 to 7
+ *
+ * @param v_mag_data_rdy_err_u8 : The status of mag data ready interrupt
+ * @param v_fatal_er_u8r : The status of fatal error
+ * @param v_err_code_u8 : The status of error code
+ * @param v_i2c_fail_err_u8 : The status of I2C fail error
+ * @param v_drop_cmd_err_u8 : The status of drop command error
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_error_status(u8 *v_fatal_er_u8r,
+u8 *v_err_code_u8, u8 *v_i2c_fail_err_u8,
+u8 *v_drop_cmd_err_u8, u8 *v_mag_data_rdy_err_u8);
+/******************************************************************/
+/**\name FUNCTIONS FOR MAG,ACCEL AND GYRO POWER MODE STATUS */
+/*****************************************************************/
+/*!
+ * @brief This API reads the magnetometer power mode from
+ * PMU status register 0x03 bit 0 and 1
+ *
+ * @param v_mag_power_mode_stat_u8 : The value of mag power mode
+ * mag_powermode | value
+ * ------------------|----------
+ * SUSPEND | 0x00
+ * NORMAL | 0x01
+ * LOW POWER | 0x02
+ *
+ *
+ * @note The power mode of mag set by the 0x7E command register
+ * @note using the function "smi130_set_command_register()"
+ * value | mode
+ * ---------|----------------
+ * 0x18 | MAG_MODE_SUSPEND
+ * 0x19 | MAG_MODE_NORMAL
+ * 0x1A | MAG_MODE_LOWPOWER
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_power_mode_stat(u8
+*v_mag_power_mode_stat_u8);
+/*!
+ * @brief This API reads the gyroscope power mode from
+ * PMU status register 0x03 bit 2 and 3
+ *
+ * @param v_gyro_power_mode_stat_u8 : The value of gyro power mode
+ * gyro_powermode | value
+ * ------------------|----------
+ * SUSPEND | 0x00
+ * NORMAL | 0x01
+ * FAST POWER UP | 0x03
+ *
+ * @note The power mode of gyro set by the 0x7E command register
+ * @note using the function "smi130_set_command_register()"
+ * value | mode
+ * ---------|----------------
+ * 0x14 | GYRO_MODE_SUSPEND
+ * 0x15 | GYRO_MODE_NORMAL
+ * 0x17 | GYRO_MODE_FASTSTARTUP
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_power_mode_stat(u8
+*v_gyro_power_mode_stat_u8);
+/*!
+ * @brief This API reads the accelerometer power mode from
+ * PMU status register 0x03 bit 4 and 5
+ *
+ *
+ * @param v_accel_power_mode_stat_u8 : The value of accel power mode
+ * accel_powermode | value
+ * ------------------|----------
+ * SUSPEND | 0x00
+ * NORMAL | 0x01
+ * LOW POWER | 0x03
+ *
+ * @note The power mode of accel set by the 0x7E command register
+ * @note using the function "smi130_set_command_register()"
+ * value | mode
+ * ---------|----------------
+ * 0x11 | ACCEL_MODE_NORMAL
+ * 0x12 | ACCEL_LOWPOWER
+ * 0x10 | ACCEL_SUSPEND
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_power_mode_stat(u8
+*v_accel_power_mode_stat_u8);
+/*!
+ * @brief This API switch mag interface to normal mode
+ * and confirm whether the mode switching done successfully or not
+*
+ * @return results of bus communication function and current MAG_PMU result
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_interface_normal(void);
+/**************************************************/
+/**\name FUNCTION FOR Mag XYZ data read */
+/*************************************************/
+/*!
+ * @brief This API reads magnetometer data X values
+ * from the register 0x04 and 0x05
+ * @brief The mag sensor data read form auxiliary mag
+ *
+ * @param v_mag_x_s16 : The value of mag x
+ * @param v_sensor_select_u8 : Mag selection value
+ * value | sensor
+ * ---------|----------------
+ * 0 | BMM150
+ * 1 | AKM09911 or AKM09912
+ *
+ * @note For mag data output rate configuration use the following function
+ * @note smi130_set_mag_output_data_rate()
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_mag_x(s16 *v_mag_x_s16,
+u8 v_sensor_select_u8);
+/*!
+ * @brief This API reads magnetometer data Y values
+ * from the register 0x06 and 0x07
+ * @brief The mag sensor data read form auxiliary mag
+ *
+ * @param v_mag_y_s16 : The value of mag y
+ * @param v_sensor_select_u8 : Mag selection value
+ * value | sensor
+ * ---------|----------------
+ * 0 | BMM150
+ * 1 | AKM09911 or AKM09912
+ *
+ * @note For mag data output rate configuration use the following function
+ * @note smi130_set_mag_output_data_rate()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_mag_y(s16 *v_mag_y_s16,
+u8 v_sensor_select_u8);
+/*!
+ * @brief This API reads magnetometer data Z values
+ * from the register 0x08 and 0x09
+ * @brief The mag sensor data read form auxiliary mag
+ *
+ * @param v_mag_z_s16 : The value of mag z
+ * @param v_sensor_select_u8 : Mag selection value
+ * value | sensor
+ * ---------|----------------
+ * 0 | BMM150
+ * 1 | AKM09911 or AKM09912
+ *
+ * @note For mag data output rate configuration use the following function
+ * @note smi130_set_mag_output_data_rate()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_mag_z(s16 *v_mag_z_s16,
+u8 v_sensor_select_u8);
+/*!
+ * @brief This API reads magnetometer data RHALL values
+ * from the register 0x0A and 0x0B
+ *
+ *
+ * @param v_mag_r_s16 : The value of BMM150 r data
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_mag_r(
+s16 *v_mag_r_s16);
+/*!
+ * @brief This API reads magnetometer data X,Y,Z values
+ * from the register 0x04 to 0x09
+ *
+ * @brief The mag sensor data read form auxiliary mag
+ *
+ * @param mag : The value of mag xyz data
+ * @param v_sensor_select_u8 : Mag selection value
+ * value | sensor
+ * ---------|----------------
+ * 0 | BMM150
+ * 1 | AKM09911 or AKM09912
+ *
+ * @note For mag data output rate configuration use the following function
+ * @note smi130_set_mag_output_data_rate()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_mag_xyz(
+struct smi130_mag_t *mag, u8 v_sensor_select_u8);
+ /*!*
+ * @brief This API reads magnetometer data X,Y,Z,r
+ * values from the register 0x04 to 0x0B
+ *
+ * @brief The mag sensor data read form auxiliary mag
+ *
+ * @param mag : The value of mag-BMM150 xyzr data
+ *
+ * @note For mag data output rate configuration use the following function
+ * @note smi130_set_mag_output_data_rate()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_mag_xyzr(
+struct smi130_mag_xyzr_t *mag);
+/**************************************************/
+/**\name FUNCTION FOR GYRO XYZ DATA READ */
+/*************************************************/
+/*!
+ * @brief This API reads gyro data X values
+ * form the register 0x0C and 0x0D
+ *
+ *
+ *
+ *
+ * @param v_gyro_x_s16 : The value of gyro x data
+ *
+ * @note Gyro Configuration use the following function
+ * @note smi130_set_gyro_output_data_rate()
+ * @note smi130_set_gyro_bw()
+ * @note smi130_set_gyro_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_gyro_x(
+s16 *v_gyro_x_s16);
+/*!
+ * @brief This API reads gyro data Y values
+ * form the register 0x0E and 0x0F
+ *
+ *
+ *
+ *
+ * @param v_gyro_y_s16 : The value of gyro y data
+ *
+ * @note Gyro Configuration use the following function
+ * @note smi130_set_gyro_output_data_rate()
+ * @note smi130_set_gyro_bw()
+ * @note smi130_set_gyro_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error result of communication routines
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_gyro_y(
+s16 *v_gyro_y_s16);
+/*!
+ * @brief This API reads gyro data Z values
+ * form the register 0x10 and 0x11
+ *
+ *
+ *
+ *
+ * @param v_gyro_z_s16 : The value of gyro z data
+ *
+ * @note Gyro Configuration use the following function
+ * @note smi130_set_gyro_output_data_rate()
+ * @note smi130_set_gyro_bw()
+ * @note smi130_set_gyro_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_gyro_z(
+s16 *v_gyro_z_s16);
+/*!
+ * @brief This API reads gyro data X,Y,Z values
+ * from the register 0x0C to 0x11
+ *
+ *
+ *
+ *
+ * @param gyro : The value of gyro xyz
+ *
+ * @note Gyro Configuration use the following function
+ * @note smi130_set_gyro_output_data_rate()
+ * @note smi130_set_gyro_bw()
+ * @note smi130_set_gyro_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_gyro_xyz(
+struct smi130_gyro_t *gyro);
+/**************************************************/
+/**\name FUNCTION FOR ACCEL XYZ DATA READ */
+/*************************************************/
+/*!
+ * @brief This API reads accelerometer data X values
+ * form the register 0x12 and 0x13
+ *
+ *
+ *
+ *
+ * @param v_accel_x_s16 : The value of accel x
+ *
+ * @note For accel configuration use the following functions
+ * @note smi130_set_accel_output_data_rate()
+ * @note smi130_set_accel_bw()
+ * @note smi130_set_accel_under_sampling_parameter()
+ * @note smi130_set_accel_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_accel_x(
+s16 *v_accel_x_s16);
+/*!
+ * @brief This API reads accelerometer data Y values
+ * form the register 0x14 and 0x15
+ *
+ *
+ *
+ *
+ * @param v_accel_y_s16 : The value of accel y
+ *
+ * @note For accel configuration use the following functions
+ * @note smi130_set_accel_output_data_rate()
+ * @note smi130_set_accel_bw()
+ * @note smi130_set_accel_under_sampling_parameter()
+ * @note smi130_set_accel_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_accel_y(
+s16 *v_accel_y_s16);
+/*!
+ * @brief This API reads accelerometer data Z values
+ * form the register 0x16 and 0x17
+ *
+ *
+ *
+ *
+ * @param v_accel_z_s16 : The value of accel z
+ *
+ * @note For accel configuration use the following functions
+ * @note smi130_set_accel_output_data_rate()
+ * @note smi130_set_accel_bw()
+ * @note smi130_set_accel_under_sampling_parameter()
+ * @note smi130_set_accel_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_accel_z(
+s16 *v_accel_z_s16);
+/*!
+ * @brief This API reads accelerometer data X,Y,Z values
+ * from the register 0x12 to 0x17
+ *
+ *
+ *
+ *
+ * @param accel :The value of accel xyz
+ *
+ * @note For accel configuration use the following functions
+ * @note smi130_set_accel_output_data_rate()
+ * @note smi130_set_accel_bw()
+ * @note smi130_set_accel_under_sampling_parameter()
+ * @note smi130_set_accel_range()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_accel_xyz(
+struct smi130_accel_t *accel);
+/**************************************************/
+/**\name FUNCTION FOR SENSOR TIME */
+/*************************************************/
+/*!
+ * @brief This API reads sensor_time from the register
+ * 0x18 to 0x1A
+ *
+ *
+ * @param v_sensor_time_u32 : The value of sensor time
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_sensor_time(
+u32 *v_sensor_time_u32);
+/**************************************************/
+/**\name FUNCTION FOR GYRO SLEF TEST */
+/*************************************************/
+/*!
+ * @brief This API reads the Gyroscope self test
+ * status from the register 0x1B bit 1
+ *
+ *
+ * @param v_gyro_selftest_u8 : The value of gyro self test status
+ * value | status
+ * ---------|----------------
+ * 0 | Gyroscope self test is running or failed
+ * 1 | Gyroscope self test completed successfully
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_selftest(u8
+*v_gyro_selftest_u8);
+/**************************************************/
+/**\name FUNCTION FOR MANUAL INTERFACE */
+/*************************************************/
+/*!
+ * @brief This API reads the status of
+ * mag manual interface operation form the register 0x1B bit 2
+ *
+ *
+ *
+ * @param v_mag_manual_stat_u8 : The value of mag manual operation status
+ * value | status
+ * ---------|----------------
+ * 0 | Indicates no manual magnetometer
+ * - | interface operation is ongoing
+ * 1 | Indicates manual magnetometer
+ * - | interface operation is ongoing
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_manual_operation_stat(u8
+*v_mag_manual_stat_u8);
+/**************************************************/
+/**\name FUNCTION FOR FAST OFFSET READY */
+/*************************************************/
+/*!
+ * @brief This API reads the fast offset compensation
+ * status form the register 0x1B bit 3
+ *
+ *
+ * @param v_foc_rdy_u8 : The status of fast compensation
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_foc_rdy(u8
+*v_foc_rdy_u8);
+/**************************************************/
+/**\name FUNCTION FOR NVM READY */
+/*************************************************/
+/*!
+ * @brief This API Reads the nvm_rdy status from the
+ * resister 0x1B bit 4
+ *
+ *
+ * @param v_nvm_rdy_u8 : The value of NVM ready status
+ * value | status
+ * ---------|----------------
+ * 0 | NVM write operation in progress
+ * 1 | NVM is ready to accept a new write trigger
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_nvm_rdy(u8
+*v_nvm_rdy_u8);
+/**************************************************/
+/**\name FUNCTION FOR DATA READY FOR MAG, GYRO, AND ACCEL */
+/*************************************************/
+/*!
+ * @brief This API reads the status of mag data ready
+ * from the register 0x1B bit 5
+ * The status get reset when one mag data register is read out
+ *
+ * @param v_data_rdy_u8 : The value of mag data ready status
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_data_rdy_mag(u8
+*v_data_rdy_u8);
+/*!
+ * @brief This API reads the status of gyro data ready form the
+ * register 0x1B bit 6
+ * The status get reset when gyro data register read out
+ *
+ *
+ * @param v_data_rdy_u8 : The value of gyro data ready
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_data_rdy(u8
+*v_data_rdy_u8);
+/*!
+ * @brief This API reads the status of accel data ready form the
+ * register 0x1B bit 7
+ * The status get reset when accel data register read out
+ *
+ *
+ * @param v_data_rdy_u8 : The value of accel data ready status
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_data_rdy(u8
+*drdy_acc);
+/**************************************************/
+/**\name FUNCTION FOR STEP INTERRUPT STATUS */
+/*************************************************/
+/*!
+ * @brief This API reads the step detector interrupt status
+ * from the register 0x1C bit 0
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_step_intr_u8 : The status of step detector interrupt
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_step_intr(u8
+*v_step_intr_u8);
+/**************************************************/
+/**\name FUNCTION FOR SIGNIFICANT INTERRUPT STATUS */
+/*************************************************/
+/*!
+ * @brief This API reads the
+ * significant motion interrupt status
+ * from the register 0x1C bit 1
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ *
+ * @param v_significant_intr_u8 : The status of step
+ * motion interrupt
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_significant_intr(u8
+*sigmot_intr);
+/**************************************************/
+/**\name FUNCTION FOR ANY MOTION INTERRUPT STATUS */
+/*************************************************/
+ /*!
+ * @brief This API reads the any motion interrupt status
+ * from the register 0x1C bit 2
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ * @param v_any_motion_intr_u8 : The status of any-motion interrupt
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_any_motion_intr(u8
+*v_any_motion_intr_u8);
+/**************************************************/
+/**\name FUNCTION FOR PMU TRIGGER INTERRUPT STATUS */
+/*************************************************/
+/*!
+ * @brief This API reads the power mode trigger interrupt status
+ * from the register 0x1C bit 3
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ *
+ * @param v_pmu_trigger_intr_u8 : The status of power mode trigger interrupt
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_pmu_trigger_intr(u8
+*v_pmu_trigger_intr_u8);
+/**************************************************/
+/**\name FUNCTION FOR DOUBLE TAB STATUS */
+/*************************************************/
+/*!
+ * @brief This API reads the double tab status
+ * from the register 0x1C bit 4
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_double_tap_intr_u8 :The status of double tab interrupt
+ *
+ * @note Double tap interrupt can be configured by the following functions
+ * @note INTERRUPT MAPPING
+ * @note smi130_set_intr_double_tap()
+ * @note AXIS MAPPING
+ * @note smi130_get_stat2_tap_first_x()
+ * @note smi130_get_stat2_tap_first_y()
+ * @note smi130_get_stat2_tap_first_z()
+ * @note DURATION
+ * @note smi130_set_intr_tap_durn()
+ * @note THRESHOLD
+ * @note smi130_set_intr_tap_thres()
+ * @note TAP QUIET
+ * @note smi130_set_intr_tap_quiet()
+ * @note TAP SHOCK
+ * @note smi130_set_intr_tap_shock()
+ * @note TAP SOURCE
+ * @note smi130_set_intr_tap_source()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_double_tap_intr(u8
+*v_double_tap_intr_u8);
+/**************************************************/
+/**\name FUNCTION FOR SINGLE TAB STATUS */
+/*************************************************/
+/*!
+ * @brief This API reads the single tab status
+ * from the register 0x1C bit 5
+ * flag is associated with a specific interrupt function.
+ * It is set when the single tab interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt
+ * signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_single_tap_intr_u8 :The status of single tap interrupt
+ *
+ * @note Single tap interrupt can be configured by the following functions
+ * @note INTERRUPT MAPPING
+ * @note smi130_set_intr_single_tap()
+ * @note AXIS MAPPING
+ * @note smi130_get_stat2_tap_first_x()
+ * @note smi130_get_stat2_tap_first_y()
+ * @note smi130_get_stat2_tap_first_z()
+ * @note DURATION
+ * @note smi130_set_intr_tap_durn()
+ * @note THRESHOLD
+ * @note smi130_set_intr_tap_thres()
+ * @note TAP QUIET
+ * @note smi130_set_intr_tap_quiet()
+ * @note TAP SHOCK
+ * @note smi130_set_intr_tap_shock()
+ * @note TAP SOURCE
+ * @note smi130_set_intr_tap_source()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_single_tap_intr(u8
+*v_single_tap_intr_u8);
+/**************************************************/
+/**\name FUNCTION FOR ORIENT INTERRUPT STATUS */
+/*************************************************/
+/*!
+ * @brief This API reads the orient 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 smi130_get_stat0_orient_intr()
+ * @note AXIS MAPPING
+ * @note smi130_get_stat3_orient_xy()
+ * @note smi130_get_stat3_orient_z()
+ * @note smi130_set_intr_orient_axes_enable()
+ * @note INTERRUPT MAPPING
+ * @note smi130_set_intr_orient()
+ * @note INTERRUPT OUTPUT
+ * @note smi130_set_intr_orient_ud_enable()
+ * @note THETA
+ * @note smi130_set_intr_orient_theta()
+ * @note HYSTERESIS
+ * @note smi130_set_intr_orient_hyst()
+ * @note BLOCKING
+ * @note smi130_set_intr_orient_blocking()
+ * @note MODE
+ * @note smi130_set_intr_orient_mode()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_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 smi130_get_stat0_flat_intr()
+ * @note smi130_get_stat3_flat()
+ * @note INTERRUPT MAPPING
+ * @note smi130_set_intr_flat()
+ * @note THETA
+ * @note smi130_set_intr_flat_theta()
+ * @note HOLD TIME
+ * @note smi130_set_intr_flat_hold()
+ * @note HYSTERESIS
+ * @note smi130_set_intr_flat_hyst()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat0_flat_intr(u8
+*v_flat_intr_u8);
+/**************************************************/
+/**\name FUNCTION FOR HIGH_G INTERRUPT STATUS */
+/*************************************************/
+/*!
+ * @brief This API reads the high_g interrupt status
+ * from the register 0x1D bit 2
+ * flag is associated with a specific interrupt function.
+ * It is set when the high g interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt signal and hence the
+ * respective interrupt flag will be permanently
+ * latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_high_g_intr_u8 : The status of high_g interrupt
+ *
+ * @note High_g interrupt configured by following functions
+ * @note STATUS
+ * @note smi130_get_stat1_high_g_intr()
+ * @note AXIS MAPPING
+ * @note smi130_get_stat3_high_g_first_x()
+ * @note smi130_get_stat3_high_g_first_y()
+ * @note smi130_get_stat3_high_g_first_z()
+ * @note SIGN MAPPING
+ * @note smi130_get_stat3_high_g_first_sign()
+ * @note INTERRUPT MAPPING
+ * @note smi130_set_intr_high_g()
+ * @note HYSTERESIS
+ * @note smi130_set_intr_high_g_hyst()
+ * @note DURATION
+ * @note smi130_set_intr_high_g_durn()
+ * @note THRESHOLD
+ * @note smi130_set_intr_high_g_thres()
+ * @note SOURCE
+ * @note smi130_set_intr_low_high_source()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat1_high_g_intr(u8
+*v_high_g_intr_u8);
+/**************************************************/
+/**\name FUNCTION FOR LOW_G INTERRUPT STATUS */
+/*************************************************/
+/*!
+ * @brief This API reads the low g interrupt status
+ * from the register 0x1D bit 3
+ * flag is associated with a specific interrupt function.
+ * It is set when the low g interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_low_g_intr_u8 : The status of low_g interrupt
+ *
+ * @note Low_g interrupt configured by following functions
+ * @note STATUS
+ * @note smi130_get_stat1_low_g_intr()
+ * @note INTERRUPT MAPPING
+ * @note smi130_set_intr_low_g()
+ * @note SOURCE
+ * @note smi130_set_intr_low_high_source()
+ * @note DURATION
+ * @note smi130_set_intr_low_g_durn()
+ * @note THRESHOLD
+ * @note smi130_set_intr_low_g_thres()
+ * @note HYSTERESIS
+ * @note smi130_set_intr_low_g_hyst()
+ * @note MODE
+ * @note smi130_set_intr_low_g_mode()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat1_low_g_intr(u8
+*v_low_g_intr_u8);
+/**************************************************/
+/**\name FUNCTION FOR DATA READY INTERRUPT STATUS */
+/*************************************************/
+/*!
+ * @brief This API reads data ready interrupt status
+ * from the register 0x1D bit 4
+ * flag is associated with a specific interrupt function.
+ * It is set when the data ready interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_data_rdy_intr_u8 : The status of data ready interrupt
+ *
+ * @note Data ready interrupt configured by following functions
+ * @note STATUS
+ * @note smi130_get_stat1_data_rdy_intr()
+ * @note INTERRUPT MAPPING
+ * @note smi130_set_intr_data_rdy()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat1_data_rdy_intr(u8
+*v_data_rdy_intr_u8);
+/**************************************************/
+/**\name FUNCTIONS FOR FIFO FULL AND WATER MARK INTERRUPT STATUS*/
+/*************************************************/
+/*!
+ * @brief This API reads data ready FIFO full interrupt status
+ * from the register 0x1D bit 5
+ * flag is associated with a specific interrupt function.
+ * It is set when the FIFO full interrupt triggers. The
+ * setting of INT_LATCH controls if the
+ * interrupt signal and hence the
+ * respective interrupt flag will
+ * be permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_fifo_full_intr_u8 : The status of fifo full interrupt
+ *
+ * @note FIFO full interrupt can be configured by following functions
+ * @note smi130_set_intr_fifo_full()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat1_fifo_full_intr(u8
+*v_fifo_full_intr_u8);
+/*!
+ * @brief This API reads data
+ * ready FIFO watermark interrupt status
+ * from the register 0x1D bit 6
+ * flag is associated with a specific interrupt function.
+ * It is set when the FIFO watermark interrupt triggers. The
+ * setting of INT_LATCH controls if the
+ * interrupt signal and hence the
+ * respective interrupt flag will be
+ * permanently latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_fifo_wm_intr_u8 : The status of fifo water mark interrupt
+ *
+ * @note FIFO full interrupt can be configured by following functions
+ * @note smi130_set_intr_fifo_wm()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat1_fifo_wm_intr(u8
+*v_fifo_wm_intr_u8);
+/**************************************************/
+/**\name FUNCTIONS FOR NO MOTION INTERRUPT STATUS*/
+/*************************************************/
+/*!
+ * @brief This API reads data ready no motion interrupt status
+ * from the register 0x1D bit 7
+ * flag is associated with a specific interrupt function.
+ * It is set when the no motion interrupt triggers. The
+ * setting of INT_LATCH controls if the interrupt signal and hence the
+ * respective interrupt flag will be permanently
+ * latched, temporarily latched
+ * or not latched.
+ *
+ *
+ *
+ *
+ * @param v_nomotion_intr_u8 : The status of no motion interrupt
+ *
+ * @note No motion interrupt can be configured by following function
+ * @note STATUS
+ * @note smi130_get_stat1_nomotion_intr()
+ * @note INTERRUPT MAPPING
+ * @note smi130_set_intr_nomotion()
+ * @note DURATION
+ * @note smi130_set_intr_slow_no_motion_durn()
+ * @note THRESHOLD
+ * @note smi130_set_intr_slow_no_motion_thres()
+ * @note SLOW/NO MOTION SELECT
+ * @note smi130_set_intr_slow_no_motion_select()
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat1_nomotion_intr(u8
+*nomo_intr);
+/**************************************************/
+/**\name FUNCTIONS FOR ANY MOTION FIRST XYZ AND SIGN INTERRUPT STATUS*/
+/*************************************************/
+/*!
+ * @brief This API reads the status of any motion first x
+ * from the register 0x1E bit 0
+ *
+ *
+ * @param v_anymotion_first_x_u8 : The status of any motion first x interrupt
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by x axis
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_any_motion_first_x(u8
+*v_anymotion_first_x_u8);
+/*!
+ * @brief This API reads the status of any motion first y interrupt
+ * from the register 0x1E bit 1
+ *
+ *
+ *
+ *@param v_any_motion_first_y_u8 : The status of any motion first y interrupt
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_any_motion_first_y(u8
+*v_any_motion_first_y_u8);
+/*!
+ * @brief This API reads the status of any motion first z interrupt
+ * from the register 0x1E bit 2
+ *
+ *
+ *
+ *
+ *@param v_any_motion_first_z_u8 : The status of any motion first z interrupt
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_any_motion_first_z(u8
+*v_any_motion_first_z_u8);
+/*!
+ * @brief This API reads the any motion sign status from the
+ * register 0x1E bit 3
+ *
+ *
+ *
+ *
+ * @param v_anymotion_sign_u8 : The status of any motion sign
+ * value | sign
+ * -----------|-------------
+ * 0 | positive
+ * 1 | negative
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_any_motion_sign(u8
+*v_anymotion_sign_u8);
+/**************************************************/
+/**\name FUNCTIONS FOR TAP FIRST XYZ AND SIGN INTERRUPT STATUS*/
+/*************************************************/
+/*!
+ * @brief This API reads the any motion tap first x status from the
+ * register 0x1E bit 4
+ *
+ *
+ *
+ *
+ * @param v_tap_first_x_u8 :The status of any motion tap first x
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by x axis
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_tap_first_x(u8
+*v_tap_first_x_u8);
+/*!
+ * @brief This API reads the tap first y interrupt status from the
+ * register 0x1E bit 5
+ *
+ *
+ *
+ *
+ * @param v_tap_first_y_u8 :The status of tap first y interrupt
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_tap_first_y(u8
+*v_tap_first_y_u8);
+/*!
+ * @brief This API reads the tap first z interrupt status from the
+ * register 0x1E bit 6
+ *
+ *
+ *
+ *
+ * @param v_tap_first_z_u8 :The status of tap first z interrupt
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_tap_first_z(u8
+*v_tap_first_z_u8);
+/*!
+ * @brief This API reads the tap sign status from the
+ * register 0x1E bit 7
+ *
+ *
+ *
+ *
+ * @param v_tap_sign_u8 : The status of tap sign
+ * value | sign
+ * -----------|-------------
+ * 0 | positive
+ * 1 | negative
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat2_tap_sign(u8
+*tap_sign);
+/**************************************************/
+/**\name FUNCTIONS FOR HIGH_G FIRST XYZ AND SIGN INTERRUPT STATUS*/
+/*************************************************/
+/*!
+ * @brief This API reads the high_g first x status from the
+ * register 0x1F bit 0
+ *
+ *
+ *
+ *
+ * @param v_high_g_first_x_u8 :The status of high_g first x
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by x axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat3_high_g_first_x(u8
+*v_high_g_first_x_u8);
+/*!
+ * @brief This API reads the high_g first y status from the
+ * register 0x1F bit 1
+ *
+ *
+ *
+ *
+ * @param v_high_g_first_y_u8 : The status of high_g first y
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat3_high_g_first_y(u8
+*v_high_g_first_y_u8);
+/*!
+ * @brief This API reads the high_g first z status from the
+ * register 0x1F bit 3
+ *
+ *
+ *
+ *
+ * @param v_high_g_first_z_u8 : The status of high_g first z
+ * value | status
+ * -----------|-------------
+ * 0 | not triggered
+ * 1 | triggered by z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat3_high_g_first_z(u8
+*v_high_g_first_z_u8);
+/*!
+ * @brief This API reads the high sign status from the
+ * register 0x1F bit 3
+ *
+ *
+ *
+ *
+ * @param v_high_g_sign_u8 :The status of high sign
+ * value | sign
+ * -----------|-------------
+ * 0 | positive
+ * 1 | negative
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat3_high_g_sign(u8
+*v_high_g_sign_u8);
+/**************************************************/
+/**\name FUNCTIONS FOR ORIENT XY AND Z INTERRUPT STATUS*/
+/*************************************************/
+/*!
+ * @brief This API reads the status of orient_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
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_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
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_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
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_stat3_flat(u8
+*flat);
+/**************************************************/
+/**\name FUNCTION FOR TEMPERATUE READ */
+/*************************************************/
+/*!
+ * @brief This API reads the temperature of the sensor
+ * from the register 0x21 bit 0 to 7
+ *
+ *
+ *
+ * @param v_temp_s16 : The value of temperature
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_temp(s16
+*v_temp_s16);
+/**************************************************/
+/**\name FUNCTION FOR FIFO LENGTH AND FIFO DATA READ */
+/*************************************************/
+/*!
+ * @brief This API reads the of the sensor
+ * form the register 0x23 and 0x24 bit 0 to 7 and 0 to 2
+ * @brief this byte counter is updated each time a complete frame
+ * was read or writtern
+ *
+ *
+ * @param v_fifo_length_u32 : The value of fifo byte counter
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_fifo_length(
+u32 *v_fifo_length_u32);
+/*!
+ * @brief This API reads the fifo data of the sensor
+ * from the register 0x24
+ * @brief Data format depends on the setting of register FIFO_CONFIG
+ *
+ *
+ *
+ * @param v_fifodata_u8 : Pointer holding the fifo data
+ *
+ * @note For reading FIFO data use the following functions
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_fifo_data(
+u8 *v_fifodata_u8, u16 v_fifo_length_u16);
+/**************************************************/
+/**\name FUNCTION FOR ACCEL CONFIGURATIONS */
+/*************************************************/
+/*!
+ * @brief This API is used to get the
+ * accel output date rate form the register 0x40 bit 0 to 3
+ *
+ *
+ * @param v_output_data_rate_u8 :The value of accel output date rate
+ * value | output data rate
+ * -------|--------------------------
+ * 0 | SMI130_ACCEL_OUTPUT_DATA_RATE_RESERVED
+ * 1 | SMI130_ACCEL_OUTPUT_DATA_RATE_0_78HZ
+ * 2 | SMI130_ACCEL_OUTPUT_DATA_RATE_1_56HZ
+ * 3 | SMI130_ACCEL_OUTPUT_DATA_RATE_3_12HZ
+ * 4 | SMI130_ACCEL_OUTPUT_DATA_RATE_6_25HZ
+ * 5 | SMI130_ACCEL_OUTPUT_DATA_RATE_12_5HZ
+ * 6 | SMI130_ACCEL_OUTPUT_DATA_RATE_25HZ
+ * 7 | SMI130_ACCEL_OUTPUT_DATA_RATE_50HZ
+ * 8 | SMI130_ACCEL_OUTPUT_DATA_RATE_100HZ
+ * 9 | SMI130_ACCEL_OUTPUT_DATA_RATE_200HZ
+ * 10 | SMI130_ACCEL_OUTPUT_DATA_RATE_400HZ
+ * 11 | SMI130_ACCEL_OUTPUT_DATA_RATE_800HZ
+ * 12 | SMI130_ACCEL_OUTPUT_DATA_RATE_1600HZ
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_output_data_rate(
+u8 *v_output_data_rate_u8);
+/*!
+ * @brief This API is used to set the
+ * accel output date rate form the register 0x40 bit 0 to 3
+ *
+ *
+ * @param v_output_data_rate_u8 :The value of accel output date rate
+ * value | output data rate
+ * -------|--------------------------
+ * 0 | SMI130_ACCEL_OUTPUT_DATA_RATE_RESERVED
+ * 1 | SMI130_ACCEL_OUTPUT_DATA_RATE_0_78HZ
+ * 2 | SMI130_ACCEL_OUTPUT_DATA_RATE_1_56HZ
+ * 3 | SMI130_ACCEL_OUTPUT_DATA_RATE_3_12HZ
+ * 4 | SMI130_ACCEL_OUTPUT_DATA_RATE_6_25HZ
+ * 5 | SMI130_ACCEL_OUTPUT_DATA_RATE_12_5HZ
+ * 6 | SMI130_ACCEL_OUTPUT_DATA_RATE_25HZ
+ * 7 | SMI130_ACCEL_OUTPUT_DATA_RATE_50HZ
+ * 8 | SMI130_ACCEL_OUTPUT_DATA_RATE_100HZ
+ * 9 | SMI130_ACCEL_OUTPUT_DATA_RATE_200HZ
+ * 10 | SMI130_ACCEL_OUTPUT_DATA_RATE_400HZ
+ * 11 | SMI130_ACCEL_OUTPUT_DATA_RATE_800HZ
+ * 12 | SMI130_ACCEL_OUTPUT_DATA_RATE_1600HZ
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_output_data_rate(u8 odr);
+/*!
+ * @brief This API is used to get the
+ * accel bandwidth from the register 0x40 bit 4 to 6
+ * @brief bandwidth parameter determines filter configuration(acc_us=0)
+ * and averaging for under sampling mode(acc_us=1)
+ *
+ *
+ * @param v_bw_u8 : The value of accel bandwidth
+ *
+ * @note accel bandwidth depends on under sampling parameter
+ * @note under sampling parameter cab be set by the function
+ * "SMI130_SET_ACCEL_UNDER_SAMPLING_PARAMETER"
+ *
+ * @note Filter configuration
+ * accel_us | Filter configuration
+ * -----------|---------------------
+ * 0x00 | OSR4 mode
+ * 0x01 | OSR2 mode
+ * 0x02 | normal mode
+ * 0x03 | CIC mode
+ * 0x04 | Reserved
+ * 0x05 | Reserved
+ * 0x06 | Reserved
+ * 0x07 | Reserved
+ *
+ * @note accel under sampling mode
+ * accel_us | Under sampling mode
+ * -----------|---------------------
+ * 0x00 | no averaging
+ * 0x01 | average 2 samples
+ * 0x02 | average 4 samples
+ * 0x03 | average 8 samples
+ * 0x04 | average 16 samples
+ * 0x05 | average 32 samples
+ * 0x06 | average 64 samples
+ * 0x07 | average 128 samples
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_bw(u8 *v_bw_u8);
+/*!
+ * @brief This API is used to set the
+ * accel bandwidth from the register 0x40 bit 4 to 6
+ * @brief bandwidth parameter determines filter configuration(acc_us=0)
+ * and averaging for under sampling mode(acc_us=1)
+ *
+ *
+ * @param v_bw_u8 : The value of accel bandwidth
+ *
+ * @note accel bandwidth depends on under sampling parameter
+ * @note under sampling parameter cab be set by the function
+ * "SMI130_SET_ACCEL_UNDER_SAMPLING_PARAMETER"
+ *
+ * @note Filter configuration
+ * accel_us | Filter configuration
+ * -----------|---------------------
+ * 0x00 | OSR4 mode
+ * 0x01 | OSR2 mode
+ * 0x02 | normal mode
+ * 0x03 | CIC mode
+ * 0x04 | Reserved
+ * 0x05 | Reserved
+ * 0x06 | Reserved
+ * 0x07 | Reserved
+ *
+ * @note accel under sampling mode
+ * accel_us | Under sampling mode
+ * -----------|---------------------
+ * 0x00 | no averaging
+ * 0x01 | average 2 samples
+ * 0x02 | average 4 samples
+ * 0x03 | average 8 samples
+ * 0x04 | average 16 samples
+ * 0x05 | average 32 samples
+ * 0x06 | average 64 samples
+ * 0x07 | average 128 samples
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_bw(u8 v_bw_u8);
+/*!
+ * @brief This API is used to get the accel
+ * under sampling parameter form the register 0x40 bit 7
+ *
+ *
+ *
+ *
+ * @param v_accel_under_sampling_u8 : The value of accel under sampling
+ * value | under_sampling
+ * ----------|---------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_under_sampling_parameter(
+u8 *v_accel_under_sampling_u8);
+/*!
+ * @brief This API is used to set the accel
+ * under sampling parameter form the register 0x40 bit 7
+ *
+ *
+ *
+ *
+ * @param v_accel_under_sampling_u8 : The value of accel under sampling
+ * value | under_sampling
+ * ----------|---------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_under_sampling_parameter(
+u8 v_accel_under_sampling_u8);
+/*!
+ * @brief This API is used to get the ranges
+ * (g values) of the accel from the register 0x41 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_range_u8 : The value of accel g range
+ * value | g_range
+ * ----------|-----------
+ * 0x03 | SMI130_ACCEL_RANGE_2G
+ * 0x05 | SMI130_ACCEL_RANGE_4G
+ * 0x08 | SMI130_ACCEL_RANGE_8G
+ * 0x0C | SMI130_ACCEL_RANGE_16G
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_range(
+u8 *v_range_u8);
+/*!
+ * @brief This API is used to set the ranges
+ * (g values) of the accel from the register 0x41 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_range_u8 : The value of accel g range
+ * value | g_range
+ * ----------|-----------
+ * 0x03 | SMI130_ACCEL_RANGE_2G
+ * 0x05 | SMI130_ACCEL_RANGE_4G
+ * 0x08 | SMI130_ACCEL_RANGE_8G
+ * 0x0C | SMI130_ACCEL_RANGE_16G
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_range(
+u8 v_range_u8);
+/**************************************************/
+/**\name FUNCTION FOR GYRO CONFIGURATIONS */
+/*************************************************/
+/*!
+ * @brief This API is used to get the
+ * gyroscope output data rate from the register 0x42 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_output_data_rate_u8 :The value of gyro output data rate
+ * value | gyro output data rate
+ * -----------|-----------------------------
+ * 0x00 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x01 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x02 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x03 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x04 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x05 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x06 | SMI130_GYRO_OUTPUT_DATA_RATE_25HZ
+ * 0x07 | SMI130_GYRO_OUTPUT_DATA_RATE_50HZ
+ * 0x08 | SMI130_GYRO_OUTPUT_DATA_RATE_100HZ
+ * 0x09 | SMI130_GYRO_OUTPUT_DATA_RATE_200HZ
+ * 0x0A | SMI130_GYRO_OUTPUT_DATA_RATE_400HZ
+ * 0x0B | SMI130_GYRO_OUTPUT_DATA_RATE_800HZ
+ * 0x0C | SMI130_GYRO_OUTPUT_DATA_RATE_1600HZ
+ * 0x0D | SMI130_GYRO_OUTPUT_DATA_RATE_3200HZ
+ * 0x0E | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x0F | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_output_data_rate(
+u8 *gyro_output_typer);
+/*!
+ * @brief This API is used to set the
+ * gyroscope output data rate from the register 0x42 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_output_data_rate_u8 :The value of gyro output data rate
+ * value | gyro output data rate
+ * -----------|-----------------------------
+ * 0x00 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x01 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x02 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x03 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x04 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x05 | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x06 | SMI130_GYRO_OUTPUT_DATA_RATE_25HZ
+ * 0x07 | SMI130_GYRO_OUTPUT_DATA_RATE_50HZ
+ * 0x08 | SMI130_GYRO_OUTPUT_DATA_RATE_100HZ
+ * 0x09 | SMI130_GYRO_OUTPUT_DATA_RATE_200HZ
+ * 0x0A | SMI130_GYRO_OUTPUT_DATA_RATE_400HZ
+ * 0x0B | SMI130_GYRO_OUTPUT_DATA_RATE_800HZ
+ * 0x0C | SMI130_GYRO_OUTPUT_DATA_RATE_1600HZ
+ * 0x0D | SMI130_GYRO_OUTPUT_DATA_RATE_3200HZ
+ * 0x0E | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ * 0x0F | SMI130_GYRO_OUTPUT_DATA_RATE_RESERVED
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_output_data_rate(
+u8 gyro_output_typer);
+/*!
+ * @brief This API is used to get the
+ * data of gyro from the register 0x42 bit 4 to 5
+ *
+ *
+ *
+ *
+ * @param v_bw_u8 : The value of gyro bandwidth
+ * value | gyro bandwidth
+ * ----------|----------------
+ * 0x00 | SMI130_GYRO_OSR4_MODE
+ * 0x01 | SMI130_GYRO_OSR2_MODE
+ * 0x02 | SMI130_GYRO_NORMAL_MODE
+ * 0x03 | SMI130_GYRO_CIC_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_bw(u8 *v_bw_u8);
+/*!
+ * @brief This API is used to set the
+ * data of gyro from the register 0x42 bit 4 to 5
+ *
+ *
+ *
+ *
+ * @param v_bw_u8 : The value of gyro bandwidth
+ * value | gyro bandwidth
+ * ----------|----------------
+ * 0x00 | SMI130_GYRO_OSR4_MODE
+ * 0x01 | SMI130_GYRO_OSR2_MODE
+ * 0x02 | SMI130_GYRO_NORMAL_MODE
+ * 0x03 | SMI130_GYRO_CIC_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_bw(u8 v_bw_u8);
+/*!
+ * @brief This API reads the range
+ * of gyro from the register 0x43 bit 0 to 2
+ *
+ * @param v_range_u8 : The value of gyro range
+ * value | range
+ * ----------|-------------------------------
+ * 0x00 | SMI130_GYRO_RANGE_2000_DEG_SEC
+ * 0x01 | SMI130_GYRO_RANGE_1000_DEG_SEC
+ * 0x02 | SMI130_GYRO_RANGE_500_DEG_SEC
+ * 0x03 | SMI130_GYRO_RANGE_250_DEG_SEC
+ * 0x04 | SMI130_GYRO_RANGE_125_DEG_SEC
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_range(
+u8 *v_range_u8);
+/*!
+ * @brief This API set the range
+ * of gyro from the register 0x43 bit 0 to 2
+ *
+ * @param v_range_u8 : The value of gyro range
+ * value | range
+ * ----------|-------------------------------
+ * 0x00 | SMI130_GYRO_RANGE_2000_DEG_SEC
+ * 0x01 | SMI130_GYRO_RANGE_1000_DEG_SEC
+ * 0x02 | SMI130_GYRO_RANGE_500_DEG_SEC
+ * 0x03 | SMI130_GYRO_RANGE_250_DEG_SEC
+ * 0x04 | SMI130_GYRO_RANGE_125_DEG_SEC
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_range(
+u8 v_range_u8);
+/**************************************************/
+/**\name FUNCTION FOR MAG CONFIGURATIONS */
+/*************************************************/
+/*!
+ * @brief This API is used to get the
+ * output data rate of magnetometer from the register 0x44 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_output_data_rat_u8e : The value of mag output data rate
+ * value | mag output data rate
+ * ---------|---------------------------
+ * 0x00 |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED
+ * 0x01 |SMI130_MAG_OUTPUT_DATA_RATE_0_78HZ
+ * 0x02 |SMI130_MAG_OUTPUT_DATA_RATE_1_56HZ
+ * 0x03 |SMI130_MAG_OUTPUT_DATA_RATE_3_12HZ
+ * 0x04 |SMI130_MAG_OUTPUT_DATA_RATE_6_25HZ
+ * 0x05 |SMI130_MAG_OUTPUT_DATA_RATE_12_5HZ
+ * 0x06 |SMI130_MAG_OUTPUT_DATA_RATE_25HZ
+ * 0x07 |SMI130_MAG_OUTPUT_DATA_RATE_50HZ
+ * 0x08 |SMI130_MAG_OUTPUT_DATA_RATE_100HZ
+ * 0x09 |SMI130_MAG_OUTPUT_DATA_RATE_200HZ
+ * 0x0A |SMI130_MAG_OUTPUT_DATA_RATE_400HZ
+ * 0x0B |SMI130_MAG_OUTPUT_DATA_RATE_800HZ
+ * 0x0C |SMI130_MAG_OUTPUT_DATA_RATE_1600HZ
+ * 0x0D |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED0
+ * 0x0E |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED1
+ * 0x0F |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED2
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_output_data_rate(u8 *odr);
+/*!
+ * @brief This API is used to set the
+ * output data rate of magnetometer from the register 0x44 bit 0 to 3
+ *
+ *
+ *
+ *
+ * @param v_output_data_rat_u8e : The value of mag output data rate
+ * value | mag output data rate
+ * ---------|---------------------------
+ * 0x00 |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED
+ * 0x01 |SMI130_MAG_OUTPUT_DATA_RATE_0_78HZ
+ * 0x02 |SMI130_MAG_OUTPUT_DATA_RATE_1_56HZ
+ * 0x03 |SMI130_MAG_OUTPUT_DATA_RATE_3_12HZ
+ * 0x04 |SMI130_MAG_OUTPUT_DATA_RATE_6_25HZ
+ * 0x05 |SMI130_MAG_OUTPUT_DATA_RATE_12_5HZ
+ * 0x06 |SMI130_MAG_OUTPUT_DATA_RATE_25HZ
+ * 0x07 |SMI130_MAG_OUTPUT_DATA_RATE_50HZ
+ * 0x08 |SMI130_MAG_OUTPUT_DATA_RATE_100HZ
+ * 0x09 |SMI130_MAG_OUTPUT_DATA_RATE_200HZ
+ * 0x0A |SMI130_MAG_OUTPUT_DATA_RATE_400HZ
+ * 0x0B |SMI130_MAG_OUTPUT_DATA_RATE_800HZ
+ * 0x0C |SMI130_MAG_OUTPUT_DATA_RATE_1600HZ
+ * 0x0D |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED0
+ * 0x0E |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED1
+ * 0x0F |SMI130_MAG_OUTPUT_DATA_RATE_RESERVED2
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_output_data_rate(u8 odr);
+/**************************************************/
+/**\name FUNCTION FOR FIFO CONFIGURATIONS */
+/*************************************************/
+ /*!
+ * @brief This API is used to read Down sampling
+ * for gyro (2**downs_gyro) in the register 0x45 bit 0 to 2
+ *
+ *
+ *
+ *
+ * @param v_fifo_down_gyro_u8 :The value of gyro fifo down
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_down_gyro(
+u8 *v_fifo_down_gyro_u8);
+ /*!
+ * @brief This API is used to set Down sampling
+ * for gyro (2**downs_gyro) in the register 0x45 bit 0 to 2
+ *
+ *
+ *
+ *
+ * @param v_fifo_down_gyro_u8 :The value of gyro fifo down
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_down_gyro(
+u8 v_fifo_down_gyro_u8);
+/*!
+ * @brief This API is used to read gyro fifo filter data
+ * from the register 0x45 bit 3
+ *
+ *
+ *
+ * @param v_gyro_fifo_filter_data_u8 :The value of gyro filter data
+ * value | gyro_fifo_filter_data
+ * ------------|-------------------------
+ * 0x00 | Unfiltered data
+ * 0x01 | Filtered data
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_fifo_filter_data(
+u8 *v_gyro_fifo_filter_data_u8);
+/*!
+ * @brief This API is used to set gyro fifo filter data
+ * from the register 0x45 bit 3
+ *
+ *
+ *
+ * @param v_gyro_fifo_filter_data_u8 :The value of gyro filter data
+ * value | gyro_fifo_filter_data
+ * ------------|-------------------------
+ * 0x00 | Unfiltered data
+ * 0x01 | Filtered data
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_fifo_filter_data(
+u8 v_gyro_fifo_filter_data_u8);
+/*!
+ * @brief This API is used to read Down sampling
+ * for accel (2*downs_accel) from the register 0x45 bit 4 to 6
+ *
+ *
+ *
+ *
+ * @param v_fifo_down_u8 :The value of accel fifo down
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_down_accel(
+u8 *v_fifo_down_u8);
+ /*!
+ * @brief This API is used to set Down sampling
+ * for accel (2*downs_accel) from the register 0x45 bit 4 to 6
+ *
+ *
+ *
+ *
+ * @param v_fifo_down_u8 :The value of accel fifo down
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_down_accel(
+u8 v_fifo_down_u8);
+/*!
+ * @brief This API is used to read accel fifo filter data
+ * from the register 0x45 bit 7
+ *
+ *
+ *
+ * @param v_accel_fifo_filter_u8 :The value of accel filter data
+ * value | accel_fifo_filter_data
+ * ------------|-------------------------
+ * 0x00 | Unfiltered data
+ * 0x01 | Filtered data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_fifo_filter_data(
+u8 *v_accel_fifo_filter_u8);
+/*!
+ * @brief This API is used to set accel fifo filter data
+ * from the register 0x45 bit 7
+ *
+ *
+ *
+ * @param v_accel_fifo_filter_u8 :The value of accel filter data
+ * value | accel_fifo_filter_data
+ * ------------|-------------------------
+ * 0x00 | Unfiltered data
+ * 0x01 | Filtered data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_fifo_filter_data(
+u8 v_accel_fifo_filter_u8);
+/**************************************************/
+/**\name FUNCTION FOR FIFO WATER MARK ENABLE */
+/*************************************************/
+/*!
+ * @brief This API is used to Trigger an interrupt
+ * when FIFO contains water mark level from the register 0x46 bit 0 to 7
+ *
+ *
+ *
+ * @param v_fifo_wm_u8 : The value of fifo water mark level
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_wm(
+u8 *v_fifo_wm_u8);
+/*!
+ * @brief This API is used to Trigger an interrupt
+ * when FIFO contains water mark level from the register 0x46 bit 0 to 7
+ *
+ *
+ *
+ * @param v_fifo_wm_u8 : The value of fifo water mark level
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_wm(
+u8 v_fifo_wm_u8);
+/**************************************************/
+/**\name FUNCTION FOR FIFO CONFIGURATIONS */
+/*************************************************/
+/*!
+ * @brief This API reads fifo sensor time
+ * frame after the last valid data frame form the register 0x47 bit 1
+ *
+ *
+ *
+ *
+ * @param v_fifo_time_enable_u8 : The value of sensor time
+ * value | fifo sensor time
+ * ------------|-------------------------
+ * 0x00 | do not return sensortime frame
+ * 0x01 | return sensortime frame
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_time_enable(
+u8 *v_fifo_time_enable_u8);
+/*!
+ * @brief This API set fifo sensor time
+ * frame after the last valid data frame form the register 0x47 bit 1
+ *
+ *
+ *
+ *
+ * @param v_fifo_time_enable_u8 : The value of sensor time
+ * value | fifo sensor time
+ * ------------|-------------------------
+ * 0x00 | do not return sensortime frame
+ * 0x01 | return sensortime frame
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_time_enable(
+u8 v_fifo_time_enable_u8);
+/*!
+ * @brief This API reads FIFO tag interrupt2 enable status
+ * from the resister 0x47 bit 2
+ *
+ * @param v_fifo_tag_intr2_u8 : The value of fifo tag interrupt
+ * value | fifo tag interrupt
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_tag_intr2_enable(
+u8 *v_fifo_tag_intr2_u8);
+/*!
+ * @brief This API set FIFO tag interrupt2 enable status
+ * from the resister 0x47 bit 2
+ *
+ * @param v_fifo_tag_intr2_u8 : The value of fifo tag interrupt
+ * value | fifo tag interrupt
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_tag_intr2_enable(
+u8 v_fifo_tag_intr2_u8);
+/*!
+ * @brief This API get FIFO tag interrupt1 enable status
+ * from the resister 0x47 bit 3
+ *
+ * @param v_fifo_tag_intr1_u8 :The value of fifo tag interrupt1
+ * value | fifo tag interrupt
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_tag_intr1_enable(
+u8 *v_fifo_tag_intr1_u8);
+/*!
+ * @brief This API set FIFO tag interrupt1 enable status
+ * from the resister 0x47 bit 3
+ *
+ * @param v_fifo_tag_intr1_u8 :The value of fifo tag interrupt1
+ * value | fifo tag interrupt
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_tag_intr1_enable(
+u8 v_fifo_tag_intr1_u8);
+/*!
+ * @brief This API reads FIFO frame
+ * header enable from the register 0x47 bit 4
+ *
+ * @param v_fifo_header_u8 :The value of fifo header
+ * value | fifo header
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_header_enable(
+u8 *v_fifo_header_u8);
+/*!
+ * @brief This API set FIFO frame
+ * header enable from the register 0x47 bit 4
+ *
+ * @param v_fifo_header_u8 :The value of fifo header
+ * value | fifo header
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_header_enable(
+u8 v_fifo_header_u8);
+/*!
+ * @brief This API is used to read stored
+ * magnetometer data in FIFO (all 3 axes) from the register 0x47 bit 5
+ *
+ * @param v_fifo_mag_u8 : The value of fifo mag enble
+ * value | fifo mag
+ * ----------|-------------------
+ * 0x00 | no magnetometer data is stored
+ * 0x01 | magnetometer data is stored
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_mag_enable(
+u8 *v_fifo_mag_u8);
+/*!
+ * @brief This API is used to set stored
+ * magnetometer data in FIFO (all 3 axes) from the register 0x47 bit 5
+ *
+ * @param v_fifo_mag_u8 : The value of fifo mag enble
+ * value | fifo mag
+ * ----------|-------------------
+ * 0x00 | no magnetometer data is stored
+ * 0x01 | magnetometer data is stored
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_mag_enable(
+u8 v_fifo_mag_u8);
+/*!
+ * @brief This API is used to read stored
+ * accel data in FIFO (all 3 axes) from the register 0x47 bit 6
+ *
+ * @param v_fifo_accel_u8 : The value of fifo accel enble
+ * value | fifo accel
+ * ----------|-------------------
+ * 0x00 | no accel data is stored
+ * 0x01 | accel data is stored
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_accel_enable(
+u8 *v_fifo_accel_u8);
+/*!
+ * @brief This API is used to set stored
+ * accel data in FIFO (all 3 axes) from the register 0x47 bit 6
+ *
+ * @param v_fifo_accel_u8 : The value of fifo accel enble
+ * value | fifo accel
+ * ----------|-------------------
+ * 0x00 | no accel data is stored
+ * 0x01 | accel data is stored
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_accel_enable(
+u8 v_fifo_accel_u8);
+/*!
+ * @brief This API is used to read stored
+ * gyro data in FIFO (all 3 axes) from the resister 0x47 bit 7
+ *
+ *
+ * @param v_fifo_gyro_u8 : The value of fifo gyro enble
+ * value | fifo gyro
+ * ----------|-------------------
+ * 0x00 | no gyro data is stored
+ * 0x01 | gyro data is stored
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_fifo_gyro_enable(
+u8 *v_fifo_gyro_u8);
+/*!
+ * @brief This API is used to set stored
+ * gyro data in FIFO (all 3 axes) from the resister 0x47 bit 7
+ *
+ *
+ * @param v_fifo_gyro_u8 : The value of fifo gyro enble
+ * value | fifo gyro
+ * ----------|-------------------
+ * 0x00 | no gyro data is stored
+ * 0x01 | gyro data is stored
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_fifo_gyro_enable(
+u8 v_fifo_gyro_u8);
+/***************************************************************/
+/**\name FUNCTION FOR MAG I2C ADDRESS SELECTION */
+/***************************************************************/
+/*!
+ * @brief This API is used to read
+ * I2C device address of auxiliary mag from the register 0x4B bit 1 to 7
+ *
+ *
+ *
+ *
+ * @param v_i2c_device_addr_u8 : The value of mag I2C device address
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_i2c_device_addr(
+u8 *v_i2c_device_addr_u8);
+/*!
+ * @brief This API is used to set
+ * I2C device address of auxiliary mag from the register 0x4B bit 1 to 7
+ *
+ *
+ *
+ *
+ * @param v_i2c_device_addr_u8 : The value of mag I2C device address
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_i2c_device_addr(
+u8 v_i2c_device_addr_u8);
+/*!
+ * @brief This API is used to read
+ * Burst data length (1,2,6,8 byte) from the register 0x4C bit 0 to 1
+ *
+ *
+ *
+ *
+ * @param v_mag_burst_u8 : The data of mag burst read lenth
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_burst(
+u8 *v_mag_burst_u8);
+/*!
+ * @brief This API is used to set
+ * Burst data length (1,2,6,8 byte) from the register 0x4C bit 0 to 1
+ *
+ *
+ *
+ *
+ * @param v_mag_burst_u8 : The data of mag burst read lenth
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_burst(
+u8 v_mag_burst_u8);
+/***************************************************************/
+/**\name FUNCTION FOR MAG OFFSET */
+/***************************************************************/
+/*!
+ * @brief This API is used to read
+ * trigger-readout offset in units of 2.5 ms. If set to zero,
+ * the offset is maximum, i.e. after readout a trigger
+ * is issued immediately. from the register 0x4C bit 2 to 5
+ *
+ *
+ *
+ *
+ * @param v_mag_offset_u8 : The value of mag offset
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_offset(
+u8 *v_mag_offset_u8);
+/*!
+ * @brief This API is used to set
+ * trigger-readout offset in units of 2.5 ms. If set to zero,
+ * the offset is maximum, i.e. after readout a trigger
+ * is issued immediately. from the register 0x4C bit 2 to 5
+ *
+ *
+ *
+ *
+ * @param v_mag_offset_u8 : The value of mag offset
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_offset(
+u8 v_mag_offset_u8);
+/***************************************************************/
+/**\name FUNCTION FOR MAG MANUAL/AUTO MODE SELECTION */
+/***************************************************************/
+/*!
+ * @brief This API is used to read
+ * Enable register access on MAG_IF[2] or MAG_IF[3] writes.
+ * This implies that the DATA registers are not updated with
+ * magnetometer values. Accessing magnetometer requires
+ * the magnetometer in normal mode in PMU_STATUS.
+ * from the register 0x4C bit 7
+ *
+ *
+ *
+ * @param v_mag_manual_u8 : The value of mag manual enable
+ * value | mag manual
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_manual_enable(
+u8 *v_mag_manual_u8);
+/*!
+ * @brief This API is used to set
+ * Enable register access on MAG_IF[2] or MAG_IF[3] writes.
+ * This implies that the DATA registers are not updated with
+ * magnetometer values. Accessing magnetometer requires
+ * the magnetometer in normal mode in PMU_STATUS.
+ * from the register 0x4C bit 7
+ *
+ *
+ *
+ * @param v_mag_manual_u8 : The value of mag manual enable
+ * value | mag manual
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_manual_enable(
+u8 v_mag_manual_u8);
+/***************************************************************/
+/**\name FUNCTIONS FOR MAG READ, WRITE AND WRITE DATA ADDRESS */
+/***************************************************************/
+/*!
+ * @brief This API is used to read data
+ * magnetometer address to read from the register 0x4D bit 0 to 7
+ * @brief It used to provide mag read address of auxiliary mag
+ *
+ *
+ *
+ *
+ * @param v_mag_read_addr_u8 : The value of address need to be read
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_read_addr(
+u8 *v_mag_read_addr_u8);
+/*!
+ * @brief This API is used to set
+ * magnetometer write address from the register 0x4D bit 0 to 7
+ * @brief mag write address writes the address of auxiliary mag to write
+ *
+ *
+ *
+ * @param v_mag_read_addr_u8:
+ * The data of auxiliary mag address to write data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_read_addr(
+u8 v_mag_read_addr_u8);
+/*!
+ * @brief This API is used to read
+ * magnetometer write address from the register 0x4E bit 0 to 7
+ * @brief mag write address writes the address of auxiliary mag to write
+ *
+ *
+ *
+ * @param v_mag_write_addr_u8:
+ * The data of auxiliary mag address to write data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_write_addr(
+u8 *v_mag_write_addr_u8);
+/*!
+ * @brief This API is used to set
+ * magnetometer write address from the register 0x4E bit 0 to 7
+ * @brief mag write address writes the address of auxiliary mag to write
+ *
+ *
+ *
+ * @param v_mag_write_addr_u8:
+ * The data of auxiliary mag address to write data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_write_addr(
+u8 v_mag_write_addr_u8);
+/*!
+ * @brief This API is used to read magnetometer write data
+ * form the resister 0x4F bit 0 to 7
+ * @brief This writes the data will be wrote to mag
+ *
+ *
+ *
+ * @param v_mag_write_data_u8: The value of mag data
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_mag_write_data(
+u8 *v_mag_write_data_u8);
+/*!
+ * @brief This API is used to set magnetometer write data
+ * form the resister 0x4F bit 0 to 7
+ * @brief This writes the data will be wrote to mag
+ *
+ *
+ *
+ * @param v_mag_write_data_u8: The value of mag data
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_mag_write_data(
+u8 v_mag_write_data_u8);
+/***************************************************************/
+/**\name FUNCTION FOR INTERRUPT ENABLE OF
+ANY-MOTION XYZ, DOUBLE AND SINGLE TAP, ORIENT AND FLAT */
+/***************************************************************/
+/*!
+ * @brief This API is used to read
+ * interrupt enable from the register 0x50 bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_enable_u8 : Value to decided to select interrupt
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_ANY_MOTION_X_ENABLE
+ * 1 | SMI130_ANY_MOTION_Y_ENABLE
+ * 2 | SMI130_ANY_MOTION_Z_ENABLE
+ * 3 | SMI130_DOUBLE_TAP_ENABLE
+ * 4 | SMI130_SINGLE_TAP_ENABLE
+ * 5 | SMI130_ORIENT_ENABLE
+ * 6 | SMI130_FLAT_ENABLE
+ *
+ * @param v_intr_enable_zero_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_enable_0(
+u8 enable, u8 *v_intr_enable_zero_u8);
+/*!
+ * @brief This API is used to set
+ * interrupt enable from the register 0x50 bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_enable_u8 : Value to decided to select interrupt
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_ANY_MOTION_X_ENABLE
+ * 1 | SMI130_ANY_MOTION_Y_ENABLE
+ * 2 | SMI130_ANY_MOTION_Z_ENABLE
+ * 3 | SMI130_DOUBLE_TAP_ENABLE
+ * 4 | SMI130_SINGLE_TAP_ENABLE
+ * 5 | SMI130_ORIENT_ENABLE
+ * 6 | SMI130_FLAT_ENABLE
+ *
+ * @param v_intr_enable_zero_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_enable_0(
+u8 enable, u8 v_intr_enable_zero_u8);
+/***************************************************************/
+/**\name FUNCTION FOR INTERRUPT ENABLE OF
+HIGH_G XYZ, LOW_G, DATA READY, FIFO FULL AND FIFO WATER MARK */
+/***************************************************************/
+/*!
+ * @brief This API is used to read
+ * interrupt enable byte1 from the register 0x51 bit 0 to 6
+ * @brief It read the high_g_x,high_g_y,high_g_z,low_g_enable
+ * data ready, fifo full and fifo water mark.
+ *
+ *
+ *
+ * @param v_enable_u8 : The value of interrupt enable
+ * @param v_enable_u8 : Value to decided to select interrupt
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_HIGH_G_X_ENABLE
+ * 1 | SMI130_HIGH_G_Y_ENABLE
+ * 2 | SMI130_HIGH_G_Z_ENABLE
+ * 3 | SMI130_LOW_G_ENABLE
+ * 4 | SMI130_DATA_RDY_ENABLE
+ * 5 | SMI130_FIFO_FULL_ENABLE
+ * 6 | SMI130_FIFO_WM_ENABLE
+ *
+ * @param v_intr_enable_1_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_enable_1(
+u8 enable, u8 *v_intr_enable_1_u8);
+/*!
+ * @brief This API is used to set
+ * interrupt enable byte1 from the register 0x51 bit 0 to 6
+ * @brief It read the high_g_x,high_g_y,high_g_z,low_g_enable
+ * data ready, fifo full and fifo water mark.
+ *
+ *
+ *
+ * @param v_enable_u8 : The value of interrupt enable
+ * @param v_enable_u8 : Value to decided to select interrupt
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_HIGH_G_X_ENABLE
+ * 1 | SMI130_HIGH_G_Y_ENABLE
+ * 2 | SMI130_HIGH_G_Z_ENABLE
+ * 3 | SMI130_LOW_G_ENABLE
+ * 4 | SMI130_DATA_RDY_ENABLE
+ * 5 | SMI130_FIFO_FULL_ENABLE
+ * 6 | SMI130_FIFO_WM_ENABLE
+ *
+ * @param v_intr_enable_1_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_enable_1(
+u8 enable, u8 v_intr_enable_1_u8);
+/***************************************************************/
+/**\name FUNCTION FOR INTERRUPT ENABLE OF
+NO MOTION XYZ */
+/***************************************************************/
+/*!
+ * @brief This API is used to read
+ * interrupt enable byte2 from the register bit 0x52 bit 0 to 3
+ * @brief It reads no motion x,y and z
+ *
+ *
+ *
+ * @param v_enable_u8: The value of interrupt enable
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_NOMOTION_X_ENABLE
+ * 1 | SMI130_NOMOTION_Y_ENABLE
+ * 2 | SMI130_NOMOTION_Z_ENABLE
+ *
+ * @param v_intr_enable_2_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_enable_2(
+u8 enable, u8 *v_intr_enable_2_u8);
+/*!
+ * @brief This API is used to set
+ * interrupt enable byte2 from the register bit 0x52 bit 0 to 3
+ * @brief It reads no motion x,y and z
+ *
+ *
+ *
+ * @param v_enable_u8: The value of interrupt enable
+ * v_enable_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_NOMOTION_X_ENABLE
+ * 1 | SMI130_NOMOTION_Y_ENABLE
+ * 2 | SMI130_NOMOTION_Z_ENABLE
+ *
+ * @param v_intr_enable_2_u8 : The interrupt enable value
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_enable_2(
+u8 enable, u8 v_intr_enable_2_u8);
+/***************************************************************/
+/**\name FUNCTION FOR INTERRUPT ENABLE OF
+ STEP DETECTOR */
+/***************************************************************/
+ /*!
+ * @brief This API is used to read
+ * interrupt enable step detector interrupt from
+ * the register bit 0x52 bit 3
+ *
+ *
+ *
+ *
+ * @param v_step_intr_u8 : The value of step detector interrupt enable
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_get_step_detector_enable(
+u8 *v_step_intr_u8);
+ /*!
+ * @brief This API is used to set
+ * interrupt enable step detector interrupt from
+ * the register bit 0x52 bit 3
+ *
+ *
+ *
+ *
+ * @param v_step_intr_u8 : The value of step detector interrupt enable
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_step_detector_enable(
+u8 v_step_intr_u8);
+/***************************************************************/
+/**\name FUNCTION FOR INTERRUPT CONTROL */
+/***************************************************************/
+/*!
+ * @brief Configure trigger condition of interrupt1
+ * and interrupt2 pin from the register 0x53
+ * @brief interrupt1 - bit 0
+ * @brief interrupt2 - bit 4
+ *
+ * @param v_channel_u8: The value of edge trigger selection
+ * v_channel_u8 | Edge trigger
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_EDGE_CTRL
+ * 1 | SMI130_INTR2_EDGE_CTRL
+ *
+ * @param v_intr_edge_ctrl_u8 : The value of edge trigger enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_EDGE
+ * 0x00 | SMI130_LEVEL
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_edge_ctrl(
+u8 v_channel_u8, u8 *v_intr_edge_ctrl_u8);
+/*!
+ * @brief Configure trigger condition of interrupt1
+ * and interrupt2 pin from the register 0x53
+ * @brief interrupt1 - bit 0
+ * @brief interrupt2 - bit 4
+ *
+ * @param v_channel_u8: The value of edge trigger selection
+ * v_channel_u8 | Edge trigger
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_EDGE_CTRL
+ * 1 | SMI130_INTR2_EDGE_CTRL
+ *
+ * @param v_intr_edge_ctrl_u8 : The value of edge trigger enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_EDGE
+ * 0x00 | SMI130_LEVEL
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_edge_ctrl(
+u8 v_channel_u8, u8 v_intr_edge_ctrl_u8);
+/*!
+ * @brief API used for get the Configure level condition of interrupt1
+ * and interrupt2 pin form the register 0x53
+ * @brief interrupt1 - bit 1
+ * @brief interrupt2 - bit 5
+ *
+ * @param v_channel_u8: The value of level condition selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_LEVEL
+ * 1 | SMI130_INTR2_LEVEL
+ *
+ * @param v_intr_level_u8 : The value of level of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | SMI130_LEVEL_HIGH
+ * 0x00 | SMI130_LEVEL_LOW
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_level(
+u8 v_channel_u8, u8 *v_intr_level_u8);
+/*!
+ * @brief API used for set the Configure level condition of interrupt1
+ * and interrupt2 pin form the register 0x53
+ * @brief interrupt1 - bit 1
+ * @brief interrupt2 - bit 5
+ *
+ * @param v_channel_u8: The value of level condition selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_LEVEL
+ * 1 | SMI130_INTR2_LEVEL
+ *
+ * @param v_intr_level_u8 : The value of level of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | SMI130_LEVEL_HIGH
+ * 0x00 | SMI130_LEVEL_LOW
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_level(
+u8 v_channel_u8, u8 v_intr_level_u8);
+/*!
+ * @brief API used to get configured output enable of interrupt1
+ * and interrupt2 from the register 0x53
+ * @brief interrupt1 - bit 2
+ * @brief interrupt2 - bit 6
+ *
+ *
+ * @param v_channel_u8: The value of output type enable selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_OUTPUT_TYPE
+ * 1 | SMI130_INTR2_OUTPUT_TYPE
+ *
+ * @param v_intr_output_type_u8 :
+ * The value of output type of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | SMI130_OPEN_DRAIN
+ * 0x00 | SMI130_PUSH_PULL
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_output_type(
+u8 v_channel_u8, u8 *v_intr_output_type_u8);
+/*!
+ * @brief API used to set output enable of interrupt1
+ * and interrupt2 from the register 0x53
+ * @brief interrupt1 - bit 2
+ * @brief interrupt2 - bit 6
+ *
+ *
+ * @param v_channel_u8: The value of output type enable selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_OUTPUT_TYPE
+ * 1 | SMI130_INTR2_OUTPUT_TYPE
+ *
+ * @param v_intr_output_type_u8 :
+ * The value of output type of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | SMI130_OPEN_DRAIN
+ * 0x00 | SMI130_PUSH_PULL
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_output_type(
+u8 v_channel_u8, u8 v_intr_output_type_u8);
+ /*!
+ * @brief API used to get the Output enable for interrupt1
+ * and interrupt1 pin from the register 0x53
+ * @brief interrupt1 - bit 3
+ * @brief interrupt2 - bit 7
+ *
+ * @param v_channel_u8: The value of output enable selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_OUTPUT_TYPE
+ * 1 | SMI130_INTR2_OUTPUT_TYPE
+ *
+ * @param v_output_enable_u8 :
+ * The value of output enable of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | SMI130_INPUT
+ * 0x00 | SMI130_OUTPUT
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_output_enable(
+u8 v_channel_u8, u8 *v_output_enable_u8);
+ /*!
+ * @brief API used to set the Output enable for interrupt1
+ * and interrupt1 pin from the register 0x53
+ * @brief interrupt1 - bit 3
+ * @brief interrupt2 - bit 7
+ *
+ * @param v_channel_u8: The value of output enable selection
+ * v_channel_u8 | level selection
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_OUTPUT_TYPE
+ * 1 | SMI130_INTR2_OUTPUT_TYPE
+ *
+ * @param v_output_enable_u8 :
+ * The value of output enable of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | SMI130_INPUT
+ * 0x00 | SMI130_OUTPUT
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_output_enable(
+u8 v_channel_u8, u8 v_output_enable_u8);
+/***************************************************************/
+/**\name FUNCTION FOR INTERRUPT LATCH INTERRUPT */
+/***************************************************************/
+/*!
+* @brief This API is used to get the latch duration
+* from the register 0x54 bit 0 to 3
+* @brief This latch selection is not applicable for data ready,
+* orientation and flat interrupts.
+*
+*
+*
+* @param v_latch_intr_u8 : The value of latch duration
+* Latch Duration | value
+* --------------------------------------|------------------
+* SMI130_LATCH_DUR_NONE | 0x00
+* SMI130_LATCH_DUR_312_5_MICRO_SEC | 0x01
+* SMI130_LATCH_DUR_625_MICRO_SEC | 0x02
+* SMI130_LATCH_DUR_1_25_MILLI_SEC | 0x03
+* SMI130_LATCH_DUR_2_5_MILLI_SEC | 0x04
+* SMI130_LATCH_DUR_5_MILLI_SEC | 0x05
+* SMI130_LATCH_DUR_10_MILLI_SEC | 0x06
+* SMI130_LATCH_DUR_20_MILLI_SEC | 0x07
+* SMI130_LATCH_DUR_40_MILLI_SEC | 0x08
+* SMI130_LATCH_DUR_80_MILLI_SEC | 0x09
+* SMI130_LATCH_DUR_160_MILLI_SEC | 0x0A
+* SMI130_LATCH_DUR_320_MILLI_SEC | 0x0B
+* SMI130_LATCH_DUR_640_MILLI_SEC | 0x0C
+* SMI130_LATCH_DUR_1_28_SEC | 0x0D
+* SMI130_LATCH_DUR_2_56_SEC | 0x0E
+* SMI130_LATCHED | 0x0F
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_latch_intr(
+u8 *v_latch_intr_u8);
+/*!
+* @brief This API is used to set the latch duration
+* from the register 0x54 bit 0 to 3
+* @brief This latch selection is not applicable for data ready,
+* orientation and flat interrupts.
+*
+*
+*
+* @param v_latch_intr_u8 : The value of latch duration
+* Latch Duration | value
+* --------------------------------------|------------------
+* SMI130_LATCH_DUR_NONE | 0x00
+* SMI130_LATCH_DUR_312_5_MICRO_SEC | 0x01
+* SMI130_LATCH_DUR_625_MICRO_SEC | 0x02
+* SMI130_LATCH_DUR_1_25_MILLI_SEC | 0x03
+* SMI130_LATCH_DUR_2_5_MILLI_SEC | 0x04
+* SMI130_LATCH_DUR_5_MILLI_SEC | 0x05
+* SMI130_LATCH_DUR_10_MILLI_SEC | 0x06
+* SMI130_LATCH_DUR_20_MILLI_SEC | 0x07
+* SMI130_LATCH_DUR_40_MILLI_SEC | 0x08
+* SMI130_LATCH_DUR_80_MILLI_SEC | 0x09
+* SMI130_LATCH_DUR_160_MILLI_SEC | 0x0A
+* SMI130_LATCH_DUR_320_MILLI_SEC | 0x0B
+* SMI130_LATCH_DUR_640_MILLI_SEC | 0x0C
+* SMI130_LATCH_DUR_1_28_SEC | 0x0D
+* SMI130_LATCH_DUR_2_56_SEC | 0x0E
+* SMI130_LATCHED | 0x0F
+*
+*
+*
+* @return results of bus communication function
+* @retval 0 -> Success
+* @retval -1 -> Error
+*
+*
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_latch_intr(
+u8 v_latch_intr_u8);
+/*!
+ * @brief API used to get input enable for interrupt1
+ * and interrupt2 pin from the register 0x54
+ * @brief interrupt1 - bit 4
+ * @brief interrupt2 - bit 5
+ *
+ * @param v_channel_u8: The value of input enable selection
+ * v_channel_u8 | input selection
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_INPUT_ENABLE
+ * 1 | SMI130_INTR2_INPUT_ENABLE
+ *
+ * @param v_input_en_u8 :
+ * The value of input enable of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | SMI130_INPUT
+ * 0x00 | SMI130_OUTPUT
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_input_enable(
+u8 v_channel_u8, u8 *v_input_en_u8);
+/*!
+ * @brief API used to set input enable for interrupt1
+ * and interrupt2 pin from the register 0x54
+ * @brief interrupt1 - bit 4
+ * @brief interrupt2 - bit 5
+ *
+ * @param v_channel_u8: The value of input enable selection
+ * v_channel_u8 | input selection
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_INPUT_ENABLE
+ * 1 | SMI130_INTR2_INPUT_ENABLE
+ *
+ * @param v_input_en_u8 :
+ * The value of input enable of interrupt enable
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x01 | SMI130_INPUT
+ * 0x00 | SMI130_OUTPUT
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_input_enable(
+u8 v_channel_u8, u8 v_input_en_u8);
+/***************************************************************/
+/**\name FUNCTION FOR INTERRUPT1 AND INTERRUPT2 MAPPING */
+/***************************************************************/
+ /*!
+ * @brief reads the Low g interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 0 in the register 0x55
+ * @brief interrupt2 bit 0 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of low_g selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_LOW_G
+ * 1 | SMI130_INTR2_MAP_LOW_G
+ *
+ * @param v_intr_low_g_u8 : The value of low_g enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_low_g(
+u8 v_channel_u8, u8 *v_intr_low_g_u8);
+ /*!
+ * @brief set the Low g interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 0 in the register 0x55
+ * @brief interrupt2 bit 0 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of low_g selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_LOW_G
+ * 1 | SMI130_INTR2_MAP_LOW_G
+ *
+ * @param v_intr_low_g_u8 : The value of low_g enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_low_g(
+u8 v_channel_u8, u8 v_intr_low_g_u8);
+/*!
+ * @brief Reads the HIGH g interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 1 in the register 0x55
+ * @brief interrupt2 bit 1 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of high_g selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_HIGH_G
+ * 1 | SMI130_INTR2_MAP_HIGH_G
+ *
+ * @param v_intr_high_g_u8 : The value of high_g enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_high_g(
+u8 v_channel_u8, u8 *v_intr_high_g_u8);
+/*!
+ * @brief Write the HIGH g interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 1 in the register 0x55
+ * @brief interrupt2 bit 1 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of high_g selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_HIGH_G
+ * 1 | SMI130_INTR2_MAP_HIGH_G
+ *
+ * @param v_intr_high_g_u8 : The value of high_g enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_high_g(
+u8 v_channel_u8, u8 v_intr_high_g_u8);
+/*!
+ * @brief Reads the Any motion interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 2 in the register 0x55
+ * @brief interrupt2 bit 2 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of any motion selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_ANY_MOTION
+ * 1 | SMI130_INTR2_MAP_ANY_MOTION
+ *
+ * @param v_intr_any_motion_u8 : The value of any motion enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_any_motion(
+u8 v_channel_u8, u8 *v_intr_any_motion_u8);
+/*!
+ * @brief Write the Any motion interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 2 in the register 0x55
+ * @brief interrupt2 bit 2 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of any motion selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_ANY_MOTION
+ * 1 | SMI130_INTR2_MAP_ANY_MOTION
+ *
+ * @param v_intr_any_motion_u8 : The value of any motion enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_any_motion(
+u8 v_channel_u8, u8 v_intr_any_motion_u8);
+/*!
+ * @brief Reads the No motion interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 3 in the register 0x55
+ * @brief interrupt2 bit 3 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of no motion selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_NOMO
+ * 1 | SMI130_INTR2_MAP_NOMO
+ *
+ * @param v_intr_nomotion_u8 : The value of no motion enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_nomotion(
+u8 v_channel_u8, u8 *v_intr_nomotion_u8);
+/*!
+ * @brief Write the No motion interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 3 in the register 0x55
+ * @brief interrupt2 bit 3 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of no motion selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_NOMO
+ * 1 | SMI130_INTR2_MAP_NOMO
+ *
+ * @param v_intr_nomotion_u8 : The value of no motion enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_nomotion(
+u8 v_channel_u8, u8 v_intr_nomotion_u8);
+/*!
+ * @brief Reads the Double Tap interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 4 in the register 0x55
+ * @brief interrupt2 bit 4 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of double tap interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_DOUBLE_TAP
+ * 1 | SMI130_INTR2_MAP_DOUBLE_TAP
+ *
+ * @param v_intr_double_tap_u8 : The value of double tap enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_double_tap(
+u8 v_channel_u8, u8 *v_intr_double_tap_u8);
+/*!
+ * @brief Write the Double Tap interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 4 in the register 0x55
+ * @brief interrupt2 bit 4 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of double tap interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_DOUBLE_TAP
+ * 1 | SMI130_INTR2_MAP_DOUBLE_TAP
+ *
+ * @param v_intr_double_tap_u8 : The value of double tap enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_double_tap(
+u8 v_channel_u8, u8 v_intr_double_tap_u8);
+/*!
+ * @brief Reads the Single Tap interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 5 in the register 0x55
+ * @brief interrupt2 bit 5 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of single tap interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_SINGLE_TAP
+ * 1 | SMI130_INTR2_MAP_SINGLE_TAP
+ *
+ * @param v_intr_single_tap_u8 : The value of single tap enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_single_tap(
+u8 v_channel_u8, u8 *v_intr_single_tap_u8);
+/*!
+ * @brief Write the Single Tap interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 5 in the register 0x55
+ * @brief interrupt2 bit 5 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of single tap interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_SINGLE_TAP
+ * 1 | SMI130_INTR2_MAP_SINGLE_TAP
+ *
+ * @param v_intr_single_tap_u8 : The value of single tap enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_single_tap(
+u8 v_channel_u8, u8 v_intr_single_tap_u8);
+/*!
+ * @brief Reads the Orient interrupt
+ * interrupt mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 6 in the register 0x55
+ * @brief interrupt2 bit 6 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of orient interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_ORIENT
+ * 1 | SMI130_INTR2_MAP_ORIENT
+ *
+ * @param v_intr_orient_u8 : The value of orient enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_orient(
+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 | SMI130_INTR1_MAP_ORIENT
+ * 1 | SMI130_INTR2_MAP_ORIENT
+ *
+ * @param v_intr_orient_u8 : The value of orient enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_orient(
+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 | SMI130_INTR1_MAP_FLAT
+ * 1 | SMI130_INTR2_MAP_FLAT
+ *
+ * @param v_intr_flat_u8 : The value of flat enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_flat(
+u8 v_channel_u8, u8 *v_intr_flat_u8);
+ /*!
+ * @brief Write the Flat interrupt
+ * mapped to interrupt1
+ * and interrupt2 from the register 0x55 and 0x57
+ * @brief interrupt1 bit 7 in the register 0x55
+ * @brief interrupt2 bit 7 in the register 0x57
+ *
+ *
+ * @param v_channel_u8: The value of flat interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_FLAT
+ * 1 | SMI130_INTR2_MAP_FLAT
+ *
+ * @param v_intr_flat_u8 : The value of flat enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_flat(
+u8 v_channel_u8, u8 v_intr_flat_u8);
+/*!
+ * @brief Reads PMU trigger interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 0 and 4
+ * @brief interrupt1 bit 0 in the register 0x56
+ * @brief interrupt2 bit 4 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of pmu trigger selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_PMUTRIG
+ * 1 | SMI130_INTR2_MAP_PMUTRIG
+ *
+ * @param v_intr_pmu_trig_u8 : The value of pmu trigger enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_pmu_trig(
+u8 v_channel_u8, u8 *v_intr_pmu_trig_u8);
+/*!
+ * @brief Write PMU trigger interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 0 and 4
+ * @brief interrupt1 bit 0 in the register 0x56
+ * @brief interrupt2 bit 4 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of pmu trigger selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_PMUTRIG
+ * 1 | SMI130_INTR2_MAP_PMUTRIG
+ *
+ * @param v_intr_pmu_trig_u8 : The value of pmu trigger enable
+ * value | trigger enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_pmu_trig(
+u8 v_channel_u8, u8 v_intr_pmu_trig_u8);
+/*!
+ * @brief Reads FIFO Full interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 5 and 1
+ * @brief interrupt1 bit 5 in the register 0x56
+ * @brief interrupt2 bit 1 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of fifo full interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_FIFO_FULL
+ * 1 | SMI130_INTR2_MAP_FIFO_FULL
+ *
+ * @param v_intr_fifo_full_u8 : The value of fifo full interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_fifo_full(
+u8 v_channel_u8, u8 *v_intr_fifo_full_u8);
+/*!
+ * @brief Write FIFO Full interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 5 and 1
+ * @brief interrupt1 bit 5 in the register 0x56
+ * @brief interrupt2 bit 1 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of fifo full interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_FIFO_FULL
+ * 1 | SMI130_INTR2_MAP_FIFO_FULL
+ *
+ * @param v_intr_fifo_full_u8 : The value of fifo full interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_fifo_full(
+u8 v_channel_u8, u8 v_intr_fifo_full_u8);
+/*!
+ * @brief Reads FIFO Watermark interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 6 and 2
+ * @brief interrupt1 bit 6 in the register 0x56
+ * @brief interrupt2 bit 2 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of fifo Watermark interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_FIFO_WM
+ * 1 | SMI130_INTR2_MAP_FIFO_WM
+ *
+ * @param v_intr_fifo_wm_u8 : The value of fifo Watermark interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_fifo_wm(
+u8 v_channel_u8, u8 *v_intr_fifo_wm_u8);
+/*!
+ * @brief Write FIFO Watermark interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56 bit 6 and 2
+ * @brief interrupt1 bit 6 in the register 0x56
+ * @brief interrupt2 bit 2 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of fifo Watermark interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_FIFO_WM
+ * 1 | SMI130_INTR2_MAP_FIFO_WM
+ *
+ * @param v_intr_fifo_wm_u8 : The value of fifo Watermark interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_fifo_wm(
+u8 v_channel_u8, u8 v_intr_fifo_wm_u8);
+/*!
+ * @brief Reads Data Ready interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56
+ * @brief interrupt1 bit 7 in the register 0x56
+ * @brief interrupt2 bit 3 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of data ready interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_DATA_RDY
+ * 1 | SMI130_INTR2_MAP_DATA_RDY
+ *
+ * @param v_intr_data_rdy_u8 : The value of data ready interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_data_rdy(
+u8 v_channel_u8, u8 *v_intr_data_rdy_u8);
+/*!
+ * @brief Write Data Ready interrupt mapped to interrupt1
+ * and interrupt2 form the register 0x56
+ * @brief interrupt1 bit 7 in the register 0x56
+ * @brief interrupt2 bit 3 in the register 0x56
+ *
+ *
+ * @param v_channel_u8: The value of data ready interrupt selection
+ * v_channel_u8 | interrupt
+ * ---------------|---------------
+ * 0 | SMI130_INTR1_MAP_DATA_RDY
+ * 1 | SMI130_INTR2_MAP_DATA_RDY
+ *
+ * @param v_intr_data_rdy_u8 : The value of data ready interrupt enable
+ * value | interrupt enable
+ * ----------|-------------------
+ * 0x01 | SMI130_ENABLE
+ * 0x00 | SMI130_DISABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_data_rdy(
+u8 v_channel_u8, u8 v_intr_data_rdy_u8);
+/***************************************************************/
+/**\name FUNCTION FOR TAP SOURCE CONFIGURATION */
+/***************************************************************/
+ /*!
+ * @brief This API reads data source for the interrupt
+ * engine for the single and double tap interrupts from the register
+ * 0x58 bit 3
+ *
+ *
+ * @param v_tap_source_u8 : The value of the tap source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_tap_source(
+u8 *v_tap_source_u8);
+ /*!
+ * @brief This API write data source for the interrupt
+ * engine for the single and double tap interrupts from the register
+ * 0x58 bit 3
+ *
+ *
+ * @param v_tap_source_u8 : The value of the tap source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_tap_source(
+u8 v_tap_source_u8);
+/***************************************************************/
+/**\name FUNCTION FOR LOW_G AND HIGH_G SOURCE CONFIGURATION */
+/***************************************************************/
+ /*!
+ * @brief This API Reads Data source for the
+ * interrupt engine for the low and high g interrupts
+ * from the register 0x58 bit 7
+ *
+ * @param v_low_high_source_u8 : The value of the tap source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_low_high_source(
+u8 *v_low_high_source_u8);
+ /*!
+ * @brief This API write Data source for the
+ * interrupt engine for the low and high g interrupts
+ * from the register 0x58 bit 7
+ *
+ * @param v_low_high_source_u8 : The value of the tap source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_low_high_source(
+u8 v_low_high_source_u8);
+/***************************************************************/
+/**\name FUNCTION FOR MOTION SOURCE CONFIGURATION */
+/***************************************************************/
+ /*!
+ * @brief This API reads Data source for the
+ * interrupt engine for the nomotion and anymotion interrupts
+ * from the register 0x59 bit 7
+ *
+ * @param v_motion_source_u8 :
+ * The value of the any/no motion interrupt source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_motion_source(
+u8 *v_motion_source_u8);
+ /*!
+ * @brief This API write Data source for the
+ * interrupt engine for the nomotion and anymotion interrupts
+ * from the register 0x59 bit 7
+ *
+ * @param v_motion_source_u8 :
+ * The value of the any/no motion interrupt source
+ * value | Description
+ * ----------|-------------------
+ * 0x01 | UNFILTER_DATA
+ * 0x00 | FILTER_DATA
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_motion_source(
+u8 v_motion_source_u8);
+/***************************************************************/
+/**\name FUNCTION FOR LOW_G DURATION CONFIGURATION */
+/***************************************************************/
+/*!
+ * @brief This API is used to read the low_g duration from register
+ * 0x5A bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_low_g_durn_u8 : The value of low_g duration
+ *
+ * @note Low_g duration trigger trigger delay according to
+ * "(v_low_g_durn_u8 * 2.5)ms" in a range from 2.5ms to 640ms.
+ * the default corresponds delay is 20ms
+ * @note When low_g data source of interrupt is unfiltered
+ * the sensor must not be in low power mode
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_low_g_durn(
+u8 *v_low_durn_u8);
+ /*!
+ * @brief This API is used to write the low_g duration from register
+ * 0x5A bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_low_g_durn_u8 : The value of low_g duration
+ *
+ * @note Low_g duration trigger trigger delay according to
+ * "(v_low_g_durn_u8 * 2.5)ms" in a range from 2.5ms to 640ms.
+ * the default corresponds delay is 20ms
+ * @note When low_g data source of interrupt is unfiltered
+ * the sensor must not be in low power mode
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_low_g_durn(
+u8 v_low_durn_u8);
+/***************************************************************/
+/**\name FUNCTION FOR LOW_G THRESH CONFIGURATION */
+/***************************************************************/
+/*!
+ * @brief This API is used to read Threshold
+ * definition for the low-g interrupt from the register 0x5B bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_low_g_thres_u8 : The value of low_g threshold
+ *
+ * @note Low_g interrupt trigger threshold according to
+ * (v_low_g_thres_u8 * 7.81)mg for v_low_g_thres_u8 > 0
+ * 3.91 mg for v_low_g_thres_u8 = 0
+ * The threshold range is form 3.91mg to 2.000mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_low_g_thres(
+u8 *v_low_g_thres_u8);
+/*!
+ * @brief This API is used to write Threshold
+ * definition for the low-g interrupt from the register 0x5B bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_low_g_thres_u8 : The value of low_g threshold
+ *
+ * @note Low_g interrupt trigger threshold according to
+ * (v_low_g_thres_u8 * 7.81)mg for v_low_g_thres_u8 > 0
+ * 3.91 mg for v_low_g_thres_u8 = 0
+ * The threshold range is form 3.91mg to 2.000mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_low_g_thres(
+u8 v_low_g_thres_u8);
+/***************************************************************/
+/**\name FUNCTION FOR LOW_G HYSTERESIS CONFIGURATION */
+/***************************************************************/
+ /*!
+ * @brief This API Reads Low-g interrupt hysteresis
+ * from the register 0x5C bit 0 to 1
+ *
+ * @param v_low_hyst_u8 :The value of low_g hysteresis
+ *
+ * @note Low_g hysteresis calculated by v_low_hyst_u8*125 mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_low_g_hyst(
+u8 *v_low_hyst_u8);
+ /*!
+ * @brief This API write Low-g interrupt hysteresis
+ * from the register 0x5C bit 0 to 1
+ *
+ * @param v_low_hyst_u8 :The value of low_g hysteresis
+ *
+ * @note Low_g hysteresis calculated by v_low_hyst_u8*125 mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_low_g_hyst(
+u8 v_low_hyst_u8);
+/***************************************************************/
+/**\name FUNCTION FOR LOW_G MODE CONFIGURATION */
+/***************************************************************/
+/*!
+ * @brief This API reads Low-g interrupt mode
+ * from the register 0x5C bit 2
+ *
+ * @param v_low_g_mode_u8 : The value of low_g mode
+ * Value | Description
+ * ----------|-----------------
+ * 0 | single-axis
+ * 1 | axis-summing
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_low_g_mode(
+u8 *v_low_g_mode_u8);
+/*!
+ * @brief This API write Low-g interrupt mode
+ * from the register 0x5C bit 2
+ *
+ * @param v_low_g_mode_u8 : The value of low_g mode
+ * Value | Description
+ * ----------|-----------------
+ * 0 | single-axis
+ * 1 | axis-summing
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_low_g_mode(
+u8 v_low_g_mode_u8);
+/***************************************************************/
+/**\name FUNCTION FOR HIGH_G HYST CONFIGURATION */
+/***************************************************************/
+/*!
+ * @brief This API reads High-g interrupt hysteresis
+ * from the register 0x5C bit 6 and 7
+ *
+ * @param v_high_g_hyst_u8 : The value of high hysteresis
+ *
+ * @note High_g hysteresis changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | high_g hysteresis
+ * ----------------|---------------------
+ * 2g | high_hy*125 mg
+ * 4g | high_hy*250 mg
+ * 8g | high_hy*500 mg
+ * 16g | high_hy*1000 mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_high_g_hyst(
+u8 *v_high_g_hyst_u8);
+/*!
+ * @brief This API write High-g interrupt hysteresis
+ * from the register 0x5C bit 6 and 7
+ *
+ * @param v_high_g_hyst_u8 : The value of high hysteresis
+ *
+ * @note High_g hysteresis changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | high_g hysteresis
+ * ----------------|---------------------
+ * 2g | high_hy*125 mg
+ * 4g | high_hy*250 mg
+ * 8g | high_hy*500 mg
+ * 16g | high_hy*1000 mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_high_g_hyst(
+u8 v_high_g_hyst_u8);
+/***************************************************************/
+/**\name FUNCTION FOR HIGH_G DURATION CONFIGURATION */
+/***************************************************************/
+/*!
+ * @brief This API is used to read Delay
+ * time definition for the high-g interrupt from the register
+ * 0x5D bit 0 to 7
+ *
+ *
+ *
+ * @param v_high_g_durn_u8 : The value of high duration
+ *
+ * @note High_g interrupt delay triggered according to
+ * v_high_g_durn_u8 * 2.5ms in a range from 2.5ms to 640ms
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_high_g_durn(
+u8 *v_high_g_durn_u8);
+/*!
+ * @brief This API is used to write Delay
+ * time definition for the high-g interrupt from the register
+ * 0x5D bit 0 to 7
+ *
+ *
+ *
+ * @param v_high_g_durn_u8 : The value of high duration
+ *
+ * @note High_g interrupt delay triggered according to
+ * v_high_g_durn_u8 * 2.5ms in a range from 2.5ms to 640ms
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_high_g_durn(
+u8 v_high_g_durn_u8);
+/***************************************************************/
+/**\name FUNCTION FOR HIGH_G THRESHOLD CONFIGURATION */
+/***************************************************************/
+/*!
+ * @brief This API is used to read Threshold
+ * definition for the high-g interrupt from the register 0x5E 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_high_g_thres_u8 : Pointer holding the value of Threshold
+ * @note High_g threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | high_g threshold
+ * ----------------|---------------------
+ * 2g | v_high_g_thres_u8*7.81 mg
+ * 4g | v_high_g_thres_u8*15.63 mg
+ * 8g | v_high_g_thres_u8*31.25 mg
+ * 16g | v_high_g_thres_u8*62.5 mg
+ * @note when v_high_g_thres_u8 = 0
+ * accel_range | high_g threshold
+ * ----------------|---------------------
+ * 2g | 3.91 mg
+ * 4g | 7.81 mg
+ * 8g | 15.63 mg
+ * 16g | 31.25 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_high_g_thres(
+u8 *v_high_g_thres_u8);
+/*!
+ * @brief This API is used to write Threshold
+ * definition for the high-g interrupt from the register 0x5E 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_high_g_thres_u8 : Pointer holding the value of Threshold
+ * @note High_g threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | high_g threshold
+ * ----------------|---------------------
+ * 2g | v_high_g_thres_u8*7.81 mg
+ * 4g | v_high_g_thres_u8*15.63 mg
+ * 8g | v_high_g_thres_u8*31.25 mg
+ * 16g | v_high_g_thres_u8*62.5 mg
+ * @note when v_high_g_thres_u8 = 0
+ * accel_range | high_g threshold
+ * ----------------|---------------------
+ * 2g | 3.91 mg
+ * 4g | 7.81 mg
+ * 8g | 15.63 mg
+ * 16g | 31.25 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_high_g_thres(
+u8 v_high_g_thres_u8);
+/***************************************************************/
+/**\name FUNCTION FOR ANY MOTION DURATION CONFIGURATION */
+/***************************************************************/
+/*!
+ * @brief This API reads any motion duration
+ * from the register 0x5F bit 0 and 1
+ *
+ * @param v_any_motion_durn_u8 : The value of any motion duration
+ *
+ * @note Any motion duration can be calculated by "v_any_motion_durn_u8 + 1"
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_any_motion_durn(
+u8 *v_any_motion_durn_u8);
+/*!
+ * @brief This API write any motion duration
+ * from the register 0x5F bit 0 and 1
+ *
+ * @param v_any_motion_durn_u8 : The value of any motion duration
+ *
+ * @note Any motion duration can be calculated by "v_any_motion_durn_u8 + 1"
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_any_motion_durn(
+u8 nomotion);
+/***************************************************************/
+/**\name FUNCTION FOR SLOW NO MOTION DURATION CONFIGURATION */
+/***************************************************************/
+ /*!
+ * @brief This API read Slow/no-motion
+ * interrupt trigger delay duration from the register 0x5F bit 2 to 7
+ *
+ * @param v_slow_no_motion_u8 :The value of slow no motion duration
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ * @note
+ * @note v_slow_no_motion_u8(5:4)=0b00 ->
+ * [v_slow_no_motion_u8(3:0) + 1] * 1.28s (1.28s-20.48s)
+ * @note v_slow_no_motion_u8(5:4)=1 ->
+ * [v_slow_no_motion_u8(3:0)+5] * 5.12s (25.6s-102.4s)
+ * @note v_slow_no_motion_u8(5)='1' ->
+ * [(v_slow_no_motion_u8:0)+11] * 10.24s (112.64s-430.08s);
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_slow_no_motion_durn(
+u8 *v_slow_no_motion_u8);
+ /*!
+ * @brief This API write Slow/no-motion
+ * interrupt trigger delay duration from the register 0x5F bit 2 to 7
+ *
+ * @param v_slow_no_motion_u8 :The value of slow no motion duration
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ * @note
+ * @note v_slow_no_motion_u8(5:4)=0b00 ->
+ * [v_slow_no_motion_u8(3:0) + 1] * 1.28s (1.28s-20.48s)
+ * @note v_slow_no_motion_u8(5:4)=1 ->
+ * [v_slow_no_motion_u8(3:0)+5] * 5.12s (25.6s-102.4s)
+ * @note v_slow_no_motion_u8(5)='1' ->
+ * [(v_slow_no_motion_u8:0)+11] * 10.24s (112.64s-430.08s);
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_slow_no_motion_durn(
+u8 v_slow_no_motion_u8);
+/***************************************************************/
+/**\name FUNCTION FOR ANY MOTION THRESHOLD CONFIGURATION */
+/***************************************************************/
+/*!
+ * @brief This API is used to read threshold
+ * definition for the any-motion interrupt
+ * from the register 0x60 bit 0 to 7
+ *
+ *
+ * @param v_any_motion_thres_u8 : The value of any motion threshold
+ *
+ * @note any motion threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | any motion threshold
+ * ----------------|---------------------
+ * 2g | v_any_motion_thres_u8*3.91 mg
+ * 4g | v_any_motion_thres_u8*7.81 mg
+ * 8g | v_any_motion_thres_u8*15.63 mg
+ * 16g | v_any_motion_thres_u8*31.25 mg
+ * @note when v_any_motion_thres_u8 = 0
+ * accel_range | any motion threshold
+ * ----------------|---------------------
+ * 2g | 1.95 mg
+ * 4g | 3.91 mg
+ * 8g | 7.81 mg
+ * 16g | 15.63 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_any_motion_thres(
+u8 *v_any_motion_thres_u8);
+/*!
+ * @brief This API is used to write threshold
+ * definition for the any-motion interrupt
+ * from the register 0x60 bit 0 to 7
+ *
+ *
+ * @param v_any_motion_thres_u8 : The value of any motion threshold
+ *
+ * @note any motion threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | any motion threshold
+ * ----------------|---------------------
+ * 2g | v_any_motion_thres_u8*3.91 mg
+ * 4g | v_any_motion_thres_u8*7.81 mg
+ * 8g | v_any_motion_thres_u8*15.63 mg
+ * 16g | v_any_motion_thres_u8*31.25 mg
+ * @note when v_any_motion_thres_u8 = 0
+ * accel_range | any motion threshold
+ * ----------------|---------------------
+ * 2g | 1.95 mg
+ * 4g | 3.91 mg
+ * 8g | 7.81 mg
+ * 16g | 15.63 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_any_motion_thres(
+u8 v_any_motion_thres_u8);
+/***************************************************************/
+/**\name FUNCTION FOR SLO/NO MOTION THRESHOLD CONFIGURATION */
+/***************************************************************/
+ /*!
+ * @brief This API is used to read threshold
+ * for the slow/no-motion interrupt
+ * from the register 0x61 bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_slow_no_motion_thres_u8 : The value of slow no motion threshold
+ * @note slow no motion threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | slow no motion threshold
+ * ----------------|---------------------
+ * 2g | v_slow_no_motion_thres_u8*3.91 mg
+ * 4g | v_slow_no_motion_thres_u8*7.81 mg
+ * 8g | v_slow_no_motion_thres_u8*15.63 mg
+ * 16g | v_slow_no_motion_thres_u8*31.25 mg
+ * @note when v_slow_no_motion_thres_u8 = 0
+ * accel_range | slow no motion threshold
+ * ----------------|---------------------
+ * 2g | 1.95 mg
+ * 4g | 3.91 mg
+ * 8g | 7.81 mg
+ * 16g | 15.63 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_slow_no_motion_thres(
+u8 *v_slow_no_motion_thres_u8);
+ /*!
+ * @brief This API is used to write threshold
+ * for the slow/no-motion interrupt
+ * from the register 0x61 bit 0 to 7
+ *
+ *
+ *
+ *
+ * @param v_slow_no_motion_thres_u8 : The value of slow no motion threshold
+ * @note slow no motion threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | slow no motion threshold
+ * ----------------|---------------------
+ * 2g | v_slow_no_motion_thres_u8*3.91 mg
+ * 4g | v_slow_no_motion_thres_u8*7.81 mg
+ * 8g | v_slow_no_motion_thres_u8*15.63 mg
+ * 16g | v_slow_no_motion_thres_u8*31.25 mg
+ * @note when v_slow_no_motion_thres_u8 = 0
+ * accel_range | slow no motion threshold
+ * ----------------|---------------------
+ * 2g | 1.95 mg
+ * 4g | 3.91 mg
+ * 8g | 7.81 mg
+ * 16g | 15.63 mg
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_slow_no_motion_thres(
+u8 v_slow_no_motion_thres_u8);
+/***************************************************************/
+/**\name FUNCTION FOR SLO/NO MOTION SELECT CONFIGURATION */
+/***************************************************************/
+ /*!
+ * @brief This API is used to read
+ * the slow/no-motion selection from the register 0x62 bit 0
+ *
+ *
+ *
+ *
+ * @param v_intr_slow_no_motion_select_u8 :
+ * The value of slow/no-motion select
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | SLOW_MOTION
+ * 0x01 | NO_MOTION
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_slow_no_motion_select(
+u8 *v_intr_slow_no_motion_select_u8);
+ /*!
+ * @brief This API is used to write
+ * the slow/no-motion selection from the register 0x62 bit 0
+ *
+ *
+ *
+ *
+ * @param v_intr_slow_no_motion_select_u8 :
+ * The value of slow/no-motion select
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | SLOW_MOTION
+ * 0x01 | NO_MOTION
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_slow_no_motion_select(
+u8 v_intr_slow_no_motion_select_u8);
+/***************************************************************/
+/**\name FUNCTION FOR SIGNIFICANT MOTION SELECT CONFIGURATION*/
+/***************************************************************/
+ /*!
+ * @brief This API is used to select
+ * the significant or any motion interrupt from the register 0x62 bit 1
+ *
+ *
+ *
+ *
+ * @param v_intr_significant_motion_select_u8 :
+ * the value of significant or any motion interrupt selection
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | ANY_MOTION
+ * 0x01 | SIGNIFICANT_MOTION
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_significant_motion_select(
+u8 *int_sig_mot_sel);
+ /*!
+ * @brief This API is used to write, select
+ * the significant or any motion interrupt from the register 0x62 bit 1
+ *
+ *
+ *
+ *
+ * @param v_intr_significant_motion_select_u8 :
+ * the value of significant or any motion interrupt selection
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | ANY_MOTION
+ * 0x01 | SIGNIFICANT_MOTION
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_significant_motion_select(
+u8 int_sig_mot_sel);
+ /*!
+ * @brief This API is used to read
+ * the significant skip time from the register 0x62 bit 2 and 3
+ *
+ *
+ *
+ *
+ * @param v_int_sig_mot_skip_u8 : the value of significant skip time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | skip time 1.5 seconds
+ * 0x01 | skip time 3 seconds
+ * 0x02 | skip time 6 seconds
+ * 0x03 | skip time 12 seconds
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_significant_motion_skip(
+u8 *v_int_sig_mot_skip_u8);
+ /*!
+ * @brief This API is used to write
+ * the significant skip time from the register 0x62 bit 2 and 3
+ *
+ *
+ *
+ *
+ * @param v_int_sig_mot_skip_u8 : the value of significant skip time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | skip time 1.5 seconds
+ * 0x01 | skip time 3 seconds
+ * 0x02 | skip time 6 seconds
+ * 0x03 | skip time 12 seconds
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_significant_motion_skip(
+u8 v_int_sig_mot_skip_u8);
+ /*!
+ * @brief This API is used to read
+ * the significant proof time from the register 0x62 bit 4 and 5
+ *
+ *
+ *
+ *
+ * @param v_significant_motion_proof_u8 :
+ * the value of significant proof time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | proof time 0.25 seconds
+ * 0x01 | proof time 0.5 seconds
+ * 0x02 | proof time 1 seconds
+ * 0x03 | proof time 2 seconds
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_significant_motion_proof(
+u8 *int_sig_mot_proof);
+ /*!
+ * @brief This API is used to write
+ * the significant proof time from the register 0x62 bit 4 and 5
+ *
+ *
+ *
+ *
+ * @param v_significant_motion_proof_u8 :
+ * the value of significant proof time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | proof time 0.25 seconds
+ * 0x01 | proof time 0.5 seconds
+ * 0x02 | proof time 1 seconds
+ * 0x03 | proof time 2 seconds
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_significant_motion_proof(
+u8 int_sig_mot_proof);
+/***************************************************************/
+/**\name FUNCTION FOR TAP DURATION CONFIGURATION*/
+/***************************************************************/
+/*!
+ * @brief This API is used to get the tap duration
+ * from the register 0x63 bit 0 to 2
+ *
+ *
+ *
+ * @param v_tap_durn_u8 : The value of tap duration
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | SMI130_TAP_DURN_50MS
+ * 0x01 | SMI130_TAP_DURN_100MS
+ * 0x03 | SMI130_TAP_DURN_150MS
+ * 0x04 | SMI130_TAP_DURN_200MS
+ * 0x05 | SMI130_TAP_DURN_250MS
+ * 0x06 | SMI130_TAP_DURN_375MS
+ * 0x07 | SMI130_TAP_DURN_700MS
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_tap_durn(
+u8 *v_tap_durn_u8);
+/*!
+ * @brief This API is used to write the tap duration
+ * from the register 0x63 bit 0 to 2
+ *
+ *
+ *
+ * @param v_tap_durn_u8 : The value of tap duration
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | SMI130_TAP_DURN_50MS
+ * 0x01 | SMI130_TAP_DURN_100MS
+ * 0x03 | SMI130_TAP_DURN_150MS
+ * 0x04 | SMI130_TAP_DURN_200MS
+ * 0x05 | SMI130_TAP_DURN_250MS
+ * 0x06 | SMI130_TAP_DURN_375MS
+ * 0x07 | SMI130_TAP_DURN_700MS
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_tap_durn(
+u8 v_tap_durn_u8);
+/***************************************************************/
+/**\name FUNCTION FOR TAP SHOCK CONFIGURATION*/
+/***************************************************************/
+ /*!
+ * @brief This API read the
+ * tap shock duration from the register 0x63 bit 2
+ *
+ * @param v_tap_shock_u8 :The value of tap shock
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | SMI130_TAP_SHOCK_50MS
+ * 0x01 | SMI130_TAP_SHOCK_75MS
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_tap_shock(
+u8 *v_tap_shock_u8);
+ /*!
+ * @brief This API write the
+ * tap shock duration from the register 0x63 bit 2
+ *
+ * @param v_tap_shock_u8 :The value of tap shock
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | SMI130_TAP_SHOCK_50MS
+ * 0x01 | SMI130_TAP_SHOCK_75MS
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_tap_shock(
+u8 v_tap_shock_u8);
+/***************************************************************/
+/**\name FUNCTION FOR TAP QUIET CONFIGURATION*/
+/***************************************************************/
+/*!
+ * @brief This API read
+ * tap quiet duration from the register 0x63 bit 7
+ *
+ *
+ * @param v_tap_quiet_u8 : The value of tap quiet
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | SMI130_TAP_QUIET_30MS
+ * 0x01 | SMI130_TAP_QUIET_20MS
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_tap_quiet(
+u8 *v_tap_quiet_u8);
+/*!
+ * @brief This API write
+ * tap quiet duration from the register 0x63 bit 7
+ *
+ *
+ * @param v_tap_quiet_u8 : The value of tap quiet
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | SMI130_TAP_QUIET_30MS
+ * 0x01 | SMI130_TAP_QUIET_20MS
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_tap_quiet(
+u8 v_tap_quiet_u8);
+/***************************************************************/
+/**\name FUNCTION FOR TAP THRESHOLD CONFIGURATION*/
+/***************************************************************/
+ /*!
+ * @brief This API read Threshold of the
+ * single/double tap interrupt from the register 0x64 bit 0 to 4
+ *
+ *
+ * @param v_tap_thres_u8 : The value of single/double tap threshold
+ *
+ * @note single/double tap threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | single/double tap threshold
+ * ----------------|---------------------
+ * 2g | ((v_tap_thres_u8 + 1) * 62.5)mg
+ * 4g | ((v_tap_thres_u8 + 1) * 125)mg
+ * 8g | ((v_tap_thres_u8 + 1) * 250)mg
+ * 16g | ((v_tap_thres_u8 + 1) * 500)mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_tap_thres(
+u8 *v_tap_thres_u8);
+ /*!
+ * @brief This API write Threshold of the
+ * single/double tap interrupt from the register 0x64 bit 0 to 4
+ *
+ *
+ * @param v_tap_thres_u8 : The value of single/double tap threshold
+ *
+ * @note single/double tap threshold changes according to accel g range
+ * accel g range can be set by the function ""
+ * accel_range | single/double tap threshold
+ * ----------------|---------------------
+ * 2g | ((v_tap_thres_u8 + 1) * 62.5)mg
+ * 4g | ((v_tap_thres_u8 + 1) * 125)mg
+ * 8g | ((v_tap_thres_u8 + 1) * 250)mg
+ * 16g | ((v_tap_thres_u8 + 1) * 500)mg
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_tap_thres(
+u8 v_tap_thres_u8);
+/***************************************************************/
+/**\name FUNCTION FOR ORIENT MODE CONFIGURATION*/
+/***************************************************************/
+ /*!
+ * @brief This API read the threshold for 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
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_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
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_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
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_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
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_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
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_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
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_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
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_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
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_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
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_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
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_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
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_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
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_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
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_flat_theta(
+u8 *v_flat_theta_u8);
+ /*!
+ * @brief This API write Flat angle (0 to 44.8) for flat interrupt
+ * from the register 0x67 bit 0 to 5
+ *
+ * @param v_flat_theta_u8 : The value of flat angle
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_flat_theta(
+u8 v_flat_theta_u8);
+/***************************************************************/
+/**\name FUNCTION FOR FLAT HOLD CONFIGURATION*/
+/***************************************************************/
+/*!
+ * @brief This API read Flat interrupt hold time;
+ * from the register 0x68 bit 4 and 5
+ *
+ * @param v_flat_hold_u8 : The value of flat hold time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | 0ms
+ * 0x01 | 512ms
+ * 0x01 | 1024ms
+ * 0x01 | 2048ms
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_flat_hold(
+u8 *v_flat_hold_u8);
+/*!
+ * @brief This API write Flat interrupt hold time;
+ * from the register 0x68 bit 4 and 5
+ *
+ * @param v_flat_hold_u8 : The value of flat hold time
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | 0ms
+ * 0x01 | 512ms
+ * 0x01 | 1024ms
+ * 0x01 | 2048ms
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_flat_hold(
+u8 v_flat_hold_u8);
+/***************************************************************/
+/**\name FUNCTION FOR FLAT HYSTERESIS CONFIGURATION*/
+/***************************************************************/
+/*!
+ * @brief This API read flat interrupt hysteresis
+ * from the register 0x68 bit 0 to 3
+ *
+ * @param v_flat_hyst_u8 : The value of flat hysteresis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_intr_flat_hyst(
+u8 *v_flat_hyst_u8);
+/*!
+ * @brief This API write flat interrupt hysteresis
+ * from the register 0x68 bit 0 to 3
+ *
+ * @param v_flat_hyst_u8 : The value of flat hysteresis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_intr_flat_hyst(
+u8 v_flat_hyst_u8);
+/***************************************************************/
+/**\name FUNCTION FAST OFFSET COMPENSATION FOR ACCEL */
+/***************************************************************/
+ /*!
+ * @brief This API read accel offset compensation
+ * target value for z-axis from the register 0x69 bit 0 and 1
+ *
+ * @param v_foc_accel_z_u8 : the value of accel offset compensation z axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_foc_accel_z(
+u8 *v_foc_accel_z_u8);
+ /*!
+ * @brief This API write accel offset compensation
+ * target value for z-axis from the register 0x69 bit 0 and 1
+ *
+ * @param v_foc_accel_z_u8 : the value of accel offset compensation z axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_foc_accel_z(
+u8 v_foc_accel_z_u8);
+/*!
+ * @brief This API read accel offset compensation
+ * target value for y-axis
+ * from the register 0x69 bit 2 and 3
+ *
+ * @param v_foc_accel_y_u8 : the value of accel offset compensation y axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_foc_accel_y(
+u8 *v_foc_accel_y_u8);
+/*!
+ * @brief This API write accel offset compensation
+ * target value for y-axis
+ * from the register 0x69 bit 2 and 3
+ *
+ * @param v_foc_accel_y_u8 : the value of accel offset compensation y axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_foc_accel_y(
+u8 v_foc_accel_y_u8);
+/*!
+ * @brief This API read accel offset compensation
+ * target value for x-axis is
+ * from the register 0x69 bit 4 and 5
+ *
+ * @param v_foc_accel_x_u8 : the value of accel offset compensation x axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_foc_accel_x(
+u8 *v_foc_accel_x_u8);
+/*!
+ * @brief This API write accel offset compensation
+ * target value for x-axis is
+ * from the register 0x69 bit 4 and 5
+ *
+ * @param v_foc_accel_x_u8 : the value of accel offset compensation x axis
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_foc_accel_x(
+u8 v_foc_accel_x_u8);
+/***************************************************************/
+/**\name FUNCTION FAST OFFSET COMPENSATION FOR GYRO */
+/***************************************************************/
+/*!
+ * @brief This API write gyro fast offset enable
+ * from the register 0x69 bit 6
+ *
+ * @param v_foc_gyro_u8 : The value of gyro fast offset enable
+ * value | Description
+ * ----------|-------------
+ * 0 | fast offset compensation disabled
+ * 1 | fast offset compensation enabled
+ *
+ * @param v_gyro_off_x_s16 : The value of gyro fast offset x axis data
+ * @param v_gyro_off_y_s16 : The value of gyro fast offset y axis data
+ * @param v_gyro_off_z_s16 : The value of gyro fast offset z axis data
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_foc_gyro_enable(
+u8 v_foc_gyro_u8, s16 *v_gyro_off_x_s16,
+s16 *v_gyro_off_y_s16, s16 *v_gyro_off_z_s16);
+/***************************************************/
+/**\name FUNCTION FOR NVM*/
+/***************************************************/
+ /*!
+ * @brief This API read NVM program enable
+ * from the register 0x6A bit 1
+ *
+ * @param v_nvm_prog_u8 : The value of NVM program enable
+ * Value | Description
+ * --------|-------------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_nvm_prog_enable(
+u8 *v_nvm_prog_u8);
+ /*!
+ * @brief This API write NVM program enable
+ * from the register 0x6A bit 1
+ *
+ * @param v_nvm_prog_u8 : The value of NVM program enable
+ * Value | Description
+ * --------|-------------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_nvm_prog_enable(
+u8 v_nvm_prog_u8);
+/***************************************************/
+/**\name FUNCTION FOR SPI MODE*/
+/***************************************************/
+/*!
+ * @brief This API read to configure SPI
+ * Interface Mode for primary and OIS interface
+ * from the register 0x6B bit 0
+ *
+ * @param v_spi3_u8 : The value of SPI mode selection
+ * Value | Description
+ * --------|-------------
+ * 0 | SPI 4-wire mode
+ * 1 | SPI 3-wire mode
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_get_spi3(
+u8 *v_spi3_u8);
+/*!
+ * @brief This API write to configure SPI
+ * Interface Mode for primary and OIS interface
+ * from the register 0x6B bit 0
+ *
+ * @param v_spi3_u8 : The value of SPI mode selection
+ * Value | Description
+ * --------|-------------
+ * 0 | SPI 4-wire mode
+ * 1 | SPI 3-wire mode
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_spi3(
+u8 v_spi3_u8);
+/***************************************************/
+/**\name FUNCTION FOR FOC GYRO */
+/***************************************************/
+/*!
+ * @brief This API read gyro fast offset enable
+ * from the register 0x69 bit 6
+ *
+ * @param v_foc_gyro_u8 : The value of gyro fast offset enable
+ * value | Description
+ * ----------|-------------
+ * 0 | fast offset compensation disabled
+ * 1 | fast offset compensation enabled
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_foc_gyro_enable(
+u8 *v_foc_gyro_u8);
+/***************************************************/
+/**\name FUNCTION FOR I2C WATCHDOG TIMBER */
+/***************************************************/
+/*!
+ * @brief This API read I2C Watchdog timer
+ * from the register 0x70 bit 1
+ *
+ * @param v_i2c_wdt_u8 : The value of I2C watch dog timer
+ * Value | Description
+ * --------|-------------
+ * 0 | I2C watchdog v_timeout_u8 after 1 ms
+ * 1 | I2C watchdog v_timeout_u8 after 50 ms
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_i2c_wdt_select(
+u8 *v_i2c_wdt_u8);
+/*!
+ * @brief This API write I2C Watchdog timer
+ * from the register 0x70 bit 1
+ *
+ * @param v_i2c_wdt_u8 : The value of I2C watch dog timer
+ * Value | Description
+ * --------|-------------
+ * 0 | I2C watchdog v_timeout_u8 after 1 ms
+ * 1 | I2C watchdog v_timeout_u8 after 50 ms
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE
+smi130_set_i2c_wdt_select(u8 v_i2c_wdt_u8);
+/*!
+ * @brief This API read I2C watchdog enable
+ * from the register 0x70 bit 2
+ *
+ * @param v_i2c_wdt_u8 : The value of I2C watchdog enable
+ * Value | Description
+ * --------|-------------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_i2c_wdt_enable(
+u8 *v_i2c_wdt_u8);
+/*!
+ * @brief This API write I2C watchdog enable
+ * from the register 0x70 bit 2
+ *
+ * @param v_i2c_wdt_u8 : The value of I2C watchdog enable
+ * Value | Description
+ * --------|-------------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_i2c_wdt_enable(
+u8 v_i2c_wdt_u8);
+/***************************************************/
+/**\name FUNCTION FOR IF MODE*/
+/***************************************************/
+/*!
+ * @brief This API read I2C interface configuration(if) moe
+ * from the register 0x6B bit 4 and 5
+ *
+ * @param v_if_mode_u8 : The value of interface configuration mode
+ * Value | Description
+ * --------|-------------
+ * 0x00 | Primary interface:autoconfig / secondary interface:off
+ * 0x01 | Primary interface:I2C / secondary interface:OIS
+ * 0x02 | Primary interface:autoconfig/secondary interface:Magnetometer
+ * 0x03 | Reserved
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_if_mode(
+u8 *v_if_mode_u8);
+/*!
+ * @brief This API write I2C interface configuration(if) moe
+ * from the register 0x6B bit 4 and 5
+ *
+ * @param v_if_mode_u8 : The value of interface configuration mode
+ * Value | Description
+ * --------|-------------
+ * 0x00 | Primary interface:autoconfig / secondary interface:off
+ * 0x01 | Primary interface:I2C / secondary interface:OIS
+ * 0x02 | Primary interface:autoconfig/secondary interface:Magnetometer
+ * 0x03 | Reserved
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_if_mode(
+u8 v_if_mode_u8);
+/***************************************************/
+/**\name FUNCTION FOR GYRO SLEEP TRIGGER INTERRUPT CONFIGURATION*/
+/***************************************************/
+/*!
+ * @brief This API read gyro sleep trigger
+ * from the register 0x6C bit 0 to 2
+ *
+ * @param v_gyro_sleep_trigger_u8 : The value of gyro sleep trigger
+ * Value | Description
+ * --------|-------------
+ * 0x00 | nomotion: no / Not INT1 pin: no / INT2 pin: no
+ * 0x01 | nomotion: no / Not INT1 pin: no / INT2 pin: yes
+ * 0x02 | nomotion: no / Not INT1 pin: yes / INT2 pin: no
+ * 0x03 | nomotion: no / Not INT1 pin: yes / INT2 pin: yes
+ * 0x04 | nomotion: yes / Not INT1 pin: no / INT2 pin: no
+ * 0x05 | anymotion: yes / Not INT1 pin: no / INT2 pin: yes
+ * 0x06 | anymotion: yes / Not INT1 pin: yes / INT2 pin: no
+ * 0x07 | anymotion: yes / Not INT1 pin: yes / INT2 pin: yes
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_sleep_trigger(
+u8 *v_gyro_sleep_trigger_u8);
+/*!
+ * @brief This API write gyro sleep trigger
+ * from the register 0x6C bit 0 to 2
+ *
+ * @param v_gyro_sleep_trigger_u8 : The value of gyro sleep trigger
+ * Value | Description
+ * --------|-------------
+ * 0x00 | nomotion: no / Not INT1 pin: no / INT2 pin: no
+ * 0x01 | nomotion: no / Not INT1 pin: no / INT2 pin: yes
+ * 0x02 | nomotion: no / Not INT1 pin: yes / INT2 pin: no
+ * 0x03 | nomotion: no / Not INT1 pin: yes / INT2 pin: yes
+ * 0x04 | nomotion: yes / Not INT1 pin: no / INT2 pin: no
+ * 0x05 | anymotion: yes / Not INT1 pin: no / INT2 pin: yes
+ * 0x06 | anymotion: yes / Not INT1 pin: yes / INT2 pin: no
+ * 0x07 | anymotion: yes / Not INT1 pin: yes / INT2 pin: yes
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_sleep_trigger(
+u8 v_gyro_sleep_trigger_u8);
+/*!
+ * @brief This API read gyro wakeup trigger
+ * from the register 0x6C bit 3 and 4
+ *
+ * @param v_gyro_wakeup_trigger_u8 : The value of gyro wakeup trigger
+ * Value | Description
+ * --------|-------------
+ * 0x00 | anymotion: no / INT1 pin: no
+ * 0x01 | anymotion: no / INT1 pin: yes
+ * 0x02 | anymotion: yes / INT1 pin: no
+ * 0x03 | anymotion: yes / INT1 pin: yes
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_wakeup_trigger(
+u8 *v_gyro_wakeup_trigger_u8);
+/*!
+ * @brief This API write gyro wakeup trigger
+ * from the register 0x6C bit 3 and 4
+ *
+ * @param v_gyro_wakeup_trigger_u8 : The value of gyro wakeup trigger
+ * Value | Description
+ * --------|-------------
+ * 0x00 | anymotion: no / INT1 pin: no
+ * 0x01 | anymotion: no / INT1 pin: yes
+ * 0x02 | anymotion: yes / INT1 pin: no
+ * 0x03 | anymotion: yes / INT1 pin: yes
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_wakeup_trigger(
+u8 v_gyro_wakeup_trigger_u8);
+/*!
+ * @brief This API read Target state for gyro sleep mode
+ * from the register 0x6C bit 5
+ *
+ * @param v_gyro_sleep_state_u8 : The value of gyro sleep mode
+ * Value | Description
+ * --------|-------------
+ * 0x00 | Sleep transition to fast wake up state
+ * 0x01 | Sleep transition to suspend state
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_sleep_state(
+u8 *v_gyro_sleep_state_u8);
+/*!
+ * @brief This API write Target state for gyro sleep mode
+ * from the register 0x6C bit 5
+ *
+ * @param v_gyro_sleep_state_u8 : The value of gyro sleep mode
+ * Value | Description
+ * --------|-------------
+ * 0x00 | Sleep transition to fast wake up state
+ * 0x01 | Sleep transition to suspend state
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_sleep_state(
+u8 v_gyro_sleep_state_u8);
+/*!
+ * @brief This API read gyro wakeup interrupt
+ * from the register 0x6C bit 6
+ *
+ * @param v_gyro_wakeup_intr_u8 : The valeu of gyro wakeup interrupt
+ * Value | Description
+ * --------|-------------
+ * 0x00 | DISABLE
+ * 0x01 | ENABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_wakeup_intr(
+u8 *v_gyro_wakeup_intr_u8);
+/*!
+ * @brief This API write gyro wakeup interrupt
+ * from the register 0x6C bit 6
+ *
+ * @param v_gyro_wakeup_intr_u8 : The valeu of gyro wakeup interrupt
+ * Value | Description
+ * --------|-------------
+ * 0x00 | DISABLE
+ * 0x01 | ENABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_wakeup_intr(
+u8 v_gyro_wakeup_intr_u8);
+/***************************************************/
+/**\name FUNCTION FOR ACCEL SELF TEST */
+/***************************************************/
+/*!
+ * @brief This API read accel select axis to be self-test
+ *
+ * @param v_accel_selftest_axis_u8 :
+ * The value of accel self test axis selection
+ * Value | Description
+ * --------|-------------
+ * 0x00 | disabled
+ * 0x01 | x-axis
+ * 0x02 | y-axis
+ * 0x03 | z-axis
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_selftest_axis(
+u8 *acc_selftest_axis);
+/*!
+ * @brief This API write accel select axis to be self-test
+ *
+ * @param v_accel_selftest_axis_u8 :
+ * The value of accel self test axis selection
+ * Value | Description
+ * --------|-------------
+ * 0x00 | disabled
+ * 0x01 | x-axis
+ * 0x02 | y-axis
+ * 0x03 | z-axis
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_selftest_axis(
+u8 acc_selftest_axis);
+/*!
+ * @brief This API read accel self test axis sign
+ * from the register 0x6D bit 2
+ *
+ * @param v_accel_selftest_sign_u8: The value of accel self test axis sign
+ * Value | Description
+ * --------|-------------
+ * 0x00 | negative
+ * 0x01 | positive
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_selftest_sign(
+u8 *acc_selftest_sign);
+/*!
+ * @brief This API write accel self test axis sign
+ * from the register 0x6D bit 2
+ *
+ * @param v_accel_selftest_sign_u8: The value of accel self test axis sign
+ * Value | Description
+ * --------|-------------
+ * 0x00 | negative
+ * 0x01 | positive
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_selftest_sign(
+u8 acc_selftest_sign);
+/*!
+ * @brief This API read accel self test amplitude
+ * from the register 0x6D bit 3
+ * select amplitude of the selftest deflection:
+ *
+ * @param v_accel_selftest_amp_u8 : The value of accel self test amplitude
+ * Value | Description
+ * --------|-------------
+ * 0x00 | LOW
+ * 0x01 | HIGH
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_selftest_amp(
+u8 *acc_selftest_amp);
+/*!
+ * @brief This API write accel self test amplitude
+ * from the register 0x6D bit 3
+ * select amplitude of the selftest deflection:
+ *
+ * @param v_accel_selftest_amp_u8 : The value of accel self test amplitude
+ * Value | Description
+ * --------|-------------
+ * 0x00 | LOW
+ * 0x01 | HIGH
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_selftest_amp(
+u8 acc_selftest_amp);
+/***************************************************/
+/**\name FUNCTION FOR GYRO SELF TEST */
+/***************************************************/
+/*!
+ * @brief This API read gyro self test trigger
+ *
+ * @param v_gyro_selftest_start_u8: The value of gyro self test start
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_selftest_start(
+u8 *v_gyro_selftest_start_u8);
+/*!
+ * @brief This API write gyro self test trigger
+ *
+ * @param v_gyro_selftest_start_u8: The value of gyro self test start
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_selftest_start(
+u8 v_gyro_selftest_start_u8);
+/***************************************************/
+/**\name FUNCTION FOR SPI/I2C ENABLE */
+/***************************************************/
+ /*!
+ * @brief This API read primary interface selection I2C or SPI
+ * from the register 0x70 bit 0
+ *
+ * @param v_spi_enable_u8: The value of Interface selection
+ * Value | Description
+ * --------|-------------
+ * 0x00 | I2C Enable
+ * 0x01 | I2C DISBALE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_spi_enable(
+u8 *v_spi_enable_u8);
+ /*!
+ * @brief This API write primary interface selection I2C or SPI
+ * from the register 0x70 bit 0
+ *
+ * @param v_spi_enable_u8: The value of Interface selection
+ * Value | Description
+ * --------|-------------
+ * 0x00 | I2C Enable
+ * 0x01 | I2C DISBALE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_spi_enable(
+u8 v_spi_enable_u8);
+ /*!
+ * @brief This API read the spare zero
+ * form register 0x70 bit 3
+ *
+ *
+ * @param v_spare0_trim_u8: The value of spare zero
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_spare0_trim
+(u8 *v_spare0_trim_u8);
+ /*!
+ * @brief This API write the spare zero
+ * form register 0x70 bit 3
+ *
+ *
+ * @param v_spare0_trim_u8: The value of spare zero
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_spare0_trim
+(u8 v_spare0_trim_u8);
+/***************************************************/
+/**\name FUNCTION FOR NVM COUNTER */
+/***************************************************/
+ /*!
+ * @brief This API read the NVM counter
+ * form register 0x70 bit 4 to 7
+ *
+ *
+ * @param v_nvm_counter_u8: The value of NVM counter
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_nvm_counter(
+u8 *v_nvm_counter_u8);
+ /*!
+ * @brief This API write the NVM counter
+ * form register 0x70 bit 4 to 7
+ *
+ *
+ * @param v_nvm_counter_u8: The value of NVM counter
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_nvm_counter(
+u8 v_nvm_counter_u8);
+/***************************************************/
+/**\name FUNCTION FOR ACCEL MANUAL OFFSET COMPENSATION */
+/***************************************************/
+/*!
+ * @brief This API read accel manual offset compensation of x axis
+ * from the register 0x71 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_x_s8:
+ * The value of accel manual offset compensation of x axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_offset_compensation_xaxis(
+s8 *v_accel_off_x_s8);
+/*!
+ * @brief This API write accel manual offset compensation of x axis
+ * from the register 0x71 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_x_s8:
+ * The value of accel manual offset compensation of x axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_offset_compensation_xaxis(
+s8 v_accel_off_x_s8);
+/*!
+ * @brief This API read accel manual offset compensation of y axis
+ * from the register 0x72 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_y_s8:
+ * The value of accel manual offset compensation of y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_offset_compensation_yaxis(
+s8 *v_accel_off_y_s8);
+/*!
+ * @brief This API write accel manual offset compensation of y axis
+ * from the register 0x72 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_y_s8:
+ * The value of accel manual offset compensation of y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_offset_compensation_yaxis(
+s8 v_accel_off_y_s8);
+/*!
+ * @brief This API read accel manual offset compensation of z axis
+ * from the register 0x73 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_z_s8:
+ * The value of accel manual offset compensation of z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_offset_compensation_zaxis(
+s8 *v_accel_off_z_s8);
+/*!
+ * @brief This API write accel manual offset compensation of z axis
+ * from the register 0x73 bit 0 to 7
+ *
+ *
+ *
+ * @param v_accel_off_z_s8:
+ * The value of accel manual offset compensation of z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_offset_compensation_zaxis(
+s8 v_accel_off_z_s8);
+/***************************************************/
+/**\name FUNCTION FOR GYRO MANUAL OFFSET COMPENSATION */
+/***************************************************/
+/*!
+ * @brief This API read gyro manual offset compensation of x axis
+ * from the register 0x74 bit 0 to 7 and 0x77 bit 0 and 1
+ *
+ *
+ *
+ * @param v_gyro_off_x_s16:
+ * The value of gyro manual offset compensation of x axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_offset_compensation_xaxis(
+s16 *v_gyro_off_x_s16);
+/*!
+ * @brief This API write gyro manual offset compensation of x axis
+ * from the register 0x74 bit 0 to 7 and 0x77 bit 0 and 1
+ *
+ *
+ *
+ * @param v_gyro_off_x_s16:
+ * The value of gyro manual offset compensation of x axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_offset_compensation_xaxis(
+s16 v_gyro_off_x_s16);
+/*!
+ * @brief This API read gyro manual offset compensation of y axis
+ * from the register 0x75 bit 0 to 7 and 0x77 bit 2 and 3
+ *
+ *
+ *
+ * @param v_gyro_off_y_s16:
+ * The value of gyro manual offset compensation of y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_offset_compensation_yaxis(
+s16 *v_gyro_off_y_s16);
+/*!
+ * @brief This API write gyro manual offset compensation of y axis
+ * from the register 0x75 bit 0 to 7 and 0x77 bit 2 and 3
+ *
+ *
+ *
+ * @param v_gyro_off_y_s16:
+ * The value of gyro manual offset compensation of y axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_offset_compensation_yaxis(
+s16 v_gyro_off_y_s16);
+/*!
+ * @brief This API read gyro manual offset compensation of z axis
+ * from the register 0x76 bit 0 to 7 and 0x77 bit 4 and 5
+ *
+ *
+ *
+ * @param v_gyro_off_z_s16:
+ * The value of gyro manual offset compensation of z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_offset_compensation_zaxis(
+s16 *v_gyro_off_z_s16);
+/*!
+ * @brief This API write gyro manual offset compensation of z axis
+ * from the register 0x76 bit 0 to 7 and 0x77 bit 4 and 5
+ *
+ *
+ *
+ * @param v_gyro_off_z_s16:
+ * The value of gyro manual offset compensation of z axis
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_offset_compensation_zaxis(
+s16 v_gyro_off_z_s16);
+/*!
+ * @brief This API writes accel fast offset compensation
+ * from the register 0x69 bit 0 to 5
+ * @brief This API writes each axis individually
+ * FOC_X_AXIS - bit 4 and 5
+ * FOC_Y_AXIS - bit 2 and 3
+ * FOC_Z_AXIS - bit 0 and 1
+ *
+ * @param v_foc_accel_u8: The value of accel offset compensation
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @param v_axis_u8: The value of accel offset axis selection
+ * value | axis
+ * ----------|-------------------
+ * 0 | FOC_X_AXIS
+ * 1 | FOC_Y_AXIS
+ * 2 | FOC_Z_AXIS
+ *
+ * @param v_accel_offset_s8: The accel offset value
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_foc_trigger(u8 axis,
+u8 foc_acc, s8 *accel_offset);
+/*!
+ * @brief This API write fast accel offset compensation
+ * it writes all axis together.To the register 0x69 bit 0 to 5
+ * FOC_X_AXIS - bit 4 and 5
+ * FOC_Y_AXIS - bit 2 and 3
+ * FOC_Z_AXIS - bit 0 and 1
+ *
+ * @param v_foc_accel_x_u8: The value of accel offset x compensation
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @param v_foc_accel_y_u8: The value of accel offset y compensation
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @param v_foc_accel_z_u8: The value of accel offset z compensation
+ * value | Behaviour
+ * ----------|-------------------
+ * 0x00 | disable
+ * 0x01 | +1g
+ * 0x01 | -1g
+ * 0x01 | 0g
+ *
+ * @param v_accel_off_x_s8: The value of accel offset x axis
+ * @param v_accel_off_y_s8: The value of accel offset y axis
+ * @param v_accel_off_z_s8: The value of accel offset z axis
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_accel_foc_trigger_xyz(u8 v_foc_accel_x_u8,
+u8 v_foc_accel_y_u8, u8 v_foc_accel_z_u8,
+s8 *acc_off_x, s8 *acc_off_y, s8 *acc_off_z);
+/***************************************************/
+/**\name FUNCTION FOR ACEL AND GYRO OFFSET ENABLE */
+/***************************************************/
+/*!
+ * @brief This API read the accel offset enable bit
+ * from the register 0x77 bit 6
+ *
+ *
+ *
+ * @param v_accel_off_enable_u8: The value of accel offset enable
+ * value | Description
+ * ----------|--------------
+ * 0x01 | ENABLE
+ * 0x00 | DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_accel_offset_enable(
+u8 *acc_off_en);
+/*!
+ * @brief This API write the accel offset enable bit
+ * from the register 0x77 bit 6
+ *
+ *
+ *
+ * @param v_accel_off_enable_u8: The value of accel offset enable
+ * value | Description
+ * ----------|--------------
+ * 0x01 | ENABLE
+ * 0x00 | DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_accel_offset_enable(
+u8 acc_off_en);
+/*!
+ * @brief This API read the accel offset enable bit
+ * from the register 0x77 bit 7
+ *
+ *
+ *
+ * @param v_gyro_off_enable_u8: The value of gyro offset enable
+ * value | Description
+ * ----------|--------------
+ * 0x01 | ENABLE
+ * 0x00 | DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_gyro_offset_enable(
+u8 *v_gyro_off_enable_u8);
+/*!
+ * @brief This API write the accel offset enable bit
+ * from the register 0x77 bit 7
+ *
+ *
+ *
+ * @param v_gyro_off_enable_u8: The value of gyro offset enable
+ * value | Description
+ * ----------|--------------
+ * 0x01 | ENABLE
+ * 0x00 | DISABLE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_gyro_offset_enable(
+u8 v_gyro_off_enable_u8);
+/***************************************************/
+/**\name FUNCTION FOR STEP COUNTER INTERRUPT */
+/***************************************************/
+/*!
+ * @brief This API reads step counter value
+ * form the register 0x78 and 0x79
+ *
+ *
+ *
+ *
+ * @param v_step_cnt_s16 : The value of step counter
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_read_step_count(u16 *v_step_cnt_s16);
+ /*!
+ * @brief This API Reads
+ * step counter configuration
+ * from the register 0x7A bit 0 to 7
+ * and from the register 0x7B bit 0 to 2 and 4 to 7
+ *
+ *
+ * @param v_step_config_u16 : The value of step configuration
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_step_config(
+u16 *v_step_config_u16);
+ /*!
+ * @brief This API write
+ * step counter configuration
+ * from the register 0x7A bit 0 to 7
+ * and from the register 0x7B bit 0 to 2 and 4 to 7
+ *
+ *
+ * @param v_step_config_u16 :
+ * the value of Enable step configuration
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_step_config(
+u16 v_step_config_u16);
+ /*!
+ * @brief This API read enable step counter
+ * from the register 0x7B bit 3
+ *
+ *
+ * @param v_step_counter_u8 : The value of step counter enable
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_step_counter_enable(
+u8 *v_step_counter_u8);
+ /*!
+ * @brief This API write enable step counter
+ * from the register 0x7B bit 3
+ *
+ *
+ * @param v_step_counter_u8 : The value of step counter enable
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_step_counter_enable(
+u8 v_step_counter_u8);
+ /*!
+ * @brief This API set Step counter modes
+ *
+ *
+ * @param v_step_mode_u8 : The value of step counter mode
+ * value | mode
+ * ----------|-----------
+ * 0 | SMI130_STEP_NORMAL_MODE
+ * 1 | SMI130_STEP_SENSITIVE_MODE
+ * 2 | SMI130_STEP_ROBUST_MODE
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_step_mode(u8 v_step_mode_u8);
+/*!
+ * @brief This API used to trigger the signification motion
+ * interrupt
+ *
+ *
+ * @param v_significant_u8 : The value of interrupt selection
+ * value | interrupt
+ * ----------|-----------
+ * 0 | SMI130_MAP_INTR1
+ * 1 | SMI130_MAP_INTR2
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_map_significant_motion_intr(
+u8 v_significant_u8);
+/*!
+ * @brief This API used to trigger the step detector
+ * interrupt
+ *
+ *
+ * @param v_step_detector_u8 : The value of interrupt selection
+ * value | interrupt
+ * ----------|-----------
+ * 0 | SMI130_MAP_INTR1
+ * 1 | SMI130_MAP_INTR2
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_map_step_detector_intr(
+u8 v_step_detector_u8);
+ /*!
+ * @brief This API used to clear the step counter interrupt
+ * interrupt
+ *
+ *
+ * @param : None
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_clear_step_counter(void);
+/***************************************************/
+/**\name FUNCTION FOR STEP COMMAND REGISTER WRITE */
+/***************************************************/
+ /*!
+ * @brief This API writes value to the register 0x7E bit 0 to 7
+ *
+ *
+ * @param v_command_reg_u8 : The value to write command register
+ * value | Description
+ * ---------|--------------------------------------------------------
+ * 0x00 | Reserved
+ * 0x03 | Starts fast offset calibration for the accel and gyro
+ * 0x10 | Sets the PMU mode for the Accelerometer to suspend
+ * 0x11 | Sets the PMU mode for the Accelerometer to normal
+ * 0x12 | Sets the PMU mode for the Accelerometer Lowpower
+ * 0x14 | Sets the PMU mode for the Gyroscope to suspend
+ * 0x15 | Sets the PMU mode for the Gyroscope to normal
+ * 0x16 | Reserved
+ * 0x17 | Sets the PMU mode for the Gyroscope to fast start-up
+ * 0x18 | Sets the PMU mode for the Magnetometer to suspend
+ * 0x19 | Sets the PMU mode for the Magnetometer to normal
+ * 0x1A | Sets the PMU mode for the Magnetometer to Lowpower
+ * 0xB0 | Clears all data in the FIFO
+ * 0xB1 | Resets the interrupt engine
+ * 0xB2 | step_cnt_clr Clears the step counter
+ * 0xB6 | Triggers a reset
+ * 0x37 | See extmode_en_last
+ * 0x9A | See extmode_en_last
+ * 0xC0 | Enable the extended mode
+ * 0xC4 | Erase NVM cell
+ * 0xC8 | Load NVM cell
+ * 0xF0 | Reset acceleration data path
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_command_register(
+u8 v_command_reg_u8);
+/***************************************************/
+/**\name FUNCTION FOR PAGE ENABLE */
+/***************************************************/
+ /*!
+ * @brief This API read target page from the register 0x7F bit 4 and 5
+ *
+ * @param v_target_page_u8: The value of target page
+ * value | page
+ * ---------|-----------
+ * 0 | User data/configure page
+ * 1 | Chip level trim/test page
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_target_page(
+u8 *v_target_page_u8);
+ /*!
+ * @brief This API write target page from the register 0x7F bit 4 and 5
+ *
+ * @param v_target_page_u8: The value of target page
+ * value | page
+ * ---------|-----------
+ * 0 | User data/configure page
+ * 1 | Chip level trim/test page
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_target_page(
+u8 v_target_page_u8);
+ /*!
+ * @brief This API read page enable from the register 0x7F bit 7
+ *
+ *
+ *
+ * @param v_page_enable_u8: The value of page enable
+ * value | page
+ * ---------|-----------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_paging_enable(
+u8 *v_page_enable_u8);
+ /*!
+ * @brief This API write page enable from the register 0x7F bit 7
+ *
+ *
+ *
+ * @param v_page_enable_u8: The value of page enable
+ * value | page
+ * ---------|-----------
+ * 0 | DISABLE
+ * 1 | ENABLE
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_paging_enable(
+u8 v_page_enable_u8);
+ /*!
+ * @brief This API read
+ * pull up configuration from the register 0X85 bit 4 an 5
+ *
+ *
+ *
+ * @param v_control_pullup_u8: The value of pull up register
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_get_pullup_configuration(
+u8 *v_control_pullup_u8);
+ /*!
+ * @brief This API write
+ * pull up configuration from the register 0X85 bit 4 an 5
+ *
+ *
+ *
+ * @param v_control_pullup_u8: The value of pull up register
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_pullup_configuration(
+u8 v_control_pullup_u8);
+/***************************************************/
+/**\name FUNCTION FOR BMM150 */
+/***************************************************/
+ /*!
+ * @brief This function used for initialize the bmm150 sensor
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bmm150_mag_interface_init(void);
+ /*!
+ * @brief This function used for set the mag power control
+ * bit enable
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bmm150_mag_wakeup(void);
+ /*!
+ * @brief This function used for read the trim values of magnetometer
+ *
+ * @note
+ * Before reading the mag trimming values
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_bmm150_mag_trim(void);
+ /*!
+ * @brief This function used for read the compensated value of mag
+ * Before start reading the mag compensated data's
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bmm150_mag_compensate_xyz(
+struct smi130_mag_xyz_s32_t *mag_comp_xyz);
+SMI130_RETURN_FUNCTION_TYPE smi130_bmm150_mag_compensate_xyz_raw(
+struct smi130_mag_xyz_s32_t *mag_comp_xyz, struct smi130_mag_xyzr_t mag_xyzr);
+
+/*!
+ * @brief This API used to get the compensated BMM150-X data
+ * the out put of X as s32
+ * Before start reading the mag compensated X data
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ *
+ * @param v_mag_data_x_s16 : The value of mag raw X data
+ * @param v_data_r_u16 : The value of mag R data
+ *
+ * @return results of compensated X data value output as s32
+ *
+ */
+s32 smi130_bmm150_mag_compensate_X(s16 v_mag_data_x_s16, u16 v_data_r_u16);
+/*!
+ * @brief This API used to get the compensated BMM150-Y data
+ * the out put of Y as s32
+ * Before start reading the mag compensated Y data
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ *
+ * @param v_mag_data_y_s16 : The value of mag raw Y data
+ * @param v_data_r_u16 : The value of mag R data
+ *
+ * @return results of compensated Y data value output as s32
+ */
+s32 smi130_bmm150_mag_compensate_Y(s16 v_mag_data_y_s16, u16 v_data_r_u16);
+/*!
+ * @brief This API used to get the compensated BMM150-Z data
+ * the out put of Z as s32
+ * Before start reading the mag compensated Z data
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ *
+ * @param v_mag_data_z_s16 : The value of mag raw Z data
+ * @param v_data_r_u16 : The value of mag R data
+ *
+ * @return results of compensated Z data value output as s32
+ */
+s32 smi130_bmm150_mag_compensate_Z(s16 v_mag_data_z_s16, u16 v_data_r_u16);
+/*!
+ * @brief This API used to set the pre-set modes of bmm150
+ * The pre-set mode setting is depend on data rate and xy and z repetitions
+ *
+ * @note
+ * Before set the mag preset mode
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ * @param v_mode_u8: The value of pre-set mode selection value
+ * value | pre_set mode
+ * ----------|------------
+ * 1 | SMI130_MAG_PRESETMODE_LOWPOWER
+ * 2 | SMI130_MAG_PRESETMODE_REGULAR
+ * 3 | SMI130_MAG_PRESETMODE_HIGHACCURACY
+ * 4 | SMI130_MAG_PRESETMODE_ENHANCED
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_set_bmm150_mag_presetmode(u8 mode);
+/*!
+ * @brief This function used for set the magnetometer
+ * power mode.
+ * @note
+ * Before set the mag power mode
+ * make sure the following two points are addressed
+ * @note
+ * 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note
+ * 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ * @param v_mag_pow_mode_u8 : The value of mag power mode
+ * value | mode
+ * ----------|------------
+ * 0 | FORCE_MODE
+ * 1 | SUSPEND_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bmm150_mag_set_power_mode(u8 mag_pow_mode);
+ /*!
+ * @brief This function used for set the magnetometer
+ * power mode.
+ * @note
+ * Before set the mag power mode
+ * make sure the following two point is addressed
+ * Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ *
+ * @param v_mag_sec_if_pow_mode_u8 : The value of mag power mode
+ * value | mode
+ * ----------|------------
+ * 0 | SMI130_MAG_FORCE_MODE
+ * 1 | SMI130_MAG_SUSPEND_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_bmm150_mag_and_secondary_if_power_mode(
+u8 v_mag_sec_if_pow_mode_u8);
+/***************************************************/
+/**\name FUNCTIONS FOR AKM09911 AND AKM09912*/
+/***************************************************/
+ /*!
+ * @brief This function used for initialize
+ * the AKM09911 and AKM09912 sensor
+ *
+ *
+ * @param v_akm_i2c_address_u8: The value of device address
+ * AKM sensor | Slave address
+ * --------------|---------------------
+ * AKM09911 | AKM09911_I2C_ADDR_1
+ * - | and AKM09911_I2C_ADDR_2
+ * AKM09912 | AKM09912_I2C_ADDR_1
+ * - | AKM09912_I2C_ADDR_2
+ * - | AKM09912_I2C_ADDR_3
+ * - | AKM09912_I2C_ADDR_4
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_akm_mag_interface_init(
+u8 v_akm_i2c_address_u8);
+ /*!
+ * @brief This function used for read the sensitivity data of
+ * AKM09911 and AKM09912
+ *
+ * @note Before reading the mag sensitivity values
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_read_bosch_akm_sensitivity_data(void);
+/*!
+ * @brief This API used to get the compensated X data
+ * of AKM09911 the out put of X as s32
+ * @note Before start reading the mag compensated X data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bosch_akm_x_s16 : The value of X data
+ *
+ * @return results of compensated X data value output as s32
+ *
+ */
+s32 smi130_bosch_akm09911_compensate_X(s16 v_bosch_akm_x_s16);
+/*!
+ * @brief This API used to get the compensated Y data
+ * of AKM09911 the out put of Y as s32
+ * @note Before start reading the mag compensated Y data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bosch_akm_y_s16 : The value of Y data
+ *
+ * @return results of compensated Y data value output as s32
+ *
+ */
+s32 smi130_bosch_akm09911_compensate_Y(s16 v_bosch_akm_y_s16);
+/*!
+ * @brief This API used to get the compensated Z data
+ * of AKM09911 the out put of Z as s32
+ * @note Before start reading the mag compensated Z data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bosch_akm_z_s16 : The value of Z data
+ *
+ * @return results of compensated Z data value output as s32
+ *
+ */
+s32 smi130_bosch_akm09911_compensate_Z(s16 v_bosch_akm_z_s16);
+/*!
+ * @brief This API used to get the compensated X data
+ * of AKM09912 the out put of X as s32
+ * @note Before start reading the mag compensated X data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bosch_akm_x_s16 : The value of X data
+ *
+ * @return results of compensated X data value output as s32
+ *
+ */
+s32 smi130_bosch_akm09912_compensate_X(s16 v_bosch_akm_x_s16);
+/*!
+ * @brief This API used to get the compensated Y data
+ * of AKM09912 the out put of Y as s32
+ * @note Before start reading the mag compensated Y data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bosch_akm_y_s16 : The value of Y data
+ *
+ * @return results of compensated Y data value output as s32
+ *
+ */
+s32 smi130_bosch_akm09912_compensate_Y(s16 v_bosch_akm_y_s16);
+/*!
+ * @brief This API used to get the compensated Z data
+ * of AKM09912 the out put of Z as s32
+ * @note Before start reading the mag compensated Z data
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ *
+ * @param v_bosch_akm_z_s16 : The value of Z data
+ *
+ * @return results of compensated Z data value output as s32
+ *
+ */
+s32 smi130_bosch_akm09912_compensate_Z(s16 v_bosch_akm_z_s16);
+ /*!
+ * @brief This function used for read the compensated value of
+ * AKM09911
+ * @note Before start reading the mag compensated data's
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_akm09911_compensate_xyz(
+struct smi130_mag_xyz_s32_t *bosch_akm_xyz);
+ /*!
+ * @brief This function used for read the compensated value of
+ * AKM09912
+ * @note Before start reading the mag compensated data's
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_akm09912_compensate_xyz(
+struct smi130_mag_xyz_s32_t *bosch_akm_xyz);
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_akm09912_compensate_xyz_raw(
+struct smi130_mag_xyz_s32_t *bosch_akm_xyz);
+/*!
+ * @brief This function used for set the AKM09911 and AKM09912
+ * power mode.
+ * @note Before set the AKM power mode
+ * make sure the following two points are addressed
+ * @note 1. Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ * @note 2. And also confirm the secondary-interface power mode
+ * is not in the SUSPEND mode.
+ * by using the function smi130_get_mag_pmu_status().
+ * If the secondary-interface power mode is in SUSPEND mode
+ * set the value of 0x19(NORMAL mode)by using the
+ * smi130_set_command_register(0x19) function.
+ *
+ * @param v_akm_pow_mode_u8 : The value of akm power mode
+ * value | Description
+ * ---------|--------------------
+ * 0 | AKM_POWER_DOWN_MODE
+ * 1 | AKM_SINGLE_MEAS_MODE
+ * 2 | FUSE_ROM_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_akm_set_powermode(u8 v_akm_pow_mode_u8);
+ /*!
+ * @brief This function used for set the magnetometer
+ * power mode of AKM09911 and AKM09912
+ * @note Before set the mag power mode
+ * make sure the following two point is addressed
+ * Make sure the mag interface is enabled or not,
+ * by using the smi130_get_if_mode() function.
+ * If mag interface is not enabled set the value of 0x02
+ * to the function smi130_get_if_mode(0x02)
+ *
+ * @param v_mag_sec_if_pow_mode_u8 : The value of secondary if power mode
+ * value | Description
+ * ---------|--------------------
+ * 0 | SMI130_MAG_FORCE_MODE
+ * 1 | SMI130_MAG_SUSPEND_MODE
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_set_bosch_akm_and_secondary_if_powermode(
+u8 v_mag_sec_if_pow_mode_u8);
+/***************************************************/
+/**\name FUNCTIONS FOR YAMAH-YAS532 */
+/***************************************************/
+/*!
+ * @brief This function used for read the YAMAH-YAS532 init
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yamaha_yas532_mag_interface_init(
+void);
+/*!
+ * @brief This function used to set the YAS532 initial values
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas532_set_initial_values(void);
+/*!
+ * @brief This function used for YAS532 offset correction
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas532_magnetic_measure_set_offset(
+void);
+/*!
+ * @brief This function used for read the
+ * YAMAHA YAS532 calibration data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yamaha_yas532_calib_values(void);
+/*!
+ * @brief This function used for calculate the
+ * YAS532 read the linear data
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas532_xy1y2_to_linear(
+u16 *v_xy1y2_u16, s32 *xy1y2_linear);
+/*!
+ * @brief This function used for read the YAS532 sensor data
+ * @param v_acquisition_command_u8: used to set the data acquisition
+ * acquisition_command | operation
+ * ---------------------|-------------------------
+ * 0x17 | turn on the acquisition coil
+ * - | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Deferred acquisition mode
+ * 0x07 | turn on the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Normal acquisition mode
+ * 0x11 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Deferred acquisition mode
+ * 0x01 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Normal acquisition mode
+ *
+ * @param v_busy_u8 : used to get the busy flay for sensor data read
+ * @param v_temp_u16 : used to get the temperature data
+ * @param v_xy1y2_u16 : used to get the sensor xy1y2 data
+ * @param v_overflow_u8 : used to get the overflow data
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas532_normal_measurement_data(
+u8 v_acquisition_command_u8, u8 *v_busy_u8,
+u16 *v_temp_u16, u16 *v_xy1y2_u16, u8 *v_overflow_u8);
+/*!
+ * @brief This function used for YAS532 sensor data
+ * @param v_acquisition_command_u8 : the value of CMDR
+ * acquisition_command | operation
+ * ---------------------|-------------------------
+ * 0x17 | turn on the acquisition coil
+ * - | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Deferred acquisition mode
+ * 0x07 | turn on the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Normal acquisition mode
+ * 0x11 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Deferred acquisition mode
+ * 0x01 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Normal acquisition mode
+ *
+ * @param xyz_data : the vector xyz output
+ * @param v_overflow_s8 : the value of overflow
+ * @param v_temp_correction_u8 : the value of temperate correction enable
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas532_measurement_xyz_data(
+struct yas532_vector *xyz_data, u8 *v_overflow_s8, u8 v_temp_correction_u8,
+u8 v_acquisition_command_u8);
+/*!
+ * @brief This function used for YAS532 write data acquisition
+ * command register write
+ * @param v_command_reg_data_u8 : the value of data acquisition
+ * acquisition_command | operation
+ * ---------------------|-------------------------
+ * 0x17 | turn on the acquisition coil
+ * - | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Deferred acquisition mode
+ * 0x07 | turn on the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Normal acquisition mode
+ * 0x11 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Deferred acquisition mode
+ * 0x01 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Normal acquisition mode
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas532_acquisition_command_register(
+u8 v_command_reg_data_u8);
+/*!
+ * @brief This function used write offset of YAS532
+ *
+ * @param p_offset_s8 : The value of offset to write
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas532_set_offset(
+const s8 *p_offset_s8);
+/*!
+ * @brief This function used to init the YAMAH-YAS537
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+*/
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yamaha_yas537_mag_interface_init(
+void);
+/*!
+ * @brief This function used for read the
+ * YAMAHA YAS537 calibration data
+ *
+ *
+ * @param v_rcoil_u8 : The value of r coil
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yamaha_yas537_calib_values(
+u8 v_rcoil_u8);
+/*!
+ * @brief This function used for YAS537 write data acquisition
+ * command register write
+ * @param v_command_reg_data_u8 : the value of data acquisition
+ * acquisition_command | operation
+ * ---------------------|-------------------------
+ * 0x17 | turn on the acquisition coil
+ * - | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Deferred acquisition mode
+ * 0x07 | turn on the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as minus(-))
+ * _ | Normal acquisition mode
+ * 0x11 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Deferred acquisition mode
+ * 0x01 | turn OFF the acquisition coil
+ * _ | set direction of the coil
+ * _ | (x and y as plus(+))
+ * _ | Normal acquisition mode
+ *
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yas537_acquisition_command_register(
+u8 v_command_reg_data_u8);
+
+/*!
+ * @brief This function used for read the
+ * YAMAHA YAS537 xy1y2 data
+ *
+ * @param v_coil_stat_u8: The value of R coil status
+ * @param v_busy_u8: The value of busy status
+ * @param v_temperature_u16: The value of temperature
+ * @param xy1y2: The value of raw xy1y2 data
+ * @param v_ouflow_u8: The value of overflow
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yamaha_yas537_read_xy1y2_data(
+u8 *v_coil_stat_u8, u8 *v_busy_u8,
+u16 *v_temperature_u16, u16 *xy1y2, u8 *v_ouflow_u8);
+/*!
+ * @brief This function used for read the
+ * YAMAHA YAS537 xy1y2 data
+ *
+ * @param v_ouflow_u8: The value of overflow
+ *
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_bosch_yamaha_yas537_measure_xyz_data(
+u8 *v_ouflow_u8, struct yas_vector *vector_xyz);
+
+/***************************************************/
+/**\name FUNCTIONS FOR FIFO DATA READ */
+/***************************************************/
+/*!
+ * @brief This function used for reading the
+ * fifo data of header less mode
+ *
+ *
+ *
+ * @note Configure the below functions for FIFO header less mode
+ * @note 1. smi130_set_fifo_down_gyro
+ * @note 2. smi130_set_gyro_fifo_filter_data
+ * @note 3. smi130_set_fifo_down_accel
+ * @note 4. smi130_set_accel_fifo_filter_dat
+ * @note 5. smi130_set_fifo_mag_enable
+ * @note 6. smi130_set_fifo_accel_enable
+ * @note 7. smi130_set_fifo_gyro_enable
+ * @note For interrupt configuration
+ * @note 1. smi130_set_intr_fifo_full
+ * @note 2. smi130_set_intr_fifo_wm
+ * @note 3. smi130_set_fifo_tag_intr2_enable
+ * @note 4. smi130_set_fifo_tag_intr1_enable
+ *
+ * @note The fifo reads the whole 1024 bytes
+ * and processing the data
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_read_fifo_headerless_mode(
+void);
+/*!
+ * @brief This function used for reading the
+ * fifo data of header less mode for using user defined length
+ *
+ *
+ * @param v_fifo_user_length_u16: The value of length of fifo read data
+ *
+ * @note Configure the below functions for FIFO header less mode
+ * @note 1. smi130_set_fifo_down_gyro
+ * @note 2. smi130_set_gyro_fifo_filter_data
+ * @note 3. smi130_set_fifo_down_accel
+ * @note 4. smi130_set_accel_fifo_filter_dat
+ * @note 5. smi130_set_fifo_mag_enable
+ * @note 6. smi130_set_fifo_accel_enable
+ * @note 7. smi130_set_fifo_gyro_enable
+ * @note For interrupt configuration
+ * @note 1. smi130_set_intr_fifo_full
+ * @note 2. smi130_set_intr_fifo_wm
+ * @note 3. smi130_set_fifo_tag_intr2_enable
+ * @note 4. smi130_set_fifo_tag_intr1_enable
+ *
+ * @note The fifo reads the whole 1024 bytes
+ * and processing the data
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE
+smi130_read_fifo_headerless_mode_user_defined_length(
+u16 v_fifo_user_length_u16);
+/*!
+ * @brief This function used for reading the
+ * fifo data of header mode
+ *
+ *
+ * @note Configure the below functions for FIFO header mode
+ * @note 1. smi130_set_fifo_down_gyro()
+ * @note 2. smi130_set_gyro_fifo_filter_data()
+ * @note 3. smi130_set_fifo_down_accel()
+ * @note 4. smi130_set_accel_fifo_filter_dat()
+ * @note 5. smi130_set_fifo_mag_enable()
+ * @note 6. smi130_set_fifo_accel_enable()
+ * @note 7. smi130_set_fifo_gyro_enable()
+ * @note 8. smi130_set_fifo_header_enable()
+ * @note For interrupt configuration
+ * @note 1. smi130_set_intr_fifo_full()
+ * @note 2. smi130_set_intr_fifo_wm()
+ * @note 3. smi130_set_fifo_tag_intr2_enable()
+ * @note 4. smi130_set_fifo_tag_intr1_enable()
+ *
+ * @note The fifo reads the whole 1024 bytes
+ * and processing the data
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_read_fifo_header_data(
+void);
+/*!
+ * @brief This function used for reading the
+ * fifo data of header mode for using user defined length
+ *
+ *
+ * @note Configure the below functions for FIFO header mode
+ * @note 1. smi130_set_fifo_down_gyro()
+ * @note 2. smi130_set_gyro_fifo_filter_data()
+ * @note 3. smi130_set_fifo_down_accel()
+ * @note 4. smi130_set_accel_fifo_filter_dat()
+ * @note 5. smi130_set_fifo_mag_enable()
+ * @note 6. smi130_set_fifo_accel_enable()
+ * @note 7. smi130_set_fifo_gyro_enable()
+ * @note 8. smi130_set_fifo_header_enable()
+ * @note For interrupt configuration
+ * @note 1. smi130_set_intr_fifo_full()
+ * @note 2. smi130_set_intr_fifo_wm()
+ * @note 3. smi130_set_fifo_tag_intr2_enable()
+ * @note 4. smi130_set_fifo_tag_intr1_enable()
+ *
+ * @note The fifo reads the whole 1024 bytes
+ * and processing the data
+ *
+ * @return results of bus communication function
+ * @retval 0 -> Success
+ * @retval -1 -> Error
+ *
+ *
+ */
+SMI130_RETURN_FUNCTION_TYPE smi130_read_fifo_header_data_user_defined_length(
+u16 v_fifo_user_length_u16);
+/*!
+ * @brief This function used for reading
+ * smi130_t structure
+ *
+ * @return the reference and values of smi130_t
+ *
+ *
+*/
+struct smi130_t *smi130_get_ptr(void);
+
+#endif
+
diff --git a/drivers/input/sensors/smi130/smi130_driver.c b/drivers/input/sensors/smi130/smi130_driver.c
new file mode 100644
index 0000000..16c1754
--- /dev/null
+++ b/drivers/input/sensors/smi130/smi130_driver.c
@@ -0,0 +1,4021 @@
+/*
+ * @section LICENSE
+ * (C) Copyright 2011~2018 Bosch Sensortec GmbH All Rights Reserved
+ *
+ * (C) Modification Copyright 2018 Robert Bosch Kft All Rights Reserved
+ *
+ * This software program is licensed subject to the GNU General
+ * Public License (GPL).Version 2,June 1991,
+ * available at http://www.fsf.org/copyleft/gpl.html
+ *
+ *
+ * @filename smi130_driver.c
+ * @date 2016/08/01 14:40
+ * @Modification Date 2018/06/21 15:03
+ * @version 1.3
+ *
+ * @brief
+ * The core code of SMI130 device driver
+ *
+ * @detail
+ * This file implements the core code of SMI130 device driver,
+ * which includes hardware related functions, input device register,
+ * device attribute files, etc.
+*/
+
+#include "smi130.h"
+#include "smi130_driver.h"
+#include <linux/device.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/of_irq.h>
+
+
+#define DRIVER_VERSION "0.0.53.0"
+#define I2C_BURST_READ_MAX_LEN (256)
+#define SMI130_STORE_COUNT (6000)
+#define LMADA (1)
+uint64_t g_current_apts_us;
+
+
+enum SMI_SENSOR_INT_T {
+ /* Interrupt enable0*/
+ SMI_ANYMO_X_INT = 0,
+ SMI_ANYMO_Y_INT,
+ SMI_ANYMO_Z_INT,
+ SMI_D_TAP_INT,
+ SMI_S_TAP_INT,
+ SMI_ORIENT_INT,
+ SMI_FLAT_INT,
+ /* Interrupt enable1*/
+ SMI_HIGH_X_INT,
+ SMI_HIGH_Y_INT,
+ SMI_HIGH_Z_INT,
+ SMI_LOW_INT,
+ SMI_DRDY_INT,
+ SMI_FFULL_INT,
+ SMI_FWM_INT,
+ /* Interrupt enable2 */
+ SMI_NOMOTION_X_INT,
+ SMI_NOMOTION_Y_INT,
+ SMI_NOMOTION_Z_INT,
+ SMI_STEP_DETECTOR_INT,
+ INT_TYPE_MAX
+};
+
+/*smi fifo sensor type combination*/
+enum SMI_SENSOR_FIFO_COMBINATION {
+ SMI_FIFO_A = 0,
+ SMI_FIFO_G,
+ SMI_FIFO_M,
+ SMI_FIFO_G_A,
+ SMI_FIFO_M_A,
+ SMI_FIFO_M_G,
+ SMI_FIFO_M_G_A,
+ SMI_FIFO_COM_MAX
+};
+
+/*smi fifo analyse return err status*/
+enum SMI_FIFO_ANALYSE_RETURN_T {
+ FIFO_OVER_READ_RETURN = -10,
+ FIFO_SENSORTIME_RETURN = -9,
+ FIFO_SKIP_OVER_LEN = -8,
+ FIFO_M_G_A_OVER_LEN = -7,
+ FIFO_M_G_OVER_LEN = -6,
+ FIFO_M_A_OVER_LEN = -5,
+ FIFO_G_A_OVER_LEN = -4,
+ FIFO_M_OVER_LEN = -3,
+ FIFO_G_OVER_LEN = -2,
+ FIFO_A_OVER_LEN = -1
+};
+
+/*!smi sensor generic power mode enum */
+enum SMI_DEV_OP_MODE {
+ SENSOR_PM_NORMAL = 0,
+ SENSOR_PM_LP1,
+ SENSOR_PM_SUSPEND,
+ SENSOR_PM_LP2
+};
+
+/*! smi acc sensor power mode enum */
+enum SMI_ACC_PM_TYPE {
+ SMI_ACC_PM_NORMAL = 0,
+ SMI_ACC_PM_LP1,
+ SMI_ACC_PM_SUSPEND,
+ SMI_ACC_PM_LP2,
+ SMI_ACC_PM_MAX
+};
+
+/*! smi gyro sensor power mode enum */
+enum SMI_GYRO_PM_TYPE {
+ SMI_GYRO_PM_NORMAL = 0,
+ SMI_GYRO_PM_FAST_START,
+ SMI_GYRO_PM_SUSPEND,
+ SMI_GYRO_PM_MAX
+};
+
+/*! smi mag sensor power mode enum */
+enum SMI_MAG_PM_TYPE {
+ SMI_MAG_PM_NORMAL = 0,
+ SMI_MAG_PM_LP1,
+ SMI_MAG_PM_SUSPEND,
+ SMI_MAG_PM_LP2,
+ SMI_MAG_PM_MAX
+};
+
+
+/*! smi sensor support type*/
+enum SMI_SENSOR_TYPE {
+ SMI_ACC_SENSOR,
+ SMI_GYRO_SENSOR,
+ SMI_MAG_SENSOR,
+ SMI_SENSOR_TYPE_MAX
+};
+
+/*!smi sensor generic power mode enum */
+enum SMI_AXIS_TYPE {
+ X_AXIS = 0,
+ Y_AXIS,
+ Z_AXIS,
+ AXIS_MAX
+};
+
+/*!smi sensor generic intterrupt enum */
+enum SMI_INT_TYPE {
+ SMI130_INT0 = 0,
+ SMI130_INT1,
+ SMI130_INT_MAX
+};
+
+/*! smi sensor time resolution definition*/
+enum SMI_SENSOR_TIME_RS_TYPE {
+ TS_0_78_HZ = 1,/*0.78HZ*/
+ TS_1_56_HZ,/*1.56HZ*/
+ TS_3_125_HZ,/*3.125HZ*/
+ TS_6_25_HZ,/*6.25HZ*/
+ TS_12_5_HZ,/*12.5HZ*/
+ TS_25_HZ,/*25HZ, odr=6*/
+ TS_50_HZ,/*50HZ*/
+ TS_100_HZ,/*100HZ*/
+ TS_200_HZ,/*200HZ*/
+ TS_400_HZ,/*400HZ*/
+ TS_800_HZ,/*800HZ*/
+ TS_1600_HZ,/*1600HZ*/
+ TS_MAX_HZ
+};
+
+/*! smi sensor interface mode */
+enum SMI_SENSOR_IF_MODE_TYPE {
+ /*primary interface:autoconfig/secondary interface off*/
+ P_AUTO_S_OFF = 0,
+ /*primary interface:I2C/secondary interface:OIS*/
+ P_I2C_S_OIS,
+ /*primary interface:autoconfig/secondary interface:Magnetometer*/
+ P_AUTO_S_MAG,
+ /*interface mode reseved*/
+ IF_MODE_RESEVED
+
+};
+
+/*! smi130 acc/gyro calibration status in H/W layer */
+enum SMI_CALIBRATION_STATUS_TYPE {
+ /*SMI FAST Calibration ready x/y/z status*/
+ SMI_ACC_X_FAST_CALI_RDY = 0,
+ SMI_ACC_Y_FAST_CALI_RDY,
+ SMI_ACC_Z_FAST_CALI_RDY
+};
+
+unsigned int reg_op_addr;
+
+static const int smi_pmu_cmd_acc_arr[SMI_ACC_PM_MAX] = {
+ /*!smi pmu for acc normal, low power1,
+ * suspend, low power2 mode command */
+ CMD_PMU_ACC_NORMAL,
+ CMD_PMU_ACC_LP1,
+ CMD_PMU_ACC_SUSPEND,
+ CMD_PMU_ACC_LP2
+};
+
+static const int smi_pmu_cmd_gyro_arr[SMI_GYRO_PM_MAX] = {
+ /*!smi pmu for gyro normal, fast startup,
+ * suspend mode command */
+ CMD_PMU_GYRO_NORMAL,
+ CMD_PMU_GYRO_FASTSTART,
+ CMD_PMU_GYRO_SUSPEND
+};
+
+static const int smi_pmu_cmd_mag_arr[SMI_MAG_PM_MAX] = {
+ /*!smi pmu for mag normal, low power1,
+ * suspend, low power2 mode command */
+ CMD_PMU_MAG_NORMAL,
+ CMD_PMU_MAG_LP1,
+ CMD_PMU_MAG_SUSPEND,
+ CMD_PMU_MAG_LP2
+};
+
+static const char *smi_axis_name[AXIS_MAX] = {"x", "y", "z"};
+
+static const int smi_interrupt_type[] = {
+ /*!smi interrupt type */
+ /* Interrupt enable0 , index=0~6*/
+ SMI130_ANY_MOTION_X_ENABLE,
+ SMI130_ANY_MOTION_Y_ENABLE,
+ SMI130_ANY_MOTION_Z_ENABLE,
+ SMI130_DOUBLE_TAP_ENABLE,
+ SMI130_SINGLE_TAP_ENABLE,
+ SMI130_ORIENT_ENABLE,
+ SMI130_FLAT_ENABLE,
+ /* Interrupt enable1, index=7~13*/
+ SMI130_HIGH_G_X_ENABLE,
+ SMI130_HIGH_G_Y_ENABLE,
+ SMI130_HIGH_G_Z_ENABLE,
+ SMI130_LOW_G_ENABLE,
+ SMI130_DATA_RDY_ENABLE,
+ SMI130_FIFO_FULL_ENABLE,
+ SMI130_FIFO_WM_ENABLE,
+ /* Interrupt enable2, index = 14~17*/
+ SMI130_NOMOTION_X_ENABLE,
+ SMI130_NOMOTION_Y_ENABLE,
+ SMI130_NOMOTION_Z_ENABLE,
+ SMI130_STEP_DETECTOR_EN
+};
+
+/*! smi sensor time depend on ODR*/
+struct smi_sensor_time_odr_tbl {
+ u32 ts_duration_lsb;
+ u32 ts_duration_us;
+ u32 ts_delat;/*sub current delat fifo_time*/
+};
+
+struct smi130_axis_data_t {
+ s16 x;
+ s16 y;
+ s16 z;
+};
+
+struct smi130_type_mapping_type {
+
+ /*! smi16x sensor chip id */
+ uint16_t chip_id;
+
+ /*! smi16x chip revision code */
+ uint16_t revision_id;
+
+ /*! bma2x2 sensor name */
+ const char *sensor_name;
+};
+
+struct smi130_store_info_t {
+ uint8_t current_frm_cnt;
+ uint64_t current_apts_us[2];
+ uint8_t fifo_ts_total_frmcnt;
+ uint64_t fifo_time;
+};
+
+uint64_t get_current_timestamp(void)
+{
+ uint64_t ts_ap;
+ struct timespec tmp_time;
+ get_monotonic_boottime(&tmp_time);
+ ts_ap = (uint64_t)tmp_time.tv_sec * 1000000000 + tmp_time.tv_nsec;
+ return ts_ap;
+
+}
+
+/*! sensor support type map */
+static const struct smi130_type_mapping_type sensor_type_map[] = {
+
+ {SENSOR_CHIP_ID_SMI, SENSOR_CHIP_REV_ID_SMI, "SMI130/162AB"},
+ {SENSOR_CHIP_ID_SMI_C2, SENSOR_CHIP_REV_ID_SMI, "SMI130C2"},
+ {SENSOR_CHIP_ID_SMI_C3, SENSOR_CHIP_REV_ID_SMI, "SMI130C3"},
+
+};
+
+/*!smi130 sensor time depends on ODR */
+static const struct smi_sensor_time_odr_tbl
+ sensortime_duration_tbl[TS_MAX_HZ] = {
+ {0x010000, 2560000, 0x00ffff},/*2560ms, 0.39hz, odr=resver*/
+ {0x008000, 1280000, 0x007fff},/*1280ms, 0.78hz, odr_acc=1*/
+ {0x004000, 640000, 0x003fff},/*640ms, 1.56hz, odr_acc=2*/
+ {0x002000, 320000, 0x001fff},/*320ms, 3.125hz, odr_acc=3*/
+ {0x001000, 160000, 0x000fff},/*160ms, 6.25hz, odr_acc=4*/
+ {0x000800, 80000, 0x0007ff},/*80ms, 12.5hz*/
+ {0x000400, 40000, 0x0003ff},/*40ms, 25hz, odr_acc = odr_gyro =6*/
+ {0x000200, 20000, 0x0001ff},/*20ms, 50hz, odr = 7*/
+ {0x000100, 10000, 0x0000ff},/*10ms, 100hz, odr=8*/
+ {0x000080, 5000, 0x00007f},/*5ms, 200hz, odr=9*/
+ {0x000040, 2500, 0x00003f},/*2.5ms, 400hz, odr=10*/
+ {0x000020, 1250, 0x00001f},/*1.25ms, 800hz, odr=11*/
+ {0x000010, 625, 0x00000f},/*0.625ms, 1600hz, odr=12*/
+
+};
+
+#if defined(CONFIG_USE_QUALCOMM_HAL)
+#define POLL_INTERVAL_MIN_MS 10
+#define POLL_INTERVAL_MAX_MS 4000
+#define POLL_DEFAULT_INTERVAL_MS 200
+#define SMI130_ACCEL_MIN_VALUE -32768
+#define SMI130_ACCEL_MAX_VALUE 32767
+#define SMI130_GYRO_MIN_VALUE -32768
+#define SMI130_GYRO_MAX_VALUE 32767
+#define SMI130_ACCEL_DEFAULT_POLL_INTERVAL_MS 200
+#define SMI130_GYRO_DEFAULT_POLL_INTERVAL_MS 200
+#define SMI130_ACCEL_MIN_POLL_INTERVAL_MS 10
+#define SMI130_ACCEL_MAX_POLL_INTERVAL_MS 5000
+#define SMI130_GYRO_MIN_POLL_INTERVAL_MS 10
+#define SMI130_GYRO_MAX_POLL_INTERVAL_MS 5000
+static struct sensors_classdev smi130_accel_cdev = {
+ .name = "smi130-accel",
+ .vendor = "bosch",
+ .version = 1,
+ .handle = SENSORS_ACCELERATION_HANDLE,
+ .type = SENSOR_TYPE_ACCELEROMETER,
+ .max_range = "156.8", /* 16g */
+ .resolution = "0.153125", /* 15.6mg */
+ .sensor_power = "0.13", /* typical value */
+ .min_delay = POLL_INTERVAL_MIN_MS * 1000, /* in microseconds */
+ .max_delay = POLL_INTERVAL_MAX_MS,
+ .delay_msec = POLL_DEFAULT_INTERVAL_MS, /* in millisecond */
+ .fifo_reserved_event_count = 0,
+ .fifo_max_event_count = 0,
+ .enabled = 0,
+ .max_latency = 0,
+ .flags = 0,
+ .sensors_enable = NULL,
+ .sensors_poll_delay = NULL,
+ .sensors_set_latency = NULL,
+ .sensors_flush = NULL,
+ .sensors_self_test = NULL,
+};
+static struct sensors_classdev smi130_gyro_cdev = {
+ .name = "smi130-gyro",
+ .vendor = "bosch",
+ .version = 1,
+ .handle = SENSORS_GYROSCOPE_HANDLE,
+ .type = SENSOR_TYPE_GYROSCOPE,
+ .max_range = "34.906586", /* rad/s */
+ .resolution = "0.0010681152", /* rad/s */
+ .sensor_power = "3.6", /* 3.6 mA */
+ .min_delay = SMI130_GYRO_MIN_POLL_INTERVAL_MS * 1000,
+ .max_delay = SMI130_GYRO_MAX_POLL_INTERVAL_MS,
+ .delay_msec = SMI130_GYRO_DEFAULT_POLL_INTERVAL_MS,
+ .fifo_reserved_event_count = 0,
+ .fifo_max_event_count = 0,
+ .enabled = 0,
+ .max_latency = 0,
+ .flags = 0, /* SENSOR_FLAG_CONTINUOUS_MODE */
+ .sensors_enable = NULL,
+ .sensors_poll_delay = NULL,
+ .sensors_enable_wakeup = NULL,
+ .sensors_set_latency = NULL,
+ .sensors_flush = NULL,
+};
+#endif
+static void smi_delay(u32 msec)
+{
+ if (msec <= 20)
+ usleep_range(msec * 1000, msec * 1000);
+ else
+ msleep(msec);
+}
+
+static void smi_dump_reg(struct smi_client_data *client_data)
+{
+ #define REG_MAX0 0x24
+ #define REG_MAX1 0x56
+ int i;
+ u8 dbg_buf0[REG_MAX0];
+ u8 dbg_buf1[REG_MAX1];
+ u8 dbg_buf_str0[REG_MAX0 * 3 + 1] = "";
+ u8 dbg_buf_str1[REG_MAX1 * 3 + 1] = "";
+
+ dev_notice(client_data->dev, "\nFrom 0x00:\n");
+
+ client_data->device.bus_read(client_data->device.dev_addr,
+ SMI_REG_NAME(USER_CHIP_ID), dbg_buf0, REG_MAX0);
+ for (i = 0; i < REG_MAX0; i++) {
+ snprintf(dbg_buf_str0 + i * 3, 16, "%02x%c", dbg_buf0[i],
+ (((i + 1) % BYTES_PER_LINE == 0) ? '\n' : ' '));
+ }
+ dev_notice(client_data->dev, "%s\n", dbg_buf_str0);
+
+ client_data->device.bus_read(client_data->device.dev_addr,
+ SMI130_USER_ACCEL_CONFIG_ADDR, dbg_buf1, REG_MAX1);
+ dev_notice(client_data->dev, "\nFrom 0x40:\n");
+ for (i = 0; i < REG_MAX1; i++) {
+ snprintf(dbg_buf_str1 + i * 3, 16, "%02x%c", dbg_buf1[i],
+ (((i + 1) % BYTES_PER_LINE == 0) ? '\n' : ' '));
+ }
+ dev_notice(client_data->dev, "\n%s\n", dbg_buf_str1);
+ }
+
+
+void smi_fifo_frame_bytes_extend_calc(
+ struct smi_client_data *client_data,
+ unsigned int *fifo_frmbytes_extend)
+{
+
+ switch (client_data->fifo_data_sel) {
+ case SMI_FIFO_A_SEL:
+ case SMI_FIFO_G_SEL:
+ *fifo_frmbytes_extend = 7;
+ break;
+ case SMI_FIFO_G_A_SEL:
+ *fifo_frmbytes_extend = 13;
+ break;
+ case SMI_FIFO_M_SEL:
+ *fifo_frmbytes_extend = 9;
+ break;
+ case SMI_FIFO_M_A_SEL:
+ case SMI_FIFO_M_G_SEL:
+ /*8(mag) + 6(gyro or acc) +1(head) = 15*/
+ *fifo_frmbytes_extend = 15;
+ break;
+ case SMI_FIFO_M_G_A_SEL:
+ /*8(mag) + 6(gyro or acc) + 6 + 1 = 21*/
+ *fifo_frmbytes_extend = 21;
+ break;
+ default:
+ *fifo_frmbytes_extend = 0;
+ break;
+
+ };
+
+}
+
+static int smi_input_init(struct smi_client_data *client_data)
+{
+ struct input_dev *dev;
+ int err = 0;
+
+ dev = input_allocate_device();
+ if (NULL == dev)
+ return -ENOMEM;
+#if defined(CONFIG_USE_QUALCOMM_HAL)
+ dev->name = "smi130-accel";
+#else
+ dev->name = SENSOR_NAME;
+#endif
+ dev->id.bustype = BUS_I2C;
+
+ input_set_capability(dev, EV_MSC, MSC_GESTURE);
+ input_set_capability(dev, EV_MSC, INPUT_EVENT_SGM);
+
+ input_set_capability(dev, EV_MSC, INPUT_EVENT_FAST_GYRO_CALIB_DONE);
+ input_set_capability(dev, EV_MSC, INPUT_EVENT_STEP_DETECTOR);
+ input_set_capability(dev, EV_MSC, INPUT_EVENT_FAST_ACC_CALIB_DONE);
+
+
+ input_set_capability(dev, EV_REL, REL_X);
+ input_set_capability(dev, EV_REL, REL_Y);
+ input_set_capability(dev, EV_REL, REL_Z);
+ #if defined(CONFIG_USE_QUALCOMM_HAL)
+ input_set_capability(dev, EV_ABS, ABS_MISC);
+ input_set_abs_params(dev, ABS_X,
+ SMI130_ACCEL_MIN_VALUE, SMI130_ACCEL_MAX_VALUE,
+ 0, 0);
+ input_set_abs_params(dev, ABS_Y,
+ SMI130_ACCEL_MIN_VALUE, SMI130_ACCEL_MAX_VALUE,
+ 0, 0);
+ input_set_abs_params(dev, ABS_Z,
+ SMI130_ACCEL_MIN_VALUE, SMI130_ACCEL_MAX_VALUE,
+ 0, 0);
+ #endif
+ input_set_drvdata(dev, client_data);
+
+ err = input_register_device(dev);
+ if (err < 0) {
+ input_free_device(dev);
+ dev_notice(client_data->dev, "smi130 input free!\n");
+ return err;
+ }
+ client_data->input = dev;
+ dev_notice(client_data->dev,
+ "smi130 input register successfully, %s!\n",
+ client_data->input->name);
+ return err;
+}
+
+//#if defined(CONFIG_USE_QUALCOMM_HAL)
+static int smi_gyro_input_init(struct smi_client_data *client_data)
+{
+ struct input_dev *dev;
+ int err = 0;
+
+ dev = input_allocate_device();
+ if (NULL == dev)
+ return -ENOMEM;
+ dev->name = "smi130-gyro";
+ dev->id.bustype = BUS_I2C;
+ input_set_capability(dev, EV_ABS, ABS_MISC);
+ input_set_capability(dev, EV_MSC, MSC_GESTURE);
+ input_set_capability(dev, EV_MSC, INPUT_EVENT_SGM);
+
+ input_set_capability(dev, EV_MSC, INPUT_EVENT_FAST_GYRO_CALIB_DONE);
+ input_set_capability(dev, EV_MSC, INPUT_EVENT_STEP_DETECTOR);
+ input_set_capability(dev, EV_MSC, INPUT_EVENT_FAST_ACC_CALIB_DONE);
+ #if defined(CONFIG_USE_QUALCOMM_HAL)
+ input_set_abs_params(dev, ABS_RX,
+ SMI130_ACCEL_MIN_VALUE, SMI130_ACCEL_MAX_VALUE,
+ 0, 0);
+ input_set_abs_params(dev, ABS_RY,
+ SMI130_ACCEL_MIN_VALUE, SMI130_ACCEL_MAX_VALUE,
+ 0, 0);
+ input_set_abs_params(dev, ABS_RZ,
+ SMI130_ACCEL_MIN_VALUE, SMI130_ACCEL_MAX_VALUE,
+ 0, 0);
+ #endif
+ input_set_drvdata(dev, client_data);
+ err = input_register_device(dev);
+ if (err < 0) {
+ input_free_device(dev);
+ dev_notice(client_data->dev, "smi130 input free!\n");
+ return err;
+ }
+ client_data->gyro_input = dev;
+ dev_notice(client_data->dev,
+ "smi130 input register successfully, %s!\n",
+ client_data->gyro_input->name);
+ return err;
+}
+//#endif
+static void smi_input_destroy(struct smi_client_data *client_data)
+{
+ struct input_dev *dev = client_data->input;
+
+ input_unregister_device(dev);
+ input_free_device(dev);
+}
+
+static int smi_check_chip_id(struct smi_client_data *client_data)
+{
+ int8_t err = 0;
+ int8_t i = 0;
+ uint8_t chip_id = 0;
+ uint8_t read_count = 0;
+ u8 smi_sensor_cnt = sizeof(sensor_type_map)
+ / sizeof(struct smi130_type_mapping_type);
+ /* read and check chip id */
+ while (read_count++ < CHECK_CHIP_ID_TIME_MAX) {
+ if (client_data->device.bus_read(client_data->device.dev_addr,
+ SMI_REG_NAME(USER_CHIP_ID), &chip_id, 1) < 0) {
+
+ dev_err(client_data->dev,
+ "Bosch Sensortec Device not found"
+ "read chip_id:%d\n", chip_id);
+ continue;
+ } else {
+ for (i = 0; i < smi_sensor_cnt; i++) {
+ if (sensor_type_map[i].chip_id == chip_id) {
+ client_data->chip_id = chip_id;
+ dev_notice(client_data->dev,
+ "Bosch Sensortec Device detected, "
+ "HW IC name: %s\n", sensor_type_map[i].sensor_name);
+ break;
+ }
+ }
+ if (i < smi_sensor_cnt)
+ break;
+ else {
+ if (read_count == CHECK_CHIP_ID_TIME_MAX) {
+ dev_err(client_data->dev,
+ "Failed!Bosch Sensortec Device not found"
+ " mismatch chip_id:%d\n", chip_id);
+ err = -ENODEV;
+ return err;
+ }
+ }
+ smi_delay(1);
+ }
+ }
+ return err;
+
+}
+
+static int smi_pmu_set_suspend(struct smi_client_data *client_data)
+{
+ int err = 0;
+ if (client_data == NULL)
+ return -EINVAL;
+ else {
+ err += SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_acc_arr[SENSOR_PM_SUSPEND]);
+ err += SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_gyro_arr[SENSOR_PM_SUSPEND]);
+ err += SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_mag_arr[SENSOR_PM_SUSPEND]);
+ client_data->pw.acc_pm = SMI_ACC_PM_SUSPEND;
+ client_data->pw.gyro_pm = SMI_GYRO_PM_SUSPEND;
+ client_data->pw.mag_pm = SMI_MAG_PM_SUSPEND;
+ }
+
+ return err;
+}
+
+static int smi_get_err_status(struct smi_client_data *client_data)
+{
+ int err = 0;
+
+ err = SMI_CALL_API(get_error_status)(&client_data->err_st.fatal_err,
+ &client_data->err_st.err_code, &client_data->err_st.i2c_fail,
+ &client_data->err_st.drop_cmd, &client_data->err_st.mag_drdy_err);
+ return err;
+}
+
+static void smi_work_func(struct work_struct *work)
+{
+ struct smi_client_data *client_data =
+ container_of((struct delayed_work *)work,
+ struct smi_client_data, work);
+ unsigned long delay =
+ msecs_to_jiffies(atomic_read(&client_data->delay));
+ struct smi130_accel_t data;
+ int err;
+
+ err = SMI_CALL_API(read_accel_xyz)(&data);
+ if (err < 0)
+ return;
+
+ /*report current frame via input event*/
+ input_event(client_data->input, EV_REL, REL_X, data.x);
+ input_event(client_data->input, EV_REL, REL_Y, data.y);
+ input_event(client_data->input, EV_REL, REL_Z, data.z);
+ input_sync(client_data->input);
+
+ schedule_delayed_work(&client_data->work, delay);
+}
+
+static ssize_t smi130_chip_id_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ return snprintf(buf, 16, "0x%x\n", client_data->chip_id);
+}
+
+static ssize_t smi130_err_st_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ int err = 0;
+ err = smi_get_err_status(client_data);
+ if (err)
+ return err;
+ else {
+ return snprintf(buf, 128, "fatal_err:0x%x, err_code:%d,\n\n"
+ "i2c_fail_err:%d, drop_cmd_err:%d, mag_drdy_err:%d\n",
+ client_data->err_st.fatal_err,
+ client_data->err_st.err_code,
+ client_data->err_st.i2c_fail,
+ client_data->err_st.drop_cmd,
+ client_data->err_st.mag_drdy_err);
+
+ }
+}
+
+static ssize_t smi130_sensor_time_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err = 0;
+ u32 sensor_time;
+ err = SMI_CALL_API(get_sensor_time)(&sensor_time);
+ if (err)
+ return err;
+ else
+ return snprintf(buf, 16, "0x%x\n", (unsigned int)sensor_time);
+}
+
+static ssize_t smi130_fifo_flush_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long enable;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &enable);
+ if (err)
+ return err;
+ if (enable)
+ err = SMI_CALL_API(set_command_register)(CMD_CLR_FIFO_DATA);
+
+ if (err)
+ dev_err(client_data->dev, "fifo flush failed!\n");
+
+ return count;
+
+}
+
+
+static ssize_t smi130_fifo_bytecount_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned int fifo_bytecount = 0;
+
+ SMI_CALL_API(fifo_length)(&fifo_bytecount);
+ err = snprintf(buf, 16, "%u\n", fifo_bytecount);
+ return err;
+}
+
+static ssize_t smi130_fifo_bytecount_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ int err;
+ unsigned long data;
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+ client_data->fifo_bytecount = (unsigned int) data;
+
+ return count;
+}
+
+int smi130_fifo_data_sel_get(struct smi_client_data *client_data)
+{
+ int err = 0;
+ unsigned char fifo_acc_en, fifo_gyro_en, fifo_mag_en;
+ unsigned char fifo_datasel;
+
+ err += SMI_CALL_API(get_fifo_accel_enable)(&fifo_acc_en);
+ err += SMI_CALL_API(get_fifo_gyro_enable)(&fifo_gyro_en);
+ err += SMI_CALL_API(get_fifo_mag_enable)(&fifo_mag_en);
+
+ if (err)
+ return err;
+
+ fifo_datasel = (fifo_acc_en << SMI_ACC_SENSOR) |
+ (fifo_gyro_en << SMI_GYRO_SENSOR) |
+ (fifo_mag_en << SMI_MAG_SENSOR);
+
+ client_data->fifo_data_sel = fifo_datasel;
+
+ return err;
+
+
+}
+
+static ssize_t smi130_fifo_data_sel_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err = 0;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ err = smi130_fifo_data_sel_get(client_data);
+ if (err) {
+ dev_err(client_data->dev, "get fifo_sel failed!\n");
+ return -EINVAL;
+ }
+ return snprintf(buf, 16, "%d\n", client_data->fifo_data_sel);
+}
+
+/* write any value to clear all the fifo data. */
+static ssize_t smi130_fifo_data_sel_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ int err;
+ unsigned long data;
+ unsigned char fifo_datasel;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+ /* data format: aimed 0b0000 0x(m)x(g)x(a), x:1 enable, 0:disable*/
+ if (data > 7)
+ return -EINVAL;
+
+
+ fifo_datasel = (unsigned char)data;
+
+
+ err += SMI_CALL_API(set_fifo_accel_enable)
+ ((fifo_datasel & (1 << SMI_ACC_SENSOR)) ? 1 : 0);
+ err += SMI_CALL_API(set_fifo_gyro_enable)
+ (fifo_datasel & (1 << SMI_GYRO_SENSOR) ? 1 : 0);
+ err += SMI_CALL_API(set_fifo_mag_enable)
+ ((fifo_datasel & (1 << SMI_MAG_SENSOR)) ? 1 : 0);
+
+ err += SMI_CALL_API(set_command_register)(CMD_CLR_FIFO_DATA);
+ if (err)
+ return -EIO;
+ else {
+ dev_notice(client_data->dev, "FIFO A_en:%d, G_en:%d, M_en:%d\n",
+ (fifo_datasel & (1 << SMI_ACC_SENSOR)) ? 1 : 0,
+ (fifo_datasel & (1 << SMI_GYRO_SENSOR) ? 1 : 0),
+ ((fifo_datasel & (1 << SMI_MAG_SENSOR)) ? 1 : 0));
+ client_data->fifo_data_sel = fifo_datasel;
+ }
+ return count;
+}
+
+static ssize_t smi130_fifo_data_out_frame_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ int err = 0;
+ uint32_t fifo_bytecount = 0;
+
+ err = SMI_CALL_API(fifo_length)(&fifo_bytecount);
+ if (err < 0) {
+ dev_err(client_data->dev, "read fifo_length err");
+ return -EINVAL;
+ }
+ if (fifo_bytecount == 0)
+ return 0;
+ err = smi_burst_read_wrapper(client_data->device.dev_addr,
+ SMI130_USER_FIFO_DATA__REG, buf,
+ fifo_bytecount);
+ if (err) {
+ dev_err(client_data->dev, "read fifo err");
+ SMI_CALL_API(set_command_register)(CMD_CLR_FIFO_DATA);
+ return -EINVAL;
+ }
+ return fifo_bytecount;
+
+}
+
+static ssize_t smi130_fifo_watermark_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char data = 0xff;
+
+ err = SMI_CALL_API(get_fifo_wm)(&data);
+
+ if (err)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_fifo_watermark_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long data;
+ unsigned char fifo_watermark;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ fifo_watermark = (unsigned char)data;
+ err = SMI_CALL_API(set_fifo_wm)(fifo_watermark);
+ if (err)
+ return -EIO;
+
+ return count;
+}
+
+
+static ssize_t smi130_fifo_header_en_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char data = 0xff;
+
+ err = SMI_CALL_API(get_fifo_header_enable)(&data);
+
+ if (err)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_fifo_header_en_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ int err;
+ unsigned long data;
+ unsigned char fifo_header_en;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+ if (data > 1)
+ return -ENOENT;
+
+ fifo_header_en = (unsigned char)data;
+ err = SMI_CALL_API(set_fifo_header_enable)(fifo_header_en);
+ if (err)
+ return -EIO;
+
+ client_data->fifo_head_en = fifo_header_en;
+
+ return count;
+}
+
+static ssize_t smi130_fifo_time_en_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char data = 0;
+
+ err = SMI_CALL_API(get_fifo_time_enable)(&data);
+
+ if (!err)
+ err = snprintf(buf, 16, "%d\n", data);
+
+ return err;
+}
+
+static ssize_t smi130_fifo_time_en_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long data;
+ unsigned char fifo_ts_en;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ fifo_ts_en = (unsigned char)data;
+
+ err = SMI_CALL_API(set_fifo_time_enable)(fifo_ts_en);
+ if (err)
+ return -EIO;
+
+ return count;
+}
+
+static ssize_t smi130_fifo_int_tag_en_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err = 0;
+ unsigned char fifo_tag_int1 = 0;
+ unsigned char fifo_tag_int2 = 0;
+ unsigned char fifo_tag_int;
+
+ err += SMI_CALL_API(get_fifo_tag_intr1_enable)(&fifo_tag_int1);
+ err += SMI_CALL_API(get_fifo_tag_intr2_enable)(&fifo_tag_int2);
+
+ fifo_tag_int = (fifo_tag_int1 << SMI130_INT0) |
+ (fifo_tag_int2 << SMI130_INT1);
+
+ if (!err)
+ err = snprintf(buf, 16, "%d\n", fifo_tag_int);
+
+ return err;
+}
+
+static ssize_t smi130_fifo_int_tag_en_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ int err;
+ unsigned long data;
+ unsigned char fifo_tag_int_en;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+ if (data > 3)
+ return -EINVAL;
+
+ fifo_tag_int_en = (unsigned char)data;
+
+ err += SMI_CALL_API(set_fifo_tag_intr1_enable)
+ ((fifo_tag_int_en & (1 << SMI130_INT0)) ? 1 : 0);
+ err += SMI_CALL_API(set_fifo_tag_intr2_enable)
+ ((fifo_tag_int_en & (1 << SMI130_INT1)) ? 1 : 0);
+
+ if (err) {
+ dev_err(client_data->dev, "fifo int tag en err:%d\n", err);
+ return -EIO;
+ }
+ client_data->fifo_int_tag_en = fifo_tag_int_en;
+
+ return count;
+}
+
+static int smi130_set_acc_op_mode(struct smi_client_data *client_data,
+ unsigned long op_mode)
+{
+ int err = 0;
+ unsigned char stc_enable;
+ unsigned char std_enable;
+ mutex_lock(&client_data->mutex_op_mode);
+
+ if (op_mode < SMI_ACC_PM_MAX) {
+ switch (op_mode) {
+ case SMI_ACC_PM_NORMAL:
+ err = SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_acc_arr[SMI_ACC_PM_NORMAL]);
+ client_data->pw.acc_pm = SMI_ACC_PM_NORMAL;
+ smi_delay(10);
+ break;
+ case SMI_ACC_PM_LP1:
+ err = SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_acc_arr[SMI_ACC_PM_LP1]);
+ client_data->pw.acc_pm = SMI_ACC_PM_LP1;
+ smi_delay(3);
+ break;
+ case SMI_ACC_PM_SUSPEND:
+ SMI_CALL_API(get_step_counter_enable)(&stc_enable);
+ SMI_CALL_API(get_step_detector_enable)(&std_enable);
+ if ((stc_enable == 0) && (std_enable == 0) &&
+ (client_data->sig_flag == 0)) {
+ err = SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_acc_arr[SMI_ACC_PM_SUSPEND]);
+ client_data->pw.acc_pm = SMI_ACC_PM_SUSPEND;
+ smi_delay(10);
+ }
+ break;
+ case SMI_ACC_PM_LP2:
+ err = SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_acc_arr[SMI_ACC_PM_LP2]);
+ client_data->pw.acc_pm = SMI_ACC_PM_LP2;
+ smi_delay(3);
+ break;
+ default:
+ mutex_unlock(&client_data->mutex_op_mode);
+ return -EINVAL;
+ }
+ } else {
+ mutex_unlock(&client_data->mutex_op_mode);
+ return -EINVAL;
+ }
+
+ mutex_unlock(&client_data->mutex_op_mode);
+
+ return err;
+
+
+}
+
+static ssize_t smi130_temperature_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ s16 temp = 0xff;
+
+ err = SMI_CALL_API(get_temp)(&temp);
+
+ if (!err)
+ err = snprintf(buf, 16, "0x%x\n", temp);
+
+ return err;
+}
+
+static ssize_t smi130_place_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ int place = BOSCH_SENSOR_PLACE_UNKNOWN;
+
+ if (NULL != client_data->bosch_pd)
+ place = client_data->bosch_pd->place;
+
+ return snprintf(buf, 16, "%d\n", place);
+}
+
+static ssize_t smi130_delay_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ return snprintf(buf, 16, "%d\n", atomic_read(&client_data->delay));
+
+}
+
+static ssize_t smi130_delay_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ int err;
+ unsigned long data;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ if (data == 0) {
+ err = -EINVAL;
+ return err;
+ }
+
+ if (data < SMI_DELAY_MIN)
+ data = SMI_DELAY_MIN;
+
+ atomic_set(&client_data->delay, (unsigned int)data);
+
+ return count;
+}
+
+static ssize_t smi130_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ return snprintf(buf, 16, "%d\n", atomic_read(&client_data->wkqueue_en));
+
+}
+
+static ssize_t smi130_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ int err;
+ unsigned long enable;
+ int pre_enable = atomic_read(&client_data->wkqueue_en);
+
+ err = kstrtoul(buf, 10, &enable);
+ if (err)
+ return err;
+
+ enable = enable ? 1 : 0;
+ mutex_lock(&client_data->mutex_enable);
+ if (enable) {
+ if (pre_enable == 0) {
+ smi130_set_acc_op_mode(client_data,
+ SMI_ACC_PM_NORMAL);
+ schedule_delayed_work(&client_data->work,
+ msecs_to_jiffies(atomic_read(&client_data->delay)));
+ atomic_set(&client_data->wkqueue_en, 1);
+ }
+
+ } else {
+ if (pre_enable == 1) {
+ smi130_set_acc_op_mode(client_data,
+ SMI_ACC_PM_SUSPEND);
+
+ cancel_delayed_work_sync(&client_data->work);
+ atomic_set(&client_data->wkqueue_en, 0);
+ }
+ }
+
+ mutex_unlock(&client_data->mutex_enable);
+
+ return count;
+}
+
+#if defined(SMI130_ENABLE_INT1) || defined(SMI130_ENABLE_INT2)
+/* accel sensor part */
+static ssize_t smi130_anymot_duration_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char data;
+
+ err = SMI_CALL_API(get_intr_any_motion_durn)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_anymot_duration_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_intr_any_motion_durn)((unsigned char)data);
+ if (err < 0)
+ return -EIO;
+
+ return count;
+}
+
+static ssize_t smi130_anymot_threshold_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+
+ err = SMI_CALL_API(get_intr_any_motion_thres)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_anymot_threshold_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_intr_any_motion_thres)((unsigned char)data);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t smi130_step_detector_status_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ u8 data = 0;
+ u8 step_det;
+ int err;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ err = SMI_CALL_API(get_step_detector_enable)(&step_det);
+ /*smi130_get_status0_step_int*/
+ if (err < 0)
+ return err;
+/*client_data->std will be updated in smi_stepdetector_interrupt_handle */
+ if ((step_det == 1) && (client_data->std == 1)) {
+ data = 1;
+ client_data->std = 0;
+ }
+ else {
+ data = 0;
+ }
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_step_detector_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+
+ err = SMI_CALL_API(get_step_detector_enable)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_step_detector_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_step_detector_enable)((unsigned char)data);
+ if (err < 0)
+ return -EIO;
+ if (data == 0)
+ client_data->pedo_data.wkar_step_detector_status = 0;
+ return count;
+}
+
+static ssize_t smi130_signification_motion_enable_store(
+ struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+ /*0x62 (bit 1) INT_MOTION_3 int_sig_mot_sel*/
+ err = SMI_CALL_API(set_intr_significant_motion_select)(
+ (unsigned char)data);
+ if (err < 0)
+ return -EIO;
+ if (data == 1) {
+ err = SMI_CALL_API(set_intr_enable_0)
+ (SMI130_ANY_MOTION_X_ENABLE, 1);
+ err += SMI_CALL_API(set_intr_enable_0)
+ (SMI130_ANY_MOTION_Y_ENABLE, 1);
+ err += SMI_CALL_API(set_intr_enable_0)
+ (SMI130_ANY_MOTION_Z_ENABLE, 1);
+ if (err < 0)
+ return -EIO;
+ enable_irq_wake(client_data->IRQ);
+ client_data->sig_flag = 1;
+ } else {
+ err = SMI_CALL_API(set_intr_enable_0)
+ (SMI130_ANY_MOTION_X_ENABLE, 0);
+ err += SMI_CALL_API(set_intr_enable_0)
+ (SMI130_ANY_MOTION_Y_ENABLE, 0);
+ err += SMI_CALL_API(set_intr_enable_0)
+ (SMI130_ANY_MOTION_Z_ENABLE, 0);
+ if (err < 0)
+ return -EIO;
+ disable_irq_wake(client_data->IRQ);
+ client_data->sig_flag = 0;
+ }
+ return count;
+}
+
+static ssize_t smi130_signification_motion_enable_show(
+ struct device *dev, struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+ /*0x62 (bit 1) INT_MOTION_3 int_sig_mot_sel*/
+ err = SMI_CALL_API(get_intr_significant_motion_select)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static int sigmotion_init_interrupts(u8 sig_map_int_pin)
+{
+ int ret = 0;
+/*0x60 */
+ ret += smi130_set_intr_any_motion_thres(0x1e);
+/* 0x62(bit 3~2) 0=1.5s */
+ ret += smi130_set_intr_significant_motion_skip(0);
+/*0x62(bit 5~4) 1=0.5s*/
+ ret += smi130_set_intr_significant_motion_proof(1);
+/*0x50 (bit 0, 1, 2) INT_EN_0 anymo x y z*/
+ ret += smi130_map_significant_motion_intr(sig_map_int_pin);
+/*0x62 (bit 1) INT_MOTION_3 int_sig_mot_sel
+close the signification_motion*/
+ ret += smi130_set_intr_significant_motion_select(0);
+/*close the anymotion interrupt*/
+ ret += SMI_CALL_API(set_intr_enable_0)
+ (SMI130_ANY_MOTION_X_ENABLE, 0);
+ ret += SMI_CALL_API(set_intr_enable_0)
+ (SMI130_ANY_MOTION_Y_ENABLE, 0);
+ ret += SMI_CALL_API(set_intr_enable_0)
+ (SMI130_ANY_MOTION_Z_ENABLE, 0);
+ if (ret)
+ printk(KERN_ERR "smi130 sig motion failed setting,%d!\n", ret);
+ return ret;
+
+}
+#endif
+
+static ssize_t smi130_acc_range_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char range;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = SMI_CALL_API(get_accel_range)(&range);
+ if (err)
+ return err;
+
+ client_data->range.acc_range = range;
+ return snprintf(buf, 16, "%d\n", range);
+}
+
+static ssize_t smi130_acc_range_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long range;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+
+ err = kstrtoul(buf, 10, &range);
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_accel_range)(range);
+ if (err)
+ return -EIO;
+
+ client_data->range.acc_range = range;
+ return count;
+}
+
+static ssize_t smi130_acc_odr_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char acc_odr;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = SMI_CALL_API(get_accel_output_data_rate)(&acc_odr);
+ if (err)
+ return err;
+
+ client_data->odr.acc_odr = acc_odr;
+ return snprintf(buf, 16, "%d\n", acc_odr);
+}
+
+static ssize_t smi130_acc_odr_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long acc_odr;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &acc_odr);
+ if (err)
+ return err;
+
+ if (acc_odr < 1 || acc_odr > 12)
+ return -EIO;
+
+ if (acc_odr < 5)
+ err = SMI_CALL_API(set_accel_under_sampling_parameter)(1);
+ else
+ err = SMI_CALL_API(set_accel_under_sampling_parameter)(0);
+
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_accel_output_data_rate)(acc_odr);
+ if (err)
+ return -EIO;
+ client_data->odr.acc_odr = acc_odr;
+ return count;
+}
+
+static ssize_t smi130_acc_op_mode_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ int err = 0;
+ u8 accel_pmu_status = 0;
+ err = SMI_CALL_API(get_accel_power_mode_stat)(
+ &accel_pmu_status);
+
+ if (err)
+ return err;
+ else
+ return snprintf(buf, 32, "reg:%d, val:%d\n", accel_pmu_status,
+ client_data->pw.acc_pm);
+}
+
+static ssize_t smi130_acc_op_mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ int err;
+ unsigned long op_mode;
+ err = kstrtoul(buf, 10, &op_mode);
+ if (err)
+ return err;
+
+ err = smi130_set_acc_op_mode(client_data, op_mode);
+ if (err)
+ return err;
+ else
+ return count;
+
+}
+
+static ssize_t smi130_acc_value_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct smi130_accel_t data;
+
+ int err;
+
+ err = SMI_CALL_API(read_accel_xyz)(&data);
+ if (err < 0)
+ return err;
+
+ return snprintf(buf, 48, "%hd %hd %hd\n",
+ data.x, data.y, data.z);
+}
+
+static ssize_t smi130_acc_fast_calibration_x_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+
+ err = SMI_CALL_API(get_foc_accel_x)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_acc_fast_calibration_x_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+ s8 accel_offset_x = 0;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+ /* 0: disable, 1: +1g, 2: -1g, 3: 0g */
+ if (data > 3)
+ return -EINVAL;
+
+ err = SMI_CALL_API(set_accel_foc_trigger)(X_AXIS,
+ data, &accel_offset_x);
+ if (err)
+ return -EIO;
+ else
+ client_data->calib_status |=
+ SMI_FAST_CALI_TRUE << SMI_ACC_X_FAST_CALI_RDY;
+ return count;
+}
+
+static ssize_t smi130_acc_fast_calibration_y_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+
+ err = SMI_CALL_API(get_foc_accel_y)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_acc_fast_calibration_y_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+ s8 accel_offset_y = 0;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+ /* 0: disable, 1: +1g, 2: -1g, 3: 0g */
+ if (data > 3)
+ return -EINVAL;
+
+ err = SMI_CALL_API(set_accel_foc_trigger)(Y_AXIS,
+ data, &accel_offset_y);
+ if (err)
+ return -EIO;
+ else
+ client_data->calib_status |=
+ SMI_FAST_CALI_TRUE << SMI_ACC_Y_FAST_CALI_RDY;
+ return count;
+}
+
+static ssize_t smi130_acc_fast_calibration_z_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+
+ err = SMI_CALL_API(get_foc_accel_z)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_acc_fast_calibration_z_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+ s8 accel_offset_z = 0;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ unsigned char data1[3] = {0};
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+ /* 0: disable, 1: +1g, 2: -1g, 3: 0g */
+ if (data > 3)
+ return -EINVAL;
+
+ err = SMI_CALL_API(set_accel_foc_trigger)(Z_AXIS,
+ data, &accel_offset_z);
+ if (err)
+ return -EIO;
+ else
+ client_data->calib_status |=
+ SMI_FAST_CALI_TRUE << SMI_ACC_Z_FAST_CALI_RDY;
+
+ if (client_data->calib_status == SMI_FAST_CALI_ALL_RDY) {
+ err = SMI_CALL_API(get_accel_offset_compensation_xaxis)(
+ &data1[0]);
+ err += SMI_CALL_API(get_accel_offset_compensation_yaxis)(
+ &data1[1]);
+ err += SMI_CALL_API(get_accel_offset_compensation_zaxis)(
+ &data1[2]);
+ dev_info(client_data->dev, "accx %d, accy %d, accz %d\n",
+ data1[0], data1[1], data1[2]);
+ if (err)
+ return -EIO;
+ input_event(client_data->input, EV_MSC,
+ INPUT_EVENT_FAST_ACC_CALIB_DONE,
+ (data1[0] | (data1[1] << 8) | (data1[2] << 16)));
+ input_sync(client_data->input);
+ client_data->calib_status = 0;
+ }
+
+ return count;
+}
+
+static ssize_t smi130_acc_offset_x_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+
+ err = SMI_CALL_API(get_accel_offset_compensation_xaxis)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+
+static ssize_t smi130_acc_offset_x_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_accel_offset_compensation_xaxis)
+ ((unsigned char)data);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t smi130_acc_offset_y_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+
+ err = SMI_CALL_API(get_accel_offset_compensation_yaxis)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_acc_offset_y_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_accel_offset_compensation_yaxis)
+ ((unsigned char)data);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t smi130_acc_offset_z_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+
+ err = SMI_CALL_API(get_accel_offset_compensation_zaxis)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_acc_offset_z_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_accel_offset_compensation_zaxis)
+ ((unsigned char)data);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t smi130_test_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ u8 raw_data[15] = {0};
+ unsigned int sensor_time = 0;
+
+ int err;
+ memset(raw_data, 0, sizeof(raw_data));
+
+ err = client_data->device.bus_read(client_data->device.dev_addr,
+ SMI130_USER_DATA_8_GYRO_X_LSB__REG, raw_data, 15);
+ if (err)
+ return err;
+
+ udelay(10);
+ sensor_time = (u32)(raw_data[14] << 16 | raw_data[13] << 8
+ | raw_data[12]);
+
+ return snprintf(buf, 128, "%d %d %d %d %d %d %u",
+ (s16)(raw_data[1] << 8 | raw_data[0]),
+ (s16)(raw_data[3] << 8 | raw_data[2]),
+ (s16)(raw_data[5] << 8 | raw_data[4]),
+ (s16)(raw_data[7] << 8 | raw_data[6]),
+ (s16)(raw_data[9] << 8 | raw_data[8]),
+ (s16)(raw_data[11] << 8 | raw_data[10]),
+ sensor_time);
+
+}
+
+static ssize_t smi130_step_counter_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = SMI_CALL_API(get_step_counter_enable)(&data);
+
+ client_data->stc_enable = data;
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_step_counter_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_step_counter_enable)((unsigned char)data);
+
+ client_data->stc_enable = data;
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+
+static ssize_t smi130_step_counter_mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_step_mode)((unsigned char)data);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t smi130_step_counter_clc_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = smi130_clear_step_counter();
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t smi130_step_counter_value_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ u16 data;
+ int err;
+ static u16 last_stc_value;
+
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = SMI_CALL_API(read_step_count)(&data);
+
+ if (err < 0)
+ return err;
+ if (data >= last_stc_value) {
+ client_data->pedo_data.last_step_counter_value += (
+ data - last_stc_value);
+ last_stc_value = data;
+ } else
+ last_stc_value = data;
+ return snprintf(buf, 16, "%d\n",
+ client_data->pedo_data.last_step_counter_value);
+}
+
+static ssize_t smi130_smi_value_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ u8 raw_data[12] = {0};
+
+ int err;
+ memset(raw_data, 0, sizeof(raw_data));
+
+ err = client_data->device.bus_read(client_data->device.dev_addr,
+ SMI130_USER_DATA_8_GYRO_X_LSB__REG, raw_data, 12);
+ if (err)
+ return err;
+ /*output:gyro x y z acc x y z*/
+ return snprintf(buf, 96, "%hd %d %hd %hd %hd %hd\n",
+ (s16)(raw_data[1] << 8 | raw_data[0]),
+ (s16)(raw_data[3] << 8 | raw_data[2]),
+ (s16)(raw_data[5] << 8 | raw_data[4]),
+ (s16)(raw_data[7] << 8 | raw_data[6]),
+ (s16)(raw_data[9] << 8 | raw_data[8]),
+ (s16)(raw_data[11] << 8 | raw_data[10]));
+
+}
+
+
+static ssize_t smi130_selftest_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ return snprintf(buf, 16, "0x%x\n",
+ atomic_read(&client_data->selftest_result));
+}
+
+static int smi_restore_hw_cfg(struct smi_client_data *client);
+
+/*!
+ * @brief store selftest result which make up of acc and gyro
+ * format: 0b 0000 xxxx x:1 failed, 0 success
+ * bit3: gyro_self
+ * bit2..0: acc_self z y x
+ */
+static ssize_t smi130_selftest_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ int err = 0;
+ int i = 0;
+
+ u8 acc_selftest = 0;
+ u8 gyro_selftest = 0;
+ u8 smi_selftest = 0;
+ s16 axis_p_value, axis_n_value;
+ u16 diff_axis[3] = {0xff, 0xff, 0xff};
+ u8 acc_odr, range, acc_selftest_amp, acc_selftest_sign;
+
+ dev_notice(client_data->dev, "Selftest for SMI16x starting.\n");
+
+ client_data->selftest = 1;
+
+ /*soft reset*/
+ err = SMI_CALL_API(set_command_register)(CMD_RESET_USER_REG);
+ msleep(70);
+ err += SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_acc_arr[SMI_ACC_PM_NORMAL]);
+ err += SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_gyro_arr[SMI_GYRO_PM_NORMAL]);
+ err += SMI_CALL_API(set_accel_under_sampling_parameter)(0);
+ err += SMI_CALL_API(set_accel_output_data_rate)(
+ SMI130_ACCEL_OUTPUT_DATA_RATE_1600HZ);
+
+ /* set to 8G range*/
+ err += SMI_CALL_API(set_accel_range)(SMI130_ACCEL_RANGE_8G);
+ /* set to self amp high */
+ err += SMI_CALL_API(set_accel_selftest_amp)(SMI_SELFTEST_AMP_HIGH);
+
+
+ err += SMI_CALL_API(get_accel_output_data_rate)(&acc_odr);
+ err += SMI_CALL_API(get_accel_range)(&range);
+ err += SMI_CALL_API(get_accel_selftest_amp)(&acc_selftest_amp);
+ err += SMI_CALL_API(read_accel_x)(&axis_n_value);
+
+ dev_info(client_data->dev,
+ "acc_odr:%d, acc_range:%d, acc_selftest_amp:%d, acc_x:%d\n",
+ acc_odr, range, acc_selftest_amp, axis_n_value);
+
+ for (i = X_AXIS; i < AXIS_MAX; i++) {
+ axis_n_value = 0;
+ axis_p_value = 0;
+ /* set every selftest axis */
+ /*set_acc_selftest_axis(param),param x:1, y:2, z:3
+ * but X_AXIS:0, Y_AXIS:1, Z_AXIS:2
+ * so we need to +1*/
+ err += SMI_CALL_API(set_accel_selftest_axis)(i + 1);
+ msleep(50);
+ switch (i) {
+ case X_AXIS:
+ /* set negative sign */
+ err += SMI_CALL_API(set_accel_selftest_sign)(0);
+ err += SMI_CALL_API(get_accel_selftest_sign)(
+ &acc_selftest_sign);
+
+ msleep(60);
+ err += SMI_CALL_API(read_accel_x)(&axis_n_value);
+ dev_info(client_data->dev,
+ "acc_x_selftest_sign:%d, axis_n_value:%d\n",
+ acc_selftest_sign, axis_n_value);
+
+ /* set postive sign */
+ err += SMI_CALL_API(set_accel_selftest_sign)(1);
+ err += SMI_CALL_API(get_accel_selftest_sign)(
+ &acc_selftest_sign);
+
+ msleep(60);
+ err += SMI_CALL_API(read_accel_x)(&axis_p_value);
+ dev_info(client_data->dev,
+ "acc_x_selftest_sign:%d, axis_p_value:%d\n",
+ acc_selftest_sign, axis_p_value);
+ diff_axis[i] = abs(axis_p_value - axis_n_value);
+ break;
+
+ case Y_AXIS:
+ /* set negative sign */
+ err += SMI_CALL_API(set_accel_selftest_sign)(0);
+ msleep(60);
+ err += SMI_CALL_API(read_accel_y)(&axis_n_value);
+ /* set postive sign */
+ err += SMI_CALL_API(set_accel_selftest_sign)(1);
+ msleep(60);
+ err += SMI_CALL_API(read_accel_y)(&axis_p_value);
+ diff_axis[i] = abs(axis_p_value - axis_n_value);
+ break;
+
+ case Z_AXIS:
+ /* set negative sign */
+ err += SMI_CALL_API(set_accel_selftest_sign)(0);
+ msleep(60);
+ err += SMI_CALL_API(read_accel_z)(&axis_n_value);
+ /* set postive sign */
+ err += SMI_CALL_API(set_accel_selftest_sign)(1);
+ msleep(60);
+ err += SMI_CALL_API(read_accel_z)(&axis_p_value);
+ /* also start gyro self test */
+ err += SMI_CALL_API(set_gyro_selftest_start)(1);
+ msleep(60);
+ err += SMI_CALL_API(get_gyro_selftest)(&gyro_selftest);
+
+ diff_axis[i] = abs(axis_p_value - axis_n_value);
+ break;
+ default:
+ err += -EINVAL;
+ break;
+ }
+ if (err) {
+ dev_err(client_data->dev,
+ "Failed selftest axis:%s, p_val=%d, n_val=%d\n",
+ smi_axis_name[i], axis_p_value, axis_n_value);
+ client_data->selftest = 0;
+ return -EINVAL;
+ }
+
+ /*400mg for acc z axis*/
+ if (Z_AXIS == i) {
+ if (diff_axis[i] < 1639) {
+ acc_selftest |= 1 << i;
+ dev_err(client_data->dev,
+ "Over selftest minimum for "
+ "axis:%s,diff=%d,p_val=%d, n_val=%d\n",
+ smi_axis_name[i], diff_axis[i],
+ axis_p_value, axis_n_value);
+ }
+ } else {
+ /*800mg for x or y axis*/
+ if (diff_axis[i] < 3277) {
+ acc_selftest |= 1 << i;
+
+ if (smi_get_err_status(client_data) < 0)
+ return err;
+ dev_err(client_data->dev,
+ "Over selftest minimum for "
+ "axis:%s,diff=%d, p_val=%d, n_val=%d\n",
+ smi_axis_name[i], diff_axis[i],
+ axis_p_value, axis_n_value);
+ dev_err(client_data->dev, "err_st:0x%x\n",
+ client_data->err_st.err_st_all);
+
+ }
+ }
+
+ }
+ /* gyro_selftest==1,gyro selftest successfully,
+ * but smi_result bit4 0 is successful, 1 is failed*/
+ smi_selftest = (acc_selftest & 0x0f) | ((!gyro_selftest) << AXIS_MAX);
+ atomic_set(&client_data->selftest_result, smi_selftest);
+ /*soft reset*/
+ err = SMI_CALL_API(set_command_register)(CMD_RESET_USER_REG);
+ if (err) {
+ client_data->selftest = 0;
+ return err;
+ }
+ msleep(50);
+
+ smi_restore_hw_cfg(client_data);
+
+ client_data->selftest = 0;
+ dev_notice(client_data->dev, "Selftest for SMI16x finished\n");
+
+ return count;
+}
+
+/* gyro sensor part */
+static ssize_t smi130_gyro_op_mode_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ int err = 0;
+ u8 gyro_pmu_status = 0;
+
+ err = SMI_CALL_API(get_gyro_power_mode_stat)(
+ &gyro_pmu_status);
+
+ if (err)
+ return err;
+ else
+ return snprintf(buf, 32, "reg:%d, val:%d\n", gyro_pmu_status,
+ client_data->pw.gyro_pm);
+}
+
+static ssize_t smi130_gyro_op_mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ unsigned long op_mode;
+ int err;
+
+ err = kstrtoul(buf, 10, &op_mode);
+ if (err)
+ return err;
+
+ mutex_lock(&client_data->mutex_op_mode);
+
+ if (op_mode < SMI_GYRO_PM_MAX) {
+ switch (op_mode) {
+ case SMI_GYRO_PM_NORMAL:
+ err = SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_gyro_arr[SMI_GYRO_PM_NORMAL]);
+ client_data->pw.gyro_pm = SMI_GYRO_PM_NORMAL;
+ smi_delay(60);
+ break;
+ case SMI_GYRO_PM_FAST_START:
+ err = SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_gyro_arr[SMI_GYRO_PM_FAST_START]);
+ client_data->pw.gyro_pm = SMI_GYRO_PM_FAST_START;
+ smi_delay(60);
+ break;
+ case SMI_GYRO_PM_SUSPEND:
+ err = SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_gyro_arr[SMI_GYRO_PM_SUSPEND]);
+ client_data->pw.gyro_pm = SMI_GYRO_PM_SUSPEND;
+ smi_delay(60);
+ break;
+ default:
+ mutex_unlock(&client_data->mutex_op_mode);
+ return -EINVAL;
+ }
+ } else {
+ mutex_unlock(&client_data->mutex_op_mode);
+ return -EINVAL;
+ }
+
+ mutex_unlock(&client_data->mutex_op_mode);
+
+ if (err)
+ return err;
+ else
+ return count;
+
+}
+
+static ssize_t smi130_gyro_value_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct smi130_gyro_t data;
+ int err;
+
+ err = SMI_CALL_API(read_gyro_xyz)(&data);
+ if (err < 0)
+ return err;
+
+
+ return snprintf(buf, 48, "%hd %hd %hd\n", data.x,
+ data.y, data.z);
+}
+
+static ssize_t smi130_gyro_range_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char range;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = SMI_CALL_API(get_gyro_range)(&range);
+ if (err)
+ return err;
+
+ client_data->range.gyro_range = range;
+ return snprintf(buf, 16, "%d\n", range);
+}
+
+static ssize_t smi130_gyro_range_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long range;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &range);
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_gyro_range)(range);
+ if (err)
+ return -EIO;
+
+ client_data->range.gyro_range = range;
+ return count;
+}
+
+static ssize_t smi130_gyro_odr_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err;
+ unsigned char gyro_odr;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = SMI_CALL_API(get_gyro_output_data_rate)(&gyro_odr);
+ if (err)
+ return err;
+
+ client_data->odr.gyro_odr = gyro_odr;
+ return snprintf(buf, 16, "%d\n", gyro_odr);
+}
+
+static ssize_t smi130_gyro_odr_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long gyro_odr;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &gyro_odr);
+ if (err)
+ return err;
+
+ if (gyro_odr < 6 || gyro_odr > 13)
+ return -EIO;
+
+ err = SMI_CALL_API(set_gyro_output_data_rate)(gyro_odr);
+ if (err)
+ return -EIO;
+
+ client_data->odr.gyro_odr = gyro_odr;
+ return count;
+}
+
+static ssize_t smi130_gyro_fast_calibration_en_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ int err;
+
+ err = SMI_CALL_API(get_foc_gyro_enable)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_gyro_fast_calibration_en_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long enable;
+ s8 err;
+ s16 gyr_off_x;
+ s16 gyr_off_y;
+ s16 gyr_off_z;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &enable);
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_foc_gyro_enable)((u8)enable,
+ &gyr_off_x, &gyr_off_y, &gyr_off_z);
+
+ if (err < 0)
+ return -EIO;
+ else {
+ input_event(client_data->input, EV_MSC,
+ INPUT_EVENT_FAST_GYRO_CALIB_DONE, 1);
+ input_sync(client_data->input);
+ }
+ return count;
+}
+
+static ssize_t smi130_gyro_offset_x_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ s16 data = 0;
+ s8 err = 0;
+
+ err = SMI_CALL_API(get_gyro_offset_compensation_xaxis)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_gyro_offset_x_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ s8 err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_gyro_offset_compensation_xaxis)((s16)data);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t smi130_gyro_offset_y_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ s16 data = 0;
+ s8 err = 0;
+
+ err = SMI_CALL_API(get_gyro_offset_compensation_yaxis)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_gyro_offset_y_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ s8 err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_gyro_offset_compensation_yaxis)((s16)data);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t smi130_gyro_offset_z_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ s16 data = 0;
+ int err = 0;
+
+ err = SMI_CALL_API(get_gyro_offset_compensation_zaxis)(&data);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "%d\n", data);
+}
+
+static ssize_t smi130_gyro_offset_z_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err = SMI_CALL_API(set_gyro_offset_compensation_zaxis)((s16)data);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+
+/* mag sensor part */
+#ifdef SMI130_MAG_INTERFACE_SUPPORT
+static ssize_t smi130_mag_op_mode_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ u8 mag_op_mode;
+ s8 err;
+ err = smi130_get_mag_power_mode_stat(&mag_op_mode);
+ if (err) {
+ dev_err(client_data->dev,
+ "Failed to get SMI130 mag power mode:%d\n", err);
+ return err;
+ } else
+ return snprintf(buf, 32, "%d, reg:%d\n",
+ client_data->pw.mag_pm, mag_op_mode);
+}
+
+static ssize_t smi130_mag_op_mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ unsigned long op_mode;
+ int err;
+
+ err = kstrtoul(buf, 10, &op_mode);
+ if (err)
+ return err;
+
+ if (op_mode == client_data->pw.mag_pm)
+ return count;
+
+ mutex_lock(&client_data->mutex_op_mode);
+
+
+ if (op_mode < SMI_MAG_PM_MAX) {
+ switch (op_mode) {
+ case SMI_MAG_PM_NORMAL:
+ /* need to modify as mag sensor connected,
+ * set write address to 0x4c and triggers
+ * write operation
+ * 0x4c(op mode control reg)
+ * enables normal mode in magnetometer */
+#if defined(SMI130_AKM09912_SUPPORT)
+ err = smi130_set_bosch_akm_and_secondary_if_powermode(
+ SMI130_MAG_FORCE_MODE);
+#else
+ err = smi130_set_bmm150_mag_and_secondary_if_power_mode(
+ SMI130_MAG_FORCE_MODE);
+#endif
+ client_data->pw.mag_pm = SMI_MAG_PM_NORMAL;
+ smi_delay(5);
+ break;
+ case SMI_MAG_PM_LP1:
+ /* need to modify as mag sensor connected,
+ * set write address to 0x4 band triggers
+ * write operation
+ * 0x4b(bmm150, power control reg, bit0)
+ * enables power in magnetometer*/
+#if defined(SMI130_AKM09912_SUPPORT)
+ err = smi130_set_bosch_akm_and_secondary_if_powermode(
+ SMI130_MAG_FORCE_MODE);
+#else
+ err = smi130_set_bmm150_mag_and_secondary_if_power_mode(
+ SMI130_MAG_FORCE_MODE);
+#endif
+ client_data->pw.mag_pm = SMI_MAG_PM_LP1;
+ smi_delay(5);
+ break;
+ case SMI_MAG_PM_SUSPEND:
+ case SMI_MAG_PM_LP2:
+#if defined(SMI130_AKM09912_SUPPORT)
+ err = smi130_set_bosch_akm_and_secondary_if_powermode(
+ SMI130_MAG_SUSPEND_MODE);
+#else
+ err = smi130_set_bmm150_mag_and_secondary_if_power_mode(
+ SMI130_MAG_SUSPEND_MODE);
+#endif
+ client_data->pw.mag_pm = op_mode;
+ smi_delay(5);
+ break;
+ default:
+ mutex_unlock(&client_data->mutex_op_mode);
+ return -EINVAL;
+ }
+ } else {
+ mutex_unlock(&client_data->mutex_op_mode);
+ return -EINVAL;
+ }
+
+ mutex_unlock(&client_data->mutex_op_mode);
+
+ if (err) {
+ dev_err(client_data->dev,
+ "Failed to switch SMI130 mag power mode:%d\n",
+ client_data->pw.mag_pm);
+ return err;
+ } else
+ return count;
+
+}
+
+static ssize_t smi130_mag_odr_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err = 0;
+ unsigned char mag_odr = 0;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = SMI_CALL_API(get_mag_output_data_rate)(&mag_odr);
+ if (err)
+ return err;
+
+ client_data->odr.mag_odr = mag_odr;
+ return snprintf(buf, 16, "%d\n", mag_odr);
+}
+
+static ssize_t smi130_mag_odr_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long mag_odr;
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ err = kstrtoul(buf, 10, &mag_odr);
+ if (err)
+ return err;
+ /*1~25/32hz,..6(25hz),7(50hz),... */
+ err = SMI_CALL_API(set_mag_output_data_rate)(mag_odr);
+ if (err)
+ return -EIO;
+
+ client_data->odr.mag_odr = mag_odr;
+ return count;
+}
+
+static ssize_t smi130_mag_i2c_address_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ u8 data;
+ s8 err;
+
+ err = SMI_CALL_API(set_mag_manual_enable)(1);
+ err += SMI_CALL_API(get_i2c_device_addr)(&data);
+ err += SMI_CALL_API(set_mag_manual_enable)(0);
+
+ if (err < 0)
+ return err;
+ return snprintf(buf, 16, "0x%x\n", data);
+}
+
+static ssize_t smi130_mag_i2c_address_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err += SMI_CALL_API(set_mag_manual_enable)(1);
+ if (!err)
+ err += SMI_CALL_API(set_i2c_device_addr)((unsigned char)data);
+ err += SMI_CALL_API(set_mag_manual_enable)(0);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t smi130_mag_value_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ struct smi130_mag_xyz_s32_t data;
+ int err;
+ /* raw data with compensation */
+#if defined(SMI130_AKM09912_SUPPORT)
+ err = smi130_bosch_akm09912_compensate_xyz(&data);
+#else
+ err = smi130_bmm150_mag_compensate_xyz(&data);
+#endif
+
+ if (err < 0) {
+ memset(&data, 0, sizeof(data));
+ dev_err(client_data->dev, "mag not ready!\n");
+ }
+ return snprintf(buf, 48, "%hd %hd %hd\n", data.x,
+ data.y, data.z);
+}
+static ssize_t smi130_mag_offset_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int err = 0;
+ unsigned char mag_offset;
+ err = SMI_CALL_API(get_mag_offset)(&mag_offset);
+ if (err)
+ return err;
+
+ return snprintf(buf, 16, "%d\n", mag_offset);
+
+}
+
+static ssize_t smi130_mag_offset_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int err;
+
+ err = kstrtoul(buf, 10, &data);
+ if (err)
+ return err;
+
+ err += SMI_CALL_API(set_mag_manual_enable)(1);
+ if (err == 0)
+ err += SMI_CALL_API(set_mag_offset)((unsigned char)data);
+ err += SMI_CALL_API(set_mag_manual_enable)(0);
+
+ if (err < 0)
+ return -EIO;
+ return count;
+}
+
+static ssize_t smi130_mag_chip_id_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ s8 err = 0;
+ u8 mag_chipid;
+
+ err = smi130_set_mag_manual_enable(0x01);
+ /* read mag chip_id value */
+#if defined(SMI130_AKM09912_SUPPORT)
+ err += smi130_set_mag_read_addr(AKM09912_CHIP_ID_REG);
+ /* 0x04 is mag_x lsb register */
+ err += smi130_read_reg(SMI130_USER_DATA_0_MAG_X_LSB__REG,
+ &mag_chipid, 1);
+
+ /* Must add this commands to re-set data register addr of mag sensor */
+ err += smi130_set_mag_read_addr(AKM_DATA_REGISTER);
+#else
+ err += smi130_set_mag_read_addr(SMI130_BMM150_CHIP_ID);
+ /* 0x04 is mag_x lsb register */
+ err += smi130_read_reg(SMI130_USER_DATA_0_MAG_X_LSB__REG,
+ &mag_chipid, 1);
+
+ /* Must add this commands to re-set data register addr of mag sensor */
+ /* 0x42 is bmm150 data register address */
+ err += smi130_set_mag_read_addr(SMI130_BMM150_DATA_REG);
+#endif
+
+ err += smi130_set_mag_manual_enable(0x00);
+
+ if (err)
+ return err;
+
+ return snprintf(buf, 16, "%x\n", mag_chipid);
+
+}
+
+static ssize_t smi130_mag_chip_name_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ u8 mag_chipid = 0;
+#if defined(SMI130_AKM09912_SUPPORT)
+ mag_chipid = 15;
+#else
+ mag_chipid = 150;
+#endif
+ return snprintf(buf, 16, "%d\n", mag_chipid);
+}
+
+struct smi130_mag_xyz_s32_t mag_compensate;
+static ssize_t smi130_mag_compensate_xyz_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ memcpy(buf, &mag_compensate, sizeof(mag_compensate));
+ return sizeof(mag_compensate);
+}
+static ssize_t smi130_mag_compensate_xyz_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct smi130_mag_xyzr_t mag_raw;
+ memset(&mag_compensate, 0, sizeof(mag_compensate));
+ memset(&mag_raw, 0, sizeof(mag_raw));
+ mag_raw.x = (buf[1] << 8 | buf[0]);
+ mag_raw.y = (buf[3] << 8 | buf[2]);
+ mag_raw.z = (buf[5] << 8 | buf[4]);
+ mag_raw.r = (buf[7] << 8 | buf[6]);
+ mag_raw.x = mag_raw.x >> 3;
+ mag_raw.y = mag_raw.y >> 3;
+ mag_raw.z = mag_raw.z >> 1;
+ mag_raw.r = mag_raw.r >> 2;
+ smi130_bmm150_mag_compensate_xyz_raw(
+ &mag_compensate, mag_raw);
+ return count;
+}
+
+#endif
+
+#if defined(SMI130_ENABLE_INT1) || defined(SMI130_ENABLE_INT2)
+static ssize_t smi_enable_int_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int interrupt_type, value;
+
+ sscanf(buf, "%3d %3d", &interrupt_type, &value);
+
+ if (interrupt_type < 0 || interrupt_type > 16)
+ return -EINVAL;
+
+ if (interrupt_type <= SMI_FLAT_INT) {
+ if (SMI_CALL_API(set_intr_enable_0)
+ (smi_interrupt_type[interrupt_type], value) < 0)
+ return -EINVAL;
+ } else if (interrupt_type <= SMI_FWM_INT) {
+ if (SMI_CALL_API(set_intr_enable_1)
+ (smi_interrupt_type[interrupt_type], value) < 0)
+ return -EINVAL;
+ } else {
+ if (SMI_CALL_API(set_intr_enable_2)
+ (smi_interrupt_type[interrupt_type], value) < 0)
+ return -EINVAL;
+ }
+
+ return count;
+}
+
+#endif
+
+static ssize_t smi130_show_reg_sel(struct device *dev
+ , struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ if (client_data == NULL) {
+ printk(KERN_ERR "Invalid client_data pointer");
+ return -ENODEV;
+ }
+
+ return snprintf(buf, 64, "reg=0X%02X, len=%d\n",
+ client_data->reg_sel, client_data->reg_len);
+}
+
+static ssize_t smi130_store_reg_sel(struct device *dev
+ , struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ ssize_t ret;
+
+ if (client_data == NULL) {
+ printk(KERN_ERR "Invalid client_data pointer");
+ return -ENODEV;
+ }
+ ret = sscanf(buf, "%11X %11d",
+ &client_data->reg_sel, &client_data->reg_len);
+ if (ret != 2) {
+ dev_err(client_data->dev, "Invalid argument");
+ return -EINVAL;
+ }
+
+ return count;
+}
+
+static ssize_t smi130_show_reg_val(struct device *dev
+ , struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+
+ ssize_t ret;
+ u8 reg_data[128], i;
+ int pos;
+
+ if (client_data == NULL) {
+ printk(KERN_ERR "Invalid client_data pointer");
+ return -ENODEV;
+ }
+
+ ret = smi_burst_read_wrapper(client_data->device.dev_addr,
+ client_data->reg_sel,
+ reg_data, client_data->reg_len);
+ if (ret < 0) {
+ dev_err(client_data->dev, "Reg op failed");
+ return ret;
+ }
+
+ pos = 0;
+ for (i = 0; i < client_data->reg_len; ++i) {
+ pos += snprintf(buf + pos, 16, "%02X", reg_data[i]);
+ buf[pos++] = (i + 1) % 16 == 0 ? '\n' : ' ';
+ }
+ if (buf[pos - 1] == ' ')
+ buf[pos - 1] = '\n';
+
+ return pos;
+}
+
+static ssize_t smi130_store_reg_val(struct device *dev
+ , struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ ssize_t ret;
+ u8 reg_data[32];
+ int i, j, status, digit;
+
+ if (client_data == NULL) {
+ printk(KERN_ERR "Invalid client_data pointer");
+ return -ENODEV;
+ }
+ status = 0;
+ for (i = j = 0; i < count && j < client_data->reg_len; ++i) {
+ if (buf[i] == ' ' || buf[i] == '\n' || buf[i] == '\t' ||
+ buf[i] == '\r') {
+ status = 0;
+ ++j;
+ continue;
+ }
+ digit = buf[i] & 0x10 ? (buf[i] & 0xF) : ((buf[i] & 0xF) + 9);
+ printk(KERN_INFO "digit is %d", digit);
+ switch (status) {
+ case 2:
+ ++j; /* Fall thru */
+ case 0:
+ reg_data[j] = digit;
+ status = 1;
+ break;
+ case 1:
+ reg_data[j] = reg_data[j] * 16 + digit;
+ status = 2;
+ break;
+ }
+ }
+ if (status > 0)
+ ++j;
+ if (j > client_data->reg_len)
+ j = client_data->reg_len;
+ else if (j < client_data->reg_len) {
+ dev_err(client_data->dev, "Invalid argument");
+ return -EINVAL;
+ }
+ printk(KERN_INFO "Reg data read as");
+ for (i = 0; i < j; ++i)
+ printk(KERN_INFO "%d", reg_data[i]);
+
+ ret = SMI_CALL_API(write_reg)(
+ client_data->reg_sel,
+ reg_data, client_data->reg_len);
+ if (ret < 0) {
+ dev_err(client_data->dev, "Reg op failed");
+ return ret;
+ }
+
+ return count;
+}
+
+static ssize_t smi130_driver_version_show(struct device *dev
+ , struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct smi_client_data *client_data = input_get_drvdata(input);
+ int ret;
+
+ if (client_data == NULL) {
+ printk(KERN_ERR "Invalid client_data pointer");
+ return -ENODEV;
+ }
+
+ ret = snprintf(buf, 128, "Driver version: %s\n",
+ DRIVER_VERSION);
+
+ return ret;
+}
+static DEVICE_ATTR(chip_id, S_IRUGO,
+ smi130_chip_id_show, NULL);
+static DEVICE_ATTR(err_st, S_IRUGO,
+ smi130_err_st_show, NULL);
+static DEVICE_ATTR(sensor_time, S_IRUGO,
+ smi130_sensor_time_show, NULL);
+
+static DEVICE_ATTR(selftest, S_IRUGO | S_IWUSR,
+ smi130_selftest_show, smi130_selftest_store);
+static DEVICE_ATTR(fifo_flush, S_IRUGO | S_IWUSR,
+ NULL, smi130_fifo_flush_store);
+static DEVICE_ATTR(fifo_bytecount, S_IRUGO | S_IWUSR,
+ smi130_fifo_bytecount_show, smi130_fifo_bytecount_store);
+static DEVICE_ATTR(fifo_data_sel, S_IRUGO | S_IWUSR,
+ smi130_fifo_data_sel_show, smi130_fifo_data_sel_store);
+static DEVICE_ATTR(fifo_data_frame, S_IRUGO,
+ smi130_fifo_data_out_frame_show, NULL);
+
+static DEVICE_ATTR(fifo_watermark, S_IRUGO | S_IWUSR,
+ smi130_fifo_watermark_show, smi130_fifo_watermark_store);
+
+static DEVICE_ATTR(fifo_header_en, S_IRUGO | S_IWUSR,
+ smi130_fifo_header_en_show, smi130_fifo_header_en_store);
+static DEVICE_ATTR(fifo_time_en, S_IRUGO | S_IWUSR,
+ smi130_fifo_time_en_show, smi130_fifo_time_en_store);
+static DEVICE_ATTR(fifo_int_tag_en, S_IRUGO | S_IWUSR,
+ smi130_fifo_int_tag_en_show, smi130_fifo_int_tag_en_store);
+
+static DEVICE_ATTR(temperature, S_IRUGO,
+ smi130_temperature_show, NULL);
+static DEVICE_ATTR(place, S_IRUGO,
+ smi130_place_show, NULL);
+static DEVICE_ATTR(delay, S_IRUGO | S_IWUSR,
+ smi130_delay_show, smi130_delay_store);
+static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR,
+ smi130_enable_show, smi130_enable_store);
+static DEVICE_ATTR(acc_range, S_IRUGO | S_IWUSR,
+ smi130_acc_range_show, smi130_acc_range_store);
+static DEVICE_ATTR(acc_odr, S_IRUGO | S_IWUSR,
+ smi130_acc_odr_show, smi130_acc_odr_store);
+static DEVICE_ATTR(acc_op_mode, S_IRUGO | S_IWUSR,
+ smi130_acc_op_mode_show, smi130_acc_op_mode_store);
+static DEVICE_ATTR(acc_value, S_IRUGO,
+ smi130_acc_value_show, NULL);
+static DEVICE_ATTR(acc_fast_calibration_x, S_IRUGO | S_IWUSR,
+ smi130_acc_fast_calibration_x_show,
+ smi130_acc_fast_calibration_x_store);
+static DEVICE_ATTR(acc_fast_calibration_y, S_IRUGO | S_IWUSR,
+ smi130_acc_fast_calibration_y_show,
+ smi130_acc_fast_calibration_y_store);
+static DEVICE_ATTR(acc_fast_calibration_z, S_IRUGO | S_IWUSR,
+ smi130_acc_fast_calibration_z_show,
+ smi130_acc_fast_calibration_z_store);
+static DEVICE_ATTR(acc_offset_x, S_IRUGO | S_IWUSR,
+ smi130_acc_offset_x_show,
+ smi130_acc_offset_x_store);
+static DEVICE_ATTR(acc_offset_y, S_IRUGO | S_IWUSR,
+ smi130_acc_offset_y_show,
+ smi130_acc_offset_y_store);
+static DEVICE_ATTR(acc_offset_z, S_IRUGO | S_IWUSR,
+ smi130_acc_offset_z_show,
+ smi130_acc_offset_z_store);
+static DEVICE_ATTR(test, S_IRUGO,
+ smi130_test_show, NULL);
+static DEVICE_ATTR(stc_enable, S_IRUGO | S_IWUSR,
+ smi130_step_counter_enable_show,
+ smi130_step_counter_enable_store);
+static DEVICE_ATTR(stc_mode, S_IRUGO | S_IWUSR,
+ NULL, smi130_step_counter_mode_store);
+static DEVICE_ATTR(stc_clc, S_IRUGO | S_IWUSR,
+ NULL, smi130_step_counter_clc_store);
+static DEVICE_ATTR(stc_value, S_IRUGO,
+ smi130_step_counter_value_show, NULL);
+static DEVICE_ATTR(reg_sel, S_IRUGO | S_IWUSR,
+ smi130_show_reg_sel, smi130_store_reg_sel);
+static DEVICE_ATTR(reg_val, S_IRUGO | S_IWUSR,
+ smi130_show_reg_val, smi130_store_reg_val);
+static DEVICE_ATTR(driver_version, S_IRUGO,
+ smi130_driver_version_show, NULL);
+/* gyro part */
+static DEVICE_ATTR(gyro_op_mode, S_IRUGO | S_IWUSR,
+ smi130_gyro_op_mode_show, smi130_gyro_op_mode_store);
+static DEVICE_ATTR(gyro_value, S_IRUGO,
+ smi130_gyro_value_show, NULL);
+static DEVICE_ATTR(gyro_range, S_IRUGO | S_IWUSR,
+ smi130_gyro_range_show, smi130_gyro_range_store);
+static DEVICE_ATTR(gyro_odr, S_IRUGO | S_IWUSR,
+ smi130_gyro_odr_show, smi130_gyro_odr_store);
+static DEVICE_ATTR(gyro_fast_calibration_en, S_IRUGO | S_IWUSR,
+smi130_gyro_fast_calibration_en_show, smi130_gyro_fast_calibration_en_store);
+static DEVICE_ATTR(gyro_offset_x, S_IRUGO | S_IWUSR,
+smi130_gyro_offset_x_show, smi130_gyro_offset_x_store);
+static DEVICE_ATTR(gyro_offset_y, S_IRUGO | S_IWUSR,
+smi130_gyro_offset_y_show, smi130_gyro_offset_y_store);
+static DEVICE_ATTR(gyro_offset_z, S_IRUGO | S_IWUSR,
+smi130_gyro_offset_z_show, smi130_gyro_offset_z_store);
+
+#ifdef SMI130_MAG_INTERFACE_SUPPORT
+static DEVICE_ATTR(mag_op_mode, S_IRUGO | S_IWUSR,
+ smi130_mag_op_mode_show, smi130_mag_op_mode_store);
+static DEVICE_ATTR(mag_odr, S_IRUGO | S_IWUSR,
+ smi130_mag_odr_show, smi130_mag_odr_store);
+static DEVICE_ATTR(mag_i2c_addr, S_IRUGO | S_IWUSR,
+ smi130_mag_i2c_address_show, smi130_mag_i2c_address_store);
+static DEVICE_ATTR(mag_value, S_IRUGO,
+ smi130_mag_value_show, NULL);
+static DEVICE_ATTR(mag_offset, S_IRUGO | S_IWUSR,
+ smi130_mag_offset_show, smi130_mag_offset_store);
+static DEVICE_ATTR(mag_chip_id, S_IRUGO,
+ smi130_mag_chip_id_show, NULL);
+static DEVICE_ATTR(mag_chip_name, S_IRUGO,
+ smi130_mag_chip_name_show, NULL);
+static DEVICE_ATTR(mag_compensate, S_IRUGO | S_IWUSR,
+ smi130_mag_compensate_xyz_show,
+ smi130_mag_compensate_xyz_store);
+#endif
+
+
+#if defined(SMI130_ENABLE_INT1) || defined(SMI130_ENABLE_INT2)
+static DEVICE_ATTR(enable_int, S_IRUGO | S_IWUSR,
+ NULL, smi_enable_int_store);
+static DEVICE_ATTR(anymot_duration, S_IRUGO | S_IWUSR,
+ smi130_anymot_duration_show, smi130_anymot_duration_store);
+static DEVICE_ATTR(anymot_threshold, S_IRUGO | S_IWUSR,
+ smi130_anymot_threshold_show, smi130_anymot_threshold_store);
+static DEVICE_ATTR(std_stu, S_IRUGO,
+ smi130_step_detector_status_show, NULL);
+static DEVICE_ATTR(std_en, S_IRUGO | S_IWUSR,
+ smi130_step_detector_enable_show,
+ smi130_step_detector_enable_store);
+static DEVICE_ATTR(sig_en, S_IRUGO | S_IWUSR,
+ smi130_signification_motion_enable_show,
+ smi130_signification_motion_enable_store);
+
+#endif
+
+
+
+static DEVICE_ATTR(smi_value, S_IRUGO,
+ smi130_smi_value_show, NULL);
+
+
+static struct attribute *smi130_attributes[] = {
+ &dev_attr_chip_id.attr,
+ &dev_attr_err_st.attr,
+ &dev_attr_sensor_time.attr,
+ &dev_attr_selftest.attr,
+ &dev_attr_driver_version.attr,
+ &dev_attr_test.attr,
+ &dev_attr_fifo_flush.attr,
+ &dev_attr_fifo_header_en.attr,
+ &dev_attr_fifo_time_en.attr,
+ &dev_attr_fifo_int_tag_en.attr,
+ &dev_attr_fifo_bytecount.attr,
+ &dev_attr_fifo_data_sel.attr,
+ &dev_attr_fifo_data_frame.attr,
+
+ &dev_attr_fifo_watermark.attr,
+
+ &dev_attr_enable.attr,
+ &dev_attr_delay.attr,
+ &dev_attr_temperature.attr,
+ &dev_attr_place.attr,
+
+ &dev_attr_acc_range.attr,
+ &dev_attr_acc_odr.attr,
+ &dev_attr_acc_op_mode.attr,
+ &dev_attr_acc_value.attr,
+
+ &dev_attr_acc_fast_calibration_x.attr,
+ &dev_attr_acc_fast_calibration_y.attr,
+ &dev_attr_acc_fast_calibration_z.attr,
+ &dev_attr_acc_offset_x.attr,
+ &dev_attr_acc_offset_y.attr,
+ &dev_attr_acc_offset_z.attr,
+
+ &dev_attr_stc_enable.attr,
+ &dev_attr_stc_mode.attr,
+ &dev_attr_stc_clc.attr,
+ &dev_attr_stc_value.attr,
+
+ &dev_attr_gyro_op_mode.attr,
+ &dev_attr_gyro_value.attr,
+ &dev_attr_gyro_range.attr,
+ &dev_attr_gyro_odr.attr,
+ &dev_attr_gyro_fast_calibration_en.attr,
+ &dev_attr_gyro_offset_x.attr,
+ &dev_attr_gyro_offset_y.attr,
+ &dev_attr_gyro_offset_z.attr,
+
+#ifdef SMI130_MAG_INTERFACE_SUPPORT
+ &dev_attr_mag_chip_id.attr,
+ &dev_attr_mag_op_mode.attr,
+ &dev_attr_mag_odr.attr,
+ &dev_attr_mag_i2c_addr.attr,
+ &dev_attr_mag_chip_name.attr,
+ &dev_attr_mag_value.attr,
+ &dev_attr_mag_offset.attr,
+ &dev_attr_mag_compensate.attr,
+#endif
+
+#if defined(SMI130_ENABLE_INT1) || defined(SMI130_ENABLE_INT2)
+ &dev_attr_enable_int.attr,
+
+ &dev_attr_anymot_duration.attr,
+ &dev_attr_anymot_threshold.attr,
+ &dev_attr_std_stu.attr,
+ &dev_attr_std_en.attr,
+ &dev_attr_sig_en.attr,
+
+#endif
+ &dev_attr_reg_sel.attr,
+ &dev_attr_reg_val.attr,
+ &dev_attr_smi_value.attr,
+ NULL
+};
+
+static struct attribute_group smi130_attribute_group = {
+ .attrs = smi130_attributes
+};
+
+#if defined(SMI130_ENABLE_INT1) || defined(SMI130_ENABLE_INT2)
+static void smi_slope_interrupt_handle(struct smi_client_data *client_data)
+{
+ /* anym_first[0..2]: x, y, z */
+ u8 anym_first[3] = {0};
+ u8 status2;
+ u8 anym_sign;
+ u8 i = 0;
+
+ client_data->device.bus_read(client_data->device.dev_addr,
+ SMI130_USER_INTR_STAT_2_ADDR, &status2, 1);
+ anym_first[0] = SMI130_GET_BITSLICE(status2,
+ SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_X);
+ anym_first[1] = SMI130_GET_BITSLICE(status2,
+ SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_Y);
+ anym_first[2] = SMI130_GET_BITSLICE(status2,
+ SMI130_USER_INTR_STAT_2_ANY_MOTION_FIRST_Z);
+ anym_sign = SMI130_GET_BITSLICE(status2,
+ SMI130_USER_INTR_STAT_2_ANY_MOTION_SIGN);
+
+ for (i = 0; i < 3; i++) {
+ if (anym_first[i]) {
+ /*1: negative*/
+ if (anym_sign)
+ dev_notice(client_data->dev,
+ "Anymotion interrupt happend!"
+ "%s axis, negative sign\n", smi_axis_name[i]);
+ else
+ dev_notice(client_data->dev,
+ "Anymotion interrupt happend!"
+ "%s axis, postive sign\n", smi_axis_name[i]);
+ }
+ }
+
+
+}
+
+static void smi_fifo_watermark_interrupt_handle
+ (struct smi_client_data *client_data)
+{
+ int err = 0;
+ unsigned int fifo_len0 = 0;
+ unsigned int fifo_frmbytes_ext = 0;
+ unsigned char *fifo_data = NULL;
+ fifo_data = kzalloc(FIFO_DATA_BUFSIZE, GFP_KERNEL);
+ /*TO DO*/
+ if (NULL == fifo_data) {
+ dev_err(client_data->dev, "no memory available");
+ err = -ENOMEM;
+ }
+ smi_fifo_frame_bytes_extend_calc(client_data, &fifo_frmbytes_ext);
+
+ if (client_data->pw.acc_pm == 2 && client_data->pw.gyro_pm == 2
+ && client_data->pw.mag_pm == 2)
+ printk(KERN_INFO "pw_acc: %d, pw_gyro: %d\n",
+ client_data->pw.acc_pm, client_data->pw.gyro_pm);
+ if (!client_data->fifo_data_sel)
+ printk(KERN_INFO "no selsect sensor fifo, fifo_data_sel:%d\n",
+ client_data->fifo_data_sel);
+
+ err = SMI_CALL_API(fifo_length)(&fifo_len0);
+ client_data->fifo_bytecount = fifo_len0;
+
+ if (client_data->fifo_bytecount == 0 || err)
+ return;
+
+ if (client_data->fifo_bytecount + fifo_frmbytes_ext > FIFO_DATA_BUFSIZE)
+ client_data->fifo_bytecount = FIFO_DATA_BUFSIZE;
+ /* need give attention for the time of burst read*/
+ if (!err) {
+ err = smi_burst_read_wrapper(client_data->device.dev_addr,
+ SMI130_USER_FIFO_DATA__REG, fifo_data,
+ client_data->fifo_bytecount + fifo_frmbytes_ext);
+ } else
+ dev_err(client_data->dev, "read fifo leght err");
+
+ if (err)
+ dev_err(client_data->dev, "brust read fifo err\n");
+ /*err = smi_fifo_analysis_handle(client_data, fifo_data,
+ client_data->fifo_bytecount + 20, fifo_out_data);*/
+ if (fifo_data != NULL) {
+ kfree(fifo_data);
+ fifo_data = NULL;
+ }
+
+}
+static void smi_data_ready_interrupt_handle(
+ struct smi_client_data *client_data, uint8_t status)
+{
+ uint8_t data12[12] = {0};
+ struct smi130_accel_t accel;
+ struct smi130_gyro_t gyro;
+ struct timespec ts;
+ client_data->device.bus_read(client_data->device.dev_addr,
+ SMI130_USER_DATA_8_ADDR, data12, 12);
+ if (status & 0x80)
+ {
+ /*report acc data*/
+ /* Data X */
+ accel.x = (s16)((((s32)((s8)data12[7])) << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) | (data12[6]));
+ /* Data Y */
+ accel.y = (s16)((((s32)((s8)data12[9])) << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) | (data12[8]));
+ /* Data Z */
+ accel.z = (s16)((((s32)((s8)data12[11]))<< SMI130_SHIFT_BIT_POSITION_BY_08_BITS) | (data12[10]));
+ ts = ns_to_timespec(client_data->timestamp);
+ input_event(client_data->input, EV_MSC, 6, ts.tv_sec);
+ input_event(client_data->input, EV_MSC, 6, ts.tv_nsec);
+ input_event(client_data->input, EV_MSC, MSC_GESTURE, accel.x);
+ input_event(client_data->input, EV_MSC, MSC_RAW, accel.y);
+ input_event(client_data->input, EV_MSC, MSC_SCAN, accel.z);
+ input_sync(client_data->input);
+ }
+ if (status & 0x40)
+ {
+ /*report gyro data*/
+ /* Data X */
+ gyro.x = (s16)((((s32)((s8)data12[1])) << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) | (data12[0]));
+ /* Data Y */
+ gyro.y = (s16)((((s32)((s8)data12[3])) << SMI130_SHIFT_BIT_POSITION_BY_08_BITS) | (data12[2]));
+ /* Data Z */
+ gyro.z = (s16)((((s32)((s8)data12[5]))<< SMI130_SHIFT_BIT_POSITION_BY_08_BITS) | (data12[4]));
+ ts = ns_to_timespec(client_data->timestamp);
+ input_event(client_data->gyro_input, EV_MSC, 6, ts.tv_sec);
+ input_event(client_data->gyro_input, EV_MSC, 6, ts.tv_nsec);
+ input_event(client_data->gyro_input, EV_MSC, MSC_GESTURE, gyro.x);
+ input_event(client_data->gyro_input, EV_MSC, MSC_RAW, gyro.y);
+ input_event(client_data->gyro_input, EV_MSC, MSC_SCAN, gyro.z);
+ input_sync(client_data->gyro_input);
+ }
+}
+
+static void smi_signification_motion_interrupt_handle(
+ struct smi_client_data *client_data)
+{
+ printk(KERN_INFO "smi_signification_motion_interrupt_handle\n");
+ input_event(client_data->input, EV_MSC, INPUT_EVENT_SGM, 1);
+/*input_report_rel(client_data->input,INPUT_EVENT_SGM,1);*/
+ input_sync(client_data->input);
+ smi130_set_command_register(CMD_RESET_INT_ENGINE);
+
+}
+static void smi_stepdetector_interrupt_handle(
+ struct smi_client_data *client_data)
+{
+ u8 current_step_dector_st = 0;
+ client_data->pedo_data.wkar_step_detector_status++;
+ current_step_dector_st =
+ client_data->pedo_data.wkar_step_detector_status;
+ client_data->std = ((current_step_dector_st == 1) ? 0 : 1);
+
+ input_event(client_data->input, EV_MSC, INPUT_EVENT_STEP_DETECTOR, 1);
+ input_sync(client_data->input);
+}
+
+static void smi_irq_work_func(struct work_struct *work)
+{
+ struct smi_client_data *client_data =
+ container_of((struct work_struct *)work,
+ struct smi_client_data, irq_work);
+
+ unsigned char int_status[4] = {0, 0, 0, 0};
+ uint8_t status = 0;
+
+ //client_data->device.bus_read(client_data->device.dev_addr,
+ // SMI130_USER_INTR_STAT_0_ADDR, int_status, 4);
+ client_data->device.bus_read(client_data->device.dev_addr,
+ SMI130_USER_STAT_ADDR, &status, 1);
+ printk("status = 0x%x", status);
+ if (SMI130_GET_BITSLICE(int_status[0],
+ SMI130_USER_INTR_STAT_0_ANY_MOTION))
+ smi_slope_interrupt_handle(client_data);
+
+ if (SMI130_GET_BITSLICE(int_status[0],
+ SMI130_USER_INTR_STAT_0_STEP_INTR))
+ smi_stepdetector_interrupt_handle(client_data);
+ if (SMI130_GET_BITSLICE(int_status[1],
+ SMI130_USER_INTR_STAT_1_FIFO_WM_INTR))
+ smi_fifo_watermark_interrupt_handle(client_data);
+ if ((status & 0x80) || (status & 0x40))
+ smi_data_ready_interrupt_handle(client_data, status);
+ /* Clear ALL inputerrupt status after handler sig mition*/
+ /* Put this commads intot the last one*/
+ if (SMI130_GET_BITSLICE(int_status[0],
+ SMI130_USER_INTR_STAT_0_SIGNIFICANT_INTR))
+ smi_signification_motion_interrupt_handle(client_data);
+
+}
+
+static void smi130_delay_sigmo_work_func(struct work_struct *work)
+{
+ struct smi_client_data *client_data =
+ container_of(work, struct smi_client_data,
+ delay_work_sig.work);
+ unsigned char int_status[4] = {0, 0, 0, 0};
+
+ client_data->device.bus_read(client_data->device.dev_addr,
+ SMI130_USER_INTR_STAT_0_ADDR, int_status, 4);
+ if (SMI130_GET_BITSLICE(int_status[0],
+ SMI130_USER_INTR_STAT_0_SIGNIFICANT_INTR))
+ smi_signification_motion_interrupt_handle(client_data);
+}
+
+static irqreturn_t smi_irq_handler(int irq, void *handle)
+{
+ struct smi_client_data *client_data = handle;
+ int in_suspend_copy;
+ in_suspend_copy = atomic_read(&client_data->in_suspend);
+
+ if (client_data == NULL)
+ return IRQ_HANDLED;
+ if (client_data->dev == NULL)
+ return IRQ_HANDLED;
+ /*this only deal with SIG_motion CTS test*/
+ if ((in_suspend_copy == 1) &&
+ (client_data->sig_flag == 1)) {
+ /*wake_lock_timeout(&client_data->wakelock, HZ);*/
+ schedule_delayed_work(&client_data->delay_work_sig,
+ msecs_to_jiffies(50));
+ }
+ schedule_work(&client_data->irq_work);
+
+ return IRQ_HANDLED;
+}
+#endif /* defined(SMI_ENABLE_INT1)||defined(SMI_ENABLE_INT2) */
+
+static int smi_restore_hw_cfg(struct smi_client_data *client)
+{
+ int err = 0;
+
+ if ((client->fifo_data_sel) & (1 << SMI_ACC_SENSOR)) {
+ err += SMI_CALL_API(set_accel_range)(client->range.acc_range);
+ err += SMI_CALL_API(set_accel_output_data_rate)
+ (client->odr.acc_odr);
+ err += SMI_CALL_API(set_fifo_accel_enable)(1);
+ }
+ if ((client->fifo_data_sel) & (1 << SMI_GYRO_SENSOR)) {
+ err += SMI_CALL_API(set_gyro_range)(client->range.gyro_range);
+ err += SMI_CALL_API(set_gyro_output_data_rate)
+ (client->odr.gyro_odr);
+ err += SMI_CALL_API(set_fifo_gyro_enable)(1);
+ }
+ if ((client->fifo_data_sel) & (1 << SMI_MAG_SENSOR)) {
+ err += SMI_CALL_API(set_mag_output_data_rate)
+ (client->odr.mag_odr);
+ err += SMI_CALL_API(set_fifo_mag_enable)(1);
+ }
+ err += SMI_CALL_API(set_command_register)(CMD_CLR_FIFO_DATA);
+
+ mutex_lock(&client->mutex_op_mode);
+ if (client->pw.acc_pm != SMI_ACC_PM_SUSPEND) {
+ err += SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_acc_arr[SMI_ACC_PM_NORMAL]);
+ smi_delay(3);
+ }
+ mutex_unlock(&client->mutex_op_mode);
+
+ mutex_lock(&client->mutex_op_mode);
+ if (client->pw.gyro_pm != SMI_GYRO_PM_SUSPEND) {
+ err += SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_gyro_arr[SMI_GYRO_PM_NORMAL]);
+ smi_delay(3);
+ }
+ mutex_unlock(&client->mutex_op_mode);
+
+ mutex_lock(&client->mutex_op_mode);
+
+ if (client->pw.mag_pm != SMI_MAG_PM_SUSPEND) {
+#ifdef SMI130_AKM09912_SUPPORT
+ err += smi130_set_bosch_akm_and_secondary_if_powermode
+ (SMI130_MAG_FORCE_MODE);
+#else
+ err += smi130_set_bmm150_mag_and_secondary_if_power_mode
+ (SMI130_MAG_FORCE_MODE);
+#endif
+ smi_delay(3);
+ }
+ mutex_unlock(&client->mutex_op_mode);
+
+ return err;
+}
+
+#if defined(CONFIG_USE_QUALCOMM_HAL)
+static void smi130_accel_work_fn(struct work_struct *work)
+{
+ struct smi_client_data *sensor;
+ ktime_t timestamp;
+ struct smi130_accel_t data;
+ int err;
+ sensor = container_of((struct delayed_work *)work,
+ struct smi_client_data, accel_poll_work);
+ timestamp = ktime_get();
+ err = SMI_CALL_API(read_accel_xyz)(&data);
+ if (err)
+ dev_err(sensor->dev, "read data err");
+ input_report_abs(sensor->input, ABS_X,
+ (data.x));
+ input_report_abs(sensor->input, ABS_Y,
+ (data.y));
+ input_report_abs(sensor->input, ABS_Z,
+ (data.z));
+ input_event(sensor->input,
+ EV_SYN, SYN_TIME_SEC,
+ ktime_to_timespec(timestamp).tv_sec);
+ input_event(sensor->input, EV_SYN,
+ SYN_TIME_NSEC,
+ ktime_to_timespec(timestamp).tv_nsec);
+ input_sync(sensor->input);
+ if (atomic_read(&sensor->accel_en))
+ queue_delayed_work(sensor->data_wq,
+ &sensor->accel_poll_work,
+ msecs_to_jiffies(sensor->accel_poll_ms));
+}
+static void smi130_gyro_work_fn(struct work_struct *work)
+{
+ struct smi_client_data *sensor;
+ ktime_t timestamp;
+ struct smi130_gyro_t data;
+ int err;
+ sensor = container_of((struct delayed_work *)work,
+ struct smi_client_data, gyro_poll_work);
+ timestamp = ktime_get();
+ err = SMI_CALL_API(read_gyro_xyz)(&data);
+ if (err)
+ dev_err(sensor->dev, "read data err");
+ input_report_abs(sensor->gyro_input, ABS_RX,
+ (data.x));
+ input_report_abs(sensor->gyro_input, ABS_RY,
+ (data.y));
+ input_report_abs(sensor->gyro_input, ABS_RZ,
+ (data.z));
+ input_event(sensor->gyro_input,
+ EV_SYN, SYN_TIME_SEC,
+ ktime_to_timespec(timestamp).tv_sec);
+ input_event(sensor->gyro_input, EV_SYN,
+ SYN_TIME_NSEC,
+ ktime_to_timespec(timestamp).tv_nsec);
+ input_sync(sensor->gyro_input);
+ if (atomic_read(&sensor->gyro_en))
+ queue_delayed_work(sensor->data_wq,
+ &sensor->gyro_poll_work,
+ msecs_to_jiffies(sensor->gyro_poll_ms));
+}
+static int smi130_set_gyro_op_mode(struct smi_client_data *client_data,
+ unsigned long op_mode)
+{
+ int err = 0;
+ mutex_lock(&client_data->mutex_op_mode);
+ if (op_mode < SMI_GYRO_PM_MAX) {
+ switch (op_mode) {
+ case SMI_GYRO_PM_NORMAL:
+ err = SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_gyro_arr[SMI_GYRO_PM_NORMAL]);
+ client_data->pw.gyro_pm = SMI_GYRO_PM_NORMAL;
+ smi_delay(60);
+ break;
+ case SMI_GYRO_PM_FAST_START:
+ err = SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_gyro_arr[SMI_GYRO_PM_FAST_START]);
+ client_data->pw.gyro_pm = SMI_GYRO_PM_FAST_START;
+ smi_delay(60);
+ break;
+ case SMI_GYRO_PM_SUSPEND:
+ err = SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_gyro_arr[SMI_GYRO_PM_SUSPEND]);
+ client_data->pw.gyro_pm = SMI_GYRO_PM_SUSPEND;
+ smi_delay(60);
+ break;
+ default:
+ mutex_unlock(&client_data->mutex_op_mode);
+ return -EINVAL;
+ }
+ } else {
+ mutex_unlock(&client_data->mutex_op_mode);
+ return -EINVAL;
+ }
+ mutex_unlock(&client_data->mutex_op_mode);
+ return err;
+}
+static int smi130_accel_set_enable(
+ struct smi_client_data *client_data, bool enable)
+{
+ int ret = 0;
+ dev_notice(client_data->dev,
+ "smi130_accel_set_enable enable=%d\n", enable);
+ if (enable) {
+ ret = smi130_set_acc_op_mode(client_data, 0);
+ if (ret) {
+ dev_err(client_data->dev,
+ "Fail to enable accel engine ret=%d\n", ret);
+ ret = -EBUSY;
+ goto exit;
+ }
+ queue_delayed_work(client_data->data_wq,
+ &client_data->accel_poll_work,
+ msecs_to_jiffies(client_data->accel_poll_ms));
+ atomic_set(&client_data->accel_en, 1);
+ } else {
+ atomic_set(&client_data->accel_en, 0);
+ cancel_delayed_work_sync(&client_data->accel_poll_work);
+ ret = smi130_set_acc_op_mode(client_data, 2);
+ if (ret) {
+ dev_err(client_data->dev,
+ "Fail to disable accel engine ret=%d\n", ret);
+ ret = -EBUSY;
+ goto exit;
+ }
+ }
+exit:
+ return ret;
+}
+static int smi130_accel_set_poll_delay(struct smi_client_data *client_data,
+ unsigned long delay)
+{
+ dev_info(client_data->dev,
+ "smi130_accel_set_poll_delay delay_ms=%ld\n", delay);
+ if (delay < SMI130_ACCEL_MIN_POLL_INTERVAL_MS)
+ delay = SMI130_ACCEL_MIN_POLL_INTERVAL_MS;
+ if (delay > SMI130_ACCEL_MAX_POLL_INTERVAL_MS)
+ delay = SMI130_ACCEL_MAX_POLL_INTERVAL_MS;
+ client_data->accel_poll_ms = delay;
+ if (!atomic_read(&client_data->accel_en))
+ goto exit;
+ cancel_delayed_work_sync(&client_data->accel_poll_work);
+ queue_delayed_work(client_data->data_wq,
+ &client_data->accel_poll_work,
+ msecs_to_jiffies(client_data->accel_poll_ms));
+exit:
+ return 0;
+}
+static int smi130_gyro_set_enable(
+ struct smi_client_data *client_data, bool enable)
+{
+ int ret = 0;
+ dev_notice(client_data->dev,
+ "smi130_gyro_set_enable enable=%d\n", enable);
+ if (enable) {
+ ret = smi130_set_gyro_op_mode(client_data, 0);
+ if (ret) {
+ dev_err(client_data->dev,
+ "Fail to enable gyro engine ret=%d\n", ret);
+ ret = -EBUSY;
+ goto exit;
+ }
+ queue_delayed_work(client_data->data_wq,
+ &client_data->gyro_poll_work,
+ msecs_to_jiffies(client_data->gyro_poll_ms));
+ atomic_set(&client_data->gyro_en, 1);
+ } else {
+ atomic_set(&client_data->gyro_en, 0);
+ cancel_delayed_work_sync(&client_data->gyro_poll_work);
+ ret = smi130_set_gyro_op_mode(client_data, 2);
+ if (ret) {
+ dev_err(client_data->dev,
+ "Fail to disable accel engine ret=%d\n", ret);
+ ret = -EBUSY;
+ goto exit;
+ }
+ }
+exit:
+ return ret;
+}
+static int smi130_gyro_set_poll_delay(struct smi_client_data *client_data,
+ unsigned long delay)
+{
+ dev_info(client_data->dev,
+ "smi130_accel_set_poll_delay delay_ms=%ld\n", delay);
+ if (delay < SMI130_GYRO_MIN_POLL_INTERVAL_MS)
+ delay = SMI130_GYRO_MIN_POLL_INTERVAL_MS;
+ if (delay > SMI130_GYRO_MAX_POLL_INTERVAL_MS)
+ delay = SMI130_GYRO_MAX_POLL_INTERVAL_MS;
+ client_data->gyro_poll_ms = delay;
+ if (!atomic_read(&client_data->gyro_en))
+ goto exit;
+ cancel_delayed_work_sync(&client_data->gyro_poll_work);
+ queue_delayed_work(client_data->data_wq,
+ &client_data->gyro_poll_work,
+ msecs_to_jiffies(client_data->gyro_poll_ms));
+exit:
+ return 0;
+}
+static int smi130_accel_cdev_enable(struct sensors_classdev *sensors_cdev,
+ unsigned int enable)
+{
+ struct smi_client_data *sensor = container_of(sensors_cdev,
+ struct smi_client_data, accel_cdev);
+ return smi130_accel_set_enable(sensor, enable);
+}
+static int smi130_accel_cdev_poll_delay(struct sensors_classdev *sensors_cdev,
+ unsigned int delay_ms)
+{
+ struct smi_client_data *sensor = container_of(sensors_cdev,
+ struct smi_client_data, accel_cdev);
+
+ return smi130_accel_set_poll_delay(sensor, delay_ms);
+}
+
+static int smi130_gyro_cdev_enable(struct sensors_classdev *sensors_cdev,
+ unsigned int enable)
+{
+ struct smi_client_data *sensor = container_of(sensors_cdev,
+ struct smi_client_data, gyro_cdev);
+
+ return smi130_gyro_set_enable(sensor, enable);
+}
+
+static int smi130_gyro_cdev_poll_delay(struct sensors_classdev *sensors_cdev,
+ unsigned int delay_ms)
+{
+ struct smi_client_data *sensor = container_of(sensors_cdev,
+ struct smi_client_data, gyro_cdev);
+
+ return smi130_gyro_set_poll_delay(sensor, delay_ms);
+}
+#endif
+
+int smi_probe(struct smi_client_data *client_data, struct device *dev)
+{
+ int err = 0;
+#ifdef SMI130_MAG_INTERFACE_SUPPORT
+ u8 mag_dev_addr;
+ u8 mag_urst_len;
+ u8 mag_op_mode;
+#endif
+ /* check chip id */
+ err = smi_check_chip_id(client_data);
+ if (err)
+ goto exit_err_clean;
+
+ dev_set_drvdata(dev, client_data);
+ client_data->dev = dev;
+
+ mutex_init(&client_data->mutex_enable);
+ mutex_init(&client_data->mutex_op_mode);
+
+ /* input device init */
+ err = smi_input_init(client_data);
+ if (err < 0)
+ goto exit_err_clean;
+
+ /* sysfs node creation */
+ err = sysfs_create_group(&client_data->input->dev.kobj,
+ &smi130_attribute_group);
+
+ if (err < 0)
+ goto exit_err_sysfs;
+
+ if (NULL != dev->platform_data) {
+ client_data->bosch_pd = kzalloc(sizeof(*client_data->bosch_pd),
+ GFP_KERNEL);
+
+ if (NULL != client_data->bosch_pd) {
+ memcpy(client_data->bosch_pd, dev->platform_data,
+ sizeof(*client_data->bosch_pd));
+ dev_notice(dev, "%s sensor driver set place: p%d\n",
+ client_data->bosch_pd->name,
+ client_data->bosch_pd->place);
+ }
+ }
+
+ if (NULL != client_data->bosch_pd) {
+ memcpy(client_data->bosch_pd, dev->platform_data,
+ sizeof(*client_data->bosch_pd));
+ dev_notice(dev, "%s sensor driver set place: p%d\n",
+ client_data->bosch_pd->name,
+ client_data->bosch_pd->place);
+ }
+
+
+ /* workqueue init */
+ INIT_DELAYED_WORK(&client_data->work, smi_work_func);
+ atomic_set(&client_data->delay, SMI_DELAY_DEFAULT);
+ atomic_set(&client_data->wkqueue_en, 0);
+
+ /* h/w init */
+ client_data->device.delay_msec = smi_delay;
+ err = SMI_CALL_API(init)(&client_data->device);
+
+ smi_dump_reg(client_data);
+
+ /*power on detected*/
+ /*or softrest(cmd 0xB6) */
+ /*fatal err check*/
+ /*soft reset*/
+ err += SMI_CALL_API(set_command_register)(CMD_RESET_USER_REG);
+ smi_delay(3);
+ if (err)
+ dev_err(dev, "Failed soft reset, er=%d", err);
+ /*usr data config page*/
+ err += SMI_CALL_API(set_target_page)(USER_DAT_CFG_PAGE);
+ if (err)
+ dev_err(dev, "Failed cffg page, er=%d", err);
+ err += smi_get_err_status(client_data);
+ if (err) {
+ dev_err(dev, "Failed to smi16x init!err_st=0x%x\n",
+ client_data->err_st.err_st_all);
+ goto exit_err_sysfs;
+ }
+
+#ifdef SMI130_MAG_INTERFACE_SUPPORT
+ err += smi130_set_command_register(MAG_MODE_NORMAL);
+ smi_delay(2);
+ err += smi130_get_mag_power_mode_stat(&mag_op_mode);
+ smi_delay(2);
+ err += SMI_CALL_API(get_i2c_device_addr)(&mag_dev_addr);
+ smi_delay(2);
+#if defined(SMI130_AKM09912_SUPPORT)
+ err += SMI_CALL_API(set_i2c_device_addr)(SMI130_AKM09912_I2C_ADDRESS);
+ smi130_bosch_akm_mag_interface_init(SMI130_AKM09912_I2C_ADDRESS);
+#else
+ err += SMI_CALL_API(set_i2c_device_addr)(
+ SMI130_AUX_BMM150_I2C_ADDRESS);
+ smi130_bmm150_mag_interface_init();
+#endif
+
+ err += smi130_set_mag_burst(3);
+ err += smi130_get_mag_burst(&mag_urst_len);
+ if (err)
+ dev_err(client_data->dev, "Failed cffg mag, er=%d", err);
+ dev_info(client_data->dev,
+ "SMI130 mag_urst_len:%d, mag_add:0x%x, mag_op_mode:%d\n",
+ mag_urst_len, mag_dev_addr, mag_op_mode);
+#endif
+ if (err < 0)
+ goto exit_err_sysfs;
+
+
+#if defined(SMI130_ENABLE_INT1) || defined(SMI130_ENABLE_INT2)
+ /*wake_lock_init(&client_data->wakelock,
+ WAKE_LOCK_SUSPEND, "smi130");*/
+ client_data->gpio_pin = of_get_named_gpio_flags(dev->of_node,
+ "smi,gpio_irq", 0, NULL);
+ dev_info(client_data->dev, "SMI130 qpio number:%d\n",
+ client_data->gpio_pin);
+ err += gpio_request_one(client_data->gpio_pin,
+ GPIOF_IN, "smi130_int");
+ err += gpio_direction_input(client_data->gpio_pin);
+ client_data->IRQ = gpio_to_irq(client_data->gpio_pin);
+ if (err) {
+ dev_err(client_data->dev,
+ "can not request gpio to irq number\n");
+ client_data->gpio_pin = 0;
+ }
+ INIT_DELAYED_WORK(&client_data->delay_work_sig,
+ smi130_delay_sigmo_work_func);
+#ifdef SMI130_ENABLE_INT1
+ /* maps interrupt to INT1/InT2 pin */
+ SMI_CALL_API(set_intr_any_motion)(SMI_INT0, ENABLE);
+ SMI_CALL_API(set_intr_fifo_wm)(SMI_INT0, ENABLE);
+ SMI_CALL_API(set_intr_data_rdy)(SMI_INT0, ENABLE);
+
+ /*Set interrupt trige level way */
+ SMI_CALL_API(set_intr_edge_ctrl)(SMI_INT0, SMI_INT_LEVEL);
+ smi130_set_intr_level(SMI_INT0, 1);
+ /*set interrupt latch temporary, 5 ms*/
+ /*smi130_set_latch_int(5);*/
+
+ SMI_CALL_API(set_output_enable)(
+ SMI130_INTR1_OUTPUT_ENABLE, ENABLE);
+ sigmotion_init_interrupts(SMI130_MAP_INTR1);
+ SMI_CALL_API(map_step_detector_intr)(SMI130_MAP_INTR1);
+ /*close step_detector in init function*/
+ SMI_CALL_API(set_step_detector_enable)(0);
+#endif
+
+#ifdef SMI130_ENABLE_INT2
+ /* maps interrupt to INT1/InT2 pin */
+ SMI_CALL_API(set_intr_any_motion)(SMI_INT1, ENABLE);
+ SMI_CALL_API(set_intr_fifo_wm)(SMI_INT1, ENABLE);
+ SMI_CALL_API(set_intr_data_rdy)(SMI_INT1, ENABLE);
+
+ /*Set interrupt trige level way */
+ SMI_CALL_API(set_intr_edge_ctrl)(SMI_INT1, SMI_INT_LEVEL);
+ smi130_set_intr_level(SMI_INT1, 1);
+ /*set interrupt latch temporary, 5 ms*/
+ /*smi130_set_latch_int(5);*/
+
+ SMI_CALL_API(set_output_enable)(
+ SMI130_INTR2_OUTPUT_ENABLE, ENABLE);
+ sigmotion_init_interrupts(SMI130_MAP_INTR2);
+ SMI_CALL_API(map_step_detector_intr)(SMI130_MAP_INTR2);
+ /*close step_detector in init function*/
+ SMI_CALL_API(set_step_detector_enable)(0);
+#endif
+ err = request_irq(client_data->IRQ, smi_irq_handler,
+ IRQF_TRIGGER_RISING, "smi130", client_data);
+ if (err)
+ dev_err(client_data->dev, "could not request irq\n");
+
+ INIT_WORK(&client_data->irq_work, smi_irq_work_func);
+#endif
+
+ client_data->selftest = 0;
+
+ client_data->fifo_data_sel = 0;
+ #if defined(CONFIG_USE_QUALCOMM_HAL)
+ SMI_CALL_API(set_accel_output_data_rate)(9);/*defalut odr 200HZ*/
+ SMI_CALL_API(set_gyro_output_data_rate)(9);/*defalut odr 200HZ*/
+ #endif
+ SMI_CALL_API(get_accel_output_data_rate)(&client_data->odr.acc_odr);
+ SMI_CALL_API(get_gyro_output_data_rate)(&client_data->odr.gyro_odr);
+ SMI_CALL_API(get_mag_output_data_rate)(&client_data->odr.mag_odr);
+ SMI_CALL_API(set_fifo_time_enable)(1);
+ SMI_CALL_API(get_accel_range)(&client_data->range.acc_range);
+ SMI_CALL_API(get_gyro_range)(&client_data->range.gyro_range);
+ /* now it's power on which is considered as resuming from suspend */
+
+ /* gyro input device init */
+ err = smi_gyro_input_init(client_data);
+ #if defined(CONFIG_USE_QUALCOMM_HAL)
+ /* gyro input device init */
+ err = smi_gyro_input_init(client_data);
+ if (err < 0)
+ goto exit_err_clean;
+ client_data->accel_poll_ms = SMI130_ACCEL_DEFAULT_POLL_INTERVAL_MS;
+ client_data->gyro_poll_ms = SMI130_GYRO_DEFAULT_POLL_INTERVAL_MS;
+ client_data->data_wq = create_freezable_workqueue("smi130_data_work");
+ if (!client_data->data_wq) {
+ dev_err(dev, "Cannot create workqueue!\n");
+ goto exit_err_clean;
+ }
+ INIT_DELAYED_WORK(&client_data->accel_poll_work,
+ smi130_accel_work_fn);
+ client_data->accel_cdev = smi130_accel_cdev;
+ client_data->accel_cdev.delay_msec = client_data->accel_poll_ms;
+ client_data->accel_cdev.sensors_enable = smi130_accel_cdev_enable;
+ client_data->accel_cdev.sensors_poll_delay =
+ smi130_accel_cdev_poll_delay;
+ err = sensors_classdev_register(dev, &client_data->accel_cdev);
+ if (err) {
+ dev_err(dev,
+ "create accel class device file failed!\n");
+ goto exit_err_clean;
+ }
+ INIT_DELAYED_WORK(&client_data->gyro_poll_work, smi130_gyro_work_fn);
+ client_data->gyro_cdev = smi130_gyro_cdev;
+ client_data->gyro_cdev.delay_msec = client_data->gyro_poll_ms;
+ client_data->gyro_cdev.sensors_enable = smi130_gyro_cdev_enable;
+ client_data->gyro_cdev.sensors_poll_delay = smi130_gyro_cdev_poll_delay;
+ err = sensors_classdev_register(dev, &client_data->gyro_cdev);
+ if (err) {
+ dev_err(dev,
+ "create accel class device file failed!\n");
+ goto exit_err_clean;
+ }
+ #endif
+ /* set sensor PMU into suspend power mode for all */
+ if (smi_pmu_set_suspend(client_data) < 0) {
+ dev_err(dev, "Failed to set SMI130 to suspend power mode\n");
+ goto exit_err_sysfs;
+ }
+ /*enable the data ready interrupt*/
+ SMI_CALL_API(set_intr_enable_1)(SMI130_DATA_RDY_ENABLE, 1);
+ dev_notice(dev, "sensor_time:%d, %d, %d",
+ sensortime_duration_tbl[0].ts_delat,
+ sensortime_duration_tbl[0].ts_duration_lsb,
+ sensortime_duration_tbl[0].ts_duration_us);
+ dev_notice(dev, "sensor %s probed successfully", SENSOR_NAME);
+
+ return 0;
+
+exit_err_sysfs:
+ if (err)
+ smi_input_destroy(client_data);
+
+exit_err_clean:
+ if (err) {
+ if (client_data != NULL) {
+ if (NULL != client_data->bosch_pd) {
+ kfree(client_data->bosch_pd);
+ client_data->bosch_pd = NULL;
+ }
+ }
+ }
+ return err;
+}
+EXPORT_SYMBOL(smi_probe);
+
+/*!
+ * @brief remove smi client
+ *
+ * @param dev the pointer of device
+ *
+ * @return zero
+ * @retval zero
+*/
+int smi_remove(struct device *dev)
+{
+ int err = 0;
+ struct smi_client_data *client_data = dev_get_drvdata(dev);
+
+ if (NULL != client_data) {
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ unregister_early_suspend(&client_data->early_suspend_handler);
+#endif
+ mutex_lock(&client_data->mutex_enable);
+ if (SMI_ACC_PM_NORMAL == client_data->pw.acc_pm ||
+ SMI_GYRO_PM_NORMAL == client_data->pw.gyro_pm ||
+ SMI_MAG_PM_NORMAL == client_data->pw.mag_pm) {
+ cancel_delayed_work_sync(&client_data->work);
+ }
+ mutex_unlock(&client_data->mutex_enable);
+
+ err = smi_pmu_set_suspend(client_data);
+
+ smi_delay(5);
+
+ sysfs_remove_group(&client_data->input->dev.kobj,
+ &smi130_attribute_group);
+ smi_input_destroy(client_data);
+
+ if (NULL != client_data->bosch_pd) {
+ kfree(client_data->bosch_pd);
+ client_data->bosch_pd = NULL;
+ }
+ kfree(client_data);
+ }
+
+ return err;
+}
+EXPORT_SYMBOL(smi_remove);
+
+static int smi_post_resume(struct smi_client_data *client_data)
+{
+ int err = 0;
+
+ mutex_lock(&client_data->mutex_enable);
+
+ if (atomic_read(&client_data->wkqueue_en) == 1) {
+ smi130_set_acc_op_mode(client_data, SMI_ACC_PM_NORMAL);
+ schedule_delayed_work(&client_data->work,
+ msecs_to_jiffies(
+ atomic_read(&client_data->delay)));
+ }
+ mutex_unlock(&client_data->mutex_enable);
+
+ return err;
+}
+
+
+int smi_suspend(struct device *dev)
+{
+ int err = 0;
+ struct smi_client_data *client_data = dev_get_drvdata(dev);
+ unsigned char stc_enable;
+ unsigned char std_enable;
+ dev_err(client_data->dev, "smi suspend function entrance");
+
+ atomic_set(&client_data->in_suspend, 1);
+ if (atomic_read(&client_data->wkqueue_en) == 1) {
+ smi130_set_acc_op_mode(client_data, SMI_ACC_PM_SUSPEND);
+ cancel_delayed_work_sync(&client_data->work);
+ }
+ SMI_CALL_API(get_step_counter_enable)(&stc_enable);
+ SMI_CALL_API(get_step_detector_enable)(&std_enable);
+ if (client_data->pw.acc_pm != SMI_ACC_PM_SUSPEND &&
+ (stc_enable != 1) && (std_enable != 1) &&
+ (client_data->sig_flag != 1)) {
+ err += SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_acc_arr[SMI_ACC_PM_SUSPEND]);
+ smi_delay(3);
+ }
+ if (client_data->pw.gyro_pm != SMI_GYRO_PM_SUSPEND) {
+ err += SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_gyro_arr[SMI_GYRO_PM_SUSPEND]);
+ smi_delay(3);
+ }
+
+ if (client_data->pw.mag_pm != SMI_MAG_PM_SUSPEND) {
+#if defined(SMI130_AKM09912_SUPPORT)
+ err += smi130_set_bosch_akm_and_secondary_if_powermode(
+ SMI130_MAG_SUSPEND_MODE);
+#else
+ err += smi130_set_bmm150_mag_and_secondary_if_power_mode(
+ SMI130_MAG_SUSPEND_MODE);
+#endif
+ smi_delay(3);
+ }
+
+ return err;
+}
+EXPORT_SYMBOL(smi_suspend);
+
+int smi_resume(struct device *dev)
+{
+ int err = 0;
+ struct smi_client_data *client_data = dev_get_drvdata(dev);
+ atomic_set(&client_data->in_suspend, 0);
+ if (client_data->pw.acc_pm != SMI_ACC_PM_SUSPEND) {
+ err += SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_acc_arr[SMI_ACC_PM_NORMAL]);
+ smi_delay(3);
+ }
+ if (client_data->pw.gyro_pm != SMI_GYRO_PM_SUSPEND) {
+ err += SMI_CALL_API(set_command_register)
+ (smi_pmu_cmd_gyro_arr[SMI_GYRO_PM_NORMAL]);
+ smi_delay(3);
+ }
+
+ if (client_data->pw.mag_pm != SMI_MAG_PM_SUSPEND) {
+#if defined(SMI130_AKM09912_SUPPORT)
+ err += smi130_set_bosch_akm_and_secondary_if_powermode
+ (SMI130_MAG_FORCE_MODE);
+#else
+ err += smi130_set_bmm150_mag_and_secondary_if_power_mode
+ (SMI130_MAG_FORCE_MODE);
+#endif
+ smi_delay(3);
+ }
+ /* post resume operation */
+ err += smi_post_resume(client_data);
+
+ return err;
+}
+EXPORT_SYMBOL(smi_resume);
+
diff --git a/drivers/input/sensors/smi130/smi130_driver.h b/drivers/input/sensors/smi130/smi130_driver.h
new file mode 100644
index 0000000..9855b22
--- /dev/null
+++ b/drivers/input/sensors/smi130/smi130_driver.h
@@ -0,0 +1,411 @@
+ /*
+ * @section LICENSE
+ * (C) Copyright 2011~2018 Bosch Sensortec GmbH All Rights Reserved
+ *
+ * (C) Modification Copyright 2018 Robert Bosch Kft All Rights Reserved
+ *
+ * This software program is licensed subject to the GNU General
+ * Public License (GPL).Version 2,June 1991,
+ * available at http://www.fsf.org/copyleft/gpl.html
+ *
+ * @filename smi130_driver.h
+ * @date 2015/08/17 14:40
+ * @Modification Date 2018/06/21 15:03
+ * @version 1.3
+ *
+ * @brief
+ * The head file of SMI130 device driver core code
+*/
+#ifndef _SMI130_DRIVER_H
+#define _SMI130_DRIVER_H
+
+#ifdef __KERNEL__
+#include <linux/kernel.h>
+#include <linux/unistd.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#else
+#include <unistd.h>
+#include <sys/types.h>
+#include <string.h>
+#endif
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/time.h>
+#include <linux/ktime.h>
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+
+#include "smi130.h"
+
+#if defined(CONFIG_USE_QUALCOMM_HAL)
+#include <linux/sensors.h>
+#endif
+/* sensor specific */
+#define SENSOR_NAME "smi130"
+#define SMI130_ENABLE_INT1 1
+#define SMI130_ENABLE_INT2 1
+/*#define SMI130_MAG_INTERFACE_SUPPORT 1*/
+
+/*#define SMI130_AKM09912_SUPPORT 1*/
+#define SMI_USE_BASIC_I2C_FUNC 1
+#define SENSOR_CHIP_ID_SMI (0xD0)
+#define SENSOR_CHIP_ID_SMI_C2 (0xD1)
+#define SENSOR_CHIP_ID_SMI_C3 (0xD3)
+
+#define SENSOR_CHIP_REV_ID_SMI (0x00)
+
+#define CHECK_CHIP_ID_TIME_MAX 5
+
+#define SMI_REG_NAME(name) SMI130_##name##__REG
+#define SMI_VAL_NAME(name) SMI130_##name
+#define SMI_CALL_API(name) smi130_##name
+
+#define SMI_I2C_WRITE_DELAY_TIME (1)
+
+/* generic */
+#define SMI_MAX_RETRY_I2C_XFER (10)
+#define SMI_MAX_RETRY_WAKEUP (5)
+#define SMI_MAX_RETRY_WAIT_DRDY (100)
+
+#define SMI_DELAY_MIN (1)
+#define SMI_DELAY_DEFAULT (200)
+
+#define SMI_VALUE_MAX (32767)
+#define SMI_VALUE_MIN (-32768)
+
+#define BYTES_PER_LINE (16)
+
+#define BUF_SIZE_PRINT (16)
+
+#define SMI_FAST_CALI_TRUE (1)
+#define SMI_FAST_CALI_ALL_RDY (7)
+
+/*! FIFO 1024 byte, max fifo frame count not over 150 */
+#define FIFO_FRAME_CNT 170
+#define FIFO_DATA_BUFSIZE 1024
+
+
+#define FRAME_LEN_ACC 6
+#define FRAME_LEN_GYRO 6
+#define FRAME_LEN_MAG 8
+
+/*! SMI Self test */
+#define SMI_SELFTEST_AMP_HIGH 1
+
+/* CMD */
+#define CMD_FOC_START 0x03
+#define CMD_PMU_ACC_SUSPEND 0x10
+#define CMD_PMU_ACC_NORMAL 0x11
+#define CMD_PMU_ACC_LP1 0x12
+#define CMD_PMU_ACC_LP2 0x13
+#define CMD_PMU_GYRO_SUSPEND 0x14
+#define CMD_PMU_GYRO_NORMAL 0x15
+#define CMD_PMU_GYRO_FASTSTART 0x17
+#define CMD_PMU_MAG_SUSPEND 0x18
+#define CMD_PMU_MAG_NORMAL 0x19
+#define CMD_PMU_MAG_LP1 0x1A
+#define CMD_PMU_MAG_LP2 0x1B
+#define CMD_CLR_FIFO_DATA 0xB0
+#define CMD_RESET_INT_ENGINE 0xB1
+#define CMD_RESET_USER_REG 0xB6
+
+#define USER_DAT_CFG_PAGE 0x00
+
+/*! FIFO Head definition*/
+#define FIFO_HEAD_A 0x84
+#define FIFO_HEAD_G 0x88
+#define FIFO_HEAD_M 0x90
+
+#define FIFO_HEAD_G_A (FIFO_HEAD_G | FIFO_HEAD_A)
+#define FIFO_HEAD_M_A (FIFO_HEAD_M | FIFO_HEAD_A)
+#define FIFO_HEAD_M_G (FIFO_HEAD_M | FIFO_HEAD_G)
+
+#define FIFO_HEAD_M_G_A (FIFO_HEAD_M | FIFO_HEAD_G | FIFO_HEAD_A)
+
+#define FIFO_HEAD_SENSOR_TIME 0x44
+#define FIFO_HEAD_SKIP_FRAME 0x40
+#define FIFO_HEAD_OVER_READ_LSB 0x80
+#define FIFO_HEAD_OVER_READ_MSB 0x00
+
+/*! FIFO head mode Frame bytes number definition */
+#define A_BYTES_FRM 6
+#define G_BYTES_FRM 6
+#define M_BYTES_FRM 8
+#define GA_BYTES_FRM 12
+#define MG_BYTES_FRM 14
+#define MA_BYTES_FRM 14
+#define MGA_BYTES_FRM 20
+
+#define ACC_FIFO_HEAD "acc"
+#define GYRO_FIFO_HEAD "gyro"
+#define MAG_FIFO_HEAD "mag"
+
+/*! Bosch sensor unknown place*/
+#define BOSCH_SENSOR_PLACE_UNKNOWN (-1)
+/*! Bosch sensor remapping table size P0~P7*/
+#define MAX_AXIS_REMAP_TAB_SZ 8
+
+#define ENABLE 1
+#define DISABLE 0
+
+/* smi sensor HW interrupt pin number */
+#define SMI_INT0 0
+#define SMI_INT1 1
+
+#define SMI_INT_LEVEL 0
+#define SMI_INT_EDGE 1
+
+/*! SMI mag interface */
+
+
+/* compensated output value returned if sensor had overflow */
+#define BMM050_OVERFLOW_OUTPUT -32768
+#define BMM050_OVERFLOW_OUTPUT_S32 ((s32)(-2147483647-1))
+
+/* Trim Extended Registers */
+#define BMM050_DIG_X1 0x5D
+#define BMM050_DIG_Y1 0x5E
+#define BMM050_DIG_Z4_LSB 0x62
+#define BMM050_DIG_Z4_MSB 0x63
+#define BMM050_DIG_X2 0x64
+#define BMM050_DIG_Y2 0x65
+#define BMM050_DIG_Z2_LSB 0x68
+#define BMM050_DIG_Z2_MSB 0x69
+#define BMM050_DIG_Z1_LSB 0x6A
+#define BMM050_DIG_Z1_MSB 0x6B
+#define BMM050_DIG_XYZ1_LSB 0x6C
+#define BMM050_DIG_XYZ1_MSB 0x6D
+#define BMM050_DIG_Z3_LSB 0x6E
+#define BMM050_DIG_Z3_MSB 0x6F
+#define BMM050_DIG_XY2 0x70
+#define BMM050_DIG_XY1 0x71
+
+struct smi130mag_compensate_t {
+ signed char dig_x1;
+ signed char dig_y1;
+
+ signed char dig_x2;
+ signed char dig_y2;
+
+ u16 dig_z1;
+ s16 dig_z2;
+ s16 dig_z3;
+ s16 dig_z4;
+
+ unsigned char dig_xy1;
+ signed char dig_xy2;
+
+ u16 dig_xyz1;
+};
+
+/*smi fifo sensor type combination*/
+enum SMI_FIFO_DATA_SELECT_T {
+ SMI_FIFO_A_SEL = 1,
+ SMI_FIFO_G_SEL,
+ SMI_FIFO_G_A_SEL,
+ SMI_FIFO_M_SEL,
+ SMI_FIFO_M_A_SEL,
+ SMI_FIFO_M_G_SEL,
+ SMI_FIFO_M_G_A_SEL,
+ SMI_FIFO_DATA_SEL_MAX
+};
+
+/*smi interrupt about step_detector and sgm*/
+#define INPUT_EVENT_STEP_DETECTOR 5
+#define INPUT_EVENT_SGM 3/*7*/
+#define INPUT_EVENT_FAST_ACC_CALIB_DONE 6
+#define INPUT_EVENT_FAST_GYRO_CALIB_DONE 4
+
+
+/*!
+* Bst sensor common definition,
+* please give parameters in BSP file.
+*/
+struct bosch_sensor_specific {
+ char *name;
+ /* 0 to 7 */
+ unsigned int place:3;
+ int irq;
+ int (*irq_gpio_cfg)(void);
+};
+
+/*! smi130 sensor spec of power mode */
+struct pw_mode {
+ u8 acc_pm;
+ u8 gyro_pm;
+ u8 mag_pm;
+};
+
+/*! smi130 sensor spec of odr */
+struct odr_t {
+ u8 acc_odr;
+ u8 gyro_odr;
+ u8 mag_odr;
+};
+
+/*! smi130 sensor spec of range */
+struct range_t {
+ u8 acc_range;
+ u8 gyro_range;
+};
+
+/*! smi130 sensor error status */
+struct err_status {
+ u8 fatal_err;
+ u8 err_code;
+ u8 i2c_fail;
+ u8 drop_cmd;
+ u8 mag_drdy_err;
+ u8 err_st_all;
+};
+
+/*! smi130 fifo frame for all sensors */
+struct fifo_frame_t {
+ struct smi130_accel_t *acc_farr;
+ struct smi130_gyro_t *gyro_farr;
+ struct smi130_mag_xyz_s32_t *mag_farr;
+
+ unsigned char acc_frame_cnt;
+ unsigned char gyro_frame_cnt;
+ unsigned char mag_frame_cnt;
+
+ u32 acc_lastf_ts;
+ u32 gyro_lastf_ts;
+ u32 mag_lastf_ts;
+};
+
+/*! smi130 fifo sensor time */
+struct fifo_sensor_time_t {
+ u32 acc_ts;
+ u32 gyro_ts;
+ u32 mag_ts;
+};
+
+struct pedometer_data_t {
+ /*! Fix step detector misinformation for the first time*/
+ u8 wkar_step_detector_status;
+ u_int32_t last_step_counter_value;
+};
+
+struct smi_client_data {
+ struct smi130_t device;
+ struct device *dev;
+ struct input_dev *input;/*acc_device*/
+ struct input_dev *gyro_input;
+ #if defined(CONFIG_USE_QUALCOMM_HAL)
+ struct input_dev *gyro_input;
+ struct sensors_classdev accel_cdev;
+ struct sensors_classdev gyro_cdev;
+ struct delayed_work accel_poll_work;
+ struct delayed_work gyro_poll_work;
+ u32 accel_poll_ms;
+ u32 gyro_poll_ms;
+ u32 accel_latency_ms;
+ u32 gyro_latency_ms;
+ atomic_t accel_en;
+ atomic_t gyro_en;
+ struct workqueue_struct *data_wq;
+ #endif
+ struct delayed_work work;
+ struct work_struct irq_work;
+
+ u8 chip_id;
+
+ struct pw_mode pw;
+ struct odr_t odr;
+ struct range_t range; /*TO DO*/
+ struct err_status err_st;
+ struct pedometer_data_t pedo_data;
+ s8 place;
+ u8 selftest;
+ /*struct wake_lock wakelock;*/
+ struct delayed_work delay_work_sig;
+ atomic_t in_suspend;
+
+ atomic_t wkqueue_en; /*TO DO acc gyro mag*/
+ atomic_t delay;
+ atomic_t selftest_result;
+
+ u8 fifo_data_sel;
+ u16 fifo_bytecount;
+ u8 fifo_head_en;
+ unsigned char fifo_int_tag_en;
+ struct fifo_frame_t fifo_frame;
+
+ unsigned char *fifo_data;
+ u64 fifo_time;
+ u8 stc_enable;
+ uint16_t gpio_pin;
+ u8 std;
+ u8 sig_flag;
+ unsigned char calib_status;
+ struct mutex mutex_op_mode;
+ struct mutex mutex_enable;
+ struct bosch_sensor_specific *bosch_pd;
+ int IRQ;
+ int reg_sel;
+ int reg_len;
+ uint64_t timestamp;
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ struct early_suspend early_suspend_handler;
+#endif
+};
+
+
+/*!
+ * we use a typedef to hide the detail,
+ * because this type might be changed
+ */
+struct bosch_sensor_axis_remap {
+ /* src means which source will be mapped to target x, y, z axis */
+ /* if an target OS axis is remapped from (-)x,
+ * src is 0, sign_* is (-)1 */
+ /* if an target OS axis is remapped from (-)y,
+ * src is 1, sign_* is (-)1 */
+ /* if an target OS axis is remapped from (-)z,
+ * src is 2, sign_* is (-)1 */
+ int src_x:3;
+ int src_y:3;
+ int src_z:3;
+
+ int sign_x:2;
+ int sign_y:2;
+ int sign_z:2;
+};
+
+
+struct bosch_sensor_data {
+ union {
+ int16_t v[3];
+ struct {
+ int16_t x;
+ int16_t y;
+ int16_t z;
+ };
+ };
+};
+
+s8 smi_burst_read_wrapper(u8 dev_addr, u8 reg_addr, u8 *data, u16 len);
+int smi_probe(struct smi_client_data *client_data, struct device *dev);
+int smi_remove(struct device *dev);
+int smi_suspend(struct device *dev);
+int smi_resume(struct device *dev);
+
+
+
+
+#endif/*_SMI130_DRIVER_H*/
+/*@}*/
+
diff --git a/drivers/input/sensors/smi130/smi130_i2c.c b/drivers/input/sensors/smi130/smi130_i2c.c
new file mode 100644
index 0000000..24a66c8
--- /dev/null
+++ b/drivers/input/sensors/smi130/smi130_i2c.c
@@ -0,0 +1,372 @@
+ /*
+ * @section LICENSE
+ * (C) Copyright 2011~2018 Bosch Sensortec GmbH All Rights Reserved
+ *
+ * (C) Modification Copyright 2018 Robert Bosch Kft All Rights Reserved
+ *
+ * This software program is licensed subject to the GNU General
+ * Public License (GPL).Version 2,June 1991,
+ * available at http://www.fsf.org/copyleft/gpl.html
+ *
+ *
+ * @filename smi130_i2c.c
+ * @date 2014/11/25 14:40
+ * @Modification Date 2018/06/21 15:03
+ * @version 1.3
+ *
+ * @brief
+ * This file implements moudle function, which add
+ * the driver to I2C core.
+*/
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include "smi130_driver.h"
+
+/*! @defgroup smi130_i2c_src
+ * @brief smi130 i2c driver module
+ @{*/
+
+static struct i2c_client *smi_client;
+/*!
+ * @brief define i2c wirte function
+ *
+ * @param client the pointer of i2c client
+ * @param reg_addr register address
+ * @param data the pointer of data buffer
+ * @param len block size need to write
+ *
+ * @return zero success, non-zero failed
+ * @retval zero success
+ * @retval non-zero failed
+*/
+/* i2c read routine for API*/
+static s8 smi_i2c_read(struct i2c_client *client, u8 reg_addr,
+ u8 *data, u8 len)
+ {
+#if !defined SMI_USE_BASIC_I2C_FUNC
+ s32 dummy;
+ if (NULL == client)
+ return -EINVAL;
+
+ while (0 != len--) {
+#ifdef SMI_SMBUS
+ dummy = i2c_smbus_read_byte_data(client, reg_addr);
+ if (dummy < 0) {
+ dev_err(&client->dev, "i2c smbus read error");
+ return -EIO;
+ }
+ *data = (u8)(dummy & 0xff);
+#else
+ dummy = i2c_master_send(client, (char *)®_addr, 1);
+ if (dummy < 0) {
+ dev_err(&client->dev, "i2c bus master write error");
+ return -EIO;
+ }
+
+ dummy = i2c_master_recv(client, (char *)data, 1);
+ if (dummy < 0) {
+ dev_err(&client->dev, "i2c bus master read error");
+ return -EIO;
+ }
+#endif
+ reg_addr++;
+ data++;
+ }
+ return 0;
+#else
+ int retry;
+
+ struct i2c_msg msg[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 1,
+ .buf = ®_addr,
+ },
+
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = len,
+ .buf = data,
+ },
+ };
+
+ for (retry = 0; retry < SMI_MAX_RETRY_I2C_XFER; retry++) {
+ if (i2c_transfer(client->adapter, msg,
+ ARRAY_SIZE(msg)) > 0)
+ break;
+ else
+ usleep_range(SMI_I2C_WRITE_DELAY_TIME * 1000,
+ SMI_I2C_WRITE_DELAY_TIME * 1000);
+ }
+
+ if (SMI_MAX_RETRY_I2C_XFER <= retry) {
+ dev_err(&client->dev, "I2C xfer error");
+ return -EIO;
+ }
+
+ return 0;
+#endif
+ }
+
+
+static s8 smi_i2c_burst_read(struct i2c_client *client, u8 reg_addr,
+ u8 *data, u16 len)
+{
+ int retry;
+
+ struct i2c_msg msg[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 1,
+ .buf = ®_addr,
+ },
+
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = len,
+ .buf = data,
+ },
+ };
+
+ for (retry = 0; retry < SMI_MAX_RETRY_I2C_XFER; retry++) {
+ if (i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)) > 0)
+ break;
+ else
+ usleep_range(SMI_I2C_WRITE_DELAY_TIME * 1000,
+ SMI_I2C_WRITE_DELAY_TIME * 1000);
+ }
+
+ if (SMI_MAX_RETRY_I2C_XFER <= retry) {
+ dev_err(&client->dev, "I2C xfer error");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+
+/* i2c write routine for */
+static s8 smi_i2c_write(struct i2c_client *client, u8 reg_addr,
+ u8 *data, u8 len)
+{
+#if !defined SMI_USE_BASIC_I2C_FUNC
+ s32 dummy;
+
+#ifndef SMI_SMBUS
+ u8 buffer[2];
+#endif
+
+ if (NULL == client)
+ return -EPERM;
+
+ while (0 != len--) {
+#ifdef SMI_SMBUS
+ dummy = i2c_smbus_write_byte_data(client, reg_addr, *data);
+#else
+ buffer[0] = reg_addr;
+ buffer[1] = *data;
+ dummy = i2c_master_send(client, (char *)buffer, 2);
+#endif
+ reg_addr++;
+ data++;
+ if (dummy < 0) {
+ dev_err(&client->dev, "error writing i2c bus");
+ return -EPERM;
+ }
+
+ }
+ usleep_range(SMI_I2C_WRITE_DELAY_TIME * 1000,
+ SMI_I2C_WRITE_DELAY_TIME * 1000);
+ return 0;
+#else
+ u8 buffer[2];
+ int retry;
+ struct i2c_msg msg[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 2,
+ .buf = buffer,
+ },
+ };
+
+ while (0 != len--) {
+ buffer[0] = reg_addr;
+ buffer[1] = *data;
+ for (retry = 0; retry < SMI_MAX_RETRY_I2C_XFER; retry++) {
+ if (i2c_transfer(client->adapter, msg,
+ ARRAY_SIZE(msg)) > 0) {
+ break;
+ } else {
+ usleep_range(SMI_I2C_WRITE_DELAY_TIME * 1000,
+ SMI_I2C_WRITE_DELAY_TIME * 1000);
+ }
+ }
+ if (SMI_MAX_RETRY_I2C_XFER <= retry) {
+ dev_err(&client->dev, "I2C xfer error");
+ return -EIO;
+ }
+ reg_addr++;
+ data++;
+ }
+
+ usleep_range(SMI_I2C_WRITE_DELAY_TIME * 1000,
+ SMI_I2C_WRITE_DELAY_TIME * 1000);
+ return 0;
+#endif
+}
+
+
+static s8 smi_i2c_read_wrapper(u8 dev_addr, u8 reg_addr, u8 *data, u8 len)
+{
+ int err = 0;
+ err = smi_i2c_read(smi_client, reg_addr, data, len);
+ return err;
+}
+
+static s8 smi_i2c_write_wrapper(u8 dev_addr, u8 reg_addr, u8 *data, u8 len)
+{
+ int err = 0;
+ err = smi_i2c_write(smi_client, reg_addr, data, len);
+ return err;
+}
+
+s8 smi_burst_read_wrapper(u8 dev_addr, u8 reg_addr, u8 *data, u16 len)
+{
+ int err = 0;
+ err = smi_i2c_burst_read(smi_client, reg_addr, data, len);
+ return err;
+}
+EXPORT_SYMBOL(smi_burst_read_wrapper);
+/*!
+ * @brief SMI probe function via i2c bus
+ *
+ * @param client the pointer of i2c client
+ * @param id the pointer of i2c device id
+ *
+ * @return zero success, non-zero failed
+ * @retval zero success
+ * @retval non-zero failed
+*/
+static int smi_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int err = 0;
+ struct smi_client_data *client_data = NULL;
+
+ dev_info(&client->dev, "SMI130 i2c function probe entrance");
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ dev_err(&client->dev, "i2c_check_functionality error!");
+ err = -EIO;
+ goto exit_err_clean;
+ }
+
+ if (NULL == smi_client) {
+ smi_client = client;
+ } else {
+ dev_err(&client->dev,
+ "this driver does not support multiple clients");
+ err = -EBUSY;
+ goto exit_err_clean;
+ }
+
+ client_data = kzalloc(sizeof(struct smi_client_data),
+ GFP_KERNEL);
+ if (NULL == client_data) {
+ dev_err(&client->dev, "no memory available");
+ err = -ENOMEM;
+ goto exit_err_clean;
+ }
+
+ client_data->device.bus_read = smi_i2c_read_wrapper;
+ client_data->device.bus_write = smi_i2c_write_wrapper;
+
+ return smi_probe(client_data, &client->dev);
+
+exit_err_clean:
+ if (err)
+ smi_client = NULL;
+ return err;
+}
+/*
+static int smi_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+ int err = 0;
+ err = smi_suspend(&client->dev);
+ return err;
+}
+
+static int smi_i2c_resume(struct i2c_client *client)
+{
+ int err = 0;
+
+ err = smi_resume(&client->dev);
+
+ return err;
+}
+*/
+
+static int smi_i2c_remove(struct i2c_client *client)
+{
+ int err = 0;
+ err = smi_remove(&client->dev);
+ smi_client = NULL;
+
+ return err;
+}
+
+
+
+static const struct i2c_device_id smi_id[] = {
+ {SENSOR_NAME, 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, smi_id);
+
+static const struct of_device_id smi130_of_match[] = {
+ { .compatible = "bosch-sensortec,smi130", },
+ { .compatible = "smi130", },
+ { .compatible = "bosch, smi130", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, smi130_of_match);
+
+static struct i2c_driver smi_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = SENSOR_NAME,
+ .of_match_table = smi130_of_match,
+ },
+ .class = I2C_CLASS_HWMON,
+ .id_table = smi_id,
+ .probe = smi_i2c_probe,
+ .remove = smi_i2c_remove,
+ /*.suspend = smi_i2c_suspend,
+ .resume = smi_i2c_resume,*/
+};
+
+static int __init SMI_i2c_init(void)
+{
+ return i2c_add_driver(&smi_i2c_driver);
+}
+
+static void __exit SMI_i2c_exit(void)
+{
+ i2c_del_driver(&smi_i2c_driver);
+}
+
+MODULE_AUTHOR("Contact <contact@bosch-sensortec.com>");
+MODULE_DESCRIPTION("driver for " SENSOR_NAME);
+MODULE_LICENSE("GPL v2");
+
+module_init(SMI_i2c_init);
+module_exit(SMI_i2c_exit);
+
diff --git a/drivers/input/sensors/smi130/smi130_spi.c b/drivers/input/sensors/smi130/smi130_spi.c
new file mode 100644
index 0000000..05bd4b8
--- /dev/null
+++ b/drivers/input/sensors/smi130/smi130_spi.c
@@ -0,0 +1,402 @@
+/*
+* @section LICENSE
+* (C) Copyright 2011~2018 Bosch Sensortec GmbH All Rights Reserved
+*
+* (C) Modification Copyright 2018 Robert Bosch Kft All Rights Reserved
+*
+* This software program is licensed subject to the GNU General
+* Public License (GPL).Version 2,June 1991,
+* available at http://www.fsf.org/copyleft/gpl.html
+*
+* Special: Description of the Software:
+*
+* This software module (hereinafter called "Software") and any
+* information on application-sheets (hereinafter called "Information") is
+* provided free of charge for the sole purpose to support your application
+* work.
+*
+* As such, the Software is merely an experimental software, not tested for
+* safety in the field and only intended for inspiration for further development
+* and testing. Any usage in a safety-relevant field of use (like automotive,
+* seafaring, spacefaring, industrial plants etc.) was not intended, so there are
+* no precautions for such usage incorporated in the Software.
+*
+* The Software is specifically designed for the exclusive use for Bosch
+* Sensortec products by personnel who have special experience and training. Do
+* not use this Software if you do not have the proper experience or training.
+*
+* This Software package is provided as is and without any expressed or
+* implied warranties, including without limitation, the implied warranties of
+* merchantability and fitness for a particular purpose.
+*
+* Bosch Sensortec and their representatives and agents deny any liability for
+* the functional impairment of this Software in terms of fitness, performance
+* and safety. Bosch Sensortec and their representatives and agents shall not be
+* liable for any direct or indirect damages or injury, except as otherwise
+* stipulated in mandatory applicable law.
+* The Information provided is believed to be accurate and reliable. Bosch
+* Sensortec assumes no responsibility for the consequences of use of such
+* Information nor for any infringement of patents or other rights of third
+* parties which may result from its use.
+*
+*------------------------------------------------------------------------------
+* The following Product Disclaimer does not apply to the BSX4-HAL-4.1NoFusion Software
+* which is licensed under the Apache License, Version 2.0 as stated above.
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Product Disclaimer
+*
+* Common:
+*
+* Assessment of Products Returned from Field
+*
+* Returned products are considered good if they fulfill the specifications /
+* test data for 0-mileage and field listed in this document.
+*
+* Engineering Samples
+*
+* Engineering samples are marked with (e) or (E). Samples may vary from the
+* valid technical specifications of the series product contained in this
+* data sheet. Therefore, they are not intended or fit for resale to
+* third parties or for use in end products. Their sole purpose is internal
+* client testing. The testing of an engineering sample may in no way replace
+* the testing of a series product. Bosch assumes no liability for the use
+* of engineering samples. The purchaser shall indemnify Bosch from all claims
+* arising from the use of engineering samples.
+*
+* Intended use
+*
+* Provided that SMI130 is used within the conditions (environment, application,
+* installation, loads) as described in this TCD and the corresponding
+* agreed upon documents, Bosch ensures that the product complies with
+* the agreed properties. Agreements beyond this require
+* the written approval by Bosch. The product is considered fit for the intended
+* use when the product successfully has passed the tests
+* in accordance with the TCD and agreed upon documents.
+*
+* It is the responsibility of the customer to ensure the proper application
+* of the product in the overall system/vehicle.
+*
+* Bosch does not assume any responsibility for changes to the environment
+* of the product that deviate from the TCD and the agreed upon documents
+* as well as all applications not released by Bosch
+*
+* The resale and/or use of products are at the purchaser’s own risk and
+* responsibility. The examination and testing of the SMI130
+* is the sole responsibility of the purchaser.
+*
+* The purchaser shall indemnify Bosch from all third party claims
+* arising from any product use not covered by the parameters of
+* this product data sheet or not approved by Bosch and reimburse Bosch
+* for all costs and damages in connection with such claims.
+*
+* The purchaser must monitor the market for the purchased products,
+* particularly with regard to product safety, and inform Bosch without delay
+* of all security relevant incidents.
+*
+* Application Examples and Hints
+*
+* With respect to any application examples, advice, normal values
+* and/or any information regarding the application of the device,
+* Bosch hereby disclaims any and all warranties and liabilities of any kind,
+* including without limitation warranties of
+* non-infringement of intellectual property rights or copyrights
+* of any third party.
+* The information given in this document shall in no event be regarded
+* as a guarantee of conditions or characteristics. They are provided
+* for illustrative purposes only and no evaluation regarding infringement
+* of intellectual property rights or copyrights or regarding functionality,
+* performance or error has been made.
+*
+*
+* @filename smi130_spi.c
+* @date 2014/11/25 14:40
+* @Modification Date 2018/06/21 15:03
+* @version 1.3
+*
+* @brief
+* This file implements moudle function, which add
+* the driver to SPI core.
+*/
+
+#include <linux/module.h>
+#include <linux/spi/spi.h>
+#include <linux/delay.h>
+#include "smi130_driver.h"
+
+/*! @defgroup smi130_spi_src
+ * @brief smi130 spi driver module
+ @{*/
+/*! the maximum of transfer buffer size */
+#define SMI_MAX_BUFFER_SIZE 32
+
+static struct spi_device *smi_spi_client;
+
+/*!
+ * @brief define spi wirte function
+ *
+ * @param dev_addr sensor device address
+ * @param reg_addr register address
+ * @param data the pointer of data buffer
+ * @param len block size need to write
+ *
+ * @return zero success, non-zero failed
+ * @retval zero success
+ * @retval non-zero failed
+*/
+static char smi_spi_write_block(u8 dev_addr, u8 reg_addr, u8 *data, u8 len)
+{
+ struct spi_device *client = smi_spi_client;
+ u8 buffer[SMI_MAX_BUFFER_SIZE + 1];
+ struct spi_transfer xfer = {
+ .tx_buf = buffer,
+ .len = len + 1,
+ };
+ struct spi_message msg;
+
+ if (len > SMI_MAX_BUFFER_SIZE)
+ return -EINVAL;
+
+ buffer[0] = reg_addr&0x7F;/* write: MSB = 0 */
+ memcpy(&buffer[1], data, len);
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ return spi_sync(client, &msg);
+}
+
+/*!
+ * @brief define spi read function
+ *
+ * @param dev_addr sensor device address
+ * @param reg_addr register address
+ * @param data the pointer of data buffer
+ * @param len block size need to read
+ *
+ * @return zero success, non-zero failed
+ * @retval zero success
+ * @retval non-zero failed
+*/
+static char smi_spi_read_block(u8 dev_addr, u8 reg_addr, u8 *data, u8 len)
+{
+ struct spi_device *client = smi_spi_client;
+ u8 reg = reg_addr | 0x80;/* read: MSB = 1 */
+ struct spi_transfer xfer[2] = {
+ [0] = {
+ .tx_buf = ®,
+ .len = 1,
+ },
+ [1] = {
+ .rx_buf = data,
+ .len = len,
+ }
+ };
+ struct spi_message msg;
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer[0], &msg);
+ spi_message_add_tail(&xfer[1], &msg);
+ return spi_sync(client, &msg);
+}
+
+s8 smi_burst_read_wrapper(u8 dev_addr, u8 reg_addr, u8 *data, u16 len)
+{
+ struct spi_device *client = smi_spi_client;
+ u8 reg = reg_addr | 0x80;/* read: MSB = 1 */
+ struct spi_transfer xfer[2] = {
+ [0] = {
+ .tx_buf = ®,
+ .len = 1,
+ },
+ [1] = {
+ .rx_buf = data,
+ .len = len,
+ }
+ };
+ struct spi_message msg;
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer[0], &msg);
+ spi_message_add_tail(&xfer[1], &msg);
+ return spi_sync(client, &msg);
+}
+EXPORT_SYMBOL(smi_burst_read_wrapper);
+/*!
+ * @brief SMI probe function via spi bus
+ *
+ * @param client the pointer of spi client
+ *
+ * @return zero success, non-zero failed
+ * @retval zero success
+ * @retval non-zero failed
+*/
+static int smi_spi_probe(struct spi_device *client)
+{
+ int status;
+ int err = 0;
+ struct smi_client_data *client_data = NULL;
+
+ if (NULL == smi_spi_client)
+ smi_spi_client = client;
+ else{
+ dev_err(&client->dev, "This driver does not support multiple clients!\n");
+ return -EBUSY;
+ }
+
+ client->bits_per_word = 8;
+ status = spi_setup(client);
+ if (status < 0) {
+ dev_err(&client->dev, "spi_setup failed!\n");
+ return status;
+ }
+
+ client_data = kzalloc(sizeof(struct smi_client_data), GFP_KERNEL);
+ if (NULL == client_data) {
+ dev_err(&client->dev, "no memory available");
+ err = -ENOMEM;
+ goto exit_err_clean;
+ }
+
+ client_data->device.bus_read = smi_spi_read_block;
+ client_data->device.bus_write = smi_spi_write_block;
+
+ return smi_probe(client_data, &client->dev);
+
+exit_err_clean:
+ if (err)
+ smi_spi_client = NULL;
+ return err;
+}
+
+/*!
+ * @brief shutdown smi device in spi driver
+ *
+ * @param client the pointer of spi client
+ *
+ * @return no return value
+*/
+static void smi_spi_shutdown(struct spi_device *client)
+{
+#ifdef CONFIG_PM
+ smi_suspend(&client->dev);
+#endif
+}
+
+/*!
+ * @brief remove smi spi client
+ *
+ * @param client the pointer of spi client
+ *
+ * @return zero
+ * @retval zero
+*/
+static int smi_spi_remove(struct spi_device *client)
+{
+ int err = 0;
+ err = smi_remove(&client->dev);
+ smi_spi_client = NULL;
+
+ return err;
+}
+
+#ifdef CONFIG_PM
+/*!
+ * @brief suspend smi device in spi driver
+ *
+ * @param dev the pointer of device
+ *
+ * @return zero
+ * @retval zero
+*/
+static int smi_spi_suspend(struct device *dev)
+{
+ int err = 0;
+ err = smi_suspend(dev);
+ return err;
+}
+
+/*!
+ * @brief resume smi device in spi driver
+ *
+ * @param dev the pointer of device
+ *
+ * @return zero
+ * @retval zero
+*/
+static int smi_spi_resume(struct device *dev)
+{
+ int err = 0;
+ /* post resume operation */
+ err = smi_resume(dev);
+
+ return err;
+}
+
+/*!
+ * @brief register spi device power manager hooks
+*/
+static const struct dev_pm_ops smi_spi_pm_ops = {
+ /**< device suspend */
+ .suspend = smi_spi_suspend,
+ /**< device resume */
+ .resume = smi_spi_resume
+};
+#endif
+
+/*!
+ * @brief register spi device id
+*/
+static const struct spi_device_id smi_id[] = {
+ { SENSOR_NAME, 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(spi, smi_id);
+
+/*!
+ * @brief register spi driver hooks
+*/
+static struct spi_driver smi_spi_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = SENSOR_NAME,
+#ifdef CONFIG_PM
+ .pm = &smi_spi_pm_ops,
+#endif
+ },
+ .id_table = smi_id,
+ .probe = smi_spi_probe,
+ .shutdown = smi_spi_shutdown,
+ .remove = smi_spi_remove
+};
+
+/*!
+ * @brief initialize smi spi module
+ *
+ * @return zero success, non-zero failed
+ * @retval zero success
+ * @retval non-zero failed
+*/
+static int __init smi_spi_init(void)
+{
+ return spi_register_driver(&smi_spi_driver);
+}
+
+/*!
+ * @brief remove smi spi module
+ *
+ * @return no return value
+*/
+static void __exit smi_spi_exit(void)
+{
+ spi_unregister_driver(&smi_spi_driver);
+}
+
+
+MODULE_AUTHOR("Contact <contact@bosch-sensortec.com>");
+MODULE_DESCRIPTION("SMI130 SPI DRIVER");
+MODULE_LICENSE("GPL v2");
+
+module_init(smi_spi_init);
+module_exit(smi_spi_exit);
+/*@}*/
+
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 84a2372..23d67f5 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -1151,4 +1151,16 @@
source "drivers/input/touchscreen/gt9xx/Kconfig"
source "drivers/input/touchscreen/focaltech_touch/Kconfig"
+config TOUCHSCREEN_HIMAX_CHIPSET
+ bool "Himax touchpanel CHIPSET"
+ depends on I2C
+ help
+ Say Y here if you have a Himax CHIPSET touchscreen.
+ HIMAX controllers are multi touch controllers which can
+ report 10 touches at a time.
+
+ If unsure, say N.
+
+source "drivers/input/touchscreen/hxchipset/Kconfig"
+
endif
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index f575624..d1a9fdb 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -90,6 +90,7 @@
obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV) += synaptics_rmi_dev.o
obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE) += synaptics_fw_update.o
obj-$(CONFIG_TOUCHSCREEN_GT9XX) += gt9xx/
+obj-$(CONFIG_TOUCHSCREEN_HIMAX_CHIPSET) += hxchipset/
obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_touch/
obj-$(CONFIG_TOUCHSCREEN_FT3207) += fts_ts.o
fts_ts-$(CONFIG_TOUCHSCREEN_FT3207) += focaltech_core.o focaltech_ctl.o focaltech_ex_fun.o focaltech_flash.o \
diff --git a/drivers/input/touchscreen/hxchipset/Kconfig b/drivers/input/touchscreen/hxchipset/Kconfig
new file mode 100644
index 0000000..3dc5a02
--- /dev/null
+++ b/drivers/input/touchscreen/hxchipset/Kconfig
@@ -0,0 +1,46 @@
+#
+# Himax Touchscreen driver configuration
+#
+
+config TOUCHSCREEN_HIMAX_I2C
+ tristate "HIMAX chipset i2c touchscreen"
+ depends on TOUCHSCREEN_HIMAX_CHIPSET
+ help
+ Say Y here to enable support for HIMAX CHIPSET over I2C based touchscreens.
+ If unsure, say N.
+
+ To compile this driver as a module,
+ This enables support for HIMAX CHIPSET over I2C based touchscreens.
+
+config TOUCHSCREEN_HIMAX_DEBUG
+ tristate "HIMAX debug function"
+ depends on TOUCHSCREEN_HIMAX_I2C
+ help
+ Say Y here to enable support for HIMAX debug function.
+
+ If unsure, say N.
+
+ To compile this driver as a module,
+ This enables support for HIMAX debug function.
+
+config TOUCHSCREEN_HIMAX_ITO_TEST
+ tristate "HIMAX driver test over Dragon Board"
+ depends on TOUCHSCREEN_HIMAX_I2C
+ help
+ Say Y here to enable support for HIMAX driver test over Dragon Board.
+
+ If unsure, say N.
+
+ To compile this driver as a module,
+ this enables support for HIMAX driver test over Dragon Board.
+
+config HMX_DB
+ tristate "HIMAX driver test over Dragon Board"
+ depends on TOUCHSCREEN_HIMAX_I2C
+ help
+ Say Y here to enable support for HIMAX driver test over Dragon Board.
+
+ If unsure, say N.
+
+ To compile this driver as a module,
+ this enables support for HIMAX driver test over Dragon Board.
diff --git a/drivers/input/touchscreen/hxchipset/Makefile b/drivers/input/touchscreen/hxchipset/Makefile
new file mode 100644
index 0000000..522907a
--- /dev/null
+++ b/drivers/input/touchscreen/hxchipset/Makefile
@@ -0,0 +1,4 @@
+# Makefile for the Himax touchscreen drivers.
+
+obj-$(CONFIG_TOUCHSCREEN_HIMAX_I2C) += himax_platform.o himax_ic.o himax_common.o himax_debug.o
+obj-$(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST) += himax_ito_test.o
\ No newline at end of file
diff --git a/drivers/input/touchscreen/hxchipset/himax_common.c b/drivers/input/touchscreen/hxchipset/himax_common.c
new file mode 100644
index 0000000..d4bc5be
--- /dev/null
+++ b/drivers/input/touchscreen/hxchipset/himax_common.c
@@ -0,0 +1,1984 @@
+ /* Himax Android Driver Sample Code for Himax chipset
+*
+* Copyright (C) 2015 Himax Corporation.
+*
+* This software is licensed under the terms of the GNU General Public
+* License version 2, as published by the Free Software Foundation, and
+* may be copied, distributed, and modified under those terms.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+*/
+
+#include "himax_common.h"
+#include "himax_ic.h"
+
+#define SUPPORT_FINGER_DATA_CHECKSUM 0x0F
+#define TS_WAKE_LOCK_TIMEOUT (2 * HZ)
+#define FRAME_COUNT 5
+
+#if defined(HX_AUTO_UPDATE_FW)
+ char *i_CTPM_firmware_name = "HX83100_Amber_0B01_030E.bin";
+ const struct firmware *i_CTPM_FW = NULL;
+#endif
+
+/*static int tpd_keys_local[HX_KEY_MAX_COUNT] = HX_KEY_ARRAY;
+// for Virtual key array */
+
+struct himax_ts_data *private_ts;
+struct himax_ic_data *ic_data;
+
+static int HX_TOUCH_INFO_POINT_CNT;
+
+static uint8_t vk_press = 0x00;
+static uint8_t AA_press = 0x00;
+static uint8_t EN_NoiseFilter = 0x00;
+static int hx_point_num; /*for himax_ts_work_func use*/
+static int p_point_num = 0xFFFF;
+static int tpd_key = 0x00;
+static int tpd_key_old = 0x00;
+static int probe_fail_flag;
+static bool config_load;
+static struct himax_config *config_selected;
+
+/*static int iref_number = 11;*/
+/*static bool iref_found = false;*/
+
+
+#if defined(CONFIG_FB)
+int fb_notifier_callback(struct notifier_block *self,
+ unsigned long event, void *data);
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+static void himax_ts_early_suspend(struct early_suspend *h);
+static void himax_ts_late_resume(struct early_suspend *h);
+#endif
+
+int himax_input_register(struct himax_ts_data *ts)
+{
+ int ret;
+
+ ts->input_dev = input_allocate_device();
+ if (ts->input_dev == NULL) {
+ ret = -ENOMEM;
+ E("%s: Failed to allocate input device\n", __func__);
+ return ret;
+ }
+ ts->input_dev->name = "himax-touchscreen";
+
+ set_bit(EV_SYN, ts->input_dev->evbit);
+ set_bit(EV_ABS, ts->input_dev->evbit);
+ set_bit(EV_KEY, ts->input_dev->evbit);
+
+ set_bit(KEY_BACK, ts->input_dev->keybit);
+ set_bit(KEY_HOME, ts->input_dev->keybit);
+ set_bit(KEY_MENU, ts->input_dev->keybit);
+ set_bit(KEY_SEARCH, ts->input_dev->keybit);
+#if defined(HX_SMART_WAKEUP)
+ set_bit(KEY_POWER, ts->input_dev->keybit);
+ set_bit(KEY_CUST_01, ts->input_dev->keybit);
+ set_bit(KEY_CUST_02, ts->input_dev->keybit);
+ set_bit(KEY_CUST_03, ts->input_dev->keybit);
+ set_bit(KEY_CUST_04, ts->input_dev->keybit);
+ set_bit(KEY_CUST_05, ts->input_dev->keybit);
+ set_bit(KEY_CUST_06, ts->input_dev->keybit);
+ set_bit(KEY_CUST_07, ts->input_dev->keybit);
+ set_bit(KEY_CUST_08, ts->input_dev->keybit);
+ set_bit(KEY_CUST_09, ts->input_dev->keybit);
+ set_bit(KEY_CUST_10, ts->input_dev->keybit);
+ set_bit(KEY_CUST_11, ts->input_dev->keybit);
+ set_bit(KEY_CUST_12, ts->input_dev->keybit);
+ set_bit(KEY_CUST_13, ts->input_dev->keybit);
+ set_bit(KEY_CUST_14, ts->input_dev->keybit);
+ set_bit(KEY_CUST_15, ts->input_dev->keybit);
+#endif
+ set_bit(BTN_TOUCH, ts->input_dev->keybit);
+
+ set_bit(KEY_F10, ts->input_dev->keybit);
+
+ set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit);
+
+ if (ts->protocol_type == PROTOCOL_TYPE_A) {
+ /*ts->input_dev->mtsize = ts->nFinger_support;*/
+ input_set_abs_params(ts->input_dev, ABS_MT_TRACKING_ID,
+ 0, 3, 0, 0);
+ } else {/* PROTOCOL_TYPE_B */
+ set_bit(MT_TOOL_FINGER, ts->input_dev->keybit);
+ input_mt_init_slots(ts->input_dev, ts->nFinger_support, 0);
+ }
+
+ I("input_set_abs_params: mix_x %d, max_x %d, min_y %d, max_y %d\n",
+ ts->pdata->abs_x_min, ts->pdata->abs_x_max,
+ ts->pdata->abs_y_min, ts->pdata->abs_y_max);
+
+ input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X,
+ ts->pdata->abs_x_min, ts->pdata->abs_x_max, ts->pdata->abs_x_fuzz, 0);
+ input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y,
+ ts->pdata->abs_y_min, ts->pdata->abs_y_max, ts->pdata->abs_y_fuzz, 0);
+ input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR,
+ ts->pdata->abs_pressure_min, ts->pdata->abs_pressure_max,
+ ts->pdata->abs_pressure_fuzz, 0);
+ input_set_abs_params(ts->input_dev, ABS_MT_PRESSURE,
+ ts->pdata->abs_pressure_min, ts->pdata->abs_pressure_max,
+ ts->pdata->abs_pressure_fuzz, 0);
+ input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR,
+ ts->pdata->abs_width_min, ts->pdata->abs_width_max,
+ ts->pdata->abs_pressure_fuzz, 0);
+
+/*input_set_abs_params(ts->input_dev, ABS_MT_AMPLITUDE, 0,
+((ts->pdata->abs_pressure_max << 16) | ts->pdata->abs_width_max), 0, 0);*/
+/*input_set_abs_params(ts->input_dev, ABS_MT_POSITION, 0,
+(BIT(31) | (ts->pdata->abs_x_max << 16) | ts->pdata->abs_y_max), 0, 0);*/
+
+ return input_register_device(ts->input_dev);
+}
+
+static void calcDataSize(uint8_t finger_num)
+{
+ struct himax_ts_data *ts_data = private_ts;
+
+ ts_data->coord_data_size = 4 * finger_num;
+ ts_data->area_data_size = ((finger_num / 4) +
+ (finger_num % 4 ? 1 : 0)) * 4;
+ ts_data->raw_data_frame_size = 128 -
+ ts_data->coord_data_size -
+ ts_data->area_data_size - 4 - 4 - 1;
+
+ ts_data->raw_data_nframes =
+ ((uint32_t)ts_data->x_channel *
+ ts_data->y_channel + ts_data->x_channel + ts_data->y_channel) /
+ ts_data->raw_data_frame_size + (((uint32_t)ts_data->x_channel *
+ ts_data->y_channel + ts_data->x_channel + ts_data->y_channel) %
+ ts_data->raw_data_frame_size) ? 1 : 0;
+
+ I("%s: coord_data_size: %d, area_data_size:%d",
+ __func__, ts_data->coord_data_size, ts_data->area_data_size);
+ I("raw_data_frame_size:%d, raw_data_nframes:%d",
+ ts_data->raw_data_frame_size, ts_data->raw_data_nframes);
+}
+
+static void calculate_point_number(void)
+{
+ HX_TOUCH_INFO_POINT_CNT = ic_data->HX_MAX_PT * 4;
+
+ if ((ic_data->HX_MAX_PT % 4) == 0)
+ HX_TOUCH_INFO_POINT_CNT += (ic_data->HX_MAX_PT / 4) * 4;
+ else
+ HX_TOUCH_INFO_POINT_CNT += ((ic_data->HX_MAX_PT / 4) + 1) * 4;
+}
+
+/*#if 0*/
+#ifdef HX_EN_CHECK_PATCH
+static int himax_read_Sensor_ID(struct i2c_client *client)
+{
+ uint8_t val_high[1], val_low[1], ID0 = 0, ID1 = 0;
+ char data[3];
+ const int normalRetry = 10;
+ int sensor_id;
+
+ data[0] = 0x56; data[1] = 0x02;
+ data[2] = 0x02;/*ID pin PULL High*/
+ i2c_himax_master_write(client, &data[0], 3, normalRetry);
+ usleep(1000);
+
+ /*read id pin high*/
+ i2c_himax_read(client, 0x57, val_high, 1, normalRetry);
+
+ data[0] = 0x56; data[1] = 0x01;
+ data[2] = 0x01;/*ID pin PULL Low*/
+ i2c_himax_master_write(client, &data[0], 3, normalRetry);
+ usleep(1000);
+
+ /*read id pin low*/
+ i2c_himax_read(client, 0x57, val_low, 1, normalRetry);
+
+ if ((val_high[0] & 0x01) == 0)
+ ID0 = 0x02;/*GND*/
+ else if ((val_low[0] & 0x01) == 0)
+ ID0 = 0x01;/*Floating*/
+ else
+ ID0 = 0x04;/*VCC*/
+
+ if ((val_high[0] & 0x02) == 0)
+ ID1 = 0x02;/*GND*/
+ else if ((val_low[0] & 0x02) == 0)
+ ID1 = 0x01;/*Floating*/
+ else
+ ID1 = 0x04;/*VCC*/
+ if ((ID0 == 0x04) && (ID1 != 0x04)) {
+ data[0] = 0x56; data[1] = 0x02;
+ data[2] = 0x01;/*ID pin PULL High,Low*/
+ i2c_himax_master_write(client,
+ &data[0], 3, normalRetry);
+ usleep(1000);
+
+ } else if ((ID0 != 0x04) && (ID1 == 0x04)) {
+ data[0] = 0x56; data[1] = 0x01;
+ data[2] = 0x02;/*ID pin PULL Low,High*/
+ i2c_himax_master_write(client,
+ &data[0], 3, normalRetry);
+ usleep(1000);
+
+ } else if ((ID0 == 0x04) && (ID1 == 0x04)) {
+ data[0] = 0x56; data[1] = 0x02;
+ data[2] = 0x02;/*ID pin PULL High,High*/
+ i2c_himax_master_write(client,
+ &data[0], 3, normalRetry);
+ usleep(1000);
+
+ }
+ sensor_id = (ID1<<4)|ID0;
+
+ data[0] = 0xE4; data[1] = sensor_id;
+ i2c_himax_master_write(client,
+ &data[0], 2, normalRetry);/*Write to MCU*/
+ usleep(1000);
+
+ return sensor_id;
+
+}
+#endif
+static void himax_power_on_initCMD(struct i2c_client *client)
+{
+ I("%s:\n", __func__);
+ himax_touch_information(client);
+ /*himax_sense_on(private_ts->client, 0x01);//1=Flash, 0=SRAM */
+}
+
+#ifdef HX_AUTO_UPDATE_FW
+static int i_update_FW(void)
+{
+ int upgrade_times = 0;
+ int fullFileLength = 0;
+ int i_FW_VER = 0, i_CFG_VER = 0;
+ int ret = -1, result = 0;
+ /*uint8_t tmp_addr[4];*/
+ /*uint8_t tmp_data[4];*/
+ int CRC_from_FW = 0;
+ int CRC_Check_result = 0;
+
+ ret = himax_load_CRC_bin_file(private_ts->client);
+ if (ret < 0) {
+ E("%s: himax_load_CRC_bin_file fail Error Code=%d.\n",
+ __func__, ret);
+ ret = -1;
+ return ret;
+ }
+ I("file name = %s\n", i_CTPM_firmware_name);
+ ret = request_firmware(&i_CTPM_FW,
+ i_CTPM_firmware_name, private_ts->dev);
+ if (ret < 0) {
+ E("%s,fail in line%d error code=%d\n",
+ __func__, __LINE__, ret);
+ ret = -2;
+ return ret;
+ }
+
+ if (i_CTPM_FW == NULL) {
+ I("%s: i_CTPM_FW = NULL\n", __func__);
+ ret = -3;
+ return ret;
+ }
+ fullFileLength = i_CTPM_FW->size;
+
+ i_FW_VER = i_CTPM_FW->data[FW_VER_MAJ_FLASH_ADDR]<<8
+ | i_CTPM_FW->data[FW_VER_MIN_FLASH_ADDR];
+ i_CFG_VER = i_CTPM_FW->data[CFG_VER_MAJ_FLASH_ADDR]<<8
+ | i_CTPM_FW->data[CFG_VER_MIN_FLASH_ADDR];
+
+ I("%s: i_fullFileLength = %d\n", __func__, fullFileLength);
+
+ himax_sense_off(private_ts->client);
+ msleep(500);
+
+ CRC_from_FW = himax_check_CRC(private_ts->client, fw_image_64k);
+ CRC_Check_result =
+ Calculate_CRC_with_AP((unsigned char *)i_CTPM_FW->data,
+ CRC_from_FW, fw_image_64k);
+ I("%s: Check sum result = %d\n", __func__, CRC_Check_result);
+ /*I("%s: ic_data->vendor_fw_ver = %X, i_FW_VER = %X,\n",
+ __func__, ic_data->vendor_fw_ver, i_FW_VER);*/
+ /*I("%s: ic_data->vendor_config_ver = %X, i_CFG_VER = %X,\n",
+ __func__, ic_data->vendor_config_ver, i_CFG_VER);*/
+
+ if ((CRC_Check_result == 0) ||
+ (ic_data->vendor_fw_ver < i_FW_VER) ||
+ (ic_data->vendor_config_ver < i_CFG_VER)) {
+ himax_int_enable(private_ts->client->irq, 0);
+update_retry:
+ if (fullFileLength == FW_SIZE_60k) {
+ ret = fts_ctpm_fw_upgrade_with_sys_fs_60k
+ (private_ts->client,
+ (unsigned char *)i_CTPM_FW->data,
+ fullFileLength, false);
+ } else if (fullFileLength == FW_SIZE_64k) {
+ ret = fts_ctpm_fw_upgrade_with_sys_fs_64k
+ (private_ts->client,
+ (unsigned char *)i_CTPM_FW->data,
+ fullFileLength, false);
+ } else if (fullFileLength == FW_SIZE_124k) {
+ ret = fts_ctpm_fw_upgrade_with_sys_fs_124k
+ (private_ts->client,
+ (unsigned char *)i_CTPM_FW->data,
+ fullFileLength, false);
+ } else if (fullFileLength == FW_SIZE_128k) {
+ ret = fts_ctpm_fw_upgrade_with_sys_fs_128k
+ (private_ts->client,
+ (unsigned char *)i_CTPM_FW->data,
+ fullFileLength, false);
+ }
+ if (ret == 0) {
+ upgrade_times++;
+ E("%s: TP upgrade error, upgrade_times = %d\n",
+ __func__, upgrade_times);
+ if (upgrade_times < 3)
+ goto update_retry;
+ else {
+ himax_sense_on(private_ts->client, 0x01);
+ msleep(120);
+#ifdef HX_ESD_WORKAROUND
+ HX_ESD_RESET_ACTIVATE = 1;
+#endif
+ result = -1;/*upgrade fail*/
+ }
+ } else if (ret == 1) {
+ /*
+ // 1. Set DDREG_Req = 1 (0x9000_0020 = 0x0000_0001)
+ (Lock register R/W from driver)
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x01;
+ himax_register_write(private_ts->client,
+ tmp_addr, 1, tmp_data);
+
+ // 2. Write driver initial code condition
+ //write value from AHB I2C:0x8001_C603 = 0x000000FF
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x01;
+ tmp_addr[1] = 0xC6; tmp_addr[0] = 0x03;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0xFF;
+ himax_register_write(private_ts->client,
+ tmp_addr, 1, tmp_data);
+
+ // 1. Set DDREG_Req = 0(0x9000_0020 = 0x0000_0001)
+ (Lock register R/W from driver)
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ himax_register_write(private_ts->client,
+ tmp_addr, 1, tmp_data);
+ */
+ himax_sense_on(private_ts->client, 0x01);
+ msleep(120);
+#ifdef HX_ESD_WORKAROUND
+ HX_ESD_RESET_ACTIVATE = 1;
+#endif
+
+ ic_data->vendor_fw_ver = i_FW_VER;
+ ic_data->vendor_config_ver = i_CFG_VER;
+ result = 1;/*upgrade success*/
+ I("%s: TP upgrade OK\n", __func__);
+ }
+
+ himax_int_enable(private_ts->client->irq, 1);
+ return result;
+
+ } else {
+ himax_sense_on(private_ts->client, 0x01);
+ return 0;/*NO upgrade*/
+ }
+}
+#endif
+
+#ifdef HX_RST_PIN_FUNC
+void himax_HW_reset(uint8_t loadconfig, uint8_t int_off)
+{
+ struct himax_ts_data *ts = private_ts;
+ int ret = 0;
+
+ return;
+ if (ts->rst_gpio) {
+ if (int_off) {
+ if (ts->use_irq)
+ himax_int_enable(private_ts->client->irq, 0);
+ else {
+ hrtimer_cancel(&ts->timer);
+ ret = cancel_work_sync(&ts->work);
+ }
+ }
+
+ I("%s: Now reset the Touch chip.\n", __func__);
+
+ himax_rst_gpio_set(ts->rst_gpio, 0);
+ msleep(20);
+ himax_rst_gpio_set(ts->rst_gpio, 1);
+ msleep(20);
+
+ if (loadconfig)
+ himax_loadSensorConfig(private_ts->client,
+ private_ts->pdata);
+
+ if (int_off) {
+ if (ts->use_irq)
+ himax_int_enable(private_ts->client->irq, 1);
+ else
+ hrtimer_start(&ts->timer,
+ ktime_set(1, 0), HRTIMER_MODE_REL);
+ }
+ }
+}
+#endif
+
+int himax_loadSensorConfig(struct i2c_client *client,
+struct himax_i2c_platform_data *pdata)
+{
+ int err = -1;
+
+ if (!client) {
+ E("%s: Necessary parameters client are null!\n", __func__);
+ return err;
+ }
+ if (config_load == false) {
+ config_selected = kzalloc(sizeof(*config_selected), GFP_KERNEL);
+ if (config_selected == NULL) {
+ E("%s: alloc config_selected fail!\n", __func__);
+ return err;
+ }
+ }
+ himax_power_on_initCMD(client);
+
+ himax_int_enable(client->irq, 0);
+ himax_read_FW_ver(client);
+#ifdef HX_RST_PIN_FUNC
+ himax_HW_reset(true, false);
+#endif
+ himax_int_enable(client->irq, 1);
+ I("FW_VER : %X\n", ic_data->vendor_fw_ver);
+
+ ic_data->vendor_sensor_id = 0x2602;
+ I("sensor_id=%x.\n", ic_data->vendor_sensor_id);
+
+ himax_sense_on(private_ts->client, 0x01);/*1=Flash, 0=SRAM*/
+ msleep(120);
+#ifdef HX_ESD_WORKAROUND
+ HX_ESD_RESET_ACTIVATE = 1;
+#endif
+ I("%s: initialization complete\n", __func__);
+
+ return 1;
+}
+
+#ifdef HX_ESD_WORKAROUND
+void ESD_HW_REST(void)
+{
+ I("START_Himax TP: ESD - Reset\n");
+
+ HX_report_ESD_event();
+ ESD_00_counter = 0;
+ ESD_00_Flag = 0;
+ /*************************************/
+ if (private_ts->protocol_type == PROTOCOL_TYPE_A)
+ input_mt_sync(private_ts->input_dev);
+ input_report_key(private_ts->input_dev, BTN_TOUCH, 0);
+ input_sync(private_ts->input_dev);
+ /*************************************/
+
+ I("END_Himax TP: ESD - Reset\n");
+}
+#endif
+#ifdef HX_HIGH_SENSE
+void himax_set_HSEN_func(struct i2c_client *client, uint8_t HSEN_enable)
+{
+ uint8_t tmp_data[4];
+
+ if (HSEN_enable) {
+ I(" %s in", __func__);
+HSEN_bit_retry:
+ himax_set_HSEN_enable(client, HSEN_enable);
+ msleep(20);
+ himax_get_HSEN_enable(client, tmp_data);
+ I("%s: Read HSEN bit data[0]=%x data[1]=%x",
+ __func__, tmp_data[0], tmp_data[1]);
+ I("data[2]=%x data[3]=%x\n",
+ tmp_data[2], tmp_data[3]);
+
+ if (tmp_data[0] != 0x01) {
+ I("%s: retry HSEN bit write data[0]=%x\n",
+ __func__, tmp_data[0]);
+ goto HSEN_bit_retry;
+ }
+ }
+}
+
+static void himax_HSEN_func(struct work_struct *work)
+{
+ struct himax_ts_data *ts =
+ container_of(work, struct himax_ts_data, hsen_work.work);
+
+ himax_set_HSEN_func(ts->client, ts->HSEN_enable);
+}
+
+#endif
+
+#ifdef HX_SMART_WAKEUP
+#ifdef HX_GESTURE_TRACK
+static void gest_pt_log_coordinate(int rx, int tx)
+{
+ /*driver report x y with range 0 - 255*/
+ /* And we scale it up to x/y coordinates*/
+ gest_pt_x[gest_pt_cnt] = rx * (ic_data->HX_X_RES) / 255;
+ gest_pt_y[gest_pt_cnt] = tx * (ic_data->HX_Y_RES) / 255;
+}
+#endif
+static int himax_parse_wake_event(struct himax_ts_data *ts)
+{
+ uint8_t buf[64];
+ unsigned char check_sum_cal = 0;
+#ifdef HX_GESTURE_TRACK
+ int tmp_max_x = 0x00, tmp_min_x = 0xFFFF,
+ tmp_max_y = 0x00, tmp_min_y = 0xFFFF;
+ int gest_len;
+#endif
+ int i = 0, check_FC = 0, gesture_flag = 0;
+
+ himax_burst_enable(ts->client, 0);
+ himax_read_event_stack(ts->client, buf, 56);
+
+ for (i = 0 ; i < GEST_PTLG_ID_LEN ; i++) {
+ if (check_FC == 0) {
+ if ((buf[0] != 0x00) &&
+ ((buf[0] <= 0x0F) || (buf[0] == 0x80))) {
+ check_FC = 1;
+ gesture_flag = buf[i];
+ } else {
+ check_FC = 0;
+ I("ID START at %x,value = %x skip event\n",
+ i, buf[i]);
+ break;
+ }
+ } else {
+ if (buf[i] != gesture_flag) {
+ check_FC = 0;
+ I("ID NOT same %x != %x So STOP parse event\n",
+ buf[i], gesture_flag);
+ break;
+ }
+ }
+
+ I("0x%2.2X ", buf[i]);
+ if (i % 8 == 7)
+ I("\n");
+ }
+ I("Himax gesture_flag= %x\n", gesture_flag);
+ I("Himax check_FC is %d\n", check_FC);
+
+ if (check_FC == 0)
+ return 0;
+ if (buf[GEST_PTLG_ID_LEN] != GEST_PTLG_HDR_ID1
+ || buf[GEST_PTLG_ID_LEN+1] != GEST_PTLG_HDR_ID2)
+ return 0;
+ for (i = 0 ; i < (GEST_PTLG_ID_LEN + GEST_PTLG_HDR_LEN) ; i++) {
+ I("P[%x]=0x%2.2X\n", i, buf[i]);
+ I("checksum=0x%2.2X\n", check_sum_cal);
+ check_sum_cal += buf[i];
+ }
+ if ((check_sum_cal != 0x00)) {
+ I(" %s : check_sum_cal: 0x%02X\n", __func__ , check_sum_cal);
+ return 0;
+ }
+#ifdef HX_GESTURE_TRACK
+ if (buf[GEST_PTLG_ID_LEN] == GEST_PTLG_HDR_ID1
+ && buf[GEST_PTLG_ID_LEN+1] == GEST_PTLG_HDR_ID2) {
+ gest_len = buf[GEST_PTLG_ID_LEN + 2];
+ I("gest_len = %d ", gest_len);
+ i = 0;
+ gest_pt_cnt = 0;
+ I("gest doornidate start\n %s", __func__);
+ while (i < (gest_len + 1) / 2) {
+ gest_pt_log_coordinate
+ (buf[GEST_PTLG_ID_LEN + 4 + i * 2],
+ buf[GEST_PTLG_ID_LEN + 4 + i * 2 + 1]);
+ i++;
+
+ I("gest_pt_x[%d]=%d\n",
+ gest_pt_cnt, gest_pt_x[gest_pt_cnt]);
+ I("gest_pt_y[%d]=%d\n",
+ gest_pt_cnt, gest_pt_y[gest_pt_cnt]);
+
+ gest_pt_cnt += 1;
+ }
+ if (gest_pt_cnt) {
+ for (i = 0 ; i < gest_pt_cnt ; i++) {
+ if (tmp_max_x < gest_pt_x[i])
+ tmp_max_x = gest_pt_x[i];
+ if (tmp_min_x > gest_pt_x[i])
+ tmp_min_x = gest_pt_x[i];
+ if (tmp_max_y < gest_pt_y[i])
+ tmp_max_y = gest_pt_y[i];
+ if (tmp_min_y > gest_pt_y[i])
+ tmp_min_y = gest_pt_y[i];
+ }
+ I("gest_point x_min= %d, x_max= %d\n",
+ tmp_min_x, tmp_max_x);
+ I("y_min= %d, y_max= %d\n",
+ tmp_min_y, tmp_max_y);
+ gest_start_x = gest_pt_x[0];
+ gn_gesture_coor[0] = gest_start_x;
+ gest_start_y = gest_pt_y[0];
+ gn_gesture_coor[1] = gest_start_y;
+ gest_end_x = gest_pt_x[gest_pt_cnt - 1];
+ gn_gesture_coor[2] = gest_end_x;
+ gest_end_y = gest_pt_y[gest_pt_cnt - 1];
+ gn_gesture_coor[3] = gest_end_y;
+ gest_width = tmp_max_x - tmp_min_x;
+ gn_gesture_coor[4] = gest_width;
+ gest_height = tmp_max_y - tmp_min_y;
+ gn_gesture_coor[5] = gest_height;
+ gest_mid_x = (tmp_max_x + tmp_min_x) / 2;
+ gn_gesture_coor[6] = gest_mid_x;
+ gest_mid_y = (tmp_max_y + tmp_min_y) / 2;
+ gn_gesture_coor[7] = gest_mid_y;
+ /*gest_up_x*/
+ gn_gesture_coor[8] = gest_mid_x;
+ /*gest_up_y*/
+ gn_gesture_coor[9] = gest_mid_y - gest_height / 2;
+ /*gest_down_x*/
+ gn_gesture_coor[10] = gest_mid_x;
+ /*gest_down_y*/
+ gn_gesture_coor[11] = gest_mid_y + gest_height / 2;
+ /*gest_left_x*/
+ gn_gesture_coor[12] = gest_mid_x - gest_width / 2;
+ /*gest_left_y*/
+ gn_gesture_coor[13] = gest_mid_y;
+ /*gest_right_x*/
+ gn_gesture_coor[14] = gest_mid_x + gest_width / 2;
+ /*gest_right_y*/
+ gn_gesture_coor[15] = gest_mid_y;
+
+ }
+
+ }
+#endif
+ if (gesture_flag != 0x80) {
+ if (!ts->gesture_cust_en[gesture_flag]) {
+ I("%s NOT report customer key\n ", __func__);
+ return 0;/*NOT report customer key*/
+ }
+ } else {
+ if (!ts->gesture_cust_en[0]) {
+ I("%s NOT report report double click\n", __func__);
+ return 0;/*NOT report power key*/
+ }
+ }
+
+ if (gesture_flag == 0x80)
+ return EV_GESTURE_PWR;
+ else
+ return gesture_flag;
+}
+
+void himax_wake_check_func(void)
+{
+ int ret_event = 0, KEY_EVENT = 0;
+
+ ret_event = himax_parse_wake_event(private_ts);
+ switch (ret_event) {
+ case EV_GESTURE_PWR:
+ KEY_EVENT = KEY_POWER;
+ break;
+ case EV_GESTURE_01:
+ KEY_EVENT = KEY_CUST_01;
+ break;
+ case EV_GESTURE_02:
+ KEY_EVENT = KEY_CUST_02;
+ break;
+ case EV_GESTURE_03:
+ KEY_EVENT = KEY_CUST_03;
+ break;
+ case EV_GESTURE_04:
+ KEY_EVENT = KEY_CUST_04;
+ break;
+ case EV_GESTURE_05:
+ KEY_EVENT = KEY_CUST_05;
+ break;
+ case EV_GESTURE_06:
+ KEY_EVENT = KEY_CUST_06;
+ break;
+ case EV_GESTURE_07:
+ KEY_EVENT = KEY_CUST_07;
+ break;
+ case EV_GESTURE_08:
+ KEY_EVENT = KEY_CUST_08;
+ break;
+ case EV_GESTURE_09:
+ KEY_EVENT = KEY_CUST_09;
+ break;
+ case EV_GESTURE_10:
+ KEY_EVENT = KEY_CUST_10;
+ break;
+ case EV_GESTURE_11:
+ KEY_EVENT = KEY_CUST_11;
+ break;
+ case EV_GESTURE_12:
+ KEY_EVENT = KEY_CUST_12;
+ break;
+ case EV_GESTURE_13:
+ KEY_EVENT = KEY_CUST_13;
+ break;
+ case EV_GESTURE_14:
+ KEY_EVENT = KEY_CUST_14;
+ break;
+ case EV_GESTURE_15:
+ KEY_EVENT = KEY_CUST_15;
+ break;
+ }
+ if (ret_event) {
+ I(" %s SMART WAKEUP KEY event %x press\n",
+ __func__, KEY_EVENT);
+ input_report_key(private_ts->input_dev, KEY_EVENT, 1);
+ input_sync(private_ts->input_dev);
+ /*msleep(100);*/
+ I(" %s SMART WAKEUP KEY event %x release\n",
+ __func__, KEY_EVENT);
+ input_report_key(private_ts->input_dev, KEY_EVENT, 0);
+ input_sync(private_ts->input_dev);
+ FAKE_POWER_KEY_SEND = true;
+#ifdef HX_GESTURE_TRACK
+ I("gest_start_x= %d, gest_start_y= %d\n",
+ gest_start_x, gest_start_y);
+ I("gest_end_x= %d, gest_end_y= %d\n",
+ gest_end_x, gest_end_y);
+ I("gest_width= %d, gest_height= %d\n",
+ gest_width, gest_height);
+ I("gest_mid_x= %d, gest_mid_y= %d\n",
+ gest_mid_x, gest_mid_y);
+ I("gest_up_x= %d, gest_up_y= %d\n",
+ gn_gesture_coor[8], gn_gesture_coor[9]);
+ I("gest_down_x= %d, gest_down_y= %d\n",
+ gn_gesture_coor[10], gn_gesture_coor[11]);
+ I("gest_left_x= %d, gest_left_y= %d\n",
+ gn_gesture_coor[12], gn_gesture_coor[13]);
+ I("gest_right_x= %d, gest_right_y= %d\n",
+ gn_gesture_coor[14], gn_gesture_coor[15]);
+#endif
+ }
+}
+
+#endif
+static void himax_ts_button_func(int tp_key_index, struct himax_ts_data *ts)
+{
+ uint16_t x_position = 0, y_position = 0;
+
+ if (tp_key_index != 0x00) {
+ I("virtual key index =%x\n", tp_key_index);
+ if (tp_key_index == 0x01) {
+ vk_press = 1;
+ I("back key pressed\n");
+ if (ts->pdata->virtual_key) {
+ if (ts->button[0].index) {
+ x_position = (ts->button[0].x_range_min
+ + ts->button[0].x_range_max) / 2;
+ y_position = (ts->button[0].y_range_min
+ + ts->button[0].y_range_max) / 2;
+ }
+ if (ts->protocol_type == PROTOCOL_TYPE_A) {
+ input_report_abs(ts->input_dev,
+ ABS_MT_TRACKING_ID, 0);
+ input_report_abs(ts->input_dev,
+ ABS_MT_TOUCH_MAJOR, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_WIDTH_MAJOR, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_PRESSURE, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_X, x_position);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_Y, y_position);
+ input_mt_sync(ts->input_dev);
+ } else if (ts->protocol_type
+ == PROTOCOL_TYPE_B) {
+ input_mt_slot(ts->input_dev, 0);
+
+ input_mt_report_slot_state
+ (ts->input_dev, MT_TOOL_FINGER, 1);
+
+ input_report_abs(ts->input_dev,
+ ABS_MT_TOUCH_MAJOR, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_WIDTH_MAJOR, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_PRESSURE, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_X, x_position);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_Y, y_position);
+ }
+ } else
+ input_report_key(ts->input_dev, KEY_BACK, 1);
+ } else if (tp_key_index == 0x02) {
+ vk_press = 1;
+ I("home key pressed\n");
+ if (ts->pdata->virtual_key) {
+ if (ts->button[1].index) {
+ x_position = (ts->button[1].x_range_min
+ + ts->button[1].x_range_max) / 2;
+ y_position = (ts->button[1].y_range_min
+ + ts->button[1].y_range_max) / 2;
+ }
+ if (ts->protocol_type == PROTOCOL_TYPE_A) {
+ input_report_abs(ts->input_dev,
+ ABS_MT_TRACKING_ID, 0);
+ input_report_abs(ts->input_dev,
+ ABS_MT_TOUCH_MAJOR, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_WIDTH_MAJOR, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_PRESSURE, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_X, x_position);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_Y, y_position);
+ input_mt_sync(ts->input_dev);
+ } else if (ts->protocol_type
+ == PROTOCOL_TYPE_B) {
+ input_mt_slot(ts->input_dev, 0);
+
+ input_mt_report_slot_state
+ (ts->input_dev, MT_TOOL_FINGER, 1);
+
+ input_report_abs(ts->input_dev,
+ ABS_MT_TOUCH_MAJOR, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_WIDTH_MAJOR, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_PRESSURE, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_X, x_position);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_Y, y_position);
+ }
+ } else
+ input_report_key(ts->input_dev, KEY_HOME, 1);
+ } else if (tp_key_index == 0x04) {
+ vk_press = 1;
+ I("APP_switch key pressed\n");
+ if (ts->pdata->virtual_key) {
+ if (ts->button[2].index) {
+ x_position = (ts->button[2].x_range_min
+ + ts->button[2].x_range_max) / 2;
+ y_position = (ts->button[2].y_range_min
+ + ts->button[2].y_range_max) / 2;
+ }
+ if (ts->protocol_type == PROTOCOL_TYPE_A) {
+ input_report_abs(ts->input_dev,
+ ABS_MT_TRACKING_ID, 0);
+ input_report_abs(ts->input_dev,
+ ABS_MT_TOUCH_MAJOR, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_WIDTH_MAJOR, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_PRESSURE, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_X, x_position);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_Y, y_position);
+ input_mt_sync(ts->input_dev);
+ } else if (ts->protocol_type ==
+ PROTOCOL_TYPE_B) {
+ input_mt_slot(ts->input_dev, 0);
+
+ input_mt_report_slot_state
+ (ts->input_dev, MT_TOOL_FINGER, 1);
+
+ input_report_abs(ts->input_dev,
+ ABS_MT_TOUCH_MAJOR, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_WIDTH_MAJOR, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_PRESSURE, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_X, x_position);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_Y, y_position);
+ }
+ } else
+ input_report_key(ts->input_dev, KEY_F10, 1);
+ }
+ input_sync(ts->input_dev);
+ } else {/*tp_key_index =0x00*/
+ I("virtual key released\n");
+ vk_press = 0;
+ if (ts->protocol_type == PROTOCOL_TYPE_A) {
+ input_mt_sync(ts->input_dev);
+ } else if (ts->protocol_type == PROTOCOL_TYPE_B) {
+ input_mt_slot(ts->input_dev, 0);
+ input_mt_report_slot_state(ts->input_dev,
+ MT_TOOL_FINGER, 0);
+ }
+ input_report_key(ts->input_dev, KEY_BACK, 0);
+ input_report_key(ts->input_dev, KEY_HOME, 0);
+ input_report_key(ts->input_dev, KEY_F10, 0);
+ input_sync(ts->input_dev);
+ }
+}
+
+void himax_ts_work(struct himax_ts_data *ts)
+{
+ int ret = 0;
+ uint8_t finger_num, hw_reset_check[2];
+ uint8_t buf[128];
+ uint8_t finger_on = 0;
+ int32_t loop_i;
+ uint16_t check_sum_cal = 0;
+ int raw_cnt_max;
+ int raw_cnt_rmd;
+ int hx_touch_info_size;
+ uint8_t coordInfoSize = ts->coord_data_size + ts->area_data_size + 4;
+
+#ifdef HX_TP_PROC_DIAG
+ int16_t *mutual_data;
+ int16_t *self_data;
+ uint8_t diag_cmd;
+ int i;
+ int mul_num;
+ int self_num;
+ int RawDataLen = 0;
+ /*coordinate dump start*/
+ char coordinate_char[15 + (ic_data->HX_MAX_PT + 5) * 2 * 5 + 2];
+ struct timeval t;
+ struct tm broken;
+ /*coordinate dump end*/
+#endif
+
+ memset(buf, 0x00, sizeof(buf));
+ memset(hw_reset_check, 0x00, sizeof(hw_reset_check));
+
+ raw_cnt_max = ic_data->HX_MAX_PT / 4;
+ raw_cnt_rmd = ic_data->HX_MAX_PT % 4;
+#if defined(HX_USB_DETECT2)
+ himax_cable_detect_func();
+#endif
+
+ if (raw_cnt_rmd != 0x00) { /*more than 4 fingers*/
+ RawDataLen = cal_data_len(raw_cnt_rmd,
+ ic_data->HX_MAX_PT, raw_cnt_max);
+ hx_touch_info_size = (ic_data->HX_MAX_PT + raw_cnt_max + 2) * 4;
+ } else { /*less than 4 fingers*/
+ RawDataLen = cal_data_len(raw_cnt_rmd,
+ ic_data->HX_MAX_PT, raw_cnt_max);
+ hx_touch_info_size = (ic_data->HX_MAX_PT + raw_cnt_max + 1) * 4;
+ }
+
+#ifdef HX_TP_PROC_DIAG
+ diag_cmd = getDiagCommand();
+ if (diag_cmd) {
+ ret = read_event_stack(ts->client, buf, 128);
+ } else {
+ if (touch_monitor_stop_flag != 0) {
+ ret = read_event_stack(ts->client, buf, 128);
+ touch_monitor_stop_flag--;
+ } else {
+ ret = read_event_stack(ts->client,
+ buf, hx_touch_info_size);
+ }
+ }
+
+ if (!ret)
+#else
+ if (!read_event_stack(ts->client, buf, hx_touch_info_size))
+#endif
+ {
+ E("%s: can't read data from chip!\n", __func__);
+ goto err_workqueue_out;
+ }
+ post_read_event_stack(ts->client);
+#ifdef HX_ESD_WORKAROUND
+ for (i = 0; i < hx_touch_info_size; i++) {
+ if (buf[i] == 0xED) { /*case 1 ESD recovery flow*/
+ check_sum_cal = 1;
+
+ } else if (buf[i] == 0x00) {
+ ESD_00_Flag = 1;
+ } else {
+ check_sum_cal = 0;
+ ESD_00_counter = 0;
+ ESD_00_Flag = 0;
+ i = hx_touch_info_size;
+ break;
+ }
+ }
+ if (ESD_00_Flag == 1)
+ ESD_00_counter++;
+ if (ESD_00_counter > 1)
+ check_sum_cal = 2;
+ if (check_sum_cal == 2 && HX_ESD_RESET_ACTIVATE == 0) {
+ I("[HIMAX TP MSG]: ESD event checked - ALL Zero.\n");
+ ESD_HW_REST();
+ return;
+ }
+ if (check_sum_cal == 1 && HX_ESD_RESET_ACTIVATE == 0) {
+ I("[HIMAX TP MSG]: ESD event checked - ALL 0xED.\n");
+ ESD_HW_REST();
+ return;
+ } else if (HX_ESD_RESET_ACTIVATE) {
+#ifdef HX_SMART_WAKEUP
+ queue_delayed_work(ts->himax_smwp_wq,
+ &ts->smwp_work, msecs_to_jiffies(50));
+#endif
+#ifdef HX_HIGH_SENSE
+ queue_delayed_work(ts->himax_hsen_wq,
+ &ts->hsen_work, msecs_to_jiffies(50));
+#endif
+/*drop 1st interrupts after chip reset*/
+ HX_ESD_RESET_ACTIVATE = 0;
+ I("[HIMAX TP MSG]:%s: Back from reset,ready to serve.\n",
+ __func__);
+ }
+#endif
+ for (loop_i = 0, check_sum_cal = 0;
+ loop_i < hx_touch_info_size; loop_i++)
+ check_sum_cal += buf[loop_i];
+
+ if ((check_sum_cal % 0x100 != 0)) {
+ I("[HIMAX TP MSG] checksum fail : check_sum_cal: 0x%02X\n",
+ check_sum_cal);
+ return;
+ }
+ if (ts->debug_log_level & BIT(0)) {
+ I("%s: raw data:\n", __func__);
+ for (loop_i = 0; loop_i < hx_touch_info_size; loop_i++) {
+ I("P %d = 0x%2.2X ", loop_i, buf[loop_i]);
+ if (loop_i % 8 == 7)
+ I("\n");
+ }
+ }
+
+ /*touch monitor raw data fetch*/
+#ifdef HX_TP_PROC_DIAG
+ diag_cmd = getDiagCommand();
+ if (diag_cmd >= 1 && diag_cmd <= 6) {
+ /*Check 124th byte CRC*/
+ if (!diag_check_sum(hx_touch_info_size, buf))
+ goto bypass_checksum_failed_packet;
+
+#ifdef HX_TP_PROC_2T2R
+ if (Is_2T2R && diag_cmd == 4) {
+ mutual_data = getMutualBuffer_2();
+ self_data = getSelfBuffer();
+
+ /* initiallize the block number of mutual and self*/
+ mul_num = getXChannel_2() * getYChannel_2();
+
+#ifdef HX_EN_SEL_BUTTON
+ self_num = getXChannel_2() +
+ getYChannel_2() + ic_data->HX_BT_NUM;
+#else
+ self_num = getXChannel_2() + getYChannel_2();
+#endif
+ } else
+#endif
+ {
+ mutual_data = getMutualBuffer();
+ self_data = getSelfBuffer();
+
+ /* initiallize the block number of mutual and self*/
+ mul_num = getXChannel() * getYChannel();
+
+#ifdef HX_EN_SEL_BUTTON
+ self_num = getXChannel() +
+ getYChannel() + ic_data->HX_BT_NUM;
+#else
+ self_num = getXChannel() + getYChannel();
+#endif
+ }
+
+ diag_parse_raw_data(hx_touch_info_size,
+ RawDataLen, mul_num, self_num, buf,
+ diag_cmd, mutual_data, self_data);
+
+ } else if (diag_cmd == 7) {
+ memcpy(&(diag_coor[0]), &buf[0], 128);
+ }
+ /*coordinate dump start*/
+ if (coordinate_dump_enable == 1) {
+ for (i = 0; i < (15 + (ic_data->
+ HX_MAX_PT + 5) * 2 * 5);
+ i++) {
+ coordinate_char[i] = 0x20;
+ }
+ coordinate_char[15 +
+ (ic_data->HX_MAX_PT + 5) * 2 * 5] = 0xD;
+ coordinate_char[15 +
+ (ic_data->HX_MAX_PT + 5) * 2 * 5 + 1] = 0xA;
+ }
+ /*coordinate dump end*/
+bypass_checksum_failed_packet:
+#endif
+ EN_NoiseFilter = (buf[HX_TOUCH_INFO_POINT_CNT + 2] >> 3);
+ /*I("EN_NoiseFilter=%d\n",EN_NoiseFilter);*/
+ EN_NoiseFilter = EN_NoiseFilter & 0x01;
+ /*I("EN_NoiseFilter2=%d\n",EN_NoiseFilter);*/
+
+#if defined(HX_EN_SEL_BUTTON) || defined(HX_EN_MUT_BUTTON)
+ tpd_key = (buf[HX_TOUCH_INFO_POINT_CNT + 2] >> 4);
+ if (tpd_key == 0x0F) {/*All (VK+AA)leave*/
+ tpd_key = 0x00;
+ }
+ /*I("[DEBUG] tpd_key: %x\r\n", tpd_key);*/
+#else
+ tpd_key = 0x00;
+#endif
+
+ p_point_num = hx_point_num;
+
+ if (buf[HX_TOUCH_INFO_POINT_CNT] == 0xff)
+ hx_point_num = 0;
+ else
+ hx_point_num = buf[HX_TOUCH_INFO_POINT_CNT] & 0x0f;
+
+ /* Touch Point information*/
+ if ((hx_point_num != 0) && (vk_press == 0x00)) {
+ uint16_t old_finger = ts->pre_finger_mask;
+
+ ts->pre_finger_mask = 0;
+ finger_num = buf[coordInfoSize - 4] & 0x0F;
+ finger_on = 1;
+ AA_press = 1;
+ for (i = 0; i < ts->nFinger_support; i++) {
+ int base = i * 4;
+ int x = buf[base] << 8 | buf[base + 1];
+ int y = (buf[base + 2] << 8 | buf[base + 3]);
+ int w = buf[(ts->nFinger_support * 4) + i];
+
+ if (x >= 0 && x <= ts->pdata->abs_x_max
+ && y >= 0 && y <= ts->pdata->abs_y_max) {
+ finger_num--;
+ if ((((ts->debug_log_level & BIT(3)) > 0)
+ && (old_finger >> i == 0))
+ && (ts->useScreenRes)) {
+ I("status:Screen:F:%02d", i + 1);
+ I("Down,X:%d,Y:%d,W:%d,N:%d\n",
+ x * ts->widthFactor >> SHIFTBITS,
+ y * ts->heightFactor >> SHIFTBITS,
+ w, EN_NoiseFilter);
+ } else if ((((ts->debug_log_level & BIT(3)) > 0)
+ && (old_finger >> i == 0))
+ && !(ts->useScreenRes)) {
+ I("status:Raw:F:%02d", i + 1);
+ I("Down,X:%d,Y:%d,W:%d,N:%d\n",
+ x, y, w, EN_NoiseFilter);
+ }
+
+ if (ts->protocol_type == PROTOCOL_TYPE_B)
+ input_mt_slot(ts->input_dev, i);
+
+ input_report_abs(ts->input_dev,
+ ABS_MT_TOUCH_MAJOR, w);
+ input_report_abs(ts->input_dev,
+ ABS_MT_WIDTH_MAJOR, w);
+ input_report_abs(ts->input_dev,
+ ABS_MT_PRESSURE, w);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_X, x);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_Y, y);
+
+ if (ts->protocol_type == PROTOCOL_TYPE_A) {
+ input_report_abs(ts->input_dev,
+ ABS_MT_TRACKING_ID, i);
+ input_mt_sync(ts->input_dev);
+ } else {
+ ts->last_slot = i;
+ input_mt_report_slot_state
+ (ts->input_dev,
+ MT_TOOL_FINGER, 1);
+ }
+
+ if (!ts->first_pressed) {
+ ts->first_pressed = 1;
+ I("S1@%d, %d\n", x, y);
+ }
+
+ ts->pre_finger_data[i][0] = x;
+ ts->pre_finger_data[i][1] = y;
+
+ if (ts->debug_log_level & BIT(1)) {
+ I("Finger %d=> X:%d,Y:%d,W:%d,",
+ i + 1, x, y, w);
+ I("Z:%d,F:%d,N:%d\n",
+ w, i + 1, EN_NoiseFilter);
+ }
+ ts->pre_finger_mask =
+ ts->pre_finger_mask + (1 << i);
+
+ } else {
+ if (ts->protocol_type == PROTOCOL_TYPE_B) {
+ input_mt_slot(ts->input_dev, i);
+ input_mt_report_slot_state
+ (ts->input_dev, MT_TOOL_FINGER, 0);
+ }
+ if (i == 0 && ts->first_pressed == 1) {
+ ts->first_pressed = 2;
+ I("E1@%d, %d\n",
+ ts->pre_finger_data[0][0],
+ ts->pre_finger_data[0][1]);
+ }
+ if ((((ts->debug_log_level & BIT(3)) > 0)
+ && (old_finger >> i == 1))
+ && (ts->useScreenRes)) {
+ I("status:Screen:F:%02d,Up,X:%d,Y:%d\n",
+ i + 1, ts->pre_finger_data[i][0]
+ * ts->widthFactor >> SHIFTBITS,
+ ts->pre_finger_data[i][1]
+ * ts->heightFactor >> SHIFTBITS);
+ } else if ((((ts->debug_log_level & BIT(3)) > 0)
+ && (old_finger >> i == 1))
+ && !(ts->useScreenRes)) {
+ I("status:Raw:F:%02d,Up,X:%d,Y:%d\n",
+ i + 1, ts->pre_finger_data[i][0],
+ ts->pre_finger_data[i][1]);
+ }
+ }
+ }
+ input_report_key(ts->input_dev, BTN_TOUCH, finger_on);
+ input_sync(ts->input_dev);
+ } else if ((hx_point_num != 0)
+ && ((tpd_key_old != 0x00) && (tpd_key == 0x00))) {
+ /*temp_x[0] = 0xFFFF;*/
+ /*temp_y[0] = 0xFFFF;*/
+ /*temp_x[1] = 0xFFFF;*/
+ /*temp_y[1] = 0xFFFF;*/
+ himax_ts_button_func(tpd_key, ts);
+ finger_on = 0;
+ input_report_key(ts->input_dev, BTN_TOUCH, finger_on);
+ input_sync(ts->input_dev);
+ } else if (hx_point_num == 0) {
+ if (AA_press) {
+ /*leave event*/
+ finger_on = 0;
+ AA_press = 0;
+ if (ts->protocol_type == PROTOCOL_TYPE_A)
+ input_mt_sync(ts->input_dev);
+
+ for (i = 0 ; i < ts->nFinger_support ; i++) {
+ if ((((ts->pre_finger_mask >> i) & 1) == 1)
+ && (ts->protocol_type == PROTOCOL_TYPE_B)) {
+ input_mt_slot(ts->input_dev, i);
+ input_mt_report_slot_state
+ (ts->input_dev, MT_TOOL_FINGER, 0);
+ }
+ }
+ if (ts->pre_finger_mask > 0) {
+ for (i = 0; i < ts->nFinger_support
+ && (ts->debug_log_level & BIT(3)) > 0; i++) {
+ if ((((ts->pre_finger_mask
+ >> i) & 1) == 1)
+ && (ts->useScreenRes)) {
+ I("status:%X,", 0);
+ I("Screen:F:%02d,", i + 1);
+ I("Up,X:%d,Y:%d\n",
+ ts->pre_finger_data[i][0]
+ * ts->widthFactor >> SHIFTBITS,
+ ts->pre_finger_data[i][1]
+ * ts->heightFactor >> SHIFTBITS
+ );
+ } else if ((((ts->pre_finger_mask
+ >> i) & 1) == 1)
+ && !(ts->useScreenRes)) {
+ I("status:%X,", 0);
+ I("Screen:F:%02d,", i + 1);
+ I("Up,X:%d,Y:%d\n",
+ ts->pre_finger_data[i][0],
+ ts->pre_finger_data[i][1]);
+ }
+ }
+ ts->pre_finger_mask = 0;
+ }
+
+ if (ts->first_pressed == 1) {
+ ts->first_pressed = 2;
+ I("E1@%d, %d\n", ts->pre_finger_data[0][0],
+ ts->pre_finger_data[0][1]);
+ }
+
+ if (ts->debug_log_level & BIT(1))
+ I("All Finger leave\n");
+
+#ifdef HX_TP_PROC_DIAG
+ /*coordinate dump start*/
+ if (coordinate_dump_enable == 1) {
+ do_gettimeofday(&t);
+ time_to_tm(t.tv_sec, 0, &broken);
+ snprintf(&coordinate_char[0], 15,
+ "%2d:%2d:%2d:%lu,", broken.tm_hour,
+ broken.tm_min, broken.tm_sec,
+ t.tv_usec / 1000);
+
+ snprintf(&coordinate_char[15], 10,
+ "Touch up!");
+
+ coordinate_fn->f_op->write
+ (coordinate_fn, &coordinate_char[0],
+ 15 + (ic_data->HX_MAX_PT + 5)
+ * 2 * sizeof(char) * 5 + 2,
+ &coordinate_fn->f_pos);
+ }
+ /*coordinate dump end*/
+#endif
+ } else if (tpd_key != 0x00) {
+ himax_ts_button_func(tpd_key, ts);
+ finger_on = 1;
+ } else if ((tpd_key_old != 0x00) && (tpd_key == 0x00)) {
+ himax_ts_button_func(tpd_key, ts);
+ finger_on = 0;
+ }
+ input_report_key(ts->input_dev, BTN_TOUCH, finger_on);
+ input_sync(ts->input_dev);
+ }
+ tpd_key_old = tpd_key;
+
+workqueue_out:
+ return;
+
+err_workqueue_out:
+ I("%s: Now reset the Touch chip.\n", __func__);
+
+#ifdef HX_RST_PIN_FUNC
+ himax_HW_reset(true, false);
+#endif
+
+ goto workqueue_out;
+}
+enum hrtimer_restart himax_ts_timer_func(struct hrtimer *timer)
+{
+ struct himax_ts_data *ts;
+
+ ts = container_of(timer, struct himax_ts_data, timer);
+ queue_work(ts->himax_wq, &ts->work);
+ hrtimer_start(&ts->timer, ktime_set(0, 12500000), HRTIMER_MODE_REL);
+ return HRTIMER_NORESTART;
+}
+
+#if defined(HX_USB_DETECT)
+static void himax_cable_tp_status_handler_func(int connect_status)
+{
+ struct himax_ts_data *ts;
+
+ I("Touch: cable change to %d\n", connect_status);
+ ts = private_ts;
+ if (ts->cable_config) {
+ if (!atomic_read(&ts->suspend_mode)) {
+ if ((!!connect_status) != ts->usb_connected) {
+ if (!!connect_status) {
+ ts->cable_config[1] = 0x01;
+ ts->usb_connected = 0x01;
+ } else {
+ ts->cable_config[1] = 0x00;
+ ts->usb_connected = 0x00;
+ }
+
+ i2c_himax_master_write(ts->client,
+ ts->cable_config,
+ sizeof(ts->cable_config),
+ HIMAX_I2C_RETRY_TIMES);
+
+ I("%s: Cable status change: 0x%2.2X\n",
+ __func__, ts->cable_config[1]);
+ } else
+ I("%s: Cable status is same, ignore.\n",
+ __func__);
+ } else {
+ if (connect_status)
+ ts->usb_connected = 0x01;
+ else
+ ts->usb_connected = 0x00;
+ I("%s: Cable status remembered: 0x%2.2X\n",
+ __func__, ts->usb_connected);
+ }
+ }
+}
+
+static struct t_cable_status_notifier himax_cable_status_handler = {
+ .name = "usb_tp_connected",
+ .func = himax_cable_tp_status_handler_func,
+};
+
+#endif
+
+#if defined(HX_USB_DETECT2)
+void himax_cable_detect_func(void)
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[128];
+ struct himax_ts_data *ts;
+ u32 connect_status = 0;
+
+ connect_status = USB_Flag;/*upmu_is_chr_det();*/
+ ts = private_ts;
+ /*I("Touch: cable status=%d, cable_config=%p,
+ usb_connected=%d\n", connect_status,
+ ts->cable_config, ts->usb_connected);*/
+
+ if (ts->cable_config) {
+ if ((!!connect_status) != ts->usb_connected) {
+ /*notify USB plug/unplug*/
+ /*0x9008_8060 ==> 0x0000_0000/0001*/
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x08;
+ tmp_addr[1] = 0x80; tmp_addr[0] = 0x60;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ if (!!connect_status) {
+ tmp_data[0] = 0x01;
+ ts->usb_connected = 0x01;
+ } else {
+ tmp_data[0] = 0x00;
+ ts->usb_connected = 0x00;
+ }
+
+ himax_flash_write_burst(ts->client, tmp_addr, tmp_data);
+
+ I("%s: Cable status change: 0x%2.2X\n",
+ __func__, ts->usb_connected);
+ }
+ /*else*/
+ /*I("%s: Cable status is the same as previous one,
+ ignore.\n", __func__);*/
+
+ }
+}
+#endif
+
+#ifdef CONFIG_FB
+int himax_fb_register(struct himax_ts_data *ts)
+{
+ int ret = 0;
+
+ I(" %s in", __func__);
+ ts->fb_notif.notifier_call = fb_notifier_callback;
+ ret = fb_register_client(&ts->fb_notif);
+ if (ret)
+ E(" Unable to register fb_notifier: %d\n", ret);
+
+ return ret;
+}
+#endif
+
+#ifdef HX_SMART_WAKEUP
+void himax_set_SMWP_func(struct i2c_client *client, uint8_t SMWP_enable)
+{
+ uint8_t tmp_data[4];
+
+ if (SMWP_enable) {
+SMWP_bit_retry:
+ himax_set_SMWP_enable(client, SMWP_enable);
+ msleep(20);
+ himax_get_SMWP_enable(client, tmp_data);
+I("%s: Read SMWP bit data[0]=%x data[1]=%x data[2]=%x data[3]=%x\n",
+__func__, tmp_data[0], tmp_data[1], tmp_data[2], tmp_data[3]);
+
+ if (tmp_data[0] != 0x01) {
+ I("%s: retry SMWP bit write data[0]=%x\n",
+ __func__, tmp_data[0]);
+ goto SMWP_bit_retry;
+ }
+ }
+}
+
+static void himax_SMWP_work(struct work_struct *work)
+{
+ struct himax_ts_data *ts =
+ container_of(work, struct himax_ts_data, smwp_work.work);
+ I(" %s in", __func__);
+
+ himax_set_SMWP_func(ts->client, ts->SMWP_enable);
+
+}
+#endif
+
+#ifdef HX_TP_PROC_FLASH_DUMP
+static void himax_ts_flash_work_func(struct work_struct *work)
+{
+ himax_ts_flash_func();
+}
+#endif
+
+#ifdef HX_TP_PROC_DIAG
+static void himax_ts_diag_work_func(struct work_struct *work)
+{
+ himax_ts_diag_func();
+}
+#endif
+
+bool himax_ts_init(struct himax_ts_data *ts)
+{
+ int ret = 0, err = 0;
+ struct himax_i2c_platform_data *pdata;
+ struct i2c_client *client;
+
+ client = ts->client;
+ pdata = ts->pdata;
+
+ I("%s: Start.\n", __func__);
+
+ /* Set pinctrl in active state */
+ if (ts->ts_pinctrl) {
+ ret = pinctrl_select_state(ts->ts_pinctrl,
+ ts->pinctrl_state_active);
+ if (ret < 0)
+ E("Failed to set pin in active state %d", ret);
+ }
+
+ himax_burst_enable(client, 0);
+
+ /*Get Himax IC Type / FW information / Calculate the point number */
+ if (himax_check_chip_version(ts->client) == false) {
+ E("Himax chip doesn NOT EXIST");
+ goto err_ic_package_failed;
+ }
+ if (himax_ic_package_check(ts->client) == false) {
+ E("Himax chip doesn NOT EXIST");
+ goto err_ic_package_failed;
+ }
+
+ if (pdata->virtual_key)
+ ts->button = pdata->virtual_key;
+#ifdef HX_TP_PROC_FLASH_DUMP
+ ts->flash_wq = create_singlethread_workqueue("himax_flash_wq");
+ if (!ts->flash_wq) {
+ E("%s: create flash workqueue failed\n", __func__);
+ err = -ENOMEM;
+ goto err_create_wq_failed;
+ }
+
+ INIT_WORK(&ts->flash_work, himax_ts_flash_work_func);
+
+ setSysOperation(0);
+ setFlashBuffer();
+#endif
+
+#ifdef HX_TP_PROC_DIAG
+ ts->himax_diag_wq = create_singlethread_workqueue("himax_diag");
+ if (!ts->himax_diag_wq) {
+ E("%s: create diag workqueue failed\n", __func__);
+ err = -ENOMEM;
+ goto err_create_wq_failed;
+ }
+ INIT_DELAYED_WORK(&ts->himax_diag_delay_wrok, himax_ts_diag_work_func);
+#endif
+
+himax_read_FW_ver(client);
+
+#ifdef HX_AUTO_UPDATE_FW
+ I(" %s in", __func__);
+ if (i_update_FW() <= 0)
+ I("FW NOT UPDATE=\n");
+ else
+ I("Have new FW=UPDATE=\n");
+#endif
+
+ /*Himax Power On and Load Config*/
+ if (himax_loadSensorConfig(client, pdata) < 0) {
+ E("%s: Load Sesnsor config failed,unload driver.\n",
+ __func__);
+ goto err_detect_failed;
+ }
+
+ calculate_point_number();
+#ifdef HX_TP_PROC_DIAG
+ setXChannel(ic_data->HX_RX_NUM); /*X channel*/
+ setYChannel(ic_data->HX_TX_NUM); /*Y channel*/
+
+ setMutualBuffer();
+ setMutualNewBuffer();
+ setMutualOldBuffer();
+ if (getMutualBuffer() == NULL) {
+ E("%s: mutual buffer allocate fail failed\n", __func__);
+ return false;
+ }
+#ifdef HX_TP_PROC_2T2R
+ if (Is_2T2R) {
+ setXChannel_2(ic_data->HX_RX_NUM_2); /*X channel*/
+ setYChannel_2(ic_data->HX_TX_NUM_2); /*Y channel*/
+
+ setMutualBuffer_2();
+
+ if (getMutualBuffer_2() == NULL) {
+ E("%s: mutual buffer 2 allocate fail failed\n",
+ __func__);
+ return false;
+ }
+ }
+#endif
+#endif
+#ifdef CONFIG_OF
+ ts->power = pdata->power;
+#endif
+ ts->pdata = pdata;
+
+ ts->x_channel = ic_data->HX_RX_NUM;
+ ts->y_channel = ic_data->HX_TX_NUM;
+ ts->nFinger_support = ic_data->HX_MAX_PT;
+ /*calculate the i2c data size*/
+ calcDataSize(ts->nFinger_support);
+ I("%s: calcDataSize complete\n", __func__);
+#ifdef CONFIG_OF
+ ts->pdata->abs_pressure_min = 0;
+ ts->pdata->abs_pressure_max = 200;
+ ts->pdata->abs_width_min = 0;
+ ts->pdata->abs_width_max = 200;
+ pdata->cable_config[0] = 0x90;
+ pdata->cable_config[1] = 0x00;
+#endif
+ ts->suspended = false;
+#if defined(HX_USB_DETECT) || defined(HX_USB_DETECT2)
+ ts->usb_connected = 0x00;
+ ts->cable_config = pdata->cable_config;
+#endif
+ ts->protocol_type = pdata->protocol_type;
+ I("%s: Use Protocol Type %c\n", __func__,
+ ts->protocol_type == PROTOCOL_TYPE_A ? 'A' : 'B');
+ ret = himax_input_register(ts);
+ if (ret) {
+ E("%s: Unable to register %s input device\n",
+ __func__, ts->input_dev->name);
+ goto err_input_register_device_failed;
+ }
+#ifdef HX_SMART_WAKEUP
+ ts->SMWP_enable = 0;
+ wakeup_source_init(&ts->ts_SMWP_wake_lock,
+ WAKE_LOCK_SUSPEND, HIMAX_common_NAME);
+
+ ts->himax_smwp_wq = create_singlethread_workqueue("HMX_SMWP_WORK");
+ if (!ts->himax_smwp_wq) {
+ E(" allocate himax_smwp_wq failed\n");
+ err = -ENOMEM;
+ goto err_smwp_wq_failed;
+ }
+ INIT_DELAYED_WORK(&ts->smwp_work, himax_SMWP_work);
+#endif
+#ifdef HX_HIGH_SENSE
+ ts->HSEN_enable = 0;
+ ts->himax_hsen_wq = create_singlethread_workqueue("HMX_HSEN_WORK");
+ if (!ts->himax_hsen_wq) {
+ E(" allocate himax_hsen_wq failed\n");
+ err = -ENOMEM;
+ goto err_hsen_wq_failed;
+ }
+ INIT_DELAYED_WORK(&ts->hsen_work, himax_HSEN_func);
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
+ himax_touch_proc_init();
+#endif
+
+#if defined(HX_USB_DETECT)
+ if (ts->cable_config)
+ cable_detect_register_notifier(&himax_cable_status_handler);
+#endif
+
+ err = himax_ts_register_interrupt(ts->client);
+ if (err)
+ goto err_register_interrupt_failed;
+ return true;
+
+err_register_interrupt_failed:
+#ifdef HX_HIGH_SENSE
+err_hsen_wq_failed:
+#endif
+#ifdef HX_SMART_WAKEUP
+err_smwp_wq_failed:
+ wakeup_source_trash(&ts->ts_SMWP_wake_lock);
+#endif
+err_input_register_device_failed:
+ input_free_device(ts->input_dev);
+err_detect_failed:
+#ifdef HX_TP_PROC_FLASH_DUMP
+err_create_wq_failed:
+#endif
+err_ic_package_failed:
+return false;
+}
+
+int himax_chip_common_probe(struct i2c_client *client,
+const struct i2c_device_id *id)
+{
+ int err = 0;
+ struct himax_ts_data *ts;
+ struct himax_i2c_platform_data *pdata;
+
+ /*Check I2C functionality*/
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ E("%s: i2c check functionality error\n", __func__);
+ err = -ENODEV;
+ goto err_check_functionality_failed;
+ }
+
+ ts = kzalloc(sizeof(struct himax_ts_data), GFP_KERNEL);
+ if (ts == NULL) {
+ E("%s: allocate himax_ts_data failed\n", __func__);
+ err = -ENOMEM;
+ goto err_alloc_data_failed;
+ }
+
+ i2c_set_clientdata(client, ts);
+ ts->client = client;
+ ts->dev = &client->dev;
+ mutex_init(&ts->rw_lock);
+
+ pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+ if (pdata == NULL) { /*Allocate Platform data space*/
+ err = -ENOMEM;
+ goto err_dt_platform_data_fail;
+ }
+
+ ic_data = kzalloc(sizeof(*ic_data), GFP_KERNEL);
+ if (ic_data == NULL) { /*Allocate IC data space*/
+ err = -ENOMEM;
+ goto err_dt_ic_data_fail;
+ }
+
+#ifdef CONFIG_OF
+ /*DeviceTree Init Platform_data*/
+ if (client->dev.of_node) {
+ err = himax_parse_dt(ts, pdata);
+ if (err < 0) {
+ I(" pdata is NULL for DT\n");
+ goto err_alloc_dt_pdata_failed;
+ }
+ }
+#endif
+
+#ifdef HX_RST_PIN_FUNC
+ ts->rst_gpio = pdata->gpio_reset;
+#endif
+
+ himax_gpio_power_config(ts->client, pdata);
+
+ err = himax_ts_pinctrl_init(ts);
+ if (err || ts->ts_pinctrl == NULL)
+ E(" Pinctrl init failed\n");
+
+#ifndef CONFIG_OF
+ if (pdata->power) {
+ err = pdata->power(1);
+ if (err < 0) {
+ E("%s: power on failed\n", __func__);
+ goto err_power_failed;
+ }
+ }
+#endif
+ ts->pdata = pdata;
+ private_ts = ts;
+
+ mutex_init(&ts->fb_mutex);
+ /* ts initialization is deferred till FB_UNBLACK event;
+ * probe is considered pending till then.*/
+ ts->probe_done = false;
+#ifdef CONFIG_FB
+ err = himax_fb_register(ts);
+ if (err) {
+ E("Falied to register fb notifier\n");
+ err = -ENOMEM;
+ goto err_fb_notif_wq_create;
+ }
+#endif
+
+ return 0;
+
+#ifdef CONFIG_FB
+err_fb_notif_wq_create:
+#endif
+#ifdef CONFIG_OF
+err_alloc_dt_pdata_failed:
+#else
+err_power_failed:
+err_get_platform_data_fail:
+#endif
+ if (ts->ts_pinctrl) {
+ if (IS_ERR_OR_NULL(ts->pinctrl_state_release)) {
+ devm_pinctrl_put(ts->ts_pinctrl);
+ ts->ts_pinctrl = NULL;
+ } else {
+ err = pinctrl_select_state(ts->ts_pinctrl,
+ ts->pinctrl_state_release);
+ if (err)
+ E("failed to select relase pinctrl state %d\n",
+ err);
+ }
+ }
+ kfree(ic_data);
+
+err_dt_ic_data_fail:
+ kfree(pdata);
+
+err_dt_platform_data_fail:
+ kfree(ts);
+
+err_alloc_data_failed:
+
+err_check_functionality_failed:
+ probe_fail_flag = 1;
+ return err;
+
+}
+
+int himax_chip_common_remove(struct i2c_client *client)
+{
+ struct himax_ts_data *ts = i2c_get_clientdata(client);
+ int ret;
+#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
+ himax_touch_proc_deinit();
+#endif
+#ifdef CONFIG_FB
+ if (fb_unregister_client(&ts->fb_notif)) {
+ dev_err(&client->dev,
+ "Error occurred while unregistering fb_notifier.\n");
+ }
+#endif
+
+ if (!ts->use_irq)
+ hrtimer_cancel(&ts->timer);
+
+ destroy_workqueue(ts->himax_wq);
+
+ if (ts->protocol_type == PROTOCOL_TYPE_B)
+ input_mt_destroy_slots(ts->input_dev);
+
+ input_unregister_device(ts->input_dev);
+
+ if (ts->ts_pinctrl) {
+ if (IS_ERR_OR_NULL(ts->pinctrl_state_release)) {
+ devm_pinctrl_put(ts->ts_pinctrl);
+ ts->ts_pinctrl = NULL;
+ } else {
+ ret = pinctrl_select_state(ts->ts_pinctrl,
+ ts->pinctrl_state_release);
+ if (ret)
+ E("failed to select relase pinctrl state %d\n",
+ ret);
+ }
+ }
+#ifdef HX_SMART_WAKEUP
+ wakeup_source_trash(&ts->ts_SMWP_wake_lock);
+#endif
+ kfree(ts);
+
+ return 0;
+
+}
+
+int himax_chip_common_suspend(struct himax_ts_data *ts)
+{
+ int ret;
+
+ if (ts->suspended) {
+ I("%s: Already suspended. Skipped.\n", __func__);
+ return 0;
+
+ } else {
+ ts->suspended = true;
+ I("%s: enter\n", __func__);
+ }
+
+#ifdef HX_TP_PROC_FLASH_DUMP
+ if (getFlashDumpGoing()) {
+ I("[himax] %s: Flash dump is going,reject suspend\n",
+ __func__);
+ return 0;
+ }
+#endif
+#ifdef HX_TP_PROC_HITOUCH
+ if (hitouch_is_connect) {
+ I("[himax] %s: Hitouch connect,reject suspend\n",
+ __func__);
+ return 0;
+ }
+#endif
+#ifdef HX_SMART_WAKEUP
+ if (ts->SMWP_enable) {
+ atomic_set(&ts->suspend_mode, 1);
+ ts->pre_finger_mask = 0;
+ FAKE_POWER_KEY_SEND = false;
+ I("[himax] %s: SMART_WAKEUP enable,reject suspend\n",
+ __func__);
+ return 0;
+ }
+#endif
+#ifdef HX_ESD_WORKAROUND
+ ESD_00_counter = 0;
+ ESD_00_Flag = 0;
+#endif
+ if (!ts->use_irq) {
+ ret = cancel_work_sync(&ts->work);
+ if (ret)
+ himax_int_enable(ts->client->irq, 1);
+ }
+
+ /*ts->first_pressed = 0;*/
+ atomic_set(&ts->suspend_mode, 1);
+ ts->pre_finger_mask = 0;
+
+ if (ts->ts_pinctrl) {
+ ret = pinctrl_select_state(ts->ts_pinctrl,
+ ts->pinctrl_state_suspend);
+ if (ret < 0)
+ E("Failed to get idle pinctrl state %d\n", ret);
+ }
+
+ if (ts->pdata->powerOff3V3 && ts->pdata->power)
+ ts->pdata->power(0);
+
+ return 0;
+}
+
+int himax_chip_common_resume(struct himax_ts_data *ts)
+{
+ int retval;
+
+ I("%s: enter\n", __func__);
+
+ if (ts->pdata->powerOff3V3 && ts->pdata->power)
+ ts->pdata->power(1);
+
+ if (ts->protocol_type == PROTOCOL_TYPE_A)
+ input_mt_sync(ts->input_dev);
+ input_report_key(ts->input_dev, BTN_TOUCH, 0);
+ input_sync(ts->input_dev);
+
+ if (ts->ts_pinctrl) {
+ retval = pinctrl_select_state(ts->ts_pinctrl,
+ ts->pinctrl_state_active);
+ if (retval < 0) {
+ E("Cannot get default pinctrl state %d\n", retval);
+ goto err_pinctrl_select_resume;
+ }
+ }
+
+ atomic_set(&ts->suspend_mode, 0);
+
+ himax_int_enable(ts->client->irq, 1);
+
+ ts->suspended = false;
+#if defined(HX_USB_DETECT2)
+ ts->usb_connected = 0x00;
+ himax_cable_detect_func();
+#endif
+#ifdef HX_SMART_WAKEUP
+ queue_delayed_work(ts->himax_smwp_wq,
+ &ts->smwp_work, msecs_to_jiffies(1000));
+#endif
+#ifdef HX_HIGH_SENSE
+ queue_delayed_work(ts->himax_hsen_wq,
+ &ts->hsen_work, msecs_to_jiffies(1000));
+#endif
+ return 0;
+err_pinctrl_select_resume:
+ if (ts->pdata->powerOff3V3 && ts->pdata->power)
+ ts->pdata->power(0);
+ return retval;
+}
+
diff --git a/drivers/input/touchscreen/hxchipset/himax_common.h b/drivers/input/touchscreen/hxchipset/himax_common.h
new file mode 100644
index 0000000..41c97f7
--- /dev/null
+++ b/drivers/input/touchscreen/hxchipset/himax_common.h
@@ -0,0 +1,472 @@
+/* Himax Android Driver Sample Code for Himax chipset
+*
+* Copyright (C) 2015 Himax Corporation.
+*
+* This software is licensed under the terms of the GNU General Public
+* License version 2, as published by the Free Software Foundation, and
+* may be copied, distributed, and modified under those terms.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+*/
+
+#ifndef HIMAX_COMMON_H
+#define HIMAX_COMMON_H
+
+#include "himax_platform.h"
+
+#include <asm/segment.h>
+/*#include <asm/uaccess.h>*/
+/*#include <asm/atomic.h>*/
+#include <linux/uaccess.h>
+#include <linux/atomic.h>
+
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/async.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/input/mt.h>
+#include <linux/firmware.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/buffer_head.h>
+#include <linux/wakelock.h>
+#include <linux/seq_file.h>
+#include <linux/proc_fs.h>
+
+#if defined(CONFIG_FB)
+#include <linux/notifier.h>
+#include <linux/fb.h>
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+#include <linux/earlysuspend.h>
+#endif
+
+#ifdef CONFIG_OF
+#include <linux/of_gpio.h>
+#endif
+#define HIMAX_DRIVER_VER "0.3.1.0"
+
+#define FLASH_DUMP_FILE "/data/user/Flash_Dump.bin"
+#define DIAG_COORDINATE_FILE "/sdcard/Coordinate_Dump.csv"
+
+#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
+
+#define HX_TP_PROC_DIAG
+#define HX_TP_PROC_REGISTER
+#define HX_TP_PROC_DEBUG
+#define HX_TP_PROC_FLASH_DUMP
+#define HX_TP_PROC_SELF_TEST
+#define HX_TP_PROC_RESET
+#define HX_TP_PROC_SENSE_ON_OFF
+/*#define HX_TP_PROC_2T2R*/
+
+int himax_touch_proc_init(void);
+void himax_touch_proc_deinit(void);
+#endif
+
+/*===========Himax Option function=============*/
+/*#define HX_RST_PIN_FUNC*/
+#define HX_AUTO_UPDATE_FW
+/*#define HX_HIGH_SENSE*/
+/*#define HX_SMART_WAKEUP*/
+/*#define HX_USB_DETECT*/
+/*#define HX_ESD_WORKAROUND*/
+/*#define HX_USB_DETECT2*/
+/*#define HX_EN_SEL_BUTTON*//* Support Self Virtual key ,default is close*/
+#define HX_EN_MUT_BUTTON/* Support Mutual Virtual Key ,default is close*/
+/*#define HX_EN_CHECK_PATCH*/
+
+#define HX_KEY_MAX_COUNT 4
+#define DEFAULT_RETRY_CNT 3
+
+#define HX_VKEY_0 KEY_BACK
+#define HX_VKEY_1 KEY_HOME
+#define HX_VKEY_2 KEY_RESERVED
+#define HX_VKEY_3 KEY_RESERVED
+#define HX_KEY_ARRAY {HX_VKEY_0, HX_VKEY_1, HX_VKEY_2, HX_VKEY_3}
+
+#define SHIFTBITS 5
+/*#define FLASH_SIZE 131072*/
+#define FW_SIZE_60k 61440
+#define FW_SIZE_64k 65536
+#define FW_SIZE_124k 126976
+#define FW_SIZE_128k 131072
+
+struct himax_ic_data {
+ int vendor_fw_ver;
+ int vendor_config_ver;
+ int vendor_sensor_id;
+ int HX_RX_NUM;
+ int HX_TX_NUM;
+ int HX_BT_NUM;
+ int HX_X_RES;
+ int HX_Y_RES;
+ int HX_MAX_PT;
+ bool HX_XY_REVERSE;
+ bool HX_INT_IS_EDGE;
+#ifdef HX_TP_PROC_2T2R
+ int HX_RX_NUM_2;
+ int HX_TX_NUM_2;
+#endif
+};
+
+struct himax_virtual_key {
+ int index;
+ int keycode;
+ int x_range_min;
+ int x_range_max;
+ int y_range_min;
+ int y_range_max;
+};
+
+struct himax_config {
+ uint8_t default_cfg;
+ uint8_t sensor_id;
+ uint8_t fw_ver;
+ uint16_t length;
+ uint32_t tw_x_min;
+ uint32_t tw_x_max;
+ uint32_t tw_y_min;
+ uint32_t tw_y_max;
+ uint32_t pl_x_min;
+ uint32_t pl_x_max;
+ uint32_t pl_y_min;
+ uint32_t pl_y_max;
+ uint8_t c1[11];
+ uint8_t c2[11];
+ uint8_t c3[11];
+ uint8_t c4[11];
+ uint8_t c5[11];
+ uint8_t c6[11];
+ uint8_t c7[11];
+ uint8_t c8[11];
+ uint8_t c9[11];
+ uint8_t c10[11];
+ uint8_t c11[11];
+ uint8_t c12[11];
+ uint8_t c13[11];
+ uint8_t c14[11];
+ uint8_t c15[11];
+ uint8_t c16[11];
+ uint8_t c17[11];
+ uint8_t c18[17];
+ uint8_t c19[15];
+ uint8_t c20[5];
+ uint8_t c21[11];
+ uint8_t c22[4];
+ uint8_t c23[3];
+ uint8_t c24[3];
+ uint8_t c25[4];
+ uint8_t c26[2];
+ uint8_t c27[2];
+ uint8_t c28[2];
+ uint8_t c29[2];
+ uint8_t c30[2];
+ uint8_t c31[2];
+ uint8_t c32[2];
+ uint8_t c33[2];
+ uint8_t c34[2];
+ uint8_t c35[3];
+ uint8_t c36[5];
+ uint8_t c37[5];
+ uint8_t c38[9];
+ uint8_t c39[14];
+ uint8_t c40[159];
+ uint8_t c41[99];
+};
+
+struct himax_ts_data {
+ bool suspended;
+ bool probe_done;
+ struct mutex fb_mutex;
+ struct mutex rw_lock;
+ atomic_t suspend_mode;
+ uint8_t x_channel;
+ uint8_t y_channel;
+ uint8_t useScreenRes;
+ uint8_t diag_command;
+ uint8_t protocol_type;
+ uint8_t first_pressed;
+ uint8_t coord_data_size;
+ uint8_t area_data_size;
+ uint8_t raw_data_frame_size;
+ uint8_t raw_data_nframes;
+ uint8_t nFinger_support;
+ uint8_t irq_enabled;
+ uint8_t diag_self[50];
+ uint16_t finger_pressed;
+ uint16_t last_slot;
+ uint16_t pre_finger_mask;
+ uint32_t debug_log_level;
+ uint32_t widthFactor;
+ uint32_t heightFactor;
+ uint32_t tw_x_min;
+ uint32_t tw_x_max;
+ uint32_t tw_y_min;
+ uint32_t tw_y_max;
+ uint32_t pl_x_min;
+ uint32_t pl_x_max;
+ uint32_t pl_y_min;
+ uint32_t pl_y_max;
+
+ int use_irq;
+ int (*power)(int on);
+ int pre_finger_data[10][2];
+
+ struct device *dev;
+ struct workqueue_struct *himax_wq;
+ struct work_struct work;
+ struct input_dev *input_dev;
+ struct hrtimer timer;
+ struct i2c_client *client;
+ struct himax_i2c_platform_data *pdata;
+ struct himax_virtual_key *button;
+
+#if defined(CONFIG_FB)
+ struct notifier_block fb_notif;
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+ struct early_suspend early_suspend;
+#endif
+
+#ifdef HX_TP_PROC_FLASH_DUMP
+ struct workqueue_struct *flash_wq;
+ struct work_struct flash_work;
+#endif
+
+#ifdef HX_RST_PIN_FUNC
+ int rst_gpio;
+#endif
+
+#ifdef HX_TP_PROC_DIAG
+ struct workqueue_struct *himax_diag_wq;
+ struct delayed_work himax_diag_delay_wrok;
+#endif
+#ifdef HX_SMART_WAKEUP
+ uint8_t SMWP_enable;
+ uint8_t gesture_cust_en[16];
+ struct wakeup_source ts_SMWP_wake_lock;
+ struct workqueue_struct *himax_smwp_wq;
+ struct delayed_work smwp_work;
+#endif
+
+#ifdef HX_HIGH_SENSE
+ uint8_t HSEN_enable;
+ struct workqueue_struct *himax_hsen_wq;
+ struct delayed_work hsen_work;
+#endif
+
+#if defined(HX_USB_DETECT) || defined(HX_USB_DETECT2)
+ uint8_t usb_connected;
+ uint8_t *cable_config;
+#endif
+
+ /* pinctrl data */
+ struct pinctrl *ts_pinctrl;
+ struct pinctrl_state *pinctrl_state_active;
+ struct pinctrl_state *pinctrl_state_suspend;
+ struct pinctrl_state *pinctrl_state_release;
+};
+
+#define HX_CMD_NOP 0x00
+#define HX_CMD_SETMICROOFF 0x35
+#define HX_CMD_SETROMRDY 0x36
+#define HX_CMD_TSSLPIN 0x80
+#define HX_CMD_TSSLPOUT 0x81
+#define HX_CMD_TSSOFF 0x82
+#define HX_CMD_TSSON 0x83
+#define HX_CMD_ROE 0x85
+#define HX_CMD_RAE 0x86
+#define HX_CMD_RLE 0x87
+#define HX_CMD_CLRES 0x88
+#define HX_CMD_TSSWRESET 0x9E
+#define HX_CMD_SETDEEPSTB 0xD7
+#define HX_CMD_SET_CACHE_FUN 0xDD
+#define HX_CMD_SETIDLE 0xF2
+#define HX_CMD_SETIDLEDELAY 0xF3
+#define HX_CMD_SELFTEST_BUFFER 0x8D
+#define HX_CMD_MANUALMODE 0x42
+#define HX_CMD_FLASH_ENABLE 0x43
+#define HX_CMD_FLASH_SET_ADDRESS 0x44
+#define HX_CMD_FLASH_WRITE_REGISTER 0x45
+#define HX_CMD_FLASH_SET_COMMAND 0x47
+#define HX_CMD_FLASH_WRITE_BUFFER 0x48
+#define HX_CMD_FLASH_PAGE_ERASE 0x4D
+#define HX_CMD_FLASH_SECTOR_ERASE 0x4E
+#define HX_CMD_CB 0xCB
+#define HX_CMD_EA 0xEA
+#define HX_CMD_4A 0x4A
+#define HX_CMD_4F 0x4F
+#define HX_CMD_B9 0xB9
+#define HX_CMD_76 0x76
+
+enum input_protocol_type {
+ PROTOCOL_TYPE_A = 0x00,
+ PROTOCOL_TYPE_B = 0x01,
+};
+
+#ifdef HX_HIGH_SENSE
+void himax_set_HSEN_func(struct i2c_client *client, uint8_t HSEN_enable);
+#endif
+
+#ifdef HX_SMART_WAKEUP
+#define GEST_PTLG_ID_LEN (4)
+#define GEST_PTLG_HDR_LEN (4)
+#define GEST_PTLG_HDR_ID1 (0xCC)
+#define GEST_PTLG_HDR_ID2 (0x44)
+#define GEST_PT_MAX_NUM (128)
+
+#ifdef HX_GESTURE_TRACK
+static int gest_pt_cnt;
+static int gest_pt_x[GEST_PT_MAX_NUM];
+static int gest_pt_y[GEST_PT_MAX_NUM];
+static int gest_start_x, gest_start_y, gest_end_x, gest_end_y;
+static int gest_width, gest_height, gest_mid_x, gest_mid_y;
+static int gn_gesture_coor[16];
+#endif
+
+void himax_set_SMWP_func(struct i2c_client *client, uint8_t SMWP_enable);
+extern bool FAKE_POWER_KEY_SEND;
+
+ enum gesture_event_type {
+ EV_GESTURE_01 = 0x01,
+ EV_GESTURE_02,
+ EV_GESTURE_03,
+ EV_GESTURE_04,
+ EV_GESTURE_05,
+ EV_GESTURE_06,
+ EV_GESTURE_07,
+ EV_GESTURE_08,
+ EV_GESTURE_09,
+ EV_GESTURE_10,
+ EV_GESTURE_11,
+ EV_GESTURE_12,
+ EV_GESTURE_13,
+ EV_GESTURE_14,
+ EV_GESTURE_15,
+ EV_GESTURE_PWR = 0x80,
+ };
+
+#define KEY_CUST_01 251
+#define KEY_CUST_02 252
+#define KEY_CUST_03 253
+#define KEY_CUST_04 254
+#define KEY_CUST_05 255
+#define KEY_CUST_06 256
+#define KEY_CUST_07 257
+#define KEY_CUST_08 258
+#define KEY_CUST_09 259
+#define KEY_CUST_10 260
+#define KEY_CUST_11 261
+#define KEY_CUST_12 262
+#define KEY_CUST_13 263
+#define KEY_CUST_14 264
+#define KEY_CUST_15 265
+#endif
+
+#ifdef HX_ESD_WORKAROUND
+ extern u8 HX_ESD_RESET_ACTIVATE;
+#endif
+
+extern int irq_enable_count;
+
+#ifdef QCT
+irqreturn_t himax_ts_thread(int irq, void *ptr);
+int himax_input_register(struct himax_ts_data *ts);
+#endif
+
+int himax_chip_common_probe(struct i2c_client *client,
+const struct i2c_device_id *id);
+int himax_chip_common_remove(struct i2c_client *client);
+int himax_chip_common_suspend(struct himax_ts_data *ts);
+int himax_chip_common_resume(struct himax_ts_data *ts);
+int himax_loadSensorConfig(struct i2c_client *client,
+struct himax_i2c_platform_data *pdata);
+
+#ifdef HX_USB_DETECT2
+/*extern kal_bool upmu_is_chr_det(void);*/
+void himax_cable_detect_func(void);
+#endif
+
+#ifdef HX_AUTO_UPDATE_FW
+extern unsigned long FW_VER_MAJ_FLASH_ADDR;
+extern unsigned long FW_VER_MIN_FLASH_ADDR;
+extern unsigned long CFG_VER_MAJ_FLASH_ADDR;
+extern unsigned long CFG_VER_MIN_FLASH_ADDR;
+#endif
+extern unsigned long FW_VER_MAJ_FLASH_LENG;
+extern unsigned long FW_VER_MIN_FLASH_LENG;
+extern unsigned long CFG_VER_MAJ_FLASH_LENG;
+extern unsigned long CFG_VER_MIN_FLASH_LENG;
+extern unsigned char IC_TYPE;
+extern unsigned char IC_CHECKSUM;
+
+#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
+extern int himax_touch_proc_init(void);
+extern void himax_touch_proc_deinit(void);
+/*PROC-START*/
+#ifdef HX_TP_PROC_FLASH_DUMP
+extern void himax_ts_flash_func(void);
+extern void setFlashBuffer(void);
+extern bool getFlashDumpGoing(void);
+extern uint8_t getSysOperation(void);
+extern void setSysOperation(uint8_t operation);
+#endif
+
+#ifdef HX_TP_PROC_HITOUCH
+extern bool hitouch_is_connect;
+#endif
+
+#ifdef HX_TP_PROC_DIAG
+ extern int touch_monitor_stop_flag;
+
+ extern int touch_monitor_stop_limit;
+
+ extern void himax_ts_diag_func(void);
+
+ extern int16_t *getMutualBuffer(void);
+ extern int16_t *getMutualNewBuffer(void);
+ extern int16_t *getMutualOldBuffer(void);
+ extern int16_t *getSelfBuffer(void);
+ extern uint8_t getXChannel(void);
+ extern uint8_t getYChannel(void);
+ extern uint8_t getDiagCommand(void);
+ extern void setXChannel(uint8_t x);
+ extern void setYChannel(uint8_t y);
+ extern void setMutualBuffer(void);
+ extern void setMutualNewBuffer(void);
+ extern void setMutualOldBuffer(void);
+ extern uint8_t coordinate_dump_enable;
+ extern struct file *coordinate_fn;
+ extern uint8_t diag_coor[128];
+#ifdef HX_TP_PROC_2T2R
+ extern int16_t *getMutualBuffer_2(void);
+ extern uint8_t getXChannel_2(void);
+ extern uint8_t getYChannel_2(void);
+ extern void setXChannel_2(uint8_t x);
+ extern void setYChannel_2(uint8_t y);
+ extern void setMutualBuffer_2(void);
+#endif
+#endif
+/*PROC-END*/
+#endif
+
+#ifdef HX_USB_DETECT2
+ extern bool USB_Flag;
+#endif
+#ifdef HX_ESD_WORKAROUND
+ extern void HX_report_ESD_event(void);
+ unsigned char ESD_00_counter = 0;
+ unsigned char ESD_00_Flag = 0;
+#endif
+bool himax_ts_init(struct himax_ts_data *ts);
+
+#endif
+
diff --git a/drivers/input/touchscreen/hxchipset/himax_debug.c b/drivers/input/touchscreen/hxchipset/himax_debug.c
new file mode 100644
index 0000000..55cc7ca
--- /dev/null
+++ b/drivers/input/touchscreen/hxchipset/himax_debug.c
@@ -0,0 +1,2205 @@
+/* Himax Android Driver Sample Code for Himax chipset
+*
+* Copyright (C) 2015 Himax Corporation.
+*
+* This software is licensed under the terms of the GNU General Public
+* License version 2, as published by the Free Software Foundation, and
+* may be copied, distributed, and modified under those terms.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+*/
+
+#include "himax_debug.h"
+#include "himax_ic.h"
+
+/*struct himax_debug_data* debug_data;*/
+
+#ifdef HX_TP_PROC_DIAG
+#ifdef HX_TP_PROC_2T2R
+int HX_RX_NUM_2;
+int HX_TX_NUM_2;
+#endif
+int touch_monitor_stop_flag;
+int touch_monitor_stop_limit = 5;
+uint8_t g_diag_arr_num;
+#endif
+
+#ifdef HX_ESD_WORKAROUND
+u8 HX_ESD_RESET_ACTIVATE;
+#endif
+
+#ifdef HX_SMART_WAKEUP
+bool FAKE_POWER_KEY_SEND;
+#endif
+
+/*========================================================
+
+Segment : Himax PROC Debug Function
+
+==========================================================*/
+#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
+
+static ssize_t himax_vendor_read(struct file *file, char *buf,
+ size_t len, loff_t *pos)
+{
+ ssize_t ret = 0;
+ char *temp_buf;
+
+ if (!HX_PROC_SEND_FLAG) {
+ temp_buf = kzalloc(len, GFP_KERNEL);
+ ret += snprintf(temp_buf, len,
+ "%s_FW:%#x_CFG:%#x_SensorId:%#x\n",
+ HIMAX_common_NAME, ic_data->vendor_fw_ver,
+ ic_data->vendor_config_ver, ic_data->vendor_sensor_id);
+
+ HX_PROC_SEND_FLAG = 1;
+
+ if (copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n", __func__, __LINE__);
+
+ kfree(temp_buf);
+ } else
+ HX_PROC_SEND_FLAG = 0;
+
+ return ret;
+}
+
+const struct file_operations himax_proc_vendor_ops = {
+ .owner = THIS_MODULE,
+ .read = himax_vendor_read,
+};
+
+static ssize_t himax_attn_read(struct file *file, char *buf,
+ size_t len, loff_t *pos)
+{
+ ssize_t ret = 0;
+ struct himax_ts_data *ts_data;
+ char *temp_buf;
+
+ ts_data = private_ts;
+
+ if (!HX_PROC_SEND_FLAG) {
+ temp_buf = kzalloc(len, GFP_KERNEL);
+ ret += snprintf(temp_buf, len, "attn = %x\n",
+ himax_int_gpio_read(ts_data->pdata->gpio_irq));
+
+ if (copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n", __func__, __LINE__);
+
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG = 1;
+ } else
+ HX_PROC_SEND_FLAG = 0;
+
+ return ret;
+}
+
+const struct file_operations himax_proc_attn_ops = {
+ .owner = THIS_MODULE,
+ .read = himax_attn_read,
+};
+
+static ssize_t himax_int_en_read(struct file *file, char *buf,
+ size_t len, loff_t *pos)
+{
+ struct himax_ts_data *ts = private_ts;
+ size_t ret = 0;
+ char *temp_buf;
+
+ if (!HX_PROC_SEND_FLAG) {
+ temp_buf = kzalloc(len, GFP_KERNEL);
+ ret += snprintf(temp_buf, len-1, "%d ", ts->irq_enabled);
+ ret += snprintf(temp_buf, 1, "\n");
+
+ if (copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n", __func__, __LINE__);
+
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG = 1;
+ } else
+ HX_PROC_SEND_FLAG = 0;
+ return ret;
+}
+
+static ssize_t himax_int_en_write(struct file *file, const char *buff,
+ size_t len, loff_t *pos)
+{
+ struct himax_ts_data *ts = private_ts;
+ char buf_tmp[12] = {0};
+ int value, ret = 0;
+
+ if (len >= 12) {
+ I("%s: no command exceeds 12 chars.\n", __func__);
+ return -EFAULT;
+ }
+ if (copy_from_user(buf_tmp, buff, len))
+ return -EFAULT;
+
+ if (buf_tmp[0] == '0')
+ value = false;
+ else if (buf_tmp[0] == '1')
+ value = true;
+ else
+ return -EINVAL;
+
+ if (value) {
+ if (ic_data->HX_INT_IS_EDGE) {
+#ifdef MTK
+#ifdef CONFIG_OF_TOUCH
+ himax_int_enable(ts->client->irq, 1);
+#else
+ /*mt_eint_set_sens(CUST_EINT_TOUCH_PANEL_NUM,
+ CUST_EINT_TOUCH_PANEL_TYPE);
+ mt_eint_set_hw_debounce(CUST_EINT_TOUCH_PANEL_NUM,
+ CUST_EINT_TOUCH_PANEL_DEBOUNCE_CN);*/
+ mt_eint_registration(ts->client->irq,
+ EINTF_TRIGGER_FALLING, tpd_eint_interrupt_handler, 1);
+#endif
+#endif
+#ifdef QCT
+ ret = request_threaded_irq(ts->client->irq,
+ NULL, himax_ts_thread,
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ ts->client->name, ts);
+#endif
+ } else {
+#ifdef MTK
+#ifdef CONFIG_OF_TOUCH
+ himax_int_enable(ts->client->irq, 1);
+#else
+ /*mt_eint_set_sens(CUST_EINT_TOUCH_PANEL_NUM,
+ CUST_EINT_TOUCH_PANEL_TYPE);
+ mt_eint_set_hw_debounce(CUST_EINT_TOUCH_PANEL_NUM,
+ CUST_EINT_TOUCH_PANEL_DEBOUNCE_CN);*/
+ mt_eint_registration(ts->client->irq,
+ EINTF_TRIGGER_LOW, tpd_eint_interrupt_handler, 1);
+#endif
+#endif
+#ifdef QCT
+ ret = request_threaded_irq(ts->client->irq,
+ NULL, himax_ts_thread,
+ IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ ts->client->name, ts);
+#endif
+ }
+ if (ret == 0) {
+ ts->irq_enabled = 1;
+ irq_enable_count = 1;
+ }
+ } else {
+ himax_int_enable(ts->client->irq, 0);
+ free_irq(ts->client->irq, ts);
+ ts->irq_enabled = 0;
+ }
+
+ return len;
+}
+
+const struct file_operations himax_proc_int_en_ops = {
+ .owner = THIS_MODULE,
+ .read = himax_int_en_read,
+ .write = himax_int_en_write,
+};
+
+static ssize_t himax_layout_read(struct file *file, char *buf,
+ size_t len, loff_t *pos)
+{
+ struct himax_ts_data *ts = private_ts;
+ size_t ret = 0;
+ char *temp_buf;
+
+ if (!HX_PROC_SEND_FLAG) {
+ temp_buf = kzalloc(len, GFP_KERNEL);
+ ret += snprintf(temp_buf, len, "%d ", ts->pdata->abs_x_min);
+ ret += snprintf(temp_buf, len, "%d ", ts->pdata->abs_x_max);
+ ret += snprintf(temp_buf, len, "%d ", ts->pdata->abs_y_min);
+ ret += snprintf(temp_buf, len, "%d ", ts->pdata->abs_y_max);
+ ret += snprintf(temp_buf, len, "\n");
+
+ if (copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n", __func__, __LINE__);
+
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG = 1;
+ } else
+ HX_PROC_SEND_FLAG = 0;
+
+ return ret;
+}
+
+static ssize_t himax_layout_write(struct file *file, const char *buff,
+ size_t len, loff_t *pos)
+{
+ struct himax_ts_data *ts = private_ts;
+ char buf_tmp[5];
+ int i = 0, j = 0, k = 0, ret;
+ unsigned long value;
+ int layout[4] = {0};
+ char buf[80] = {0};
+
+ if (len >= 80) {
+ I("%s: no command exceeds 80 chars.\n", __func__);
+ return -EFAULT;
+ }
+ if (copy_from_user(buf, buff, len))
+ return -EFAULT;
+
+ for (i = 0 ; i < 20 ; i++) {
+ if (buf[i] == ',' || buf[i] == '\n') {
+ memset(buf_tmp, 0x0, sizeof(buf_tmp));
+ if (i - j <= 5)
+ memcpy(buf_tmp, buf + j, i - j);
+ else {
+ I("buffer size is over 5 char\n");
+ return len;
+ }
+ j = i + 1;
+ if (k < 4) {
+ ret = kstrtoul(buf_tmp, 10, &value);
+ layout[k++] = value;
+ }
+ }
+ }
+ if (k == 4) {
+ ts->pdata->abs_x_min = layout[0];
+ ts->pdata->abs_x_max = layout[1];
+ ts->pdata->abs_y_min = layout[2];
+ ts->pdata->abs_y_max = layout[3];
+ I("%d, %d, %d, %d\n", ts->pdata->abs_x_min,
+ ts->pdata->abs_x_max, ts->pdata->abs_y_min,
+ ts->pdata->abs_y_max);
+ input_unregister_device(ts->input_dev);
+ himax_input_register(ts);
+ } else {
+ I("ERR@%d, %d, %d, %d\n", ts->pdata->abs_x_min,
+ ts->pdata->abs_x_max, ts->pdata->abs_y_min,
+ ts->pdata->abs_y_max);
+ }
+ return len;
+}
+
+const struct file_operations himax_proc_layout_ops = {
+ .owner = THIS_MODULE,
+ .read = himax_layout_read,
+ .write = himax_layout_write,
+};
+
+static ssize_t himax_debug_level_read(struct file *file, char *buf,
+ size_t len, loff_t *pos)
+{
+ struct himax_ts_data *ts_data;
+ size_t ret = 0;
+ char *temp_buf;
+
+ ts_data = private_ts;
+
+ if (!HX_PROC_SEND_FLAG) {
+ temp_buf = kzalloc(len, GFP_KERNEL);
+ ret += snprintf(temp_buf, len, "%d\n",
+ ts_data->debug_log_level);
+
+ if (copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n", __func__, __LINE__);
+
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG = 1;
+ } else
+ HX_PROC_SEND_FLAG = 0;
+
+ return ret;
+}
+
+static ssize_t himax_debug_level_write(struct file *file, const char *buff,
+ size_t len, loff_t *pos)
+{
+ struct himax_ts_data *ts;
+ char buf_tmp[11];
+ int i;
+
+ ts = private_ts;
+
+ if (len >= 12) {
+ I("%s: no command exceeds 12 chars.\n", __func__);
+ return -EFAULT;
+ }
+ if (copy_from_user(buf_tmp, buff, len))
+ return -EFAULT;
+
+ ts->debug_log_level = 0;
+ for (i = 0 ; i < len - 1 ; i++) {
+ if (buf_tmp[i] >= '0' && buf_tmp[i] <= '9')
+ ts->debug_log_level |= (buf_tmp[i] - '0');
+ else if (buf_tmp[i] >= 'A' && buf_tmp[i] <= 'F')
+ ts->debug_log_level |= (buf_tmp[i]-'A' + 10);
+ else if (buf_tmp[i] >= 'a' && buf_tmp[i] <= 'f')
+ ts->debug_log_level |= (buf_tmp[i] - 'a' + 10);
+
+ if (i != len - 2)
+ ts->debug_log_level <<= 4;
+ }
+
+ if (ts->debug_log_level & BIT(3)) {
+ if (ts->pdata->screenWidth > 0 && ts->pdata->screenHeight > 0 &&
+ (ts->pdata->abs_x_max - ts->pdata->abs_x_min) > 0 &&
+ (ts->pdata->abs_y_max - ts->pdata->abs_y_min) > 0) {
+ ts->widthFactor =
+ (ts->pdata->screenWidth << SHIFTBITS)
+ / (ts->pdata->abs_x_max - ts->pdata->abs_x_min);
+ ts->heightFactor =
+ (ts->pdata->screenHeight << SHIFTBITS)
+ / (ts->pdata->abs_y_max - ts->pdata->abs_y_min);
+ if (ts->widthFactor > 0 && ts->heightFactor > 0)
+ ts->useScreenRes = 1;
+ else {
+ ts->heightFactor = 0;
+ ts->widthFactor = 0;
+ ts->useScreenRes = 0;
+ }
+ } else
+ I("Enable finger debug with raw position mode!\n");
+ } else {
+ ts->useScreenRes = 0;
+ ts->widthFactor = 0;
+ ts->heightFactor = 0;
+ }
+
+ return len;
+}
+
+const struct file_operations himax_proc_debug_level_ops = {
+ .owner = THIS_MODULE,
+ .read = himax_debug_level_read,
+ .write = himax_debug_level_write,
+};
+
+#ifdef HX_TP_PROC_REGISTER
+static ssize_t himax_proc_register_read(struct file *file, char *buf,
+ size_t len, loff_t *pos)
+{
+ int ret = 0;
+ uint16_t loop_i;
+ uint8_t data[128];
+ char *temp_buf;
+
+ memset(data, 0x00, sizeof(data));
+
+ I("himax_register_show: %x,%x,%x,%x\n", register_command[0],
+ register_command[1], register_command[2], register_command[3]);
+
+ if (!HX_PROC_SEND_FLAG) {
+ temp_buf = kzalloc(len, GFP_KERNEL);
+ himax_register_read(private_ts->client,
+ register_command, 1, data);
+
+ ret += snprintf(temp_buf, len, "command: %x,%x,%x,%x\n",
+ register_command[0], register_command[1],
+ register_command[2], register_command[3]);
+
+ for (loop_i = 0 ; loop_i < 128 ; loop_i++) {
+ ret += snprintf(temp_buf + ret,
+ sizeof(data[loop_i]), "0x%2.2X ", data[loop_i]);
+ if ((loop_i % 16) == 15)
+ ret += snprintf(temp_buf + ret, 1, "\n");
+ }
+ ret += snprintf(temp_buf + ret, len, "\n");
+ HX_PROC_SEND_FLAG = 1;
+
+ if (copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n", __func__, __LINE__);
+
+ kfree(temp_buf);
+ } else
+ HX_PROC_SEND_FLAG = 0;
+ return ret;
+}
+
+static ssize_t himax_proc_register_write(struct file *file, const char *buff,
+ size_t len, loff_t *pos)
+{
+ char buf_tmp[16], length = 0;
+ unsigned long result = 0;
+ uint8_t loop_i = 0;
+ uint16_t base = 5;
+ uint8_t write_da[128];
+ char buf[80] = {0};
+
+ if (len >= 80) {
+ I("%s: no command exceeds 80 chars.\n", __func__);
+ return -EFAULT;
+ }
+ if (copy_from_user(buf, buff, len))
+ return -EFAULT;
+
+ memset(buf_tmp, 0x0, sizeof(buf_tmp));
+ memset(write_da, 0x0, sizeof(write_da));
+
+ I("himax %s\n", buf);
+
+ if ((buf[0] == 'r' || buf[0] == 'w') && buf[1] == ':') {
+
+ if (buf[2] == 'x') {
+ memcpy(buf_tmp, buf + 3, 8);
+ if (!kstrtoul(buf_tmp, 16, &result)) {
+ register_command[0] =
+ (uint8_t)result;
+ register_command[1] =
+ (uint8_t)(result >> 8);
+ register_command[2] =
+ (uint8_t)(result >> 16);
+ register_command[3] =
+ (uint8_t)(result >> 24);
+ }
+ base = 11;
+ I("CMD: %x,%x,%x,%x\n", register_command[0],
+ register_command[1], register_command[2],
+ register_command[3]);
+
+ for (loop_i = 0 ; loop_i < 128 ; loop_i++) {
+ if (buf[base] == '\n') {
+ if (buf[0] == 'w') {
+ himax_register_write
+ (private_ts->client,
+ register_command
+ , 1, write_da);
+ I("CMD:%x, %x, %x, %x,len=%d\n",
+ write_da[0], write_da[1],
+ write_da[2], write_da[3],
+ length);
+ }
+ I("\n");
+ return len;
+ }
+ if (buf[base + 1] == 'x') {
+ buf_tmp[10] = '\n';
+ buf_tmp[11] = '\0';
+ memcpy(buf_tmp, buf + base + 2, 8);
+ if (!kstrtoul(buf_tmp, 16, &result)) {
+ write_da[loop_i] =
+ (uint8_t)result;
+ write_da[loop_i+1] =
+ (uint8_t)(result >> 8);
+ write_da[loop_i+2] =
+ (uint8_t)(result >> 16);
+ write_da[loop_i+3] =
+ (uint8_t)(result >> 24);
+ }
+ length += 4;
+ }
+ base += 10;
+ }
+ }
+ }
+ return len;
+}
+
+const struct file_operations himax_proc_register_ops = {
+ .owner = THIS_MODULE,
+ .read = himax_proc_register_read,
+ .write = himax_proc_register_write,
+};
+#endif
+
+#ifdef HX_TP_PROC_DIAG
+int16_t *getMutualBuffer(void)
+{
+ return diag_mutual;
+}
+int16_t *getMutualNewBuffer(void)
+{
+ return diag_mutual_new;
+}
+int16_t *getMutualOldBuffer(void)
+{
+ return diag_mutual_old;
+}
+int16_t *getSelfBuffer(void)
+{
+ return &diag_self[0];
+}
+uint8_t getXChannel(void)
+{
+ return x_channel;
+}
+uint8_t getYChannel(void)
+{
+ return y_channel;
+}
+uint8_t getDiagCommand(void)
+{
+ return diag_command;
+}
+void setXChannel(uint8_t x)
+{
+ x_channel = x;
+}
+void setYChannel(uint8_t y)
+{
+ y_channel = y;
+}
+void setMutualBuffer(void)
+{
+ diag_mutual = kzalloc
+ (x_channel * y_channel * sizeof(int16_t), GFP_KERNEL);
+}
+void setMutualNewBuffer(void)
+{
+ diag_mutual_new = kzalloc
+ (x_channel * y_channel * sizeof(int16_t), GFP_KERNEL);
+}
+void setMutualOldBuffer(void)
+{
+ diag_mutual_old = kzalloc
+ (x_channel * y_channel * sizeof(int16_t), GFP_KERNEL);
+}
+
+#ifdef HX_TP_PROC_2T2R
+int16_t *getMutualBuffer_2(void)
+{
+ return diag_mutual_2;
+}
+uint8_t getXChannel_2(void)
+{
+ return x_channel_2;
+}
+uint8_t getYChannel_2(void)
+{
+ return y_channel_2;
+}
+void setXChannel_2(uint8_t x)
+{
+ x_channel_2 = x;
+}
+void setYChannel_2(uint8_t y)
+{
+ y_channel_2 = y;
+}
+void setMutualBuffer_2(void)
+{
+ diag_mutual_2 = kzalloc
+ (x_channel_2 * y_channel_2 * sizeof(int16_t), GFP_KERNEL);
+}
+#endif
+
+static ssize_t himax_diag_arrange_write(struct file *file, const char *buff,
+ size_t len, loff_t *pos)
+{
+ /*struct himax_ts_data *ts = private_ts;*/
+ char buf[80] = {0};
+
+ if (len >= 80) {
+ I("%s: no command exceeds 80 chars.\n", __func__);
+ return -EFAULT;
+ }
+ if (copy_from_user(buf, buff, len))
+ return -EFAULT;
+
+ g_diag_arr_num = buf[0] - '0';
+ I("%s: g_diag_arr_num = %d\n", __func__, g_diag_arr_num);
+
+ return len;
+}
+
+const struct file_operations himax_proc_diag_arrange_ops = {
+ .owner = THIS_MODULE,
+ .write = himax_diag_arrange_write,
+};
+
+static void himax_diag_arrange_print
+(struct seq_file *s, int i, int j, int transpose)
+{
+ if (transpose)
+ seq_printf(s, "%6d", diag_mutual[j + i * x_channel]);
+ else
+ seq_printf(s, "%6d", diag_mutual[i + j * x_channel]);
+}
+
+static void himax_diag_arrange_inloop
+(struct seq_file *s, int in_init, bool transpose, int j)
+{
+ int i;
+ int in_max = 0;
+
+ if (transpose)
+ in_max = y_channel;
+ else
+ in_max = x_channel;
+
+ if (in_init > 0) {
+ for (i = in_init - 1 ; i >= 0 ; i--)
+ himax_diag_arrange_print(s, i, j, transpose);
+ } else {
+ for (i = 0 ; i < in_max ; i++)
+ himax_diag_arrange_print(s, i, j, transpose);
+ }
+}
+
+static void himax_diag_arrange_outloop
+(struct seq_file *s, int transpose, int out_init, int in_init)
+{
+ int j;
+ int out_max = 0;
+
+ if (transpose)
+ out_max = x_channel;
+ else
+ out_max = y_channel;
+
+ if (out_init > 0) {
+ for (j = out_init - 1 ; j >= 0 ; j--) {
+ himax_diag_arrange_inloop(s, in_init, transpose, j);
+ seq_printf(s, " %5d\n", diag_self[j]);
+ }
+ } else {
+ for (j = 0 ; j < out_max ; j++) {
+ himax_diag_arrange_inloop(s, in_init, transpose, j);
+ seq_printf(s, " %5d\n", diag_self[j]);
+ }
+ }
+}
+
+static void himax_diag_arrange(struct seq_file *s)
+{
+ int bit2, bit1, bit0;
+ int i;
+
+ bit2 = g_diag_arr_num >> 2;
+ bit1 = g_diag_arr_num >> 1 & 0x1;
+ bit0 = g_diag_arr_num & 0x1;
+
+ if (g_diag_arr_num < 4) {
+ himax_diag_arrange_outloop(s,
+ bit2, bit1 * y_channel, bit0 * x_channel);
+
+ for (i = y_channel ; i < x_channel + y_channel ; i++)
+ seq_printf(s, "%6d", diag_self[i]);
+
+ } else {
+ himax_diag_arrange_outloop(s,
+ bit2, bit1 * x_channel, bit0 * y_channel);
+
+ for (i = x_channel ; i < x_channel + y_channel ; i++)
+ seq_printf(s, "%6d", diag_self[i]);
+
+ }
+}
+
+static void *himax_diag_seq_start(struct seq_file *s, loff_t *pos)
+{
+ if (*pos >= 1)
+ return NULL;
+ return (void *)((unsigned long) *pos + 1);
+}
+
+static void *himax_diag_seq_next(struct seq_file *s, void *v, loff_t *pos)
+{
+ return NULL;
+}
+static void himax_diag_seq_stop(struct seq_file *s, void *v)
+{
+}
+static int himax_diag_seq_read(struct seq_file *s, void *v)
+{
+ size_t count = 0;
+ int32_t loop_i;/*loop_j*/
+ uint16_t mutual_num, self_num, width;
+
+#ifdef HX_TP_PROC_2T2R
+ if (Is_2T2R && diag_command == 4) {
+ mutual_num = x_channel_2 * y_channel_2;
+ /*don't add KEY_COUNT*/
+ self_num = x_channel_2 + y_channel_2;
+ width = x_channel_2;
+ seq_printf(s, "ChannelStart: %4d, %4d\n\n",
+ x_channel_2, y_channel_2);
+ } else
+#endif
+ {
+ mutual_num = x_channel * y_channel;
+ /*don't add KEY_COUNT*/
+ self_num = x_channel + y_channel;
+ width = x_channel;
+ seq_printf(s, "ChannelStart: %4d, %4d\n\n",
+ x_channel, y_channel);
+ }
+
+ /* start to show out the raw data in adb shell*/
+ if (diag_command >= 1 && diag_command <= 6) {
+ if (diag_command <= 3) {
+ himax_diag_arrange(s);
+ seq_puts(s, "\n\n");
+#ifdef HX_EN_SEL_BUTTON
+ seq_putc(s, '\n');
+ for (loop_i = 0 ; loop_i < HX_BT_NUM ; loop_i++)
+ seq_printf(s, "%6d",
+ diag_self[HX_RX_NUM + HX_TX_NUM + loop_i]);
+#endif
+#ifdef HX_TP_PROC_2T2R
+ } else if (Is_2T2R && diag_command == 4) {
+ for (loop_i = 0 ; loop_i < mutual_num ; loop_i++) {
+ seq_printf(s, "%4d", diag_mutual_2[loop_i]);
+ if ((loop_i % width) == (width - 1))
+ seq_printf(s, " %6d\n",
+ diag_self[width + loop_i / width]);
+ }
+ seq_putc(s, '\n');
+ for (loop_i = 0 ; loop_i < width ; loop_i++) {
+ seq_printf(s, "%6d", diag_self[loop_i]);
+ if (((loop_i) % width) == (width - 1))
+ seq_putc(s, '\n');
+ }
+#ifdef HX_EN_SEL_BUTTON
+ seq_putc(s, '\n');
+ for (loop_i = 0 ; loop_i < HX_BT_NUM ; loop_i++) {
+ seq_printf(s, "%4d",
+ diag_self[HX_RX_NUM_2 + HX_TX_NUM_2 + loop_i]);
+ }
+#endif
+#endif
+ } else if (diag_command > 4) {
+ for (loop_i = 0 ; loop_i < self_num ; loop_i++) {
+ seq_printf(s, "%4d", diag_self[loop_i]);
+ if (((loop_i - mutual_num) % width)
+ == (width - 1)) {
+ seq_putc(s, '\n');
+ }
+ }
+ } else {
+ for (loop_i = 0 ; loop_i < mutual_num ; loop_i++) {
+ seq_printf(s, "%4d", diag_mutual[loop_i]);
+ if ((loop_i % width) == (width - 1))
+ seq_putc(s, '\n');
+ }
+ }
+ seq_puts(s, "ChannelEnd");
+ seq_putc(s, '\n');
+ } else if (diag_command == 7) {
+ for (loop_i = 0; loop_i < 128 ; loop_i++) {
+ if ((loop_i % 16) == 0)
+ seq_puts(s, "LineStart:");
+ seq_printf(s, "%4d", diag_coor[loop_i]);
+ if ((loop_i % 16) == 15)
+ seq_putc(s, '\n');
+ }
+ } else if (diag_command == 9 ||
+ diag_command == 91 || diag_command == 92) {
+
+ himax_diag_arrange(s);
+ seq_putc(s, '\n');
+ }
+
+ return count;
+}
+const struct seq_operations himax_diag_seq_ops = {
+ .start = himax_diag_seq_start,
+ .next = himax_diag_seq_next,
+ .stop = himax_diag_seq_stop,
+ .show = himax_diag_seq_read,
+};
+static int himax_diag_proc_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &himax_diag_seq_ops);
+};
+bool DSRAM_Flag = false;
+
+/*DSRAM thread*/
+void himax_ts_diag_func(void)
+{
+ int i = 0, j = 0;
+ unsigned int index = 0;
+ int total_size = ic_data->HX_TX_NUM * ic_data->HX_RX_NUM * 2;
+ uint8_t info_data[total_size];
+ int16_t *mutual_data;
+ int16_t *mutual_data_new;
+ int16_t *mutual_data_old;
+ int16_t new_data;
+
+ himax_burst_enable(private_ts->client, 1);
+ if (diag_command == 9 || diag_command == 91) {
+ mutual_data = getMutualBuffer();
+ } else if (diag_command == 92) {
+ mutual_data = getMutualBuffer();
+ mutual_data_new = getMutualNewBuffer();
+ mutual_data_old = getMutualOldBuffer();
+ }
+ himax_get_DSRAM_data(private_ts->client, info_data);
+
+ index = 0;
+ for (i = 0 ; i < ic_data->HX_TX_NUM ; i++) {
+ for (j = 0 ; j < ic_data->HX_RX_NUM ; j++) {
+ new_data = (short)(info_data[index + 1]
+ << 8 | info_data[index]);
+ if (diag_command == 9) {
+ mutual_data[i * ic_data->HX_RX_NUM + j]
+ = new_data;
+ /*Keep max data for 100 frame*/
+ } else if (diag_command == 91) {
+ if (mutual_data[i * ic_data->HX_RX_NUM + j]
+ < new_data) {
+ mutual_data[i * ic_data->HX_RX_NUM + j]
+ = new_data;
+ }
+ /*Cal data for [N]-[N-1] frame*/
+ } else if (diag_command == 92) {
+ mutual_data_new[i * ic_data->HX_RX_NUM + j]
+ = new_data;
+
+ mutual_data[i * ic_data->HX_RX_NUM + j] =
+ mutual_data_new[i * ic_data->HX_RX_NUM + j] -
+ mutual_data_old[i * ic_data->HX_RX_NUM + j];
+ }
+ index += 2;
+ }
+ }
+ /*copy N data to N-1 array*/
+ if (diag_command == 92) {
+ memcpy(mutual_data_old, mutual_data_new,
+ x_channel * y_channel * sizeof(int16_t));
+ }
+
+ diag_max_cnt++;
+ if (diag_command == 9 || diag_command == 92) {
+ queue_delayed_work(private_ts->himax_diag_wq,
+ &private_ts->himax_diag_delay_wrok, 1/10*HZ);
+ } else if (diag_command == 91) {
+ if (diag_max_cnt > 100) {/*count for 100 frame*/
+ /*Clear DSRAM flag*/
+ DSRAM_Flag = false;
+
+ /*Enable ISR*/
+ himax_int_enable(private_ts->client->irq, 1);
+
+ /*=====================================
+ test result command : 0x8002_0324 ==> 0x00
+ =====================================*/
+ himax_diag_register_set(private_ts->client, 0x00);
+ } else {
+ queue_delayed_work(private_ts->himax_diag_wq,
+ &private_ts->himax_diag_delay_wrok, 1 / 10 * HZ);
+ }
+ }
+}
+
+static ssize_t himax_diag_write
+(struct file *filp, const char __user *buff, size_t len, loff_t *data)
+{
+ char messages[80] = {0};
+
+ uint8_t command[2] = {0x00, 0x00};
+ uint8_t receive[1];
+
+ memset(receive, 0x00, sizeof(receive));
+
+ if (len >= 80) {
+ I("%s: no command exceeds 80 chars.\n", __func__);
+ return -EFAULT;
+ }
+ if (copy_from_user(messages, buff, len))
+ return -EFAULT;
+
+ if (messages[1] == 0x0A)
+ diag_command = messages[0] - '0';
+ else
+ diag_command = (messages[0] - '0') * 10 + (messages[1] - '0');
+
+
+ I("[Himax]diag_command=0x%x\n", diag_command);
+ if (diag_command < 0x04) {
+ if (DSRAM_Flag) {
+ /*1. Clear DSRAM flag*/
+ DSRAM_Flag = false;
+
+ /*2. Stop DSRAM thread*/
+ cancel_delayed_work_sync
+ (&private_ts->himax_diag_delay_wrok);
+
+ /*3. Enable ISR*/
+ himax_int_enable(private_ts->client->irq, 1);
+ }
+ command[0] = diag_command;
+ himax_diag_register_set(private_ts->client, command[0]);
+ /*coordinate dump start*/
+ } else if (diag_command == 0x09 ||
+ diag_command == 91 || diag_command == 92) {
+
+ diag_max_cnt = 0;
+ /*Set data 0 everytime*/
+ memset(diag_mutual, 0x00,
+ x_channel * y_channel * sizeof(int16_t));
+
+ /*1. Disable ISR*/
+ himax_int_enable(private_ts->client->irq, 0);
+
+ /*2. Start DSRAM thread*/
+ /*himax_diag_register_set(private_ts->client, 0x0A);*/
+
+ queue_delayed_work(private_ts->himax_diag_wq,
+ &private_ts->himax_diag_delay_wrok, 2 * HZ / 100);
+
+ I("%s: Start get raw data in DSRAM\n", __func__);
+
+ /*3. Set DSRAM flag*/
+ DSRAM_Flag = true;
+ } else {
+ command[0] = 0x00;
+ himax_diag_register_set(private_ts->client, command[0]);
+ E("[Himax]Diag command error!diag_command=0x%x\n",
+ diag_command);
+ }
+ return len;
+}
+
+const struct file_operations himax_proc_diag_ops = {
+ .owner = THIS_MODULE,
+ .open = himax_diag_proc_open,
+ .read = seq_read,
+ .write = himax_diag_write,
+};
+#endif
+
+#ifdef HX_TP_PROC_RESET
+static ssize_t himax_reset_write(struct file *file, const char *buff,
+ size_t len, loff_t *pos)
+{
+ char buf_tmp[12];
+
+ if (len >= 12) {
+ I("%s: no command exceeds 12 chars.\n", __func__);
+ return -EFAULT;
+ }
+ if (copy_from_user(buf_tmp, buff, len))
+ return -EFAULT;
+
+ /*if (buf_tmp[0] == '1')
+ ESD_HW_REST();*/
+
+ return len;
+}
+
+const struct file_operations himax_proc_reset_ops = {
+ .owner = THIS_MODULE,
+ .write = himax_reset_write,
+};
+#endif
+
+#ifdef HX_TP_PROC_DEBUG
+static ssize_t himax_debug_read(struct file *file, char *buf,
+ size_t len, loff_t *pos)
+{
+ size_t count = 0;
+ char *temp_buf;
+
+ if (!HX_PROC_SEND_FLAG) {
+ temp_buf = kzalloc(len, GFP_KERNEL);
+ if (debug_level_cmd == 't') {
+ if (fw_update_complete) {
+ count += snprintf(temp_buf, len,
+ "FW Update Complete ");
+ } else {
+ count += snprintf(temp_buf, len,
+ "FW Update Fail ");
+ }
+
+ } else if (debug_level_cmd == 'h') {
+ if (handshaking_result == 0) {
+ count += snprintf(temp_buf, len,
+ "Handshaking Result = %d (MCU Running)\n",
+ handshaking_result);
+ } else if (handshaking_result == 1) {
+ count += snprintf(temp_buf, len,
+ "Handshaking Result = %d (MCU Stop)\n",
+ handshaking_result);
+ } else if (handshaking_result == 2) {
+ count += snprintf(temp_buf, len,
+ "Handshaking Result = %d (I2C Error)\n",
+ handshaking_result);
+ } else {
+ count += snprintf(temp_buf, len,
+ "Handshaking Result = error\n");
+ }
+ } else if (debug_level_cmd == 'v') {
+ count += snprintf(temp_buf + count, len,
+ "FW_VER = ");
+ count += snprintf(temp_buf + count, len,
+ "0x%2.2X\n", ic_data->vendor_fw_ver);
+ count += snprintf(temp_buf + count, len,
+ "CONFIG_VER = ");
+ count += snprintf(temp_buf + count, len,
+ "0x%2.2X\n", ic_data->vendor_config_ver);
+ count += snprintf(temp_buf + count, len,
+ "\n");
+ } else if (debug_level_cmd == 'd') {
+ count += snprintf(temp_buf + count, len,
+ "Himax Touch IC Information :\n");
+ if (IC_TYPE == HX_85XX_D_SERIES_PWON) {
+ count += snprintf(temp_buf + count, len,
+ "IC Type : D\n");
+ } else if (IC_TYPE == HX_85XX_E_SERIES_PWON) {
+ count += snprintf(temp_buf + count, len,
+ "IC Type : E\n");
+ } else if (IC_TYPE == HX_85XX_ES_SERIES_PWON) {
+ count += snprintf(temp_buf + count, len,
+ "IC Type : ES\n");
+ } else if (IC_TYPE == HX_85XX_F_SERIES_PWON) {
+ count += snprintf(temp_buf + count, len,
+ "IC Type : F\n");
+ } else {
+ count += snprintf(temp_buf + count, len,
+ "IC Type error.\n");
+ }
+ if (IC_CHECKSUM == HX_TP_BIN_CHECKSUM_SW) {
+ count += snprintf(temp_buf + count, len,
+ "IC Checksum : SW\n");
+ } else if (IC_CHECKSUM == HX_TP_BIN_CHECKSUM_HW) {
+ count += snprintf(temp_buf + count, len,
+ "IC Checksum : HW\n");
+ } else if (IC_CHECKSUM == HX_TP_BIN_CHECKSUM_CRC) {
+ count += snprintf(temp_buf + count, len,
+ "IC Checksum : CRC\n");
+ } else {
+ count += snprintf(temp_buf + count, len,
+ "IC Checksum error.\n");
+ }
+ if (ic_data->HX_INT_IS_EDGE) {
+ count += snprintf(temp_buf + count, len,
+ "Interrupt : EDGE TIRGGER\n");
+ } else {
+ count += snprintf(temp_buf + count, len,
+ "Interrupt : LEVEL TRIGGER\n");
+ }
+ count += snprintf(temp_buf + count, len,
+ "RX Num : %d\n", ic_data->HX_RX_NUM);
+ count += snprintf(temp_buf + count, len,
+ "TX Num : %d\n", ic_data->HX_TX_NUM);
+ count += snprintf(temp_buf + count, len,
+ "BT Num : %d\n", ic_data->HX_BT_NUM);
+ count += snprintf(temp_buf + count, len,
+ "X Resolution : %d\n", ic_data->HX_X_RES);
+ count += snprintf(temp_buf + count, len,
+ "Y Resolution : %d\n", ic_data->HX_Y_RES);
+ count += snprintf(temp_buf + count, len,
+ "Max Point : %d\n", ic_data->HX_MAX_PT);
+ count += snprintf(temp_buf + count, len,
+ "XY reverse : %d\n", ic_data->HX_XY_REVERSE);
+ #ifdef HX_TP_PROC_2T2R
+ if (Is_2T2R) {
+ count += snprintf(temp_buf + count, len,
+ "2T2R panel\n");
+ count += snprintf(temp_buf + count, len,
+ "RX Num_2 : %d\n", HX_RX_NUM_2);
+ count += snprintf(temp_buf + count, len,
+ "TX Num_2 : %d\n", HX_TX_NUM_2);
+ }
+ #endif
+ } else if (debug_level_cmd == 'i') {
+ count += snprintf(temp_buf + count, len,
+ "Himax Touch Driver Version:\n");
+ count += snprintf(temp_buf + count, len,
+ "%s\n", HIMAX_DRIVER_VER);
+ }
+ if (copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n", __func__, __LINE__);
+
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG = 1;
+ } else
+ HX_PROC_SEND_FLAG = 0;
+ return count;
+}
+
+static ssize_t himax_debug_write(struct file *file, const char *buff,
+ size_t len, loff_t *pos)
+{
+ int result = 0;
+ char fileName[128];
+ char buf[80] = {0};
+ const struct firmware *fw = NULL;
+
+ if (len >= 80) {
+ I("%s: no command exceeds 80 chars.\n", __func__);
+ return -EFAULT;
+ }
+ if (copy_from_user(buf, buff, len))
+ return -EFAULT;
+
+ if (buf[0] == 'h') {/*handshaking*/
+ debug_level_cmd = buf[0];
+
+ himax_int_enable(private_ts->client->irq, 0);
+
+ /*0:Running, 1:Stop, 2:I2C Fail*/
+ handshaking_result = himax_hand_shaking(private_ts->client);
+
+ himax_int_enable(private_ts->client->irq, 1);
+
+ return len;
+ } else if (buf[0] == 'v') { /*firmware version*/
+ debug_level_cmd = buf[0];
+ himax_int_enable(private_ts->client->irq, 0);
+#ifdef HX_RST_PIN_FUNC
+ himax_HW_reset(false, false);
+#endif
+ himax_read_FW_ver(private_ts->client);
+ /*himax_check_chip_version();*/
+#ifdef HX_RST_PIN_FUNC
+ himax_HW_reset(true, false);
+#endif
+ himax_int_enable(private_ts->client->irq, 1);
+ return len;
+ } else if (buf[0] == 'd') { /*ic information*/
+
+ debug_level_cmd = buf[0];
+ return len;
+ } else if (buf[0] == 'i') {/*driver version*/
+
+ debug_level_cmd = buf[0];
+ return len;
+ } else if (buf[0] == 't') {
+
+ himax_int_enable(private_ts->client->irq, 0);
+ debug_level_cmd = buf[0];
+ fw_update_complete = false;
+
+ result = himax_load_CRC_bin_file(private_ts->client);
+ if (result < 0) {
+ E("%s: himax_load_CRC_bin_file fail Error Code=%d.\n",
+ __func__, result);
+ return result;
+ }
+
+ memset(fileName, 0, 128);
+/* parse the file name*/
+ snprintf(fileName, len-4, "%s", &buf[4]);
+ I("%s: upgrade from file(%s) start!\n", __func__, fileName);
+ result = request_firmware(&fw, fileName, private_ts->dev);
+ if (result < 0) {
+ I("fail to request_firmware fwpath: %s (ret:%d)\n",
+ fileName, result);
+ return result;
+ }
+ I("%s: FW image: %02X, %02X, %02X, %02X ret=%d\n", __func__,
+ fw->data[0], fw->data[1], fw->data[2], fw->data[3], result);
+ if (result >= 0) {
+ /*start to upgrade*/
+ himax_int_enable(private_ts->client->irq, 0);
+
+ if ((buf[1] == '6') && (buf[2] == '0')) {
+ if (fts_ctpm_fw_upgrade_with_sys_fs_60k
+ (private_ts->client, (unsigned char *)fw->data,
+ fw->size, false) == 0) {
+ E("%s: TP upgrade error, line: %d\n",
+ __func__, __LINE__);
+ fw_update_complete = false;
+ } else {
+ I("%s: TP upgrade OK, line: %d\n",
+ __func__, __LINE__);
+ fw_update_complete = true;
+ }
+ } else if ((buf[1] == '6') && (buf[2] == '4')) {
+ if (fts_ctpm_fw_upgrade_with_sys_fs_64k
+ (private_ts->client, (unsigned char *)fw->data,
+ fw->size, false) == 0) {
+ E("%s: TP upgrade error, line: %d\n",
+ __func__, __LINE__);
+ fw_update_complete = false;
+ } else {
+ I("%s: TP upgrade OK, line: %d\n",
+ __func__, __LINE__);
+ fw_update_complete = true;
+ }
+ } else if ((buf[1] == '2') && (buf[2] == '4')) {
+ if (fts_ctpm_fw_upgrade_with_sys_fs_124k
+ (private_ts->client, (unsigned char *)fw->data,
+ fw->size, false) == 0) {
+ E("%s: TP upgrade error, line: %d\n",
+ __func__, __LINE__);
+ fw_update_complete = false;
+ } else {
+ I("%s: TP upgrade OK, line: %d\n",
+ __func__, __LINE__);
+ fw_update_complete = true;
+ }
+ } else if ((buf[1] == '2') && (buf[2] == '8')) {
+ if (fts_ctpm_fw_upgrade_with_sys_fs_128k
+ (private_ts->client, (unsigned char *)fw->data,
+ fw->size, false) == 0) {
+ E("%s: TP upgrade error, line: %d\n",
+ __func__, __LINE__);
+ fw_update_complete = false;
+ } else {
+ I("%s: TP upgrade OK, line: %d\n",
+ __func__, __LINE__);
+ fw_update_complete = true;
+ }
+ } else {
+ E("%s: Flash command fail: %d\n",
+ __func__, __LINE__);
+ fw_update_complete = false;
+ }
+ release_firmware(fw);
+ goto firmware_upgrade_done;
+ /*return count;*/
+ }
+ }
+
+firmware_upgrade_done:
+
+#ifdef HX_RST_PIN_FUNC
+ himax_HW_reset(true, false);
+#endif
+
+ himax_sense_on(private_ts->client, 0x01);
+ msleep(120);
+#ifdef HX_ESD_WORKAROUND
+ HX_ESD_RESET_ACTIVATE = 1;
+#endif
+ himax_int_enable(private_ts->client->irq, 1);
+
+ /*todo himax_chip->tp_firmware_upgrade_proceed = 0;
+ todo himax_chip->suspend_state = 0;
+ todo enable_irq(himax_chip->irq);*/
+ return len;
+}
+
+const struct file_operations himax_proc_debug_ops = {
+ .owner = THIS_MODULE,
+ .read = himax_debug_read,
+ .write = himax_debug_write,
+};
+
+#endif
+
+#ifdef HX_TP_PROC_FLASH_DUMP
+
+static uint8_t getFlashCommand(void)
+{
+ return flash_command;
+}
+
+static uint8_t getFlashDumpProgress(void)
+{
+ return flash_progress;
+}
+
+static uint8_t getFlashDumpComplete(void)
+{
+ return flash_dump_complete;
+}
+
+static uint8_t getFlashDumpFail(void)
+{
+ return flash_dump_fail;
+}
+
+uint8_t getSysOperation(void)
+{
+ return sys_operation;
+}
+
+static uint8_t getFlashReadStep(void)
+{
+ return flash_read_step;
+}
+/*
+static uint8_t getFlashDumpSector(void)
+{
+ return flash_dump_sector;
+}
+
+static uint8_t getFlashDumpPage(void)
+{
+ return flash_dump_page;
+}
+*/
+bool getFlashDumpGoing(void)
+{
+ return flash_dump_going;
+}
+
+void setFlashBuffer(void)
+{
+ flash_buffer = kzalloc
+ (Flash_Size * sizeof(uint8_t), GFP_KERNEL);
+ memset(flash_buffer, 0x00, Flash_Size);
+}
+
+void setSysOperation(uint8_t operation)
+{
+ sys_operation = operation;
+}
+
+static void setFlashDumpProgress(uint8_t progress)
+{
+ flash_progress = progress;
+ /*I("setFlashDumpProgress : progress = %d ,
+ flash_progress = %d\n",progress,flash_progress);*/
+}
+
+static void setFlashDumpComplete(uint8_t status)
+{
+ flash_dump_complete = status;
+}
+
+static void setFlashDumpFail(uint8_t fail)
+{
+ flash_dump_fail = fail;
+}
+
+static void setFlashCommand(uint8_t command)
+{
+ flash_command = command;
+}
+
+static void setFlashReadStep(uint8_t step)
+{
+ flash_read_step = step;
+}
+
+static void setFlashDumpSector(uint8_t sector)
+{
+ flash_dump_sector = sector;
+}
+
+static void setFlashDumpPage(uint8_t page)
+{
+ flash_dump_page = page;
+}
+
+static void setFlashDumpGoing(bool going)
+{
+ flash_dump_going = going;
+}
+
+static ssize_t himax_proc_flash_read(struct file *file, char *buf,
+ size_t len, loff_t *pos)
+{
+ int ret = 0;
+ int loop_i;
+ uint8_t local_flash_read_step = 0;
+ uint8_t local_flash_complete = 0;
+ uint8_t local_flash_progress = 0;
+ uint8_t local_flash_command = 0;
+ uint8_t local_flash_fail = 0;
+ char *temp_buf;
+
+ local_flash_complete = getFlashDumpComplete();
+ local_flash_progress = getFlashDumpProgress();
+ local_flash_command = getFlashCommand();
+ local_flash_fail = getFlashDumpFail();
+
+ I("flash_progress = %d\n", local_flash_progress);
+ if (!HX_PROC_SEND_FLAG) {
+ temp_buf = kzalloc(len, GFP_KERNEL);
+ if (local_flash_fail) {
+ ret += snprintf(temp_buf + ret, len,
+ "FlashStart:Fail\n");
+ ret += snprintf(temp_buf + ret, len,
+ "FlashEnd");
+ ret += snprintf(temp_buf + ret, len,
+ "\n");
+
+ if (copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n", __func__, __LINE__);
+
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG = 1;
+ return ret;
+ }
+
+ if (!local_flash_complete) {
+ ret += snprintf(temp_buf+ret, len,
+ "FlashStart:Ongoing:0x%2.2x\n", flash_progress);
+ ret += snprintf(temp_buf + ret, len, "FlashEnd");
+ ret += snprintf(temp_buf + ret, len, "\n");
+
+ if (copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n", __func__, __LINE__);
+
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG = 1;
+ return ret;
+ }
+
+ if (local_flash_command == 1 && local_flash_complete) {
+ ret += snprintf(temp_buf+ret, len,
+ "FlashStart:Complete\n");
+ ret += snprintf(temp_buf + ret, len, "FlashEnd");
+ ret += snprintf(temp_buf + ret, len, "\n");
+
+ if (copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n", __func__, __LINE__);
+
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG = 1;
+ return ret;
+ }
+
+ if (local_flash_command == 3 && local_flash_complete) {
+ ret += snprintf(temp_buf+ret, len, "FlashStart:\n");
+ for (loop_i = 0 ; loop_i < 128 ; loop_i++) {
+ ret += snprintf(temp_buf + ret, len,
+ "x%2.2x", flash_buffer[loop_i]);
+ if ((loop_i % 16) == 15)
+ ret += snprintf(temp_buf + ret, len,
+ "\n");
+ }
+ ret += snprintf(temp_buf + ret, len, "FlashEnd");
+ ret += snprintf(temp_buf + ret, len, "\n");
+
+ if (copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n", __func__, __LINE__);
+
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG = 1;
+ return ret;
+ }
+
+ /*flash command == 0 , report the data*/
+ local_flash_read_step = getFlashReadStep();
+
+ ret += snprintf(temp_buf + ret, len,
+ "FlashStart:%2.2x\n", local_flash_read_step);
+
+ for (loop_i = 0 ; loop_i < 1024 ; loop_i++) {
+ ret += snprintf(temp_buf + ret, len, "x%2.2X",
+ flash_buffer[local_flash_read_step * 1024 + loop_i]);
+
+ if ((loop_i % 16) == 15)
+ ret += snprintf(temp_buf + ret, len, "\n");
+ }
+
+ ret += snprintf(temp_buf + ret, len, "FlashEnd");
+ ret += snprintf(temp_buf + ret, len, "\n");
+ if (copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n", __func__, __LINE__);
+
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG = 1;
+ } else
+ HX_PROC_SEND_FLAG = 0;
+ return ret;
+}
+
+static ssize_t himax_proc_flash_write(struct file *file,
+const char *buff, size_t len, loff_t *pos)
+{
+ char buf_tmp[6];
+ unsigned long result = 0;
+ uint8_t loop_i = 0;
+ int base = 0;
+ char buf[80] = {0};
+
+ if (len >= 80) {
+ I("%s: no command exceeds 80 chars.\n", __func__);
+ return -EFAULT;
+ }
+ if (copy_from_user(buf, buff, len))
+ return -EFAULT;
+ memset(buf_tmp, 0x0, sizeof(buf_tmp));
+
+ I("%s: buf[0] = %s\n", __func__, buf);
+
+ if (getSysOperation() == 1) {
+ E("%s: PROC is busy , return!\n", __func__);
+ return len;
+ }
+
+ if (buf[0] == '0') {
+ setFlashCommand(0);
+ if (buf[1] == ':' && buf[2] == 'x') {
+ memcpy(buf_tmp, buf + 3, 2);
+ I("%s: read_Step = %s\n", __func__, buf_tmp);
+ if (!kstrtoul(buf_tmp, 16, &result)) {
+ I("%s: read_Step = %lu\n", __func__, result);
+ setFlashReadStep(result);
+ }
+ }
+ /* 1_60,1_64,1_24,1_28 for flash size 60k,64k,124k,128k*/
+ } else if (buf[0] == '1') {
+
+ setSysOperation(1);
+ setFlashCommand(1);
+ setFlashDumpProgress(0);
+ setFlashDumpComplete(0);
+ setFlashDumpFail(0);
+ if ((buf[1] == '_') && (buf[2] == '6')) {
+ if (buf[3] == '0')
+ Flash_Size = FW_SIZE_60k;
+ else if (buf[3] == '4')
+ Flash_Size = FW_SIZE_64k;
+
+ } else if ((buf[1] == '_') && (buf[2] == '2')) {
+ if (buf[3] == '4')
+ Flash_Size = FW_SIZE_124k;
+ else if (buf[3] == '8')
+ Flash_Size = FW_SIZE_128k;
+ }
+ queue_work(private_ts->flash_wq, &private_ts->flash_work);
+ /* 2_60,2_64,2_24,2_28 for flash size 60k,64k,124k,128k*/
+ } else if (buf[0] == '2') {
+ setSysOperation(1);
+ setFlashCommand(2);
+ setFlashDumpProgress(0);
+ setFlashDumpComplete(0);
+ setFlashDumpFail(0);
+ if ((buf[1] == '_') && (buf[2] == '6')) {
+ if (buf[3] == '0')
+ Flash_Size = FW_SIZE_60k;
+ else if (buf[3] == '4')
+ Flash_Size = FW_SIZE_64k;
+
+ } else if ((buf[1] == '_') && (buf[2] == '2')) {
+ if (buf[3] == '4')
+ Flash_Size = FW_SIZE_124k;
+ else if (buf[3] == '8')
+ Flash_Size = FW_SIZE_128k;
+
+ }
+ queue_work(private_ts->flash_wq, &private_ts->flash_work);
+ } else if (buf[0] == '3') {
+ setSysOperation(1);
+ setFlashCommand(3);
+ setFlashDumpProgress(0);
+ setFlashDumpComplete(0);
+ setFlashDumpFail(0);
+
+ memcpy(buf_tmp, buf + 3, 2);
+ if (!kstrtoul(buf_tmp, 16, &result))
+ setFlashDumpSector(result);
+
+ memcpy(buf_tmp, buf + 7, 2);
+ if (!kstrtoul(buf_tmp, 16, &result))
+ setFlashDumpPage(result);
+
+ queue_work(private_ts->flash_wq, &private_ts->flash_work);
+ } else if (buf[0] == '4') {
+ I("%s: command 4 enter.\n", __func__);
+ setSysOperation(1);
+ setFlashCommand(4);
+ setFlashDumpProgress(0);
+ setFlashDumpComplete(0);
+ setFlashDumpFail(0);
+
+ memcpy(buf_tmp, buf + 3, 2);
+ if (!kstrtoul(buf_tmp, 16, &result))
+ setFlashDumpSector(result);
+ else
+ E("%s: command 4 , sector error.\n", __func__);
+ return len;
+
+
+ memcpy(buf_tmp, buf + 7, 2);
+ if (!kstrtoul(buf_tmp, 16, &result))
+ setFlashDumpPage(result);
+ else
+ E("%s: command 4 , page error.\n", __func__);
+ return len;
+
+ base = 11;
+
+ I("=========Himax flash page buffer start=========\n");
+ for (loop_i = 0 ; loop_i < 128 ; loop_i++) {
+ memcpy(buf_tmp, buf + base, 2);
+ if (!kstrtoul(buf_tmp, 16, &result)) {
+ flash_buffer[loop_i] = result;
+ I("%d ", flash_buffer[loop_i]);
+ if (loop_i % 16 == 15)
+ I("\n");
+ }
+ base += 3;
+ }
+ I("=========Himax flash page buffer end=========\n");
+
+ queue_work(private_ts->flash_wq, &private_ts->flash_work);
+ }
+ return len;
+}
+
+const struct file_operations himax_proc_flash_ops = {
+ .owner = THIS_MODULE,
+ .read = himax_proc_flash_read,
+ .write = himax_proc_flash_write,
+};
+
+void himax_ts_flash_func(void)
+{
+ uint8_t local_flash_command = 0;
+
+ himax_int_enable(private_ts->client->irq, 0);
+ setFlashDumpGoing(true);
+
+ /*sector = getFlashDumpSector();*/
+ /*page = getFlashDumpPage();*/
+
+ local_flash_command = getFlashCommand();
+
+ msleep(100);
+
+ I("%s: local_flash_command = %d enter.\n",
+ __func__, local_flash_command);
+
+ if ((local_flash_command == 1 || local_flash_command == 2)
+ || (local_flash_command == 0x0F)) {
+ himax_flash_dump_func(private_ts->client,
+ local_flash_command, Flash_Size, flash_buffer);
+ }
+
+
+ I("Complete~~~~~~~~~~~~~~~~~~~~~~~\n");
+
+ if (local_flash_command == 2) {
+ struct file *fn;
+ struct filename *vts_name;
+
+ vts_name = getname_kernel(FLASH_DUMP_FILE);
+ fn = file_open_name(vts_name, O_CREAT | O_WRONLY, 0);
+ if (!IS_ERR(fn)) {
+ I("%s create file and ready to write\n", __func__);
+ fn->f_op->write(fn, flash_buffer,
+ Flash_Size * sizeof(uint8_t), &fn->f_pos);
+
+ filp_close(fn, NULL);
+ }
+ }
+
+ himax_int_enable(private_ts->client->irq, 1);
+ setFlashDumpGoing(false);
+
+ setFlashDumpComplete(1);
+ setSysOperation(0);
+ return;
+
+/* Flash_Dump_i2c_transfer_error:
+
+ himax_int_enable(private_ts->client->irq, 1);
+ setFlashDumpGoing(false);
+ setFlashDumpComplete(0);
+ setFlashDumpFail(1);
+ setSysOperation(0);
+ return;
+*/
+}
+
+#endif
+
+#ifdef HX_TP_PROC_SELF_TEST
+static ssize_t himax_self_test_read(struct file *file, char *buf,
+ size_t len, loff_t *pos)
+{
+ int val = 0x00;
+ int ret = 0;
+ char *temp_buf;
+
+ I("%s:enter, %d\n", __func__, __LINE__);
+ if (!HX_PROC_SEND_FLAG) {
+ temp_buf = kzalloc(len, GFP_KERNEL);
+ himax_int_enable(private_ts->client->irq, 0);/*disable irq*/
+ val = himax_chip_self_test(private_ts->client);
+#ifdef HX_ESD_WORKAROUND
+ HX_ESD_RESET_ACTIVATE = 1;
+#endif
+ himax_int_enable(private_ts->client->irq, 1);/*enable irq*/
+
+ if (val == 0x01) {
+ ret += snprintf(temp_buf + ret, len,
+ "Self_Test Pass\n");
+ } else {
+ ret += snprintf(temp_buf + ret, len,
+ "Self_Test Fail\n");
+ }
+ if (copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n", __func__, __LINE__);
+
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG = 1;
+ } else
+ HX_PROC_SEND_FLAG = 0;
+ return ret;
+}
+
+/*
+static ssize_t himax_chip_self_test_store(struct device *dev,
+struct device_attribute *attr, const char *buf, size_t count)
+{
+ char buf_tmp[2];
+ unsigned long result = 0;
+
+ memset(buf_tmp, 0x0, sizeof(buf_tmp));
+ memcpy(buf_tmp, buf, 2);
+ if (!kstrtoul(buf_tmp, 16, &result))
+ {
+ sel_type = (uint8_t)result;
+ }
+ I("sel_type = %x \r\n", sel_type);
+ return count;
+}
+*/
+
+const struct file_operations himax_proc_self_test_ops = {
+ .owner = THIS_MODULE,
+ .read = himax_self_test_read,
+};
+#endif
+
+#ifdef HX_TP_PROC_SENSE_ON_OFF
+static ssize_t himax_sense_on_off_write(struct file *file, const char *buff,
+ size_t len, loff_t *pos)
+{
+ char buf[80] = {0};
+
+ if (len >= 80) {
+ I("%s: no command exceeds 80 chars.\n", __func__);
+ return -EFAULT;
+ }
+ if (copy_from_user(buf, buff, len))
+ return -EFAULT;
+
+ if (buf[0] == '0') {
+ himax_sense_off(private_ts->client);
+ I("Sense off\n");
+ } else if (buf[0] == '1') {
+ if (buf[1] == '1') {
+ himax_sense_on(private_ts->client, 0x01);
+ I("Sense on re-map off, run flash\n");
+ } else if (buf[1] == '0') {
+ himax_sense_on(private_ts->client, 0x00);
+ I("Sense on re-map on, run sram\n");
+ } else {
+ I("Do nothing\n");
+ }
+ } else {
+ I("Do nothing\n");
+ }
+ return len;
+}
+
+const struct file_operations himax_proc_sense_on_off_ops = {
+ .owner = THIS_MODULE,
+ .write = himax_sense_on_off_write,
+};
+#endif
+
+#ifdef HX_HIGH_SENSE
+static ssize_t himax_HSEN_read(struct file *file, char *buf,
+ size_t len, loff_t *pos)
+{
+ struct himax_ts_data *ts = private_ts;
+ size_t count = 0;
+ char *temp_buf;
+
+ if (!HX_PROC_SEND_FLAG) {
+ temp_buf = kzalloc(len, GFP_KERNEL);
+ count = snprintf(temp_buf, len, "%d\n", ts->HSEN_enable);
+ HX_PROC_SEND_FLAG = 1;
+
+ if (copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n", __func__, __LINE__);
+
+
+ kfree(temp_buf);
+ } else
+ HX_PROC_SEND_FLAG = 0;
+ return count;
+}
+
+static ssize_t himax_HSEN_write(struct file *file, const char *buff,
+ size_t len, loff_t *pos)
+{
+ struct himax_ts_data *ts = private_ts;
+ char buf[80] = {0};
+
+
+ if (len >= 80) {
+ I("%s: no command exceeds 80 chars.\n", __func__);
+ return -EFAULT;
+ }
+ if (copy_from_user(buf, buff, len))
+ return -EFAULT;
+
+ if (buf[0] == '0')
+ ts->HSEN_enable = 0;
+ else if (buf[0] == '1')
+ ts->HSEN_enable = 1;
+ else
+ return -EINVAL;
+
+ himax_set_HSEN_func(ts->client, ts->HSEN_enable);
+
+ I("%s: HSEN_enable = %d.\n", __func__, ts->HSEN_enable);
+
+ return len;
+}
+
+const struct file_operations himax_proc_HSEN_ops = {
+ .owner = THIS_MODULE,
+ .read = himax_HSEN_read,
+ .write = himax_HSEN_write,
+};
+#endif
+
+#ifdef HX_SMART_WAKEUP
+static ssize_t himax_SMWP_read(struct file *file, char *buf,
+ size_t len, loff_t *pos)
+{
+ size_t count = 0;
+ struct himax_ts_data *ts = private_ts;
+ char *temp_buf;
+
+ if (!HX_PROC_SEND_FLAG) {
+ temp_buf = kzalloc(len, GFP_KERNEL);
+ count = snprintf(temp_buf, "%d\n", len, ts->SMWP_enable);
+
+ if (copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n", __func__, __LINE__);
+
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG = 1;
+ } else
+ HX_PROC_SEND_FLAG = 0;
+
+ return count;
+}
+
+static ssize_t himax_SMWP_write(struct file *file, const char *buff,
+ size_t len, loff_t *pos)
+{
+ struct himax_ts_data *ts = private_ts;
+ char buf[80] = {0};
+
+ if (len >= 80) {
+ I("%s: no command exceeds 80 chars.\n", __func__);
+ return -EFAULT;
+ }
+ if (copy_from_user(buf, buff, len))
+ return -EFAULT;
+
+ if (buf[0] == '0')
+ ts->SMWP_enable = 0;
+ else if (buf[0] == '1')
+ ts->SMWP_enable = 1;
+ else
+ return -EINVAL;
+
+ himax_set_SMWP_func(ts->client, ts->SMWP_enable);
+ HX_SMWP_EN = ts->SMWP_enable;
+ I("%s: SMART_WAKEUP_enable = %d.\n", __func__, HX_SMWP_EN);
+
+ return len;
+}
+
+const struct file_operations himax_proc_SMWP_ops = {
+ .owner = THIS_MODULE,
+ .read = himax_SMWP_read,
+ .write = himax_SMWP_write,
+};
+
+static ssize_t himax_GESTURE_read(struct file *file,
+char *buf, size_t len, loff_t *pos)
+{
+ struct himax_ts_data *ts = private_ts;
+ int i = 0;
+ int ret = 0;
+ char *temp_buf;
+
+ if (!HX_PROC_SEND_FLAG) {
+ temp_buf = kzalloc(len, GFP_KERNEL);
+ for (i = 0 ; i < 16 ; i++)
+ ret += snprintf(temp_buf + ret, len,
+ "ges_en[%d]=%d\n", i, ts->gesture_cust_en[i]);
+
+ HX_PROC_SEND_FLAG = 1;
+ if (copy_to_user(buf, temp_buf, len))
+ I("%s,here:%d\n", __func__, __LINE__);
+
+ kfree(temp_buf);
+ HX_PROC_SEND_FLAG = 1;
+ } else {
+ HX_PROC_SEND_FLAG = 0;
+ ret = 0;
+ }
+ return ret;
+}
+
+static ssize_t himax_GESTURE_write(struct file *file, const char *buff,
+ size_t len, loff_t *pos)
+{
+ struct himax_ts_data *ts = private_ts;
+ int i = 0;
+ char buf[80] = {0};
+
+ if (len >= 80) {
+ I("%s: no command exceeds 80 chars.\n", __func__);
+ return -EFAULT;
+ }
+ if (copy_from_user(buf, buff, len))
+ return -EFAULT;
+
+ I("himax_GESTURE_store= %s\n", buf);
+ for (i = 0 ; i < 16 ; i++) {
+ if (buf[i] == '0')
+ ts->gesture_cust_en[i] = 0;
+ else if (buf[i] == '1')
+ ts->gesture_cust_en[i] = 1;
+ else
+ ts->gesture_cust_en[i] = 0;
+ I("gesture en[%d]=%d\n", i, ts->gesture_cust_en[i]);
+ }
+ return len;
+}
+
+const struct file_operations himax_proc_Gesture_ops = {
+ .owner = THIS_MODULE,
+ .read = himax_GESTURE_read,
+ .write = himax_GESTURE_write,
+};
+#endif
+
+int himax_touch_proc_init(void)
+{
+ himax_touch_proc_dir = proc_mkdir(HIMAX_PROC_TOUCH_FOLDER, NULL);
+ if (himax_touch_proc_dir == NULL) {
+ E(" %s: himax_touch_proc_dir file create failed!\n", __func__);
+ return -ENOMEM;
+ }
+
+ himax_proc_debug_level_file = proc_create(HIMAX_PROC_DEBUG_LEVEL_FILE,
+ (S_IWUSR | S_IRUGO), himax_touch_proc_dir, &himax_proc_debug_level_ops);
+
+ if (himax_proc_debug_level_file == NULL) {
+ E(" %s: proc debug_level file create failed!\n", __func__);
+ goto fail_1;
+ }
+
+ himax_proc_vendor_file = proc_create(HIMAX_PROC_VENDOR_FILE,
+ (S_IRUGO), himax_touch_proc_dir, &himax_proc_vendor_ops);
+
+ if (himax_proc_vendor_file == NULL) {
+ E(" %s: proc vendor file create failed!\n", __func__);
+ goto fail_2;
+ }
+
+ himax_proc_attn_file = proc_create(HIMAX_PROC_ATTN_FILE,
+ (S_IRUGO), himax_touch_proc_dir, &himax_proc_attn_ops);
+
+ if (himax_proc_attn_file == NULL) {
+ E(" %s: proc attn file create failed!\n", __func__);
+ goto fail_3;
+ }
+
+ himax_proc_int_en_file = proc_create(HIMAX_PROC_INT_EN_FILE,
+ (S_IWUSR | S_IRUGO), himax_touch_proc_dir, &himax_proc_int_en_ops);
+
+ if (himax_proc_int_en_file == NULL) {
+ E(" %s: proc int en file create failed!\n", __func__);
+ goto fail_4;
+ }
+
+ himax_proc_layout_file = proc_create(HIMAX_PROC_LAYOUT_FILE,
+ (S_IWUSR | S_IRUGO), himax_touch_proc_dir, &himax_proc_layout_ops);
+
+ if (himax_proc_layout_file == NULL) {
+ E(" %s: proc layout file create failed!\n", __func__);
+ goto fail_5;
+ }
+
+#ifdef HX_TP_PROC_RESET
+ himax_proc_reset_file = proc_create(HIMAX_PROC_RESET_FILE,
+ (S_IWUSR), himax_touch_proc_dir, &himax_proc_reset_ops);
+
+ if (himax_proc_reset_file == NULL) {
+ E(" %s: proc reset file create failed!\n", __func__);
+ goto fail_6;
+ }
+#endif
+
+#ifdef HX_TP_PROC_DIAG
+ himax_proc_diag_file = proc_create(HIMAX_PROC_DIAG_FILE,
+ (S_IWUSR | S_IRUGO), himax_touch_proc_dir, &himax_proc_diag_ops);
+
+ if (himax_proc_diag_file == NULL) {
+ E(" %s: proc diag file create failed!\n", __func__);
+ goto fail_7;
+ }
+ himax_proc_diag_arrange_file = proc_create(HIMAX_PROC_DIAG_ARR_FILE,
+ (S_IWUSR | S_IRUGO),
+ himax_touch_proc_dir, &himax_proc_diag_arrange_ops);
+
+ if (himax_proc_diag_arrange_file == NULL) {
+ E(" %s: proc diag file create failed!\n", __func__);
+ goto fail_7_1;
+ }
+#endif
+
+#ifdef HX_TP_PROC_REGISTER
+ himax_proc_register_file = proc_create(HIMAX_PROC_REGISTER_FILE,
+ (S_IWUSR | S_IRUGO), himax_touch_proc_dir, &himax_proc_register_ops);
+
+ if (himax_proc_register_file == NULL) {
+ E(" %s: proc register file create failed!\n", __func__);
+ goto fail_8;
+ }
+#endif
+
+#ifdef HX_TP_PROC_DEBUG
+ himax_proc_debug_file = proc_create(HIMAX_PROC_DEBUG_FILE,
+ (S_IWUSR | S_IRUGO), himax_touch_proc_dir, &himax_proc_debug_ops);
+
+ if (himax_proc_debug_file == NULL) {
+ E(" %s: proc debug file create failed!\n", __func__);
+ goto fail_9;
+ }
+#endif
+
+#ifdef HX_TP_PROC_FLASH_DUMP
+ himax_proc_flash_dump_file = proc_create(HIMAX_PROC_FLASH_DUMP_FILE,
+ (S_IWUSR | S_IRUGO), himax_touch_proc_dir, &himax_proc_flash_ops);
+
+ if (himax_proc_flash_dump_file == NULL) {
+ E(" %s: proc flash dump file create failed!\n", __func__);
+ goto fail_10;
+ }
+#endif
+
+#ifdef HX_TP_PROC_SELF_TEST
+ himax_proc_self_test_file = proc_create(HIMAX_PROC_SELF_TEST_FILE,
+ (S_IRUGO), himax_touch_proc_dir, &himax_proc_self_test_ops);
+
+ if (himax_proc_self_test_file == NULL) {
+ E(" %s: proc self_test file create failed!\n", __func__);
+ goto fail_11;
+ }
+#endif
+
+#ifdef HX_HIGH_SENSE
+ himax_proc_HSEN_file = proc_create(HIMAX_PROC_HSEN_FILE,
+ (S_IWUSR | S_IRUGO | S_IWUGO),
+ himax_touch_proc_dir, &himax_proc_HSEN_ops);
+
+ if (himax_proc_HSEN_file == NULL) {
+ E(" %s: proc HSEN file create failed!\n", __func__);
+ goto fail_12;
+ }
+#endif
+
+#ifdef HX_SMART_WAKEUP
+ himax_proc_SMWP_file = proc_create(HIMAX_PROC_SMWP_FILE,
+ (S_IWUSR | S_IRUGO | S_IWUGO),
+ himax_touch_proc_dir, &himax_proc_SMWP_ops);
+
+ if (himax_proc_SMWP_file == NULL) {
+ E(" %s: proc SMWP file create failed!\n", __func__);
+ goto fail_13;
+ }
+
+ himax_proc_GESTURE_file = proc_create(HIMAX_PROC_GESTURE_FILE,
+ (S_IWUSR | S_IRUGO | S_IWUGO),
+ himax_touch_proc_dir, &himax_proc_Gesture_ops);
+
+ if (himax_proc_GESTURE_file == NULL) {
+ E(" %s: proc GESTURE file create failed!\n", __func__);
+ goto fail_14;
+ }
+#endif
+
+#ifdef HX_TP_PROC_SENSE_ON_OFF
+ himax_proc_SENSE_ON_OFF_file = proc_create(HIMAX_PROC_SENSE_ON_OFF_FILE,
+ (S_IWUSR | S_IRUGO | S_IWUGO),
+ himax_touch_proc_dir, &himax_proc_sense_on_off_ops);
+
+ if (himax_proc_SENSE_ON_OFF_file == NULL) {
+ E(" %s: proc SENSE_ON_OFF file create failed!\n", __func__);
+ goto fail_15;
+ }
+#endif
+
+ return 0;
+
+#ifdef HX_TP_PROC_SENSE_ON_OFF
+fail_15:
+#endif
+#ifdef HX_SMART_WAKEUP
+ remove_proc_entry(HIMAX_PROC_GESTURE_FILE, himax_touch_proc_dir);
+fail_14:
+ remove_proc_entry(HIMAX_PROC_SMWP_FILE, himax_touch_proc_dir);
+fail_13:
+#endif
+#ifdef HX_HIGH_SENSE
+ remove_proc_entry(HIMAX_PROC_HSEN_FILE, himax_touch_proc_dir);
+fail_12:
+#endif
+#ifdef HX_TP_PROC_SELF_TEST
+ remove_proc_entry(HIMAX_PROC_SELF_TEST_FILE, himax_touch_proc_dir);
+fail_11:
+#endif
+#ifdef HX_TP_PROC_FLASH_DUMP
+ remove_proc_entry(HIMAX_PROC_FLASH_DUMP_FILE, himax_touch_proc_dir);
+fail_10:
+#endif
+#ifdef HX_TP_PROC_DEBUG
+ remove_proc_entry(HIMAX_PROC_DEBUG_FILE, himax_touch_proc_dir);
+fail_9:
+#endif
+#ifdef HX_TP_PROC_REGISTER
+ remove_proc_entry(HIMAX_PROC_REGISTER_FILE, himax_touch_proc_dir);
+fail_8:
+#endif
+#ifdef HX_TP_PROC_DIAG
+ remove_proc_entry(HIMAX_PROC_DIAG_FILE, himax_touch_proc_dir);
+fail_7:
+ remove_proc_entry(HIMAX_PROC_DIAG_ARR_FILE, himax_touch_proc_dir);
+fail_7_1:
+#endif
+#ifdef HX_TP_PROC_RESET
+ remove_proc_entry(HIMAX_PROC_RESET_FILE, himax_touch_proc_dir);
+fail_6:
+#endif
+ remove_proc_entry(HIMAX_PROC_LAYOUT_FILE, himax_touch_proc_dir);
+fail_5: remove_proc_entry(HIMAX_PROC_INT_EN_FILE, himax_touch_proc_dir);
+fail_4: remove_proc_entry(HIMAX_PROC_ATTN_FILE, himax_touch_proc_dir);
+fail_3: remove_proc_entry(HIMAX_PROC_VENDOR_FILE, himax_touch_proc_dir);
+fail_2: remove_proc_entry(HIMAX_PROC_DEBUG_LEVEL_FILE, himax_touch_proc_dir);
+fail_1: remove_proc_entry(HIMAX_PROC_TOUCH_FOLDER, NULL);
+ return -ENOMEM;
+}
+
+void himax_touch_proc_deinit(void)
+{
+#ifdef HX_TP_PROC_SENSE_ON_OFF
+ remove_proc_entry(HIMAX_PROC_SENSE_ON_OFF_FILE, himax_touch_proc_dir);
+#endif
+#ifdef HX_SMART_WAKEUP
+ remove_proc_entry(HIMAX_PROC_GESTURE_FILE, himax_touch_proc_dir);
+ remove_proc_entry(HIMAX_PROC_SMWP_FILE, himax_touch_proc_dir);
+#endif
+#ifdef HX_DOT_VIEW
+ remove_proc_entry(HIMAX_PROC_HSEN_FILE, himax_touch_proc_dir);
+#endif
+#ifdef HX_TP_PROC_SELF_TEST
+ remove_proc_entry(HIMAX_PROC_SELF_TEST_FILE, himax_touch_proc_dir);
+#endif
+#ifdef HX_TP_PROC_FLASH_DUMP
+ remove_proc_entry(HIMAX_PROC_FLASH_DUMP_FILE, himax_touch_proc_dir);
+#endif
+#ifdef HX_TP_PROC_DEBUG
+ remove_proc_entry(HIMAX_PROC_DEBUG_FILE, himax_touch_proc_dir);
+#endif
+#ifdef HX_TP_PROC_REGISTER
+ remove_proc_entry(HIMAX_PROC_REGISTER_FILE, himax_touch_proc_dir);
+#endif
+#ifdef HX_TP_PROC_DIAG
+ remove_proc_entry(HIMAX_PROC_DIAG_FILE, himax_touch_proc_dir);
+#endif
+#ifdef HX_TP_PROC_RESET
+ remove_proc_entry(HIMAX_PROC_RESET_FILE, himax_touch_proc_dir);
+#endif
+ remove_proc_entry(HIMAX_PROC_LAYOUT_FILE, himax_touch_proc_dir);
+ remove_proc_entry(HIMAX_PROC_INT_EN_FILE, himax_touch_proc_dir);
+ remove_proc_entry(HIMAX_PROC_ATTN_FILE, himax_touch_proc_dir);
+ remove_proc_entry(HIMAX_PROC_VENDOR_FILE, himax_touch_proc_dir);
+ remove_proc_entry(HIMAX_PROC_DEBUG_LEVEL_FILE, himax_touch_proc_dir);
+ remove_proc_entry(HIMAX_PROC_TOUCH_FOLDER, NULL);
+}
+#endif
diff --git a/drivers/input/touchscreen/hxchipset/himax_debug.h b/drivers/input/touchscreen/hxchipset/himax_debug.h
new file mode 100644
index 0000000..7a24a17
--- /dev/null
+++ b/drivers/input/touchscreen/hxchipset/himax_debug.h
@@ -0,0 +1,197 @@
+/* Himax Android Driver Sample Code for Himax chipset
+*
+* Copyright (C) 2015 Himax Corporation.
+*
+* This software is licensed under the terms of the GNU General Public
+* License version 2, as published by the Free Software Foundation, and
+* may be copied, distributed, and modified under those terms.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+*/
+
+#include "himax_platform.h"
+#include "himax_common.h"
+
+#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
+ #define HIMAX_PROC_TOUCH_FOLDER "android_touch"
+ #define HIMAX_PROC_DEBUG_LEVEL_FILE "debug_level"
+ #define HIMAX_PROC_VENDOR_FILE "vendor"
+ #define HIMAX_PROC_ATTN_FILE "attn"
+ #define HIMAX_PROC_INT_EN_FILE "int_en"
+ #define HIMAX_PROC_LAYOUT_FILE "layout"
+
+ static struct proc_dir_entry *himax_touch_proc_dir;
+ static struct proc_dir_entry *himax_proc_debug_level_file;
+ static struct proc_dir_entry *himax_proc_vendor_file;
+ static struct proc_dir_entry *himax_proc_attn_file;
+ static struct proc_dir_entry *himax_proc_int_en_file;
+ static struct proc_dir_entry *himax_proc_layout_file;
+
+ uint8_t HX_PROC_SEND_FLAG;
+
+ extern int himax_touch_proc_init(void);
+ extern void himax_touch_proc_deinit(void);
+ bool getFlashDumpGoing(void);
+
+ extern struct himax_ic_data *ic_data;
+ extern struct himax_ts_data *private_ts;
+ extern unsigned char IC_TYPE;
+ extern unsigned char IC_CHECKSUM;
+
+#ifdef QCT
+ extern irqreturn_t himax_ts_thread(int irq, void *ptr);
+#endif
+#ifdef MTK
+#ifdef CONFIG_OF_TOUCH
+ extern irqreturn_t tpd_eint_interrupt_handler(int irq, void *desc);
+#else
+ extern void tpd_eint_interrupt_handler(void);
+#endif
+#endif
+
+#ifdef HX_TP_PROC_REGISTER
+ #define HIMAX_PROC_REGISTER_FILE "register"
+ struct proc_dir_entry *himax_proc_register_file = NULL;
+ uint8_t register_command[4];
+#endif
+
+#ifdef HX_TP_PROC_DIAG
+ #define HIMAX_PROC_DIAG_FILE "diag"
+ struct proc_dir_entry *himax_proc_diag_file = NULL;
+ #define HIMAX_PROC_DIAG_ARR_FILE "diag_arr"
+ struct proc_dir_entry *himax_proc_diag_arrange_file = NULL;
+
+#ifdef HX_TP_PROC_2T2R
+ static bool Is_2T2R;
+ static uint8_t x_channel_2;
+ static uint8_t y_channel_2;
+ static uint8_t *diag_mutual_2;
+
+ int16_t *getMutualBuffer_2(void);
+ uint8_t getXChannel_2(void);
+ uint8_t getYChannel_2(void);
+
+ void setMutualBuffer_2(void);
+ void setXChannel_2(uint8_t x);
+ void setYChannel_2(uint8_t y);
+#endif
+ uint8_t x_channel = 0;
+ uint8_t y_channel = 0;
+ int16_t *diag_mutual = NULL;
+ int16_t *diag_mutual_new = NULL;
+ int16_t *diag_mutual_old = NULL;
+ uint8_t diag_max_cnt = 0;
+
+ int diag_command = 0;
+ uint8_t diag_coor[128];/* = {0xFF};*/
+ int16_t diag_self[100] = {0};
+
+ int16_t *getMutualBuffer(void);
+ int16_t *getMutualNewBuffer(void);
+ int16_t *getMutualOldBuffer(void);
+ int16_t *getSelfBuffer(void);
+ uint8_t getDiagCommand(void);
+ uint8_t getXChannel(void);
+ uint8_t getYChannel(void);
+
+ void setMutualBuffer(void);
+ void setMutualNewBuffer(void);
+ void setMutualOldBuffer(void);
+ void setXChannel(uint8_t x);
+ void setYChannel(uint8_t y);
+ uint8_t coordinate_dump_enable = 0;
+ struct file *coordinate_fn;
+#endif
+
+#ifdef HX_TP_PROC_DEBUG
+ #define HIMAX_PROC_DEBUG_FILE "debug"
+ struct proc_dir_entry *himax_proc_debug_file = NULL;
+
+ bool fw_update_complete = false;
+ int handshaking_result = 0;
+ unsigned char debug_level_cmd = 0;
+ unsigned char upgrade_fw[128*1024];
+#endif
+
+#ifdef HX_TP_PROC_FLASH_DUMP
+ #define HIMAX_PROC_FLASH_DUMP_FILE "flash_dump"
+ struct proc_dir_entry *himax_proc_flash_dump_file = NULL;
+
+ static int Flash_Size = 131072;
+ static uint8_t *flash_buffer;
+ static uint8_t flash_command;
+ static uint8_t flash_read_step;
+ static uint8_t flash_progress;
+ static uint8_t flash_dump_complete;
+ static uint8_t flash_dump_fail;
+ static uint8_t sys_operation;
+ static uint8_t flash_dump_sector;
+ static uint8_t flash_dump_page;
+ static bool flash_dump_going;
+
+ static uint8_t getFlashCommand(void);
+ static uint8_t getFlashDumpComplete(void);
+ static uint8_t getFlashDumpFail(void);
+ static uint8_t getFlashDumpProgress(void);
+ static uint8_t getFlashReadStep(void);
+ /*static uint8_t getFlashDumpSector(void);*/
+ /*static uint8_t getFlashDumpPage(void);*/
+
+ void setFlashBuffer(void);
+ uint8_t getSysOperation(void);
+
+ static void setFlashCommand(uint8_t command);
+ static void setFlashReadStep(uint8_t step);
+ static void setFlashDumpComplete(uint8_t complete);
+ static void setFlashDumpFail(uint8_t fail);
+ static void setFlashDumpProgress(uint8_t progress);
+ void setSysOperation(uint8_t operation);
+ static void setFlashDumpSector(uint8_t sector);
+ static void setFlashDumpPage(uint8_t page);
+ static void setFlashDumpGoing(bool going);
+
+#endif
+
+#ifdef HX_TP_PROC_SELF_TEST
+ #define HIMAX_PROC_SELF_TEST_FILE "self_test"
+ struct proc_dir_entry *himax_proc_self_test_file = NULL;
+ uint32_t **raw_data_array;
+ uint8_t X_NUM = 0, Y_NUM = 0;
+ uint8_t sel_type = 0x0D;
+#endif
+
+#ifdef HX_TP_PROC_RESET
+#define HIMAX_PROC_RESET_FILE "reset"
+extern void himax_HW_reset(uint8_t loadconfig, uint8_t int_off);
+struct proc_dir_entry *himax_proc_reset_file;
+#endif
+
+#ifdef HX_HIGH_SENSE
+ #define HIMAX_PROC_HSEN_FILE "HSEN"
+ struct proc_dir_entry *himax_proc_HSEN_file = NULL;
+#endif
+
+#ifdef HX_TP_PROC_SENSE_ON_OFF
+ #define HIMAX_PROC_SENSE_ON_OFF_FILE "SenseOnOff"
+ struct proc_dir_entry *himax_proc_SENSE_ON_OFF_file = NULL;
+#endif
+
+#ifdef HX_RST_PIN_FUNC
+ void himax_HW_reset(uint8_t loadconfig, uint8_t int_off);
+#endif
+
+#ifdef HX_SMART_WAKEUP
+#define HIMAX_PROC_SMWP_FILE "SMWP"
+struct proc_dir_entry *himax_proc_SMWP_file;
+#define HIMAX_PROC_GESTURE_FILE "GESTURE"
+struct proc_dir_entry *himax_proc_GESTURE_file;
+uint8_t HX_SMWP_EN;
+/*extern bool FAKE_POWER_KEY_SEND;*/
+#endif
+
+#endif
+
diff --git a/drivers/input/touchscreen/hxchipset/himax_ic.c b/drivers/input/touchscreen/hxchipset/himax_ic.c
new file mode 100644
index 0000000..e2934c2
--- /dev/null
+++ b/drivers/input/touchscreen/hxchipset/himax_ic.c
@@ -0,0 +1,2381 @@
+/* Himax Android Driver Sample Code for HMX83100 chipset
+*
+* Copyright (C) 2015 Himax Corporation.
+*
+* This software is licensed under the terms of the GNU General Public
+* License version 2, as published by the Free Software Foundation, and
+* may be copied, distributed, and modified under those terms.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+*/
+
+#include "himax_ic.h"
+
+const struct firmware *i_TP_CRC_FW_128K;
+const struct firmware *i_TP_CRC_FW_64K;
+const struct firmware *i_TP_CRC_FW_124K;
+const struct firmware *i_TP_CRC_FW_60K;
+
+unsigned long FW_VER_MAJ_FLASH_ADDR;
+unsigned long FW_VER_MAJ_FLASH_LENG;
+unsigned long FW_VER_MIN_FLASH_ADDR;
+unsigned long FW_VER_MIN_FLASH_LENG;
+unsigned long CFG_VER_MAJ_FLASH_ADDR;
+unsigned long CFG_VER_MAJ_FLASH_LENG;
+unsigned long CFG_VER_MIN_FLASH_ADDR;
+unsigned long CFG_VER_MIN_FLASH_LENG;
+
+unsigned char IC_TYPE;
+unsigned char IC_CHECKSUM;
+
+ /*0:Running, 1:Stop, 2:I2C Fail*/
+int himax_hand_shaking(struct i2c_client *client)
+{
+ int ret, result;
+ uint8_t hw_reset_check[1];
+ uint8_t hw_reset_check_2[1];
+ uint8_t buf0[2];
+ uint8_t IC_STATUS_CHECK = 0xAA;
+
+ memset(hw_reset_check, 0x00, sizeof(hw_reset_check));
+ memset(hw_reset_check_2, 0x00, sizeof(hw_reset_check_2));
+
+ buf0[0] = 0xF2;
+ if (IC_STATUS_CHECK == 0xAA) {
+ buf0[1] = 0xAA;
+ IC_STATUS_CHECK = 0x55;
+ } else {
+ buf0[1] = 0x55;
+ IC_STATUS_CHECK = 0xAA;
+ }
+
+ ret = i2c_himax_master_write(client,
+ buf0, 2, HIMAX_I2C_RETRY_TIMES);
+ if (ret < 0) {
+ E("[Himax]:write 0xF2 failed line: %d\n", __LINE__);
+ goto work_func_send_i2c_msg_fail;
+ }
+ msleep(50);
+
+ buf0[0] = 0xF2;
+ buf0[1] = 0x00;
+ ret = i2c_himax_master_write(client,
+ buf0, 2, HIMAX_I2C_RETRY_TIMES);
+ if (ret < 0) {
+ E("[Himax]:write 0x92 failed line: %d\n", __LINE__);
+ goto work_func_send_i2c_msg_fail;
+ }
+ usleep_range(1999, 2000);
+
+ ret = i2c_himax_read(client, 0xD1,
+ hw_reset_check, 1, HIMAX_I2C_RETRY_TIMES);
+ if (ret < 0) {
+ E("[Himax]:i2c_himax_read 0xD1 failed line: %d\n", __LINE__);
+ goto work_func_send_i2c_msg_fail;
+ }
+
+ if (IC_STATUS_CHECK != hw_reset_check[0]) {
+ usleep_range(1999, 2000);
+ ret = i2c_himax_read(client, 0xD1,
+ hw_reset_check_2, 1, HIMAX_I2C_RETRY_TIMES);
+ if (ret < 0) {
+ E("[Himax]:i2c_himax_read 0xD1 failed line: %d\n",
+ __LINE__);
+ goto work_func_send_i2c_msg_fail;
+ }
+
+ if (hw_reset_check[0] == hw_reset_check_2[0])
+ result = 1;
+ else
+ result = 0;
+
+ } else {
+ result = 0;
+ }
+
+ return result;
+
+work_func_send_i2c_msg_fail:
+ return 2;
+}
+
+void himax_diag_register_set(struct i2c_client *client, uint8_t diag_command)
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+
+ if (diag_command != 0)
+ diag_command = diag_command + 5;
+
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x02;
+ tmp_addr[1] = 0x01; tmp_addr[0] = 0x80;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = diag_command;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+}
+
+void himax_flash_dump_func(struct i2c_client *client,
+uint8_t local_flash_command, int Flash_Size, uint8_t *flash_buffer)
+{
+ /*struct himax_ts_data *ts =
+ container_of(work, struct himax_ts_data, flash_work);*/
+ /*uint8_t sector = 0;*/
+ /*uint8_t page = 0;*/
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+ uint8_t out_buffer[20];
+ uint8_t in_buffer[260];
+ int page_prog_start = 0;
+ int i = 0;
+
+ himax_sense_off(client);
+ himax_burst_enable(client, 0);
+ /*=============Dump Flash Start=============*/
+ /*=====================================*/
+ /* SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780*/
+ /*=====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x02;
+ tmp_data[1] = 0x07; tmp_data[0] = 0x80;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ for (page_prog_start = 0 ; page_prog_start < Flash_Size;
+ page_prog_start = page_prog_start + 256) {
+ /*=====================================
+ SPI Transfer Control
+ Set 256 bytes page read : 0x8000_0020 ==> 0x6940_02FF
+ Set read start address : 0x8000_0028 ==> 0x0000_0000
+ Set command : 0x8000_0024 ==> 0x0000_003B
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x69; tmp_data[2] = 0x40;
+ tmp_data[1] = 0x02; tmp_data[0] = 0xFF;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x28;
+ if (page_prog_start < 0x100) {
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = (uint8_t)page_prog_start;
+ } else if (page_prog_start >= 0x100
+ && page_prog_start < 0x10000) {
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = (uint8_t)(page_prog_start >> 8);
+ tmp_data[0] = (uint8_t)page_prog_start;
+ } else if (page_prog_start >= 0x10000
+ && page_prog_start < 0x1000000) {
+ tmp_data[3] = 0x00;
+ tmp_data[2] = (uint8_t)(page_prog_start >> 16);
+ tmp_data[1] = (uint8_t)(page_prog_start >> 8);
+ tmp_data[0] = (uint8_t)page_prog_start;
+ }
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x3B;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ /*=====================================
+ AHB_I2C Burst Read
+ Set SPI data register : 0x8000_002C ==> 0x00
+ =====================================*/
+ out_buffer[0] = 0x2C;
+ out_buffer[1] = 0x00;
+ out_buffer[2] = 0x00;
+ out_buffer[3] = 0x80;
+ i2c_himax_write(client, 0x00, out_buffer, 4, 3);
+
+ /*=====================================
+ Read access : 0x0C ==> 0x00
+ =====================================*/
+ out_buffer[0] = 0x00;
+ i2c_himax_write(client, 0x0C, out_buffer, 1, 3);
+
+ /*=====================================
+ Read 128 bytes two times
+ =====================================*/
+ i2c_himax_read(client, 0x08, in_buffer, 128, 3);
+ for (i = 0 ; i < 128 ; i++)
+ flash_buffer[i + page_prog_start]
+ = in_buffer[i];
+
+ i2c_himax_read(client, 0x08 , in_buffer, 128, 3);
+ for (i = 0 ; i < 128 ; i++)
+ flash_buffer[(i + 128) + page_prog_start]
+ = in_buffer[i];
+
+ I("%s:Verify Progress: %x\n", __func__, page_prog_start);
+ }
+
+/*=============Dump Flash End=============*/
+ /*//msleep(100);
+ for( i=0 ; i<8 ;i++)
+ {
+ for(j=0 ; j<64 ; j++)
+ {
+ setFlashDumpProgress(i*32 + j);
+ }
+ }
+ */
+ himax_sense_on(client, 0x01);
+
+ return;
+
+}
+
+int himax_chip_self_test(struct i2c_client *client)
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[128];
+ int pf_value = 0x00;
+ uint8_t test_result_id = 0;
+ int j;
+
+ memset(tmp_addr, 0x00, sizeof(tmp_addr));
+ memset(tmp_data, 0x00, sizeof(tmp_data));
+
+ himax_interface_on(client);
+ himax_sense_off(client);
+
+ /*Set criteria*/
+ himax_burst_enable(client, 1);
+
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x08;
+ tmp_addr[1] = 0x80; tmp_addr[0] = 0x94;
+ tmp_data[3] = 0x14; tmp_data[2] = 0xC8;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ tmp_data[7] = 0x13; tmp_data[6] = 0x60;
+ tmp_data[5] = 0x0A; tmp_data[4] = 0x99;
+
+ himax_flash_write_burst_length(client, tmp_addr, tmp_data, 8);
+
+ /*start selftest*/
+ /* 0x9008_805C ==> 0x0000_0001*/
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x08;
+ tmp_addr[1] = 0x80; tmp_addr[0] = 0x5C;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x01;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ himax_sense_on(client, 1);
+
+ msleep(2000);
+
+ himax_sense_off(client);
+ msleep(20);
+
+ /*=====================================
+ Read test result ID : 0x9008_8078 ==> 0xA/0xB/0xC/0xF
+ =====================================*/
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x08;
+ tmp_addr[1] = 0x80; tmp_addr[0] = 0x78;
+ himax_register_read(client, tmp_addr, 1, tmp_data);
+
+ test_result_id = tmp_data[0];
+
+ I("%s: check test result, test_result_id=%x, test_result=%x\n",
+ __func__ , test_result_id, tmp_data[0]);
+
+ if (test_result_id == 0xF) {
+ I("[Himax]: self-test pass\n");
+ pf_value = 0x1;
+ } else {
+ E("[Himax]: self-test fail\n");
+ pf_value = 0x0;
+ }
+ himax_burst_enable(client, 1);
+
+ for (j = 0 ; j < 10 ; j++) {
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x06;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x0C;
+ himax_register_read(client, tmp_addr, 1, tmp_data);
+ I("[Himax]: 9006000C = %d\n", tmp_data[0]);
+ if (tmp_data[0] != 0) {
+ tmp_data[3] = 0x90; tmp_data[2] = 0x06;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ if (i2c_himax_write(client, 0x00,
+ tmp_data, 4, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ }
+ tmp_data[0] = 0x00;
+ if (i2c_himax_write(client, 0x0C,
+ tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ }
+ i2c_himax_read(client, 0x08,
+ tmp_data, 124, HIMAX_I2C_RETRY_TIMES);
+ } else {
+ break;
+ }
+ }
+
+ himax_sense_on(client, 1);
+ msleep(120);
+
+ return pf_value;
+}
+
+void himax_set_HSEN_enable(struct i2c_client *client, uint8_t HSEN_enable)
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+
+ himax_burst_enable(client, 0);
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x08;
+ tmp_addr[1] = 0x80; tmp_addr[0] = 0x50;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = HSEN_enable;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+}
+void himax_get_HSEN_enable(struct i2c_client *client, uint8_t *tmp_data)
+{
+ uint8_t tmp_addr[4];
+
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x08;
+ tmp_addr[1] = 0x80; tmp_addr[0] = 0x50;
+ himax_register_read(client, tmp_addr, 1, tmp_data);
+}
+
+void himax_set_SMWP_enable(struct i2c_client *client, uint8_t SMWP_enable)
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x08;
+ tmp_addr[1] = 0x80; tmp_addr[0] = 0x54;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = SMWP_enable;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+}
+
+void himax_get_SMWP_enable(struct i2c_client *client,
+uint8_t *tmp_data)
+{
+ uint8_t tmp_addr[4];
+
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x08;
+ tmp_addr[1] = 0x80; tmp_addr[0] = 0x54;
+ himax_register_read(client, tmp_addr, 1, tmp_data);
+}
+
+int himax_burst_enable(struct i2c_client *client, uint8_t auto_add_4_byte)
+{
+ uint8_t tmp_data[4];
+ int err = -1;
+
+ tmp_data[0] = 0x31;
+
+ if (i2c_himax_write(client, 0x13,
+ tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return err;
+ }
+
+ tmp_data[0] = (0x10 | auto_add_4_byte);
+ if (i2c_himax_write(client, 0x0D,
+ tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return err;
+ }
+ return 0;
+
+}
+
+void himax_register_read(struct i2c_client *client,
+uint8_t *read_addr, int read_length, uint8_t *read_data)
+{
+ uint8_t tmp_data[4];
+ int i = 0;
+ int address = 0;
+
+ if (read_length > 256) {
+ E("%s: read len over 256!\n", __func__);
+ return;
+ }
+ if (read_length > 1)
+ himax_burst_enable(client, 1);
+ else
+ himax_burst_enable(client, 0);
+
+ address = (read_addr[3] << 24) +
+ (read_addr[2] << 16) +
+ (read_addr[1] << 8) +
+ read_addr[0];
+
+ i = address;
+ tmp_data[0] = (uint8_t)i;
+ tmp_data[1] = (uint8_t)(i >> 8);
+ tmp_data[2] = (uint8_t)(i >> 16);
+ tmp_data[3] = (uint8_t)(i >> 24);
+ if (i2c_himax_write(client, 0x00,
+ tmp_data, 4, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+ tmp_data[0] = 0x00;
+ if (i2c_himax_write(client, 0x0C,
+ tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+ if (i2c_himax_read(client, 0x08,
+ read_data, read_length * 4, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+ if (read_length > 1)
+ himax_burst_enable(client, 0);
+}
+
+void himax_flash_read(struct i2c_client *client,
+uint8_t *reg_byte, uint8_t *read_data)
+{
+ uint8_t tmpbyte[2];
+
+ if (i2c_himax_write(client, 0x00,
+ ®_byte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ if (i2c_himax_write(client, 0x01,
+ ®_byte[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ if (i2c_himax_write(client, 0x02,
+ ®_byte[2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ if (i2c_himax_write(client, 0x03,
+ ®_byte[3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ tmpbyte[0] = 0x00;
+ if (i2c_himax_write(client, 0x0C,
+ &tmpbyte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ if (i2c_himax_read(client, 0x08,
+ &read_data[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ if (i2c_himax_read(client, 0x09,
+ &read_data[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ if (i2c_himax_read(client, 0x0A,
+ &read_data[2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ if (i2c_himax_read(client, 0x0B,
+ &read_data[3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ if (i2c_himax_read(client, 0x18,
+ &tmpbyte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ } /* No bus request*/
+
+ if (i2c_himax_read(client, 0x0F,
+ &tmpbyte[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ } /* idle state*/
+
+}
+
+void himax_flash_write_burst(struct i2c_client *client,
+uint8_t *reg_byte, uint8_t *write_data)
+{
+ uint8_t data_byte[8];
+ int i = 0, j = 0;
+
+ for (i = 0 ; i < 4; i++)
+ data_byte[i] = reg_byte[i];
+
+ for (j = 4 ; j < 8; j++)
+ data_byte[j] = write_data[j-4];
+
+ if (i2c_himax_write(client, 0x00,
+ data_byte, 8, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+}
+
+int himax_flash_write_burst_length(struct i2c_client *client,
+uint8_t *reg_byte, uint8_t *write_data, int length)
+{
+ uint8_t data_byte[256];
+ int i = 0, j = 0, err = -1;
+
+ for (i = 0 ; i < 4 ; i++)
+ data_byte[i] = reg_byte[i];
+
+ for (j = 4 ; j < length + 4 ; j++)
+ data_byte[j] = write_data[j - 4];
+
+ if (i2c_himax_write(client, 0x00,
+ data_byte, length + 4, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return err;
+ }
+ return 0;
+}
+
+int himax_register_write(struct i2c_client *client,
+uint8_t *write_addr, int write_length, uint8_t *write_data)
+{
+ int i = 0, address = 0;
+ int ret = 0, err = -1;
+
+ address = (write_addr[3] << 24) +
+ (write_addr[2] << 16) +
+ (write_addr[1] << 8) +
+ write_addr[0];
+
+ for (i = address ; i < address + write_length * 4;
+ i = i + 4) {
+ if (write_length > 1) {
+ ret = himax_burst_enable(client, 1);
+ if (ret)
+ return err;
+ } else {
+ ret = himax_burst_enable(client, 0);
+ if (ret)
+ return err;
+ }
+ ret = himax_flash_write_burst_length(client,
+ write_addr, write_data, write_length * 4);
+ if (ret < 0)
+ return err;
+ }
+
+ return 0;
+}
+
+void himax_sense_off(struct i2c_client *client)
+{
+ uint8_t wdt_off = 0x00;
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[5];
+
+ himax_burst_enable(client, 0);
+
+ while (wdt_off == 0x00) {
+ /* 0x9000_800C ==> 0x0000_AC53*/
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x80; tmp_addr[0] = 0x0C;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0xAC; tmp_data[0] = 0x53;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ /*=====================================*/
+ /* Read Watch Dog disable password :
+ 0x9000_800C ==> 0x0000_AC53 */
+ /*=====================================*/
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x80; tmp_addr[0] = 0x0C;
+ himax_register_read(client, tmp_addr, 1, tmp_data);
+
+ /*Check WDT*/
+ if (tmp_data[0] == 0x53 && tmp_data[1] == 0xAC
+ && tmp_data[2] == 0x00 && tmp_data[3] == 0x00)
+ wdt_off = 0x01;
+ else
+ wdt_off = 0x00;
+ }
+
+ /* VCOM //0x9008_806C ==> 0x0000_0001*/
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x08;
+ tmp_addr[1] = 0x80; tmp_addr[0] = 0x6C;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x01;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ msleep(20);
+
+ /* 0x9000_0010 ==> 0x0000_00DA*/
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0xDA;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ /*=====================================
+ Read CPU clock off password : 0x9000_0010 ==> 0x0000_00DA
+ =====================================*/
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+ himax_register_read(client, tmp_addr, 1, tmp_data);
+ I("%s: CPU clock off password data[0]=%x",
+ __func__, tmp_data[0]);
+ I(" data[1]=%x data[2]=%x data[3]=%x\n",
+ tmp_data[1], tmp_data[2], tmp_data[3]);
+
+}
+
+void himax_interface_on(struct i2c_client *client)
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[5];
+
+ /*=====================================
+ Any Cmd for ineterface on : 0x9000_0000 ==> 0x0000_0000
+ =====================================*/
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x00;
+ himax_flash_read(client, tmp_addr, tmp_data); /*avoid RD/WR fail*/
+}
+
+bool wait_wip(struct i2c_client *client, int Timing)
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+ uint8_t in_buffer[10];
+ /*uint8_t out_buffer[20];*/
+ int retry_cnt = 0;
+
+ /*=====================================
+ SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x02;
+ tmp_data[1] = 0x07; tmp_data[0] = 0x80;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ in_buffer[0] = 0x01;
+
+ do {
+ /*=====================================
+ SPI Transfer Control : 0x8000_0020 ==> 0x4200_0003
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x42; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x03;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ /*=====================================
+ SPI Command : 0x8000_0024 ==> 0x0000_0005
+ read 0x8000_002C for 0x01, means wait success
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x05;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ in_buffer[0] = in_buffer[1] =
+ in_buffer[2] = in_buffer[3] = 0xFF;
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x2C;
+ himax_register_read(client, tmp_addr, 1, in_buffer);
+
+ if ((in_buffer[0] & 0x01) == 0x00)
+ return true;
+
+ retry_cnt++;
+
+ if (in_buffer[0] != 0x00 || in_buffer[1] != 0x00
+ || in_buffer[2] != 0x00 || in_buffer[3] != 0x00){
+ I("%s:Wait wip retry_cnt:%d, buffer[0]=%d, ",
+ __func__, retry_cnt, in_buffer[0]);
+ I("buffer[1]=%d, buffer[2]=%d, buffer[3]=%d\n",
+ in_buffer[1], in_buffer[2], in_buffer[3]);
+ }
+ if (retry_cnt > 100) {
+ E("%s: Wait wip error!\n", __func__);
+ return false;
+ }
+ msleep(Timing);
+ } while ((in_buffer[0] & 0x01) == 0x01);
+ return true;
+}
+
+void himax_sense_on(struct i2c_client *client, uint8_t FlashMode)
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[128];
+
+ himax_interface_on(client);
+ himax_burst_enable(client, 0);
+ /*CPU reset*/
+ /* 0x9000_0014 ==> 0x0000_00CA*/
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x14;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0xCA;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ /*=====================================
+ Read pull low CPU reset signal : 0x9000_0014 ==> 0x0000_00CA
+ =====================================*/
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x14;
+ himax_register_read(client, tmp_addr, 1, tmp_data);
+
+ I("%s: check pull low CPU reset signal data[0]=%x data[1]=%x ",
+ __func__, tmp_data[0], tmp_data[1]);
+ I("data[2]=%x data[3]=%x\n",
+ tmp_data[2], tmp_data[3]);
+
+ /* 0x9000_0014 ==> 0x0000_0000*/
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x14;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ /*=====================================
+ Read revert pull low CPU reset signal : 0x9000_0014 ==> 0x0000_0000
+ =====================================*/
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x14;
+ himax_register_read(client, tmp_addr, 1, tmp_data);
+
+ I("%s: revert pull low CPU reset signal data[0]=%x data[1]=%x ",
+ __func__, tmp_data[0], tmp_data[1]);
+ I("data[2]=%x data[3]=%x\n",
+ tmp_data[2], tmp_data[3]);
+
+ /*=====================================
+ Reset TCON
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x02;
+ tmp_addr[1] = 0x01; tmp_addr[0] = 0xE0;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+ usleep_range(9999, 10000);
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x02;
+ tmp_addr[1] = 0x01; tmp_addr[0] = 0xE0;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x01;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ if (FlashMode == 0x00) { /*SRAM*/
+ /*=====================================
+ Re-map
+ =====================================*/
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x00;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0xF1;
+ himax_flash_write_burst_length(client, tmp_addr, tmp_data, 4);
+ I("%s:83100_Chip_Re-map ON\n", __func__);
+ } else {
+ /*=====================================
+ Re-map off
+ =====================================*/
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x00;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ himax_flash_write_burst_length(client, tmp_addr, tmp_data, 4);
+ I("%s:83100_Chip_Re-map OFF\n", __func__);
+ }
+ /*=====================================
+ CPU clock on
+ =====================================*/
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ himax_flash_write_burst_length(client, tmp_addr, tmp_data, 4);
+
+}
+
+void himax_chip_erase(struct i2c_client *client)
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+
+ himax_burst_enable(client, 0);
+
+ /*=====================================
+ SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x02;
+ tmp_data[1] = 0x07; tmp_data[0] = 0x80;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ /*=====================================
+ Chip Erase
+ Write Enable :
+ 1. 0x8000_0020 ==> 0x4700_0000
+ 2. 0x8000_0024 ==> 0x0000_0006
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x47; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x06;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ /*=====================================
+ Chip Erase
+ Erase Command : 0x8000_0024 ==> 0x0000_00C7
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0xC7;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ msleep(2000);
+
+ if (!wait_wip(client, 100))
+ E("%s:83100_Chip_Erase Fail\n", __func__);
+
+}
+
+bool himax_block_erase(struct i2c_client *client)
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+
+ himax_burst_enable(client, 0);
+
+ /*=====================================
+ SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x02;
+ tmp_data[1] = 0x07; tmp_data[0] = 0x80;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ /*=====================================
+ Chip Erase
+ Write Enable :
+ 1. 0x8000_0020 ==> 0x4700_0000
+ 2. 0x8000_0024 ==> 0x0000_0006
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x47; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x06;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ /*=====================================
+ Block Erase
+ Erase Command :
+ 0x8000_0028 ==> 0x0000_0000 //SPI addr
+ 0x8000_0020 ==> 0x6700_0000 //control
+ 0x8000_0024 ==> 0x0000_0052 //BE
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x28;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x67; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x52;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ msleep(1000);
+
+ if (!wait_wip(client, 100)) {
+ E("%s:83100_Erase Fail\n", __func__);
+ return false;
+ } else {
+ return true;
+ }
+
+}
+
+bool himax_sector_erase(struct i2c_client *client, int start_addr)
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+ int page_prog_start = 0;
+
+ himax_burst_enable(client, 0);
+
+ /*=====================================
+ SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x02;
+ tmp_data[1] = 0x07; tmp_data[0] = 0x80;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+ for (page_prog_start = start_addr;
+ page_prog_start < start_addr + 0x0F000;
+ page_prog_start = page_prog_start + 0x1000) {
+ /*=====================================
+ Chip Erase
+ Write Enable :
+ 1. 0x8000_0020 ==> 0x4700_0000
+ 2. 0x8000_0024 ==> 0x0000_0006
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x47; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x06;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ /*=====================================
+ Sector Erase
+ Erase Command :
+ 0x8000_0028 ==> 0x0000_0000 //SPI addr
+ 0x8000_0020 ==> 0x6700_0000 //control
+ 0x8000_0024 ==> 0x0000_0020 //SE
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x28;
+ if (page_prog_start < 0x100) {
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = (uint8_t)page_prog_start;
+ } else if (page_prog_start >= 0x100
+ && page_prog_start < 0x10000) {
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = (uint8_t)(page_prog_start >> 8);
+ tmp_data[0] = (uint8_t)page_prog_start;
+ } else if (page_prog_start >= 0x10000
+ && page_prog_start < 0x1000000) {
+ tmp_data[3] = 0x00;
+ tmp_data[2] = (uint8_t)(page_prog_start >> 16);
+ tmp_data[1] = (uint8_t)(page_prog_start >> 8);
+ tmp_data[0] = (uint8_t)page_prog_start;
+ }
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x67; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x20;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ msleep(200);
+
+ if (!wait_wip(client, 100)) {
+ E("%s:83100_Erase Fail\n", __func__);
+ return false;
+ }
+ }
+ return true;
+}
+
+void himax_sram_write(struct i2c_client *client, uint8_t *FW_content)
+{
+ int i = 0;
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[64];
+ int FW_length = 0x4000; /* 0x4000 = 16K bin file */
+
+ /*himax_sense_off(client);*/
+
+ for (i = 0; i < FW_length; i = i + 64) {
+ himax_burst_enable(client, 1);
+
+ if (i < 0x100) {
+ tmp_addr[3] = 0x08;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
+ tmp_addr[0] = i;
+ } else if (i >= 0x100 && i < 0x10000) {
+ tmp_addr[3] = 0x08;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = (i >> 8);
+ tmp_addr[0] = i;
+ }
+
+ memcpy(&tmp_data[0], &FW_content[i], 64);
+ himax_flash_write_burst_length(client, tmp_addr, tmp_data, 64);
+
+ }
+
+ if (!wait_wip(client, 100))
+ E("%s:83100_Sram_Write Fail\n", __func__);
+}
+
+bool himax_sram_verify(struct i2c_client *client,
+uint8_t *FW_File, int FW_Size)
+{
+ int i = 0;
+ uint8_t out_buffer[20];
+ uint8_t in_buffer[128];
+ uint8_t *get_fw_content;
+
+ get_fw_content = kzalloc(0x4000 * sizeof(uint8_t), GFP_KERNEL);
+
+ for (i = 0 ; i < 0x4000 ; i = i + 128) {
+ himax_burst_enable(client, 1);
+
+ /*=====================================
+ AHB_I2C Burst Read
+ =====================================*/
+ if (i < 0x100) {
+ out_buffer[3] = 0x08;
+ out_buffer[2] = 0x00;
+ out_buffer[1] = 0x00;
+ out_buffer[0] = i;
+ } else if (i >= 0x100 && i < 0x10000) {
+ out_buffer[3] = 0x08;
+ out_buffer[2] = 0x00;
+ out_buffer[1] = (i >> 8);
+ out_buffer[0] = i;
+ }
+
+ if (i2c_himax_write(client, 0x00, out_buffer,
+ 4, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return false;
+ }
+
+ out_buffer[0] = 0x00;
+ if (i2c_himax_write(client, 0x0C, out_buffer,
+ 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return false;
+ }
+
+ if (i2c_himax_read(client, 0x08, in_buffer,
+ 128, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return false;
+ }
+ memcpy(&get_fw_content[i], &in_buffer[0], 128);
+ }
+
+ for (i = 0 ; i < FW_Size ; i++) {
+ if (FW_File[i] != get_fw_content[i]) {
+ E("%s: fail! SRAM[%x]=%x NOT CRC_ifile=%x\n",
+ __func__, i, get_fw_content[i], FW_File[i]);
+ return false;
+ }
+ }
+
+ kfree(get_fw_content);
+
+ return true;
+}
+
+void himax_flash_programming(struct i2c_client *client,
+uint8_t *FW_content, int FW_Size)
+{
+ int page_prog_start = 0;
+ int program_length = 48;
+ int i = 0, j = 0, k = 0;
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+ /* // Read for flash data, 128K //4 bytes for 0x80002C padding */
+ uint8_t buring_data[256];
+
+ /*himax_interface_on(client);*/
+ himax_burst_enable(client, 0);
+
+ /*=====================================
+ SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x02;
+ tmp_data[1] = 0x07; tmp_data[0] = 0x80;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ for (page_prog_start = 0 ; page_prog_start < FW_Size;
+ page_prog_start = page_prog_start + 256) {
+ /*msleep(5);*/
+ /*=====================================
+ Write Enable :
+ 1. 0x8000_0020 ==> 0x4700_0000
+ 2. 0x8000_0024 ==> 0x0000_0006
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x47; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x06;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ /*=====================================
+ SPI Transfer Control
+ Set 256 bytes page write : 0x8000_0020 ==> 0x610F_F000
+ Set read start address : 0x8000_0028 ==> 0x0000_0000
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x61; tmp_data[2] = 0x0F;
+ tmp_data[1] = 0xF0; tmp_data[0] = 0x00;
+ /*data bytes should be 0x6100_0000 +
+ ((word_number)*4-1)*4096 = 0x6100_0000 +
+ 0xFF000 = 0x610F_F000
+ Programmable size = 1 page = 256 bytes,
+ word_number = 256 byte / 4 = 64*/
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x28;
+ /* tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ // Flash start address 1st : 0x0000_0000 */
+
+ if (page_prog_start < 0x100) {
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = (uint8_t)page_prog_start;
+ } else if (page_prog_start >= 0x100
+ && page_prog_start < 0x10000) {
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = (uint8_t)(page_prog_start >> 8);
+ tmp_data[0] = (uint8_t)page_prog_start;
+ } else if (page_prog_start >= 0x10000
+ && page_prog_start < 0x1000000) {
+ tmp_data[3] = 0x00;
+ tmp_data[2] = (uint8_t)(page_prog_start >> 16);
+ tmp_data[1] = (uint8_t)(page_prog_start >> 8);
+ tmp_data[0] = (uint8_t)page_prog_start;
+ }
+
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ /*=====================================
+ Send 16 bytes data : 0x8000_002C ==> 16 bytes data
+ =====================================*/
+ buring_data[0] = 0x2C;
+ buring_data[1] = 0x00;
+ buring_data[2] = 0x00;
+ buring_data[3] = 0x80;
+
+ for (i = /*0*/page_prog_start, j = 0;
+ i < 16 + page_prog_start/**/;
+ i++, j++) { /* <------ bin file*/
+
+ buring_data[j + 4] = FW_content[i];
+ }
+
+ if (i2c_himax_write(client, 0x00, buring_data,
+ 20, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+ /*=====================================
+ Write command : 0x8000_0024 ==> 0x0000_0002
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x02;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ /*=====================================
+ Send 240 bytes data : 0x8000_002C ==> 240 bytes data
+ =====================================*/
+
+ for (j = 0; j < 5; j++) {
+ for (i = (page_prog_start + 16 + (j * 48)), k = 0;
+ i < (page_prog_start + 16 + (j * 48)) + program_length;
+ i++, k++) { /*<------ bin file*/
+ buring_data[k+4] = FW_content[i];/*(byte)i;*/
+ }
+
+ if (i2c_himax_write(client, 0x00, buring_data,
+ program_length + 4,
+ HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ }
+
+ if (!wait_wip(client, 1))
+ E("%s:83100_Flash_Programming Fail\n", __func__);
+ }
+}
+
+bool himax_check_chip_version(struct i2c_client *client)
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+ uint8_t ret_data = 0x00;
+ int i = 0;
+ int ret = 0;
+
+ himax_sense_off(client);
+
+ for (i = 0 ; i < 5 ; i++) {
+ /* 1. Set DDREG_Req = 1 (0x9000_0020 = 0x0000_0001)
+ (Lock register R/W from driver) */
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x01;
+ ret = himax_register_write(client, tmp_addr, 1, tmp_data);
+ if (ret)
+ return false;
+
+ /* 2. Set bank as 0 (0x8001_BD01 = 0x0000_0000)*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x01;
+ tmp_addr[1] = 0xBD; tmp_addr[0] = 0x01;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ ret = himax_register_write(client, tmp_addr, 1, tmp_data);
+ if (ret)
+ return false;
+
+ /* 3. Read driver ID register RF4H 1 byte (0x8001_F401)
+ // Driver register RF4H 1 byte value = 0x84H,
+ read back value will become 0x84848484 */
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x01;
+ tmp_addr[1] = 0xF4; tmp_addr[0] = 0x01;
+ himax_register_read(client, tmp_addr, 1, tmp_data);
+ ret_data = tmp_data[0];
+
+ I("%s:Read driver IC ID = %X\n", __func__, ret_data);
+ if (ret_data == 0x84) {
+ IC_TYPE = HX_83100_SERIES_PWON;
+ /*himax_sense_on(client, 0x01);*/
+ ret_data = true;
+ break;
+
+ } else {
+ ret_data = false;
+ E("%s:Read driver ID register Fail:\n", __func__);
+ }
+ }
+ /* 4. After read finish, set DDREG_Req = 0
+ (0x9000_0020 = 0x0000_0000) (Unlock register R/W from driver)*/
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ himax_register_write(client, tmp_addr, 1, tmp_data);
+ /*himax_sense_on(client, 0x01);*/
+ return ret_data;
+}
+
+/*#if 1*/
+int himax_check_CRC(struct i2c_client *client, int mode)
+{
+ bool burnFW_success = false;
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+ int tmp_value;
+ int CRC_value = 0;
+
+ memset(tmp_data, 0x00, sizeof(tmp_data));
+ if (i_TP_CRC_FW_60K == NULL) {
+ I("%s: i_TP_CRC_FW_60K = NULL\n", __func__);
+ return 0;
+ } else if (i_TP_CRC_FW_64K == NULL) {
+ I("%s: i_TP_CRC_FW_64K = NULL\n", __func__);
+ return 0;
+ } else if (i_TP_CRC_FW_124K == NULL) {
+ I("%s: i_TP_CRC_FW_124K = NULL\n", __func__);
+ return 0;
+ } else if (i_TP_CRC_FW_128K == NULL) {
+ I("%s: i_TP_CRC_FW_128K = NULL\n", __func__);
+ return 0;
+ }
+
+ if (1) {
+ if (mode == fw_image_60k) {
+ himax_sram_write(client,
+ (unsigned char *)i_TP_CRC_FW_60K->data);
+ burnFW_success = himax_sram_verify(client,
+ (unsigned char *)i_TP_CRC_FW_60K->data, 0x4000);
+ } else if (mode == fw_image_64k) {
+ himax_sram_write(client,
+ (unsigned char *)i_TP_CRC_FW_64K->data);
+ burnFW_success = himax_sram_verify(client,
+ (unsigned char *)i_TP_CRC_FW_64K->data, 0x4000);
+ } else if (mode == fw_image_124k) {
+ himax_sram_write(client,
+ (unsigned char *)i_TP_CRC_FW_124K->data);
+ burnFW_success = himax_sram_verify(client,
+ (unsigned char *)i_TP_CRC_FW_124K->data, 0x4000);
+ } else if (mode == fw_image_128k) {
+ himax_sram_write(client,
+ (unsigned char *)i_TP_CRC_FW_128K->data);
+ burnFW_success = himax_sram_verify(client,
+ (unsigned char *)i_TP_CRC_FW_128K->data, 0x4000);
+ }
+ if (burnFW_success) {
+ I("%s: Start to do CRC FW mode=%d\n", __func__, mode);
+ himax_sense_on(client, 0x00); /* run CRC firmware*/
+
+ while (true) {
+ msleep(100);
+ tmp_addr[3] = 0x90;
+ tmp_addr[2] = 0x08;
+ tmp_addr[1] = 0x80;
+ tmp_addr[0] = 0x94;
+ himax_register_read(client,
+ tmp_addr, 1, tmp_data);
+
+ I("%s: CRC from firmware is %x, %x, %x, %x\n",
+ __func__, tmp_data[3], tmp_data[2],
+ tmp_data[1], tmp_data[0]);
+/*
+ if (tmp_data[3] == 0xFF && tmp_data[2] == 0xFF
+ && tmp_data[1] == 0xFF && tmp_data[0] == 0xFF) {
+ } else
+ break;
+ */
+ if (!(tmp_data[3] == 0xFF
+ && tmp_data[2] == 0xFF
+ && tmp_data[1] == 0xFF
+ && tmp_data[0] == 0xFF)) {
+ break;
+ }
+ }
+
+ CRC_value = tmp_data[3];
+
+ tmp_value = tmp_data[2] << 8;
+ CRC_value += tmp_value;
+
+ tmp_value = tmp_data[1] << 16;
+ CRC_value += tmp_value;
+
+ tmp_value = tmp_data[0] << 24;
+ CRC_value += tmp_value;
+
+ I("%s: CRC Value is %x\n", __func__, CRC_value);
+
+ /*Close Remapping*/
+ /*=====================================
+ Re-map close
+ =====================================*/
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x00;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ himax_flash_write_burst_length(client,
+ tmp_addr, tmp_data, 4);
+ return CRC_value;
+
+ } else {
+ E("%s: SRAM write fail\n", __func__);
+ return 0;
+ }
+ } else
+ I("%s: NO CRC Check File\n", __func__);
+
+ return 0;
+}
+
+bool Calculate_CRC_with_AP(unsigned char *FW_content,
+int CRC_from_FW, int mode)
+{
+ uint8_t tmp_data[4];
+ int i, j;
+ int fw_data;
+ int fw_data_2;
+ int CRC = 0xFFFFFFFF;
+ int PolyNomial = 0x82F63B78;
+ int length = 0;
+
+ if (mode == fw_image_128k)
+ length = 0x8000;
+ else if (mode == fw_image_124k)
+ length = 0x7C00;
+ else if (mode == fw_image_64k)
+ length = 0x4000;
+ else /*if (mode == fw_image_60k)*/
+ length = 0x3C00;
+
+ for (i = 0 ; i < length ; i++) {
+ fw_data = FW_content[i * 4];
+
+ for (j = 1 ; j < 4 ; j++) {
+ fw_data_2 = FW_content[i * 4 + j];
+ fw_data += (fw_data_2) << (8 * j);
+ }
+
+ CRC = fw_data ^ CRC;
+
+ for (j = 0 ; j < 32 ; j++) {
+ if ((CRC % 2) != 0)
+ CRC = ((CRC >> 1) & 0x7FFFFFFF) ^ PolyNomial;
+ else
+ CRC = (((CRC >> 1) ^ 0x7FFFFFFF) & 0x7FFFFFFF);
+ }
+ }
+
+ I("%s: CRC calculate from bin file is %x\n", __func__, CRC);
+
+ tmp_data[0] = (uint8_t)(CRC >> 24);
+ tmp_data[1] = (uint8_t)(CRC >> 16);
+ tmp_data[2] = (uint8_t)(CRC >> 8);
+ tmp_data[3] = (uint8_t) CRC;
+
+ CRC = tmp_data[0];
+ CRC += tmp_data[1] << 8;
+ CRC += tmp_data[2] << 16;
+ CRC += tmp_data[3] << 24;
+
+ I("%s: CRC calculate from bin file REVERSE %x\n", __func__, CRC);
+ I("%s: CRC calculate from FWis %x\n", __func__, CRC_from_FW);
+ if (CRC_from_FW == CRC)
+ return true;
+ else
+ return false;
+}
+/*#endif*/
+
+int himax_load_CRC_bin_file(struct i2c_client *client)
+{
+ int err = 0;
+ char *CRC_60_firmware_name = "HX_CRC_60.bin";
+ char *CRC_64_firmware_name = "HX_CRC_64.bin";
+ char *CRC_124_firmware_name = "HX_CRC_124.bin";
+ char *CRC_128_firmware_name = "HX_CRC_128.bin";
+
+ I("%s,Entering\n", __func__);
+ if (i_TP_CRC_FW_60K == NULL) {
+ I("load file name = %s\n", CRC_60_firmware_name);
+ err = request_firmware(&i_TP_CRC_FW_60K,
+ CRC_60_firmware_name, private_ts->dev);
+ if (err < 0) {
+ E("%s,fail in line%d error code=%d\n",
+ __func__, __LINE__, err);
+ err = -1;
+ goto request_60k_fw_fail;
+ }
+ } else
+ I("%s already load i_TP_CRC_FW_60K\n", __func__);
+
+ if (i_TP_CRC_FW_64K == NULL) {
+ I("load file name = %s\n", CRC_64_firmware_name);
+ err = request_firmware(&i_TP_CRC_FW_64K,
+ CRC_64_firmware_name, private_ts->dev);
+ if (err < 0) {
+ E("%s,fail in line%d error code=%d\n",
+ __func__, __LINE__, err);
+ err = -2;
+ goto request_64k_fw_fail;
+ }
+ } else
+ I("%s already load i_TP_CRC_FW_64K\n", __func__);
+
+ if (i_TP_CRC_FW_124K == NULL) {
+ I("load file name = %s\n", CRC_124_firmware_name);
+ err = request_firmware(&i_TP_CRC_FW_124K,
+ CRC_124_firmware_name, private_ts->dev);
+ if (err < 0) {
+ E("%s,fail in line%d error code=%d\n",
+ __func__, __LINE__, err);
+ err = -3;
+ goto request_124k_fw_fail;
+ }
+ } else
+ I("%s already load i_TP_CRC_FW_124K\n", __func__);
+
+ if (i_TP_CRC_FW_128K == NULL) {
+ I("load file name = %s\n", CRC_128_firmware_name);
+ err = request_firmware(&i_TP_CRC_FW_128K,
+ CRC_128_firmware_name, private_ts->dev);
+ if (err < 0) {
+ E("%s,fail in line%d error code=%d\n",
+ __func__, __LINE__, err);
+ err = -4;
+ goto request_128k_fw_fail;
+ }
+ } else
+ I("%s already load i_TP_CRC_FW_128K\n", __func__);
+
+ return err;
+
+request_128k_fw_fail:
+ release_firmware(i_TP_CRC_FW_124K);
+request_124k_fw_fail:
+ release_firmware(i_TP_CRC_FW_64K);
+request_64k_fw_fail:
+ release_firmware(i_TP_CRC_FW_60K);
+request_60k_fw_fail:
+ return err;
+}
+int fts_ctpm_fw_upgrade_with_sys_fs_60k(struct i2c_client *client,
+unsigned char *fw, int len, bool change_iref)
+{
+ int CRC_from_FW = 0;
+ int burnFW_success = 0;
+
+ if (len != 0x10000) {/*64k*/
+ E("%s: The file size is not 64K bytes\n", __func__);
+ return false;
+ }
+ himax_sense_off(client);
+ msleep(500);
+ himax_interface_on(client);
+ if (!himax_sector_erase(client, 0x00000)) {
+ E("%s:Sector erase fail!Please restart the IC.\n", __func__);
+ return false;
+ }
+ himax_flash_programming(client, fw, 0x0F000);
+
+ /*burnFW_success = himax_83100_Verify(fw, len);
+ if(burnFW_success==false)
+ return burnFW_success;*/
+
+ CRC_from_FW = himax_check_CRC(client, fw_image_60k);
+ burnFW_success = Calculate_CRC_with_AP(fw, CRC_from_FW, fw_image_60k);
+ /*himax_sense_on(client, 0x01);*/
+ return burnFW_success;
+}
+
+int fts_ctpm_fw_upgrade_with_sys_fs_64k(struct i2c_client *client,
+unsigned char *fw, int len, bool change_iref)
+{
+ int CRC_from_FW = 0;
+ int burnFW_success = 0;
+
+ if (len != 0x10000) { /*64k*/
+ E("%s: The file size is not 64K bytes\n", __func__);
+ return false;
+ }
+ himax_sense_off(client);
+ msleep(500);
+ himax_interface_on(client);
+ himax_chip_erase(client);
+ himax_flash_programming(client, fw, len);
+
+ /*burnFW_success = himax_83100_Verify(fw, len);
+ if(burnFW_success==false)
+ return burnFW_success;*/
+
+ CRC_from_FW = himax_check_CRC(client, fw_image_64k);
+ burnFW_success = Calculate_CRC_with_AP(fw, CRC_from_FW, fw_image_64k);
+ /*himax_sense_on(client, 0x01);*/
+ return burnFW_success;
+}
+
+int fts_ctpm_fw_upgrade_with_sys_fs_124k(struct i2c_client *client,
+unsigned char *fw, int len, bool change_iref)
+{
+ int CRC_from_FW = 0;
+ int burnFW_success = 0;
+
+ if (len != 0x20000) { /*128k*/
+ E("%s: The file size is not 128K bytes\n", __func__);
+ return false;
+ }
+ himax_sense_off(client);
+ msleep(500);
+ himax_interface_on(client);
+ if (!himax_block_erase(client)) {
+ E("%s:Block erase fail!Please restart the IC.\n", __func__);
+ return false;
+ }
+ if (!himax_sector_erase(client, 0x10000)) {
+ E("%s:Sector erase fail!Please restart the IC.\n", __func__);
+ return false;
+ }
+ himax_flash_programming(client, fw, 0x1F000);
+
+ /*burnFW_success = himax_83100_Verify(fw, len);
+ if(burnFW_success==false)
+ return burnFW_success;*/
+
+ CRC_from_FW = himax_check_CRC(client, fw_image_124k);
+ burnFW_success = Calculate_CRC_with_AP(fw, CRC_from_FW, fw_image_124k);
+ /*himax_sense_on(client, 0x01);*/
+ return burnFW_success;
+}
+
+int fts_ctpm_fw_upgrade_with_sys_fs_128k(struct i2c_client *client,
+unsigned char *fw, int len, bool change_iref)
+{
+ int CRC_from_FW = 0;
+ int burnFW_success = 0;
+
+ if (len != 0x20000) { /*128k*/
+ E("%s: The file size is not 128K bytes\n", __func__);
+ return false;
+ }
+ himax_sense_off(client);
+ msleep(500);
+ himax_interface_on(client);
+ himax_chip_erase(client);
+
+ himax_flash_programming(client, fw, len);
+
+ /*burnFW_success = himax_83100_Verify(fw, len);
+ if(burnFW_success==false)
+ return burnFW_success;*/
+
+ CRC_from_FW = himax_check_CRC(client, fw_image_128k);
+ burnFW_success = Calculate_CRC_with_AP(fw, CRC_from_FW, fw_image_128k);
+ /*himax_sense_on(client, 0x01); */
+ return burnFW_success;
+}
+
+void himax_touch_information(struct i2c_client *client)
+{
+ uint8_t cmd[4];
+ char data[12] = {0};
+
+ I("%s:IC_TYPE =%d\n", __func__, IC_TYPE);
+
+ if (IC_TYPE == HX_83100_SERIES_PWON) {
+ cmd[3] = 0x08; cmd[2] = 0x00; cmd[1] = 0x00; cmd[0] = 0xF8;
+ himax_register_read(client, cmd, 1, data);
+
+ ic_data->HX_RX_NUM = data[1];
+ ic_data->HX_TX_NUM = data[2];
+ ic_data->HX_MAX_PT = data[3];
+
+ cmd[3] = 0x08; cmd[2] = 0x00; cmd[1] = 0x00; cmd[0] = 0xFC;
+ himax_register_read(client, cmd, 1, data);
+
+ if ((data[1] & 0x04) == 0x04)
+ ic_data->HX_XY_REVERSE = true;
+ else
+ ic_data->HX_XY_REVERSE = false;
+
+ ic_data->HX_Y_RES = data[3]*256;
+ cmd[3] = 0x08; cmd[2] = 0x00; cmd[1] = 0x01; cmd[0] = 0x00;
+ himax_register_read(client, cmd, 1, data);
+ ic_data->HX_Y_RES = ic_data->HX_Y_RES + data[0];
+ ic_data->HX_X_RES = data[1]*256 + data[2];
+ cmd[3] = 0x08; cmd[2] = 0x00; cmd[1] = 0x00; cmd[0] = 0x8C;
+ himax_register_read(client, cmd, 1, data);
+ if ((data[0] & 0x01) == 1)
+ ic_data->HX_INT_IS_EDGE = true;
+ else
+ ic_data->HX_INT_IS_EDGE = false;
+
+ if (ic_data->HX_RX_NUM > 40)
+ ic_data->HX_RX_NUM = 29;
+ if (ic_data->HX_TX_NUM > 20)
+ ic_data->HX_TX_NUM = 16;
+ if (ic_data->HX_MAX_PT > 10)
+ ic_data->HX_MAX_PT = 10;
+ if (ic_data->HX_Y_RES > 2000)
+ ic_data->HX_Y_RES = 1280;
+ if (ic_data->HX_X_RES > 2000)
+ ic_data->HX_X_RES = 720;
+#ifdef HX_EN_MUT_BUTTON
+ cmd[3] = 0x08; cmd[2] = 0x00; cmd[1] = 0x00; cmd[0] = 0xE8;
+ himax_register_read(client, cmd, 1, data);
+ ic_data->HX_BT_NUM = data[3];
+#endif
+ I("%s:HX_RX_NUM =%d,HX_TX_NUM =%d,HX_MAX_PT=%d\n",
+ __func__, ic_data->HX_RX_NUM,
+ ic_data->HX_TX_NUM, ic_data->HX_MAX_PT);
+ I("%s:HX_XY_REVERSE =%d,HX_Y_RES =%d,HX_X_RES=%d\n",
+ __func__, ic_data->HX_XY_REVERSE,
+ ic_data->HX_Y_RES, ic_data->HX_X_RES);
+ I("%s:HX_INT_IS_EDGE =%d\n",
+ __func__, ic_data->HX_INT_IS_EDGE);
+ } else {
+ ic_data->HX_RX_NUM = 0;
+ ic_data->HX_TX_NUM = 0;
+ ic_data->HX_BT_NUM = 0;
+ ic_data->HX_X_RES = 0;
+ ic_data->HX_Y_RES = 0;
+ ic_data->HX_MAX_PT = 0;
+ ic_data->HX_XY_REVERSE = false;
+ ic_data->HX_INT_IS_EDGE = false;
+ }
+}
+
+void himax_read_FW_ver(struct i2c_client *client)
+{
+ uint8_t cmd[4];
+ uint8_t data[64];
+
+ /*=====================================
+ Read FW version : 0x0000_E303
+ =====================================*/
+ cmd[3] = 0x00; cmd[2] = 0x00; cmd[1] = 0xE3; cmd[0] = 0x00;
+ himax_register_read(client, cmd, 1, data);
+
+ ic_data->vendor_config_ver = data[3] << 8;
+
+ cmd[3] = 0x00; cmd[2] = 0x00; cmd[1] = 0xE3; cmd[0] = 0x04;
+ himax_register_read(client, cmd, 1, data);
+
+ ic_data->vendor_config_ver = data[0] | ic_data->vendor_config_ver;
+ I("CFG_VER : %X\n", ic_data->vendor_config_ver);
+
+ cmd[3] = 0x08; cmd[2] = 0x00; cmd[1] = 0x00; cmd[0] = 0x28;
+ himax_register_read(client, cmd, 1, data);
+
+ ic_data->vendor_fw_ver = data[0]<<8 | data[1];
+ I("FW_VER : %X\n", ic_data->vendor_fw_ver);
+
+}
+
+bool himax_ic_package_check(struct i2c_client *client)
+{
+/*#if 0*/
+#ifdef HX_EN_CHECK_PATCH
+ uint8_t cmd[3];
+ uint8_t data[3];
+
+ memset(cmd, 0x00, sizeof(cmd));
+ memset(data, 0x00, sizeof(data));
+
+ if (i2c_himax_read(client, 0xD1, cmd, 3, HIMAX_I2C_RETRY_TIMES) < 0)
+ return false;
+
+ if (i2c_himax_read(client, 0x31, data, 3, HIMAX_I2C_RETRY_TIMES) < 0)
+ return false;
+
+ if ((data[0] == 0x85 && data[1] == 0x29)) {
+ IC_TYPE = HX_85XX_F_SERIES_PWON;
+ IC_CHECKSUM = HX_TP_BIN_CHECKSUM_CRC;
+ /*Himax: Set FW and CFG Flash Address*/
+ FW_VER_MAJ_FLASH_ADDR = 64901; /*0xFD85*/
+ FW_VER_MAJ_FLASH_LENG = 1;
+ FW_VER_MIN_FLASH_ADDR = 64902; /*0xFD86*/
+ FW_VER_MIN_FLASH_LENG = 1;
+ CFG_VER_MAJ_FLASH_ADDR = 64928; /*0xFDA0*/
+ CFG_VER_MAJ_FLASH_LENG = 12;
+ CFG_VER_MIN_FLASH_ADDR = 64940; /*0xFDAC*/
+ CFG_VER_MIN_FLASH_LENG = 12;
+ I("Himax IC package 852x F\n");
+ }
+ if ((data[0] == 0x85 && data[1] == 0x30)
+ || (cmd[0] == 0x05 && cmd[1] == 0x85 && cmd[2] == 0x29)) {
+ IC_TYPE = HX_85XX_E_SERIES_PWON;
+ IC_CHECKSUM = HX_TP_BIN_CHECKSUM_CRC;
+ /*Himax: Set FW and CFG Flash Address*/
+ FW_VER_MAJ_FLASH_ADDR = 133; /*0x0085*/
+ FW_VER_MAJ_FLASH_LENG = 1;
+ FW_VER_MIN_FLASH_ADDR = 134; /*0x0086*/
+ FW_VER_MIN_FLASH_LENG = 1;
+ CFG_VER_MAJ_FLASH_ADDR = 160; /*0x00A0*/
+ CFG_VER_MAJ_FLASH_LENG = 12;
+ CFG_VER_MIN_FLASH_ADDR = 172; /*0x00AC*/
+ CFG_VER_MIN_FLASH_LENG = 12;
+ I("Himax IC package 852x E\n");
+ } else if ((data[0] == 0x85 && data[1] == 0x31)) {
+ IC_TYPE = HX_85XX_ES_SERIES_PWON;
+ IC_CHECKSUM = HX_TP_BIN_CHECKSUM_CRC;
+ /*Himax: Set FW and CFG Flash Address*/
+ FW_VER_MAJ_FLASH_ADDR = 133; /*0x0085*/
+ FW_VER_MAJ_FLASH_LENG = 1;
+ FW_VER_MIN_FLASH_ADDR = 134; /*0x0086*/
+ FW_VER_MIN_FLASH_LENG = 1;
+ CFG_VER_MAJ_FLASH_ADDR = 160; /*0x00A0*/
+ CFG_VER_MAJ_FLASH_LENG = 12;
+ CFG_VER_MIN_FLASH_ADDR = 172; /*0x00AC*/
+ CFG_VER_MIN_FLASH_LENG = 12;
+ I("Himax IC package 852x ES\n");
+ } else if ((data[0] == 0x85 && data[1] == 0x28)
+ || (cmd[0] == 0x04 && cmd[1] == 0x85
+ && (cmd[2] == 0x26 || cmd[2] == 0x27
+ || cmd[2] == 0x28))) {
+ IC_TYPE = HX_85XX_D_SERIES_PWON;
+ IC_CHECKSUM = HX_TP_BIN_CHECKSUM_CRC;
+ /*Himax: Set FW and CFG Flash Address*/
+ FW_VER_MAJ_FLASH_ADDR = 133; /*0x0085*/
+ FW_VER_MAJ_FLASH_LENG = 1;
+ FW_VER_MIN_FLASH_ADDR = 134; /*0x0086*/
+ FW_VER_MIN_FLASH_LENG = 1;
+ CFG_VER_MAJ_FLASH_ADDR = 160; /*0x00A0*/
+ CFG_VER_MAJ_FLASH_LENG = 12;
+ CFG_VER_MIN_FLASH_ADDR = 172; /* 0x00AC*/
+ CFG_VER_MIN_FLASH_LENG = 12;
+ I("Himax IC package 852x D\n");
+ } else if ((data[0] == 0x85 && data[1] == 0x23) ||
+ (cmd[0] == 0x03 && cmd[1] == 0x85 &&
+ (cmd[2] == 0x26 || cmd[2] == 0x27 ||
+ cmd[2] == 0x28 || cmd[2] == 0x29))) {
+ IC_TYPE = HX_85XX_C_SERIES_PWON;
+ IC_CHECKSUM = HX_TP_BIN_CHECKSUM_SW;
+ /*Himax: Set FW and CFG Flash Address*/
+ FW_VER_MAJ_FLASH_ADDR = 133; /*0x0085*/
+ FW_VER_MAJ_FLASH_LENG = 1;
+ FW_VER_MIN_FLASH_ADDR = 134; /*0x0086*/
+ FW_VER_MIN_FLASH_LENG = 1;
+ CFG_VER_MAJ_FLASH_ADDR = 135; /*0x0087*/
+ CFG_VER_MAJ_FLASH_LENG = 12;
+ CFG_VER_MIN_FLASH_ADDR = 147; /*0x0093*/
+ CFG_VER_MIN_FLASH_LENG = 12;
+ I("Himax IC package 852x C\n");
+ } else if ((data[0] == 0x85 && data[1] == 0x26) ||
+ (cmd[0] == 0x02 && cmd[1] == 0x85 &&
+ (cmd[2] == 0x19 || cmd[2] == 0x25 || cmd[2] == 0x26))) {
+ IC_TYPE = HX_85XX_B_SERIES_PWON;
+ IC_CHECKSUM = HX_TP_BIN_CHECKSUM_SW;
+ /*Himax: Set FW and CFG Flash Address*/
+ FW_VER_MAJ_FLASH_ADDR = 133; /*0x0085*/
+ FW_VER_MAJ_FLASH_LENG = 1;
+ FW_VER_MIN_FLASH_ADDR = 728; /*0x02D8*/
+ FW_VER_MIN_FLASH_LENG = 1;
+ CFG_VER_MAJ_FLASH_ADDR = 692; /*0x02B4*/
+ CFG_VER_MAJ_FLASH_LENG = 3;
+ CFG_VER_MIN_FLASH_ADDR = 704; /*0x02C0*/
+ CFG_VER_MIN_FLASH_LENG = 3;
+ I("Himax IC package 852x B\n");
+ } else if ((data[0] == 0x85 && data[1] == 0x20) || (cmd[0] == 0x01 &&
+ cmd[1] == 0x85 && cmd[2] == 0x19)) {
+ IC_TYPE = HX_85XX_A_SERIES_PWON;
+ IC_CHECKSUM = HX_TP_BIN_CHECKSUM_SW;
+ I("Himax IC package 852x A\n");
+ } else {
+ E("Himax IC package incorrect!!\n");
+ }
+#else
+ IC_TYPE = HX_83100_SERIES_PWON;
+ IC_CHECKSUM = HX_TP_BIN_CHECKSUM_CRC;
+ /*Himax: Set FW and CFG Flash Address*/
+ FW_VER_MAJ_FLASH_ADDR = 57384; /*0xE028*/
+ FW_VER_MAJ_FLASH_LENG = 1;
+ FW_VER_MIN_FLASH_ADDR = 57385; /*0xE029*/
+ FW_VER_MIN_FLASH_LENG = 1;
+ CFG_VER_MAJ_FLASH_ADDR = 58115; /*0xE303*/
+ CFG_VER_MAJ_FLASH_LENG = 1;
+ CFG_VER_MIN_FLASH_ADDR = 58116; /*0xE304*/
+ CFG_VER_MIN_FLASH_LENG = 1;
+ I("Himax IC package 83100_in\n");
+
+#endif
+ return true;
+}
+
+void himax_read_event_stack(struct i2c_client *client,
+uint8_t *buf, uint8_t length)
+{
+ uint8_t cmd[4];
+
+ cmd[3] = 0x90; cmd[2] = 0x06;
+ cmd[1] = 0x00; cmd[0] = 0x00;
+ if (i2c_himax_write(client, 0x00,
+ cmd, 4, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ }
+
+ cmd[0] = 0x00;
+ if (i2c_himax_write(client, 0x0C,
+ cmd, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ }
+
+ i2c_himax_read(client, 0x08,
+ buf, length, HIMAX_I2C_RETRY_TIMES);
+}
+
+/*#if 0*/
+#ifdef HX_EN_CHECK_PATCH
+static void himax_83100_Flash_Write(uint8_t *reg_byte, uint8_t *write_data)
+{
+ uint8_t tmpbyte[2];
+
+ if (i2c_himax_write(private_ts->client, 0x00,
+ ®_byte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ if (i2c_himax_write(private_ts->client, 0x01,
+ ®_byte[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ if (i2c_himax_write(private_ts->client, 0x02,
+ ®_byte[2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ if (i2c_himax_write(private_ts->client,
+ 0x03, ®_byte[3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ if (i2c_himax_write(private_ts->client,
+ 0x04, &write_data[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ if (i2c_himax_write(private_ts->client,
+ 0x05, &write_data[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ if (i2c_himax_write(private_ts->client,
+ 0x06, &write_data[2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ if (i2c_himax_write(private_ts->client,
+ 0x07, &write_data[3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ if (isBusrtOn == false) {
+ tmpbyte[0] = 0x01;
+ if (i2c_himax_write(private_ts->client,
+ 0x0C, &tmpbyte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+ }
+}
+#endif
+/*#if 0*/
+#ifdef HX_EN_CHECK_PATCH
+static void himax_83100_Flash_Burst_Write
+(uint8_t *reg_byte, uint8_t *write_data)
+{
+ /*uint8_t tmpbyte[2];*/
+ int i = 0;
+
+ if (i2c_himax_write(private_ts->client, 0x00,
+ ®_byte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ if (i2c_himax_write(private_ts->client, 0x01,
+ ®_byte[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ if (i2c_himax_write(private_ts->client, 0x02,
+ ®_byte[2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ if (i2c_himax_write(private_ts->client, 0x03,
+ ®_byte[3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ /*Write 256 bytes with continue burst mode*/
+ for (i = 0 ; i < 256 ; i = i + 4) {
+ if (i2c_himax_write(private_ts->client,
+ 0x04, &write_data[i], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ if (i2c_himax_write(private_ts->client, 0x05,
+ &write_data[i+1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ if (i2c_himax_write(private_ts->client, 0x06,
+ &write_data[i+2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+
+ if (i2c_himax_write(private_ts->client, 0x07,
+ &write_data[i+3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+ }
+
+ /*if (isBusrtOn == false)
+ {
+ tmpbyte[0] = 0x01;
+ if (i2c_himax_write(private_ts->client,
+ 0x0C, &tmpbyte[0], 1, 3) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }*/
+
+}
+#endif
+
+/*#if 0*/
+#ifdef HX_EN_CHECK_PATCH
+static bool himax_83100_Verify(uint8_t *FW_File, int FW_Size)
+{
+ uint8_t tmp_addr[4];
+ uint8_t tmp_data[4];
+ uint8_t out_buffer[20];
+ uint8_t in_buffer[260];
+
+ int fail_addr = 0, fail_cnt = 0;
+ int page_prog_start = 0;
+ int i = 0;
+
+ himax_interface_on(private_ts->client);
+ himax_burst_enable(private_ts->client, 0);
+
+ /*=====================================
+ SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x02;
+ tmp_data[1] = 0x07; tmp_data[0] = 0x80;
+ himax_83100_Flash_Write(tmp_addr, tmp_data);
+
+ for (page_prog_start = 0; page_prog_start < FW_Size;
+ page_prog_start = page_prog_start + 256) {
+ /*=====================================
+ SPI Transfer Control
+ Set 256 bytes page read : 0x8000_0020 ==> 0x6940_02FF
+ Set read start address : 0x8000_0028 ==> 0x0000_0000
+ Set command : 0x8000_0024 ==> 0x0000_003B
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x69; tmp_data[2] = 0x40;
+ tmp_data[1] = 0x02; tmp_data[0] = 0xFF;
+ himax_83100_Flash_Write(tmp_addr, tmp_data);
+
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x28;
+ if (page_prog_start < 0x100) {
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = (uint8_t)page_prog_start;
+ } else if (page_prog_start >= 0x100
+ && page_prog_start < 0x10000) {
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = (uint8_t)(page_prog_start >> 8);
+ tmp_data[0] = (uint8_t)page_prog_start;
+ } else if (page_prog_start >= 0x10000
+ && page_prog_start < 0x1000000) {
+ tmp_data[3] = 0x00;
+ tmp_data[2] = (uint8_t)(page_prog_start >> 16);
+ tmp_data[1] = (uint8_t)(page_prog_start >> 8);
+ tmp_data[0] = (uint8_t)page_prog_start;
+ }
+ himax_83100_Flash_Write(tmp_addr, tmp_data);
+
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x3B;
+ himax_83100_Flash_Write(tmp_addr, tmp_data);
+
+ /*==================================
+ AHB_I2C Burst Read
+ Set SPI data register : 0x8000_002C ==> 0x00
+ ==================================*/
+ out_buffer[0] = 0x2C;
+ out_buffer[1] = 0x00;
+ out_buffer[2] = 0x00;
+ out_buffer[3] = 0x80;
+ i2c_himax_write(private_ts->client, 0x00,
+ out_buffer, 4, HIMAX_I2C_RETRY_TIMES);
+
+ /*==================================
+ Read access : 0x0C ==> 0x00
+ ==================================*/
+ out_buffer[0] = 0x00;
+ i2c_himax_write(private_ts->client, 0x0C,
+ out_buffer, 1, HIMAX_I2C_RETRY_TIMES);
+
+ /*==================================
+ Read 128 bytes two times
+ ==================================*/
+ i2c_himax_read(private_ts->client, 0x08,
+ in_buffer, 128, HIMAX_I2C_RETRY_TIMES);
+ for (i = 0; i < 128; i++)
+ flash_buffer[i + page_prog_start] = in_buffer[i];
+
+ i2c_himax_read(private_ts->client, 0x08,
+ in_buffer, 128, HIMAX_I2C_RETRY_TIMES);
+ for (i = 0; i < 128; i++)
+ flash_buffer[(i + 128)
+ + page_prog_start] = in_buffer[i];
+
+ /*tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x2C;
+ himax_register_read(tmp_addr, 32, out in_buffer);
+ for (int i = 0; i < 128; i++)
+ flash_buffer[i + page_prog_start] = in_buffer[i];
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x2C;
+ himax_register_read(tmp_addr, 32, out in_buffer);
+ for (int i = 0; i < 128; i++)
+ flash_buffer[i + page_prog_start] = in_buffer[i];
+ */
+ I("%s:Verify Progress: %x\n", __func__, page_prog_start);
+ }
+
+ fail_cnt = 0;
+ for (i = 0; i < FW_Size; i++) {
+ if (FW_File[i] != flash_buffer[i]) {
+ if (fail_cnt == 0)
+ fail_addr = i;
+
+ fail_cnt++;
+ /*E("%s Fail Block:%x\n", __func__, i);
+ return false;*/
+ }
+ }
+ if (fail_cnt > 0) {
+ E("%s:Start Fail Block:%x and fail block count=%x\n",
+ __func__, fail_addr, fail_cnt);
+ return false;
+ }
+
+ I("%s:Byte read verify pass.\n", __func__);
+ return true;
+
+}
+#endif
+
+void himax_get_DSRAM_data(struct i2c_client *client, uint8_t *info_data)
+{
+ int i;
+ int cnt = 0;
+ unsigned char tmp_addr[4];
+ unsigned char tmp_data[4];
+ uint8_t max_i2c_size = 32;
+ int total_size = ic_data->HX_TX_NUM * ic_data->HX_RX_NUM * 2;
+ int total_size_4bytes = total_size / 4;
+ int total_read_times = 0;
+ unsigned long address = 0x08000468;
+
+ tmp_addr[3] = 0x08; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x04; tmp_addr[0] = 0x64;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x5A; tmp_data[0] = 0xA5;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+ do {
+ cnt++;
+ himax_register_read(client, tmp_addr, 1, tmp_data);
+ usleep_range(9999, 10000);
+ } while ((tmp_data[1] != 0xA5 || tmp_data[0] != 0x5A) && cnt < 100);
+ tmp_addr[3] = 0x08; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x04; tmp_addr[0] = 0x68;
+ if (total_size_4bytes % max_i2c_size == 0)
+ total_read_times = total_size_4bytes / max_i2c_size;
+ else
+ total_read_times = total_size_4bytes / max_i2c_size + 1;
+
+ for (i = 0 ; i < (total_read_times) ; i++) {
+ if (total_size_4bytes >= max_i2c_size) {
+ himax_register_read(client, tmp_addr,
+ max_i2c_size,
+ &info_data[i*max_i2c_size*4]);
+ total_size_4bytes = total_size_4bytes - max_i2c_size;
+ } else {
+ himax_register_read(client, tmp_addr,
+ total_size_4bytes % max_i2c_size,
+ &info_data[i*max_i2c_size*4]);
+ }
+ address += max_i2c_size * 4;
+ tmp_addr[1] = (uint8_t)((address>>8) & 0x00FF);
+ tmp_addr[0] = (uint8_t)((address) & 0x00FF);
+ }
+ tmp_addr[3] = 0x08; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x04; tmp_addr[0] = 0x64;
+ tmp_data[3] = 0x11; tmp_data[2] = 0x22;
+ tmp_data[1] = 0x33; tmp_data[0] = 0x44;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+}
+/*ts_work*/
+int cal_data_len(int raw_cnt_rmd, int HX_MAX_PT, int raw_cnt_max)
+{
+ int RawDataLen;
+
+ if (raw_cnt_rmd != 0x00)
+ RawDataLen = 124 - ((HX_MAX_PT + raw_cnt_max + 3) * 4) - 1;
+ else
+ RawDataLen = 124 - ((HX_MAX_PT + raw_cnt_max + 2) * 4) - 1;
+
+ return RawDataLen;
+}
+
+bool read_event_stack(struct i2c_client *client, uint8_t *buf, int length)
+{
+ uint8_t cmd[4];
+
+ if (length > 56)
+ length = 124;
+ /*=====================
+ AHB I2C Burst Read
+ =====================*/
+ cmd[0] = 0x31;
+ if (i2c_himax_write(client, 0x13, cmd, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ goto err_workqueue_out;
+ }
+
+ cmd[0] = 0x10;
+ if (i2c_himax_write(client, 0x0D, cmd, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ goto err_workqueue_out;
+ }
+ /*=====================
+ Read event stack
+ =====================*/
+ cmd[3] = 0x90; cmd[2] = 0x06; cmd[1] = 0x00; cmd[0] = 0x00;
+ if (i2c_himax_write(client, 0x00, cmd, 4, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ goto err_workqueue_out;
+ }
+
+ cmd[0] = 0x00;
+ if (i2c_himax_write(client, 0x0C, cmd, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ goto err_workqueue_out;
+ }
+ i2c_himax_read(client, 0x08, buf, length, HIMAX_I2C_RETRY_TIMES);
+ return 1;
+
+err_workqueue_out:
+ return 0;
+}
+
+bool post_read_event_stack(struct i2c_client *client)
+{
+ return 1;
+}
+bool diag_check_sum(uint8_t hx_touch_info_size,
+uint8_t *buf) /*return checksum value*/
+{
+ uint16_t check_sum_cal = 0;
+ int i;
+
+ /*Check 124th byte CRC*/
+ for (i = hx_touch_info_size, check_sum_cal = 0 ; i < 124 ; i = i + 2)
+ check_sum_cal += (buf[i + 1] * 256 + buf[i]);
+
+ if (check_sum_cal % 0x10000 != 0) {
+ I("%s:diag chksum fail!check_sum_cal=%X,hx_touchinfo_sz=%d,\n",
+ __func__, check_sum_cal, hx_touch_info_size);
+ return 0;
+ }
+ return 1;
+}
+
+void diag_parse_raw_data(int hx_touch_info_size,
+int RawDataLen, int mul_num, int self_num, uint8_t *buf,
+uint8_t diag_cmd, int16_t *mutual_data, int16_t *self_data)
+{
+ int RawDataLen_word;
+ int index = 0;
+ int temp1, temp2, i;
+
+ if (buf[hx_touch_info_size] == 0x3A &&
+ buf[hx_touch_info_size + 1] == 0xA3 &&
+ buf[hx_touch_info_size + 2] > 0 &&
+ buf[hx_touch_info_size + 3] == diag_cmd + 5) {
+ RawDataLen_word = RawDataLen / 2;
+ index = (buf[hx_touch_info_size + 2] - 1) * RawDataLen_word;
+ /*I("Header[%d]: %x, %x, %x, %x, mutual: %d, self: %d\n",
+ index, buf[56], buf[57], buf[58], buf[59], mul_num, self_num);*/
+ for (i = 0; i < RawDataLen_word; i++) {
+ temp1 = index + i;
+
+ if (temp1 < mul_num) { /*mutual*/
+ /*4: RawData Header, 1:HSB */
+ mutual_data[index + i]
+ = buf[i*2 + hx_touch_info_size + 4 + 1]
+ * 256
+ + buf[i * 2 + hx_touch_info_size + 4];
+ } else { /*self*/
+ temp1 = i + index;
+ temp2 = self_num + mul_num;
+
+ if (temp1 >= temp2)
+ break;
+
+ /*4: RawData Header*/
+ self_data[i + index - mul_num]
+ = buf[i * 2 + hx_touch_info_size + 4];
+ self_data[i + index - mul_num + 1]
+ = buf[i * 2 + hx_touch_info_size + 4 + 1];
+ }
+ }
+ } else {
+ I("[HIMAX TP MSG]%s: header format is wrong!\n", __func__);
+ I("Header[%d]: %x, %x, %x, %x, mutual: %d, self: %d\n",
+ index, buf[56], buf[57], buf[58], buf[59],
+ mul_num, self_num);
+ }
+}
diff --git a/drivers/input/touchscreen/hxchipset/himax_ic.h b/drivers/input/touchscreen/hxchipset/himax_ic.h
new file mode 100644
index 0000000..ce7d0d4
--- /dev/null
+++ b/drivers/input/touchscreen/hxchipset/himax_ic.h
@@ -0,0 +1,148 @@
+/* Himax Android Driver Sample Code for HMX83100 chipset
+*
+* Copyright (C) 2015 Himax Corporation.
+*
+* This software is licensed under the terms of the GNU General Public
+* License version 2, as published by the Free Software Foundation, and
+* may be copied, distributed, and modified under those terms.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+*/
+
+#include "himax_platform.h"
+#include "himax_common.h"
+
+#include <linux/slab.h>
+
+#define HX_85XX_A_SERIES_PWON 1
+#define HX_85XX_B_SERIES_PWON 2
+#define HX_85XX_C_SERIES_PWON 3
+#define HX_85XX_D_SERIES_PWON 4
+#define HX_85XX_E_SERIES_PWON 5
+#define HX_85XX_ES_SERIES_PWON 6
+#define HX_85XX_F_SERIES_PWON 7
+#define HX_83100_SERIES_PWON 8
+
+#define HX_TP_BIN_CHECKSUM_SW 1
+#define HX_TP_BIN_CHECKSUM_HW 2
+#define HX_TP_BIN_CHECKSUM_CRC 3
+
+enum fw_image_type {
+ fw_image_60k = 0x01,
+ fw_image_64k,
+ fw_image_124k,
+ fw_image_128k,
+};
+
+int himax_hand_shaking(struct i2c_client *client);
+void himax_set_SMWP_enable(struct i2c_client *client, uint8_t SMWP_enable);
+void himax_get_SMWP_enable(struct i2c_client *client, uint8_t *tmp_data);
+void himax_set_HSEN_enable(struct i2c_client *client, uint8_t HSEN_enable);
+void himax_get_HSEN_enable(struct i2c_client *client, uint8_t *tmp_data);
+void himax_diag_register_set(struct i2c_client *client, uint8_t diag_command);
+
+void himax_flash_dump_func(struct i2c_client *client,
+uint8_t local_flash_command, int Flash_Size, uint8_t *flash_buffer);
+
+int himax_chip_self_test(struct i2c_client *client);
+
+/*himax_83100_BURST_INC0_EN*/
+int himax_burst_enable(struct i2c_client *client, uint8_t auto_add_4_byte);
+
+/*RegisterRead83100*/
+void himax_register_read(struct i2c_client *client,
+ uint8_t *read_addr, int read_length, uint8_t *read_data);
+
+/*himax_83100_Flash_Read*/
+void himax_flash_read(struct i2c_client *client,
+ uint8_t *reg_byte, uint8_t *read_data);
+
+/*himax_83100_Flash_Write_Burst*/
+void himax_flash_write_burst(struct i2c_client *client,
+ uint8_t *reg_byte, uint8_t *write_data);
+
+/*himax_83100_Flash_Write_Burst_length*/
+int himax_flash_write_burst_length(struct i2c_client *client,
+ uint8_t *reg_byte, uint8_t *write_data, int length);
+
+/*RegisterWrite83100*/
+int himax_register_write(struct i2c_client *client,
+ uint8_t *write_addr, int write_length, uint8_t *write_data);
+
+/*himax_83100_SenseOff*/
+void himax_sense_off(struct i2c_client *client);
+/*himax_83100_Interface_on*/
+void himax_interface_on(struct i2c_client *client);
+bool wait_wip(struct i2c_client *client, int Timing);
+
+/*himax_83100_SenseOn*/
+void himax_sense_on(struct i2c_client *client,
+ uint8_t FlashMode);
+
+/*himax_83100_Chip_Erase*/
+void himax_chip_erase(struct i2c_client *client);
+/*himax_83100_Block_Erase*/
+bool himax_block_erase(struct i2c_client *client);
+
+/*himax_83100_Sector_Erase*/
+bool himax_sector_erase(struct i2c_client *client, int start_addr);
+
+/*himax_83100_Sram_Write*/
+void himax_sram_write(struct i2c_client *client, uint8_t *FW_content);
+
+/*himax_83100_Sram_Verify*/
+bool himax_sram_verify(struct i2c_client *client,
+ uint8_t *FW_File, int FW_Size);
+
+/*himax_83100_Flash_Programming*/
+void himax_flash_programming(struct i2c_client *client,
+ uint8_t *FW_content, int FW_Size);
+
+/*himax_83100_CheckChipVersion*/
+bool himax_check_chip_version(struct i2c_client *client);
+
+/*himax_83100_Check_CRC*/
+int himax_check_CRC(struct i2c_client *client, int mode);
+
+bool Calculate_CRC_with_AP(unsigned char *FW_content,
+ int CRC_from_FW, int mode);
+
+int fts_ctpm_fw_upgrade_with_sys_fs_60k(struct i2c_client *client,
+ unsigned char *fw, int len, bool change_iref);
+
+int fts_ctpm_fw_upgrade_with_sys_fs_64k(struct i2c_client *client,
+ unsigned char *fw, int len, bool change_iref);
+
+int fts_ctpm_fw_upgrade_with_sys_fs_124k(struct i2c_client *client,
+ unsigned char *fw, int len, bool change_iref);
+
+int fts_ctpm_fw_upgrade_with_sys_fs_128k(struct i2c_client *client,
+ unsigned char *fw, int len, bool change_iref);
+
+void himax_touch_information(struct i2c_client *client);
+void himax_read_FW_ver(struct i2c_client *client);
+bool himax_ic_package_check(struct i2c_client *client);
+
+void himax_read_event_stack(struct i2c_client *client,
+ uint8_t *buf, uint8_t length);
+
+int cal_data_len(int raw_cnt_rmd, int HX_MAX_PT, int raw_cnt_max);
+bool read_event_stack(struct i2c_client *client, uint8_t *buf_ts, int length);
+bool post_read_event_stack(struct i2c_client *client);
+
+/*return checksum value*/
+bool diag_check_sum(uint8_t hx_touch_info_size, uint8_t *buf_ts);
+
+void diag_parse_raw_data(int hx_touch_info_size, int RawDataLen,
+ int mul_num, int self_num, uint8_t *buf_ts,
+ uint8_t diag_cmd, int16_t *mutual_data, int16_t *self_data);
+
+void himax_get_DSRAM_data(struct i2c_client *client, uint8_t *info_data);
+extern struct himax_ts_data *private_ts;
+extern struct himax_ic_data *ic_data;
+
+int himax_load_CRC_bin_file(struct i2c_client *client);
diff --git a/drivers/input/touchscreen/hxchipset/himax_platform.c b/drivers/input/touchscreen/hxchipset/himax_platform.c
new file mode 100644
index 0000000..309bb5e
--- /dev/null
+++ b/drivers/input/touchscreen/hxchipset/himax_platform.c
@@ -0,0 +1,783 @@
+/* Himax Android Driver Sample Code for HIMAX chipset
+*
+* Copyright (C) 2015 Himax Corporation.
+*
+* This software is licensed under the terms of the GNU General Public
+* License version 2, as published by the Free Software Foundation, and
+* may be copied, distributed, and modified under those terms.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+*/
+
+#include "himax_platform.h"
+#include "himax_common.h"
+
+#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
+#define D(x...) pr_info("[HXTP][DEBUG] " x)
+#define I(x...) pr_info("[HXTP][INFO] " x)
+#define W(x...) pr_info("[HXTP][WARNING] " x)
+#define E(x...) pr_info("[HXTP][ERROR] " x)
+#endif
+
+int irq_enable_count = 0;
+#ifdef HX_SMART_WAKEUP
+#define TS_WAKE_LOCK_TIMEOUT (2 * HZ)
+#endif
+
+#define PINCTRL_STATE_ACTIVE "pmx_ts_active"
+#define PINCTRL_STATE_SUSPEND "pmx_ts_suspend"
+#define PINCTRL_STATE_RELEASE "pmx_ts_release"
+
+/*extern int himax_ts_init(struct himax_ts_data *ts);*/
+
+void himax_vk_parser(struct device_node *dt,
+ struct himax_i2c_platform_data *pdata)
+{
+ u32 data = 0;
+ uint8_t cnt = 0, i = 0;
+ uint32_t coords[4] = {0};
+ struct device_node *node, *pp = NULL;
+ struct himax_virtual_key *vk;
+
+ node = of_parse_phandle(dt, "virtualkey", 0);
+ if (node == NULL) {
+ I(" DT-No vk info in DT");
+ return;
+
+ } else {
+ while ((pp = of_get_next_child(node, pp)))
+ cnt++;
+ if (!cnt)
+ return;
+
+ vk = kcalloc(cnt, sizeof(*vk), GFP_KERNEL);
+ pp = NULL;
+ while ((pp = of_get_next_child(node, pp))) {
+ if (of_property_read_u32(pp, "idx", &data) == 0)
+ vk[i].index = data;
+ if (of_property_read_u32_array(pp, "range",
+ coords, 4) == 0) {
+ vk[i].x_range_min = coords[0],
+ vk[i].x_range_max = coords[1];
+ vk[i].y_range_min = coords[2],
+ vk[i].y_range_max = coords[3];
+ } else
+ I(" range faile");
+ i++;
+ }
+ pdata->virtual_key = vk;
+ for (i = 0; i < cnt; i++)
+ I(" vk[%d] idx:%d x_min:%d, y_max:%d",
+ i, pdata->virtual_key[i].index,
+ pdata->virtual_key[i].x_range_min,
+ pdata->virtual_key[i].y_range_max);
+ }
+}
+
+int himax_parse_dt(struct himax_ts_data *ts,
+ struct himax_i2c_platform_data *pdata)
+{
+ int rc, coords_size = 0;
+ uint32_t coords[4] = {0};
+ struct property *prop;
+ struct device_node *dt = ts->client->dev.of_node;
+ u32 data = 0;
+
+ prop = of_find_property(dt, "himax,panel-coords", NULL);
+ if (prop) {
+ coords_size = prop->length / sizeof(u32);
+ if (coords_size != 4)
+ D(" %s:Invalid panel coords size %d",
+ __func__, coords_size);
+ }
+
+ if (of_property_read_u32_array(dt, "himax,panel-coords",
+ coords, coords_size) == 0) {
+ pdata->abs_x_min = coords[0], pdata->abs_x_max = coords[1];
+ pdata->abs_y_min = coords[2], pdata->abs_y_max = coords[3];
+ I(" DT-%s:panel-coords = %d, %d, %d, %d\n",
+ __func__, pdata->abs_x_min, pdata->abs_x_max,
+ pdata->abs_y_min, pdata->abs_y_max);
+ }
+
+ prop = of_find_property(dt, "himax,display-coords", NULL);
+ if (prop) {
+ coords_size = prop->length / sizeof(u32);
+ if (coords_size != 4)
+ D(" %s:Invalid display coords size %d",
+ __func__, coords_size);
+ }
+ rc = of_property_read_u32_array(dt, "himax,display-coords",
+ coords, coords_size);
+ if (rc && (rc != -EINVAL)) {
+ D(" %s:Fail to read display-coords %d\n",
+ __func__, rc);
+ return rc;
+ }
+ pdata->screenWidth = coords[1];
+ pdata->screenHeight = coords[3];
+ I(" DT-%s:display-coords = (%d, %d)", __func__, pdata->screenWidth,
+ pdata->screenHeight);
+
+ pdata->gpio_irq = of_get_named_gpio(dt, "himax,irq-gpio", 0);
+ if (!gpio_is_valid(pdata->gpio_irq))
+ I(" DT:gpio_irq value is not valid\n");
+
+ pdata->gpio_reset = of_get_named_gpio(dt, "himax,rst-gpio", 0);
+ if (!gpio_is_valid(pdata->gpio_reset))
+ I(" DT:gpio_rst value is not valid\n");
+
+ pdata->gpio_3v3_en = of_get_named_gpio(dt, "himax,3v3-gpio", 0);
+ if (!gpio_is_valid(pdata->gpio_3v3_en))
+ I(" DT:gpio_3v3_en value is not valid\n");
+
+ I(" DT:gpio_irq=%d, gpio_rst=%d, gpio_3v3_en=%d",
+ pdata->gpio_irq, pdata->gpio_reset, pdata->gpio_3v3_en);
+
+ if (of_property_read_u32(dt, "report_type", &data) == 0) {
+ pdata->protocol_type = data;
+ I(" DT:protocol_type=%d", pdata->protocol_type);
+ }
+
+ himax_vk_parser(dt, pdata);
+
+ return 0;
+}
+
+int i2c_himax_read(struct i2c_client *client,
+uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry)
+{
+ int retry;
+ struct i2c_msg msg[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 1,
+ .buf = &command,
+ },
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = length,
+ .buf = data,
+ }
+ };
+ mutex_lock(&private_ts->rw_lock);
+ for (retry = 0; retry < toRetry; retry++) {
+ if (i2c_transfer(client->adapter, msg, 2) == 2)
+ break;
+ msleep(20);
+ }
+ if (retry == toRetry) {
+ E("%s: i2c_read_block retry over %d\n",
+ __func__, toRetry);
+ mutex_unlock(&private_ts->rw_lock);
+ return -EIO;
+ }
+ mutex_unlock(&private_ts->rw_lock);
+ return 0;
+
+}
+
+int i2c_himax_write(struct i2c_client *client,
+uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry)
+{
+ int retry/*, loop_i*/;
+ uint8_t buf[length + 1];
+
+ struct i2c_msg msg[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = length + 1,
+ .buf = buf,
+ }
+ };
+
+ buf[0] = command;
+ memcpy(buf+1, data, length);
+ mutex_lock(&private_ts->rw_lock);
+ for (retry = 0; retry < toRetry; retry++) {
+ if (i2c_transfer(client->adapter, msg, 1) == 1)
+ break;
+ msleep(20);
+ }
+
+ if (retry == toRetry) {
+ E("%s: i2c_write_block retry over %d\n",
+ __func__, toRetry);
+ mutex_unlock(&private_ts->rw_lock);
+ return -EIO;
+ }
+ mutex_unlock(&private_ts->rw_lock);
+ return 0;
+
+}
+
+int i2c_himax_read_command(struct i2c_client *client,
+uint8_t length, uint8_t *data, uint8_t *readlength, uint8_t toRetry)
+{
+ int retry;
+ struct i2c_msg msg[] = {
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = length,
+ .buf = data,
+ }
+ };
+ mutex_lock(&private_ts->rw_lock);
+ for (retry = 0; retry < toRetry; retry++) {
+ if (i2c_transfer(client->adapter, msg, 1) == 1)
+ break;
+ msleep(20);
+ }
+ if (retry == toRetry) {
+ E("%s: i2c_read_block retry over %d\n",
+ __func__, toRetry);
+ mutex_unlock(&private_ts->rw_lock);
+ return -EIO;
+ }
+ mutex_unlock(&private_ts->rw_lock);
+ return 0;
+}
+
+int i2c_himax_write_command(struct i2c_client *client,
+uint8_t command, uint8_t toRetry)
+{
+ return i2c_himax_write(client, command, NULL, 0, toRetry);
+}
+
+int i2c_himax_master_write(struct i2c_client *client,
+uint8_t *data, uint8_t length, uint8_t toRetry)
+{
+ int retry/*, loop_i*/;
+ uint8_t buf[length];
+
+ struct i2c_msg msg[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = length,
+ .buf = buf,
+ }
+ };
+
+ memcpy(buf, data, length);
+ mutex_lock(&private_ts->rw_lock);
+ for (retry = 0; retry < toRetry; retry++) {
+ if (i2c_transfer(client->adapter, msg, 1) == 1)
+ break;
+ msleep(20);
+ }
+
+ if (retry == toRetry) {
+ E("%s: i2c_write_block retry over %d\n",
+ __func__, toRetry);
+ mutex_unlock(&private_ts->rw_lock);
+ return -EIO;
+ }
+ mutex_unlock(&private_ts->rw_lock);
+ return 0;
+}
+
+void himax_int_enable(int irqnum, int enable)
+{
+ if (enable == 1 && irq_enable_count == 0) {
+ enable_irq(irqnum);
+ irq_enable_count++;
+ } else if (enable == 0 && irq_enable_count == 1) {
+ disable_irq_nosync(irqnum);
+ irq_enable_count--;
+ }
+ I("irq_enable_count = %d", irq_enable_count);
+}
+
+void himax_rst_gpio_set(int pinnum, uint8_t value)
+{
+ gpio_direction_output(pinnum, value);
+}
+
+uint8_t himax_int_gpio_read(int pinnum)
+{
+ return gpio_get_value(pinnum);
+}
+
+#if defined(CONFIG_HMX_DB)
+static int himax_regulator_configure(struct i2c_client *client,
+struct himax_i2c_platform_data *pdata)
+{
+ int retval;
+
+ pdata->vcc_dig = regulator_get(&client->dev, "vdd");
+ if (IS_ERR(pdata->vcc_dig)) {
+ E("%s: Failed to get regulator vdd\n", __func__);
+ retval = PTR_ERR(pdata->vcc_dig);
+ return retval;
+ }
+ pdata->vcc_ana = regulator_get(&client->dev, "avdd");
+ if (IS_ERR(pdata->vcc_ana)) {
+ E("%s: Failed to get regulator avdd\n", __func__);
+ retval = PTR_ERR(pdata->vcc_ana);
+ regulator_put(pdata->vcc_ana);
+ return retval;
+ }
+
+ return 0;
+};
+
+static int himax_power_on(struct himax_i2c_platform_data *pdata,
+bool on)
+{
+ int retval;
+
+ if (on) {
+ retval = regulator_enable(pdata->vcc_dig);
+ if (retval) {
+ E("%s: Failed to enable regulator vdd\n", __func__);
+ return retval;
+ }
+ msleep(100);
+ retval = regulator_enable(pdata->vcc_ana);
+ if (retval) {
+ E("%s: Failed to enable regulator avdd\n", __func__);
+ regulator_disable(pdata->vcc_dig);
+ return retval;
+ }
+ } else {
+ regulator_disable(pdata->vcc_dig);
+ regulator_disable(pdata->vcc_ana);
+ }
+ return 0;
+}
+
+int himax_ts_pinctrl_init(struct himax_ts_data *ts)
+{
+ int retval;
+
+ /* Get pinctrl if target uses pinctrl */
+ ts->ts_pinctrl = devm_pinctrl_get(&(ts->client->dev));
+ if (IS_ERR_OR_NULL(ts->ts_pinctrl)) {
+ retval = PTR_ERR(ts->ts_pinctrl);
+ dev_dbg(&ts->client->dev, "Target does not use pinctrl %d\n",
+ retval);
+ goto err_pinctrl_get;
+ }
+
+ ts->pinctrl_state_active = pinctrl_lookup_state(ts->ts_pinctrl,
+ PINCTRL_STATE_ACTIVE);
+ if (IS_ERR_OR_NULL(ts->pinctrl_state_active)) {
+ retval = PTR_ERR(ts->pinctrl_state_active);
+ dev_err(&ts->client->dev, "Can not lookup %s pinstate %d\n",
+ PINCTRL_STATE_ACTIVE, retval);
+ goto err_pinctrl_lookup;
+ }
+
+ ts->pinctrl_state_suspend = pinctrl_lookup_state(ts->ts_pinctrl,
+ PINCTRL_STATE_SUSPEND);
+ if (IS_ERR_OR_NULL(ts->pinctrl_state_suspend)) {
+ retval = PTR_ERR(ts->pinctrl_state_suspend);
+ dev_err(&ts->client->dev, "Can not lookup %s pinstate %d\n",
+ PINCTRL_STATE_SUSPEND, retval);
+ goto err_pinctrl_lookup;
+ }
+
+ ts->pinctrl_state_release = pinctrl_lookup_state(ts->ts_pinctrl,
+ PINCTRL_STATE_RELEASE);
+ if (IS_ERR_OR_NULL(ts->pinctrl_state_release)) {
+ retval = PTR_ERR(ts->pinctrl_state_release);
+ dev_dbg(&ts->client->dev, "Can not lookup %s pinstate %d\n",
+ PINCTRL_STATE_RELEASE, retval);
+ }
+
+ return 0;
+
+err_pinctrl_lookup:
+ devm_pinctrl_put(ts->ts_pinctrl);
+err_pinctrl_get:
+ ts->ts_pinctrl = NULL;
+ return retval;
+}
+
+int himax_gpio_power_config(struct i2c_client *client,
+struct himax_i2c_platform_data *pdata)
+{
+ int error;
+
+ error = himax_regulator_configure(client, pdata);
+ if (error) {
+ E("Failed to initialize hardware\n");
+ goto err_regulator_not_on;
+ }
+
+#ifdef HX_RST_PIN_FUNC
+ if (gpio_is_valid(pdata->gpio_reset)) {
+ /* configure touchscreen reset out gpio */
+ error = gpio_request(pdata->gpio_reset, "hmx_reset_gpio");
+ if (error) {
+ E("unable to request gpio [%d]\n",
+ pdata->gpio_reset);
+ goto err_regulator_on;
+ }
+ error = gpio_direction_output(pdata->gpio_reset, 0);
+ if (error) {
+ E("unable to set direction for gpio [%d]\n",
+ pdata->gpio_reset);
+ goto err_gpio_reset_req;
+ }
+ }
+#endif
+
+ error = himax_power_on(pdata, true);
+ if (error) {
+ E("Failed to power on hardware\n");
+ goto err_gpio_reset_req;
+ }
+#ifdef HX_IRQ_PIN_FUNC
+ /* configure touchscreen irq gpio */
+ if (gpio_is_valid(pdata->gpio_irq)) {
+ error = gpio_request(pdata->gpio_irq, "hmx_gpio_irq");
+ if (error) {
+ E("unable to request gpio [%d]\n", pdata->gpio_irq);
+ goto err_power_on;
+ }
+ error = gpio_direction_input(pdata->gpio_irq);
+ if (error) {
+ E("unable to set direction for gpio [%d]\n",
+ pdata->gpio_irq);
+ goto err_gpio_irq_req;
+ }
+ client->irq = gpio_to_irq(pdata->gpio_irq);
+ } else {
+ E("irq gpio not provided\n");
+ goto err_power_on;
+ }
+#endif
+ msleep(20);
+
+#ifdef HX_RST_PIN_FUNC
+ if (gpio_is_valid(pdata->gpio_reset)) {
+ error = gpio_direction_output(pdata->gpio_reset, 1);
+ if (error) {
+ E("unable to set direction for gpio [%d]\n",
+ pdata->gpio_reset);
+ goto err_gpio_irq_req;
+ }
+ }
+#endif
+ return 0;
+#ifdef HX_RST_PIN_FUNC
+err_gpio_irq_req:
+#endif
+#ifdef HX_IRQ_PIN_FUNC
+ if (gpio_is_valid(pdata->gpio_irq))
+ gpio_free(pdata->gpio_irq);
+err_power_on:
+#endif
+ himax_power_on(pdata, false);
+err_gpio_reset_req:
+#ifdef HX_RST_PIN_FUNC
+ if (gpio_is_valid(pdata->gpio_reset))
+ gpio_free(pdata->gpio_reset);
+err_regulator_on:
+#endif
+err_regulator_not_on:
+
+ return error;
+}
+
+#else
+int himax_gpio_power_config(struct i2c_client *client,
+struct himax_i2c_platform_data *pdata)
+{
+ int error = 0;
+
+#ifdef HX_RST_PIN_FUNC
+ if (pdata->gpio_reset >= 0) {
+ error = gpio_request(pdata->gpio_reset, "himax-reset");
+ if (error < 0) {
+ E("%s: request reset pin failed\n", __func__);
+ return error;
+ }
+ error = gpio_direction_output(pdata->gpio_reset, 0);
+ if (error) {
+ E("unable to set direction for gpio [%d]\n",
+ pdata->gpio_reset);
+ return error;
+ }
+ }
+#endif
+ if (pdata->gpio_3v3_en >= 0) {
+ error = gpio_request(pdata->gpio_3v3_en, "himax-3v3_en");
+ if (error < 0) {
+ E("%s: request 3v3_en pin failed\n", __func__);
+ return error;
+ }
+ gpio_direction_output(pdata->gpio_3v3_en, 1);
+ I("3v3_en pin =%d\n", gpio_get_value(pdata->gpio_3v3_en));
+ }
+
+#ifdef HX_IRQ_PIN_FUNC
+ if (gpio_is_valid(pdata->gpio_irq)) {
+ /* configure touchscreen irq gpio */
+ error = gpio_request(pdata->gpio_irq, "himax_gpio_irq");
+ if (error) {
+ E("unable to request gpio [%d]\n", pdata->gpio_irq);
+ return error;
+ }
+ error = gpio_direction_input(pdata->gpio_irq);
+ if (error) {
+ E("unable to set direction for gpio [%d]\n",
+ pdata->gpio_irq);
+ return error;
+ }
+ client->irq = gpio_to_irq(pdata->gpio_irq);
+ } else {
+ E("irq gpio not provided\n");
+ return error;
+ }
+#endif
+
+ msleep(20);
+
+#ifdef HX_RST_PIN_FUNC
+ if (pdata->gpio_reset >= 0) {
+ error = gpio_direction_output(pdata->gpio_reset, 1);
+ if (error) {
+ E("unable to set direction for gpio [%d]\n",
+ pdata->gpio_reset);
+ return error;
+ }
+ }
+ msleep(20);
+#endif
+
+ return error;
+}
+#endif
+
+static void himax_ts_isr_func(struct himax_ts_data *ts)
+{
+ himax_ts_work(ts);
+}
+
+irqreturn_t himax_ts_thread(int irq, void *ptr)
+{
+ uint8_t diag_cmd;
+ struct himax_ts_data *ts = ptr;
+ struct timespec timeStart, timeEnd, timeDelta;
+
+ diag_cmd = getDiagCommand();
+
+ if (ts->debug_log_level & BIT(2)) {
+ getnstimeofday(&timeStart);
+ usleep_range(4999, 5000);
+ /*I(" Irq start time = %ld.%06ld s\n",
+ timeStart.tv_sec, timeStart.tv_nsec/1000);*/
+ }
+
+#ifdef HX_SMART_WAKEUP
+ if (atomic_read(&ts->suspend_mode)
+ && (!FAKE_POWER_KEY_SEND)
+ && (ts->SMWP_enable)
+ && (!diag_cmd)) {
+ __pm_wakeup_event(&ts->ts_SMWP_wake_lock, TS_WAKE_LOCK_TIMEOUT);
+ msleep(200);
+ himax_wake_check_func();
+ return IRQ_HANDLED;
+ }
+#endif
+ himax_ts_isr_func((struct himax_ts_data *)ptr);
+ if (ts->debug_log_level & BIT(2)) {
+ getnstimeofday(&timeEnd);
+ timeDelta.tv_nsec
+ = (timeEnd.tv_sec * 1000000000 + timeEnd.tv_nsec)
+ - (timeStart.tv_sec * 1000000000 + timeStart.tv_nsec);
+ /*I("Irq finish time = %ld.%06ld s\n",
+ timeEnd.tv_sec, timeEnd.tv_nsec/1000);
+ I("Touch latency = %ld us\n", timeDelta.tv_nsec/1000);*/
+ }
+ return IRQ_HANDLED;
+}
+
+static void himax_ts_work_func(struct work_struct *work)
+{
+ struct himax_ts_data *ts =
+ container_of(work, struct himax_ts_data, work);
+
+ himax_ts_work(ts);
+}
+
+int tp_irq = -1;
+
+int himax_ts_register_interrupt(struct i2c_client *client)
+{
+ struct himax_ts_data *ts = i2c_get_clientdata(client);
+ int ret = 0;
+
+ ts->irq_enabled = 0;
+ /*Work functon*/
+ if (client->irq) {/*INT mode*/
+ ts->use_irq = 1;
+ if (ic_data->HX_INT_IS_EDGE) {
+ I("%s edge triiger falling\n ", __func__);
+ ret = request_threaded_irq(client->irq,
+ NULL, himax_ts_thread, IRQF_TRIGGER_FALLING
+ | IRQF_ONESHOT, client->name, ts);
+ } else {
+ I("%s level trigger low\n ", __func__);
+ ret = request_threaded_irq(client->irq,
+ NULL, himax_ts_thread, IRQF_TRIGGER_LOW
+ | IRQF_ONESHOT, client->name, ts);
+ }
+ if (ret == 0) {
+ ts->irq_enabled = 1;
+ irq_enable_count = 1;
+ tp_irq = client->irq;
+ I("%s: irq enabled at qpio: %d\n",
+ __func__, client->irq);
+#ifdef HX_SMART_WAKEUP
+ irq_set_irq_wake(client->irq, 1);
+#endif
+ } else {
+ ts->use_irq = 0;
+ E("%s: request_irq failed\n", __func__);
+ }
+ } else {
+ I("%s: client->irq is empty, use polling mode.\n", __func__);
+ }
+ /*if use polling mode need to disable HX_ESD_WORKAROUND function*/
+ if (!ts->use_irq) {
+ ts->himax_wq = create_singlethread_workqueue("himax_touch");
+
+ INIT_WORK(&ts->work, himax_ts_work_func);
+
+ hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ ts->timer.function = himax_ts_timer_func;
+ hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
+ I("%s: polling mode enabled\n", __func__);
+ }
+ return ret;
+}
+
+static int himax_common_suspend(struct device *dev)
+{
+ struct himax_ts_data *ts = dev_get_drvdata(dev);
+
+ I("%s: enter\n", __func__);
+
+ himax_chip_common_suspend(ts);
+ return 0;
+}
+
+static int himax_common_resume(struct device *dev)
+{
+ struct himax_ts_data *ts = dev_get_drvdata(dev);
+
+ I("%s: enter\n", __func__);
+
+ himax_chip_common_resume(ts);
+ return 0;
+}
+
+#if defined(CONFIG_FB)
+int fb_notifier_callback(struct notifier_block *self,
+ unsigned long event, void *data)
+{
+ struct fb_event *evdata = data;
+ int *blank;
+ struct himax_ts_data *ts
+ = container_of(self, struct himax_ts_data, fb_notif);
+ int ERR = 1;
+
+ I(" %s\n", __func__);
+ if (evdata && evdata->data && event
+ == FB_EVENT_BLANK && ts && ts->client) {
+ blank = evdata->data;
+
+ mutex_lock(&ts->fb_mutex);
+ switch (*blank) {
+ case FB_BLANK_UNBLANK:
+ if (!ts->probe_done) {
+ if (himax_ts_init(ts) == true) {
+ I("himax_ts_init return OK\n");
+ ts->probe_done = true;
+ } else {
+ I("himax_ts_init return Fail\n");
+ return -ERR;
+ }
+ } else
+ himax_common_resume(&ts->client->dev);
+ break;
+
+ case FB_BLANK_POWERDOWN:
+ case FB_BLANK_HSYNC_SUSPEND:
+ case FB_BLANK_VSYNC_SUSPEND:
+ case FB_BLANK_NORMAL:
+ himax_common_suspend(&ts->client->dev);
+ break;
+ }
+ mutex_unlock(&ts->fb_mutex);
+ }
+
+ return 0;
+}
+#endif
+
+static const struct i2c_device_id himax_common_ts_id[] = {
+ {HIMAX_common_NAME, 0 },
+ {}
+};
+
+static const struct dev_pm_ops himax_common_pm_ops = {
+#if (!defined(CONFIG_FB))
+ .suspend = himax_common_suspend,
+ .resume = himax_common_resume,
+#endif
+};
+
+#ifdef CONFIG_OF
+static struct of_device_id himax_match_table[] = {
+ {.compatible = "himax,hxcommon" },
+ {},
+};
+#else
+#define himax_match_table NULL
+#endif
+
+static struct i2c_driver himax_common_driver = {
+ .id_table = himax_common_ts_id,
+ .probe = himax_chip_common_probe,
+ .remove = himax_chip_common_remove,
+ .driver = {
+ .name = HIMAX_common_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = himax_match_table,
+#ifdef CONFIG_PM
+ .pm = &himax_common_pm_ops,
+#endif
+ },
+};
+
+static int __init himax_common_init(void)
+{
+ I("Himax common touch panel driver init\n");
+ i2c_add_driver(&himax_common_driver);
+ return 0;
+}
+
+static void __exit himax_common_exit(void)
+{
+ i2c_del_driver(&himax_common_driver);
+}
+
+module_init(himax_common_init);
+module_exit(himax_common_exit);
+
+MODULE_DESCRIPTION("Himax_common driver");
+MODULE_LICENSE("GPL v2");
+
diff --git a/drivers/input/touchscreen/hxchipset/himax_platform.h b/drivers/input/touchscreen/hxchipset/himax_platform.h
new file mode 100644
index 0000000..6871e53
--- /dev/null
+++ b/drivers/input/touchscreen/hxchipset/himax_platform.h
@@ -0,0 +1,157 @@
+/* Himax Android Driver Sample Code for Himax chipset
+*
+* Copyright (C) 2015 Himax Corporation.
+*
+* This software is licensed under the terms of the GNU General Public
+* License version 2, as published by the Free Software Foundation, and
+* may be copied, distributed, and modified under those terms.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+*/
+
+#ifndef HIMAX_PLATFORM_H
+#define HIMAX_PLATFORM_H
+
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/gpio.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+
+#if defined(CONFIG_HMX_DB)
+#include <linux/regulator/consumer.h>
+#endif
+
+#define QCT
+
+#define HIMAX_I2C_RETRY_TIMES 10
+
+#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
+#define D(x...) pr_info("[HXTP][DEBUG] " x)
+#define I(x...) pr_info("[HXTP][INFO] " x)
+#define W(x...) pr_info("[HXTP][WARNING] " x)
+#define E(x...) pr_info("[HXTP][ERROR] " x)
+#define DIF(x...) do { if (debug_flag) pr_info("[HXTP][DEBUG] " x) } while (0)
+#else
+#define D(x...)
+#define I(x...)
+#define W(x...)
+#define E(x...)
+#define DIF(x...)
+#endif
+
+#if defined(CONFIG_HMX_DB)
+/* Analog voltage @2.7 V */
+#define HX_VTG_MIN_UV 2700000
+#define HX_VTG_MAX_UV 3300000
+#define HX_ACTIVE_LOAD_UA 15000
+#define HX_LPM_LOAD_UA 10
+/* Digital voltage @1.8 V */
+#define HX_VTG_DIG_MIN_UV 1800000
+#define HX_VTG_DIG_MAX_UV 1800000
+#define HX_ACTIVE_LOAD_DIG_UA 10000
+#define HX_LPM_LOAD_DIG_UA 10
+
+#define HX_I2C_VTG_MIN_UV 1800000
+#define HX_I2C_VTG_MAX_UV 1800000
+#define HX_I2C_LOAD_UA 10000
+#define HX_I2C_LPM_LOAD_UA 10
+#endif
+
+#define HIMAX_common_NAME "himax_tp"
+#define HIMAX_I2C_ADDR 0x48
+#define INPUT_DEV_NAME "himax-touchscreen"
+
+struct himax_i2c_platform_data {
+ int abs_x_min;
+ int abs_x_max;
+ int abs_x_fuzz;
+ int abs_y_min;
+ int abs_y_max;
+ int abs_y_fuzz;
+ int abs_pressure_min;
+ int abs_pressure_max;
+ int abs_pressure_fuzz;
+ int abs_width_min;
+ int abs_width_max;
+ int screenWidth;
+ int screenHeight;
+ uint8_t fw_version;
+ uint8_t tw_id;
+ uint8_t powerOff3V3;
+ uint8_t cable_config[2];
+ uint8_t protocol_type;
+ int gpio_irq;
+ int gpio_reset;
+ int gpio_3v3_en;
+ int (*power)(int on);
+ void (*reset)(void);
+ struct himax_virtual_key *virtual_key;
+ struct kobject *vk_obj;
+ struct kobj_attribute *vk2Use;
+
+ struct himax_config *hx_config;
+ int hx_config_size;
+#if defined(CONFIG_HMX_DB)
+ bool i2c_pull_up;
+ bool digital_pwr_regulator;
+ int reset_gpio;
+ u32 reset_gpio_flags;
+ int irq_gpio;
+ u32 irq_gpio_flags;
+
+ struct regulator *vcc_ana; /*For Dragon Board*/
+ struct regulator *vcc_dig; /*For Dragon Board*/
+ struct regulator *vcc_i2c; /*For Dragon Board*/
+#endif
+};
+
+
+extern int irq_enable_count;
+int i2c_himax_read(struct i2c_client *client,
+ uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry);
+
+int i2c_himax_write(struct i2c_client *client,
+ uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry);
+
+int i2c_himax_write_command(struct i2c_client *client,
+ uint8_t command, uint8_t toRetry);
+
+int i2c_himax_master_write(struct i2c_client *client,
+ uint8_t *data, uint8_t length, uint8_t toRetry);
+
+int i2c_himax_read_command(struct i2c_client *client,
+ uint8_t length, uint8_t *data, uint8_t *readlength, uint8_t toRetry);
+
+void himax_int_enable(int irqnum, int enable);
+int himax_ts_register_interrupt(struct i2c_client *client);
+void himax_rst_gpio_set(int pinnum, uint8_t value);
+uint8_t himax_int_gpio_read(int pinnum);
+
+int himax_gpio_power_config(struct i2c_client *client,
+ struct himax_i2c_platform_data *pdata);
+
+#if defined(CONFIG_FB)
+extern int fb_notifier_callback(struct notifier_block *self,
+ unsigned long event, void *data);
+#endif
+extern struct himax_ts_data *private_ts;
+extern struct himax_ic_data *ic_data;
+extern void himax_ts_work(struct himax_ts_data *ts);
+extern enum hrtimer_restart himax_ts_timer_func(struct hrtimer *timer);
+extern int tp_rst_gpio;
+
+#ifdef HX_TP_PROC_DIAG
+extern uint8_t getDiagCommand(void);
+#endif
+
+int himax_parse_dt(struct himax_ts_data *ts,
+ struct himax_i2c_platform_data *pdata);
+int himax_ts_pinctrl_init(struct himax_ts_data *ts);
+
+#endif
diff --git a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_core.c b/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_core.c
index 2a3e663..1436a68 100644
--- a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_core.c
+++ b/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_core.c
@@ -66,6 +66,9 @@
#define IGNORE_FN_INIT_FAILURE
+#define FB_READY_RESET
+#define SDW2500_I2C_ADDR 0x20
+
#define FB_READY_WAIT_MS 100
#define FB_READY_TIMEOUT_S 30
@@ -4731,7 +4734,6 @@
#ifdef FB_READY_RESET
int retval;
#endif
- int retval;
struct synaptics_rmi4_exp_fhandler *exp_fhandler;
struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
@@ -4776,12 +4778,14 @@
}
exit:
-#ifdef FB_READY_RESET
- retval = synaptics_rmi4_reset_device(rmi4_data, false);
- if (retval < 0) {
- dev_err(rmi4_data->pdev->dev.parent,
- "%s: Failed to issue reset command\n",
- __func__);
+ #ifdef FB_READY_RESET
+ if (rmi4_data->hw_if->board_data->i2c_addr != SDW2500_I2C_ADDR) {
+ retval = synaptics_rmi4_reset_device(rmi4_data, false);
+ if (retval < 0) {
+ dev_err(rmi4_data->pdev->dev.parent,
+ "%s: Failed to issue reset command\n",
+ __func__);
+ }
}
#endif
mutex_lock(&exp_data.mutex);
diff --git a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_fw_update.c b/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_fw_update.c
index f4854a9..b3afc71 100644
--- a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_fw_update.c
+++ b/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_fw_update.c
@@ -43,10 +43,9 @@
#include "synaptics_dsx_core.h"
#define FW_IMAGE_NAME "synaptics/startup_fw_update.img"
-/*
+
#define DO_STARTUP_FW_UPDATE
-*/
-/*
+
#ifdef DO_STARTUP_FW_UPDATE
#ifdef CONFIG_FB
#define WAIT_FOR_FB_READY
@@ -54,7 +53,7 @@
#define FB_READY_TIMEOUT_S 30
#endif
#endif
-*/
+
#define FORCE_UPDATE false
#define DO_LOCKDOWN false
@@ -3418,6 +3417,7 @@
enum flash_area flash_area;
const struct firmware *fw_entry = NULL;
struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
+ const unsigned char *image_name;
if (rmi4_data->sensor_sleep) {
dev_err(rmi4_data->pdev->dev.parent,
@@ -3433,9 +3433,14 @@
pr_notice("%s: Start of reflash process\n", __func__);
if (fwu->image == NULL) {
+ if (rmi4_data->hw_if->board_data->fw_name)
+ image_name = rmi4_data->hw_if->board_data->fw_name;
+ else
+ image_name = FW_IMAGE_NAME;
+
retval = secure_memcpy(fwu->image_name, MAX_IMAGE_NAME_LEN,
- FW_IMAGE_NAME, sizeof(FW_IMAGE_NAME),
- sizeof(FW_IMAGE_NAME));
+ image_name, strlen(image_name),
+ strlen(image_name));
if (retval < 0) {
dev_err(rmi4_data->pdev->dev.parent,
"%s: Failed to copy image file name\n",
diff --git a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_i2c.c b/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_i2c.c
index 1098f6a..95ea222 100644
--- a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_i2c.c
+++ b/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_i2c.c
@@ -5,7 +5,8 @@
*
* Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
* Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com>
- * Copyright (C) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2016, 2018 The Linux Foundation. All rights reserved.
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -215,6 +216,12 @@
bdata->ub_i2c_addr = -1;
}
+ retval = of_property_read_string(np, "synaptics,fw-name", &name);
+ if (retval < 0)
+ bdata->fw_name = NULL;
+ else
+ bdata->fw_name = name;
+
prop = of_find_property(np, "synaptics,cap-button-codes", NULL);
if (prop && prop->length) {
bdata->cap_button_map->map = devm_kzalloc(dev,
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index c47429f..33c27f8 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -675,7 +675,7 @@
MPIDR_TO_SGI_AFFINITY(cluster_id, 1) |
tlist << ICC_SGI1R_TARGET_LIST_SHIFT);
- pr_debug("CPU%d: ICC_SGI1R_EL1 %llx\n", smp_processor_id(), val);
+ pr_devel("CPU%d: ICC_SGI1R_EL1 %llx\n", smp_processor_id(), val);
gic_write_sgi1r(val);
}
diff --git a/drivers/isdn/hardware/eicon/diva.c b/drivers/isdn/hardware/eicon/diva.c
index d91dd58..37aaea8 100644
--- a/drivers/isdn/hardware/eicon/diva.c
+++ b/drivers/isdn/hardware/eicon/diva.c
@@ -387,10 +387,10 @@
** Receive and process command from user mode utility
*/
void *diva_xdi_open_adapter(void *os_handle, const void __user *src,
- int length,
+ int length, void *mptr,
divas_xdi_copy_from_user_fn_t cp_fn)
{
- diva_xdi_um_cfg_cmd_t msg;
+ diva_xdi_um_cfg_cmd_t *msg = (diva_xdi_um_cfg_cmd_t *)mptr;
diva_os_xdi_adapter_t *a = NULL;
diva_os_spin_lock_magic_t old_irql;
struct list_head *tmp;
@@ -400,21 +400,21 @@
length, sizeof(diva_xdi_um_cfg_cmd_t)))
return NULL;
}
- if ((*cp_fn) (os_handle, &msg, src, sizeof(msg)) <= 0) {
+ if ((*cp_fn) (os_handle, msg, src, sizeof(*msg)) <= 0) {
DBG_ERR(("A: A(?) open, write error"))
return NULL;
}
diva_os_enter_spin_lock(&adapter_lock, &old_irql, "open_adapter");
list_for_each(tmp, &adapter_queue) {
a = list_entry(tmp, diva_os_xdi_adapter_t, link);
- if (a->controller == (int)msg.adapter)
+ if (a->controller == (int)msg->adapter)
break;
a = NULL;
}
diva_os_leave_spin_lock(&adapter_lock, &old_irql, "open_adapter");
if (!a) {
- DBG_ERR(("A: A(%d) open, adapter not found", msg.adapter))
+ DBG_ERR(("A: A(%d) open, adapter not found", msg->adapter))
}
return (a);
@@ -436,8 +436,10 @@
int
diva_xdi_write(void *adapter, void *os_handle, const void __user *src,
- int length, divas_xdi_copy_from_user_fn_t cp_fn)
+ int length, void *mptr,
+ divas_xdi_copy_from_user_fn_t cp_fn)
{
+ diva_xdi_um_cfg_cmd_t *msg = (diva_xdi_um_cfg_cmd_t *)mptr;
diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) adapter;
void *data;
@@ -458,7 +460,13 @@
return (-2);
}
- length = (*cp_fn) (os_handle, data, src, length);
+ if (msg) {
+ *(diva_xdi_um_cfg_cmd_t *)data = *msg;
+ length = (*cp_fn) (os_handle, (char *)data + sizeof(*msg),
+ src + sizeof(*msg), length - sizeof(*msg));
+ } else {
+ length = (*cp_fn) (os_handle, data, src, length);
+ }
if (length > 0) {
if ((*(a->interface.cmd_proc))
(a, (diva_xdi_um_cfg_cmd_t *) data, length)) {
diff --git a/drivers/isdn/hardware/eicon/diva.h b/drivers/isdn/hardware/eicon/diva.h
index e979085..a0a607c 100644
--- a/drivers/isdn/hardware/eicon/diva.h
+++ b/drivers/isdn/hardware/eicon/diva.h
@@ -19,10 +19,11 @@
int max_length, divas_xdi_copy_to_user_fn_t cp_fn);
int diva_xdi_write(void *adapter, void *os_handle, const void __user *src,
- int length, divas_xdi_copy_from_user_fn_t cp_fn);
+ int length, void *msg,
+ divas_xdi_copy_from_user_fn_t cp_fn);
void *diva_xdi_open_adapter(void *os_handle, const void __user *src,
- int length,
+ int length, void *msg,
divas_xdi_copy_from_user_fn_t cp_fn);
void diva_xdi_close_adapter(void *adapter, void *os_handle);
diff --git a/drivers/isdn/hardware/eicon/divasmain.c b/drivers/isdn/hardware/eicon/divasmain.c
index a2e0ed6..91bd2ba 100644
--- a/drivers/isdn/hardware/eicon/divasmain.c
+++ b/drivers/isdn/hardware/eicon/divasmain.c
@@ -591,19 +591,22 @@
static ssize_t divas_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
+ diva_xdi_um_cfg_cmd_t msg;
int ret = -EINVAL;
if (!file->private_data) {
file->private_data = diva_xdi_open_adapter(file, buf,
- count,
+ count, &msg,
xdi_copy_from_user);
- }
- if (!file->private_data) {
- return (-ENODEV);
+ if (!file->private_data)
+ return (-ENODEV);
+ ret = diva_xdi_write(file->private_data, file,
+ buf, count, &msg, xdi_copy_from_user);
+ } else {
+ ret = diva_xdi_write(file->private_data, file,
+ buf, count, NULL, xdi_copy_from_user);
}
- ret = diva_xdi_write(file->private_data, file,
- buf, count, xdi_copy_from_user);
switch (ret) {
case -1: /* Message should be removed from rx mailbox first */
ret = -EBUSY;
@@ -622,11 +625,12 @@
static ssize_t divas_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
+ diva_xdi_um_cfg_cmd_t msg;
int ret = -EINVAL;
if (!file->private_data) {
file->private_data = diva_xdi_open_adapter(file, buf,
- count,
+ count, &msg,
xdi_copy_from_user);
}
if (!file->private_data) {
diff --git a/drivers/md/bcache/alloc.c b/drivers/md/bcache/alloc.c
index f8c5bc7..d6427a7 100644
--- a/drivers/md/bcache/alloc.c
+++ b/drivers/md/bcache/alloc.c
@@ -285,8 +285,10 @@
break; \
\
mutex_unlock(&(ca)->set->bucket_lock); \
- if (kthread_should_stop()) \
+ if (kthread_should_stop()) { \
+ set_current_state(TASK_RUNNING); \
return 0; \
+ } \
\
try_to_freeze(); \
schedule(); \
diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
index dfdd190..b4812b1 100644
--- a/drivers/md/bcache/bcache.h
+++ b/drivers/md/bcache/bcache.h
@@ -922,7 +922,7 @@
int bch_flash_dev_create(struct cache_set *c, uint64_t size);
-int bch_cached_dev_attach(struct cached_dev *, struct cache_set *);
+int bch_cached_dev_attach(struct cached_dev *, struct cache_set *, uint8_t *);
void bch_cached_dev_detach(struct cached_dev *);
void bch_cached_dev_run(struct cached_dev *);
void bcache_device_stop(struct bcache_device *);
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c
index e53ce5e..5a8c401 100644
--- a/drivers/md/bcache/btree.c
+++ b/drivers/md/bcache/btree.c
@@ -1869,14 +1869,17 @@
*/
for_each_cache(ca, c, i) {
for_each_bucket(b, ca) {
- if (fifo_full(&ca->free[RESERVE_PRIO]))
+ if (fifo_full(&ca->free[RESERVE_PRIO]) &&
+ fifo_full(&ca->free[RESERVE_BTREE]))
break;
if (bch_can_invalidate_bucket(ca, b) &&
!GC_MARK(b)) {
__bch_invalidate_one_bucket(ca, b);
- fifo_push(&ca->free[RESERVE_PRIO],
- b - ca->buckets);
+ if (!fifo_push(&ca->free[RESERVE_PRIO],
+ b - ca->buckets))
+ fifo_push(&ca->free[RESERVE_BTREE],
+ b - ca->buckets);
}
}
}
diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c
index 92c7692..ac8f1ac 100644
--- a/drivers/md/bcache/request.c
+++ b/drivers/md/bcache/request.c
@@ -631,11 +631,11 @@
static void search_free(struct closure *cl)
{
struct search *s = container_of(cl, struct search, cl);
- bio_complete(s);
if (s->iop.bio)
bio_put(s->iop.bio);
+ bio_complete(s);
closure_debug_destroy(cl);
mempool_free(s, s->d->c->search);
}
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index cb98bad..e41760e 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -967,7 +967,8 @@
cached_dev_put(dc);
}
-int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c)
+int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c,
+ uint8_t *set_uuid)
{
uint32_t rtime = cpu_to_le32(get_seconds());
struct uuid_entry *u;
@@ -975,7 +976,8 @@
bdevname(dc->bdev, buf);
- if (memcmp(dc->sb.set_uuid, c->sb.set_uuid, 16))
+ if ((set_uuid && memcmp(set_uuid, c->sb.set_uuid, 16)) ||
+ (!set_uuid && memcmp(dc->sb.set_uuid, c->sb.set_uuid, 16)))
return -ENOENT;
if (dc->disk.c) {
@@ -1209,7 +1211,7 @@
list_add(&dc->list, &uncached_devices);
list_for_each_entry(c, &bch_cache_sets, list)
- bch_cached_dev_attach(dc, c);
+ bch_cached_dev_attach(dc, c, NULL);
if (BDEV_STATE(&dc->sb) == BDEV_STATE_NONE ||
BDEV_STATE(&dc->sb) == BDEV_STATE_STALE)
@@ -1729,7 +1731,7 @@
bcache_write_super(c);
list_for_each_entry_safe(dc, t, &uncached_devices, list)
- bch_cached_dev_attach(dc, c);
+ bch_cached_dev_attach(dc, c, NULL);
flash_devs_run(c);
@@ -1848,6 +1850,7 @@
static int cache_alloc(struct cache_sb *sb, struct cache *ca)
{
size_t free;
+ size_t btree_buckets;
struct bucket *b;
__module_get(THIS_MODULE);
@@ -1857,9 +1860,19 @@
ca->journal.bio.bi_max_vecs = 8;
ca->journal.bio.bi_io_vec = ca->journal.bio.bi_inline_vecs;
+ /*
+ * when ca->sb.njournal_buckets is not zero, journal exists,
+ * and in bch_journal_replay(), tree node may split,
+ * so bucket of RESERVE_BTREE type is needed,
+ * the worst situation is all journal buckets are valid journal,
+ * and all the keys need to replay,
+ * so the number of RESERVE_BTREE type buckets should be as much
+ * as journal buckets
+ */
+ btree_buckets = ca->sb.njournal_buckets ?: 8;
free = roundup_pow_of_two(ca->sb.nbuckets) >> 10;
- if (!init_fifo(&ca->free[RESERVE_BTREE], 8, GFP_KERNEL) ||
+ if (!init_fifo(&ca->free[RESERVE_BTREE], btree_buckets, GFP_KERNEL) ||
!init_fifo_exact(&ca->free[RESERVE_PRIO], prio_buckets(ca), GFP_KERNEL) ||
!init_fifo(&ca->free[RESERVE_MOVINGGC], free, GFP_KERNEL) ||
!init_fifo(&ca->free[RESERVE_NONE], free, GFP_KERNEL) ||
diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c
index 4fbb553..5a5c1f1 100644
--- a/drivers/md/bcache/sysfs.c
+++ b/drivers/md/bcache/sysfs.c
@@ -191,7 +191,7 @@
{
struct cached_dev *dc = container_of(kobj, struct cached_dev,
disk.kobj);
- ssize_t v = size;
+ ssize_t v;
struct cache_set *c;
struct kobj_uevent_env *env;
@@ -263,17 +263,20 @@
}
if (attr == &sysfs_attach) {
- if (bch_parse_uuid(buf, dc->sb.set_uuid) < 16)
+ uint8_t set_uuid[16];
+
+ if (bch_parse_uuid(buf, set_uuid) < 16)
return -EINVAL;
+ v = -ENOENT;
list_for_each_entry(c, &bch_cache_sets, list) {
- v = bch_cached_dev_attach(dc, c);
+ v = bch_cached_dev_attach(dc, c, set_uuid);
if (!v)
return size;
}
pr_err("Can't attach %s: cache set not found", buf);
- size = v;
+ return v;
}
if (attr == &sysfs_detach && dc->disk.c)
diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c
index b0667b3..6e3fae2 100644
--- a/drivers/md/bcache/writeback.c
+++ b/drivers/md/bcache/writeback.c
@@ -425,19 +425,28 @@
while (!kthread_should_stop()) {
down_write(&dc->writeback_lock);
- if (!atomic_read(&dc->has_dirty) ||
- (!test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags) &&
- !dc->writeback_running)) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ /*
+ * If the bache device is detaching, skip here and continue
+ * to perform writeback. Otherwise, if no dirty data on cache,
+ * or there is dirty data on cache but writeback is disabled,
+ * the writeback thread should sleep here and wait for others
+ * to wake up it.
+ */
+ if (!test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags) &&
+ (!atomic_read(&dc->has_dirty) || !dc->writeback_running)) {
up_write(&dc->writeback_lock);
- set_current_state(TASK_INTERRUPTIBLE);
- if (kthread_should_stop())
+ if (kthread_should_stop()) {
+ set_current_state(TASK_RUNNING);
return 0;
+ }
try_to_freeze();
schedule();
continue;
}
+ set_current_state(TASK_RUNNING);
searched_full_index = refill_dirty(dc);
@@ -447,6 +456,14 @@
cached_dev_put(dc);
SET_BDEV_STATE(&dc->sb, BDEV_STATE_CLEAN);
bch_write_bdev_super(dc, NULL);
+ /*
+ * If bcache device is detaching via sysfs interface,
+ * writeback thread should stop after there is no dirty
+ * data on cache. BCACHE_DEV_DETACHING flag is set in
+ * bch_cached_dev_detach().
+ */
+ if (test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags))
+ break;
}
up_write(&dc->writeback_lock);
diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c
index 169d176..e5235c8 100644
--- a/drivers/md/dm-bufio.c
+++ b/drivers/md/dm-bufio.c
@@ -801,12 +801,14 @@
static struct dm_buffer *__alloc_buffer_wait_no_callback(struct dm_bufio_client *c, enum new_flag nf)
{
struct dm_buffer *b;
+ bool tried_noio_alloc = false;
/*
* dm-bufio is resistant to allocation failures (it just keeps
* one buffer reserved in cases all the allocations fail).
* So set flags to not try too hard:
- * GFP_NOIO: don't recurse into the I/O layer
+ * GFP_NOWAIT: don't wait; if we need to sleep we'll release our
+ * mutex and wait ourselves.
* __GFP_NORETRY: don't retry and rather return failure
* __GFP_NOMEMALLOC: don't use emergency reserves
* __GFP_NOWARN: don't print a warning in case of failure
@@ -816,7 +818,7 @@
*/
while (1) {
if (dm_bufio_cache_size_latch != 1) {
- b = alloc_buffer(c, GFP_NOIO | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN);
+ b = alloc_buffer(c, GFP_NOWAIT | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN);
if (b)
return b;
}
@@ -824,6 +826,15 @@
if (nf == NF_PREFETCH)
return NULL;
+ if (dm_bufio_cache_size_latch != 1 && !tried_noio_alloc) {
+ dm_bufio_unlock(c);
+ b = alloc_buffer(c, GFP_NOIO | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN);
+ dm_bufio_lock(c);
+ if (b)
+ return b;
+ tried_noio_alloc = true;
+ }
+
if (!list_empty(&c->reserved_buffers)) {
b = list_entry(c->reserved_buffers.next,
struct dm_buffer, lru_list);
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
index 9dfe2bb..0e8d19b 100644
--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -992,6 +992,8 @@
static void set_pool_mode(struct pool *pool, enum pool_mode new_mode);
+static void requeue_bios(struct pool *pool);
+
static void check_for_space(struct pool *pool)
{
int r;
@@ -1004,8 +1006,10 @@
if (r)
return;
- if (nr_free)
+ if (nr_free) {
set_pool_mode(pool, PM_WRITE);
+ requeue_bios(pool);
+ }
}
/*
@@ -1082,7 +1086,10 @@
r = dm_pool_alloc_data_block(pool->pmd, result);
if (r) {
- metadata_operation_failed(pool, "dm_pool_alloc_data_block", r);
+ if (r == -ENOSPC)
+ set_pool_mode(pool, PM_OUT_OF_DATA_SPACE);
+ else
+ metadata_operation_failed(pool, "dm_pool_alloc_data_block", r);
return r;
}
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 63e5725..3064a6e 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1722,6 +1722,17 @@
struct md_rdev *repl =
conf->mirrors[conf->raid_disks + number].rdev;
freeze_array(conf, 0);
+ if (atomic_read(&repl->nr_pending)) {
+ /* It means that some queued IO of retry_list
+ * hold repl. Thus, we cannot set replacement
+ * as NULL, avoiding rdev NULL pointer
+ * dereference in sync_request_write and
+ * handle_write_finished.
+ */
+ err = -EBUSY;
+ unfreeze_array(conf);
+ goto abort;
+ }
clear_bit(Replacement, &repl->flags);
p->rdev = repl;
conf->mirrors[conf->raid_disks + number].rdev = NULL;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 5952db6..b19149e 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -2754,7 +2754,8 @@
for (m = 0; m < conf->copies; m++) {
int dev = r10_bio->devs[m].devnum;
rdev = conf->mirrors[dev].rdev;
- if (r10_bio->devs[m].bio == NULL)
+ if (r10_bio->devs[m].bio == NULL ||
+ r10_bio->devs[m].bio->bi_end_io == NULL)
continue;
if (test_bit(BIO_UPTODATE,
&r10_bio->devs[m].bio->bi_flags)) {
@@ -2770,7 +2771,8 @@
md_error(conf->mddev, rdev);
}
rdev = conf->mirrors[dev].replacement;
- if (r10_bio->devs[m].repl_bio == NULL)
+ if (r10_bio->devs[m].repl_bio == NULL ||
+ r10_bio->devs[m].repl_bio->bi_end_io == NULL)
continue;
if (test_bit(BIO_UPTODATE,
&r10_bio->devs[m].repl_bio->bi_flags)) {
diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index 61b94150..e5b559f 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -224,8 +224,20 @@
wake_up_interruptible (&events->wait_queue);
}
+static int dvb_frontend_test_event(struct dvb_frontend_private *fepriv,
+ struct dvb_fe_events *events)
+{
+ int ret;
+
+ up(&fepriv->sem);
+ ret = events->eventw != events->eventr;
+ down(&fepriv->sem);
+
+ return ret;
+}
+
static int dvb_frontend_get_event(struct dvb_frontend *fe,
- struct dvb_frontend_event *event, int flags)
+ struct dvb_frontend_event *event, int flags)
{
struct dvb_frontend_private *fepriv = fe->frontend_priv;
struct dvb_fe_events *events = &fepriv->events;
@@ -243,13 +255,8 @@
if (flags & O_NONBLOCK)
return -EWOULDBLOCK;
- up(&fepriv->sem);
-
- ret = wait_event_interruptible (events->wait_queue,
- events->eventw != events->eventr);
-
- if (down_interruptible (&fepriv->sem))
- return -ERESTARTSYS;
+ ret = wait_event_interruptible(events->wait_queue,
+ dvb_frontend_test_event(fepriv, events));
if (ret < 0)
return ret;
diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c
index 5025512..d96582b 100644
--- a/drivers/media/i2c/cx25840/cx25840-core.c
+++ b/drivers/media/i2c/cx25840/cx25840-core.c
@@ -467,8 +467,13 @@
{
DEFINE_WAIT(wait);
struct cx25840_state *state = to_state(i2c_get_clientdata(client));
+ u32 clk_freq = 0;
struct workqueue_struct *q;
+ /* cx23885 sets hostdata to clk_freq pointer */
+ if (v4l2_get_subdev_hostdata(&state->sd))
+ clk_freq = *((u32 *)v4l2_get_subdev_hostdata(&state->sd));
+
/*
* Come out of digital power down
* The CX23888, at least, needs this, otherwise registers aside from
@@ -504,8 +509,13 @@
* 50.0 MHz * (0xb + 0xe8ba26/0x2000000)/4 = 5 * 28.636363 MHz
* 572.73 MHz before post divide
*/
- /* HVR1850 or 50MHz xtal */
- cx25840_write(client, 0x2, 0x71);
+ if (clk_freq == 25000000) {
+ /* 888/ImpactVCBe or 25Mhz xtal */
+ ; /* nothing to do */
+ } else {
+ /* HVR1850 or 50MHz xtal */
+ cx25840_write(client, 0x2, 0x71);
+ }
cx25840_write4(client, 0x11c, 0x01d1744c);
cx25840_write4(client, 0x118, 0x00000416);
cx25840_write4(client, 0x404, 0x0010253e);
@@ -548,9 +558,15 @@
/* HVR1850 */
switch (state->id) {
case CX23888_AV:
- /* 888/HVR1250 specific */
- cx25840_write4(client, 0x10c, 0x13333333);
- cx25840_write4(client, 0x108, 0x00000515);
+ if (clk_freq == 25000000) {
+ /* 888/ImpactVCBe or 25MHz xtal */
+ cx25840_write4(client, 0x10c, 0x01b6db7b);
+ cx25840_write4(client, 0x108, 0x00000512);
+ } else {
+ /* 888/HVR1250 or 50MHz xtal */
+ cx25840_write4(client, 0x10c, 0x13333333);
+ cx25840_write4(client, 0x108, 0x00000515);
+ }
break;
default:
cx25840_write4(client, 0x10c, 0x002be2c9);
@@ -577,7 +593,7 @@
* 368.64 MHz before post divide
* 122.88 MHz / 0xa = 12.288 MHz
*/
- /* HVR1850 or 50MHz xtal */
+ /* HVR1850 or 50MHz xtal or 25MHz xtal */
cx25840_write4(client, 0x114, 0x017dbf48);
cx25840_write4(client, 0x110, 0x000a030e);
break;
diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c
index 3778188..f74cd5b 100644
--- a/drivers/media/pci/cx23885/cx23885-cards.c
+++ b/drivers/media/pci/cx23885/cx23885-cards.c
@@ -1950,6 +1950,10 @@
&dev->i2c_bus[2].i2c_adap,
"cx25840", 0x88 >> 1, NULL);
if (dev->sd_cx25840) {
+ /* set host data for clk_freq configuration */
+ v4l2_set_subdev_hostdata(dev->sd_cx25840,
+ &dev->clk_freq);
+
dev->sd_cx25840->grp_id = CX23885_HW_AV_CORE;
v4l2_subdev_call(dev->sd_cx25840, core, load_fw);
}
diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c
index 3bd386c..0196696 100644
--- a/drivers/media/pci/cx23885/cx23885-core.c
+++ b/drivers/media/pci/cx23885/cx23885-core.c
@@ -870,6 +870,16 @@
if (cx23885_boards[dev->board].clk_freq > 0)
dev->clk_freq = cx23885_boards[dev->board].clk_freq;
+ if (dev->board == CX23885_BOARD_HAUPPAUGE_IMPACTVCBE &&
+ dev->pci->subsystem_device == 0x7137) {
+ /* Hauppauge ImpactVCBe device ID 0x7137 is populated
+ * with an 888, and a 25Mhz crystal, instead of the
+ * usual third overtone 50Mhz. The default clock rate must
+ * be overridden so the cx25840 is properly configured
+ */
+ dev->clk_freq = 25000000;
+ }
+
dev->pci_bus = dev->pci->bus->number;
dev->pci_slot = PCI_SLOT(dev->pci->devfn);
cx23885_irq_add(dev, 0x001f00);
diff --git a/drivers/media/pci/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c
index e81173c..34335ce 100644
--- a/drivers/media/pci/cx25821/cx25821-core.c
+++ b/drivers/media/pci/cx25821/cx25821-core.c
@@ -871,6 +871,10 @@
dev->nr = ++cx25821_devcount;
sprintf(dev->name, "cx25821[%d]", dev->nr);
+ if (dev->nr >= ARRAY_SIZE(card)) {
+ CX25821_INFO("dev->nr >= %zd", ARRAY_SIZE(card));
+ return -ENODEV;
+ }
if (dev->pci->device != 0x8210) {
pr_info("%s(): Exiting. Incorrect Hardware device = 0x%02x\n",
__func__, dev->pci->device);
@@ -887,9 +891,6 @@
dev->channels[i].sram_channels = &cx25821_sram_channels[i];
}
- if (dev->nr > 1)
- CX25821_INFO("dev->nr > 1!");
-
/* board config */
dev->board = 1; /* card[dev->nr]; */
dev->_max_num_decoders = MAX_DECODERS;
diff --git a/drivers/media/platform/msm/ais/jpeg_10/msm_jpeg_dev.c b/drivers/media/platform/msm/ais/jpeg_10/msm_jpeg_dev.c
index a0a6ffd..a2232e6 100644
--- a/drivers/media/platform/msm/ais/jpeg_10/msm_jpeg_dev.c
+++ b/drivers/media/platform/msm/ais/jpeg_10/msm_jpeg_dev.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -32,6 +32,8 @@
#define MSM_JPEG_NAME "jpeg"
#define DEV_NAME_LEN 10
+static char devname[DEV_NAME_LEN];
+
static int msm_jpeg_open(struct inode *inode, struct file *filp)
{
int rc = 0;
@@ -185,7 +187,6 @@
struct msm_jpeg_device *msm_jpeg_device_p;
const struct of_device_id *device_id;
const struct msm_jpeg_priv_data *priv_data;
- char devname[DEV_NAME_LEN];
msm_jpeg_device_p = kzalloc(sizeof(struct msm_jpeg_device), GFP_ATOMIC);
if (!msm_jpeg_device_p) {
diff --git a/drivers/media/platform/msm/ais/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/ais/pproc/cpp/msm_cpp.c
index d265210..37891ad 100644
--- a/drivers/media/platform/msm/ais/pproc/cpp/msm_cpp.c
+++ b/drivers/media/platform/msm/ais/pproc/cpp/msm_cpp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -836,9 +836,14 @@
if (irq_status & 0x8) {
tx_level = msm_camera_io_r(cpp_dev->base +
MSM_CPP_MICRO_FIFO_TX_STAT) >> 2;
- for (i = 0; i < tx_level; i++) {
- tx_fifo[i] = msm_camera_io_r(cpp_dev->base +
- MSM_CPP_MICRO_FIFO_TX_DATA);
+ if (tx_level < MSM_CPP_TX_FIFO_LEVEL) {
+ for (i = 0; i < tx_level; i++) {
+ tx_fifo[i] = msm_camera_io_r(cpp_dev->base +
+ MSM_CPP_MICRO_FIFO_TX_DATA);
+ }
+ } else {
+ pr_err("Fatal invalid tx level %d", tx_level);
+ goto err;
}
spin_lock_irqsave(&cpp_dev->tasklet_lock, flags);
queue_cmd = &cpp_dev->tasklet_queue_cmd[cpp_dev->taskletq_idx];
@@ -893,6 +898,7 @@
pr_debug("DEBUG_R1: 0x%x\n",
msm_camera_io_r(cpp_dev->base + 0x8C));
}
+err:
msm_camera_io_w(irq_status, cpp_dev->base + MSM_CPP_MICRO_IRQGEN_CLR);
return IRQ_HANDLED;
}
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_dev.c b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_dev.c
index de27e58..48f53f1 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_dev.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_dev.c
@@ -32,6 +32,8 @@
#define MSM_JPEG_NAME "jpeg"
#define DEV_NAME_LEN 10
+static char devname[DEV_NAME_LEN];
+
static int msm_jpeg_open(struct inode *inode, struct file *filp)
{
int rc = 0;
@@ -185,7 +187,6 @@
struct msm_jpeg_device *msm_jpeg_device_p;
const struct of_device_id *device_id;
const struct msm_jpeg_priv_data *priv_data;
- char devname[DEV_NAME_LEN];
msm_jpeg_device_p = kzalloc(sizeof(struct msm_jpeg_device), GFP_ATOMIC);
if (!msm_jpeg_device_p) {
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
index f98d1ef..b38ce49 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -833,9 +833,14 @@
if (irq_status & 0x8) {
tx_level = msm_camera_io_r(cpp_dev->base +
MSM_CPP_MICRO_FIFO_TX_STAT) >> 2;
- for (i = 0; i < tx_level; i++) {
- tx_fifo[i] = msm_camera_io_r(cpp_dev->base +
- MSM_CPP_MICRO_FIFO_TX_DATA);
+ if (tx_level < MSM_CPP_TX_FIFO_LEVEL) {
+ for (i = 0; i < tx_level; i++) {
+ tx_fifo[i] = msm_camera_io_r(cpp_dev->base +
+ MSM_CPP_MICRO_FIFO_TX_DATA);
+ }
+ } else {
+ pr_err("Fatal invalid tx level %d", tx_level);
+ goto err;
}
spin_lock_irqsave(&cpp_dev->tasklet_lock, flags);
queue_cmd = &cpp_dev->tasklet_queue_cmd[cpp_dev->taskletq_idx];
@@ -890,6 +895,7 @@
pr_debug("DEBUG_R1: 0x%x\n",
msm_camera_io_r(cpp_dev->base + 0x8C));
}
+err:
msm_camera_io_w(irq_status, cpp_dev->base + MSM_CPP_MICRO_IRQGEN_CLR);
return IRQ_HANDLED;
}
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index 0343e3f..9e279c4 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1385,7 +1385,7 @@
.name = "Set Color space transfer characterstics",
.type = V4L2_CTRL_TYPE_INTEGER,
.minimum = MSM_VIDC_TRANSFER_BT709_5,
- .maximum = MSM_VIDC_TRANSFER_BT_2020_12,
+ .maximum = MSM_VIDC_TRANSFER_HLG,
.default_value = MSM_VIDC_TRANSFER_601_6_625,
.step = 1,
.qmenu = NULL,
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 8390363..6bae3e9c 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -2447,7 +2447,6 @@
}
hdev = inst->core->device;
abort_completion = SESSION_MSG_INDEX(HAL_SESSION_ABORT_DONE);
- init_completion(&inst->completions[abort_completion]);
rc = call_hfi_op(hdev, session_abort, (void *)inst->session);
if (rc) {
@@ -2606,8 +2605,6 @@
__func__);
}
- init_completion(&core->completions
- [SYS_MSG_INDEX(HAL_SYS_INIT_DONE)]);
rc = call_hfi_op(hdev, core_init, hdev->hfi_device_data);
if (rc) {
dprintk(VIDC_ERR, "Failed to init core, id = %d\n",
@@ -2711,8 +2708,6 @@
dprintk(VIDC_ERR, "Invalid session\n");
return -EINVAL;
}
- init_completion(
- &inst->completions[SESSION_MSG_INDEX(HAL_SESSION_INIT_DONE)]);
rc = call_hfi_op(hdev, session_init, hdev->hfi_device_data,
inst, get_hal_domain(inst->session_type),
@@ -2850,8 +2845,6 @@
inst, inst->state);
goto exit;
}
- init_completion(
- &inst->completions[SESSION_MSG_INDEX(HAL_SESSION_START_DONE)]);
rc = call_hfi_op(hdev, session_start, (void *) inst->session);
if (rc) {
dprintk(VIDC_ERR,
@@ -2881,8 +2874,6 @@
goto exit;
}
dprintk(VIDC_DBG, "Send Stop to hal\n");
- init_completion(
- &inst->completions[SESSION_MSG_INDEX(HAL_SESSION_STOP_DONE)]);
rc = call_hfi_op(hdev, session_stop, (void *) inst->session);
if (rc) {
dprintk(VIDC_ERR, "Failed to send stop\n");
@@ -2912,8 +2903,6 @@
}
dprintk(VIDC_DBG,
"Send release res to hal\n");
- init_completion(&inst->completions[
- SESSION_MSG_INDEX(HAL_SESSION_RELEASE_RESOURCE_DONE)]);
rc = call_hfi_op(hdev, session_release_res, (void *) inst->session);
if (rc) {
dprintk(VIDC_ERR,
@@ -2944,8 +2933,6 @@
}
dprintk(VIDC_DBG,
"Send session close to hal\n");
- init_completion(
- &inst->completions[SESSION_MSG_INDEX(HAL_SESSION_END_DONE)]);
rc = call_hfi_op(hdev, session_end, (void *) inst->session);
if (rc) {
dprintk(VIDC_ERR,
@@ -3983,8 +3970,6 @@
}
mutex_unlock(&inst->sync_lock);
- init_completion(&inst->completions[
- SESSION_MSG_INDEX(HAL_SESSION_PROPERTY_INFO)]);
switch (ptype) {
case HAL_PARAM_PROFILE_LEVEL_CURRENT:
case HAL_CONFIG_VDEC_ENTROPY:
@@ -4208,8 +4193,6 @@
if (inst->state != MSM_VIDC_CORE_INVALID &&
core->state != VIDC_CORE_INVALID) {
buffer_info.response_required = true;
- init_completion(&inst->completions[SESSION_MSG_INDEX
- (HAL_SESSION_RELEASE_BUFFER_DONE)]);
rc = call_hfi_op(hdev, session_release_buffers,
(void *)inst->session, &buffer_info);
if (rc) {
@@ -4280,9 +4263,6 @@
if (inst->state != MSM_VIDC_CORE_INVALID &&
core->state != VIDC_CORE_INVALID) {
buffer_info.response_required = true;
- init_completion(
- &inst->completions[SESSION_MSG_INDEX
- (HAL_SESSION_RELEASE_BUFFER_DONE)]);
rc = call_hfi_op(hdev, session_release_buffers,
(void *)inst->session, &buffer_info);
if (rc) {
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index 081459d..2e1bd37 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -937,8 +937,6 @@
return rc;
}
-static DECLARE_COMPLETION(release_resources_done);
-
static int __alloc_imem(struct venus_hfi_device *device, unsigned long size)
{
struct imem *imem = NULL;
@@ -2158,8 +2156,6 @@
dev = device;
mutex_lock(&dev->lock);
- init_completion(&release_resources_done);
-
rc = __load_fw(dev);
if (rc) {
dprintk(VIDC_ERR, "Failed to load Venus FW\n");
@@ -3461,7 +3457,6 @@
break;
case HAL_SYS_RELEASE_RESOURCE_DONE:
dprintk(VIDC_DBG, "Received SYS_RELEASE_RESOURCE\n");
- complete(&release_resources_done);
break;
case HAL_SYS_INIT_DONE:
dprintk(VIDC_DBG, "Received SYS_INIT_DONE\n");
diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c
index df33e72..97a52d4 100644
--- a/drivers/media/platform/s3c-camif/camif-capture.c
+++ b/drivers/media/platform/s3c-camif/camif-capture.c
@@ -1280,16 +1280,17 @@
{
const struct s3c_camif_variant *variant = camif->variant;
const struct vp_pix_limits *pix_lim;
- int i = ARRAY_SIZE(camif_mbus_formats);
+ unsigned int i;
/* FIXME: constraints against codec or preview path ? */
pix_lim = &variant->vp_pix_limits[VP_CODEC];
- while (i-- >= 0)
+ for (i = 0; i < ARRAY_SIZE(camif_mbus_formats); i++)
if (camif_mbus_formats[i] == mf->code)
break;
- mf->code = camif_mbus_formats[i];
+ if (i == ARRAY_SIZE(camif_mbus_formats))
+ mf->code = camif_mbus_formats[0];
if (pad == CAMIF_SD_PAD_SINK) {
v4l_bound_align_image(&mf->width, 8, CAMIF_MAX_PIX_WIDTH,
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c
index 9592ba8..dc92777 100644
--- a/drivers/media/usb/cx231xx/cx231xx-cards.c
+++ b/drivers/media/usb/cx231xx/cx231xx-cards.c
@@ -805,6 +805,9 @@
.driver_info = CX231XX_BOARD_CNXT_RDE_250},
{USB_DEVICE(0x0572, 0x58A0),
.driver_info = CX231XX_BOARD_CNXT_RDU_250},
+ /* AverMedia DVD EZMaker 7 */
+ {USB_DEVICE(0x07ca, 0xc039),
+ .driver_info = CX231XX_BOARD_CNXT_VIDEO_GRABBER},
{USB_DEVICE(0x2040, 0xb110),
.driver_info = CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL},
{USB_DEVICE(0x2040, 0xb111),
diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h
index a21a746..0b4825e 100644
--- a/drivers/media/usb/em28xx/em28xx.h
+++ b/drivers/media/usb/em28xx/em28xx.h
@@ -183,7 +183,7 @@
USB 2.0 spec says bulk packet size is always 512 bytes
*/
#define EM28XX_BULK_PACKET_MULTIPLIER 384
-#define EM28XX_DVB_BULK_PACKET_MULTIPLIER 384
+#define EM28XX_DVB_BULK_PACKET_MULTIPLIER 94
#define EM28XX_INTERLACED_DEFAULT 1
diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index 8886db8..8ba134d 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -862,7 +862,7 @@
get_user(kcontrols, &kp->controls))
return -EFAULT;
- if (!count)
+ if (!count || count > (U32_MAX/sizeof(*ucontrols)))
return 0;
if (get_user(p, &up->controls))
return -EFAULT;
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index fc73937..227164a 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -2694,6 +2694,8 @@
__FILE__, __LINE__, iocnum);
return -ENODEV;
}
+ if (karg.hdr.id >= MPT_MAX_FC_DEVICES)
+ return -EINVAL;
dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_hp_targetinfo called.\n",
ioc->name));
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index bd068dc..a2c41d9 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -8716,6 +8716,7 @@
static int qseecom_remove(struct platform_device *pdev)
{
struct qseecom_registered_kclient_list *kclient = NULL;
+ struct qseecom_registered_kclient_list *kclient_tmp = NULL;
unsigned long flags = 0;
int ret = 0;
int i;
@@ -8725,10 +8726,8 @@
atomic_set(&qseecom.qseecom_state, QSEECOM_STATE_NOT_READY);
spin_lock_irqsave(&qseecom.registered_kclient_list_lock, flags);
- list_for_each_entry(kclient, &qseecom.registered_kclient_list_head,
- list) {
- if (!kclient)
- goto exit_irqrestore;
+ list_for_each_entry_safe(kclient, kclient_tmp,
+ &qseecom.registered_kclient_list_head, list) {
/* Break the loop if client handle is NULL */
if (!kclient->handle)
@@ -8752,7 +8751,7 @@
kzfree(kclient->handle);
exit_free_kclient:
kzfree(kclient);
-exit_irqrestore:
+
spin_unlock_irqrestore(&qseecom.registered_kclient_list_lock, flags);
if (qseecom.qseos_version > QSEEE_VERSION_00)
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index df6371a..551dab3 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -766,7 +766,7 @@
mmc_hostname(card->host), __func__);
}
cmd_rel_host_halt:
- mmc_release_host(card->host);
+ mmc_put_card(card);
cmd_done:
mmc_blk_put(md);
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 3096f3d..8e2a7d0 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -45,6 +45,7 @@
#define I82802AB 0x00ad
#define I82802AC 0x00ac
#define PF38F4476 0x881c
+#define M28F00AP30 0x8963
/* STMicroelectronics chips */
#define M50LPW080 0x002F
#define M50FLW080A 0x0080
@@ -375,6 +376,17 @@
extp->MinorVersion = '1';
}
+static int cfi_is_micron_28F00AP30(struct cfi_private *cfi, struct flchip *chip)
+{
+ /*
+ * Micron(was Numonyx) 1Gbit bottom boot are buggy w.r.t
+ * Erase Supend for their small Erase Blocks(0x8000)
+ */
+ if (cfi->mfr == CFI_MFR_INTEL && cfi->id == M28F00AP30)
+ return 1;
+ return 0;
+}
+
static inline struct cfi_pri_intelext *
read_pri_intelext(struct map_info *map, __u16 adr)
{
@@ -825,21 +837,30 @@
(mode == FL_WRITING && (cfip->SuspendCmdSupport & 1))))
goto sleep;
+ /* Do not allow suspend iff read/write to EB address */
+ if ((adr & chip->in_progress_block_mask) ==
+ chip->in_progress_block_addr)
+ goto sleep;
+
+ /* do not suspend small EBs, buggy Micron Chips */
+ if (cfi_is_micron_28F00AP30(cfi, chip) &&
+ (chip->in_progress_block_mask == ~(0x8000-1)))
+ goto sleep;
/* Erase suspend */
- map_write(map, CMD(0xB0), adr);
+ map_write(map, CMD(0xB0), chip->in_progress_block_addr);
/* If the flash has finished erasing, then 'erase suspend'
* appears to make some (28F320) flash devices switch to
* 'read' mode. Make sure that we switch to 'read status'
* mode so we get the right data. --rmk
*/
- map_write(map, CMD(0x70), adr);
+ map_write(map, CMD(0x70), chip->in_progress_block_addr);
chip->oldstate = FL_ERASING;
chip->state = FL_ERASE_SUSPENDING;
chip->erase_suspended = 1;
for (;;) {
- status = map_read(map, adr);
+ status = map_read(map, chip->in_progress_block_addr);
if (map_word_andequal(map, status, status_OK, status_OK))
break;
@@ -1035,8 +1056,8 @@
sending the 0x70 (Read Status) command to an erasing
chip and expecting it to be ignored, that's what we
do. */
- map_write(map, CMD(0xd0), adr);
- map_write(map, CMD(0x70), adr);
+ map_write(map, CMD(0xd0), chip->in_progress_block_addr);
+ map_write(map, CMD(0x70), chip->in_progress_block_addr);
chip->oldstate = FL_READY;
chip->state = FL_ERASING;
break;
@@ -1927,6 +1948,8 @@
map_write(map, CMD(0xD0), adr);
chip->state = FL_ERASING;
chip->erase_suspended = 0;
+ chip->in_progress_block_addr = adr;
+ chip->in_progress_block_mask = ~(len - 1);
ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
adr, len,
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index c50d8cf..529115b 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -42,7 +42,7 @@
#define AMD_BOOTLOC_BUG
#define FORCE_WORD_WRITE 0
-#define MAX_WORD_RETRIES 3
+#define MAX_RETRIES 3
#define SST49LF004B 0x0060
#define SST49LF040B 0x0050
@@ -814,9 +814,10 @@
(mode == FL_WRITING && (cfip->EraseSuspend & 0x2))))
goto sleep;
- /* We could check to see if we're trying to access the sector
- * that is currently being erased. However, no user will try
- * anything like that so we just wait for the timeout. */
+ /* Do not allow suspend iff read/write to EB address */
+ if ((adr & chip->in_progress_block_mask) ==
+ chip->in_progress_block_addr)
+ goto sleep;
/* Erase suspend */
/* It's harmless to issue the Erase-Suspend and Erase-Resume
@@ -1644,7 +1645,7 @@
map_write( map, CMD(0xF0), chip->start );
/* FIXME - should have reset delay before continuing */
- if (++retry_cnt <= MAX_WORD_RETRIES)
+ if (++retry_cnt <= MAX_RETRIES)
goto retry;
ret = -EIO;
@@ -1877,7 +1878,7 @@
if (time_after(jiffies, timeo) && !chip_ready(map, adr))
break;
- if (chip_ready(map, adr)) {
+ if (chip_good(map, adr, datum)) {
xip_enable(map, chip, adr);
goto op_done;
}
@@ -2103,7 +2104,7 @@
map_write(map, CMD(0xF0), chip->start);
/* FIXME - should have reset delay before continuing */
- if (++retry_cnt <= MAX_WORD_RETRIES)
+ if (++retry_cnt <= MAX_RETRIES)
goto retry;
ret = -EIO;
@@ -2238,6 +2239,7 @@
unsigned long int adr;
DECLARE_WAITQUEUE(wait, current);
int ret = 0;
+ int retry_cnt = 0;
adr = cfi->addr_unlock1;
@@ -2255,6 +2257,7 @@
ENABLE_VPP(map);
xip_disable(map, chip, adr);
+ retry:
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
@@ -2265,6 +2268,7 @@
chip->state = FL_ERASING;
chip->erase_suspended = 0;
chip->in_progress_block_addr = adr;
+ chip->in_progress_block_mask = ~(map->size - 1);
INVALIDATE_CACHE_UDELAY(map, chip,
adr, map->size,
@@ -2290,12 +2294,13 @@
chip->erase_suspended = 0;
}
- if (chip_ready(map, adr))
+ if (chip_good(map, adr, map_word_ff(map)))
break;
if (time_after(jiffies, timeo)) {
printk(KERN_WARNING "MTD %s(): software timeout\n",
__func__ );
+ ret = -EIO;
break;
}
@@ -2303,12 +2308,15 @@
UDELAY(map, chip, adr, 1000000/HZ);
}
/* Did we succeed? */
- if (!chip_good(map, adr, map_word_ff(map))) {
+ if (ret) {
/* reset on all failures. */
map_write( map, CMD(0xF0), chip->start );
/* FIXME - should have reset delay before continuing */
- ret = -EIO;
+ if (++retry_cnt <= MAX_RETRIES) {
+ ret = 0;
+ goto retry;
+ }
}
chip->state = FL_READY;
@@ -2327,6 +2335,7 @@
unsigned long timeo = jiffies + HZ;
DECLARE_WAITQUEUE(wait, current);
int ret = 0;
+ int retry_cnt = 0;
adr += chip->start;
@@ -2344,6 +2353,7 @@
ENABLE_VPP(map);
xip_disable(map, chip, adr);
+ retry:
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
@@ -2354,6 +2364,7 @@
chip->state = FL_ERASING;
chip->erase_suspended = 0;
chip->in_progress_block_addr = adr;
+ chip->in_progress_block_mask = ~(len - 1);
INVALIDATE_CACHE_UDELAY(map, chip,
adr, len,
@@ -2379,7 +2390,7 @@
chip->erase_suspended = 0;
}
- if (chip_ready(map, adr)) {
+ if (chip_good(map, adr, map_word_ff(map))) {
xip_enable(map, chip, adr);
break;
}
@@ -2388,6 +2399,7 @@
xip_enable(map, chip, adr);
printk(KERN_WARNING "MTD %s(): software timeout\n",
__func__ );
+ ret = -EIO;
break;
}
@@ -2395,12 +2407,15 @@
UDELAY(map, chip, adr, 1000000/HZ);
}
/* Did we succeed? */
- if (!chip_good(map, adr, map_word_ff(map))) {
+ if (ret) {
/* reset on all failures. */
map_write( map, CMD(0xF0), chip->start );
/* FIXME - should have reset delay before continuing */
- ret = -EIO;
+ if (++retry_cnt <= MAX_RETRIES) {
+ ret = 0;
+ goto retry;
+ }
}
chip->state = FL_READY;
@@ -2530,7 +2545,7 @@
struct ppb_lock {
struct flchip *chip;
- loff_t offset;
+ unsigned long adr;
int locked;
};
@@ -2548,8 +2563,9 @@
unsigned long timeo;
int ret;
+ adr += chip->start;
mutex_lock(&chip->mutex);
- ret = get_chip(map, chip, adr + chip->start, FL_LOCKING);
+ ret = get_chip(map, chip, adr, FL_LOCKING);
if (ret) {
mutex_unlock(&chip->mutex);
return ret;
@@ -2567,8 +2583,8 @@
if (thunk == DO_XXLOCK_ONEBLOCK_LOCK) {
chip->state = FL_LOCKING;
- map_write(map, CMD(0xA0), chip->start + adr);
- map_write(map, CMD(0x00), chip->start + adr);
+ map_write(map, CMD(0xA0), adr);
+ map_write(map, CMD(0x00), adr);
} else if (thunk == DO_XXLOCK_ONEBLOCK_UNLOCK) {
/*
* Unlocking of one specific sector is not supported, so we
@@ -2606,7 +2622,7 @@
map_write(map, CMD(0x00), chip->start);
chip->state = FL_READY;
- put_chip(map, chip, adr + chip->start);
+ put_chip(map, chip, adr);
mutex_unlock(&chip->mutex);
return ret;
@@ -2663,9 +2679,9 @@
* sectors shall be unlocked, so lets keep their locking
* status at "unlocked" (locked=0) for the final re-locking.
*/
- if ((adr < ofs) || (adr >= (ofs + len))) {
+ if ((offset < ofs) || (offset >= (ofs + len))) {
sect[sectors].chip = &cfi->chips[chipnum];
- sect[sectors].offset = offset;
+ sect[sectors].adr = adr;
sect[sectors].locked = do_ppb_xxlock(
map, &cfi->chips[chipnum], adr, 0,
DO_XXLOCK_ONEBLOCK_GETLOCK);
@@ -2679,6 +2695,8 @@
i++;
if (adr >> cfi->chipshift) {
+ if (offset >= (ofs + len))
+ break;
adr = 0;
chipnum++;
@@ -2709,7 +2727,7 @@
*/
for (i = 0; i < sectors; i++) {
if (sect[i].locked)
- do_ppb_xxlock(map, sect[i].chip, sect[i].offset, 0,
+ do_ppb_xxlock(map, sect[i].chip, sect[i].adr, 0,
DO_XXLOCK_ONEBLOCK_LOCK);
}
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index dba262b..7cf0473 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -49,7 +49,7 @@
#define NFC_V1_V2_CONFIG (host->regs + 0x0a)
#define NFC_V1_V2_ECC_STATUS_RESULT (host->regs + 0x0c)
#define NFC_V1_V2_RSLTMAIN_AREA (host->regs + 0x0e)
-#define NFC_V1_V2_RSLTSPARE_AREA (host->regs + 0x10)
+#define NFC_V21_RSLTSPARE_AREA (host->regs + 0x10)
#define NFC_V1_V2_WRPROT (host->regs + 0x12)
#define NFC_V1_UNLOCKSTART_BLKADDR (host->regs + 0x14)
#define NFC_V1_UNLOCKEND_BLKADDR (host->regs + 0x16)
@@ -958,6 +958,9 @@
writew(config1, NFC_V1_V2_CONFIG1);
/* preset operation */
+ /* spare area size in 16-bit half-words */
+ writew(mtd->oobsize / 2, NFC_V21_RSLTSPARE_AREA);
+
/* Unlock the internal RAM Buffer */
writew(0x2, NFC_V1_V2_CONFIG);
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c
index 65b35e0a..9c763e1 100644
--- a/drivers/mtd/ubi/eba.c
+++ b/drivers/mtd/ubi/eba.c
@@ -350,6 +350,82 @@
return err;
}
+#ifdef CONFIG_MTD_UBI_FASTMAP
+/**
+ * check_mapping - check and fixup a mapping
+ * @ubi: UBI device description object
+ * @vol: volume description object
+ * @lnum: logical eraseblock number
+ * @pnum: physical eraseblock number
+ *
+ * Checks whether a given mapping is valid. Fastmap cannot track LEB unmap
+ * operations, if such an operation is interrupted the mapping still looks
+ * good, but upon first read an ECC is reported to the upper layer.
+ * Normaly during the full-scan at attach time this is fixed, for Fastmap
+ * we have to deal with it while reading.
+ * If the PEB behind a LEB shows this symthom we change the mapping to
+ * %UBI_LEB_UNMAPPED and schedule the PEB for erasure.
+ *
+ * Returns 0 on success, negative error code in case of failure.
+ */
+static int check_mapping(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
+ int *pnum)
+{
+ int err;
+ struct ubi_vid_hdr *vid_hdr;
+
+ if (!ubi->fast_attach)
+ return 0;
+
+ vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS);
+ if (!vid_hdr)
+ return -ENOMEM;
+
+ err = ubi_io_read_vid_hdr(ubi, *pnum, vid_hdr, 0);
+ if (err > 0 && err != UBI_IO_BITFLIPS) {
+ int torture = 0;
+
+ switch (err) {
+ case UBI_IO_FF:
+ case UBI_IO_FF_BITFLIPS:
+ case UBI_IO_BAD_HDR:
+ case UBI_IO_BAD_HDR_EBADMSG:
+ break;
+ default:
+ ubi_assert(0);
+ }
+
+ if (err == UBI_IO_BAD_HDR_EBADMSG || err == UBI_IO_FF_BITFLIPS)
+ torture = 1;
+
+ down_read(&ubi->fm_sem);
+ vol->eba_tbl[lnum] = UBI_LEB_UNMAPPED;
+ up_read(&ubi->fm_sem);
+ ubi_wl_put_peb(ubi, vol->vol_id, lnum, *pnum, torture);
+
+ *pnum = UBI_LEB_UNMAPPED;
+ } else if (err < 0) {
+ ubi_err("unable to read VID header back from PEB %i: %i",
+ *pnum, err);
+
+ goto out_free;
+ }
+
+ err = 0;
+
+out_free:
+ ubi_free_vid_hdr(ubi, vid_hdr);
+
+ return err;
+}
+#else
+static int check_mapping(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
+ int *pnum)
+{
+ return 0;
+}
+#endif
+
/**
* ubi_eba_read_leb - read data.
* @ubi: UBI device description object
@@ -381,7 +457,13 @@
return err;
pnum = vol->eba_tbl[lnum];
- if (pnum < 0) {
+ if (pnum >= 0) {
+ err = check_mapping(ubi, vol, lnum, &pnum);
+ if (err < 0)
+ goto out_unlock;
+ }
+
+ if (pnum == UBI_LEB_UNMAPPED) {
/*
* The logical eraseblock is not mapped, fill the whole buffer
* with 0xFF bytes. The exception is static volumes for which
@@ -689,6 +771,14 @@
pnum = vol->eba_tbl[lnum];
if (pnum >= 0) {
+ err = check_mapping(ubi, vol, lnum, &pnum);
+ if (err < 0) {
+ leb_write_unlock(ubi, vol_id, lnum);
+ return err;
+ }
+ }
+
+ if (pnum >= 0) {
dbg_eba("write %d bytes at offset %d of LEB %d:%d, PEB %d",
len, offset, vol_id, lnum, pnum);
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 4a692845..bb54622 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -453,7 +453,7 @@
{
int i;
- if (!client_info->slave)
+ if (!client_info->slave || !is_valid_ether_addr(client_info->mac_dst))
return;
for (i = 0; i < RLB_ARP_BURST_SIZE; i++) {
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
index 031b687..85db2a5 100644
--- a/drivers/net/can/dev.c
+++ b/drivers/net/can/dev.c
@@ -471,7 +471,7 @@
{
struct can_priv *priv = netdev_priv(dev);
- netdev_dbg(dev, "bus-off\n");
+ netdev_info(dev, "bus-off\n");
netif_carrier_off(dev);
priv->can_stats.bus_off++;
diff --git a/drivers/net/can/spi/k61.c b/drivers/net/can/spi/k61.c
index 303fc95..6bb9204 100644
--- a/drivers/net/can/spi/k61.c
+++ b/drivers/net/can/spi/k61.c
@@ -99,6 +99,8 @@
#define CMD_CAN_RELEASE_BUFFER 0x89
#define CMD_CAN_DATA_BUFF_REMOVE_ALL 0x8A
#define CMD_UPDATE_TIME_INFO 0x9D
+#define CMD_SUSPEND_EVENT 0x9E
+#define CMD_RESUME_EVENT 0x9F
#define IOCTL_RELEASE_CAN_BUFFER (SIOCDEVPRIVATE + 0)
#define IOCTL_ENABLE_BUFFERING (SIOCDEVPRIVATE + 1)
@@ -389,6 +391,30 @@
return ret;
}
+static int k61_notify_power_events(struct k61_can *priv_data, u8 event_type)
+{
+ char *tx_buf, *rx_buf;
+ int ret;
+ struct spi_mosi *req;
+
+ mutex_lock(&priv_data->spi_lock);
+ tx_buf = priv_data->tx_buf;
+ rx_buf = priv_data->rx_buf;
+ memset(tx_buf, 0, XFER_BUFFER_SIZE);
+ memset(rx_buf, 0, XFER_BUFFER_SIZE);
+ priv_data->xfer_length = XFER_BUFFER_SIZE;
+
+ req = (struct spi_mosi *)tx_buf;
+ req->cmd = event_type;
+ req->len = 0;
+ req->seq = atomic_inc_return(&priv_data->msg_seq);
+
+ ret = k61_do_spi_transaction(priv_data);
+ mutex_unlock(&priv_data->spi_lock);
+
+ return ret;
+}
+
static int k61_can_write(struct k61_can *priv_data, struct can_frame *cf)
{
char *tx_buf, *rx_buf;
@@ -825,6 +851,7 @@
int err, retry = 0, query_err = -1;
struct k61_can *priv_data;
struct device *dev;
+ u32 irq_type;
dev = &spi->dev;
dev_dbg(dev, "k61_probe");
@@ -881,8 +908,11 @@
goto unregister_candev;
}
+ irq_type = irq_get_trigger_type(spi->irq);
+ if (irq_type == IRQ_TYPE_NONE)
+ irq_type = IRQ_TYPE_EDGE_FALLING;
err = request_threaded_irq(spi->irq, NULL, k61_irq,
- IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ irq_type | IRQF_ONESHOT,
"k61", priv_data);
if (err) {
dev_err(dev, "Failed to request irq: %d", err);
@@ -936,7 +966,10 @@
static int k61_suspend(struct device *dev)
{
struct spi_device *spi = to_spi_device(dev);
+ struct k61_can *priv_data = spi_get_drvdata(spi);
+ u8 power_event = CMD_SUSPEND_EVENT;
+ k61_notify_power_events(priv_data, power_event);
enable_irq_wake(spi->irq);
return 0;
}
@@ -945,9 +978,10 @@
{
struct spi_device *spi = to_spi_device(dev);
struct k61_can *priv_data = spi_get_drvdata(spi);
+ u8 power_event = CMD_RESUME_EVENT;
disable_irq_wake(spi->irq);
- k61_rx_message(priv_data);
+ k61_notify_power_events(priv_data, power_event);
return 0;
}
diff --git a/drivers/net/can/spi/qti-can.c b/drivers/net/can/spi/qti-can.c
index 8667614..9ffa7e9 100644
--- a/drivers/net/can/spi/qti-can.c
+++ b/drivers/net/can/spi/qti-can.c
@@ -1263,6 +1263,7 @@
int err, retry = 0, query_err = -1, i;
struct qti_can *priv_data = NULL;
struct device *dev;
+ u32 irq_type;
dev = &spi->dev;
dev_info(dev, "qti_can_probe");
@@ -1339,7 +1340,7 @@
}
priv_data->support_can_fd = of_property_read_bool(spi->dev.of_node,
- "support-can-fd");
+ "qcom,support-can-fd");
if (of_device_is_compatible(spi->dev.of_node, "qcom,nxp,mpc5746c"))
qti_can_bittiming_const = flexcan_bittiming_const;
@@ -1369,8 +1370,11 @@
}
}
+ irq_type = irq_get_trigger_type(spi->irq);
+ if (irq_type == IRQ_TYPE_NONE)
+ irq_type = IRQ_TYPE_EDGE_FALLING;
err = request_threaded_irq(spi->irq, NULL, qti_can_irq,
- IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ irq_type | IRQF_ONESHOT,
"qti-can", priv_data);
if (err) {
LOGDE("Failed to request irq: %d", err);
diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c
index 355914a..a50b32b 100644
--- a/drivers/net/can/usb/kvaser_usb.c
+++ b/drivers/net/can/usb/kvaser_usb.c
@@ -850,7 +850,7 @@
skb = alloc_can_skb(priv->netdev, &cf);
if (!skb) {
- stats->tx_dropped++;
+ stats->rx_dropped++;
return;
}
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index 549549e..8beea27 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -588,7 +588,7 @@
* slots for the highest priority.
*/
REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS :
- NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
+ NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
/* Mapping between the CREDIT_WEIGHT registers and actual client
* numbers
*/
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 397bc86..4dbe218 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -8705,14 +8705,15 @@
tg3_mem_rx_release(tp);
tg3_mem_tx_release(tp);
- /* Protect tg3_get_stats64() from reading freed tp->hw_stats. */
- tg3_full_lock(tp, 0);
+ /* tp->hw_stats can be referenced safely:
+ * 1. under rtnl_lock
+ * 2. or under tp->lock if TG3_FLAG_INIT_COMPLETE is set.
+ */
if (tp->hw_stats) {
dma_free_coherent(&tp->pdev->dev, sizeof(struct tg3_hw_stats),
tp->hw_stats, tp->stats_mapping);
tp->hw_stats = NULL;
}
- tg3_full_unlock(tp);
}
/*
@@ -14137,7 +14138,7 @@
struct tg3 *tp = netdev_priv(dev);
spin_lock_bh(&tp->lock);
- if (!tp->hw_stats) {
+ if (!tp->hw_stats || !tg3_flag(tp, INIT_COMPLETE)) {
*stats = tp->net_stats_prev;
spin_unlock_bh(&tp->lock);
return stats;
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index 167cd8e..14b19aa 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -2362,11 +2362,11 @@
pci_set_master(pdev);
/* Query PCI controller on system for DMA addressing
- * limitation for the device. Try 64-bit first, and
+ * limitation for the device. Try 47-bit first, and
* fail to 32-bit.
*/
- err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(47));
if (err) {
err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
@@ -2380,10 +2380,10 @@
goto err_out_release_regions;
}
} else {
- err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(47));
if (err) {
dev_err(dev, "Unable to obtain %u-bit DMA "
- "for consistent allocations, aborting\n", 64);
+ "for consistent allocations, aborting\n", 47);
goto err_out_release_regions;
}
using_dac = 1;
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c
index 227f833..24b4df8 100644
--- a/drivers/net/ethernet/intel/e1000e/ich8lan.c
+++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c
@@ -1441,7 +1441,7 @@
* we have already determined whether we have link or not.
*/
if (!mac->autoneg)
- return -E1000_ERR_CONFIG;
+ return 1;
/* Auto-Neg is enabled. Auto Speed Detection takes care
* of MAC speed/duplex configuration. So we only need to
diff --git a/drivers/net/ethernet/intel/e1000e/mac.c b/drivers/net/ethernet/intel/e1000e/mac.c
index 1c9cb53..3aa3e9e8 100644
--- a/drivers/net/ethernet/intel/e1000e/mac.c
+++ b/drivers/net/ethernet/intel/e1000e/mac.c
@@ -450,7 +450,7 @@
* we have already determined whether we have link or not.
*/
if (!mac->autoneg)
- return -E1000_ERR_CONFIG;
+ return 1;
/* Auto-Neg is enabled. Auto Speed Detection takes care
* of MAC speed/duplex configuration. So we only need to
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index d4c788a..0bf0d12 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -2330,8 +2330,8 @@
{
struct pci_dev *pdev = adapter->pdev;
- ring->desc = dma_alloc_coherent(&pdev->dev, ring->size, &ring->dma,
- GFP_KERNEL);
+ ring->desc = dma_zalloc_coherent(&pdev->dev, ring->size, &ring->dma,
+ GFP_KERNEL);
if (!ring->desc)
return -ENOMEM;
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index a53e7c6..b6ac976 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -748,6 +748,7 @@
}
mvreg_write(pp, MVNETA_TXQ_CMD, q_map);
+ q_map = 0;
/* Enable all initialized RXQs. */
q_map = 0;
for (queue = 0; queue < rxq_number; queue++) {
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
index ae83da9..a3f355d 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
@@ -453,6 +453,22 @@
if (!coal->tx_max_coalesced_frames_irq)
return -EINVAL;
+ if (coal->tx_coalesce_usecs > MLX4_EN_MAX_COAL_TIME ||
+ coal->rx_coalesce_usecs > MLX4_EN_MAX_COAL_TIME ||
+ coal->rx_coalesce_usecs_low > MLX4_EN_MAX_COAL_TIME ||
+ coal->rx_coalesce_usecs_high > MLX4_EN_MAX_COAL_TIME) {
+ netdev_info(dev, "%s: maximum coalesce time supported is %d usecs\n",
+ __func__, MLX4_EN_MAX_COAL_TIME);
+ return -ERANGE;
+ }
+
+ if (coal->tx_max_coalesced_frames > MLX4_EN_MAX_COAL_PKTS ||
+ coal->rx_max_coalesced_frames > MLX4_EN_MAX_COAL_PKTS) {
+ netdev_info(dev, "%s: maximum coalesced frames supported is %d\n",
+ __func__, MLX4_EN_MAX_COAL_PKTS);
+ return -ERANGE;
+ }
+
priv->rx_frames = (coal->rx_max_coalesced_frames ==
MLX4_EN_AUTO_CONF) ?
MLX4_EN_RX_COAL_TARGET :
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index 4f90806..76a5b93 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -138,6 +138,9 @@
#define MLX4_EN_TX_COAL_PKTS 16
#define MLX4_EN_TX_COAL_TIME 0x10
+#define MLX4_EN_MAX_COAL_PKTS U16_MAX
+#define MLX4_EN_MAX_COAL_TIME U16_MAX
+
#define MLX4_EN_RX_RATE_LOW 400000
#define MLX4_EN_RX_COAL_TIME_LOW 0
#define MLX4_EN_RX_RATE_HIGH 450000
@@ -535,8 +538,8 @@
u16 rx_usecs_low;
u32 pkt_rate_high;
u16 rx_usecs_high;
- u16 sample_interval;
- u16 adaptive_rx_coal;
+ u32 sample_interval;
+ u32 adaptive_rx_coal;
u32 msg_enable;
u32 loopback_ok;
u32 validate_loopback;
diff --git a/drivers/net/ethernet/mellanox/mlx4/qp.c b/drivers/net/ethernet/mellanox/mlx4/qp.c
index 87e0074..4b588a3 100644
--- a/drivers/net/ethernet/mellanox/mlx4/qp.c
+++ b/drivers/net/ethernet/mellanox/mlx4/qp.c
@@ -363,11 +363,11 @@
struct mlx4_qp_table *qp_table = &mlx4_priv(dev)->qp_table;
struct mlx4_qp *qp;
- spin_lock(&qp_table->lock);
+ spin_lock_irq(&qp_table->lock);
qp = __mlx4_qp_lookup(dev, qpn);
- spin_unlock(&qp_table->lock);
+ spin_unlock_irq(&qp_table->lock);
return qp;
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
index dea4ade..7eff69f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
@@ -1371,7 +1371,7 @@
cmd->checksum_disabled = 1;
cmd->max_reg_cmds = (1 << cmd->log_sz) - 1;
- cmd->bitmask = (1 << cmd->max_reg_cmds) - 1;
+ cmd->bitmask = (1UL << cmd->max_reg_cmds) - 1;
cmd->cmdif_rev = ioread32be(&dev->iseg->cmdif_rev_fw_sub) >> 16;
if (cmd->cmdif_rev > CMD_IF_REV) {
diff --git a/drivers/net/ethernet/natsemi/sonic.c b/drivers/net/ethernet/natsemi/sonic.c
index 1bd419d..0798b4a 100644
--- a/drivers/net/ethernet/natsemi/sonic.c
+++ b/drivers/net/ethernet/natsemi/sonic.c
@@ -71,7 +71,7 @@
for (i = 0; i < SONIC_NUM_RRS; i++) {
dma_addr_t laddr = dma_map_single(lp->device, skb_put(lp->rx_skb[i], SONIC_RBSIZE),
SONIC_RBSIZE, DMA_FROM_DEVICE);
- if (!laddr) {
+ if (dma_mapping_error(lp->device, laddr)) {
while(i > 0) { /* free any that were mapped successfully */
i--;
dma_unmap_single(lp->device, lp->rx_laddr[i], SONIC_RBSIZE, DMA_FROM_DEVICE);
diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c
index 007b38c..7858f2b 100644
--- a/drivers/net/ethernet/realtek/8139too.c
+++ b/drivers/net/ethernet/realtek/8139too.c
@@ -2215,7 +2215,7 @@
struct rtl8139_private *tp = netdev_priv(dev);
const int irq = tp->pci_dev->irq;
- disable_irq(irq);
+ disable_irq_nosync(irq);
rtl8139_interrupt(irq, dev);
enable_irq(irq);
}
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index abaf73c..d1ea2df 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -4764,6 +4764,9 @@
static void rtl_pll_power_up(struct rtl8169_private *tp)
{
rtl_generic_op(tp, tp->pll_power_ops.up);
+
+ /* give MAC/PHY some time to resume */
+ msleep(20);
}
static void rtl_init_pll_power_ops(struct rtl8169_private *tp)
diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c
index 904fd1a..68738aa 100644
--- a/drivers/net/ethernet/sun/niu.c
+++ b/drivers/net/ethernet/sun/niu.c
@@ -3443,7 +3443,7 @@
len = (val & RCR_ENTRY_L2_LEN) >>
RCR_ENTRY_L2_LEN_SHIFT;
- len -= ETH_FCS_LEN;
+ append_size = len + ETH_HLEN + ETH_FCS_LEN;
addr = (val & RCR_ENTRY_PKT_BUF_ADDR) <<
RCR_ENTRY_PKT_BUF_ADDR_SHIFT;
@@ -3453,7 +3453,6 @@
RCR_ENTRY_PKTBUFSZ_SHIFT];
off = addr & ~PAGE_MASK;
- append_size = rcr_size;
if (num_rcr == 1) {
int ptype;
@@ -3466,7 +3465,7 @@
else
skb_checksum_none_assert(skb);
} else if (!(val & RCR_ENTRY_MULTI))
- append_size = len - skb->len;
+ append_size = append_size - skb->len;
niu_rx_skb_append(skb, page, off, append_size, rcr_size);
if ((page->index + rp->rbr_block_size) - rcr_size == addr) {
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c
index c5789cdf..cd93ba7 100644
--- a/drivers/net/phy/dp83640.c
+++ b/drivers/net/phy/dp83640.c
@@ -1173,6 +1173,23 @@
kfree(dp83640);
}
+static int dp83640_soft_reset(struct phy_device *phydev)
+{
+ int ret;
+
+ ret = genphy_soft_reset(phydev);
+ if (ret < 0)
+ return ret;
+
+ /* From DP83640 datasheet: "Software driver code must wait 3 us
+ * following a software reset before allowing further serial MII
+ * operations with the DP83640."
+ */
+ udelay(10); /* Taking udelay inaccuracy into account */
+
+ return 0;
+}
+
static int dp83640_config_init(struct phy_device *phydev)
{
struct dp83640_private *dp83640 = phydev->priv;
@@ -1470,6 +1487,7 @@
.flags = PHY_HAS_INTERRUPT,
.probe = dp83640_probe,
.remove = dp83640_remove,
+ .soft_reset = dp83640_soft_reset,
.config_init = dp83640_config_init,
.config_aneg = genphy_config_aneg,
.read_status = genphy_read_status,
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index b6cad17..e8fa76a 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -828,6 +828,15 @@
if (err < 0)
return err;
+ /* If WOL event happened once, the LED[2] interrupt pin
+ * will not be cleared unless we reading the interrupt status
+ * register. If interrupts are in use, the normal interrupt
+ * handling will clear the WOL event. Clear the WOL event
+ * before enabling it if !phy_interrupt_is_valid()
+ */
+ if (!phy_interrupt_is_valid(phydev))
+ phy_read(phydev, MII_M1011_IEVENT);
+
/* Enable the WOL interrupt */
temp = phy_read(phydev, MII_88E1318S_PHY_CSIER);
temp |= MII_88E1318S_PHY_CSIER_WOL_EIE;
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 8eb5667..e149393 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -989,7 +989,8 @@
static void __team_compute_features(struct team *team)
{
struct team_port *port;
- u32 vlan_features = TEAM_VLAN_FEATURES & NETIF_F_ALL_FOR_ALL;
+ netdev_features_t vlan_features = TEAM_VLAN_FEATURES &
+ NETIF_F_ALL_FOR_ALL;
unsigned short max_hard_header_len = ETH_HLEN;
unsigned int dst_release_flag = IFF_XMIT_DST_RELEASE |
IFF_XMIT_DST_RELEASE_PERM;
diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c
index d11415b..279708e 100644
--- a/drivers/net/usb/cdc_mbim.c
+++ b/drivers/net/usb/cdc_mbim.c
@@ -550,7 +550,7 @@
static const struct driver_info cdc_mbim_info = {
.description = "CDC MBIM",
- .flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET | FLAG_WWAN,
+ .flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET | FLAG_WWAN | FLAG_SEND_ZLP,
.bind = cdc_mbim_bind,
.unbind = cdc_mbim_unbind,
.manage_power = cdc_mbim_manage_power,
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index cdaeb92..becfc0f 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -673,11 +673,16 @@
{QMI_FIXED_INTF(0x05c6, 0x9080, 8)},
{QMI_FIXED_INTF(0x05c6, 0x9083, 3)},
{QMI_FIXED_INTF(0x05c6, 0x9084, 4)},
+ {QMI_FIXED_INTF(0x05c6, 0x90b2, 3)}, /* ublox R410M */
{QMI_FIXED_INTF(0x05c6, 0x920d, 0)},
{QMI_FIXED_INTF(0x05c6, 0x920d, 5)},
{QMI_FIXED_INTF(0x0846, 0x68a2, 8)},
+ {QMI_FIXED_INTF(0x0846, 0x68d3, 8)}, /* Netgear Aircard 779S */
{QMI_FIXED_INTF(0x12d1, 0x140c, 1)}, /* Huawei E173 */
{QMI_FIXED_INTF(0x12d1, 0x14ac, 1)}, /* Huawei E1820 */
+ {QMI_FIXED_INTF(0x1435, 0xd181, 3)}, /* Wistron NeWeb D18Q1 */
+ {QMI_FIXED_INTF(0x1435, 0xd181, 4)}, /* Wistron NeWeb D18Q1 */
+ {QMI_FIXED_INTF(0x1435, 0xd181, 5)}, /* Wistron NeWeb D18Q1 */
{QMI_FIXED_INTF(0x16d8, 0x6003, 0)}, /* CMOTech 6003 */
{QMI_FIXED_INTF(0x16d8, 0x6007, 0)}, /* CMOTech CHE-628S */
{QMI_FIXED_INTF(0x16d8, 0x6008, 0)}, /* CMOTech CMU-301 */
@@ -754,6 +759,7 @@
{QMI_FIXED_INTF(0x19d2, 0x2002, 4)}, /* ZTE (Vodafone) K3765-Z */
{QMI_FIXED_INTF(0x2001, 0x7e19, 4)}, /* D-Link DWM-221 B1 */
{QMI_FIXED_INTF(0x2001, 0x7e35, 4)}, /* D-Link DWM-222 */
+ {QMI_FIXED_INTF(0x2020, 0x2033, 4)}, /* BroadMobi BM806U */
{QMI_FIXED_INTF(0x0f3d, 0x68a2, 8)}, /* Sierra Wireless MC7700 */
{QMI_FIXED_INTF(0x114f, 0x68a2, 8)}, /* Sierra Wireless MC7750 */
{QMI_FIXED_INTF(0x1199, 0x68a2, 8)}, /* Sierra Wireless MC7710 in QMI mode */
@@ -865,6 +871,7 @@
const struct usb_device_id *prod)
{
struct usb_device_id *id = (struct usb_device_id *)prod;
+ struct usb_interface_descriptor *desc = &intf->cur_altsetting->desc;
/* Workaround to enable dynamic IDs. This disables usbnet
* blacklisting functionality. Which, if required, can be
@@ -876,6 +883,18 @@
id->driver_info = (unsigned long)&qmi_wwan_info;
}
+ /* There are devices where the same interface number can be
+ * configured as different functions. We should only bind to
+ * vendor specific functions when matching on interface number
+ */
+ if (id->match_flags & USB_DEVICE_ID_MATCH_INT_NUMBER &&
+ desc->bInterfaceClass != USB_CLASS_VENDOR_SPEC) {
+ dev_dbg(&intf->dev,
+ "Rejecting interface number match for class %02x\n",
+ desc->bInterfaceClass);
+ return -ENODEV;
+ }
+
return usbnet_probe(intf, id);
}
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 01f3b51..68cc5f5 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1590,7 +1590,7 @@
tx_data += len;
agg->skb_len += len;
- agg->skb_num++;
+ agg->skb_num += skb_shinfo(skb)->gso_segs ?: 1;
dev_kfree_skb_any(skb);
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c
index 25f9fae..b1fccaa 100644
--- a/drivers/net/usb/smsc75xx.c
+++ b/drivers/net/usb/smsc75xx.c
@@ -945,10 +945,11 @@
/* it's racing here! */
ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
- if (ret < 0)
+ if (ret < 0) {
netdev_warn(dev->net, "Error writing RFE_CTL\n");
-
- return ret;
+ return ret;
+ }
+ return 0;
}
static int smsc75xx_wait_ready(struct usbnet *dev, int in_pm)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 1da5473..3b507ccb 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1876,8 +1876,8 @@
/* Assume link up if device can't report link status,
otherwise get link status from config. */
+ netif_carrier_off(dev);
if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) {
- netif_carrier_off(dev);
schedule_work(&vi->config_work);
} else {
vi->status = VIRTIO_NET_S_LINK_UP;
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index a9d84c1..1e0f532 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -4320,10 +4320,20 @@
{
struct ath10k *ar = hw->priv;
struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
+ struct ath10k_vif *arvif = (void *)vif->drv_priv;
+ struct ath10k_peer *peer;
u32 bw, smps;
spin_lock_bh(&ar->data_lock);
+ peer = ath10k_peer_find(ar, arvif->vdev_id, sta->addr);
+ if (!peer) {
+ spin_unlock_bh(&ar->data_lock);
+ ath10k_warn(ar, "mac sta rc update failed to find peer %pM on vdev %i\n",
+ sta->addr, arvif->vdev_id);
+ return;
+ }
+
ath10k_dbg(ar, ATH10K_DBG_MAC,
"mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n",
sta->addr, changed, sta->bandwidth, sta->rx_nss,
diff --git a/drivers/net/wireless/cnss/cnss_pci.c b/drivers/net/wireless/cnss/cnss_pci.c
index db3d081..438eeda 100644
--- a/drivers/net/wireless/cnss/cnss_pci.c
+++ b/drivers/net/wireless/cnss/cnss_pci.c
@@ -2732,7 +2732,7 @@
cnss_wlan_vreg_set(vreg_info, VREG_OFF);
if (penv->pdev) {
if (wdrv && wdrv->update_status)
- wdrv->update_status(penv->pdev, CNSS_WLAN_SSR_FAIL);
+ wdrv->update_status(penv->pdev, CNSS_SSR_FAIL);
if (!penv->recovery_in_progress) {
pr_err("%d: Unregistering pci device\n", __LINE__);
pci_unregister_driver(&cnss_wlan_pci_driver);
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index f15f58d..39431f6 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -2016,14 +2016,14 @@
if (param->regd) {
int i;
- for (i = 0; hwsim_world_regdom_custom[i] != param->regd &&
- i < ARRAY_SIZE(hwsim_world_regdom_custom); i++)
- ;
+ for (i = 0; i < ARRAY_SIZE(hwsim_world_regdom_custom); i++) {
+ if (hwsim_world_regdom_custom[i] != param->regd)
+ continue;
- if (i < ARRAY_SIZE(hwsim_world_regdom_custom)) {
ret = nla_put_u32(skb, HWSIM_ATTR_REG_CUSTOM_REG, i);
if (ret < 0)
goto error;
+ break;
}
}
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index dee9270..24e025f 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -333,7 +333,7 @@
* of the overlay in a list. This list can be used to prevent
* illegal overlay removals.
*
- * Returns the id of the created overlay, or an negative error number
+ * Returns the id of the created overlay, or a negative error number
*/
int of_overlay_create(struct device_node *tree)
{
@@ -481,7 +481,7 @@
*
* Removes an overlay if it is permissible.
*
- * Returns 0 on success, or an negative error number
+ * Returns 0 on success, or a negative error number
*/
int of_overlay_destroy(int id)
{
@@ -528,7 +528,7 @@
*
* Removes all overlays from the system in the correct order.
*
- * Returns 0 on success, or an negative error number
+ * Returns 0 on success, or a negative error number
*/
int of_overlay_destroy_all(void)
{
diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c
index e5fa3e9..5b29754 100644
--- a/drivers/of/unittest.c
+++ b/drivers/of/unittest.c
@@ -526,7 +526,8 @@
/* Make sure node names are constructed correctly */
selftest((np = of_find_node_by_path("/testcase-data/changeset/n2/n21")),
"'%s' not added\n", n21->full_name);
- of_node_put(np);
+ if (np)
+ of_node_put(np);
mutex_lock(&of_mutex);
selftest(!of_changeset_revert(&chgset), "revert failed\n");
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
index 23817b0..dd8ed97 100644
--- a/drivers/parisc/lba_pci.c
+++ b/drivers/parisc/lba_pci.c
@@ -1366,9 +1366,27 @@
WRITE_REG32(stat, d->hba.base_addr + LBA_ERROR_CONFIG);
}
- /* Set HF mode as the default (vs. -1 mode). */
+
+ /*
+ * Hard Fail vs. Soft Fail on PCI "Master Abort".
+ *
+ * "Master Abort" means the MMIO transaction timed out - usually due to
+ * the device not responding to an MMIO read. We would like HF to be
+ * enabled to find driver problems, though it means the system will
+ * crash with a HPMC.
+ *
+ * In SoftFail mode "~0L" is returned as a result of a timeout on the
+ * pci bus. This is like how PCI busses on x86 and most other
+ * architectures behave. In order to increase compatibility with
+ * existing (x86) PCI hardware and existing Linux drivers we enable
+ * Soft Faul mode on PA-RISC now too.
+ */
stat = READ_REG32(d->hba.base_addr + LBA_STAT_CTL);
+#if defined(ENABLE_HARDFAIL)
WRITE_REG32(stat | HF_ENABLE, d->hba.base_addr + LBA_STAT_CTL);
+#else
+ WRITE_REG32(stat & ~HF_ENABLE, d->hba.base_addr + LBA_STAT_CTL);
+#endif
/*
** Writing a zero to STAT_CTL.rf (bit 0) will clear reset signal
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index b115219..8b58e7a 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -144,7 +144,7 @@
int pcie_init_notification(struct controller *ctrl);
int pciehp_enable_slot(struct slot *p_slot);
int pciehp_disable_slot(struct slot *p_slot);
-void pcie_enable_notification(struct controller *ctrl);
+void pcie_reenable_notification(struct controller *ctrl);
int pciehp_power_on_slot(struct slot *slot);
void pciehp_power_off_slot(struct slot *slot);
void pciehp_get_power_status(struct slot *slot, u8 *status);
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 07aa722..688bf66 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -332,7 +332,7 @@
ctrl = get_service_data(dev);
/* reinitialize the chipset's event detection logic */
- pcie_enable_notification(ctrl);
+ pcie_reenable_notification(ctrl);
slot = ctrl->slot;
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 6d68688..fc7f48a7 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -602,7 +602,7 @@
return IRQ_HANDLED;
}
-void pcie_enable_notification(struct controller *ctrl)
+static void pcie_enable_notification(struct controller *ctrl)
{
u16 cmd, mask;
@@ -642,6 +642,17 @@
pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, cmd);
}
+void pcie_reenable_notification(struct controller *ctrl)
+{
+ /*
+ * Clear both Presence and Data Link Layer Changed to make sure
+ * those events still fire after we have re-enabled them.
+ */
+ pcie_capability_write_word(ctrl->pcie->port, PCI_EXP_SLTSTA,
+ PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC);
+ pcie_enable_notification(ctrl);
+}
+
static void pcie_disable_notification(struct controller *ctrl)
{
u16 mask;
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 0ad37e6..cf4f3ad 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -1120,11 +1120,14 @@
int error;
/*
- * If pci_dev->driver is not set (unbound), the device should
- * always remain in D0 regardless of the runtime PM status
+ * If pci_dev->driver is not set (unbound), we leave the device in D0,
+ * but it may go to D3cold when the bridge above it runtime suspends.
+ * Save its config space in case that happens.
*/
- if (!pci_dev->driver)
+ if (!pci_dev->driver) {
+ pci_save_state(pci_dev);
return 0;
+ }
if (!pm || !pm->runtime_suspend)
return -ENOSYS;
@@ -1163,16 +1166,18 @@
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
/*
- * If pci_dev->driver is not set (unbound), the device should
- * always remain in D0 regardless of the runtime PM status
+ * Restoring config space is necessary even if the device is not bound
+ * to a driver because although we left it in D0, it may have gone to
+ * D3cold when the bridge above it runtime suspended.
*/
+ pci_restore_standard_config(pci_dev);
+
if (!pci_dev->driver)
return 0;
if (!pm || !pm->runtime_resume)
return -ENOSYS;
- pci_restore_standard_config(pci_dev);
pci_fixup_device(pci_fixup_resume_early, pci_dev);
__pci_enable_wake(pci_dev, PCI_D0, true, false);
pci_fixup_device(pci_fixup_resume, pci_dev);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index b3e63f5..9e86ace 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3559,6 +3559,8 @@
*/
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9123,
quirk_dma_func1_alias);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9128,
+ quirk_dma_func1_alias);
/* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c14 */
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9130,
quirk_dma_func1_alias);
@@ -3571,6 +3573,9 @@
/* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c46 */
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x91a0,
quirk_dma_func1_alias);
+/* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c127 */
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9220,
+ quirk_dma_func1_alias);
/* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c49 */
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9230,
quirk_dma_func1_alias);
diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
index d596e71..7d0ad5e 100644
--- a/drivers/pinctrl/qcom/pinctrl-msm.c
+++ b/drivers/pinctrl/qcom/pinctrl-msm.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2013, Sony Mobile Communications AB.
- * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017, 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
@@ -635,6 +635,10 @@
spin_lock_irqsave(&pctrl->lock, flags);
+ val = readl(pctrl->regs + g->intr_status_reg);
+ val &= ~BIT(g->intr_status_bit);
+ writel(val, pctrl->regs + g->intr_status_reg);
+
val = readl(pctrl->regs + g->intr_cfg_reg);
val |= BIT(g->intr_enable_bit);
writel(val, pctrl->regs + g->intr_cfg_reg);
diff --git a/drivers/platform/msm/Kconfig b/drivers/platform/msm/Kconfig
index b4d3336..3b03857d 100644
--- a/drivers/platform/msm/Kconfig
+++ b/drivers/platform/msm/Kconfig
@@ -195,16 +195,6 @@
The user interface to run and control the tests is debugfs file
system.
-config SSM
- tristate "QTI Secure Service Module"
- depends on QSEECOM
- depends on MSM_SMD
- help
- Provides an interface for OEM driver to communicate with Trustzone
- and modem for key exchange and mode change.
- This driver uses Secure Channel Manager interface for trustzone
- communication and communicates with modem over SMD channel.
-
config MSM_MHI
tristate "Modem Host Interface Driver"
help
diff --git a/drivers/platform/msm/Makefile b/drivers/platform/msm/Makefile
index 1ecb76f..5507a12 100644
--- a/drivers/platform/msm/Makefile
+++ b/drivers/platform/msm/Makefile
@@ -25,4 +25,3 @@
obj-$(CONFIG_MSM_AVTIMER) += avtimer.o
obj-$(CONFIG_MSM_11AD) += msm_11ad/
obj-$(CONFIG_MSM_MHI_DEV) += mhi_dev/
-obj-$(CONFIG_SSM) += ssm.o
\ No newline at end of file
diff --git a/drivers/platform/msm/ep_pcie/ep_pcie_core.c b/drivers/platform/msm/ep_pcie/ep_pcie_core.c
index 810f2c7..7fa2443 100644
--- a/drivers/platform/msm/ep_pcie/ep_pcie_core.c
+++ b/drivers/platform/msm/ep_pcie/ep_pcie_core.c
@@ -760,6 +760,7 @@
char prop_name[MAX_PROP_SIZE];
const __be32 *prop;
u32 *clkfreq = NULL;
+ enum of_gpio_flags gpio_flags;
EP_PCIE_DBG(dev, "PCIe V%d\n", dev->rev);
@@ -868,10 +869,15 @@
for (i = 0; i < EP_PCIE_MAX_GPIO; i++) {
gpio_info = &dev->gpio[i];
- ret = of_get_named_gpio((&pdev->dev)->of_node,
- gpio_info->name, 0);
+ ret = of_get_named_gpio_flags((&pdev->dev)->of_node,
+ gpio_info->name, 0, &gpio_flags);
if (ret >= 0) {
gpio_info->num = ret;
+ if (i == EP_PCIE_GPIO_MDM2AP) {
+ gpio_info->init =
+ gpio_flags & OF_GPIO_ACTIVE_LOW;
+ gpio_info->on = !gpio_info->init;
+ }
ret = 0;
EP_PCIE_DBG(dev, "GPIO num for %s is %d\n",
gpio_info->name, gpio_info->num);
diff --git a/drivers/platform/msm/gsi/gsi.c b/drivers/platform/msm/gsi/gsi.c
index 60a6101..43d99b9c 100644
--- a/drivers/platform/msm/gsi/gsi.c
+++ b/drivers/platform/msm/gsi/gsi.c
@@ -1099,13 +1099,14 @@
uint32_t val;
struct gsi_evt_ctx *ctx;
int res;
- int ee = gsi_ctx->per.ee;
+ int ee;
unsigned long flags;
if (!gsi_ctx) {
pr_err("%s:%d gsi context not allocated\n", __func__, __LINE__);
return -GSI_STATUS_NODEV;
}
+ ee = gsi_ctx->per.ee;
if (!props || !evt_ring_hdl || dev_hdl != (uintptr_t)gsi_ctx) {
GSIERR("bad params props=%p dev_hdl=0x%lx evt_ring_hdl=%p\n",
@@ -1637,7 +1638,7 @@
struct gsi_chan_ctx *ctx;
uint32_t val;
int res;
- int ee = gsi_ctx->per.ee;
+ int ee;
enum gsi_ch_cmd_opcode op = GSI_CH_ALLOCATE;
uint8_t erindex;
void **user_data;
@@ -1646,6 +1647,7 @@
pr_err("%s:%d gsi context not allocated\n", __func__, __LINE__);
return -GSI_STATUS_NODEV;
}
+ ee = gsi_ctx->per.ee;
if (!props || !chan_hdl || dev_hdl != (uintptr_t)gsi_ctx) {
GSIERR("bad params props=%p dev_hdl=0x%lx chan_hdl=%p\n",
@@ -2287,12 +2289,13 @@
unsigned long flags;
uint64_t rp;
uint64_t wp;
- int ee = gsi_ctx->per.ee;
+ int ee;
if (!gsi_ctx) {
pr_err("%s:%d gsi context not allocated\n", __func__, __LINE__);
return -GSI_STATUS_NODEV;
}
+ ee = gsi_ctx->per.ee;
if (chan_hdl >= gsi_ctx->max_ch || !info) {
GSIERR("bad params chan_hdl=%lu info=%p\n", chan_hdl, info);
@@ -2357,12 +2360,13 @@
unsigned long flags;
uint64_t rp;
uint64_t wp;
- int ee = gsi_ctx->per.ee;
+ int ee;
if (!gsi_ctx) {
pr_err("%s:%d gsi context not allocated\n", __func__, __LINE__);
return -GSI_STATUS_NODEV;
}
+ ee = gsi_ctx->per.ee;
if (chan_hdl >= gsi_ctx->max_ch || !is_empty) {
GSIERR("bad params chan_hdl=%lu is_empty=%p\n",
@@ -2546,13 +2550,14 @@
{
struct gsi_chan_ctx *ctx;
uint64_t rp;
- int ee = gsi_ctx->per.ee;
+ int ee;
unsigned long flags;
if (!gsi_ctx) {
pr_err("%s:%d gsi context not allocated\n", __func__, __LINE__);
return -GSI_STATUS_NODEV;
}
+ ee = gsi_ctx->per.ee;
if (chan_hdl >= gsi_ctx->max_ch || !notify) {
GSIERR("bad params chan_hdl=%lu notify=%p\n", chan_hdl, notify);
diff --git a/drivers/platform/msm/ipa/ipa_clients/ipa_mhi_client.c b/drivers/platform/msm/ipa/ipa_clients/ipa_mhi_client.c
index 158be88..2143adbd 100644
--- a/drivers/platform/msm/ipa/ipa_clients/ipa_mhi_client.c
+++ b/drivers/platform/msm/ipa/ipa_clients/ipa_mhi_client.c
@@ -2119,6 +2119,15 @@
IPA_MHI_ERR("ipa_mhi_set_state failed %d\n", res);
return res;
}
+
+ res = ipa_mhi_suspend_dl(force);
+ if (res) {
+ IPA_MHI_ERR("ipa_mhi_suspend_dl failed %d\n", res);
+ goto fail_suspend_dl_channel;
+ }
+
+ usleep_range(IPA_MHI_SUSPEND_SLEEP_MIN, IPA_MHI_SUSPEND_SLEEP_MAX);
+
res = ipa_mhi_suspend_ul(force, &empty, &force_clear);
if (res) {
IPA_MHI_ERR("ipa_mhi_suspend_ul failed %d\n", res);
@@ -2147,12 +2156,6 @@
usleep_range(IPA_MHI_SUSPEND_SLEEP_MIN, IPA_MHI_SUSPEND_SLEEP_MAX);
- res = ipa_mhi_suspend_dl(force);
- if (res) {
- IPA_MHI_ERR("ipa_mhi_suspend_dl failed %d\n", res);
- goto fail_suspend_dl_channel;
- }
-
if (!empty)
ipa_set_tag_process_before_gating(false);
@@ -2166,14 +2169,12 @@
IPA_MHI_FUNC_EXIT();
return 0;
-fail_suspend_dl_channel:
fail_release_cons:
ipa_mhi_request_prod();
fail_release_prod:
IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
fail_suspend_ul_channel:
ipa_mhi_resume_channels(true, ipa_mhi_client_ctx->ul_channels);
- ipa_mhi_set_state(IPA_MHI_STATE_STARTED);
if (force_clear) {
if (
ipa_mhi_disable_force_clear(ipa_mhi_client_ctx->qmi_req_id)) {
@@ -2183,6 +2184,9 @@
IPA_MHI_DBG("force clear datapath disabled\n");
ipa_mhi_client_ctx->qmi_req_id++;
}
+fail_suspend_dl_channel:
+ ipa_mhi_resume_channels(true, ipa_mhi_client_ctx->dl_channels);
+ ipa_mhi_set_state(IPA_MHI_STATE_STARTED);
return res;
}
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa.c b/drivers/platform/msm/ipa/ipa_v2/ipa.c
index 8889475..7b93792 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa.c
@@ -3941,7 +3941,7 @@
ipa_ctx->logbuf = ipc_log_context_create(IPA_IPC_LOG_PAGES, "ipa", 0);
if (ipa_ctx->logbuf == NULL)
- IPAERR("failed to create IPC log, continue...\n");
+ IPADBG("failed to create IPC log, continue...\n");
ipa_ctx->pdev = ipa_dev;
ipa_ctx->uc_pdev = ipa_dev;
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v2/ipa_debugfs.c
index dbb0cbb..23645d4 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_debugfs.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_debugfs.c
@@ -89,6 +89,7 @@
__stringify(IPA_QUOTA_REACH),
__stringify(IPA_SSR_BEFORE_SHUTDOWN),
__stringify(IPA_SSR_AFTER_POWERUP),
+ __stringify(WLAN_FWR_SSR_BEFORE_SHUTDOWN),
};
const char *ipa_hdr_l2_type_name[] = {
@@ -1899,7 +1900,7 @@
ipc_log_context_create(IPA_IPC_LOG_PAGES,
"ipa_low", 0);
if (ipa_ipc_low_buff == NULL)
- IPAERR("failed to get logbuf_low\n");
+ IPADBG("failed to get logbuf_low\n");
}
ipa_ctx->logbuf_low = ipa_ipc_low_buff;
} else {
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v2/ipa_dp.c
index aacd74e..7860ad4 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_dp.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_dp.c
@@ -435,16 +435,16 @@
&dma_addr);
if (!transfer.iovec) {
IPAERR("fail to alloc dma mem for sps xfr buff\n");
- return -EFAULT;
+ return -ENOMEM;
}
} else {
transfer.iovec = kmalloc(size, flag);
if (!transfer.iovec) {
IPAERR("fail to alloc mem for sps xfr buff ");
IPAERR("num_desc = %d size = %d\n", num_desc, size);
- return -EFAULT;
+ return -ENOMEM;
}
- dma_addr = dma_map_single(ipa_ctx->pdev,
+ dma_addr = dma_map_single(ipa_ctx->pdev,
transfer.iovec, size, DMA_TO_DEVICE);
if (dma_mapping_error(ipa_ctx->pdev, dma_addr)) {
IPAERR("dma_map_single failed for sps xfr buff\n");
@@ -459,9 +459,10 @@
for (i = 0; i < num_desc; i++) {
tx_pkt = kmem_cache_zalloc(ipa_ctx->tx_pkt_wrapper_cache,
- mem_flag);
+ GFP_ATOMIC);
if (!tx_pkt) {
IPAERR("failed to alloc tx wrapper\n");
+ ret = -ENOMEM;
goto failure;
}
/*
@@ -515,6 +516,7 @@
if (dma_mapping_error(ipa_ctx->pdev, tx_pkt->mem.phys_base)) {
IPAERR("dma_map_single failed\n");
+ ret = -EFAULT;
goto failure_dma_map;
}
@@ -564,6 +566,7 @@
result = sps_transfer(sys->ep->ep_hdl, &transfer);
if (result) {
IPAERR("sps_transfer failed rc=%d\n", result);
+ ret = -EFAULT;
goto failure;
}
@@ -605,7 +608,7 @@
}
}
spin_unlock_bh(&sys->spinlock);
- return -EFAULT;
+ return ret;
}
/**
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c b/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c
index 6392c37..c29cbdf 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c
@@ -1495,8 +1495,16 @@
}
}
}
- mutex_unlock(&ipa_ctx->lock);
+ /* commit the change to IPA-HW */
+ if (ipa_ctx->ctrl->ipa_commit_flt(IPA_IP_v4) ||
+ ipa_ctx->ctrl->ipa_commit_flt(IPA_IP_v6)) {
+ IPAERR_RL("fail to commit flt-rule\n");
+ WARN_ON_RATELIMIT_IPA(1);
+ mutex_unlock(&ipa_ctx->lock);
+ return -EPERM;
+ }
+ mutex_unlock(&ipa_ctx->lock);
return 0;
}
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c
index c42b93b..9e09888 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c
@@ -1249,8 +1249,9 @@
struct ipa_hdr_offset_entry *off_next;
struct ipa_hdr_proc_ctx_offset_entry *ctx_off_entry;
struct ipa_hdr_proc_ctx_offset_entry *ctx_off_next;
- int i, end = 0;
- bool user_rule = false;
+ struct ipa_hdr_tbl *htbl = &ipa_ctx->hdr_tbl;
+ struct ipa_hdr_proc_ctx_tbl *htbl_proc = &ipa_ctx->hdr_proc_ctx_tbl;
+ int i;
/*
* issue a reset on the routing module since routing rules point to
@@ -1288,8 +1289,6 @@
return -EFAULT;
}
- if (entry->ipacm_installed)
- user_rule = true;
if (!user_only || entry->ipacm_installed) {
if (entry->is_hdr_proc_ctx) {
dma_unmap_single(ipa_ctx->pdev,
@@ -1297,9 +1296,15 @@
entry->hdr_len,
DMA_TO_DEVICE);
entry->proc_ctx = NULL;
+ } else {
+ /* move the offset entry to free list */
+ entry->offset_entry->ipacm_installed = 0;
+ list_move(&entry->offset_entry->link,
+ &htbl->head_free_offset_list[
+ entry->offset_entry->bin]);
}
list_del(&entry->link);
- ipa_ctx->hdr_tbl.hdr_cnt--;
+ htbl->hdr_cnt--;
entry->ref_cnt = 0;
entry->cookie = 0;
@@ -1308,53 +1313,37 @@
kmem_cache_free(ipa_ctx->hdr_cache, entry);
}
}
- for (i = 0; i < IPA_HDR_BIN_MAX; i++) {
- list_for_each_entry_safe(off_entry, off_next,
- &ipa_ctx->hdr_tbl.head_offset_list[i],
- link) {
- /*
- * do not remove the default exception header which is
- * at offset 0
- */
- if (off_entry->offset == 0)
- continue;
-
- if (!user_only ||
- off_entry->ipacm_installed) {
+ /* only clean up offset_list and free_offset_list on global reset */
+ if (!user_only) {
+ for (i = 0; i < IPA_HDR_BIN_MAX; i++) {
+ list_for_each_entry_safe(off_entry, off_next,
+ &ipa_ctx->hdr_tbl.head_offset_list[i],
+ link) {
+ /**
+ * do not remove the default exception
+ * header which is at offset 0
+ */
+ if (off_entry->offset == 0)
+ continue;
list_del(&off_entry->link);
kmem_cache_free(ipa_ctx->hdr_offset_cache,
off_entry);
- } else {
- if (off_entry->offset +
- ipa_hdr_bin_sz[off_entry->bin] > end) {
- end = off_entry->offset +
- ipa_hdr_bin_sz[off_entry->bin];
- IPADBG("replace end = %d\n", end);
- }
}
- }
- list_for_each_entry_safe(off_entry, off_next,
+ list_for_each_entry_safe(off_entry, off_next,
&ipa_ctx->hdr_tbl.head_free_offset_list[i],
link) {
-
- if (!user_only ||
- off_entry->ipacm_installed) {
list_del(&off_entry->link);
kmem_cache_free(ipa_ctx->hdr_offset_cache,
off_entry);
}
}
+ /* there is one header of size 8 */
+ ipa_ctx->hdr_tbl.end = 8;
+ ipa_ctx->hdr_tbl.hdr_cnt = 1;
}
- IPADBG("hdr_tbl.end = %d\n", end);
- if (user_rule) {
- ipa_ctx->hdr_tbl.end = end;
- IPADBG("hdr_tbl.end = %d\n", end);
- }
IPADBG("reset hdr proc ctx\n");
- user_rule = false;
- end = 0;
list_for_each_entry_safe(
ctx_entry,
ctx_next,
@@ -1363,16 +1352,18 @@
if (ipa_id_find(ctx_entry->id) == NULL) {
mutex_unlock(&ipa_ctx->lock);
- WARN_ON(1);
+ WARN_ON_RATELIMIT_IPA(1);
return -EFAULT;
}
- if (entry->ipacm_installed)
- user_rule = true;
if (!user_only ||
ctx_entry->ipacm_installed) {
+ /* move the offset entry to appropriate free list */
+ list_move(&ctx_entry->offset_entry->link,
+ &htbl_proc->head_free_offset_list[
+ ctx_entry->offset_entry->bin]);
list_del(&ctx_entry->link);
- ipa_ctx->hdr_proc_ctx_tbl.proc_ctx_cnt--;
+ htbl_proc->proc_ctx_cnt--;
ctx_entry->ref_cnt = 0;
ctx_entry->cookie = 0;
@@ -1382,48 +1373,40 @@
ctx_entry);
}
}
- for (i = 0; i < IPA_HDR_PROC_CTX_BIN_MAX; i++) {
- list_for_each_entry_safe(ctx_off_entry, ctx_off_next,
+ /* only clean up offset_list and free_offset_list on global reset */
+ if (!user_only) {
+ for (i = 0; i < IPA_HDR_PROC_CTX_BIN_MAX; i++) {
+ list_for_each_entry_safe(ctx_off_entry, ctx_off_next,
&ipa_ctx->hdr_proc_ctx_tbl.head_offset_list[i],
link) {
-
- if (!user_only ||
- ctx_off_entry->ipacm_installed) {
list_del(&ctx_off_entry->link);
kmem_cache_free(
ipa_ctx->hdr_proc_ctx_offset_cache,
ctx_off_entry);
- } else {
- if (ctx_off_entry->offset +
- ipa_hdr_bin_sz[ctx_off_entry->bin]
- > end) {
- end = ctx_off_entry->offset +
- ipa_hdr_bin_sz[ctx_off_entry->bin];
- IPADBG("replace hdr_proc as %d\n", end);
- }
}
- }
- list_for_each_entry_safe(ctx_off_entry, ctx_off_next,
- &ipa_ctx->hdr_proc_ctx_tbl.head_free_offset_list[i],
- link) {
-
- if (!user_only ||
- ctx_off_entry->ipacm_installed) {
+ list_for_each_entry_safe(ctx_off_entry, ctx_off_next,
+ &ipa_ctx->hdr_proc_ctx_tbl.
+ head_free_offset_list[i], link) {
list_del(&ctx_off_entry->link);
kmem_cache_free(
ipa_ctx->hdr_proc_ctx_offset_cache,
ctx_off_entry);
}
}
+ ipa_ctx->hdr_proc_ctx_tbl.end = 0;
+ ipa_ctx->hdr_proc_ctx_tbl.proc_ctx_cnt = 0;
}
- IPADBG("hdr_proc_tbl.end = %d\n", end);
- if (user_rule) {
- ipa_ctx->hdr_proc_ctx_tbl.end = end;
- IPADBG("hdr_proc_tbl.end = %d\n", end);
+
+ /* commit the change to IPA-HW */
+ if (ipa_ctx->ctrl->ipa_commit_hdr()) {
+ IPAERR_RL("fail to commit hdr\n");
+ WARN_ON_RATELIMIT_IPA(1);
+ mutex_unlock(&ipa_ctx->lock);
+ return -EFAULT;
}
+
mutex_unlock(&ipa_ctx->lock);
-
return 0;
}
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_nat.c b/drivers/platform/msm/ipa/ipa_v2/ipa_nat.c
index cc3d267..acc2615 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_nat.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_nat.c
@@ -344,6 +344,9 @@
IPAERR_RL("Detected overflow\n");
return -EPERM;
}
+
+ mutex_lock(&ipa_ctx->nat_mem.lock);
+
/* Check Table Entry offset is not
beyond allocated size */
tmp = init->ipv4_rules_offset +
@@ -353,6 +356,7 @@
IPAERR_RL("offset:%d entrys:%d size:%zu mem_size:%zu\n",
init->ipv4_rules_offset, (init->table_entries + 1),
tmp, ipa_ctx->nat_mem.size);
+ mutex_unlock(&ipa_ctx->nat_mem.lock);
return -EPERM;
}
@@ -360,6 +364,7 @@
if (init->expn_rules_offset >
UINT_MAX - (TBL_ENTRY_SIZE * init->expn_table_entries)) {
IPAERR_RL("Detected overflow\n");
+ mutex_unlock(&ipa_ctx->nat_mem.lock);
return -EPERM;
}
/* Check Expn Table Entry offset is not
@@ -371,6 +376,7 @@
IPAERR_RL("offset:%d entrys:%d size:%zu mem_size:%zu\n",
init->expn_rules_offset, init->expn_table_entries,
tmp, ipa_ctx->nat_mem.size);
+ mutex_unlock(&ipa_ctx->nat_mem.lock);
return -EPERM;
}
@@ -378,6 +384,7 @@
if (init->index_offset >
UINT_MAX - (INDX_TBL_ENTRY_SIZE * (init->table_entries + 1))) {
IPAERR_RL("Detected overflow\n");
+ mutex_unlock(&ipa_ctx->nat_mem.lock);
return -EPERM;
}
/* Check Indx Table Entry offset is not
@@ -389,6 +396,7 @@
IPAERR_RL("offset:%d entrys:%d size:%zu mem_size:%zu\n",
init->index_offset, (init->table_entries + 1),
tmp, ipa_ctx->nat_mem.size);
+ mutex_unlock(&ipa_ctx->nat_mem.lock);
return -EPERM;
}
@@ -396,6 +404,7 @@
if (init->index_expn_offset >
(UINT_MAX - (INDX_TBL_ENTRY_SIZE * init->expn_table_entries))) {
IPAERR_RL("Detected overflow\n");
+ mutex_unlock(&ipa_ctx->nat_mem.lock);
return -EPERM;
}
/* Check Expn Table entry offset is not
@@ -407,6 +416,7 @@
IPAERR_RL("offset:%d entrys:%d size:%zu mem_size:%zu\n",
init->index_expn_offset, init->expn_table_entries,
tmp, ipa_ctx->nat_mem.size);
+ mutex_unlock(&ipa_ctx->nat_mem.lock);
return -EPERM;
}
@@ -555,6 +565,7 @@
free_nop:
kfree(reg_write_nop);
bail:
+ mutex_unlock(&ipa_ctx->nat_mem.lock);
return result;
}
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c b/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c
index e4a3a72..5bab6d0 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c
@@ -1443,6 +1443,15 @@
}
}
}
+
+ /* commit the change to IPA-HW */
+ if (ipa_ctx->ctrl->ipa_commit_rt(IPA_IP_v4) ||
+ ipa_ctx->ctrl->ipa_commit_rt(IPA_IP_v6)) {
+ IPAERR("fail to commit rt-rule\n");
+ WARN_ON_RATELIMIT_IPA(1);
+ mutex_unlock(&ipa_ctx->lock);
+ return -EPERM;
+ }
mutex_unlock(&ipa_ctx->lock);
return 0;
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c
index 3a9df42..4d2fe65 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c
@@ -49,6 +49,10 @@
#define UPPER_CUTOFF 50
#define LOWER_CUTOFF 10
+#define MAX_RETRY_ALLOC 10
+#define ALLOC_MIN_SLEEP_RX 100000
+#define ALLOC_MAX_SLEEP_RX 200000
+
#define IPA_DEFAULT_SYS_YELLOW_WM 32
#define IPA_AGGR_BYTE_LIMIT (\
@@ -4626,6 +4630,7 @@
int res;
struct ipa_tag_completion *comp;
int ep_idx;
+ u32 retry_cnt = 0;
gfp_t flag = GFP_KERNEL | (ipa_ctx->use_dma_zone ? GFP_DMA : 0);
/* Not enough room for the required descriptors for the tag process */
@@ -4742,9 +4747,22 @@
tag_desc[desc_idx].user1 = dummy_skb;
desc_idx++;
+retry_alloc:
+
/* send all descriptors to IPA with single EOT */
res = ipa_send(sys, desc_idx, tag_desc, true);
if (res) {
+ if (res == -ENOMEM) {
+ if (retry_cnt < MAX_RETRY_ALLOC) {
+ IPADBG(
+ "Failed to alloc memory retry count %d\n",
+ retry_cnt);
+ retry_cnt++;
+ usleep_range(ALLOC_MIN_SLEEP_RX,
+ ALLOC_MAX_SLEEP_RX);
+ goto retry_alloc;
+ }
+ }
IPAERR("failed to send TAG packets %d\n", res);
res = -ENOMEM;
goto fail_send;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c
index 23fef69..fbcdbaa 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c
@@ -2608,6 +2608,9 @@
ipa3_q6_pipe_delay(true);
ipa3_q6_avoid_holb();
+ if (ipa3_ctx->ipa_config_is_mhi)
+ ipa3_set_reset_client_cons_pipe_sus_holb(true,
+ IPA_CLIENT_MHI_CONS);
if (ipa3_q6_clean_q6_tables()) {
IPAERR("Failed to clean Q6 tables\n");
BUG();
@@ -2620,8 +2623,11 @@
* on pipe reset procedure
*/
ipa3_q6_pipe_delay(false);
-
- ipa3_set_usb_prod_pipe_delay();
+ ipa3_set_reset_client_prod_pipe_delay(true,
+ IPA_CLIENT_USB_PROD);
+ if (ipa3_ctx->ipa_config_is_mhi)
+ ipa3_set_reset_client_prod_pipe_delay(true,
+ IPA_CLIENT_MHI_PROD);
IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
IPADBG_LOW("Exit with success\n");
@@ -4883,7 +4889,7 @@
ipa3_ctx->logbuf = ipc_log_context_create(IPA_IPC_LOG_PAGES, "ipa", 0);
if (ipa3_ctx->logbuf == NULL)
- IPAERR("failed to create IPC log, continue...\n");
+ IPADBG("failed to create IPC log, continue...\n");
ipa3_ctx->pdev = ipa_dev;
ipa3_ctx->uc_pdev = ipa_dev;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c
index 66a4e8d..4ad2f1d 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c
@@ -1848,27 +1848,32 @@
}
/*
- * Set USB PROD pipe delay for MBIM/RMNET config
+ * Set reset eo_deay for CLEINT PROD pipe
* Clocks, should be voted before calling this API
* locks should be taken before calling this API
*/
-void ipa3_set_usb_prod_pipe_delay(void)
+int ipa3_set_reset_client_prod_pipe_delay(bool set_reset,
+ enum ipa_client_type client)
{
- int result;
+ int result = 0;
int pipe_idx;
struct ipa3_ep_context *ep;
struct ipa_ep_cfg_ctrl ep_ctrl;
memset(&ep_ctrl, 0, sizeof(struct ipa_ep_cfg_ctrl));
- ep_ctrl.ipa_ep_delay = true;
+ ep_ctrl.ipa_ep_delay = set_reset;
+ if (IPA_CLIENT_IS_CONS(client)) {
+ IPAERR("client (%d) not PROD\n", client);
+ return -EINVAL;
+ }
- pipe_idx = ipa3_get_ep_mapping(IPA_CLIENT_USB_PROD);
+ pipe_idx = ipa3_get_ep_mapping(client);
if (pipe_idx == IPA_EP_NOT_ALLOCATED) {
- IPAERR("client (%d) not valid\n", IPA_CLIENT_USB_PROD);
- return;
+ IPAERR("client (%d) not valid\n", client);
+ return -EINVAL;
}
ep = &ipa3_ctx->ep[pipe_idx];
@@ -1885,6 +1890,59 @@
IPADBG("client (ep: %d) success\n", pipe_idx);
}
client_lock_unlock_cb(pipe_idx, false);
+ return result;
+}
+
+int ipa3_set_reset_client_cons_pipe_sus_holb(bool set_reset,
+ enum ipa_client_type client)
+{
+ int pipe_idx;
+ struct ipa3_ep_context *ep;
+ struct ipa_ep_cfg_ctrl ep_suspend;
+ struct ipa_ep_cfg_holb ep_holb;
+
+ memset(&ep_suspend, 0, sizeof(ep_suspend));
+ memset(&ep_holb, 0, sizeof(ep_holb));
+
+ ep_suspend.ipa_ep_suspend = set_reset;
+ ep_holb.tmr_val = 0;
+ ep_holb.en = set_reset;
+
+ if (IPA_CLIENT_IS_PROD(client)) {
+ IPAERR("client (%d) not CONS\n", client);
+ return -EINVAL;
+ }
+
+ pipe_idx = ipa3_get_ep_mapping(client);
+
+ if (pipe_idx == IPA_EP_NOT_ALLOCATED) {
+ IPAERR("client (%d) not valid\n", client);
+ return -EINVAL;
+ }
+
+ ep = &ipa3_ctx->ep[pipe_idx];
+ /* Setting sus/holb on MHI_CONS with skip_ep_cfg */
+ client_lock_unlock_cb(pipe_idx, true);
+ if (ep->valid && ep->skip_ep_cfg) {
+ if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_0)
+ ipahal_write_reg_n_fields(
+ IPA_ENDP_INIT_CTRL_n,
+ pipe_idx, &ep_suspend);
+ /*
+ * ipa3_cfg_ep_holb is not used here because we are
+ * setting HOLB on Q6 pipes, and from APPS perspective
+ * they are not valid, therefore, the above function
+ * will fail.
+ */
+ ipahal_write_reg_n_fields(
+ IPA_ENDP_INIT_HOL_BLOCK_TIMER_n,
+ pipe_idx, &ep_holb);
+ ipahal_write_reg_n_fields(
+ IPA_ENDP_INIT_HOL_BLOCK_EN_n,
+ pipe_idx, &ep_holb);
+ }
+ client_lock_unlock_cb(pipe_idx, false);
+ return 0;
}
void ipa3_xdci_ep_delay_rm(u32 clnt_hdl)
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c
index bfe4660..e461ce8 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c
@@ -70,6 +70,7 @@
__stringify(IPA_QUOTA_REACH),
__stringify(IPA_SSR_BEFORE_SHUTDOWN),
__stringify(IPA_SSR_AFTER_POWERUP),
+ __stringify(WLAN_FWR_SSR_BEFORE_SHUTDOWN),
};
const char *ipa3_hdr_l2_type_name[] = {
@@ -1795,7 +1796,7 @@
"ipa_low", 0);
}
if (ipa_ipc_low_buff == NULL)
- IPAERR("failed to get logbuf_low\n");
+ IPADBG("failed to get logbuf_low\n");
ipa3_ctx->logbuf_low = ipa_ipc_low_buff;
} else {
ipa3_ctx->logbuf_low = NULL;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c b/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c
index a1a0591..2d493e1 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c
@@ -1758,8 +1758,16 @@
}
}
}
- mutex_unlock(&ipa3_ctx->lock);
+ /* commit the change to IPA-HW */
+ if (ipa3_ctx->ctrl->ipa3_commit_flt(IPA_IP_v4) ||
+ ipa3_ctx->ctrl->ipa3_commit_flt(IPA_IP_v6)) {
+ IPAERR("fail to commit flt-rule\n");
+ WARN_ON_RATELIMIT_IPA(1);
+ mutex_unlock(&ipa3_ctx->lock);
+ return -EPERM;
+ }
+ mutex_unlock(&ipa3_ctx->lock);
return 0;
}
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c
index 8f99972..3d950c9c 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c
@@ -1007,8 +1007,9 @@
struct ipa_hdr_offset_entry *off_next;
struct ipa3_hdr_proc_ctx_offset_entry *ctx_off_entry;
struct ipa3_hdr_proc_ctx_offset_entry *ctx_off_next;
- int i, end = 0;
- bool user_rule = false;
+ struct ipa3_hdr_tbl *htbl = &ipa3_ctx->hdr_tbl;
+ struct ipa3_hdr_proc_ctx_tbl *htbl_proc = &ipa3_ctx->hdr_proc_ctx_tbl;
+ int i;
/*
* issue a reset on the routing module since routing rules point to
@@ -1046,8 +1047,6 @@
return -EFAULT;
}
- if (entry->ipacm_installed)
- user_rule = true;
if (!user_only || entry->ipacm_installed) {
if (entry->is_hdr_proc_ctx) {
dma_unmap_single(ipa3_ctx->pdev,
@@ -1055,9 +1054,15 @@
entry->hdr_len,
DMA_TO_DEVICE);
entry->proc_ctx = NULL;
+ } else {
+ /* move the offset entry to free list */
+ entry->offset_entry->ipacm_installed = 0;
+ list_move(&entry->offset_entry->link,
+ &htbl->head_free_offset_list[
+ entry->offset_entry->bin]);
}
list_del(&entry->link);
- ipa3_ctx->hdr_tbl.hdr_cnt--;
+ htbl->hdr_cnt--;
entry->ref_cnt = 0;
entry->cookie = 0;
/* remove the handle from the database */
@@ -1065,54 +1070,37 @@
kmem_cache_free(ipa3_ctx->hdr_cache, entry);
}
}
- for (i = 0; i < IPA_HDR_BIN_MAX; i++) {
- list_for_each_entry_safe(off_entry, off_next,
+
+ /* only clean up offset_list and free_offset_list on global reset */
+ if (!user_only) {
+ for (i = 0; i < IPA_HDR_BIN_MAX; i++) {
+ list_for_each_entry_safe(off_entry, off_next,
&ipa3_ctx->hdr_tbl.head_offset_list[i],
link) {
-
- /*
- * do not remove the default exception header which is
- * at offset 0
- */
- if (off_entry->offset == 0)
- continue;
-
- if (!user_only ||
- off_entry->ipacm_installed) {
+ /**
+ * do not remove the default exception
+ * header which is at offset 0
+ */
+ if (off_entry->offset == 0)
+ continue;
list_del(&off_entry->link);
kmem_cache_free(ipa3_ctx->hdr_offset_cache,
- off_entry);
- } else {
- if (off_entry->offset +
- ipa_hdr_bin_sz[off_entry->bin] > end) {
- end = off_entry->offset +
- ipa_hdr_bin_sz[off_entry->bin];
- IPADBG("replace end = %d\n",
- end);
- }
+ off_entry);
}
- }
- list_for_each_entry_safe(off_entry, off_next,
+ list_for_each_entry_safe(off_entry, off_next,
&ipa3_ctx->hdr_tbl.head_free_offset_list[i],
link) {
-
- if (!user_only ||
- off_entry->ipacm_installed) {
list_del(&off_entry->link);
kmem_cache_free(ipa3_ctx->hdr_offset_cache,
off_entry);
}
}
+ /* there is one header of size 8 */
+ ipa3_ctx->hdr_tbl.end = 8;
+ ipa3_ctx->hdr_tbl.hdr_cnt = 1;
}
- IPADBG("hdr_tbl.end = %d\n", end);
- if (user_rule) {
- ipa3_ctx->hdr_tbl.end = end;
- IPADBG("hdr_tbl.end = %d\n", end);
- }
IPADBG("reset hdr proc ctx\n");
- user_rule = false;
- end = 0;
list_for_each_entry_safe(
ctx_entry,
ctx_next,
@@ -1125,12 +1113,14 @@
return -EFAULT;
}
- if (entry->ipacm_installed)
- user_rule = true;
if (!user_only ||
ctx_entry->ipacm_installed) {
+ /* move the offset entry to appropriate free list */
+ list_move(&ctx_entry->offset_entry->link,
+ &htbl_proc->head_free_offset_list[
+ ctx_entry->offset_entry->bin]);
list_del(&ctx_entry->link);
- ipa3_ctx->hdr_proc_ctx_tbl.proc_ctx_cnt--;
+ htbl_proc->proc_ctx_cnt--;
ctx_entry->ref_cnt = 0;
ctx_entry->cookie = 0;
@@ -1140,48 +1130,40 @@
ctx_entry);
}
}
- for (i = 0; i < IPA_HDR_PROC_CTX_BIN_MAX; i++) {
- list_for_each_entry_safe(ctx_off_entry, ctx_off_next,
+
+ /* only clean up offset_list and free_offset_list on global reset */
+ if (!user_only) {
+ for (i = 0; i < IPA_HDR_PROC_CTX_BIN_MAX; i++) {
+ list_for_each_entry_safe(ctx_off_entry, ctx_off_next,
&ipa3_ctx->hdr_proc_ctx_tbl.head_offset_list[i],
link) {
-
- if (!user_only ||
- ctx_off_entry->ipacm_installed) {
list_del(&ctx_off_entry->link);
kmem_cache_free(
ipa3_ctx->hdr_proc_ctx_offset_cache,
ctx_off_entry);
- } else {
- if (ctx_off_entry->offset +
- ipa_hdr_bin_sz[ctx_off_entry->bin]
- > end) {
- end = ctx_off_entry->offset +
- ipa_hdr_bin_sz[ctx_off_entry->bin];
- IPADBG("replace hdr_proc as %d\n", end);
- }
}
- }
- list_for_each_entry_safe(ctx_off_entry, ctx_off_next,
- &ipa3_ctx->hdr_proc_ctx_tbl.head_free_offset_list[i],
- link) {
-
- if (!user_only ||
- ctx_off_entry->ipacm_installed) {
+ list_for_each_entry_safe(ctx_off_entry, ctx_off_next,
+ &ipa3_ctx->hdr_proc_ctx_tbl.
+ head_free_offset_list[i], link) {
list_del(&ctx_off_entry->link);
kmem_cache_free(
ipa3_ctx->hdr_proc_ctx_offset_cache,
ctx_off_entry);
}
}
+ ipa3_ctx->hdr_proc_ctx_tbl.end = 0;
+ ipa3_ctx->hdr_proc_ctx_tbl.proc_ctx_cnt = 0;
}
- IPADBG("hdr_proc_tbl.end = %d\n", end);
- if (user_rule) {
- ipa3_ctx->hdr_proc_ctx_tbl.end = end;
- IPADBG("hdr_proc_tbl.end = %d\n", end);
+ /* commit the change to IPA-HW */
+ if (ipa3_ctx->ctrl->ipa3_commit_hdr()) {
+ IPAERR("fail to commit hdr\n");
+ WARN_ON_RATELIMIT_IPA(1);
+ mutex_unlock(&ipa3_ctx->lock);
+ return -EFAULT;
}
+
mutex_unlock(&ipa3_ctx->lock);
-
return 0;
}
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
index c06b1c1..1a21708 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
@@ -1544,7 +1544,10 @@
void ipa3_xdci_ep_delay_rm(u32 clnt_hdl);
void ipa3_register_lock_unlock_callback(int (*client_cb)(bool), u32 ipa_ep_idx);
void ipa3_deregister_lock_unlock_callback(u32 ipa_ep_idx);
-void ipa3_set_usb_prod_pipe_delay(void);
+int ipa3_set_reset_client_prod_pipe_delay(bool set_reset,
+ enum ipa_client_type client);
+int ipa3_set_reset_client_cons_pipe_sus_holb(bool set_reset,
+ enum ipa_client_type client);
int ipa3_xdci_suspend(u32 ul_clnt_hdl, u32 dl_clnt_hdl,
bool should_force_clear, u32 qmi_req_id, bool is_dpl);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_mhi.c b/drivers/platform/msm/ipa/ipa_v3/ipa_mhi.c
index c56a60f..45340fc 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_mhi.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_mhi.c
@@ -198,6 +198,7 @@
union __packed gsi_channel_scratch ch_scratch;
struct ipa3_ep_context *ep;
const struct ipa_gsi_ep_config *ep_cfg;
+ struct ipa_ep_cfg_ctrl ep_cfg_ctrl;
IPA_MHI_FUNC_ENTRY();
@@ -323,6 +324,20 @@
*params->mhi = ch_scratch.mhi;
+ if (IPA_CLIENT_IS_PROD(ep->client) && ep->skip_ep_cfg) {
+ memset(&ep_cfg_ctrl, 0 , sizeof(struct ipa_ep_cfg_ctrl));
+ ep_cfg_ctrl.ipa_ep_delay = true;
+ ep->ep_delay_set = true;
+ res = ipa3_cfg_ep_ctrl(ipa_ep_idx, &ep_cfg_ctrl);
+ if (res)
+ IPA_MHI_ERR("client (ep: %d) failed result=%d\n",
+ ipa_ep_idx, res);
+ else
+ IPA_MHI_DBG("client (ep: %d) success\n", ipa_ep_idx);
+ } else {
+ ep->ep_delay_set = false;
+ }
+
IPA_MHI_DBG("Starting channel\n");
res = gsi_start_channel(ep->gsi_chan_hdl);
if (res) {
@@ -496,6 +511,7 @@
{
struct ipa3_ep_context *ep;
int res;
+ struct ipa_ep_cfg_ctrl ep_cfg_ctrl;
IPA_MHI_FUNC_ENTRY();
@@ -510,6 +526,23 @@
}
ep = &ipa3_ctx->ep[clnt_hdl];
+ IPA_MHI_ERR("Debug --> Remove ep_delay start");
+ if (ep->ep_delay_set == true) {
+ memset(&ep_cfg_ctrl, 0 , sizeof(struct ipa_ep_cfg_ctrl));
+ ep_cfg_ctrl.ipa_ep_delay = false;
+ res = ipa3_cfg_ep_ctrl(clnt_hdl,
+ &ep_cfg_ctrl);
+ if (res) {
+ IPAERR
+ ("client(ep:%d) failed to remove delay res=%d\n",
+ clnt_hdl, res);
+ } else {
+ IPADBG("client (ep: %d) delay removed\n",
+ clnt_hdl);
+ ep->ep_delay_set = false;
+ }
+ }
+ IPA_MHI_ERR("Debug --> Remov ep_delay end");
if (ipa3_ctx->transport_prototype == IPA_TRANSPORT_TYPE_GSI) {
res = gsi_dealloc_channel(ep->gsi_chan_hdl);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c b/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c
index 92cd32d..e11b428 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c
@@ -368,6 +368,8 @@
IPAERR_RL("Detected overflow\n");
return -EPERM;
}
+ mutex_lock(&ipa3_ctx->nat_mem.lock);
+
/* Check Table Entry offset is not
beyond allocated size */
tmp = init->ipv4_rules_offset +
@@ -377,6 +379,7 @@
IPAERR_RL("offset:%d entrys:%d size:%zu mem_size:%zu\n",
init->ipv4_rules_offset, (init->table_entries + 1),
tmp, ipa3_ctx->nat_mem.size);
+ mutex_unlock(&ipa3_ctx->nat_mem.lock);
return -EPERM;
}
@@ -384,6 +387,7 @@
if (init->expn_rules_offset >
(UINT_MAX - (TBL_ENTRY_SIZE * init->expn_table_entries))) {
IPAERR_RL("Detected overflow\n");
+ mutex_unlock(&ipa3_ctx->nat_mem.lock);
return -EPERM;
}
/* Check Expn Table Entry offset is not
@@ -395,6 +399,7 @@
IPAERR_RL("offset:%d entrys:%d size:%zu mem_size:%zu\n",
init->expn_rules_offset, init->expn_table_entries,
tmp, ipa3_ctx->nat_mem.size);
+ mutex_unlock(&ipa3_ctx->nat_mem.lock);
return -EPERM;
}
@@ -402,6 +407,7 @@
if (init->index_offset >
UINT_MAX - (INDX_TBL_ENTRY_SIZE * (init->table_entries + 1))) {
IPAERR_RL("Detected overflow\n");
+ mutex_unlock(&ipa3_ctx->nat_mem.lock);
return -EPERM;
}
/* Check Indx Table Entry offset is not
@@ -413,6 +419,7 @@
IPAERR_RL("offset:%d entrys:%d size:%zu mem_size:%zu\n",
init->index_offset, (init->table_entries + 1),
tmp, ipa3_ctx->nat_mem.size);
+ mutex_unlock(&ipa3_ctx->nat_mem.lock);
return -EPERM;
}
@@ -420,6 +427,7 @@
if (init->index_expn_offset >
UINT_MAX - (INDX_TBL_ENTRY_SIZE * init->expn_table_entries)) {
IPAERR_RL("Detected overflow\n");
+ mutex_unlock(&ipa3_ctx->nat_mem.lock);
return -EPERM;
}
/* Check Expn Table entry offset is not
@@ -431,6 +439,7 @@
IPAERR_RL("offset:%d entrys:%d size:%zu mem_size:%zu\n",
init->index_expn_offset, init->expn_table_entries,
tmp, ipa3_ctx->nat_mem.size);
+ mutex_unlock(&ipa3_ctx->nat_mem.lock);
return -EPERM;
}
@@ -580,6 +589,7 @@
free_nop:
ipahal_destroy_imm_cmd(nop_cmd_pyld);
bail:
+ mutex_unlock(&ipa3_ctx->nat_mem.lock);
return result;
}
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c b/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
index 759610f..587f41c 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
@@ -1753,6 +1753,15 @@
}
}
}
+
+ /* commit the change to IPA-HW */
+ if (ipa3_ctx->ctrl->ipa3_commit_rt(IPA_IP_v4) ||
+ ipa3_ctx->ctrl->ipa3_commit_rt(IPA_IP_v6)) {
+ IPAERR("fail to commit rt-rule\n");
+ WARN_ON_RATELIMIT_IPA(1);
+ mutex_unlock(&ipa3_ctx->lock);
+ return -EPERM;
+ }
mutex_unlock(&ipa3_ctx->lock);
return 0;
diff --git a/drivers/platform/msm/mhi_dev/mhi.c b/drivers/platform/msm/mhi_dev/mhi.c
index b53af00..d76cec6 100644
--- a/drivers/platform/msm/mhi_dev/mhi.c
+++ b/drivers/platform/msm/mhi_dev/mhi.c
@@ -1483,6 +1483,7 @@
enum mhi_dev_state state;
enum mhi_dev_event event = 0;
bool mhi_reset = false;
+ uint32_t bhi_imgtxdb = 0;
mutex_lock(&mhi_ctx->mhi_lock);
/* Check for interrupts */
@@ -1520,6 +1521,10 @@
pr_err("error sending SM event\n");
goto fail;
}
+
+ rc = mhi_dev_mmio_read(mhi, BHI_IMGTXDB, &bhi_imgtxdb);
+ mhi_log(MHI_MSG_VERBOSE,
+ "BHI_IMGTXDB = 0x%x\n", bhi_imgtxdb);
}
if (int_value & MHI_MMIO_CTRL_CRDB_STATUS_MSK) {
@@ -1878,6 +1883,7 @@
(struct mhi_dev_client_cb_reason *cb))
{
int rc = 0;
+ int i = 0;
struct mhi_dev_channel *ch;
struct platform_device *pdev;
@@ -1901,6 +1907,38 @@
goto exit;
}
+ /* Pre allocate event requests */
+ ch->ereqs = kcalloc(MHI_MAX_EVT_REQ, sizeof(*ch->ereqs), GFP_KERNEL);
+ if (!ch->ereqs) {
+ rc = -ENOMEM;
+ goto free_client;
+ }
+ /* pre allocate buffers to queue transfer completion events */
+ ch->tr_events = kcalloc(MHI_MAX_EVT_REQ,
+ MAX_TR_EVENTS * sizeof(*ch->tr_events),
+ GFP_KERNEL);
+ if (!ch->tr_events) {
+ rc = -ENOMEM;
+ goto free_ereqs;
+ }
+
+ /*
+ * Organize the above allocated event request block and
+ * completion event block into linked lists. Each event
+ * request includes a pointer to a block of MAX_TR_EVENTS
+ * completion events.
+ */
+ INIT_LIST_HEAD(&mhi_ctx->ch[chan_id].event_req_buffers);
+ for (i = 0; i < MHI_MAX_EVT_REQ; ++i) {
+ ch->ereqs[i].tr_events = ch->tr_events + i * MAX_TR_EVENTS;
+ list_add_tail(&ch->ereqs[i].list,
+ &mhi_ctx->ch[chan_id].event_req_buffers);
+ }
+ mhi_ctx->ch[chan_id].curr_ereq =
+ container_of(mhi_ctx->ch[chan_id].event_req_buffers.next,
+ struct event_req, list);
+ list_del_init(&mhi_ctx->ch[chan_id].curr_ereq->list);
+
ch->active_client = (*handle_client);
(*handle_client)->channel = ch;
(*handle_client)->event_trigger = mhi_dev_client_cb_reason;
@@ -1913,6 +1951,13 @@
else if (ch->state == MHI_DEV_CH_STOPPED)
ch->state = MHI_DEV_CH_PENDING_START;
+ goto exit;
+
+free_ereqs:
+ kfree(ch->ereqs);
+ ch->ereqs = NULL;
+free_client:
+ kfree(*handle_client);
exit:
mutex_unlock(&ch->ch_lock);
return rc;
@@ -1946,14 +1991,12 @@
mhi_log(MHI_MSG_ERROR,
"Trying to close an active channel (%d)\n",
ch->ch_id);
- mutex_unlock(&ch->ch_lock);
rc = -EAGAIN;
goto exit;
} else if (ch->tre_loc) {
mhi_log(MHI_MSG_ERROR,
"Trying to close channel (%d) when a TRE is active",
ch->ch_id);
- mutex_unlock(&ch->ch_lock);
rc = -EAGAIN;
goto exit;
}
@@ -1961,6 +2004,10 @@
ch->state = MHI_DEV_CH_CLOSED;
ch->active_client = NULL;
+ kfree(ch->ereqs);
+ kfree(ch->tr_events);
+ ch->ereqs = NULL;
+ ch->tr_events = NULL;
kfree(handle);
exit:
mutex_unlock(&ch->ch_lock);
@@ -2668,40 +2715,8 @@
if (!mhi->ch)
return -ENOMEM;
-
- for (i = 0; i < mhi->cfg.channels; i++) {
+ for (i = 0; i < mhi->cfg.channels; i++)
mutex_init(&mhi->ch[i].ch_lock);
- if (i == MHI_CLIENT_IP_SW_4_OUT || i == MHI_CLIENT_IP_SW_4_IN) {
- int nreq = 0;
-
- INIT_LIST_HEAD(&mhi->ch[i].event_req_buffers);
- while (nreq < MHI_MAX_EVT_REQ) {
- struct event_req *ereq;
- /* Pre allocate event requests */
- ereq = kzalloc(sizeof(struct event_req),
- GFP_KERNEL);
- if (!ereq)
- return -ENOMEM;
-
- /* pre allocate buffers to queue
- * transfer completion events
- */
- ereq->tr_events = kzalloc(RING_ELEMENT_TYPE_SZ*
- MAX_TR_EVENTS, GFP_KERNEL);
- if (!ereq->tr_events) {
- kfree(ereq);
- return -ENOMEM;
- }
- list_add_tail(&ereq->list,
- &mhi->ch[i].event_req_buffers);
- nreq++;
- }
- mhi->ch[i].curr_ereq =
- container_of(mhi->ch[i].event_req_buffers.next,
- struct event_req, list);
- list_del_init(&mhi->ch[i].curr_ereq->list);
- }
- }
spin_lock_init(&mhi->lock);
mhi->mmio_backup = devm_kzalloc(&pdev->dev,
diff --git a/drivers/platform/msm/mhi_dev/mhi.h b/drivers/platform/msm/mhi_dev/mhi.h
index d764e1c..147a435 100644
--- a/drivers/platform/msm/mhi_dev/mhi.h
+++ b/drivers/platform/msm/mhi_dev/mhi.h
@@ -440,7 +440,13 @@
struct mutex ch_lock;
/* client which the current inbound/outbound message is for */
struct mhi_dev_client *active_client;
-
+ /*
+ * Pointer to event request structs used to temporarily store
+ * completion events and meta data before sending them to host
+ */
+ struct event_req *ereqs;
+ /* Pointer to completion event buffers */
+ union mhi_dev_ring_element_type *tr_events;
struct list_head event_req_buffers;
struct event_req *curr_ereq;
diff --git a/drivers/platform/msm/mhi_dev/mhi_hwio.h b/drivers/platform/msm/mhi_dev/mhi_hwio.h
index 40e1a91a..db46f27 100644
--- a/drivers/platform/msm/mhi_dev/mhi_hwio.h
+++ b/drivers/platform/msm/mhi_dev/mhi_hwio.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015, 2017-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -192,4 +192,6 @@
#define BHI_EXECENV_MASK 0xFFFFFFFF
#define BHI_EXECENV_SHIFT 0
+#define BHI_IMGTXDB (0x218)
+
#endif
diff --git a/drivers/platform/msm/mhi_dev/mhi_ring.c b/drivers/platform/msm/mhi_dev/mhi_ring.c
index 785d6d0..91496a4 100644
--- a/drivers/platform/msm/mhi_dev/mhi_ring.c
+++ b/drivers/platform/msm/mhi_dev/mhi_ring.c
@@ -264,11 +264,12 @@
int mhi_dev_add_element(struct mhi_dev_ring *ring,
union mhi_dev_ring_element_type *element,
- struct event_req *ereq, int evt_offset)
+ struct event_req *ereq, int size)
{
uint32_t old_offset = 0;
struct mhi_addr host_addr;
- uint32_t num_elem = 0;
+ uint32_t num_elem = 1;
+ uint32_t num_free_elem;
if (!ring || !element) {
pr_err("%s: Invalid context\n", __func__);
@@ -277,16 +278,24 @@
mhi_dev_update_wr_offset(ring);
- if ((ring->rd_offset + 1) % ring->ring_size == ring->wr_offset) {
- mhi_log(MHI_MSG_VERBOSE, "ring full to insert element\n");
+ if (ereq)
+ num_elem = size / (sizeof(union mhi_dev_ring_element_type));
+
+ if (ring->rd_offset < ring->wr_offset)
+ num_free_elem = ring->wr_offset - ring->rd_offset - 1;
+ else
+ num_free_elem = ring->ring_size - ring->rd_offset +
+ ring->wr_offset - 1;
+
+ if (num_free_elem < num_elem) {
+ mhi_log(MHI_MSG_ERROR, "No space to add %d elem in ring (%d)\n",
+ num_elem, ring->id);
return -EINVAL;
}
old_offset = ring->rd_offset;
- if (evt_offset) {
- num_elem = evt_offset /
- (sizeof(union mhi_dev_ring_element_type));
+ if (ereq) {
ring->rd_offset += num_elem;
if (ring->rd_offset >= ring->ring_size)
ring->rd_offset -= ring->ring_size;
@@ -308,23 +317,47 @@
host_addr.device_va = ring->ring_shadow.device_va +
sizeof(union mhi_dev_ring_element_type) * old_offset;
- host_addr.virt_addr = element;
-
- if (evt_offset)
- host_addr.size = evt_offset;
- else
+ if (!ereq) {
+ /* We're adding only a single ring element */
+ host_addr.virt_addr = element;
host_addr.size = sizeof(union mhi_dev_ring_element_type);
- mhi_log(MHI_MSG_VERBOSE, "adding element to ring (%d)\n", ring->id);
- mhi_log(MHI_MSG_VERBOSE, "rd_ofset %d\n", ring->rd_offset);
- mhi_log(MHI_MSG_VERBOSE, "type %d\n", element->generic.type);
+ mhi_log(MHI_MSG_VERBOSE, "adding element to ring (%d)\n",
+ ring->id);
+ mhi_log(MHI_MSG_VERBOSE, "rd_ofset %d\n", ring->rd_offset);
+ mhi_log(MHI_MSG_VERBOSE, "type %d\n", element->generic.type);
- if (ereq)
mhi_dev_write_to_host(ring->mhi_dev, &host_addr,
- ereq, MHI_DEV_DMA_ASYNC);
- else
+ NULL, MHI_DEV_DMA_SYNC);
+ return 0;
+ }
+
+ /* Adding multiple ring elements */
+ if (ring->rd_offset == 0 || (ring->rd_offset > old_offset)) {
+ /* No wrap-around case */
+ host_addr.virt_addr = element;
+ host_addr.size = size;
mhi_dev_write_to_host(ring->mhi_dev, &host_addr,
- NULL, MHI_DEV_DMA_SYNC);
+ ereq, MHI_DEV_DMA_ASYNC);
+ } else {
+ /* Wrap-around case - first chunk uses dma sync */
+ host_addr.virt_addr = element;
+ host_addr.size = (ring->ring_size - old_offset) *
+ sizeof(union mhi_dev_ring_element_type);
+ mhi_dev_write_to_host(ring->mhi_dev, &host_addr,
+ NULL, MHI_DEV_DMA_SYNC);
+
+ /* Copy remaining elements */
+ if (ring->mhi_dev->use_ipa)
+ host_addr.host_pa = ring->ring_shadow.host_pa;
+ else
+ host_addr.device_va = ring->ring_shadow.device_va;
+ host_addr.virt_addr = element + (ring->ring_size - old_offset);
+ host_addr.size = ring->rd_offset *
+ sizeof(union mhi_dev_ring_element_type);
+ mhi_dev_write_to_host(ring->mhi_dev, &host_addr,
+ ereq, MHI_DEV_DMA_ASYNC);
+ }
return 0;
}
EXPORT_SYMBOL(mhi_dev_add_element);
diff --git a/drivers/platform/msm/mhi_dev/mhi_sm.c b/drivers/platform/msm/mhi_dev/mhi_sm.c
index dc149bc..f30263d 100644
--- a/drivers/platform/msm/mhi_dev/mhi_sm.c
+++ b/drivers/platform/msm/mhi_dev/mhi_sm.c
@@ -399,15 +399,18 @@
break;
case EP_PCIE_EVENT_PM_D3_HOT:
res = ((curr_mstate == MHI_DEV_M3_STATE ||
- curr_mstate == MHI_DEV_READY_STATE) &&
+ curr_mstate == MHI_DEV_READY_STATE ||
+ curr_mstate == MHI_DEV_RESET_STATE) &&
curr_dstate != MHI_SM_EP_PCIE_LINK_DISABLE);
break;
case EP_PCIE_EVENT_PM_D3_COLD:
res = (curr_dstate == MHI_SM_EP_PCIE_D3_HOT_STATE ||
- curr_dstate == MHI_SM_EP_PCIE_D3_COLD_STATE);
+ curr_dstate == MHI_SM_EP_PCIE_D3_COLD_STATE ||
+ curr_dstate == MHI_SM_EP_PCIE_D0_STATE);
break;
case EP_PCIE_EVENT_PM_RST_DEAST:
res = (curr_dstate == MHI_SM_EP_PCIE_D0_STATE ||
+ curr_dstate == MHI_SM_EP_PCIE_D3_HOT_STATE ||
curr_dstate == MHI_SM_EP_PCIE_D3_COLD_STATE);
break;
case EP_PCIE_EVENT_PM_D0:
diff --git a/drivers/platform/msm/mhi_dev/mhi_uci.c b/drivers/platform/msm/mhi_dev/mhi_uci.c
index 4d9aa2e..41360fb 100644
--- a/drivers/platform/msm/mhi_dev/mhi_uci.c
+++ b/drivers/platform/msm/mhi_dev/mhi_uci.c
@@ -35,9 +35,13 @@
#define MHI_SOFTWARE_CLIENT_LIMIT (MHI_MAX_SOFTWARE_CHANNELS/2)
#define MHI_UCI_IPC_LOG_PAGES (100)
-#define MAX_NR_TRBS_PER_CHAN 1
+/* Max number of MHI write request structures (used in async writes) */
+#define MAX_UCI_WR_REQ 10
+#define MAX_NR_TRBS_PER_CHAN 9
#define MHI_QTI_IFACE_ID 4
-#define DEVICE_NAME "mhi"
+#define DEVICE_NAME "mhi"
+
+#define MHI_UCI_ASYNC_READ_TIMEOUT msecs_to_jiffies(100)
enum uci_dbg_level {
UCI_DBG_VERBOSE = 0x0,
@@ -70,7 +74,131 @@
u32 nr_trbs;
/* direction of the channel, see enum mhi_chan_dir */
enum mhi_chan_dir dir;
- u32 uci_ownership;
+ /* need to register mhi channel state change callback */
+ bool register_cb;
+};
+
+/* UCI channel attributes table */
+static const struct chan_attr uci_chan_attr_table[] = {
+ {
+ MHI_CLIENT_LOOPBACK_OUT,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_OUT,
+ false
+ },
+ {
+ MHI_CLIENT_LOOPBACK_IN,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_IN,
+ false
+ },
+ {
+ MHI_CLIENT_SAHARA_OUT,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_OUT,
+ false
+ },
+ {
+ MHI_CLIENT_SAHARA_IN,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_IN,
+ false
+ },
+ {
+ MHI_CLIENT_EFS_OUT,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_OUT,
+ false
+ },
+ {
+ MHI_CLIENT_EFS_IN,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_IN,
+ false
+ },
+ {
+ MHI_CLIENT_MBIM_OUT,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_OUT,
+ false
+ },
+ {
+ MHI_CLIENT_MBIM_IN,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_IN,
+ false
+ },
+ {
+ MHI_CLIENT_QMI_OUT,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_OUT,
+ false
+ },
+ {
+ MHI_CLIENT_QMI_IN,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_IN,
+ false
+ },
+ {
+ MHI_CLIENT_IP_CTRL_0_OUT,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_OUT,
+ false
+ },
+ {
+ MHI_CLIENT_IP_CTRL_0_IN,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_IN,
+ false
+ },
+ {
+ MHI_CLIENT_IP_CTRL_1_OUT,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_OUT,
+ false
+ },
+ {
+ MHI_CLIENT_IP_CTRL_1_IN,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_IN,
+ false
+ },
+ {
+ MHI_CLIENT_DUN_OUT,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_OUT,
+ false
+ },
+ {
+ MHI_CLIENT_DUN_IN,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_IN,
+ false
+ },
+ { /* Must be the last */
+ MHI_CLIENT_INVALID,
+ 0,
+ 0,
+ MHI_DIR_INVALID,
+ false
+ },
};
struct uci_ctrl {
@@ -87,6 +215,8 @@
u32 in_chan;
struct mhi_dev_client *out_handle;
struct mhi_dev_client *in_handle;
+ const struct chan_attr *in_chan_attr;
+ const struct chan_attr *out_chan_attr;
wait_queue_head_t read_wq;
wait_queue_head_t write_wq;
atomic_t read_data_ready;
@@ -101,10 +231,16 @@
struct mhi_uci_ctxt_t *uci_ctxt;
struct mutex in_chan_lock;
struct mutex out_chan_lock;
+ spinlock_t wr_req_lock;
+ unsigned int f_flags;
+ struct mhi_req *wreqs;
+ struct list_head wr_req_list;
+ struct completion read_done;
+ int (*send)(struct uci_client*, void*, u32);
+ int (*read)(struct uci_client*, struct mhi_req*, int*);
};
struct mhi_uci_ctxt_t {
- struct chan_attr chan_attrib[MHI_MAX_SOFTWARE_CHANNELS];
struct uci_client client_handles[MHI_SOFTWARE_CLIENT_LIMIT];
struct uci_ctrl ctrl_handle;
void (*event_notifier)(struct mhi_dev_client_cb_reason *cb);
@@ -119,6 +255,7 @@
};
#define CHAN_TO_CLIENT(_CHAN_NR) (_CHAN_NR / 2)
+#define CLIENT_TO_CHAN(_CLIENT_NR) (_CLIENT_NR * 2)
#define uci_log(_msg_lvl, _msg, ...) do { \
if (_msg_lvl >= mhi_uci_msg_lvl) { \
@@ -155,8 +292,8 @@
enum mhi_client_channel chan)
{
int rc = 0;
- u32 i , j;
- struct chan_attr *chan_attributes;
+ u32 i, j;
+ const struct chan_attr *in_chan_attr;
size_t buf_size;
void *data_loc;
@@ -169,10 +306,18 @@
return -EINVAL;
}
- chan_attributes = &uci_ctxt.chan_attrib[chan];
- buf_size = chan_attributes->max_packet_size;
+ in_chan_attr = client_handle->in_chan_attr;
+ if (!in_chan_attr) {
+ uci_log(UCI_DBG_ERROR, "Null channel attributes for chan %d\n",
+ client_handle->in_chan);
+ return -EINVAL;
+ }
- for (i = 0; i < (chan_attributes->nr_trbs); i++) {
+ /* Init the completion event for read */
+ init_completion(&client_handle->read_done);
+
+ buf_size = in_chan_attr->max_packet_size;
+ for (i = 0; i < (in_chan_attr->nr_trbs); i++) {
data_loc = kmalloc(buf_size, GFP_KERNEL);
if (!data_loc) {
rc = -ENOMEM;
@@ -191,48 +336,129 @@
return rc;
}
-static int mhi_uci_send_packet(struct mhi_dev_client **client_handle, void *buf,
- u32 size, u32 is_uspace_buf)
+static void mhi_uci_write_completion_cb(void *req)
{
- void *data_loc = NULL;
- uintptr_t memcpy_result = 0;
- u32 data_inserted_so_far = 0;
+ struct mhi_req *ureq = req;
struct uci_client *uci_handle;
+ unsigned long flags;
+
+ uci_handle = (struct uci_client *)ureq->context;
+ kfree(ureq->buf);
+ ureq->buf = NULL;
+
+ spin_lock_irqsave(&uci_handle->wr_req_lock, flags);
+ list_add_tail(&ureq->list, &uci_handle->wr_req_list);
+ spin_unlock_irqrestore(&uci_handle->wr_req_lock, flags);
+}
+
+static void mhi_uci_read_completion_cb(void *req)
+{
+ struct mhi_req *ureq = req;
+ struct uci_client *uci_handle;
+
+ uci_handle = (struct uci_client *)ureq->context;
+ complete(&uci_handle->read_done);
+}
+
+static int mhi_uci_send_sync(struct uci_client *uci_handle,
+ void *data_loc, u32 size)
+{
struct mhi_req ureq;
+ int ret_val;
-
- uci_handle = container_of(client_handle, struct uci_client,
- out_handle);
-
- if (!client_handle || !buf ||
- !size || !uci_handle)
- return -EINVAL;
-
- if (is_uspace_buf) {
- data_loc = kmalloc(size, GFP_KERNEL);
- if (!data_loc) {
- uci_log(UCI_DBG_ERROR,
- "Failed to allocate memory 0x%x\n",
- size);
- return -ENOMEM;
- }
- memcpy_result = copy_from_user(data_loc, buf, size);
- if (memcpy_result)
- goto error_memcpy;
- } else {
- data_loc = buf;
- }
- ureq.client = *client_handle;
+ ureq.client = uci_handle->out_handle;
ureq.buf = data_loc;
ureq.len = size;
ureq.chan = uci_handle->out_chan;
ureq.mode = IPA_DMA_SYNC;
- data_inserted_so_far = mhi_dev_write_channel(&ureq);
+ ret_val = mhi_dev_write_channel(&ureq);
+
+ kfree(data_loc);
+ return ret_val;
+}
+
+static int mhi_uci_send_async(struct uci_client *uci_handle,
+ void *data_loc, u32 size)
+{
+ int bytes_to_write;
+ struct mhi_req *ureq;
+
+ uci_log(UCI_DBG_VERBOSE,
+ "Got async write for ch %d of size %d\n",
+ uci_handle->out_chan, size);
+
+ spin_lock_irq(&uci_handle->wr_req_lock);
+ if (list_empty(&uci_handle->wr_req_list)) {
+ uci_log(UCI_DBG_ERROR, "Write request pool empty\n");
+ spin_unlock_irq(&uci_handle->wr_req_lock);
+ return -ENOMEM;
+ }
+ ureq = container_of(uci_handle->wr_req_list.next,
+ struct mhi_req, list);
+ list_del_init(&ureq->list);
+ spin_unlock_irq(&uci_handle->wr_req_lock);
+
+ ureq->client = uci_handle->out_handle;
+ ureq->context = uci_handle;
+ ureq->buf = data_loc;
+ ureq->len = size;
+ ureq->chan = uci_handle->out_chan;
+ ureq->mode = IPA_DMA_ASYNC;
+ ureq->client_cb = mhi_uci_write_completion_cb;
+ ureq->snd_cmpl = 1;
+
+ bytes_to_write = mhi_dev_write_channel(ureq);
+ if (bytes_to_write != size)
+ goto error_async_transfer;
+
+ return bytes_to_write;
+
+error_async_transfer:
+ kfree(data_loc);
+ ureq->buf = NULL;
+ spin_lock_irq(&uci_handle->wr_req_lock);
+ list_add_tail(&ureq->list, &uci_handle->wr_req_list);
+ spin_unlock_irq(&uci_handle->wr_req_lock);
+
+ return bytes_to_write;
+}
+
+static int mhi_uci_send_packet(struct mhi_dev_client **client_handle,
+ const char __user *buf, u32 size)
+{
+ void *data_loc;
+ unsigned long memcpy_result;
+ struct uci_client *uci_handle;
+
+ if (!client_handle || !buf || !size)
+ return -EINVAL;
+
+ if (size > TRB_MAX_DATA_SIZE) {
+ uci_log(UCI_DBG_ERROR,
+ "Too big write size: %d, max supported size is %d\n",
+ size, TRB_MAX_DATA_SIZE);
+ return -EFBIG;
+ }
+
+ uci_handle = container_of(client_handle, struct uci_client,
+ out_handle);
+ data_loc = kmalloc(size, GFP_KERNEL);
+ if (!data_loc) {
+ uci_log(UCI_DBG_ERROR,
+ "Failed to allocate kernel buf for user requested size 0x%x\n",
+ size);
+ return -ENOMEM;
+ }
+ memcpy_result = copy_from_user(data_loc, buf, size);
+ if (memcpy_result)
+ goto error_memcpy;
+
+ return uci_handle->send(uci_handle, data_loc, size);
error_memcpy:
kfree(data_loc);
- return data_inserted_so_far;
+ return -EFAULT;
}
static unsigned int mhi_uci_ctrl_poll(struct file *file, poll_table *wait)
@@ -290,6 +516,119 @@
return mask;
}
+static int mhi_uci_alloc_write_reqs(struct uci_client *client)
+{
+ int i;
+
+ client->wreqs = kcalloc(MAX_UCI_WR_REQ,
+ sizeof(struct mhi_req),
+ GFP_KERNEL);
+ if (!client->wreqs) {
+ uci_log(UCI_DBG_ERROR, "Write reqs alloc failed\n");
+ return -ENOMEM;
+ }
+
+ INIT_LIST_HEAD(&client->wr_req_list);
+ for (i = 0; i < MAX_UCI_WR_REQ; ++i)
+ list_add_tail(&client->wreqs[i].list, &client->wr_req_list);
+
+ uci_log(UCI_DBG_INFO,
+ "UCI write reqs allocation successful\n");
+ return 0;
+}
+
+static int mhi_uci_read_async(struct uci_client *uci_handle,
+ struct mhi_req *ureq, int *bytes_avail)
+{
+ int ret_val = 0;
+ unsigned long compl_ret;
+
+ uci_log(UCI_DBG_ERROR,
+ "Async read for ch %d\n", uci_handle->in_chan);
+
+ ureq->mode = IPA_DMA_ASYNC;
+ ureq->client_cb = mhi_uci_read_completion_cb;
+ ureq->snd_cmpl = 1;
+ ureq->context = uci_handle;
+
+ reinit_completion(&uci_handle->read_done);
+
+ *bytes_avail = mhi_dev_read_channel(ureq);
+ uci_log(UCI_DBG_VERBOSE, "buf_size = 0x%x bytes_read = 0x%x\n",
+ ureq->len, *bytes_avail);
+ if (*bytes_avail < 0) {
+ uci_log(UCI_DBG_ERROR, "Failed to read channel ret %d\n",
+ *bytes_avail);
+ return -EIO;
+ }
+
+ if (*bytes_avail > 0) {
+ uci_log(UCI_DBG_VERBOSE,
+ "Waiting for async read completion!\n");
+ compl_ret =
+ wait_for_completion_interruptible_timeout(
+ &uci_handle->read_done,
+ MHI_UCI_ASYNC_READ_TIMEOUT);
+
+ if (compl_ret == -ERESTARTSYS) {
+ uci_log(UCI_DBG_ERROR, "Exit signal caught\n");
+ return compl_ret;
+ } else if (compl_ret == 0) {
+ uci_log(UCI_DBG_ERROR, "Read timed out for ch %d\n",
+ uci_handle->in_chan);
+ return -EIO;
+ }
+ uci_log(UCI_DBG_VERBOSE,
+ "wk up Read completed on ch %d\n", ureq->chan);
+
+ uci_handle->pkt_loc = (void *)ureq->buf;
+ uci_handle->pkt_size = ureq->actual_len;
+
+ uci_log(UCI_DBG_VERBOSE,
+ "Got pkt of sz 0x%x at adr %pK, ch %d\n",
+ uci_handle->pkt_size,
+ ureq->buf, ureq->chan);
+ } else {
+ uci_handle->pkt_loc = NULL;
+ uci_handle->pkt_size = 0;
+ }
+
+ return ret_val;
+}
+
+static int mhi_uci_read_sync(struct uci_client *uci_handle,
+ struct mhi_req *ureq, int *bytes_avail)
+{
+ int ret_val = 0;
+
+ ureq->mode = IPA_DMA_SYNC;
+ *bytes_avail = mhi_dev_read_channel(ureq);
+
+ uci_log(UCI_DBG_VERBOSE, "buf_size = 0x%x bytes_read = 0x%x\n",
+ ureq->len, *bytes_avail);
+
+ if (*bytes_avail < 0) {
+ uci_log(UCI_DBG_ERROR, "Failed to read channel ret %d\n",
+ *bytes_avail);
+ return -EIO;
+ }
+
+ if (*bytes_avail > 0) {
+ uci_handle->pkt_loc = (void *)ureq->buf;
+ uci_handle->pkt_size = ureq->actual_len;
+
+ uci_log(UCI_DBG_VERBOSE,
+ "Got pkt of sz 0x%x at adr %pK, ch %d\n",
+ uci_handle->pkt_size,
+ ureq->buf, ureq->chan);
+ } else {
+ uci_handle->pkt_loc = NULL;
+ uci_handle->pkt_size = 0;
+ }
+
+ return ret_val;
+}
+
static int open_client_mhi_channels(struct uci_client *uci_client)
{
int rc = 0;
@@ -300,16 +639,27 @@
uci_client->in_chan);
mutex_lock(&uci_client->out_chan_lock);
mutex_lock(&uci_client->in_chan_lock);
+
+ /* Allocate write requests for async operations */
+ if (!(uci_client->f_flags & O_SYNC)) {
+ rc = mhi_uci_alloc_write_reqs(uci_client);
+ if (rc)
+ goto handle_not_rdy_err;
+ uci_client->send = mhi_uci_send_async;
+ uci_client->read = mhi_uci_read_async;
+ } else {
+ uci_client->send = mhi_uci_send_sync;
+ uci_client->read = mhi_uci_read_sync;
+ }
+
uci_log(UCI_DBG_DBG,
"Initializing inbound chan %d.\n",
uci_client->in_chan);
-
rc = mhi_init_read_chan(uci_client, uci_client->in_chan);
- if (rc < 0) {
+ if (rc < 0)
uci_log(UCI_DBG_ERROR,
"Failed to init inbound 0x%x, ret 0x%x\n",
uci_client->in_chan, rc);
- }
rc = mhi_dev_open_channel(uci_client->out_chan,
&uci_client->out_handle,
@@ -320,7 +670,6 @@
rc = mhi_dev_open_channel(uci_client->in_chan,
&uci_client->in_handle,
uci_ctxt.event_notifier);
-
if (rc < 0) {
uci_log(UCI_DBG_ERROR,
"Failed to open chan %d, ret 0x%x\n",
@@ -375,6 +724,7 @@
return -ENOMEM;
}
uci_handle->uci_ctxt = &uci_ctxt;
+ uci_handle->f_flags = file_handle->f_flags;
if (!atomic_read(&uci_handle->mhi_chans_open)) {
uci_log(UCI_DBG_INFO,
"Opening channels client %d\n",
@@ -397,20 +747,11 @@
struct file *file_handle)
{
struct uci_client *uci_handle = file_handle->private_data;
- struct mhi_uci_ctxt_t *uci_ctxt;
- u32 nr_in_bufs = 0;
int rc = 0;
- int in_chan = 0;
- u32 buf_size = 0;
if (!uci_handle)
return -EINVAL;
- uci_ctxt = uci_handle->uci_ctxt;
- in_chan = iminor(mhi_inode) + 1;
- nr_in_bufs = uci_ctxt->chan_attrib[in_chan].nr_trbs;
- buf_size = uci_ctxt->chan_attrib[in_chan].max_packet_size;
-
if (atomic_sub_return(1, &uci_handle->ref_count) == 0) {
uci_log(UCI_DBG_DBG,
"Last client left, closing channel 0x%x\n",
@@ -418,6 +759,8 @@
if (atomic_read(&uci_handle->mhi_chans_open)) {
atomic_set(&uci_handle->mhi_chans_open, 0);
+ if (!(uci_handle->f_flags & O_SYNC))
+ kfree(uci_handle->wreqs);
mutex_lock(&uci_handle->out_chan_lock);
rc = mhi_dev_close_channel(uci_handle->out_handle);
wake_up(&uci_handle->write_wq);
@@ -553,7 +896,6 @@
struct mutex *mutex;
ssize_t bytes_copied = 0;
u32 addr_offset = 0;
- void *local_buf = NULL;
struct mhi_req ureq;
if (!file || !ubuf || !uspace_buf_size ||
@@ -569,44 +911,19 @@
ureq.client = client_handle;
ureq.buf = uci_handle->in_buf_list[0].addr;
ureq.len = uci_handle->in_buf_list[0].buf_size;
- ureq.mode = IPA_DMA_SYNC;
+
uci_log(UCI_DBG_VERBOSE, "Client attempted read on chan %d\n",
ureq.chan);
do {
if (!uci_handle->pkt_loc &&
- !atomic_read(&uci_ctxt.mhi_disabled)) {
-
- bytes_avail = mhi_dev_read_channel(&ureq);
-
- uci_log(UCI_DBG_VERBOSE,
- "reading from mhi_core local_buf = %p",
- local_buf);
- uci_log(UCI_DBG_VERBOSE,
- "buf_size = 0x%x bytes_read = 0x%x\n",
- ureq.len, bytes_avail);
-
- if (bytes_avail < 0) {
- uci_log(UCI_DBG_ERROR,
- "Failed to read channel ret %d\n",
- bytes_avail);
- ret_val = -EIO;
+ !atomic_read(&uci_ctxt.mhi_disabled)) {
+ ret_val = uci_handle->read(uci_handle, &ureq,
+ &bytes_avail);
+ if (ret_val)
goto error;
- }
-
- if (bytes_avail > 0) {
- uci_handle->pkt_loc = (void *) ureq.buf;
- uci_handle->pkt_size = ureq.actual_len;
-
+ if (bytes_avail > 0)
*bytes_pending = (loff_t)uci_handle->pkt_size;
- uci_log(UCI_DBG_VERBOSE,
- "Got pkt of sz 0x%x at adr %p, ch %d\n",
- uci_handle->pkt_size,
- ureq.buf, ureq.chan);
- } else {
- uci_handle->pkt_loc = 0;
- uci_handle->pkt_size = 0;
- }
}
if (bytes_avail == 0) {
@@ -615,7 +932,10 @@
"No data read_data_ready %d, chan %d\n",
atomic_read(&uci_handle->read_data_ready),
ureq.chan);
-
+ if (uci_handle->f_flags & (O_NONBLOCK | O_NDELAY)) {
+ ret_val = -EAGAIN;
+ goto error;
+ }
ret_val = wait_event_interruptible(uci_handle->read_wq,
(!mhi_dev_channel_isempty(client_handle)));
@@ -719,10 +1039,10 @@
mutex_lock(&uci_handle->out_chan_lock);
while (!ret_val) {
ret_val = mhi_uci_send_packet(&uci_handle->out_handle,
- (void *)buf, count, 1);
+ buf, count);
if (ret_val < 0) {
uci_log(UCI_DBG_ERROR,
- "Error while writing data to MHI, chan %d, buf %p, size %d\n",
+ "Error while writing data to MHI, chan %d, buf %pK, size %d\n",
chan, (void *)buf, count);
ret_val = -EIO;
break;
@@ -732,6 +1052,8 @@
"No descriptors available, did we poll, chan %d?\n",
chan);
mutex_unlock(&uci_handle->out_chan_lock);
+ if (uci_handle->f_flags & (O_NONBLOCK | O_NDELAY))
+ return -EAGAIN;
ret_val = wait_event_interruptible(uci_handle->write_wq,
!mhi_dev_channel_isempty(
uci_handle->out_handle));
@@ -750,54 +1072,27 @@
static int uci_init_client_attributes(struct mhi_uci_ctxt_t *uci_ctxt)
{
- u32 i = 0;
- u32 data_size = TRB_MAX_DATA_SIZE;
- u32 index = 0;
+ u32 i;
+ u32 index;
struct uci_client *client;
- struct chan_attr *chan_attrib = NULL;
+ const struct chan_attr *chan_attrib;
- for (i = 0; i < ARRAY_SIZE(uci_ctxt->chan_attrib); i++) {
- chan_attrib = &uci_ctxt->chan_attrib[i];
- switch (i) {
- case MHI_CLIENT_LOOPBACK_OUT:
- case MHI_CLIENT_LOOPBACK_IN:
- case MHI_CLIENT_SAHARA_OUT:
- case MHI_CLIENT_SAHARA_IN:
- case MHI_CLIENT_EFS_OUT:
- case MHI_CLIENT_EFS_IN:
- case MHI_CLIENT_MBIM_OUT:
- case MHI_CLIENT_MBIM_IN:
- case MHI_CLIENT_QMI_OUT:
- case MHI_CLIENT_QMI_IN:
- case MHI_CLIENT_IP_CTRL_0_OUT:
- case MHI_CLIENT_IP_CTRL_0_IN:
- case MHI_CLIENT_IP_CTRL_1_OUT:
- case MHI_CLIENT_IP_CTRL_1_IN:
- case MHI_CLIENT_DUN_OUT:
- case MHI_CLIENT_DUN_IN:
- chan_attrib->uci_ownership = 1;
+ for (i = 0; i < ARRAY_SIZE(uci_chan_attr_table); i += 2) {
+ chan_attrib = &uci_chan_attr_table[i];
+ if (chan_attrib->chan_id == MHI_CLIENT_INVALID)
break;
- default:
- chan_attrib->uci_ownership = 0;
- break;
- }
- if (chan_attrib->uci_ownership) {
- chan_attrib->chan_id = i;
- chan_attrib->max_packet_size = data_size;
- index = CHAN_TO_CLIENT(i);
- client = &uci_ctxt->client_handles[index];
- chan_attrib->nr_trbs = 9;
- client->in_buf_list =
- kmalloc(sizeof(struct mhi_dev_iov) *
- chan_attrib->nr_trbs,
+ index = CHAN_TO_CLIENT(chan_attrib->chan_id);
+ client = &uci_ctxt->client_handles[index];
+ client->out_chan_attr = chan_attrib;
+ client->in_chan_attr = ++chan_attrib;
+ client->in_chan = index * 2;
+ client->out_chan = index * 2 + 1;
+ client->in_buf_list =
+ kcalloc(chan_attrib->nr_trbs,
+ sizeof(struct mhi_dev_iov),
GFP_KERNEL);
- if (NULL == client->in_buf_list)
- return -ENOMEM;
- }
- if (i % 2 == 0)
- chan_attrib->dir = MHI_DIR_OUT;
- else
- chan_attrib->dir = MHI_DIR_IN;
+ if (!client->in_buf_list)
+ return -ENOMEM;
}
return 0;
}
@@ -846,12 +1141,11 @@
{
init_waitqueue_head(&mhi_client->read_wq);
init_waitqueue_head(&mhi_client->write_wq);
- mhi_client->out_chan = index * 2 + 1;
- mhi_client->in_chan = index * 2;
mhi_client->client_index = index;
mutex_init(&mhi_client->in_chan_lock);
mutex_init(&mhi_client->out_chan_lock);
+ spin_lock_init(&mhi_client->wr_req_lock);
uci_log(UCI_DBG_DBG, "Registering chan %d.\n", mhi_client->out_chan);
return 0;
@@ -949,16 +1243,14 @@
uci_log(UCI_DBG_INFO, "Registering for MHI events.\n");
for (i = 0; i < MHI_SOFTWARE_CLIENT_LIMIT; i++) {
- if (uci_ctxt.chan_attrib[i * 2].uci_ownership) {
- mhi_client = &uci_ctxt.client_handles[i];
-
- r = mhi_register_client(mhi_client, i);
-
- if (r) {
- uci_log(UCI_DBG_CRITICAL,
- "Failed to reg client %d ret %d\n",
- r, i);
- }
+ mhi_client = &uci_ctxt.client_handles[i];
+ if (!mhi_client->in_chan_attr)
+ continue;
+ r = mhi_register_client(mhi_client, i);
+ if (r) {
+ uci_log(UCI_DBG_CRITICAL,
+ "Failed to reg client %d ret %d\n",
+ r, i);
}
}
@@ -992,29 +1284,30 @@
uci_log(UCI_DBG_INFO, "Setting up device nodes.\n");
for (i = 0; i < MHI_SOFTWARE_CLIENT_LIMIT; i++) {
- if (uci_ctxt.chan_attrib[i*2].uci_ownership) {
- cdev_init(&uci_ctxt.cdev[i], &mhi_uci_client_fops);
- uci_ctxt.cdev[i].owner = THIS_MODULE;
- r = cdev_add(&uci_ctxt.cdev[i],
- uci_ctxt.start_ctrl_nr + i , 1);
- if (IS_ERR_VALUE(r)) {
- uci_log(UCI_DBG_ERROR,
- "Failed to add cdev %d, ret 0x%x\n",
- i, r);
- goto failed_char_add;
- }
+ mhi_client = &uci_ctxt.client_handles[i];
+ if (!mhi_client->in_chan_attr)
+ continue;
+ cdev_init(&uci_ctxt.cdev[i], &mhi_uci_client_fops);
+ uci_ctxt.cdev[i].owner = THIS_MODULE;
+ r = cdev_add(&uci_ctxt.cdev[i],
+ uci_ctxt.start_ctrl_nr + i, 1);
+ if (IS_ERR_VALUE(r)) {
+ uci_log(UCI_DBG_ERROR,
+ "Failed to add cdev %d, ret 0x%x\n",
+ i, r);
+ goto failed_char_add;
+ }
- uci_ctxt.client_handles[i].dev =
- device_create(uci_ctxt.mhi_uci_class, NULL,
- uci_ctxt.start_ctrl_nr + i,
- NULL, DEVICE_NAME "_pipe_%d",
- i * 2);
- if (IS_ERR(uci_ctxt.client_handles[i].dev)) {
- uci_log(UCI_DBG_ERROR,
- "Failed to add cdev %d\n", i);
- cdev_del(&uci_ctxt.cdev[i]);
- goto failed_device_create;
- }
+ uci_ctxt.client_handles[i].dev =
+ device_create(uci_ctxt.mhi_uci_class, NULL,
+ uci_ctxt.start_ctrl_nr + i,
+ NULL, DEVICE_NAME "_pipe_%d",
+ i * 2);
+ if (IS_ERR(uci_ctxt.client_handles[i].dev)) {
+ uci_log(UCI_DBG_ERROR,
+ "Failed to add cdev %d\n", i);
+ cdev_del(&uci_ctxt.cdev[i]);
+ goto failed_device_create;
}
}
diff --git a/drivers/platform/msm/msm_bus/msm_bus_arb_adhoc.c b/drivers/platform/msm/msm_bus/msm_bus_arb_adhoc.c
index 6d9dc58..486e017 100644
--- a/drivers/platform/msm/msm_bus/msm_bus_arb_adhoc.c
+++ b/drivers/platform/msm/msm_bus/msm_bus_arb_adhoc.c
@@ -552,7 +552,8 @@
uint64_t max_ab = 0;
uint64_t sum_ab = 0;
- if (!bus_dev || !to_msm_bus_node(bus_dev->node_info->bus_device)) {
+ if (!bus_dev || !bus_dev->node_info->bus_device ||
+ !to_msm_bus_node(bus_dev->node_info->bus_device)) {
MSM_BUS_ERR("Bus node pointer is Invalid");
goto exit_agg_bus_req;
}
@@ -1016,7 +1017,7 @@
src = pdata->usecase->vectors[i].src;
dest = pdata->usecase->vectors[i].dst;
- if ((src < 0) || (dest < 0)) {
+ if ((src < 0) || (dest < 0) || (src == dest)) {
MSM_BUS_ERR("%s:Invalid src/dst.src %d dest %d",
__func__, src, dest);
goto exit_invalid_data;
diff --git a/drivers/platform/msm/msm_bus/msm_bus_fabric_adhoc.c b/drivers/platform/msm/msm_bus/msm_bus_fabric_adhoc.c
index 146d7c6..f3722a5 100644
--- a/drivers/platform/msm/msm_bus/msm_bus_fabric_adhoc.c
+++ b/drivers/platform/msm/msm_bus/msm_bus_fabric_adhoc.c
@@ -1012,10 +1012,8 @@
bus_node = kzalloc(sizeof(struct msm_bus_node_device_type), GFP_KERNEL);
if (!bus_node) {
- MSM_BUS_ERR("%s:Bus node alloc failed\n", __func__);
- kfree(bus_dev);
- bus_dev = NULL;
- goto exit_device_init;
+ ret = -ENOMEM;
+ goto err_device_init;
}
bus_dev = &bus_node->dev;
device_initialize(bus_dev);
@@ -1023,47 +1021,36 @@
node_info = devm_kzalloc(bus_dev,
sizeof(struct msm_bus_node_info_type), GFP_KERNEL);
if (!node_info) {
- MSM_BUS_ERR("%s:Bus node info alloc failed\n", __func__);
- devm_kfree(bus_dev, bus_node);
- kfree(bus_dev);
- bus_dev = NULL;
- goto exit_device_init;
+ ret = -ENOMEM;
+ goto err_put_device;
}
bus_node->node_info = node_info;
bus_node->ap_owned = pdata->ap_owned;
bus_dev->of_node = pdata->of_node;
- if (msm_bus_copy_node_info(pdata, bus_dev) < 0) {
- devm_kfree(bus_dev, bus_node);
- devm_kfree(bus_dev, node_info);
- kfree(bus_dev);
- bus_dev = NULL;
- goto exit_device_init;
- }
+ ret = msm_bus_copy_node_info(pdata, bus_dev);
+ if (ret)
+ goto err_put_device;
bus_dev->bus = &msm_bus_type;
dev_set_name(bus_dev, bus_node->node_info->name);
ret = device_add(bus_dev);
- if (ret < 0) {
+ if (ret) {
MSM_BUS_ERR("%s: Error registering device %d",
__func__, pdata->node_info->id);
- devm_kfree(bus_dev, bus_node);
- devm_kfree(bus_dev, node_info->dev_connections);
- devm_kfree(bus_dev, node_info->connections);
- devm_kfree(bus_dev, node_info->black_connections);
- devm_kfree(bus_dev, node_info->black_listed_connections);
- devm_kfree(bus_dev, node_info);
- kfree(bus_dev);
- bus_dev = NULL;
- goto exit_device_init;
+ goto err_put_device;
}
device_create_file(bus_dev, &dev_attr_bw);
INIT_LIST_HEAD(&bus_node->devlist);
-
-exit_device_init:
return bus_dev;
+err_put_device:
+ put_device(bus_dev);
+ bus_dev = NULL;
+ kfree(bus_node);
+err_device_init:
+ return ERR_PTR(ret);
}
static int msm_bus_setup_dev_conn(struct device *bus_dev, void *data)
@@ -1258,10 +1245,10 @@
node_dev = msm_bus_device_init(&pdata->info[i]);
- if (!node_dev) {
+ if (IS_ERR(node_dev)) {
MSM_BUS_ERR("%s: Error during dev init for %d",
__func__, pdata->info[i].node_info->id);
- ret = -ENXIO;
+ ret = PTR_ERR(node_dev);
goto exit_device_probe;
}
diff --git a/drivers/platform/msm/sps/sps.c b/drivers/platform/msm/sps/sps.c
index 03cc14a..2237db1 100644
--- a/drivers/platform/msm/sps/sps.c
+++ b/drivers/platform/msm/sps/sps.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1006,8 +1006,6 @@
"sps:%s:BAMs are still registered", __func__);
sps_map_de_init();
-
- kfree(sps);
}
sps_mem_de_init();
@@ -2989,6 +2987,7 @@
.name = SPS_DRV_NAME,
.owner = THIS_MODULE,
.of_match_table = msm_sps_match,
+ .suppress_bind_attrs = true,
},
.remove = msm_sps_remove,
};
diff --git a/drivers/platform/msm/ssm.c b/drivers/platform/msm/ssm.c
deleted file mode 100644
index 6a2909b..0000000
--- a/drivers/platform/msm/ssm.c
+++ /dev/null
@@ -1,516 +0,0 @@
-/* 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
- * 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.
- */
-/*
- * QTI Secure Service Module(SSM) driver
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/fs.h>
-#include <linux/of.h>
-#include <linux/cdev.h>
-#include <linux/uaccess.h>
-#include <linux/mutex.h>
-#include <linux/ion.h>
-#include <linux/types.h>
-#include <linux/elf.h>
-#include <linux/platform_device.h>
-#include <linux/msm_ion.h>
-#include <linux/platform_data/qcom_ssm.h>
-#include <soc/qcom/scm.h>
-#include <soc/qcom/smd.h>
-
-#include "../../misc/qseecom_kernel.h"
-#include "ssm.h"
-
-/* Macros */
-#define SSM_DEV_NAME "ssm"
-#define MPSS_SUBSYS 0
-#define SSM_INFO_CMD_ID 1
-#define MAX_APP_NAME_SIZE 32
-#define SSM_MSG_LEN 200
-#define SSM_MSG_FIELD_LEN 11
-#define ATOM_MSG_LEN (SSM_MSG_FIELD_LEN + SSM_MSG_LEN + 40)
-
-#define TZAPP_NAME "SsmApp"
-#define CHANNEL_NAME "SSM_RTR_MODEM_APPS"
-
-/* SSM driver structure.*/
-struct ssm_driver {
- int32_t app_status;
- int32_t update_status;
- unsigned char *channel_name;
- unsigned char *smd_buffer;
- struct device *dev;
- smd_channel_t *ch;
- struct work_struct ipc_work;
- struct mutex mutex;
- struct qseecom_handle *qseecom_handle;
- struct tzapp_get_mode_info_rsp *resp;
- bool key_status;
- bool ready;
-};
-
-static struct ssm_driver *ssm_drv;
-
-static unsigned int getint(char *buff, unsigned long *res)
-{
- char value[SSM_MSG_FIELD_LEN];
-
- memcpy(value, buff, SSM_MSG_FIELD_LEN);
- value[SSM_MSG_FIELD_LEN - 1] = '\0';
-
- return kstrtoul(skip_spaces(value), 10, res);
-}
-
-/*
- * Setup CMD/RSP pointers.
- */
-static void setup_cmd_rsp_buffers(struct qseecom_handle *handle, void **cmd,
- int *cmd_len, void **resp, int *resp_len)
-{
- *cmd = handle->sbuf;
- if (*cmd_len & QSEECOM_ALIGN_MASK)
- *cmd_len = QSEECOM_ALIGN(*cmd_len);
-
- *resp = handle->sbuf + *cmd_len;
- if (*resp_len & QSEECOM_ALIGN_MASK)
- *resp_len = QSEECOM_ALIGN(*resp_len);
-}
-
-/*
- * Send packet to modem over SMD channel.
- */
-static int update_modem(enum ssm_ipc_req ipc_req, struct ssm_driver *ssm,
- int length, char *data)
-{
- unsigned int packet_len = length + SSM_MSG_FIELD_LEN;
- int rc = 0, count;
-
- snprintf(ssm->smd_buffer, SSM_MSG_FIELD_LEN + 1, "%10u|", ipc_req);
- memcpy(ssm->smd_buffer + SSM_MSG_FIELD_LEN, data, length);
-
- if (smd_write_avail(ssm->ch) < packet_len) {
- dev_err(ssm->dev, "Not enough space dropping request\n");
- rc = -ENOSPC;
- goto out;
- }
-
- count = smd_write(ssm->ch, ssm->smd_buffer, packet_len);
- if (count < packet_len) {
- dev_err(ssm->dev, "smd_write failed for %d\n", ipc_req);
- rc = -EIO;
- }
-
-out:
- return rc;
-}
-
-/*
- * Header Format
- * Each member of header is of 10 byte (ASCII).
- * Each entry is separated by '|' delimiter.
- * |<-10 bytes->|<-10 bytes->|
- * |-------------------------|
- * | IPC code | error code |
- * |-------------------------|
- *
- */
-static int decode_packet(char *buffer, struct ssm_common_msg *pkt)
-{
- int rc;
-
- rc = getint(buffer, (unsigned long *)&pkt->ipc_req);
- if (rc < 0)
- return -EINVAL;
-
- buffer += SSM_MSG_FIELD_LEN;
- rc = getint(buffer, (unsigned long *)&pkt->err_code);
- if (rc < 0)
- return -EINVAL;
-
- dev_dbg(ssm_drv->dev, "req %d error code %d\n",
- pkt->ipc_req, pkt->err_code);
- return 0;
-}
-
-static void process_message(struct ssm_common_msg pkt, struct ssm_driver *ssm)
-{
-
- switch (pkt.ipc_req) {
-
- case SSM_MTOA_MODE_UPDATE_STATUS:
- if (pkt.err_code) {
- dev_err(ssm->dev, "Modem mode update failed\n");
- ssm->update_status = FAILED;
- } else
- ssm->update_status = SUCCESS;
-
- dev_dbg(ssm->dev, "Modem mode update status %d\n",
- pkt.err_code);
- break;
-
- default:
- dev_dbg(ssm->dev, "Invalid message\n");
- break;
- };
-}
-
-/*
- * Work function to handle and process packets coming from modem.
- */
-static void ssm_app_modem_work_fn(struct work_struct *work)
-{
- int sz, rc;
- struct ssm_common_msg pkt;
- struct ssm_driver *ssm;
-
- ssm = container_of(work, struct ssm_driver, ipc_work);
-
- mutex_lock(&ssm->mutex);
- sz = smd_cur_packet_size(ssm->ch);
- if ((sz < SSM_MSG_FIELD_LEN) || (sz > ATOM_MSG_LEN)) {
- dev_dbg(ssm_drv->dev, "Garbled message size\n");
- goto unlock;
- }
-
- if (smd_read_avail(ssm->ch) < sz) {
- dev_err(ssm_drv->dev, "SMD error data in channel\n");
- goto unlock;
- }
-
- if (smd_read(ssm->ch, ssm->smd_buffer, sz) != sz) {
- dev_err(ssm_drv->dev, "Incomplete data\n");
- goto unlock;
- }
-
- rc = decode_packet(ssm->smd_buffer, &pkt);
- if (rc < 0) {
- dev_err(ssm_drv->dev, "Corrupted header\n");
- goto unlock;
- }
-
- process_message(pkt, ssm);
-
-unlock:
- mutex_unlock(&ssm->mutex);
-}
-
-/*
- * MODEM-APPS smd channel callback function.
- */
-static void modem_request(void *ctxt, unsigned event)
-{
- struct ssm_driver *ssm;
-
- ssm = (struct ssm_driver *)ctxt;
-
- switch (event) {
- case SMD_EVENT_OPEN:
- case SMD_EVENT_CLOSE:
- dev_dbg(ssm->dev, "SMD port status changed\n");
- break;
- case SMD_EVENT_DATA:
- if (smd_read_avail(ssm->ch) > 0)
- schedule_work(&ssm->ipc_work);
- break;
- };
-}
-
-/*
- * Load SSM application in TZ and start application:
- */
-static int ssm_load_app(struct ssm_driver *ssm)
-{
- int rc;
-
- /* Load the APP */
- rc = qseecom_start_app(&ssm->qseecom_handle, TZAPP_NAME, SZ_4K);
- if (rc < 0) {
- dev_err(ssm->dev, "Unable to load SSM app\n");
- ssm->app_status = FAILED;
- return -EIO;
- }
-
- ssm->app_status = SUCCESS;
- return 0;
-}
-
-static struct ssm_platform_data *populate_ssm_pdata(struct device *dev)
-{
- struct ssm_platform_data *pdata;
-
- pdata = devm_kzalloc(dev, sizeof(struct ssm_platform_data),
- GFP_KERNEL);
- if (!pdata)
- return NULL;
-
- pdata->need_key_exchg =
- of_property_read_bool(dev->of_node, "qcom,need-keyexhg");
-
- pdata->channel_name = CHANNEL_NAME;
-
- return pdata;
-}
-
-static int ssm_probe(struct platform_device *pdev)
-{
- int rc;
- struct ssm_platform_data *pdata;
- struct ssm_driver *drv;
-
- if (pdev->dev.of_node)
- pdata = populate_ssm_pdata(&pdev->dev);
- else
- pdata = pdev->dev.platform_data;
-
- if (!pdata) {
- dev_err(&pdev->dev, "Empty platform data\n");
- return -ENOMEM;
- }
-
- drv = devm_kzalloc(&pdev->dev, sizeof(struct ssm_driver),
- GFP_KERNEL);
- if (!drv)
- return -ENOMEM;
-
- /* Allocate response buffer */
- drv->resp = devm_kzalloc(&pdev->dev,
- sizeof(struct tzapp_get_mode_info_rsp),
- GFP_KERNEL);
- if (!drv->resp) {
- devm_kfree(&pdev->dev, drv);
- rc = -ENOMEM;
- goto exit;
- }
-
- /* Initialize the driver structure */
- drv->app_status = RETRY;
- drv->ready = false;
- drv->update_status = FAILED;
- mutex_init(&drv->mutex);
- drv->key_status = !pdata->need_key_exchg;
- drv->channel_name = (char *)pdata->channel_name;
- INIT_WORK(&drv->ipc_work, ssm_app_modem_work_fn);
-
- /* Allocate memory for smd buffer */
- drv->smd_buffer = devm_kzalloc(&pdev->dev,
- (sizeof(char) * ATOM_MSG_LEN), GFP_KERNEL);
- if (!drv->smd_buffer) {
- devm_kfree(&pdev->dev, drv->resp);
- devm_kfree(&pdev->dev, drv);
- rc = -ENOMEM;
- goto exit;
- }
-
- drv->dev = &pdev->dev;
- ssm_drv = drv;
- platform_set_drvdata(pdev, ssm_drv);
-
- dev_dbg(&pdev->dev, "probe success\n");
- return 0;
-
-exit:
- mutex_destroy(&drv->mutex);
- platform_set_drvdata(pdev, NULL);
- return rc;
-
-}
-
-static int ssm_remove(struct platform_device *pdev)
-{
-
- if (!ssm_drv)
- return 0;
- /*
- * Step to exit
- * 1. set ready to 0 (oem access closed).
- * 2. Close SMD modem connection closed.
- * 3. cleanup ion.
- */
- ssm_drv->ready = false;
- smd_close(ssm_drv->ch);
- flush_work(&ssm_drv->ipc_work);
-
- /* Shutdown tzapp */
- dev_dbg(&pdev->dev, "Shutting down TZapp\n");
- qseecom_shutdown_app(&ssm_drv->qseecom_handle);
-
- /* freeing the memory allocations
- for the driver and the buffer */
- devm_kfree(&pdev->dev, ssm_drv->smd_buffer);
- devm_kfree(&pdev->dev, ssm_drv->resp);
- devm_kfree(&pdev->dev, ssm_drv);
-
- return 0;
-}
-
-static struct of_device_id ssm_match_table[] = {
- {
- .compatible = "qcom,ssm",
- },
- {}
-};
-
-static struct platform_driver ssm_pdriver = {
- .probe = ssm_probe,
- .remove = ssm_remove,
- .driver = {
- .name = SSM_DEV_NAME,
- .owner = THIS_MODULE,
- .of_match_table = ssm_match_table,
- },
-};
-module_platform_driver(ssm_pdriver);
-
-/*
- * Interface for external OEM driver.
- * This interface supports following functionalities:
- * 1. Set mode (encrypted mode and it's length is passed as parameter).
- * 2. Set mode from TZ (read encrypted mode from TZ)
- * 3. Get status of mode update.
- *
- */
-int ssm_oem_driver_intf(int cmd, char *mode, int len)
-{
- int rc, req_len, resp_len;
- struct tzapp_get_mode_info_req *get_mode_req;
- struct tzapp_get_mode_info_rsp *get_mode_resp;
-
- /* If ssm_drv is NULL, probe failed */
- if (!ssm_drv)
- return -ENODEV;
-
- mutex_lock(&ssm_drv->mutex);
-
- if (ssm_drv->app_status == RETRY) {
- /* Load TZAPP */
- rc = ssm_load_app(ssm_drv);
- if (rc) {
- rc = -ENODEV;
- goto unlock;
- }
- } else if (ssm_drv->app_status == FAILED) {
- rc = -ENODEV;
- goto unlock;
- }
-
- /* Open modem SMD interface */
- if (!ssm_drv->ready) {
- rc = smd_named_open_on_edge(ssm_drv->channel_name,
- SMD_APPS_MODEM,
- &ssm_drv->ch,
- ssm_drv,
- modem_request);
- if (rc) {
- rc = -EAGAIN;
- goto unlock;
- } else
- ssm_drv->ready = true;
- }
-
- /* Try again modem key-exchange not yet done.*/
- if (!ssm_drv->key_status) {
- rc = -EAGAIN;
- goto unlock;
- }
-
- /* Set return status to success */
- rc = 0;
-
- switch (cmd) {
- case SSM_READY:
- break;
-
- case SSM_MODE_INFO_READY:
- ssm_drv->update_status = RETRY;
- /* Fill command structure */
- req_len = sizeof(struct tzapp_get_mode_info_req);
- resp_len = sizeof(struct tzapp_get_mode_info_rsp);
- setup_cmd_rsp_buffers(ssm_drv->qseecom_handle,
- (void **)&get_mode_req, &req_len,
- (void **)&get_mode_resp, &resp_len);
- get_mode_req->tzapp_ssm_cmd = GET_ENC_MODE;
-
- rc = qseecom_set_bandwidth(ssm_drv->qseecom_handle, 1);
- if (rc) {
- ssm_drv->update_status = FAILED;
- dev_err(ssm_drv->dev, "set bandwidth failed\n");
- rc = -EIO;
- break;
- }
- rc = qseecom_send_command(ssm_drv->qseecom_handle,
- (void *)get_mode_req, req_len,
- (void *)get_mode_resp, resp_len);
- if (rc || get_mode_resp->status) {
- ssm_drv->update_status = FAILED;
- break;
- }
- rc = qseecom_set_bandwidth(ssm_drv->qseecom_handle, 0);
- if (rc) {
- ssm_drv->update_status = FAILED;
- dev_err(ssm_drv->dev, "clear bandwidth failed\n");
- rc = -EIO;
- break;
- }
-
- if (get_mode_resp->enc_mode_len > ENC_MODE_MAX_SIZE) {
- ssm_drv->update_status = FAILED;
- rc = -EINVAL;
- break;
- }
- /* Send mode_info to modem */
- rc = update_modem(SSM_ATOM_MODE_UPDATE, ssm_drv,
- get_mode_resp->enc_mode_len,
- get_mode_resp->enc_mode_info);
- if (rc)
- ssm_drv->update_status = FAILED;
- break;
-
- case SSM_SET_MODE:
- ssm_drv->update_status = RETRY;
-
- if (len > ENC_MODE_MAX_SIZE) {
- ssm_drv->update_status = FAILED;
- rc = -EINVAL;
- break;
- }
- memcpy(ssm_drv->resp->enc_mode_info, mode, len);
- ssm_drv->resp->enc_mode_len = len;
-
- /* Send mode_info to modem */
- rc = update_modem(SSM_ATOM_MODE_UPDATE, ssm_drv,
- ssm_drv->resp->enc_mode_len,
- ssm_drv->resp->enc_mode_info);
- if (rc)
- ssm_drv->update_status = FAILED;
- break;
-
- case SSM_GET_MODE_STATUS:
- rc = ssm_drv->update_status;
- break;
-
- default:
- rc = -EINVAL;
- dev_err(ssm_drv->dev, "Invalid command\n");
- break;
- };
-
-unlock:
- mutex_unlock(&ssm_drv->mutex);
- return rc;
-}
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("QTI Secure Service Module");
-
diff --git a/drivers/platform/msm/ssm.h b/drivers/platform/msm/ssm.h
deleted file mode 100644
index ee4f1bc..0000000
--- a/drivers/platform/msm/ssm.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* 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
- * 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 __SSM_H_
-#define __SSM_H_
-
-#define MAX_APP_NAME_SIZE 32
-#define ENC_MODE_MAX_SIZE 200
-
-/* tzapp response.*/
-enum tz_response {
- RESULT_SUCCESS = 0,
- RESULT_FAILURE = 0xFFFFFFFF,
-};
-
-/* tzapp command list.*/
-enum tz_commands {
- ENC_MODE,
- GET_ENC_MODE,
- KEY_EXCHANGE = 11,
-};
-
-/* MODEM/SSM command list.*/
-enum ssm_ipc_req {
- SSM_IPC_MIN = 0x0000AAAB,
- SSM_ATOM_MODE_UPDATE,
- SSM_MTOA_MODE_UPDATE_STATUS = SSM_IPC_MIN + 4,
- SSM_INVALID_REQ,
-};
-
-/* OEM request commands list.*/
-enum oem_req {
- SSM_READY,
- SSM_MODE_INFO_READY,
- SSM_SET_MODE,
- SSM_GET_MODE_STATUS,
- SSM_INVALID,
-};
-
-/* Modem mode update status.*/
-enum modem_mode_status {
- SUCCESS,
- RETRY,
- FAILED = -1,
-};
-
-/* tzapp encode mode request.*/
-__packed struct tzapp_mode_enc_req {
- uint32_t tzapp_ssm_cmd;
- uint8_t mode_info[4];
-};
-
-/* tzapp encode mode response.*/
-__packed struct tzapp_mode_enc_rsp {
- uint32_t tzapp_ssm_cmd;
- uint8_t enc_mode_info[ENC_MODE_MAX_SIZE];
- uint32_t enc_mode_len;
- uint32_t status;
-};
-
-/* tzapp get mode request.*/
-__packed struct tzapp_get_mode_info_req {
- uint32_t tzapp_ssm_cmd;
-};
-
-/* tzapp get mode response.*/
-__packed struct tzapp_get_mode_info_rsp {
- uint32_t tzapp_ssm_cmd;
- uint8_t enc_mode_info[ENC_MODE_MAX_SIZE];
- uint32_t enc_mode_len;
- uint32_t status;
-};
-
-/* Modem/SSM packet format.*/
-struct ssm_common_msg {
- enum ssm_ipc_req ipc_req;
- int err_code;
-
-};
-
-#endif
diff --git a/drivers/power/fg-core.h b/drivers/power/fg-core.h
index f99c9c0..a6f1fcf 100644
--- a/drivers/power/fg-core.h
+++ b/drivers/power/fg-core.h
@@ -257,6 +257,7 @@
bool auto_recharge_soc;
bool use_esr_sw;
bool disable_esr_pull_dn;
+ bool disable_fg_twm;
int cutoff_volt_mv;
int empty_volt_mv;
int vbatt_low_thr_mv;
@@ -405,6 +406,7 @@
struct fg_batt_props bp;
struct fg_cyc_ctr_data cyc_ctr;
struct notifier_block nb;
+ struct notifier_block twm_nb;
struct fg_cap_learning cl;
struct alarm esr_sw_timer;
struct mutex bus_lock;
@@ -448,6 +450,7 @@
bool slope_limit_en;
bool use_ima_single_mode;
bool usb_present;
+ bool twm_state;
struct completion soc_update;
struct completion soc_ready;
struct delayed_work profile_load_work;
diff --git a/drivers/power/fg-reg.h b/drivers/power/fg-reg.h
index 668aca8..a63f7a4 100644
--- a/drivers/power/fg-reg.h
+++ b/drivers/power/fg-reg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -29,6 +29,7 @@
#define BATT_SOC_STS_CLR(chip) (chip->batt_soc_base + 0x4A)
#define BATT_SOC_LOW_PWR_CFG(chip) (chip->batt_soc_base + 0x52)
#define BATT_SOC_LOW_PWR_STS(chip) (chip->batt_soc_base + 0x56)
+#define BATT_SOC_RST_CTRL0(chip) (chip->batt_soc_base + 0xBA)
/* BATT_SOC_INT_RT_STS */
#define MSOC_EMPTY_BIT BIT(5)
@@ -39,6 +40,11 @@
/* BATT_SOC_RESTART */
#define RESTART_GO_BIT BIT(0)
+/* BATT_SOC_RST_CTRL0 */
+#define BCL_RST_BIT BIT(2)
+#define MEM_RST_BIT BIT(1)
+#define ALG_RST_BIT BIT(0)
+
/* FG_BATT_INFO register definitions */
#define BATT_INFO_BATT_TEMP_STS(chip) (chip->batt_info_base + 0x06)
#define BATT_INFO_SYS_BATT(chip) (chip->batt_info_base + 0x07)
diff --git a/drivers/power/fg-util.c b/drivers/power/fg-util.c
index 16af322..2061efd2 100644
--- a/drivers/power/fg-util.c
+++ b/drivers/power/fg-util.c
@@ -432,7 +432,7 @@
reg &= ~mask;
reg |= val & mask;
- sec_access = (addr & 0x00FF) > 0xD0;
+ sec_access = (addr & 0x00FF) > 0xB8;
if (sec_access) {
rc = spmi_ext_register_writel(spmi->ctrl, spmi->sid,
(addr & 0xFF00) | 0xD0, &sec_addr_val, 1);
diff --git a/drivers/power/qpnp-fg-gen3.c b/drivers/power/qpnp-fg-gen3.c
index 5c82b12..9285727 100644
--- a/drivers/power/qpnp-fg-gen3.c
+++ b/drivers/power/qpnp-fg-gen3.c
@@ -21,6 +21,7 @@
#include <linux/of_batterydata.h>
#include <linux/iio/consumer.h>
#include <linux/qpnp/qpnp-revid.h>
+#include <linux/qpnp-misc.h>
#include "fg-core.h"
#include "fg-reg.h"
@@ -3621,6 +3622,22 @@
return NOTIFY_OK;
}
+static int twm_notifier_cb(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct fg_chip *chip = container_of(nb, struct fg_chip, twm_nb);
+
+ if (action != PMIC_TWM_CLEAR &&
+ action != PMIC_TWM_ENABLE) {
+ pr_debug("Unsupported option %lu\n", action);
+ return NOTIFY_OK;
+ }
+
+ chip->twm_state = (u8)action;
+
+ return NOTIFY_OK;
+}
+
static enum power_supply_property fg_psy_props[] = {
POWER_SUPPLY_PROP_CAPACITY,
POWER_SUPPLY_PROP_TEMP,
@@ -5012,6 +5029,9 @@
chip->dt.disable_esr_pull_dn = of_property_read_bool(node,
"qcom,fg-disable-esr-pull-dn");
+ chip->dt.disable_fg_twm = of_property_read_bool(node,
+ "qcom,fg-disable-in-twm");
+
return 0;
}
@@ -5190,6 +5210,11 @@
goto exit;
}
+ chip->twm_nb.notifier_call = twm_notifier_cb;
+ rc = qpnp_misc_twm_notifier_register(&chip->twm_nb);
+ if (rc < 0)
+ pr_err("Failed to register twm_notifier_cb rc=%d\n", rc);
+
rc = fg_register_interrupts(chip);
if (rc < 0) {
dev_err(chip->dev, "Error in registering interrupts, rc:%d\n",
@@ -5290,17 +5315,11 @@
return 0;
}
-static int __init get_board_id(char *buf)
-{
- device_board_id = 0;
- device_board_id = simple_strtol(buf, NULL, 10);
- return 0;
-}
-
static void fg_gen3_shutdown(struct spmi_device *spmi)
{
struct fg_chip *chip = dev_get_drvdata(&spmi->dev);
int rc;
+ u8 mask;
rc = fg_set_esr_timer(chip, chip->dt.esr_timer_shutdown[TIMER_RETRY],
chip->dt.esr_timer_shutdown[TIMER_MAX], false,
@@ -5308,11 +5327,22 @@
if (rc < 0)
pr_err("Error in setting ESR timer at shutdown, rc=%d\n", rc);
+ if (chip->twm_state == PMIC_TWM_ENABLE && chip->dt.disable_fg_twm) {
+ rc = fg_masked_write(chip, BATT_SOC_EN_CTL(chip),
+ FG_ALGORITHM_EN_BIT, 0);
+ if (rc < 0)
+ pr_err("Error in disabling FG rc=%d\n", rc);
+
+ mask = BCL_RST_BIT | MEM_RST_BIT | ALG_RST_BIT;
+ rc = fg_masked_write(chip, BATT_SOC_RST_CTRL0(chip),
+ mask, mask);
+ if (rc < 0)
+ pr_err("Error in disabling FG resets rc=%d\n", rc);
+ }
+
fg_cleanup(chip);
}
-early_param("BuildPhase", get_board_id);
-
static const struct of_device_id fg_gen3_match_table[] = {
{.compatible = FG_GEN3_DEV_NAME},
{},
diff --git a/drivers/power/qpnp-smb2.c b/drivers/power/qpnp-smb2.c
index 33f6667..df62b2d 100644
--- a/drivers/power/qpnp-smb2.c
+++ b/drivers/power/qpnp-smb2.c
@@ -567,6 +567,8 @@
POWER_SUPPLY_PROP_RERUN_AICL,
POWER_SUPPLY_PROP_DP_DM,
POWER_SUPPLY_PROP_CHARGE_COUNTER,
+ POWER_SUPPLY_PROP_CHARGE_FULL,
+ POWER_SUPPLY_PROP_CYCLE_COUNT,
};
static int smb2_batt_get_prop(struct power_supply *psy,
@@ -616,9 +618,6 @@
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED:
rc = smblib_get_prop_input_current_limited(chg, val);
break;
- case POWER_SUPPLY_PROP_VOLTAGE_NOW:
- rc = smblib_get_prop_batt_voltage_now(chg, val);
- break;
case POWER_SUPPLY_PROP_VOLTAGE_MAX:
val->intval = get_client_vote(chg->fv_votable,
BATT_PROFILE_VOTER);
@@ -630,9 +629,6 @@
val->intval = get_client_vote_locked(chg->fv_votable,
QNOVO_VOTER);
break;
- case POWER_SUPPLY_PROP_CURRENT_NOW:
- rc = smblib_get_prop_batt_current_now(chg, val);
- break;
case POWER_SUPPLY_PROP_CURRENT_QNOVO:
val->intval = get_client_vote_locked(chg->fcc_votable,
QNOVO_VOTER);
@@ -645,9 +641,6 @@
val->intval = get_client_vote(chg->fcc_votable,
FG_ESR_VOTER);
break;
- case POWER_SUPPLY_PROP_TEMP:
- rc = smblib_get_prop_batt_temp(chg, val);
- break;
case POWER_SUPPLY_PROP_TECHNOLOGY:
val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
break;
@@ -672,7 +665,12 @@
val->intval = 0;
break;
case POWER_SUPPLY_PROP_CHARGE_COUNTER:
- rc = smblib_get_prop_batt_charge_counter(chg, val);
+ case POWER_SUPPLY_PROP_CHARGE_FULL:
+ case POWER_SUPPLY_PROP_CYCLE_COUNT:
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ case POWER_SUPPLY_PROP_CURRENT_NOW:
+ case POWER_SUPPLY_PROP_TEMP:
+ rc = smblib_get_prop_from_bms(chg, psp, val);
break;
default:
pr_err("batt power supply prop %d not supported\n", psp);
diff --git a/drivers/power/smb-lib.c b/drivers/power/smb-lib.c
index 44946ec..a476701 100644
--- a/drivers/power/smb-lib.c
+++ b/drivers/power/smb-lib.c
@@ -1729,7 +1729,8 @@
stat);
if (stat & CHARGER_ERROR_STATUS_BAT_OV_BIT) {
- rc = smblib_get_prop_batt_voltage_now(chg, &pval);
+ rc = smblib_get_prop_from_bms(chg,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW, &pval);
if (!rc) {
/*
* If Vbatt is within 40mV above Vfloat, then don't
@@ -1787,45 +1788,6 @@
return 0;
}
-int smblib_get_prop_batt_voltage_now(struct smb_charger *chg,
- union power_supply_propval *val)
-{
- int rc;
-
- if (!chg->bms_psy)
- return -EINVAL;
-
- rc = power_supply_get_property(chg->bms_psy,
- POWER_SUPPLY_PROP_VOLTAGE_NOW, val);
- return rc;
-}
-
-int smblib_get_prop_batt_current_now(struct smb_charger *chg,
- union power_supply_propval *val)
-{
- int rc;
-
- if (!chg->bms_psy)
- return -EINVAL;
-
- rc = power_supply_get_property(chg->bms_psy,
- POWER_SUPPLY_PROP_CURRENT_NOW, val);
- return rc;
-}
-
-int smblib_get_prop_batt_temp(struct smb_charger *chg,
- union power_supply_propval *val)
-{
- int rc;
-
- if (!chg->bms_psy)
- return -EINVAL;
-
- rc = power_supply_get_property(chg->bms_psy,
- POWER_SUPPLY_PROP_TEMP, val);
- return rc;
-}
-
int smblib_get_prop_batt_charge_done(struct smb_charger *chg,
union power_supply_propval *val)
{
@@ -1861,16 +1823,17 @@
return 0;
}
-int smblib_get_prop_batt_charge_counter(struct smb_charger *chg,
- union power_supply_propval *val)
+int smblib_get_prop_from_bms(struct smb_charger *chg,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
{
int rc;
if (!chg->bms_psy)
return -EINVAL;
- rc = power_supply_get_property(chg->bms_psy,
- POWER_SUPPLY_PROP_CHARGE_COUNTER, val);
+ rc = power_supply_get_property(chg->bms_psy, psp, val);
+
return rc;
}
diff --git a/drivers/power/smb-lib.h b/drivers/power/smb-lib.h
index c623371..11cbea6 100644
--- a/drivers/power/smb-lib.h
+++ b/drivers/power/smb-lib.h
@@ -404,14 +404,6 @@
union power_supply_propval *val);
int smblib_get_prop_input_current_limited(struct smb_charger *chg,
union power_supply_propval *val);
-int smblib_get_prop_batt_voltage_now(struct smb_charger *chg,
- union power_supply_propval *val);
-int smblib_get_prop_batt_current_now(struct smb_charger *chg,
- union power_supply_propval *val);
-int smblib_get_prop_batt_temp(struct smb_charger *chg,
- union power_supply_propval *val);
-int smblib_get_prop_batt_charge_counter(struct smb_charger *chg,
- union power_supply_propval *val);
int smblib_set_prop_input_suspend(struct smb_charger *chg,
const union power_supply_propval *val);
int smblib_set_prop_batt_capacity(struct smb_charger *chg,
@@ -500,6 +492,9 @@
int smblib_get_charge_current(struct smb_charger *chg, int *total_current_ua);
int smblib_get_prop_pr_swap_in_progress(struct smb_charger *chg,
union power_supply_propval *val);
+int smblib_get_prop_from_bms(struct smb_charger *chg,
+ enum power_supply_property psp,
+ union power_supply_propval *val);
int smblib_set_prop_pr_swap_in_progress(struct smb_charger *chg,
const union power_supply_propval *val);
diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
index 5a1d4af..87621db 100644
--- a/drivers/regulator/of_regulator.c
+++ b/drivers/regulator/of_regulator.c
@@ -181,6 +181,7 @@
dev_err(dev,
"failed to parse DT for regulator %s\n",
child->name);
+ of_node_put(child);
return -EINVAL;
}
match->of_node = of_node_get(child);
diff --git a/drivers/rtc/rtc-tx4939.c b/drivers/rtc/rtc-tx4939.c
index 2e678c6..5d91852a 100644
--- a/drivers/rtc/rtc-tx4939.c
+++ b/drivers/rtc/rtc-tx4939.c
@@ -86,7 +86,8 @@
for (i = 2; i < 6; i++)
buf[i] = __raw_readl(&rtcreg->dat);
spin_unlock_irq(&pdata->lock);
- sec = (buf[5] << 24) | (buf[4] << 16) | (buf[3] << 8) | buf[2];
+ sec = ((unsigned long)buf[5] << 24) | (buf[4] << 16) |
+ (buf[3] << 8) | buf[2];
rtc_time_to_tm(sec, tm);
return rtc_valid_tm(tm);
}
@@ -147,7 +148,8 @@
alrm->enabled = (ctl & TX4939_RTCCTL_ALME) ? 1 : 0;
alrm->pending = (ctl & TX4939_RTCCTL_ALMD) ? 1 : 0;
spin_unlock_irq(&pdata->lock);
- sec = (buf[5] << 24) | (buf[4] << 16) | (buf[3] << 8) | buf[2];
+ sec = ((unsigned long)buf[5] << 24) | (buf[4] << 16) |
+ (buf[3] << 8) | buf[2];
rtc_time_to_tm(sec, &alrm->time);
return rtc_valid_tm(&alrm->time);
}
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index 83da53c8..8febd61 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -784,6 +784,7 @@
ccw_device_set_timeout(cdev, 0);
cdev->private->iretry = 255;
+ cdev->private->async_kill_io_rc = -ETIMEDOUT;
ret = ccw_device_cancel_halt_clear(cdev);
if (ret == -EBUSY) {
ccw_device_set_timeout(cdev, 3*HZ);
@@ -860,7 +861,7 @@
/* OK, i/o is dead now. Call interrupt handler. */
if (cdev->handler)
cdev->handler(cdev, cdev->private->intparm,
- ERR_PTR(-EIO));
+ ERR_PTR(cdev->private->async_kill_io_rc));
}
static void
@@ -877,14 +878,16 @@
ccw_device_online_verify(cdev, 0);
if (cdev->handler)
cdev->handler(cdev, cdev->private->intparm,
- ERR_PTR(-EIO));
+ ERR_PTR(cdev->private->async_kill_io_rc));
}
void ccw_device_kill_io(struct ccw_device *cdev)
{
int ret;
+ ccw_device_set_timeout(cdev, 0);
cdev->private->iretry = 255;
+ cdev->private->async_kill_io_rc = -EIO;
ret = ccw_device_cancel_halt_clear(cdev);
if (ret == -EBUSY) {
ccw_device_set_timeout(cdev, 3*HZ);
diff --git a/drivers/s390/cio/io_sch.h b/drivers/s390/cio/io_sch.h
index b108f4a..b142c7a 100644
--- a/drivers/s390/cio/io_sch.h
+++ b/drivers/s390/cio/io_sch.h
@@ -155,6 +155,7 @@
unsigned long intparm; /* user interruption parameter */
struct qdio_irq *qdio_data;
struct irb irb; /* device status */
+ int async_kill_io_rc;
struct senseid senseid; /* SenseID info */
struct pgid pgid[8]; /* path group IDs per chpid*/
struct ccw1 iccws[2]; /* ccws for SNID/SID/SPGID commands */
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c
index d8f990b..333dcb7 100644
--- a/drivers/s390/net/smsgiucv.c
+++ b/drivers/s390/net/smsgiucv.c
@@ -190,7 +190,7 @@
static void __exit smsg_exit(void)
{
- cpcmd("SET SMSG IUCV", NULL, 0, NULL);
+ cpcmd("SET SMSG OFF", NULL, 0, NULL);
device_unregister(smsg_dev);
iucv_unregister(&smsg_handler, 1);
driver_unregister(&smsg_driver);
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index ce177a5..e51fc39 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -1270,9 +1270,10 @@
host = aac->scsi_host_ptr;
scsi_block_requests(host);
aac_adapter_disable_int(aac);
- if (aac->thread->pid != current->pid) {
+ if (aac->thread && aac->thread->pid != current->pid) {
spin_unlock_irq(host->host_lock);
kthread_stop(aac->thread);
+ aac->thread = NULL;
jafo = 1;
}
@@ -1343,6 +1344,7 @@
aac->name);
if (IS_ERR(aac->thread)) {
retval = PTR_ERR(aac->thread);
+ aac->thread = NULL;
goto out;
}
}
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index a759cb2d..3902bf0 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -1096,6 +1096,7 @@
up(&fib->event_wait);
}
kthread_stop(aac->thread);
+ aac->thread = NULL;
}
aac_send_shutdown(aac);
aac_adapter_disable_int(aac);
@@ -1172,8 +1173,10 @@
* Map in the registers from the adapter.
*/
aac->base_size = AAC_MIN_FOOTPRINT_SIZE;
- if ((*aac_drivers[index].init)(aac))
+ if ((*aac_drivers[index].init)(aac)) {
+ error = -ENODEV;
goto out_unmap;
+ }
if (aac->sync_mode) {
if (aac_sync_mode)
diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c
index 71cfb1e..80aa67d 100644
--- a/drivers/scsi/arm/fas216.c
+++ b/drivers/scsi/arm/fas216.c
@@ -2010,7 +2010,7 @@
* have valid data in the sense buffer that could
* confuse the higher levels.
*/
- memset(SCpnt->sense_buffer, 0, sizeof(SCpnt->sense_buffer));
+ memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
//printk("scsi%d.%c: sense buffer: ", info->host->host_no, '0' + SCpnt->device->id);
//{ int i; for (i = 0; i < 32; i++) printk("%02x ", SCpnt->sense_buffer[i]); printk("\n"); }
/*
diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c
index 5b99844..82adbf5 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_io.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_io.c
@@ -1932,6 +1932,7 @@
/* we will not receive ABTS response for this IO */
BNX2FC_IO_DBG(io_req, "Timer context finished processing "
"this scsi cmd\n");
+ return;
}
/* Cancel the timeout_work, as we received IO completion */
diff --git a/drivers/scsi/isci/port_config.c b/drivers/scsi/isci/port_config.c
index ac87974..18a409b 100644
--- a/drivers/scsi/isci/port_config.c
+++ b/drivers/scsi/isci/port_config.c
@@ -291,7 +291,7 @@
* Note: We have not moved the current phy_index so we will actually
* compare the startting phy with itself.
* This is expected and required to add the phy to the port. */
- while (phy_index < SCI_MAX_PHYS) {
+ for (; phy_index < SCI_MAX_PHYS; phy_index++) {
if ((phy_mask & (1 << phy_index)) == 0)
continue;
sci_phy_get_sas_address(&ihost->phys[phy_index],
@@ -311,7 +311,6 @@
&ihost->phys[phy_index]);
assigned_phy_mask |= (1 << phy_index);
- phy_index++;
}
}
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index 24e477d..7e3e0fe 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -250,6 +250,7 @@
static void sas_eh_finish_cmd(struct scsi_cmnd *cmd)
{
struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(cmd->device->host);
+ struct domain_device *dev = cmd_to_domain_dev(cmd);
struct sas_task *task = TO_SAS_TASK(cmd);
/* At this point, we only get called following an actual abort
@@ -258,6 +259,14 @@
*/
sas_end_task(cmd, task);
+ if (dev_is_sata(dev)) {
+ /* defer commands to libata so that libata EH can
+ * handle ata qcs correctly
+ */
+ list_move_tail(&cmd->eh_entry, &sas_ha->eh_ata_q);
+ return;
+ }
+
/* now finish the command and move it on to the error
* handler done list, this also takes it off the
* error handler pending list.
@@ -265,22 +274,6 @@
scsi_eh_finish_cmd(cmd, &sas_ha->eh_done_q);
}
-static void sas_eh_defer_cmd(struct scsi_cmnd *cmd)
-{
- struct domain_device *dev = cmd_to_domain_dev(cmd);
- struct sas_ha_struct *ha = dev->port->ha;
- struct sas_task *task = TO_SAS_TASK(cmd);
-
- if (!dev_is_sata(dev)) {
- sas_eh_finish_cmd(cmd);
- return;
- }
-
- /* report the timeout to libata */
- sas_end_task(cmd, task);
- list_move_tail(&cmd->eh_entry, &ha->eh_ata_q);
-}
-
static void sas_scsi_clear_queue_lu(struct list_head *error_q, struct scsi_cmnd *my_cmd)
{
struct scsi_cmnd *cmd, *n;
@@ -288,7 +281,7 @@
list_for_each_entry_safe(cmd, n, error_q, eh_entry) {
if (cmd->device->sdev_target == my_cmd->device->sdev_target &&
cmd->device->lun == my_cmd->device->lun)
- sas_eh_defer_cmd(cmd);
+ sas_eh_finish_cmd(cmd);
}
}
@@ -678,12 +671,12 @@
case TASK_IS_DONE:
SAS_DPRINTK("%s: task 0x%p is done\n", __func__,
task);
- sas_eh_defer_cmd(cmd);
+ sas_eh_finish_cmd(cmd);
continue;
case TASK_IS_ABORTED:
SAS_DPRINTK("%s: task 0x%p is aborted\n",
__func__, task);
- sas_eh_defer_cmd(cmd);
+ sas_eh_finish_cmd(cmd);
continue;
case TASK_IS_AT_LU:
SAS_DPRINTK("task 0x%p is at LU: lu recover\n", task);
@@ -694,7 +687,7 @@
"recovered\n",
SAS_ADDR(task->dev),
cmd->device->lun);
- sas_eh_defer_cmd(cmd);
+ sas_eh_finish_cmd(cmd);
sas_scsi_clear_queue_lu(work_q, cmd);
goto Again;
}
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index a53dc1c..aa347c3 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -629,7 +629,12 @@
LPFC_MBOXQ_t *pmboxq;
int mbxstatus = MBXERR_ERROR;
+ /*
+ * If the link is offline, disabled or BLOCK_MGMT_IO
+ * it doesn't make any sense to allow issue_lip
+ */
if ((vport->fc_flag & FC_OFFLINE_MODE) ||
+ (phba->hba_flag & LINK_DISABLED) ||
(phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO))
return -EPERM;
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 908b2a4f..efb100a 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -716,8 +716,9 @@
(phba->hba_flag & HBA_SP_QUEUE_EVT)) {
if (pring->flag & LPFC_STOP_IOCB_EVENT) {
pring->flag |= LPFC_DEFERRED_RING_EVENT;
- /* Set the lpfc data pending flag */
- set_bit(LPFC_DATA_READY, &phba->data_flags);
+ /* Preserve legacy behavior. */
+ if (!(phba->hba_flag & HBA_SP_QUEUE_EVT))
+ set_bit(LPFC_DATA_READY, &phba->data_flags);
} else {
if (phba->link_state >= LPFC_LINK_UP) {
pring->flag &= ~LPFC_DEFERRED_RING_EVENT;
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index c3cdb9f..cdade58 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -115,6 +115,8 @@
/* set consumption flag every once in a while */
if (!((q->host_index + 1) % q->entry_repost))
bf_set(wqe_wqec, &wqe->generic.wqe_com, 1);
+ else
+ bf_set(wqe_wqec, &wqe->generic.wqe_com, 0);
if (q->phba->sli3_options & LPFC_SLI4_PHWQ_ENABLED)
bf_set(wqe_wqid, &wqe->generic.wqe_com, q->queue_id);
lpfc_sli_pcimem_bcopy(wqe, temp_wqe, q->entry_size);
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index b2bd602..99bdccf 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -3212,7 +3212,8 @@
return;
if (fcport->fp_speed == PORT_SPEED_UNKNOWN ||
- fcport->fp_speed > ha->link_data_rate)
+ fcport->fp_speed > ha->link_data_rate ||
+ !ha->flags.gpsc_supported)
return;
rval = qla2x00_set_idma_speed(vha, fcport->loop_id, fcport->fp_speed,
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index e191177..3f613ef 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -268,7 +268,8 @@
struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
/* Read all mbox registers? */
- mboxes = (1 << ha->mbx_count) - 1;
+ WARN_ON_ONCE(ha->mbx_count > 32);
+ mboxes = (1ULL << ha->mbx_count) - 1;
if (!ha->mcp)
ql_dbg(ql_dbg_async, vha, 0x5001, "MBX pointer ERROR.\n");
else
@@ -2454,7 +2455,8 @@
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
/* Read all mbox registers? */
- mboxes = (1 << ha->mbx_count) - 1;
+ WARN_ON_ONCE(ha->mbx_count > 32);
+ mboxes = (1ULL << ha->mbx_count) - 1;
if (!ha->mcp)
ql_dbg(ql_dbg_async, vha, 0x504e, "MBX pointer ERROR.\n");
else
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
index 8f6d0fb..f3c7c5b 100644
--- a/drivers/scsi/qla4xxx/ql4_def.h
+++ b/drivers/scsi/qla4xxx/ql4_def.h
@@ -167,6 +167,8 @@
#define DEV_DB_NON_PERSISTENT 0
#define DEV_DB_PERSISTENT 1
+#define QL4_ISP_REG_DISCONNECT 0xffffffffU
+
#define COPY_ISID(dst_isid, src_isid) { \
int i, j; \
for (i = 0, j = ISID_SIZE - 1; i < ISID_SIZE;) \
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 199fcf7..d0cad6f 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -268,6 +268,24 @@
static struct scsi_transport_template *qla4xxx_scsi_transport;
+static int qla4xxx_isp_check_reg(struct scsi_qla_host *ha)
+{
+ u32 reg_val = 0;
+ int rval = QLA_SUCCESS;
+
+ if (is_qla8022(ha))
+ reg_val = readl(&ha->qla4_82xx_reg->host_status);
+ else if (is_qla8032(ha) || is_qla8042(ha))
+ reg_val = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_ALIVE_COUNTER);
+ else
+ reg_val = readw(&ha->reg->ctrl_status);
+
+ if (reg_val == QL4_ISP_REG_DISCONNECT)
+ rval = QLA_ERROR;
+
+ return rval;
+}
+
static int qla4xxx_send_ping(struct Scsi_Host *shost, uint32_t iface_num,
uint32_t iface_type, uint32_t payload_size,
uint32_t pid, struct sockaddr *dst_addr)
@@ -9230,10 +9248,17 @@
struct srb *srb = NULL;
int ret = SUCCESS;
int wait = 0;
+ int rval;
ql4_printk(KERN_INFO, ha, "scsi%ld:%d:%llu: Abort command issued cmd=%p, cdb=0x%x\n",
ha->host_no, id, lun, cmd, cmd->cmnd[0]);
+ rval = qla4xxx_isp_check_reg(ha);
+ if (rval != QLA_SUCCESS) {
+ ql4_printk(KERN_INFO, ha, "PCI/Register disconnect, exiting.\n");
+ return FAILED;
+ }
+
spin_lock_irqsave(&ha->hardware_lock, flags);
srb = (struct srb *) CMD_SP(cmd);
if (!srb) {
@@ -9285,6 +9310,7 @@
struct scsi_qla_host *ha = to_qla_host(cmd->device->host);
struct ddb_entry *ddb_entry = cmd->device->hostdata;
int ret = FAILED, stat;
+ int rval;
if (!ddb_entry)
return ret;
@@ -9304,6 +9330,12 @@
cmd, jiffies, cmd->request->timeout / HZ,
ha->dpc_flags, cmd->result, cmd->allowed));
+ rval = qla4xxx_isp_check_reg(ha);
+ if (rval != QLA_SUCCESS) {
+ ql4_printk(KERN_INFO, ha, "PCI/Register disconnect, exiting.\n");
+ return FAILED;
+ }
+
/* FIXME: wait for hba to go online */
stat = qla4xxx_reset_lun(ha, ddb_entry, cmd->device->lun);
if (stat != QLA_SUCCESS) {
@@ -9347,6 +9379,7 @@
struct scsi_qla_host *ha = to_qla_host(cmd->device->host);
struct ddb_entry *ddb_entry = cmd->device->hostdata;
int stat, ret;
+ int rval;
if (!ddb_entry)
return FAILED;
@@ -9364,6 +9397,12 @@
ha->host_no, cmd, jiffies, cmd->request->timeout / HZ,
ha->dpc_flags, cmd->result, cmd->allowed));
+ rval = qla4xxx_isp_check_reg(ha);
+ if (rval != QLA_SUCCESS) {
+ ql4_printk(KERN_INFO, ha, "PCI/Register disconnect, exiting.\n");
+ return FAILED;
+ }
+
stat = qla4xxx_reset_target(ha, ddb_entry);
if (stat != QLA_SUCCESS) {
starget_printk(KERN_INFO, scsi_target(cmd->device),
@@ -9418,9 +9457,16 @@
{
int return_status = FAILED;
struct scsi_qla_host *ha;
+ int rval;
ha = to_qla_host(cmd->device->host);
+ rval = qla4xxx_isp_check_reg(ha);
+ if (rval != QLA_SUCCESS) {
+ ql4_printk(KERN_INFO, ha, "PCI/Register disconnect, exiting.\n");
+ return FAILED;
+ }
+
if ((is_qla8032(ha) || is_qla8042(ha)) && ql4xdontresethba)
qla4_83xx_set_idc_dontreset(ha);
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index b5a653a..c36c65c 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2343,6 +2343,12 @@
return nlmsg_multicast(nls, skb, 0, group, gfp);
}
+static int
+iscsi_unicast_skb(struct sk_buff *skb, u32 portid)
+{
+ return nlmsg_unicast(nls, skb, portid);
+}
+
int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
char *data, uint32_t data_size)
{
@@ -2545,14 +2551,11 @@
EXPORT_SYMBOL_GPL(iscsi_ping_comp_event);
static int
-iscsi_if_send_reply(uint32_t group, int seq, int type, int done, int multi,
- void *payload, int size)
+iscsi_if_send_reply(u32 portid, int type, void *payload, int size)
{
struct sk_buff *skb;
struct nlmsghdr *nlh;
int len = nlmsg_total_size(size);
- int flags = multi ? NLM_F_MULTI : 0;
- int t = done ? NLMSG_DONE : type;
skb = alloc_skb(len, GFP_ATOMIC);
if (!skb) {
@@ -2560,10 +2563,9 @@
return -ENOMEM;
}
- nlh = __nlmsg_put(skb, 0, 0, t, (len - sizeof(*nlh)), 0);
- nlh->nlmsg_flags = flags;
+ nlh = __nlmsg_put(skb, 0, 0, type, (len - sizeof(*nlh)), 0);
memcpy(nlmsg_data(nlh), payload, size);
- return iscsi_multicast_skb(skb, group, GFP_ATOMIC);
+ return iscsi_unicast_skb(skb, portid);
}
static int
@@ -3490,6 +3492,7 @@
iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
{
int err = 0;
+ u32 portid;
struct iscsi_uevent *ev = nlmsg_data(nlh);
struct iscsi_transport *transport = NULL;
struct iscsi_internal *priv;
@@ -3510,10 +3513,12 @@
if (!try_module_get(transport->owner))
return -EINVAL;
+ portid = NETLINK_CB(skb).portid;
+
switch (nlh->nlmsg_type) {
case ISCSI_UEVENT_CREATE_SESSION:
err = iscsi_if_create_session(priv, ep, ev,
- NETLINK_CB(skb).portid,
+ portid,
ev->u.c_session.initial_cmdsn,
ev->u.c_session.cmds_max,
ev->u.c_session.queue_depth);
@@ -3526,7 +3531,7 @@
}
err = iscsi_if_create_session(priv, ep, ev,
- NETLINK_CB(skb).portid,
+ portid,
ev->u.c_bound_session.initial_cmdsn,
ev->u.c_bound_session.cmds_max,
ev->u.c_bound_session.queue_depth);
@@ -3684,6 +3689,8 @@
static void
iscsi_if_rx(struct sk_buff *skb)
{
+ u32 portid = NETLINK_CB(skb).portid;
+
mutex_lock(&rx_queue_mutex);
while (skb->len >= NLMSG_HDRLEN) {
int err;
@@ -3719,8 +3726,8 @@
break;
if (ev->type == ISCSI_UEVENT_GET_CHAP && !err)
break;
- err = iscsi_if_send_reply(group, nlh->nlmsg_seq,
- nlh->nlmsg_type, 0, 0, ev, sizeof(*ev));
+ err = iscsi_if_send_reply(portid, nlh->nlmsg_type,
+ ev, sizeof(*ev));
} while (err < 0 && err != -ECONNREFUSED && err != -ESRCH);
skb_pull(skb, rlen);
}
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 8192b7a..4b7ed4e 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1795,6 +1795,8 @@
break; /* standby */
if (sshdr.asc == 4 && sshdr.ascq == 0xc)
break; /* unavailable */
+ if (sshdr.asc == 4 && sshdr.ascq == 0x1b)
+ break; /* sanitize in progress */
/*
* Issue command to spin up drive when not ready
*/
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index edc2780..b847972 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -52,6 +52,7 @@
#include <linux/atomic.h>
#include <linux/ratelimit.h>
#include <linux/sizes.h>
+#include <linux/cred.h> /* for sg_check_file_access() */
#include "scsi.h"
#include <scsi/scsi_dbg.h>
@@ -222,6 +223,33 @@
sdev_printk(prefix, (sdp)->device, "[%s] " fmt, \
(sdp)->disk->disk_name, ##a)
+/*
+ * The SCSI interfaces that use read() and write() as an asynchronous variant of
+ * ioctl(..., SG_IO, ...) are fundamentally unsafe, since there are lots of ways
+ * to trigger read() and write() calls from various contexts with elevated
+ * privileges. This can lead to kernel memory corruption (e.g. if these
+ * interfaces are called through splice()) and privilege escalation inside
+ * userspace (e.g. if a process with access to such a device passes a file
+ * descriptor to a SUID binary as stdin/stdout/stderr).
+ *
+ * This function provides protection for the legacy API by restricting the
+ * calling context.
+ */
+static int sg_check_file_access(struct file *filp, const char *caller)
+{
+ if (filp->f_cred != current_real_cred()) {
+ pr_err_once("%s: process %d (%s) changed security contexts after opening file descriptor, this is not allowed.\n",
+ caller, task_tgid_vnr(current), current->comm);
+ return -EPERM;
+ }
+ if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
+ pr_err_once("%s: process %d (%s) called from kernel context, this is not allowed.\n",
+ caller, task_tgid_vnr(current), current->comm);
+ return -EACCES;
+ }
+ return 0;
+}
+
static int sg_allow_access(struct file *filp, unsigned char *cmd)
{
struct sg_fd *sfp = filp->private_data;
@@ -406,6 +434,14 @@
struct sg_header *old_hdr = NULL;
int retval = 0;
+ /*
+ * This could cause a response to be stranded. Close the associated
+ * file descriptor to free up any resources being held.
+ */
+ retval = sg_check_file_access(filp, __func__);
+ if (retval)
+ return retval;
+
if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
return -ENXIO;
SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sdp,
@@ -593,9 +629,11 @@
struct sg_header old_hdr;
sg_io_hdr_t *hp;
unsigned char cmnd[SG_MAX_CDB_SIZE];
+ int retval;
- if (unlikely(segment_eq(get_fs(), KERNEL_DS)))
- return -EINVAL;
+ retval = sg_check_file_access(filp, __func__);
+ if (retval)
+ return retval;
if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
return -ENXIO;
@@ -1950,7 +1988,7 @@
num = (rem_sz > scatter_elem_sz_prev) ?
scatter_elem_sz_prev : rem_sz;
- schp->pages[k] = alloc_pages(gfp_mask, order);
+ schp->pages[k] = alloc_pages(gfp_mask | __GFP_ZERO, order);
if (!schp->pages[k])
goto out;
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 288bd5f..ff243f8 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -522,6 +522,8 @@
struct scsi_cd *cd;
int ret = -ENXIO;
+ check_disk_change(bdev);
+
mutex_lock(&sr_mutex);
cd = scsi_cd_get(bdev->bd_disk);
if (cd) {
@@ -587,18 +589,28 @@
static unsigned int sr_block_check_events(struct gendisk *disk,
unsigned int clearing)
{
- struct scsi_cd *cd = scsi_cd(disk);
+ unsigned int ret = 0;
+ struct scsi_cd *cd;
- if (atomic_read(&cd->device->disk_events_disable_depth))
+ cd = scsi_cd_get(disk);
+ if (!cd)
return 0;
- return cdrom_check_events(&cd->cdi, clearing);
+ if (!atomic_read(&cd->device->disk_events_disable_depth))
+ ret = cdrom_check_events(&cd->cdi, clearing);
+
+ scsi_cd_put(cd);
+ return ret;
}
static int sr_block_revalidate_disk(struct gendisk *disk)
{
- struct scsi_cd *cd = scsi_cd(disk);
struct scsi_sense_hdr sshdr;
+ struct scsi_cd *cd;
+
+ cd = scsi_cd_get(disk);
+ if (!cd)
+ return -ENXIO;
/* if the unit is not ready, nothing more to do */
if (scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr))
@@ -607,6 +619,7 @@
sr_cd_check(&cd->cdi);
get_sectorsize(cd);
out:
+ scsi_cd_put(cd);
return 0;
}
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c
index 6b349e3..c6425e3 100644
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.c
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c
@@ -536,7 +536,7 @@
* Look for the greatest clock divisor that allows an
* input speed faster than the period.
*/
- while (div-- > 0)
+ while (--div > 0)
if (kpc >= (div_10M[div] << 2)) break;
/*
diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c
index 598f65e..1a71542 100644
--- a/drivers/scsi/vmw_pvscsi.c
+++ b/drivers/scsi/vmw_pvscsi.c
@@ -615,7 +615,7 @@
break;
case BTSTAT_ABORTQUEUE:
- cmd->result = (DID_ABORT << 16);
+ cmd->result = (DID_BUS_BUSY << 16);
break;
case BTSTAT_SCSIPARITY:
diff --git a/drivers/soc/qcom/bg_rsb.c b/drivers/soc/qcom/bg_rsb.c
index a1bb0be..694de69 100644
--- a/drivers/soc/qcom/bg_rsb.c
+++ b/drivers/soc/qcom/bg_rsb.c
@@ -83,6 +83,8 @@
struct input_dev *input;
struct mutex glink_mutex;
+ struct mutex rsb_state_mutex;
+
enum bgrsb_state bgrsb_current_state;
enum glink_link_state link_state;
@@ -651,9 +653,10 @@
struct bgrsb_priv *dev = container_of(work, struct bgrsb_priv,
rsb_up_work);
+ mutex_lock(&dev->rsb_state_mutex);
if (dev->bgrsb_current_state != BGRSB_STATE_RSB_CONFIGURED) {
pr_err("BG is not yet configured for RSB\n");
- return;
+ goto unlock;
}
if (bgrsb_ldo_work(dev, BGRSB_ENABLE_LDO15) == 0) {
@@ -663,7 +666,7 @@
pr_err("Failed to send enable command to BG\n");
bgrsb_ldo_work(dev, BGRSB_DISABLE_LDO15);
dev->bgrsb_current_state = BGRSB_STATE_RSB_CONFIGURED;
- return;
+ goto unlock;
}
}
dev->bgrsb_current_state = BGRSB_STATE_RSB_ENABLED;
@@ -673,6 +676,9 @@
dev->calibration_needed = false;
queue_work(dev->bgrsb_wq, &dev->rsb_calibration_work);
}
+unlock:
+ mutex_unlock(&dev->rsb_state_mutex);
+
}
static void bgrsb_disable_rsb(struct work_struct *work)
@@ -681,20 +687,24 @@
struct bgrsb_priv *dev = container_of(work, struct bgrsb_priv,
rsb_down_work);
+ mutex_lock(&dev->rsb_state_mutex);
if (dev->bgrsb_current_state == BGRSB_STATE_RSB_ENABLED) {
rc = bgrsb_enable(dev, false);
if (rc != 0) {
pr_err("Failed to send disable command to BG\n");
- return;
+ goto unlock;
}
if (bgrsb_ldo_work(dev, BGRSB_DISABLE_LDO15) != 0)
- return;
+ goto unlock;
dev->bgrsb_current_state = BGRSB_STATE_RSB_CONFIGURED;
pr_debug("RSB Disabled\n");
}
+
+unlock:
+ mutex_unlock(&dev->rsb_state_mutex);
}
static void bgrsb_calibration(struct work_struct *work)
@@ -763,13 +773,9 @@
switch (val) {
case BGRSB_POWER_DISABLE:
- if (dev->bgrsb_current_state == BGRSB_STATE_RSB_CONFIGURED)
- return 0;
queue_work(dev->bgrsb_wq, &dev->rsb_down_work);
break;
case BGRSB_POWER_ENABLE:
- if (dev->bgrsb_current_state == BGRSB_STATE_RSB_ENABLED)
- return 0;
queue_work(dev->bgrsb_wq, &dev->rsb_up_work);
break;
case BGRSB_POWER_CALIBRATION:
@@ -857,6 +863,7 @@
dev->chnl.chnl_edge = "bg";
dev->chnl.chnl_trnsprt = "bgcom";
mutex_init(&dev->glink_mutex);
+ mutex_init(&dev->rsb_state_mutex);
dev->link_state = GLINK_LINK_STATE_DOWN;
dev->ldo_action = BGRSB_NO_ACTION;
@@ -981,18 +988,24 @@
struct platform_device *pdev = to_platform_device(pldev);
struct bgrsb_priv *dev = platform_get_drvdata(pdev);
+ mutex_lock(&dev->rsb_state_mutex);
if (dev->bgrsb_current_state == BGRSB_STATE_RSB_CONFIGURED)
- return 0;
+ goto ret_success;
if (dev->bgrsb_current_state == BGRSB_STATE_INIT) {
if (bgrsb_ldo_work(dev, BGRSB_ENABLE_LDO11) == 0) {
dev->bgrsb_current_state = BGRSB_STATE_RSB_CONFIGURED;
pr_debug("RSB Cofigured\n");
- return 0;
+ goto ret_success;
}
pr_err("RSB failed to resume\n");
}
+ mutex_unlock(&dev->rsb_state_mutex);
return -EINVAL;
+
+ret_success:
+ mutex_unlock(&dev->rsb_state_mutex);
+ return 0;
}
static int bg_rsb_suspend(struct device *pldev)
@@ -1000,8 +1013,9 @@
struct platform_device *pdev = to_platform_device(pldev);
struct bgrsb_priv *dev = platform_get_drvdata(pdev);
+ mutex_lock(&dev->rsb_state_mutex);
if (dev->bgrsb_current_state == BGRSB_STATE_INIT)
- return 0;
+ goto ret_success;
if (dev->bgrsb_current_state == BGRSB_STATE_RSB_ENABLED) {
if (bgrsb_ldo_work(dev, BGRSB_DISABLE_LDO15) != 0)
@@ -1011,12 +1025,17 @@
if (bgrsb_ldo_work(dev, BGRSB_DISABLE_LDO11) == 0) {
dev->bgrsb_current_state = BGRSB_STATE_INIT;
pr_debug("RSB Init\n");
- return 0;
+ goto ret_success;
}
ret_err:
pr_err("RSB failed to suspend\n");
+ mutex_unlock(&dev->rsb_state_mutex);
return -EINVAL;
+
+ret_success:
+ mutex_unlock(&dev->rsb_state_mutex);
+ return 0;
}
static const struct of_device_id bg_rsb_of_match[] = {
diff --git a/drivers/soc/qcom/bgcom_spi.c b/drivers/soc/qcom/bgcom_spi.c
index ae37fee..9073cb1 100644
--- a/drivers/soc/qcom/bgcom_spi.c
+++ b/drivers/soc/qcom/bgcom_spi.c
@@ -47,6 +47,7 @@
#define HED_EVENT_ID_LEN (0x02)
#define HED_EVENT_SIZE_LEN (0x02)
#define HED_EVENT_DATA_STRT_LEN (0x05)
+#define CMA_BFFR_POOL_SIZE (128*1024)
#define MAX_RETRY 500
@@ -116,6 +117,9 @@
static atomic_t bg_is_spi_active;
static int bg_irq;
+static uint8_t *fxd_mem_buffer;
+static struct mutex cma_buffer_lock;
+
static struct spi_device *get_spi_device(void)
{
struct bg_spi_priv *bg_spi = container_of(bg_com_drv,
@@ -534,6 +538,7 @@
uint8_t *tx_buf;
uint32_t size;
int ret;
+ bool is_cma_used = false;
uint8_t cmnd = 0;
uint32_t ahb_addr = 0;
struct spi_device *spi = get_spi_device();
@@ -557,11 +562,22 @@
return -EBUSY;
}
+
+ mutex_lock(&cma_buffer_lock);
size = num_words*BG_SPI_WORD_SIZE;
txn_len = BG_SPI_AHB_CMD_LEN + size;
- tx_buf = dma_zalloc_coherent(&spi->dev, txn_len, &dma_hndl, GFP_KERNEL);
- if (!tx_buf)
+ if (fxd_mem_buffer != NULL && txn_len <= CMA_BFFR_POOL_SIZE) {
+ memset(fxd_mem_buffer, 0, txn_len);
+ tx_buf = fxd_mem_buffer;
+ is_cma_used = true;
+ } else
+ tx_buf = dma_zalloc_coherent(&spi->dev, txn_len,
+ &dma_hndl, GFP_KERNEL);
+
+ if (!tx_buf) {
+ mutex_unlock(&cma_buffer_lock);
return -ENOMEM;
+ }
cmnd |= BG_SPI_AHB_WRITE_CMD;
ahb_addr |= ahb_start_addr;
@@ -571,7 +587,9 @@
memcpy(tx_buf+BG_SPI_AHB_CMD_LEN, write_buf, size);
ret = bgcom_transfer(handle, tx_buf, NULL, txn_len);
- dma_free_coherent(&spi->dev, txn_len, tx_buf, dma_hndl);
+ if (!is_cma_used)
+ dma_free_coherent(&spi->dev, txn_len, tx_buf, dma_hndl);
+ mutex_unlock(&cma_buffer_lock);
return ret;
}
EXPORT_SYMBOL(bgcom_ahb_write);
@@ -911,10 +929,15 @@
{
struct bg_spi_priv *bg_spi = device;
/* check if call-back exists */
- if (list_empty(&cb_head)) {
- pr_debug("No callback registered\n");
+ if (!atomic_read(&bg_is_spi_active)) {
+ printk_ratelimited("Interrupt received in suspend state\n");
+ return IRQ_HANDLED;
+ } else if (list_empty(&cb_head)) {
+ pr_err("No callback registered\n");
return IRQ_HANDLED;
} else if (spi_state == BGCOM_SPI_BUSY) {
+ /* delay for spi to be freed */
+ msleep(50);
return IRQ_HANDLED;
} else if (!bg_spi->irq_lock) {
bg_spi->irq_lock = 1;
@@ -948,6 +971,10 @@
bg_com_drv = &bg_spi->lhandle;
mutex_init(&bg_resume_mutex);
+
+ fxd_mem_buffer = kmalloc(CMA_BFFR_POOL_SIZE, GFP_KERNEL | GFP_ATOMIC);
+
+ mutex_init(&cma_buffer_lock);
}
static int bg_spi_probe(struct spi_device *spi)
@@ -1011,10 +1038,17 @@
mutex_destroy(&bg_spi->xfer_mutex);
devm_kfree(&spi->dev, bg_spi);
spi_set_drvdata(spi, NULL);
-
+ if (fxd_mem_buffer != NULL)
+ kfree(fxd_mem_buffer);
+ mutex_destroy(&cma_buffer_lock);
return 0;
}
+static void bg_spi_shutdown(struct spi_device *spi)
+{
+ bg_spi_remove(spi);
+}
+
static int bgcom_pm_suspend(struct device *dev)
{
uint32_t cmnd_reg = 0;
@@ -1030,6 +1064,7 @@
if (ret == 0) {
bg_spi->bg_state = BGCOM_STATE_SUSPEND;
atomic_set(&bg_is_spi_active, 0);
+ disable_irq(bg_irq);
}
pr_info("suspended with : %d\n", ret);
return ret;
@@ -1045,8 +1080,11 @@
clnt_handle.bg_spi = spi;
atomic_set(&bg_is_spi_active, 1);
ret = bgcom_resume(&clnt_handle);
- if (ret == 0)
- pr_info("Bgcom resumed\n");
+ if (ret == 0) {
+ pr_err("Bgcom resumed\n");
+ enable_irq(bg_irq);
+ }
+ pr_err("Bgcom resumed with : %d\n", ret);
return ret;
}
@@ -1069,6 +1107,7 @@
},
.probe = bg_spi_probe,
.remove = bg_spi_remove,
+ .shutdown = bg_spi_shutdown,
};
module_spi_driver(bg_spi_driver);
diff --git a/drivers/soc/qcom/mpm-of.c b/drivers/soc/qcom/mpm-of.c
index 97e0325..c1cd245 100644
--- a/drivers/soc/qcom/mpm-of.c
+++ b/drivers/soc/qcom/mpm-of.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2016, 2018 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -608,8 +608,13 @@
unsigned int apps_irq = msm_mpm_get_irq_m2a(mpm_irq);
struct irq_desc *desc = apps_irq ?
irq_to_desc(apps_irq) : NULL;
+ struct irq_chip *chip = NULL;
- if (desc && !irqd_is_level_type(&desc->irq_data)) {
+ if (desc)
+ chip = desc->irq_data.chip;
+
+ if (desc && !irqd_is_level_type(&desc->irq_data) &&
+ (!(chip && !strcmp(chip->name, "msmgpio")))) {
irq_set_pending(apps_irq);
if (from_idle) {
raw_spin_lock(&desc->lock);
diff --git a/drivers/soc/qcom/pil_bg_intf.h b/drivers/soc/qcom/pil_bg_intf.h
index 46aed25..777ccaa 100644
--- a/drivers/soc/qcom/pil_bg_intf.h
+++ b/drivers/soc/qcom/pil_bg_intf.h
@@ -23,6 +23,7 @@
BGPIL_IMAGE_LOAD,
BGPIL_AUTH_MDT,
BGPIL_DLOAD_CONT,
+ BGPIL_GET_BG_VERSION,
};
/* tzapp bg request.*/
diff --git a/drivers/soc/qcom/qdsp6v2/msm_audio_ion.c b/drivers/soc/qcom/qdsp6v2/msm_audio_ion.c
index ec1526a..e61794c 100644
--- a/drivers/soc/qcom/qdsp6v2/msm_audio_ion.c
+++ b/drivers/soc/qcom/qdsp6v2/msm_audio_ion.c
@@ -44,6 +44,7 @@
#define MSM_AUDIO_SMMU_SID_OFFSET 32
#define TZBSP_MEM_PROTECT_AUDIO_CMD_ID 0x00000005
+#define TZBSP_MEM_PROTECT_AUDIO_CMD_ID_2 0x00000006
struct addr_range {
dma_addr_t start;
@@ -813,11 +814,12 @@
return upper_32_bits(pa);
}
-static void msm_audio_protect_memory_region(struct device *dev)
+static int msm_audio_protect_memory_region(struct device *dev)
{
int ret = 0;
unsigned long size = 0;
phys_addr_t phys_addr = 0;
+ struct scm_desc desc2 = {0};
struct tz_mem_protect_cmd_buf desc = {0};
struct tz_resp resp = {0};
@@ -827,13 +829,24 @@
pr_debug("%s: cma_audio_mem_addr %pK with size %lu\n",
__func__, &phys_addr, size);
- desc.phys_addr = phys_addr;
- desc.size = size;
- ret = scm_call(SCM_SVC_MP, TZBSP_MEM_PROTECT_AUDIO_CMD_ID,
- (void *)&desc , sizeof(desc), (void *)&resp, sizeof(resp));
+ desc2.args[0] = desc.phys_addr = phys_addr;
+ desc2.args[1] = desc.size = size;
+ desc2.arginfo = SCM_ARGS(2);
+ if (!is_scm_armv8()) {
+ ret = scm_call(SCM_SVC_MP, TZBSP_MEM_PROTECT_AUDIO_CMD_ID,
+ (void *)&desc , sizeof(desc),
+ (void *)&resp, sizeof(resp));
+ } else {
+ ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP,
+ TZBSP_MEM_PROTECT_AUDIO_CMD_ID_2), &desc2);
+ resp.ret = desc2.ret[0];
+ }
if (ret < 0)
pr_err("%s: SCM call failed, scm_call_ret %d tz_resp %d\n",
__func__, ret, resp.ret);
+ if (!is_scm_armv8())
+ return ret;
+ return desc2.ret[0];
}
static int msm_audio_ion_probe(struct platform_device *pdev)
diff --git a/drivers/soc/qcom/smcinvoke.c b/drivers/soc/qcom/smcinvoke.c
index e8dd8b2..9a1825a 100644
--- a/drivers/soc/qcom/smcinvoke.c
+++ b/drivers/soc/qcom/smcinvoke.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -11,6 +11,8 @@
*/
#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/miscdevice.h>
#include <linux/poll.h>
@@ -19,6 +21,11 @@
#include <linux/fs.h>
#include <linux/anon_inodes.h>
#include <linux/smcinvoke.h>
+#include <linux/cdev.h>
+#include <linux/uaccess.h>
+#include <linux/clk.h>
+#include <linux/msm-bus.h>
+#include <linux/of.h>
#include <soc/qcom/scm.h>
#include <asm/cacheflush.h>
#include "smcinvoke_object.h"
@@ -32,6 +39,14 @@
#define SMCINVOKE_TZ_MIN_BUF_SIZE 4096
#define SMCINVOKE_ARGS_ALIGN_SIZE (sizeof(uint64_t))
#define SMCINVOKE_TZ_OBJ_NULL 0
+#define SMCINVOKE_CE_CLK_100MHZ 100000000
+#define SMCINVOKE_CE_CLK_DIV 1000000
+#define SMCINVOKE_DEINIT_CLK(x) \
+ { if (x) { clk_put(x); x = NULL; } }
+#define SMCINVOKE_ENABLE_CLK(x) \
+ { if (x) clk_prepare_enable(x); }
+#define SMCINVOKE_DISABLE_CLK(x) \
+ { if (x) clk_disable_unprepare(x); }
#define FOR_ARGS(ndxvar, counts, section) \
for (ndxvar = object_counts_index_##section(counts); \
@@ -39,6 +54,7 @@
+ object_counts_num_##section(counts)); \
++ndxvar)
+static DEFINE_MUTEX(smcinvoke_lock);
static long smcinvoke_ioctl(struct file *, unsigned , unsigned long);
static int smcinvoke_open(struct inode *, struct file *);
static int smcinvoke_release(struct inode *, struct file *);
@@ -51,11 +67,28 @@
.release = smcinvoke_release,
};
-static struct miscdevice smcinvoke_miscdev = {
- .minor = MISC_DYNAMIC_MINOR,
- .name = "smcinvoke",
- .fops = &smcinvoke_fops
+enum clk_types { CE_CORE_SRC_CLK, CE_CORE_CLK, CE_CLK, CE_BUS_CLK, CE_MAX_CLK };
+static const char *clk_names[CE_MAX_CLK] = {
+ "core_clk_src", "core_clk", "iface_clk", "bus_clk"
};
+enum bandwidth_request_mode {BW_INACTIVE = 0, BW_HIGH};
+
+static dev_t smcinvoke_device_no;
+static struct cdev smcinvoke_cdev;
+static struct class *driver_class;
+static struct device *class_dev;
+static struct platform_device *smcinvoke_pdev;
+static struct msm_bus_scale_pdata *bus_scale_pdata;
+static uint32_t qsee_perf_client;
+static bool support_clocks;
+static uint32_t ce_opp_freq_hz;
+static enum bandwidth_request_mode current_mode;
+
+struct smcinvoke_clk {
+ struct clk *clks[CE_MAX_CLK];
+ uint32_t clk_access_cnt;
+};
+static struct smcinvoke_clk g_clk;
struct smcinvoke_buf_hdr {
uint32_t offset;
@@ -103,6 +136,132 @@
return size_add(a, pad_size(a, b));
}
+static void disable_clocks(void)
+{
+ int i;
+
+ for (i = CE_MAX_CLK; i > 0; i--)
+ SMCINVOKE_DISABLE_CLK(g_clk.clks[i-1]);
+}
+
+static int enable_clocks(void)
+{
+ int rc = 0, i;
+
+ for (i = 0; i < CE_MAX_CLK; i++) {
+ if (g_clk.clks[i]) {
+ rc = clk_prepare_enable(g_clk.clks[i]);
+ if (rc) {
+ pr_err("Err %d enabling %s", rc, clk_names[i]);
+ break;
+ }
+ }
+ }
+ if (rc) {
+ for ( ; i >= 0; i--)
+ SMCINVOKE_DISABLE_CLK(g_clk.clks[i]);
+ }
+ return rc;
+}
+
+static int set_msm_bus_request_locked(enum bandwidth_request_mode mode)
+{
+ int ret = 0;
+
+ if (support_clocks == 0)
+ return ret;
+
+ if (g_clk.clks[CE_CORE_SRC_CLK] == NULL) {
+ pr_err("%s clock NULL\n", __func__);
+ return ret;
+ }
+
+ if (current_mode == mode) {
+ if (mode == BW_INACTIVE) {
+ if (g_clk.clk_access_cnt)
+ g_clk.clk_access_cnt--;
+ } else {
+ g_clk.clk_access_cnt++;
+ }
+ return ret;
+ }
+
+ if (mode == BW_INACTIVE) {
+ disable_clocks();
+ } else {
+ ret = enable_clocks();
+ if (ret)
+ goto out;
+ }
+
+ ret = msm_bus_scale_client_update_request(qsee_perf_client, mode);
+ if (ret) {
+ pr_err("BW req failed(%d) MODE (%d)\n", ret, mode);
+ if (mode == BW_INACTIVE)
+ enable_clocks();
+ else
+ disable_clocks();
+ goto out;
+ }
+ current_mode = mode;
+ if (mode == BW_INACTIVE) {
+ if (g_clk.clk_access_cnt)
+ g_clk.clk_access_cnt--;
+ } else {
+ g_clk.clk_access_cnt++;
+ }
+out:
+ return ret;
+}
+
+static void deinit_clocks(void)
+{
+ int i;
+
+ for (i = CE_MAX_CLK; i > 0; i--)
+ SMCINVOKE_DEINIT_CLK(g_clk.clks[i-1])
+}
+
+static struct clk *get_clk(const char *clk_name)
+{
+ int rc = 0;
+ struct clk *clk = clk_get(class_dev, clk_name);
+
+ if (!IS_ERR(clk)) {
+ if (!strcmp(clk_name, clk_names[CE_CORE_SRC_CLK])) {
+ rc = clk_set_rate(clk, ce_opp_freq_hz);
+ if (rc) {
+ SMCINVOKE_DEINIT_CLK(clk);
+ pr_err("Err %d setting clk %s to %uMhz\n",
+ rc, clk_name,
+ ce_opp_freq_hz/SMCINVOKE_CE_CLK_DIV);
+ }
+ }
+ } else {
+ pr_warn("Err %d getting clk %s\n", IS_ERR(clk), clk_name);
+ clk = NULL;
+ }
+ return clk;
+}
+
+static int init_clocks(void)
+{
+ int i = 0;
+ int rc = -1;
+
+ for (i = 0; i < CE_MAX_CLK; i++) {
+ g_clk.clks[i] = get_clk(clk_names[i]);
+ if (!g_clk.clks[i])
+ goto exit;
+ }
+ g_clk.clk_access_cnt = 0;
+ return 0;
+exit:
+ for ( ; i >= 0; i--)
+ SMCINVOKE_DEINIT_CLK(g_clk.clks[i]);
+ return rc;
+}
+
/*
* This function retrieves file pointer corresponding to FD provided. It stores
* retrived file pointer until IOCTL call is concluded. Once call is completed,
@@ -192,14 +351,20 @@
desc.arginfo = SMCINVOKE_TZ_PARAM_ID;
desc.args[0] = (uint64_t)virt_to_phys(in_buf);
- desc.args[1] = in_buf_len;
+ desc.args[1] = inbuf_flush_size;
desc.args[2] = (uint64_t)virt_to_phys(out_buf);
- desc.args[3] = out_buf_len;
+ desc.args[3] = outbuf_flush_size;
dmac_flush_range(in_buf, in_buf + inbuf_flush_size);
dmac_flush_range(out_buf, out_buf + outbuf_flush_size);
+ mutex_lock(&smcinvoke_lock);
+ set_msm_bus_request_locked(BW_HIGH);
+ mutex_unlock(&smcinvoke_lock);
ret = scm_call2(SMCINVOKE_TZ_CMD, &desc);
+ mutex_lock(&smcinvoke_lock);
+ set_msm_bus_request_locked(BW_INACTIVE);
+ mutex_unlock(&smcinvoke_lock);
/* process listener request */
if (!ret && (desc.ret[0] == QSEOS_RESULT_INCOMPLETE ||
@@ -207,12 +372,11 @@
ret = qseecom_process_listener_from_smcinvoke(&desc);
*smcinvoke_result = (int32_t)desc.ret[1];
- if (ret || desc.ret[1] || desc.ret[2] || desc.ret[0]) {
+ if (ret || desc.ret[1] || desc.ret[2] || desc.ret[0])
pr_err("SCM call failed with ret val = %d %d %d %d\n",
ret, (int)desc.ret[0],
(int)desc.ret[1], (int)desc.ret[2]);
- ret = ret | desc.ret[0] | desc.ret[1] | desc.ret[2];
- }
+
dmac_inv_range(in_buf, in_buf + inbuf_flush_size);
dmac_inv_range(out_buf, out_buf + outbuf_flush_size);
return ret;
@@ -243,7 +407,7 @@
pr_err("%s: buffer overflow detected\n", __func__);
goto out;
}
- if (copy_to_user((void __user *)(args_buf[i].b.addr),
+ if (copy_to_user((void __user *)(uintptr_t)(args_buf[i].b.addr),
(uint8_t *)(buf) + tz_args->b.offset,
tz_args->b.size)) {
pr_err("Error %d copying ctxt to user\n", ret);
@@ -328,7 +492,7 @@
tz_args++;
if (copy_from_user(buf+offset,
- (void __user *)(args_buf[i].b.addr),
+ (void __user *)(uintptr_t)(args_buf[i].b.addr),
args_buf[i].b.size))
goto out;
@@ -383,23 +547,27 @@
nr_args = object_counts_num_buffers(req.counts) +
object_counts_num_objects(req.counts);
- if (!nr_args || req.argsize != sizeof(union smcinvoke_arg)) {
+ if (req.argsize != sizeof(union smcinvoke_arg)) {
ret = -EINVAL;
goto out;
}
- args_buf = kzalloc(nr_args * req.argsize, GFP_KERNEL);
- if (!args_buf) {
- ret = -ENOMEM;
- goto out;
- }
+ if (nr_args) {
- ret = copy_from_user(args_buf, (void __user *)(req.args),
+ args_buf = kzalloc(nr_args * req.argsize, GFP_KERNEL);
+ if (!args_buf) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = copy_from_user(args_buf,
+ (void __user *)(uintptr_t)(req.args),
nr_args * req.argsize);
- if (ret) {
- ret = -EFAULT;
- goto out;
+ if (ret) {
+ ret = -EFAULT;
+ goto out;
+ }
}
inmsg_size = compute_in_msg_size(&req, args_buf);
@@ -426,10 +594,17 @@
if (ret)
goto out;
- ret = marshal_out(in_msg, inmsg_size, &req, args_buf);
+ /*
+ * if invoke op results in an err, no need to marshal_out and
+ * copy args buf to user space
+ */
+ if (!req.result) {
+ ret = marshal_out(in_msg, inmsg_size, &req, args_buf);
- ret |= copy_to_user((void __user *)(req.args), args_buf,
- nr_args * req.argsize);
+ ret |= copy_to_user(
+ (void __user *)(uintptr_t)(req.args),
+ args_buf, nr_args * req.argsize);
+ }
ret |= copy_to_user((void __user *)arg, &req, sizeof(req));
if (ret)
goto out;
@@ -499,10 +674,136 @@
return ret;
}
-static int __init smcinvoke_init(void)
+static int smcinvoke_probe(struct platform_device *pdev)
{
- return misc_register(&smcinvoke_miscdev);
+ unsigned int baseminor = 0;
+ unsigned int count = 1;
+ int rc = 0;
+
+ rc = alloc_chrdev_region(&smcinvoke_device_no, baseminor, count,
+ SMCINVOKE_FILE);
+ if (rc < 0) {
+ pr_err("chrdev_region failed %d for %s\n", rc, SMCINVOKE_FILE);
+ return rc;
+ }
+ driver_class = class_create(THIS_MODULE, SMCINVOKE_FILE);
+ if (IS_ERR(driver_class)) {
+ rc = -ENOMEM;
+ pr_err("class_create failed %d\n", rc);
+ goto exit_unreg_chrdev_region;
+ }
+ class_dev = device_create(driver_class, NULL, smcinvoke_device_no,
+ NULL, SMCINVOKE_FILE);
+ if (!class_dev) {
+ pr_err("class_device_create failed %d\n", rc);
+ rc = -ENOMEM;
+ goto exit_destroy_class;
+ }
+
+ cdev_init(&smcinvoke_cdev, &smcinvoke_fops);
+ smcinvoke_cdev.owner = THIS_MODULE;
+
+ rc = cdev_add(&smcinvoke_cdev, MKDEV(MAJOR(smcinvoke_device_no), 0),
+ count);
+ if (rc < 0) {
+ pr_err("cdev_add failed %d for %s\n", rc, SMCINVOKE_FILE);
+ goto exit_destroy_device;
+ }
+ smcinvoke_pdev = pdev;
+ class_dev->of_node = pdev->dev.of_node;
+
+ if (pdev->dev.of_node) {
+ support_clocks =
+ of_property_read_bool(pdev->dev.of_node,
+ "qcom,clock-support");
+ if (of_property_read_u32(pdev->dev.of_node,
+ "qcom,ce-opp-freq",
+ &ce_opp_freq_hz)) {
+ pr_debug("CE op freq not defined, setting to 100MHZ\n");
+ ce_opp_freq_hz = SMCINVOKE_CE_CLK_100MHZ;
+ }
+ }
+ if (support_clocks) {
+ init_clocks();
+ bus_scale_pdata = msm_bus_cl_get_pdata(pdev);
+ if (bus_scale_pdata)
+ qsee_perf_client = msm_bus_scale_register_client(
+ bus_scale_pdata);
+ }
+ return 0;
+
+exit_destroy_device:
+ device_destroy(driver_class, smcinvoke_device_no);
+exit_destroy_class:
+ class_destroy(driver_class);
+exit_unreg_chrdev_region:
+ unregister_chrdev_region(smcinvoke_device_no, count);
+ return rc;
}
-device_initcall(smcinvoke_init);
+static int smcinvoke_remove(struct platform_device *pdev)
+{
+ int count = 1;
+
+ if (support_clocks) {
+ /* ok to call with NULL */
+ msm_bus_scale_unregister_client(qsee_perf_client);
+ if (bus_scale_pdata)
+ msm_bus_cl_clear_pdata(bus_scale_pdata);
+ deinit_clocks();
+ support_clocks = false;
+ }
+ cdev_del(&smcinvoke_cdev);
+ device_destroy(driver_class, smcinvoke_device_no);
+ class_destroy(driver_class);
+ unregister_chrdev_region(smcinvoke_device_no, count);
+ return 0;
+}
+
+static int smcinvoke_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ if (current_mode == BW_HIGH)
+ return 1;
+ else
+ return 0;
+}
+
+static int smcinvoke_resume(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static const struct of_device_id smcinvoke_match[] = {
+ {
+ .compatible = "qcom,smcinvoke",
+ },
+ {},
+};
+
+static struct platform_driver smcinvoke_plat_driver = {
+ .probe = smcinvoke_probe,
+ .remove = smcinvoke_remove,
+ .suspend = smcinvoke_suspend,
+ .resume = smcinvoke_resume,
+ .driver = {
+ .name = "smcinvoke",
+ .owner = THIS_MODULE,
+ .of_match_table = smcinvoke_match,
+ },
+};
+
+static int smcinvoke_init(void)
+{
+ return platform_driver_register(&smcinvoke_plat_driver);
+}
+
+static void smcinvoke_exit(void)
+{
+ platform_driver_unregister(&smcinvoke_plat_driver);
+}
+
+module_init(smcinvoke_init);
+module_exit(smcinvoke_exit);
+
MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("SMC Invoke driver");
diff --git a/drivers/soc/qcom/subsys-pil-bg.c b/drivers/soc/qcom/subsys-pil-bg.c
index 99b600d..b1fa0ca 100644
--- a/drivers/soc/qcom/subsys-pil-bg.c
+++ b/drivers/soc/qcom/subsys-pil-bg.c
@@ -38,6 +38,7 @@
#define desc_to_data(d) container_of(d, struct pil_bg_data, desc)
#define subsys_to_data(d) container_of(d, struct pil_bg_data, subsys_desc)
#define BG_RAMDUMP_SZ 0x00102000
+#define BG_VERSION_SZ 32
#define BG_CRASH_IN_TWM -2
/**
* struct pil_bg_data
@@ -213,6 +214,15 @@
pbd->cmd_status = bg_tz_rsp->status;
else
pbd->cmd_status = 0;
+ /* if last command sent was BG_VERSION print the version*/
+ if (req->tzapp_bg_cmd == BGPIL_GET_BG_VERSION) {
+ int i;
+
+ pr_info("BG FW ver ");
+ for (i = 0; i < bg_tz_rsp->bg_info_len; i++)
+ pr_info("0x%08x ", bg_tz_rsp->bg_info[i]);
+ pr_info("\n");
+ }
end:
return rc;
}
@@ -390,6 +400,28 @@
return 0;
}
+static int bg_get_version(const struct subsys_desc *subsys)
+{
+ struct pil_bg_data *bg_data = subsys_to_data(subsys);
+ struct pil_desc desc = bg_data->desc;
+ struct tzapp_bg_req bg_tz_req;
+ int ret;
+
+ init_dma_attrs(&desc.attrs);
+ dma_set_attr(DMA_ATTR_SKIP_ZEROING, &desc.attrs);
+ dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &desc.attrs);
+
+ bg_tz_req.tzapp_bg_cmd = BGPIL_GET_BG_VERSION;
+
+ ret = bgpil_tzapp_comm(bg_data, &bg_tz_req);
+ if (ret || bg_data->cmd_status) {
+ dev_dbg(desc.dev, "%s: BG PIL get BG version failed error %d\n",
+ __func__, bg_data->cmd_status);
+ return bg_data->cmd_status;
+ }
+
+ return 0;
+}
/**
* bg_auth_and_xfer() - Called by Peripheral loader framework
@@ -424,6 +456,7 @@
pil_free_memory(&bg_data->desc);
return bg_data->cmd_status;
}
+ ret = bg_get_version(&bg_data->subsys_desc);
/* BG Transfer of image is complete, free up the memory */
pr_debug("BG Firmware authentication and transfer done\n");
pil_free_memory(&bg_data->desc);
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index 181bbcd..4dc5ab2 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -2993,6 +2993,14 @@
else
return_error = BR_DEAD_REPLY;
mutex_unlock(&context->context_mgr_node_lock);
+ if (target_node && target_proc == proc) {
+ binder_user_error("%d:%d got transaction to context manager from process owning it\n",
+ proc->pid, thread->pid);
+ return_error = BR_FAILED_REPLY;
+ return_error_param = -EINVAL;
+ return_error_line = __LINE__;
+ goto err_invalid_target_handle;
+ }
}
if (!target_node) {
/*
diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c
index 062de5a..735f5f24 100644
--- a/drivers/staging/android/ion/ion_system_heap.c
+++ b/drivers/staging/android/ion/ion_system_heap.c
@@ -2,7 +2,7 @@
* drivers/staging/android/ion/ion_system_heap.c
*
* Copyright (C) 2011 Google, Inc.
- * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -619,8 +619,10 @@
{
int i;
for (i = 0; i < num_orders; i++)
- if (pools[i])
+ if (pools[i]) {
ion_page_pool_destroy(pools[i]);
+ pools[i] = NULL;
+ }
}
/**
diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
index 6fe48eb..dafbb71 100644
--- a/drivers/staging/android/lowmemorykiller.c
+++ b/drivers/staging/android/lowmemorykiller.c
@@ -44,6 +44,11 @@
#define CREATE_TRACE_POINTS
#include "trace/lowmemorykiller.h"
+/* to enable lowmemorykiller */
+static int enable_lmk = 1;
+module_param_named(enable_lmk, enable_lmk, int,
+ S_IRUGO | S_IWUSR);
+
static uint32_t lowmem_debug_level = 1;
static short lowmem_adj[6] = {
0,
@@ -71,6 +76,9 @@
static unsigned long lowmem_count(struct shrinker *s,
struct shrink_control *sc)
{
+ if (!enable_lmk)
+ return 0;
+
return global_page_state(NR_ACTIVE_ANON) +
global_page_state(NR_ACTIVE_FILE) +
global_page_state(NR_INACTIVE_ANON) +
diff --git a/drivers/staging/android/vsoc.c b/drivers/staging/android/vsoc.c
index 2cb273b..dfe7914 100644
--- a/drivers/staging/android/vsoc.c
+++ b/drivers/staging/android/vsoc.c
@@ -82,8 +82,8 @@
atomic_t *incoming_signalled;
/* Flag indicating the guest has signalled the host. */
atomic_t *outgoing_signalled;
- int irq_requested;
- int device_created;
+ bool irq_requested;
+ bool device_created;
};
struct vsoc_device {
@@ -92,7 +92,7 @@
/* Physical address of SHARED_MEMORY_BAR. */
phys_addr_t shm_phys_start;
/* Kernel virtual address of SHARED_MEMORY_BAR. */
- void *kernel_mapped_shm;
+ void __iomem *kernel_mapped_shm;
/* Size of the entire shared memory window in bytes. */
size_t shm_size;
/*
@@ -117,22 +117,23 @@
* vsoc_region_data because the kernel deals with them as an array.
*/
struct msix_entry *msix_entries;
- /*
- * Flags that indicate what we've initialzied. These are used to do an
- * orderly cleanup of the device.
- */
- char enabled_device;
- char requested_regions;
- char cdev_added;
- char class_added;
- char msix_enabled;
/* Mutex that protectes the permission list */
struct mutex mtx;
/* Major number assigned by the kernel */
int major;
-
+ /* Character device assigned by the kernel */
struct cdev cdev;
+ /* Device class assigned by the kernel */
struct class *class;
+ /*
+ * Flags that indicate what we've initialized. These are used to do an
+ * orderly cleanup of the device.
+ */
+ bool enabled_device;
+ bool requested_regions;
+ bool cdev_added;
+ bool class_added;
+ bool msix_enabled;
};
static struct vsoc_device vsoc_dev;
@@ -154,13 +155,13 @@
static int vsoc_mmap(struct file *, struct vm_area_struct *);
static int vsoc_open(struct inode *, struct file *);
static int vsoc_release(struct inode *, struct file *);
-static ssize_t vsoc_read(struct file *, char *, size_t, loff_t *);
-static ssize_t vsoc_write(struct file *, const char *, size_t, loff_t *);
+static ssize_t vsoc_read(struct file *, char __user *, size_t, loff_t *);
+static ssize_t vsoc_write(struct file *, const char __user *, size_t, loff_t *);
static loff_t vsoc_lseek(struct file *filp, loff_t offset, int origin);
static int do_create_fd_scoped_permission(
struct vsoc_device_region *region_p,
struct fd_scoped_permission_node *np,
- struct fd_scoped_permission_arg *__user arg);
+ struct fd_scoped_permission_arg __user *arg);
static void do_destroy_fd_scoped_permission(
struct vsoc_device_region *owner_region_p,
struct fd_scoped_permission *perm);
@@ -199,7 +200,7 @@
/* Converts from shared memory offset to virtual address */
static inline void *shm_off_to_virtual_addr(__u32 offset)
{
- return vsoc_dev.kernel_mapped_shm + offset;
+ return (void __force *)vsoc_dev.kernel_mapped_shm + offset;
}
/* Converts from shared memory offset to physical address */
@@ -262,7 +263,7 @@
static int do_create_fd_scoped_permission(
struct vsoc_device_region *region_p,
struct fd_scoped_permission_node *np,
- struct fd_scoped_permission_arg *__user arg)
+ struct fd_scoped_permission_arg __user *arg)
{
struct file *managed_filp;
s32 managed_fd;
@@ -633,11 +634,11 @@
return 0;
}
-static ssize_t vsoc_read(struct file *filp, char *buffer, size_t len,
+static ssize_t vsoc_read(struct file *filp, char __user *buffer, size_t len,
loff_t *poffset)
{
__u32 area_off;
- void *area_p;
+ const void *area_p;
ssize_t area_len;
int retval = vsoc_validate_filep(filp);
@@ -707,7 +708,7 @@
return offset;
}
-static ssize_t vsoc_write(struct file *filp, const char *buffer,
+static ssize_t vsoc_write(struct file *filp, const char __user *buffer,
size_t len, loff_t *poffset)
{
__u32 area_off;
@@ -773,14 +774,14 @@
pci_name(pdev), result);
return result;
}
- vsoc_dev.enabled_device = 1;
+ vsoc_dev.enabled_device = true;
result = pci_request_regions(pdev, "vsoc");
if (result < 0) {
dev_err(&pdev->dev, "pci_request_regions failed\n");
vsoc_remove_device(pdev);
return -EBUSY;
}
- vsoc_dev.requested_regions = 1;
+ vsoc_dev.requested_regions = true;
/* Set up the control registers in BAR 0 */
reg_size = pci_resource_len(pdev, REGISTER_BAR);
if (reg_size > MAX_REGISTER_BAR_LEN)
@@ -791,7 +792,7 @@
if (!vsoc_dev.regs) {
dev_err(&pdev->dev,
- "cannot ioremap registers of size %zu\n",
+ "cannot map registers of size %zu\n",
(size_t)reg_size);
vsoc_remove_device(pdev);
return -EBUSY;
@@ -801,8 +802,8 @@
vsoc_dev.shm_phys_start = pci_resource_start(pdev, SHARED_MEMORY_BAR);
vsoc_dev.shm_size = pci_resource_len(pdev, SHARED_MEMORY_BAR);
- dev_info(&pdev->dev, "shared memory @ DMA %p size=0x%zx\n",
- (void *)vsoc_dev.shm_phys_start, vsoc_dev.shm_size);
+ dev_info(&pdev->dev, "shared memory @ DMA %pa size=0x%zx\n",
+ &vsoc_dev.shm_phys_start, vsoc_dev.shm_size);
/* TODO(ghartman): ioremap_wc should work here */
vsoc_dev.kernel_mapped_shm = ioremap_nocache(
vsoc_dev.shm_phys_start, vsoc_dev.shm_size);
@@ -812,8 +813,8 @@
return -EBUSY;
}
- vsoc_dev.layout =
- (struct vsoc_shm_layout_descriptor *)vsoc_dev.kernel_mapped_shm;
+ vsoc_dev.layout = (struct vsoc_shm_layout_descriptor __force *)
+ vsoc_dev.kernel_mapped_shm;
dev_info(&pdev->dev, "major_version: %d\n",
vsoc_dev.layout->major_version);
dev_info(&pdev->dev, "minor_version: %d\n",
@@ -844,16 +845,16 @@
vsoc_remove_device(pdev);
return -EBUSY;
}
- vsoc_dev.cdev_added = 1;
+ vsoc_dev.cdev_added = true;
vsoc_dev.class = class_create(THIS_MODULE, VSOC_DEV_NAME);
if (IS_ERR(vsoc_dev.class)) {
dev_err(&vsoc_dev.dev->dev, "class_create failed\n");
vsoc_remove_device(pdev);
return PTR_ERR(vsoc_dev.class);
}
- vsoc_dev.class_added = 1;
- vsoc_dev.regions = (struct vsoc_device_region *)
- (vsoc_dev.kernel_mapped_shm +
+ vsoc_dev.class_added = true;
+ vsoc_dev.regions = (struct vsoc_device_region __force *)
+ ((void *)vsoc_dev.layout +
vsoc_dev.layout->vsoc_region_desc_offset);
vsoc_dev.msix_entries = kcalloc(
vsoc_dev.layout->region_count,
@@ -913,7 +914,7 @@
return -EFAULT;
}
}
- vsoc_dev.msix_enabled = 1;
+ vsoc_dev.msix_enabled = true;
for (i = 0; i < vsoc_dev.layout->region_count; ++i) {
const struct vsoc_device_region *region = vsoc_dev.regions + i;
size_t name_sz = sizeof(vsoc_dev.regions_data[i].name) - 1;
@@ -931,14 +932,11 @@
&vsoc_dev.regions_data[i].interrupt_wait_queue);
init_waitqueue_head(&vsoc_dev.regions_data[i].futex_wait_queue);
vsoc_dev.regions_data[i].incoming_signalled =
- vsoc_dev.kernel_mapped_shm +
- region->region_begin_offset +
+ shm_off_to_virtual_addr(region->region_begin_offset) +
h_to_g_signal_table->interrupt_signalled_offset;
vsoc_dev.regions_data[i].outgoing_signalled =
- vsoc_dev.kernel_mapped_shm +
- region->region_begin_offset +
+ shm_off_to_virtual_addr(region->region_begin_offset) +
g_to_h_signal_table->interrupt_signalled_offset;
-
result = request_irq(
vsoc_dev.msix_entries[i].vector,
vsoc_interrupt, 0,
@@ -951,7 +949,7 @@
vsoc_remove_device(pdev);
return -ENOSPC;
}
- vsoc_dev.regions_data[i].irq_requested = 1;
+ vsoc_dev.regions_data[i].irq_requested = true;
if (!device_create(vsoc_dev.class, NULL,
MKDEV(vsoc_dev.major, i),
NULL, vsoc_dev.regions_data[i].name)) {
@@ -959,7 +957,7 @@
vsoc_remove_device(pdev);
return -EBUSY;
}
- vsoc_dev.regions_data[i].device_created = 1;
+ vsoc_dev.regions_data[i].device_created = true;
}
return 0;
}
@@ -991,51 +989,51 @@
if (vsoc_dev.regions_data[i].device_created) {
device_destroy(vsoc_dev.class,
MKDEV(vsoc_dev.major, i));
- vsoc_dev.regions_data[i].device_created = 0;
+ vsoc_dev.regions_data[i].device_created = false;
}
if (vsoc_dev.regions_data[i].irq_requested)
free_irq(vsoc_dev.msix_entries[i].vector, NULL);
- vsoc_dev.regions_data[i].irq_requested = 0;
+ vsoc_dev.regions_data[i].irq_requested = false;
}
kfree(vsoc_dev.regions_data);
- vsoc_dev.regions_data = 0;
+ vsoc_dev.regions_data = NULL;
}
if (vsoc_dev.msix_enabled) {
pci_disable_msix(pdev);
- vsoc_dev.msix_enabled = 0;
+ vsoc_dev.msix_enabled = false;
}
kfree(vsoc_dev.msix_entries);
- vsoc_dev.msix_entries = 0;
- vsoc_dev.regions = 0;
+ vsoc_dev.msix_entries = NULL;
+ vsoc_dev.regions = NULL;
if (vsoc_dev.class_added) {
class_destroy(vsoc_dev.class);
- vsoc_dev.class_added = 0;
+ vsoc_dev.class_added = false;
}
if (vsoc_dev.cdev_added) {
cdev_del(&vsoc_dev.cdev);
- vsoc_dev.cdev_added = 0;
+ vsoc_dev.cdev_added = false;
}
if (vsoc_dev.major && vsoc_dev.layout) {
unregister_chrdev_region(MKDEV(vsoc_dev.major, 0),
vsoc_dev.layout->region_count);
vsoc_dev.major = 0;
}
- vsoc_dev.layout = 0;
+ vsoc_dev.layout = NULL;
if (vsoc_dev.kernel_mapped_shm) {
pci_iounmap(pdev, vsoc_dev.kernel_mapped_shm);
- vsoc_dev.kernel_mapped_shm = 0;
+ vsoc_dev.kernel_mapped_shm = NULL;
}
if (vsoc_dev.regs) {
pci_iounmap(pdev, vsoc_dev.regs);
- vsoc_dev.regs = 0;
+ vsoc_dev.regs = NULL;
}
if (vsoc_dev.requested_regions) {
pci_release_regions(pdev);
- vsoc_dev.requested_regions = 0;
+ vsoc_dev.requested_regions = false;
}
if (vsoc_dev.enabled_device) {
pci_disable_device(pdev);
- vsoc_dev.enabled_device = 0;
+ vsoc_dev.enabled_device = false;
}
/* Do this last: it indicates that the device is not initialized. */
vsoc_dev.dev = NULL;
diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg80211.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg80211.c
index 81b1474..cbb66f6 100644
--- a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -16070,6 +16070,12 @@
if ( NULL != ie )
{
pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
+
+ if (ie[1] < DOT11F_IE_WPA_MIN_LEN ||
+ ie[1] > DOT11F_IE_WPA_MAX_LEN) {
+ hddLog(LOGE, FL("invalid ie len:%d"), ie[1]);
+ return -EINVAL;
+ }
// Unpack the WPA IE
//Skip past the EID byte and length byte - and four byte WiFi OUI
ret = dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_wext.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_wext.c
index 665f89b..b4b00cb 100644
--- a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_wext.c
+++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_wext.c
@@ -2104,7 +2104,8 @@
hdd_wext_state_t *pWextState;
hdd_station_ctx_t *pHddStaCtx;
hdd_context_t *pHddCtx;
- v_U8_t supp_rates[WNI_CFG_SUPPORTED_RATES_11A_LEN];
+ v_U8_t supp_rates[WNI_CFG_SUPPORTED_RATES_11A_LEN +
+ WNI_CFG_SUPPORTED_RATES_11B_LEN];
v_U32_t a_len = WNI_CFG_SUPPORTED_RATES_11A_LEN;
v_U32_t b_len = WNI_CFG_SUPPORTED_RATES_11B_LEN;
v_U32_t i, rate;
@@ -2167,7 +2168,7 @@
supp_rates, &a_len) == eHAL_STATUS_SUCCESS) &&
(ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
WNI_CFG_SUPPORTED_RATES_11B,
- supp_rates, &b_len) == eHAL_STATUS_SUCCESS))
+ supp_rates + a_len, &b_len) == eHAL_STATUS_SUCCESS))
{
for (i = 0; i < (b_len + a_len); ++i)
{
@@ -6327,6 +6328,7 @@
else
{
/* request was sent -- wait for the response */
+ ret = hdd_request_wait_for_response(request);
if (ret)
{
hddLog(VOS_TRACE_LEVEL_ERROR,
@@ -8944,6 +8946,7 @@
{
hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to execute Clear Filter",
__func__);
+ hdd_request_put(request);
return -EINVAL;
}
diff --git a/drivers/staging/prima/CORE/MAC/src/include/dot11f.h b/drivers/staging/prima/CORE/MAC/src/include/dot11f.h
index a76f3f8..e1461c1 100644
--- a/drivers/staging/prima/CORE/MAC/src/include/dot11f.h
+++ b/drivers/staging/prima/CORE/MAC/src/include/dot11f.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -32,7 +32,7 @@
* \brief Structures, function prototypes & definitions
* for working with 802.11 Frames
* This file was automatically generated by 'framesc'
- * Thu Dec 28 14:04:50 2017 from the following file(s):
+ * Tue Jul 24 13:24:45 2018 from the following file(s):
*
* dot11f.frms
*
@@ -51,6 +51,10 @@
# pragma warning (disable: 4214) /* nonstandard extension used */
#endif /* Microsoft C/C++ bit field types other than int */
+#if !defined unlikely
+#define unlikely(x) (x)
+#endif
+
/*
* Frames Return Codes:
*
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limLogDump.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limLogDump.c
index af5c95e..12ca209 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limLogDump.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limLogDump.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2013, 2016-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 2016-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -725,6 +725,8 @@
limSetEdcaBcastACMFlag(tpAniSirGlobal pMac, tANI_U32 ac, tANI_U32 acmFlag)
{
tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry?????
+ if (ac >= MAX_NUM_AC)
+ return;
psessionEntry->gLimEdcaParamsBC[ac].aci.acm = (tANI_U8)acmFlag;
psessionEntry->gLimEdcaParamSetCount++;
schSetFixedBeaconFields(pMac,psessionEntry);
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c
index 195f844..bf206fe 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c
@@ -1744,6 +1744,13 @@
pAddBssParams->cfParamSet.cfpDurRemaining = pMlmStartReq->cfParamSet.cfpDurRemaining;
pAddBssParams->rateSet.numRates = pMlmStartReq->rateSet.numRates;
+ if (pAddBssParams->rateSet.numRates > SIR_MAC_RATESET_EID_MAX) {
+ limLog(pMac, LOGW,
+ FL("num of sup rates %d exceeding the limit %d, resetting"),
+ pAddBssParams->rateSet.numRates,
+ SIR_MAC_RATESET_EID_MAX);
+ pAddBssParams->rateSet.numRates = SIR_MAC_RATESET_EID_MAX;
+ }
vos_mem_copy(pAddBssParams->rateSet.rate,
pMlmStartReq->rateSet.rate, pMlmStartReq->rateSet.numRates);
@@ -1769,10 +1776,19 @@
pAddBssParams->sessionId = pMlmStartReq->sessionId;
//Send the SSID to HAL to enable SSID matching for IBSS
- vos_mem_copy(&(pAddBssParams->ssId.ssId),
+ pAddBssParams->ssId.length = pMlmStartReq->ssId.length;
+ if (pAddBssParams->ssId.length > SIR_MAC_MAX_SSID_LENGTH) {
+ limLog(pMac, LOGE,
+ FL("Invalid ssid length %d, max length allowed %d"),
+ pAddBssParams->ssId.length,
+ SIR_MAC_MAX_SSID_LENGTH);
+ vos_mem_free(pAddBssParams);
+ return eSIR_SME_INVALID_PARAMETERS;
+ }
+ vos_mem_copy(pAddBssParams->ssId.ssId,
pMlmStartReq->ssId.ssId,
pMlmStartReq->ssId.length);
- pAddBssParams->ssId.length = pMlmStartReq->ssId.length;
+
pAddBssParams->bHiddenSSIDEn = pMlmStartReq->ssidHidden;
limLog( pMac, LOGE, FL( "TRYING TO HIDE SSID %d" ),pAddBssParams->bHiddenSSIDEn);
// CR309183. Disable Proxy Probe Rsp. Host handles Probe Requests. Until FW fixed.
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limScanResultUtils.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limScanResultUtils.c
index 26b3b5b..607585d7 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limScanResultUtils.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limScanResultUtils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2014, 2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2014, 2016, 2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -512,7 +512,7 @@
*/
ieLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
- if (ieLen <= SIR_MAC_B_PR_SSID_OFFSET)
+ if (ieLen <= (SIR_MAC_B_PR_SSID_OFFSET + 2))
{
limLog(pMac, LOGP,
FL("RX packet has invalid length %d"), ieLen);
@@ -563,18 +563,21 @@
limLog(pMac, LOG1, FL(" pHdr->addr3:"MAC_ADDRESS_STR),
MAC_ADDR_ARRAY(pHdr->addr3));
limLog( pMac, LOG1, FL("Save this entry in LFR cache"));
- status = limLookupNaddLfrHashEntry(pMac, pBssDescr, LIM_HASH_ADD, dontUpdateAll);
+ status = limLookupNaddLfrHashEntry(pMac, pBssDescr, LIM_HASH_ADD,
+ dontUpdateAll, ieLen - 2);
}
else
#endif
//If it is not scanning, only save unique results
if (pMac->lim.gLimReturnUniqueResults || (!fScanning))
{
- status = limLookupNaddHashEntry(pMac, pBssDescr, LIM_HASH_UPDATE, dontUpdateAll);
+ status = limLookupNaddHashEntry(pMac, pBssDescr, LIM_HASH_UPDATE,
+ dontUpdateAll, ieLen - 2);
}
else
{
- status = limLookupNaddHashEntry(pMac, pBssDescr, LIM_HASH_ADD, dontUpdateAll);
+ status = limLookupNaddHashEntry(pMac, pBssDescr, LIM_HASH_ADD,
+ dontUpdateAll, ieLen - 2);
}
if(fScanning)
@@ -715,7 +718,7 @@
eHalStatus
limLookupNaddHashEntry(tpAniSirGlobal pMac,
tLimScanResultNode *pBssDescr, tANI_U8 action,
- tANI_U8 dontUpdateAll)
+ tANI_U8 dontUpdateAll, tANI_U32 ie_len)
{
tANI_U8 index, ssidLen = 0;
tANI_U8 found = false;
@@ -730,6 +733,11 @@
//ieFields start with TLV of SSID IE
ssidLen = * ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1);
+ if ((ssidLen > ie_len) || (ssidLen > DOT11F_IE_SSID_MAX_LEN)) {
+ limLog(pMac, LOGE, FL("SSID length %d, IE overall Length %d"),
+ ssidLen, ie_len);
+ return eHAL_STATUS_FAILURE;
+ }
pSirCap = (tSirMacCapabilityInfo *)&pBssDescr->bssDescription.capabilityInfo;
for (pprev = ptemp; ptemp; pprev = ptemp, ptemp = ptemp->next)
@@ -743,6 +751,8 @@
// matching band to update new channel info
(vos_chan_to_band(pBssDescr->bssDescription.channelId) ==
vos_chan_to_band(ptemp->bssDescription.channelId)) &&
+ (*((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1) ==
+ *((tANI_U8 *) &ptemp->bssDescription.ieFields + 1)) &&
vos_mem_compare( ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1),
((tANI_U8 *) &ptemp->bssDescription.ieFields + 1),
(tANI_U8) (ssidLen + 1)) &&
@@ -939,9 +949,9 @@
eHalStatus
limLookupNaddLfrHashEntry(tpAniSirGlobal pMac,
tLimScanResultNode *pBssDescr, tANI_U8 action,
- tANI_U8 dontUpdateAll)
+ tANI_U8 dontUpdateAll, tANI_U32 ie_len)
{
- tANI_U8 index, ssidLen = 0;
+ tANI_U8 index, ssidLen = 0;
tLimScanResultNode *ptemp, *pprev;
tSirMacCapabilityInfo *pSirCap, *pSirCapTemp;
int idx, len;
@@ -953,6 +963,11 @@
//ieFields start with TLV of SSID IE
ssidLen = * ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1);
+ if ((ssidLen > ie_len) || (ssidLen > DOT11F_IE_SSID_MAX_LEN)) {
+ limLog(pMac, LOGE, FL("SSID length %d, IE overall Length %d"),
+ ssidLen, ie_len);
+ return eHAL_STATUS_FAILURE;
+ }
pSirCap = (tSirMacCapabilityInfo *)&pBssDescr->bssDescription.capabilityInfo;
for (pprev = ptemp; ptemp; pprev = ptemp, ptemp = ptemp->next)
@@ -965,6 +980,8 @@
sizeof(tSirMacAddr))) && //matching BSSID
(pBssDescr->bssDescription.channelId ==
ptemp->bssDescription.channelId) &&
+ (*((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1) ==
+ *((tANI_U8 *) &ptemp->bssDescription.ieFields + 1)) &&
vos_mem_compare( ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1),
((tANI_U8 *) &ptemp->bssDescription.ieFields + 1),
(tANI_U8) (ssidLen + 1)) &&
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limScanResultUtils.h b/drivers/staging/prima/CORE/MAC/src/pe/lim/limScanResultUtils.h
index 28ea943..dd5168c 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limScanResultUtils.h
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limScanResultUtils.h
@@ -44,7 +44,8 @@
tANI_U8 limScanHashFunction(tSirMacAddr);
void limInitHashTable(tpAniSirGlobal);
eHalStatus
- limLookupNaddHashEntry(tpAniSirGlobal, tLimScanResultNode *, tANI_U8, tANI_U8);
+ limLookupNaddHashEntry(tpAniSirGlobal, tLimScanResultNode *,
+ tANI_U8, tANI_U8, tANI_U32);
void limDeleteHashEntry(tLimScanResultNode *);
void limDeleteCachedScanResults(tpAniSirGlobal);
void limRestorePreScanState(tpAniSirGlobal);
@@ -53,7 +54,8 @@
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
void limInitLfrHashTable(tpAniSirGlobal);
eHalStatus
- limLookupNaddLfrHashEntry(tpAniSirGlobal, tLimScanResultNode *, tANI_U8, tANI_U8);
+ limLookupNaddLfrHashEntry(tpAniSirGlobal, tLimScanResultNode *,
+ tANI_U8, tANI_U8, tANI_U32);
void limDeleteLfrHashEntry(tLimScanResultNode *);
void limDeleteCachedLfrScanResults(tpAniSirGlobal);
void limReInitLfrScanResults(tpAniSirGlobal);
diff --git a/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/dot11f.c b/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/dot11f.c
index 6cb5b08..193aff1 100644
--- a/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/dot11f.c
+++ b/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/dot11f.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -30,7 +30,7 @@
* \brief Structures, functions & definitions for
* working with 802.11 Frames
* This file was automatically generated by 'framesc'
- * Thu Dec 28 14:04:50 2017 from the following file(s):
+ * Tue Jul 24 13:24:45 2018 from the following file(s):
*
* dot11f.frms
*
@@ -455,8 +455,9 @@
if (*pBuf == pIe->eid)
{
if (pIe->eid == 0xff) {
- if ((*(pBuf + 2)) == pIe->extn_eid)
- return pIe;
+ if ((nBuf > 2) &&
+ (*(pBuf + 2)) == pIe->extn_eid)
+ return pIe;
} else {
if (0 == pIe->noui)
return pIe;
@@ -1046,6 +1047,11 @@
{
tANI_U32 status = DOT11F_PARSE_SUCCESS;
pDst->present = 1;
+ if (unlikely(tlvlen < 6)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->mac, pBuf, 6);
pBuf += 6;
tlvlen -= (tANI_U8)6;
@@ -1064,6 +1070,11 @@
tANI_U32 status = DOT11F_PARSE_SUCCESS;
tANI_U8 tmp7__;
pDst->present = 1;
+ if (unlikely(tlvlen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp7__ = *pBuf;
pBuf += 1;
tlvlen -= 1;
@@ -1086,6 +1097,11 @@
{
tANI_U32 status = DOT11F_PARSE_SUCCESS;
pDst->present = 1;
+ if (unlikely(tlvlen < 3)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->countryString, pBuf, 3);
pBuf += 3;
tlvlen -= (tANI_U8)3;
@@ -1115,9 +1131,19 @@
{
tANI_U32 status = DOT11F_PARSE_SUCCESS;
pDst->present = 1;
+ if (unlikely(tlvlen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->GOConfigTimeout = *pBuf;
pBuf += 1;
tlvlen -= (tANI_U8)1;
+ if (unlikely(tlvlen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->CLConfigTimeout = *pBuf;
pBuf += 1;
tlvlen -= (tANI_U8)1;
@@ -1155,9 +1181,19 @@
{
tANI_U32 status = DOT11F_PARSE_SUCCESS;
pDst->present = 1;
+ if (unlikely(tlvlen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->availibilityPeriod, pBuf, 0);
pBuf += 2;
tlvlen -= (tANI_U8)2;
+ if (unlikely(tlvlen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->availibilityInterval, pBuf, 0);
pBuf += 2;
tlvlen -= (tANI_U8)2;
@@ -1175,6 +1211,11 @@
{
tANI_U32 status = DOT11F_PARSE_SUCCESS;
pDst->present = 1;
+ if (unlikely(tlvlen < 6)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->P2PInterfaceAddress, pBuf, 6);
pBuf += 6;
tlvlen -= (tANI_U8)6;
@@ -1192,12 +1233,27 @@
{
tANI_U32 status = DOT11F_PARSE_SUCCESS;
pDst->present = 1;
+ if (unlikely(tlvlen < 3)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->countryString, pBuf, 3);
pBuf += 3;
tlvlen -= (tANI_U8)3;
+ if (unlikely(tlvlen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->regulatoryClass = *pBuf;
pBuf += 1;
tlvlen -= (tANI_U8)1;
+ if (unlikely(tlvlen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->channel = *pBuf;
pBuf += 1;
tlvlen -= (tANI_U8)1;
@@ -1275,9 +1331,19 @@
{
tANI_U32 status = DOT11F_PARSE_SUCCESS;
pDst->present = 1;
+ if (unlikely(tlvlen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->index = *pBuf;
pBuf += 1;
tlvlen -= (tANI_U8)1;
+ if (unlikely(tlvlen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->CTSWindowOppPS = *pBuf;
pBuf += 1;
tlvlen -= (tANI_U8)1;
@@ -1301,12 +1367,27 @@
{
tANI_U32 status = DOT11F_PARSE_SUCCESS;
pDst->present = 1;
+ if (unlikely(tlvlen < 3)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->countryString, pBuf, 3);
pBuf += 3;
tlvlen -= (tANI_U8)3;
+ if (unlikely(tlvlen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->regulatoryClass = *pBuf;
pBuf += 1;
tlvlen -= (tANI_U8)1;
+ if (unlikely(tlvlen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->channel = *pBuf;
pBuf += 1;
tlvlen -= (tANI_U8)1;
@@ -1321,9 +1402,19 @@
{
tANI_U32 status = DOT11F_PARSE_SUCCESS;
pDst->present = 1;
+ if (unlikely(tlvlen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->deviceCapability = *pBuf;
pBuf += 1;
tlvlen -= (tANI_U8)1;
+ if (unlikely(tlvlen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->groupCapability = *pBuf;
pBuf += 1;
tlvlen -= (tANI_U8)1;
@@ -1338,6 +1429,11 @@
{
tANI_U32 status = DOT11F_PARSE_SUCCESS;
pDst->present = 1;
+ if (unlikely(tlvlen < 6)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->P2PDeviceAddress, pBuf, 6);
pBuf += 6;
tlvlen -= (tANI_U8)6;
@@ -1357,12 +1453,27 @@
{
tANI_U32 status = DOT11F_PARSE_SUCCESS;
pDst->present = 1;
+ if (unlikely(tlvlen < 6)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->P2PDeviceAddress, pBuf, 6);
pBuf += 6;
tlvlen -= (tANI_U8)6;
+ if (unlikely(tlvlen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->configMethod, pBuf, 0);
pBuf += 2;
tlvlen -= (tANI_U8)2;
+ if (unlikely(tlvlen < 8)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->primaryDeviceType, pBuf, 8);
pBuf += 8;
tlvlen -= (tANI_U8)8;
@@ -1383,6 +1494,11 @@
{
tANI_U32 status = DOT11F_PARSE_SUCCESS;
pDst->present = 1;
+ if (unlikely(tlvlen < 6)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->P2PGroupBssid, pBuf, 6);
pBuf += 6;
tlvlen -= (tANI_U8)6;
@@ -1397,6 +1513,11 @@
{
tANI_U32 status = DOT11F_PARSE_SUCCESS;
pDst->present = 1;
+ if (unlikely(tlvlen < 6)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->deviceAddress, pBuf, 6);
pBuf += 6;
tlvlen -= (tANI_U8)6;
@@ -1439,12 +1560,27 @@
tANI_U32 status = DOT11F_PARSE_SUCCESS;
(void)pBuf; (void)tlvlen; /* Shutup the compiler */
pDst->present = 1;
+ if (unlikely(tlvlen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->primary_category, pBuf, 1);
pBuf += 2;
tlvlen -= (tANI_U8)2;
+ if (unlikely(tlvlen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->oui, pBuf, 4);
pBuf += 4;
tlvlen -= (tANI_U8)4;
+ if (unlikely(tlvlen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->sub_category, pBuf, 1);
pBuf += 2;
tlvlen -= (tANI_U8)2;
@@ -1462,12 +1598,27 @@
{
tANI_U32 status = DOT11F_PARSE_SUCCESS;
pDst->present = 1;
+ if (unlikely(tlvlen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->primary_category, pBuf, 1);
pBuf += 2;
tlvlen -= (tANI_U8)2;
+ if (unlikely(tlvlen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->oui, pBuf, 4);
pBuf += 4;
tlvlen -= (tANI_U8)4;
+ if (unlikely(tlvlen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->sub_category, pBuf, 1);
pBuf += 2;
tlvlen -= (tANI_U8)2;
@@ -1514,6 +1665,11 @@
{
tANI_U32 status = DOT11F_PARSE_SUCCESS;
pDst->present = 1;
+ if (unlikely(tlvlen < 16)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->uuid, pBuf, 16);
pBuf += 16;
tlvlen -= (tANI_U8)16;
@@ -1528,6 +1684,11 @@
{
tANI_U32 status = DOT11F_PARSE_SUCCESS;
pDst->present = 1;
+ if (unlikely(tlvlen < 16)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->uuid, pBuf, 16);
pBuf += 16;
tlvlen -= (tANI_U8)16;
@@ -1549,6 +1710,11 @@
{
tANI_U32 status = DOT11F_PARSE_SUCCESS;
pDst->present = 1;
+ if (unlikely(tlvlen < 3)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->vendorId, pBuf, 3);
pBuf += 3;
tlvlen -= (tANI_U8)3;
@@ -1570,6 +1736,11 @@
tANI_U32 status = DOT11F_PARSE_SUCCESS;
tANI_U8 tmp8__;
pDst->present = 1;
+ if (unlikely(tlvlen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp8__ = *pBuf;
pBuf += 1;
tlvlen -= 1;
@@ -1589,6 +1760,11 @@
{
tANI_U32 status = DOT11F_PARSE_SUCCESS;
pDst->present = 1;
+ if (unlikely(tlvlen < 6)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->P2PDeviceAddress, pBuf, 6);
pBuf += 6;
tlvlen -= (tANI_U8)6;
@@ -1628,9 +1804,19 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->indicator = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->type = *pBuf;
(void)pCtx;
return status;
@@ -1645,6 +1831,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->countryStr, pBuf, 2);
(void)pCtx;
return status;
@@ -1660,14 +1851,29 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &tmp9__, pBuf, 0);
pBuf += 2;
ielen -= 2;
pDst->keyId = tmp9__ >> 0 & 0x3;
pDst->reserved = tmp9__ >> 2 & 0x3feb;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->keyLength = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 8)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->RSC, pBuf, 8);
pBuf += 8;
ielen -= (tANI_U8)8;
@@ -1694,15 +1900,35 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->keyID, pBuf, 2);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 6)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->IPN, pBuf, 6);
pBuf += 6;
ielen -= (tANI_U8)6;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->keyLength = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 24)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->key, pBuf, 24);
(void)pCtx;
return status;
@@ -1717,6 +1943,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->defer_threshold, pBuf, 1);
(void)pCtx;
return status;
@@ -1731,9 +1962,19 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 6)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->bssid, pBuf, 6);
pBuf += 6;
ielen -= (tANI_U8)6;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->channel = *pBuf;
(void)pCtx;
return status;
@@ -1748,9 +1989,19 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->num_stas, pBuf, 1);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->channel_util, pBuf, 1);
(void)pCtx;
return status;
@@ -1768,6 +2019,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->capability, pBuf, 0);
(void)pCtx;
return status;
@@ -1782,15 +2038,35 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->mode = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->primary_channel = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->sub_band = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->channel_switch_count = *pBuf;
(void)pCtx;
return status;
@@ -1813,12 +2089,27 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->qos = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->reserved = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp10__ = *pBuf;
pBuf += 1;
ielen -= 1;
@@ -1826,14 +2117,29 @@
pDst->acbe_acm = tmp10__ >> 4 & 0x1;
pDst->acbe_aci = tmp10__ >> 5 & 0x3;
pDst->unused1 = tmp10__ >> 7 & 0x1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp11__ = *pBuf;
pBuf += 1;
ielen -= 1;
pDst->acbe_min = tmp11__ >> 0 & 0xf;
pDst->acbe_max = tmp11__ >> 4 & 0xf;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->acbe_txoplimit, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp12__ = *pBuf;
pBuf += 1;
ielen -= 1;
@@ -1841,14 +2147,29 @@
pDst->acbk_acm = tmp12__ >> 4 & 0x1;
pDst->acbk_aci = tmp12__ >> 5 & 0x3;
pDst->unused2 = tmp12__ >> 7 & 0x1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp13__ = *pBuf;
pBuf += 1;
ielen -= 1;
pDst->acbk_min = tmp13__ >> 0 & 0xf;
pDst->acbk_max = tmp13__ >> 4 & 0xf;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->acbk_txoplimit, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp14__ = *pBuf;
pBuf += 1;
ielen -= 1;
@@ -1856,14 +2177,29 @@
pDst->acvi_acm = tmp14__ >> 4 & 0x1;
pDst->acvi_aci = tmp14__ >> 5 & 0x3;
pDst->unused3 = tmp14__ >> 7 & 0x1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp15__ = *pBuf;
pBuf += 1;
ielen -= 1;
pDst->acvi_min = tmp15__ >> 0 & 0xf;
pDst->acvi_max = tmp15__ >> 4 & 0xf;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->acvi_txoplimit, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp16__ = *pBuf;
pBuf += 1;
ielen -= 1;
@@ -1871,11 +2207,21 @@
pDst->acvo_acm = tmp16__ >> 4 & 0x1;
pDst->acvo_aci = tmp16__ >> 5 & 0x3;
pDst->unused4 = tmp16__ >> 7 & 0x1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp17__ = *pBuf;
pBuf += 1;
ielen -= 1;
pDst->acvo_min = tmp17__ >> 0 & 0xf;
pDst->acvo_max = tmp17__ >> 4 & 0xf;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->acvo_txoplimit, pBuf, 0);
(void)pCtx;
return status;
@@ -1890,15 +2236,35 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->quiet_count = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->quiet_period = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->quiet_duration, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->quiet_offset, pBuf, 0);
(void)pCtx;
return status;
@@ -1961,6 +2327,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 6)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->PMK_R1_ID, pBuf, 6);
(void)pCtx;
return status;
@@ -1975,9 +2346,19 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->TsfOffset, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->BeaconIntvl, pBuf, 0);
(void)pCtx;
return status;
@@ -1993,12 +2374,27 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->baTIDBitmap, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->baPolicy, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &tmp18__, pBuf, 0);
pDst->baBufferSize = tmp18__ >> 0 & 0xfff;
pDst->rsvd = tmp18__ >> 12 & 0xf;
@@ -2015,15 +2411,35 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->concat_tcid_bitmap = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->compression_tcid_bitmap = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->cb_state = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->rev_fcs_state = *pBuf;
(void)pCtx;
return status;
@@ -2041,9 +2457,19 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->chip_rev, pBuf, 0);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->card_type = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
@@ -2087,6 +2513,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->regulatoryClass = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
@@ -2110,6 +2541,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->reportingDetail = *pBuf;
(void)pCtx;
return status;
@@ -2144,9 +2580,19 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->reportingCondition = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->threshold = *pBuf;
(void)pCtx;
return status;
@@ -2161,6 +2607,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->measurementPilot = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
@@ -2179,6 +2630,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->maxBSSIDIndicator = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
@@ -2197,12 +2653,27 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->Identifier = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->resourceDescCount = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->statusCode, pBuf, 0);
(void)pCtx;
return status;
@@ -2217,6 +2688,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->resourceType = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
@@ -2240,6 +2716,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp19__ = *pBuf;
pBuf += 1;
ielen -= 1;
@@ -2251,6 +2732,11 @@
pDst->BeaconActive = tmp19__ >> 5 & 0x1;
pDst->BeaconTable = tmp19__ >> 6 & 0x1;
pDst->BeaconRepCond = tmp19__ >> 7 & 0x1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp20__ = *pBuf;
pBuf += 1;
ielen -= 1;
@@ -2262,6 +2748,11 @@
pDst->LCIAzimuth = tmp20__ >> 5 & 0x1;
pDst->TCMCapability = tmp20__ >> 6 & 0x1;
pDst->triggeredTCM = tmp20__ >> 7 & 0x1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp21__ = *pBuf;
pBuf += 1;
ielen -= 1;
@@ -2269,6 +2760,11 @@
pDst->RRMMIBEnabled = tmp21__ >> 1 & 0x1;
pDst->operatingChanMax = tmp21__ >> 2 & 0x7;
pDst->nonOperatinChanMax = tmp21__ >> 5 & 0x7;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp22__ = *pBuf;
pBuf += 1;
ielen -= 1;
@@ -2278,6 +2774,11 @@
pDst->RCPIMeasurement = tmp22__ >> 5 & 0x1;
pDst->RSNIMeasurement = tmp22__ >> 6 & 0x1;
pDst->BssAvgAccessDelay = tmp22__ >> 7 & 0x1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp23__ = *pBuf;
pDst->BSSAvailAdmission = tmp23__ >> 0 & 0x1;
pDst->AntennaInformation = tmp23__ >> 1 & 0x1;
@@ -2335,6 +2836,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &tmp24__, pBuf, 0);
pBuf += 2;
ielen -= 2;
@@ -2342,15 +2848,35 @@
pDst->tsid = tmp24__ >> 1 & 0xf;
pDst->direction = tmp24__ >> 5 & 0x3;
pDst->reserved = tmp24__ >> 7 & 0x1ff;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->service_start_time, pBuf, 0);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->service_interval, pBuf, 0);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->max_service_dur, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->spec_interval, pBuf, 0);
(void)pCtx;
return status;
@@ -2365,70 +2891,165 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->user_priority = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->classifier_type = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->classifier_mask = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
switch (pDst->classifier_type)
{
case 0:
+ if (unlikely(ielen < 6)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->info.EthParams.source, pBuf, 6);
pBuf += 6;
ielen -= (tANI_U8)6;
+ if (unlikely(ielen < 6)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->info.EthParams.dest, pBuf, 6);
pBuf += 6;
ielen -= (tANI_U8)6;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->info.EthParams.type, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
break;
case 1:
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->info.IpParams.version = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
switch (pDst->info.IpParams.version)
{
case 4:
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV4Params.source, pBuf, 4);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV4Params.dest, pBuf, 4);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->info.IpParams.params.IpV4Params.src_port, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->info.IpParams.params.IpV4Params.dest_port, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->info.IpParams.params.IpV4Params.DSCP = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->info.IpParams.params.IpV4Params.proto = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->info.IpParams.params.IpV4Params.reserved = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
break;
case 6:
+ if (unlikely(ielen < 16)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.source, pBuf, 16);
pBuf += 16;
ielen -= (tANI_U8)16;
+ if (unlikely(ielen < 16)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.dest, pBuf, 16);
pBuf += 16;
ielen -= (tANI_U8)16;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->info.IpParams.params.IpV6Params.src_port, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->info.IpParams.params.IpV6Params.dest_port, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 3)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.flow_label, pBuf, 3);
pBuf += 3;
ielen -= (tANI_U8)3;
@@ -2436,6 +3057,11 @@
}
break;
case 2:
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->info.Params8021dq.tag_type, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
@@ -2457,6 +3083,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->delay, pBuf, 0);
(void)pCtx;
return status;
@@ -2474,6 +3105,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &tmp25__, pBuf, 0);
pBuf += 2;
ielen -= 2;
@@ -2485,55 +3121,135 @@
pDst->psb = tmp25__ >> 10 & 0x1;
pDst->user_priority = tmp25__ >> 11 & 0x7;
pDst->tsinfo_ack_pol = tmp25__ >> 14 & 0x3;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp26__ = *pBuf;
pBuf += 1;
ielen -= 1;
pDst->schedule = tmp26__ >> 0 & 0x1;
pDst->unused = tmp26__ >> 1 & 0x7f;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &tmp27__, pBuf, 0);
pBuf += 2;
ielen -= 2;
pDst->size = tmp27__ >> 0 & 0x7fff;
pDst->fixed = tmp27__ >> 15 & 0x1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->max_msdu_size, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->min_service_int, pBuf, 0);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->max_service_int, pBuf, 0);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->inactivity_int, pBuf, 0);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->suspension_int, pBuf, 0);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->service_start_time, pBuf, 0);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->min_data_rate, pBuf, 0);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->mean_data_rate, pBuf, 0);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->peak_data_rate, pBuf, 0);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->burst_size, pBuf, 0);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->delay_bound, pBuf, 0);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->min_phy_rate, pBuf, 0);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->surplus_bw_allowance, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->medium_time, pBuf, 0);
(void)pCtx;
return status;
@@ -2549,6 +3265,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->version = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
@@ -2557,6 +3278,11 @@
pDst->present = 0;
return ( status | DOT11F_BAD_FIXED_VALUE );
}
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &tmp28__, pBuf, 0);
pBuf += 2;
ielen -= 2;
@@ -2564,15 +3290,35 @@
pDst->tsid = tmp28__ >> 1 & 0xf;
pDst->direction = tmp28__ >> 5 & 0x3;
pDst->reserved = tmp28__ >> 7 & 0x1ff;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->service_start_time, pBuf, 0);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->service_interval, pBuf, 0);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->max_service_dur, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->spec_interval, pBuf, 0);
(void)pCtx;
return status;
@@ -2587,6 +3333,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->version = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
@@ -2595,70 +3346,165 @@
pDst->present = 0;
return ( status | DOT11F_BAD_FIXED_VALUE );
}
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->user_priority = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->classifier_type = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->classifier_mask = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
switch (pDst->classifier_type)
{
case 0:
+ if (unlikely(ielen < 6)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->info.EthParams.source, pBuf, 6);
pBuf += 6;
ielen -= (tANI_U8)6;
+ if (unlikely(ielen < 6)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->info.EthParams.dest, pBuf, 6);
pBuf += 6;
ielen -= (tANI_U8)6;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->info.EthParams.type, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
break;
case 1:
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->info.IpParams.version = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
switch (pDst->info.IpParams.version)
{
case 4:
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV4Params.source, pBuf, 4);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV4Params.dest, pBuf, 4);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->info.IpParams.params.IpV4Params.src_port, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->info.IpParams.params.IpV4Params.dest_port, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->info.IpParams.params.IpV4Params.DSCP = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->info.IpParams.params.IpV4Params.proto = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->info.IpParams.params.IpV4Params.reserved = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
break;
case 6:
+ if (unlikely(ielen < 16)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.source, pBuf, 16);
pBuf += 16;
ielen -= (tANI_U8)16;
+ if (unlikely(ielen < 16)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.dest, pBuf, 16);
pBuf += 16;
ielen -= (tANI_U8)16;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->info.IpParams.params.IpV6Params.src_port, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->info.IpParams.params.IpV6Params.dest_port, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 3)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.flow_label, pBuf, 3);
pBuf += 3;
ielen -= (tANI_U8)3;
@@ -2666,6 +3512,11 @@
}
break;
case 2:
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->info.Params8021dq.tag_type, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
@@ -2684,6 +3535,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->version = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
@@ -2692,6 +3548,11 @@
pDst->present = 0;
return ( status | DOT11F_BAD_FIXED_VALUE );
}
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->processing = *pBuf;
(void)pCtx;
return status;
@@ -2706,6 +3567,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->version = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
@@ -2714,6 +3580,11 @@
pDst->present = 0;
return ( status | DOT11F_BAD_FIXED_VALUE );
}
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->delay, pBuf, 0);
(void)pCtx;
return status;
@@ -2731,6 +3602,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->version = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
@@ -2739,6 +3615,11 @@
pDst->present = 0;
return ( status | DOT11F_BAD_FIXED_VALUE );
}
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &tmp29__, pBuf, 0);
pBuf += 2;
ielen -= 2;
@@ -2750,55 +3631,135 @@
pDst->psb = tmp29__ >> 10 & 0x1;
pDst->user_priority = tmp29__ >> 11 & 0x7;
pDst->tsinfo_ack_pol = tmp29__ >> 14 & 0x3;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp30__ = *pBuf;
pBuf += 1;
ielen -= 1;
pDst->tsinfo_rsvd = tmp30__ >> 0 & 0x7f;
pDst->burst_size_defn = tmp30__ >> 7 & 0x1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &tmp31__, pBuf, 0);
pBuf += 2;
ielen -= 2;
pDst->size = tmp31__ >> 0 & 0x7fff;
pDst->fixed = tmp31__ >> 15 & 0x1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->max_msdu_size, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->min_service_int, pBuf, 0);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->max_service_int, pBuf, 0);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->inactivity_int, pBuf, 0);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->suspension_int, pBuf, 0);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->service_start_time, pBuf, 0);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->min_data_rate, pBuf, 0);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->mean_data_rate, pBuf, 0);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->peak_data_rate, pBuf, 0);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->burst_size, pBuf, 0);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->delay_bound, pBuf, 0);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->min_phy_rate, pBuf, 0);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->surplus_bw_allowance, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->medium_time, pBuf, 0);
(void)pCtx;
return status;
@@ -2813,6 +3774,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->assocId, pBuf, 0);
(void)pCtx;
return status;
@@ -2872,15 +3838,35 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->cfp_count = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->cfp_period = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->cfp_maxduration, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->cfp_durremaining, pBuf, 0);
(void)pCtx;
return status;
@@ -2915,12 +3901,27 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->switchMode = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->newChannel = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->switchCount = *pBuf;
(void)pCtx;
return status;
@@ -2935,6 +3936,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 3)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->country, pBuf, 3);
pBuf += 3;
ielen -= (tANI_U8)3;
@@ -2977,12 +3983,27 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->qos = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->reserved = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp32__ = *pBuf;
pBuf += 1;
ielen -= 1;
@@ -2990,14 +4011,29 @@
pDst->acbe_acm = tmp32__ >> 4 & 0x1;
pDst->acbe_aci = tmp32__ >> 5 & 0x3;
pDst->unused1 = tmp32__ >> 7 & 0x1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp33__ = *pBuf;
pBuf += 1;
ielen -= 1;
pDst->acbe_acwmin = tmp33__ >> 0 & 0xf;
pDst->acbe_acwmax = tmp33__ >> 4 & 0xf;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->acbe_txoplimit, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp34__ = *pBuf;
pBuf += 1;
ielen -= 1;
@@ -3005,14 +4041,29 @@
pDst->acbk_acm = tmp34__ >> 4 & 0x1;
pDst->acbk_aci = tmp34__ >> 5 & 0x3;
pDst->unused2 = tmp34__ >> 7 & 0x1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp35__ = *pBuf;
pBuf += 1;
ielen -= 1;
pDst->acbk_acwmin = tmp35__ >> 0 & 0xf;
pDst->acbk_acwmax = tmp35__ >> 4 & 0xf;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->acbk_txoplimit, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp36__ = *pBuf;
pBuf += 1;
ielen -= 1;
@@ -3020,14 +4071,29 @@
pDst->acvi_acm = tmp36__ >> 4 & 0x1;
pDst->acvi_aci = tmp36__ >> 5 & 0x3;
pDst->unused3 = tmp36__ >> 7 & 0x1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp37__ = *pBuf;
pBuf += 1;
ielen -= 1;
pDst->acvi_acwmin = tmp37__ >> 0 & 0xf;
pDst->acvi_acwmax = tmp37__ >> 4 & 0xf;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->acvi_txoplimit, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp38__ = *pBuf;
pBuf += 1;
ielen -= 1;
@@ -3035,11 +4101,21 @@
pDst->acvo_acm = tmp38__ >> 4 & 0x1;
pDst->acvo_aci = tmp38__ >> 5 & 0x3;
pDst->unused4 = tmp38__ >> 7 & 0x1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp39__ = *pBuf;
pBuf += 1;
ielen -= 1;
pDst->acvo_acwmin = tmp39__ >> 0 & 0xf;
pDst->acvo_acwmax = tmp39__ >> 4 & 0xf;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->acvo_txoplimit, pBuf, 0);
(void)pCtx;
return status;
@@ -3055,6 +4131,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp40__ = *pBuf;
pDst->non_erp_present = tmp40__ >> 0 & 0x1;
pDst->use_prot = tmp40__ >> 1 & 0x1;
@@ -3094,9 +4175,19 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->mgmt_state = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp41__ = *pBuf;
pDst->mbssid_mask = tmp41__ >> 0 & 0x7;
pDst->reserved = tmp41__ >> 3 & 0x1f;
@@ -3113,12 +4204,27 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->tsid = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->state = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->msmt_interval, pBuf, 0);
(void)pCtx;
return status;
@@ -3133,6 +4239,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->tsid = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
@@ -3156,9 +4267,19 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->power_limit = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->reserved = *pBuf;
(void)pCtx;
return status;
@@ -3173,6 +4294,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->version = *pBuf;
(void)pCtx;
return status;
@@ -3243,15 +4369,35 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->dwell_time, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->hop_set = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->hop_pattern = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->hop_index = *pBuf;
(void)pCtx;
return status;
@@ -3266,9 +4412,19 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->radix = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->nchannels = *pBuf;
(void)pCtx;
return status;
@@ -3283,15 +4439,35 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->flag = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->nsets = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->modulus = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->offset = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
@@ -3328,17 +4504,37 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &tmp42__, pBuf, 0);
pBuf += 2;
ielen -= 2;
pDst->reserved = tmp42__ >> 0 & 0xff;
pDst->IECount = tmp42__ >> 8 & 0xff;
+ if (unlikely(ielen < 16)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->MIC, pBuf, 16);
pBuf += 16;
ielen -= (tANI_U8)16;
+ if (unlikely(ielen < 32)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->Anonce, pBuf, 32);
pBuf += 32;
ielen -= (tANI_U8)32;
+ if (unlikely(ielen < 32)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->Snonce, pBuf, 32);
pBuf += 32;
ielen -= (tANI_U8)32;
@@ -3363,6 +4559,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp43__ = *pBuf;
pDst->infoRequest = tmp43__ >> 0 & 0x1;
pDst->fortyMHzIntolerant = tmp43__ >> 1 & 0x1;
@@ -3383,6 +4584,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->operatingClass = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
@@ -3411,6 +4617,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &tmp44__, pBuf, 0);
pBuf += 2;
ielen -= 2;
@@ -3428,15 +4639,30 @@
pDst->psmp = tmp44__ >> 13 & 0x1;
pDst->stbcControlFrame = tmp44__ >> 14 & 0x1;
pDst->lsigTXOPProtection = tmp44__ >> 15 & 0x1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp45__ = *pBuf;
pBuf += 1;
ielen -= 1;
pDst->maxRxAMPDUFactor = tmp45__ >> 0 & 0x3;
pDst->mpduDensity = tmp45__ >> 2 & 0x7;
pDst->reserved1 = tmp45__ >> 5 & 0x7;
+ if (unlikely(ielen < 16)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->supportedMCSSet, pBuf, 16);
pBuf += 16;
ielen -= (tANI_U8)16;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &tmp46__, pBuf, 0);
pBuf += 2;
ielen -= 2;
@@ -3445,6 +4671,11 @@
pDst->reserved2 = tmp46__ >> 3 & 0x1f;
pDst->mcsFeedback = tmp46__ >> 8 & 0x3;
pDst->reserved3 = tmp46__ >> 10 & 0x3f;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &tmp47__, pBuf, 0);
pBuf += 4;
ielen -= 4;
@@ -3464,6 +4695,11 @@
pDst->uncompressedSteeringMatrixBFAntennae = tmp47__ >> 21 & 0x3;
pDst->compressedSteeringMatrixBFAntennae = tmp47__ >> 23 & 0x3;
pDst->reserved4 = tmp47__ >> 25 & 0x7f;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp48__ = *pBuf;
pBuf += 1;
ielen -= 1;
@@ -3498,9 +4734,19 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->primaryChannel = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp49__ = *pBuf;
pBuf += 1;
ielen -= 1;
@@ -3509,6 +4755,11 @@
pDst->rifsMode = tmp49__ >> 3 & 0x1;
pDst->controlledAccessOnly = tmp49__ >> 4 & 0x1;
pDst->serviceIntervalGranularity = tmp49__ >> 5 & 0x7;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &tmp50__, pBuf, 0);
pBuf += 2;
ielen -= 2;
@@ -3517,6 +4768,11 @@
pDst->transmitBurstLimit = tmp50__ >> 3 & 0x1;
pDst->obssNonHTStaPresent = tmp50__ >> 4 & 0x1;
pDst->reserved = tmp50__ >> 5 & 0x7ff;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &tmp51__, pBuf, 0);
pBuf += 2;
ielen -= 2;
@@ -3527,6 +4783,11 @@
pDst->pcoActive = tmp51__ >> 10 & 0x1;
pDst->pcoPhase = tmp51__ >> 11 & 0x1;
pDst->reserved2 = tmp51__ >> 12 & 0xf;
+ if (unlikely(ielen < 16)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->basicMCSSet, pBuf, 16);
pBuf += 16;
ielen -= (tANI_U8)16;
@@ -3550,6 +4811,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->atim, pBuf, 0);
(void)pCtx;
return status;
@@ -3564,12 +4830,27 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 6)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->bssid, pBuf, 6);
pBuf += 6;
ielen -= (tANI_U8)6;
+ if (unlikely(ielen < 6)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->InitStaAddr, pBuf, 6);
pBuf += 6;
ielen -= (tANI_U8)6;
+ if (unlikely(ielen < 6)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->RespStaAddr, pBuf, 6);
(void)pCtx;
return status;
@@ -3596,9 +4877,19 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->token = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp52__ = *pBuf;
pBuf += 1;
ielen -= 1;
@@ -3606,6 +4897,11 @@
pDst->incapable = tmp52__ >> 1 & 0x1;
pDst->refused = tmp52__ >> 2 & 0x1;
pDst->unused = tmp52__ >> 3 & 0x1f;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->type = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
@@ -3618,15 +4914,35 @@
switch (pDst->type)
{
case 0:
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->report.Basic.channel = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 8)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohq(pCtx, &pDst->report.Basic.meas_start_time, pBuf, 0);
pBuf += 8;
ielen -= (tANI_U8)8;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->report.Basic.meas_duration, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp53__ = *pBuf;
pBuf += 1;
ielen -= 1;
@@ -3638,84 +4954,209 @@
pDst->report.Basic.unused = tmp53__ >> 5 & 0x7;
break;
case 1:
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->report.CCA.channel = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 8)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohq(pCtx, &pDst->report.CCA.meas_start_time, pBuf, 0);
pBuf += 8;
ielen -= (tANI_U8)8;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->report.CCA.meas_duration, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->report.CCA.cca_busy_fraction = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
break;
case 2:
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->report.RPIHistogram.channel = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 8)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohq(pCtx, &pDst->report.RPIHistogram.meas_start_time, pBuf, 0);
pBuf += 8;
ielen -= (tANI_U8)8;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->report.RPIHistogram.meas_duration, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->report.RPIHistogram.rpi0_density = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->report.RPIHistogram.rpi1_density = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->report.RPIHistogram.rpi2_density = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->report.RPIHistogram.rpi3_density = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->report.RPIHistogram.rpi4_density = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->report.RPIHistogram.rpi5_density = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->report.RPIHistogram.rpi6_density = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->report.RPIHistogram.rpi7_density = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
break;
case 5:
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->report.Beacon.regClass = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->report.Beacon.channel = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 8)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohq(pCtx, &pDst->report.Beacon.meas_start_time, pBuf, 0);
pBuf += 8;
ielen -= (tANI_U8)8;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->report.Beacon.meas_duration, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp54__ = *pBuf;
pBuf += 1;
ielen -= 1;
pDst->report.Beacon.condensed_PHY = tmp54__ >> 0 & 0x7f;
pDst->report.Beacon.reported_frame_type = tmp54__ >> 7 & 0x1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->report.Beacon.RCPI = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->report.Beacon.RSNI = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 6)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->report.Beacon.BSSID, pBuf, 6);
pBuf += 6;
ielen -= (tANI_U8)6;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->report.Beacon.antenna_id = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->report.Beacon.parent_TSF, pBuf, 0);
pBuf += 4;
ielen -= (tANI_U8)4;
@@ -3756,9 +5197,19 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->measurement_token = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp55__ = *pBuf;
pBuf += 1;
ielen -= 1;
@@ -3768,60 +5219,140 @@
pDst->report = tmp55__ >> 3 & 0x1;
pDst->durationMandatory = tmp55__ >> 4 & 0x1;
pDst->unused = tmp55__ >> 5 & 0x7;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->measurement_type = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
switch (pDst->measurement_type)
{
case 0:
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->measurement_request.Basic.channel_no = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 8)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->measurement_request.Basic.meas_start_time, pBuf, 8);
pBuf += 8;
ielen -= (tANI_U8)8;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->measurement_request.Basic.meas_duration, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
break;
case 1:
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->measurement_request.CCA.channel_no = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 8)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->measurement_request.CCA.meas_start_time, pBuf, 8);
pBuf += 8;
ielen -= (tANI_U8)8;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->measurement_request.CCA.meas_duration, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
break;
case 2:
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->measurement_request.RPIHistogram.channel_no = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 8)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->measurement_request.RPIHistogram.meas_start_time, pBuf, 8);
pBuf += 8;
ielen -= (tANI_U8)8;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->measurement_request.RPIHistogram.meas_duration, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
break;
case 5:
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->measurement_request.Beacon.regClass = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->measurement_request.Beacon.channel = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->measurement_request.Beacon.randomization, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->measurement_request.Beacon.meas_duration, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->measurement_request.Beacon.meas_mode = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 6)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->measurement_request.Beacon.BSSID, pBuf, 6);
pBuf += 6;
ielen -= (tANI_U8)6;
@@ -3848,9 +5379,19 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->MDID, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp56__ = *pBuf;
pDst->overDSCap = tmp56__ >> 0 & 0x1;
pDst->resourceReqCap = tmp56__ >> 1 & 0x1;
@@ -3883,9 +5424,19 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 6)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->bssid, pBuf, 6);
pBuf += 6;
ielen -= (tANI_U8)6;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp57__ = *pBuf;
pBuf += 1;
ielen -= 1;
@@ -3896,6 +5447,11 @@
pDst->QosCap = tmp57__ >> 5 & 0x1;
pDst->apsd = tmp57__ >> 6 & 0x1;
pDst->rrm = tmp57__ >> 7 & 0x1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp58__ = *pBuf;
pBuf += 1;
ielen -= 1;
@@ -3903,15 +5459,35 @@
pDst->ImmBA = tmp58__ >> 1 & 0x1;
pDst->MobilityDomain = tmp58__ >> 2 & 0x1;
pDst->reserved = tmp58__ >> 3 & 0x1f;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->reserved1, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->regulatoryClass = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->channel = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->PhyType = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
@@ -3935,24 +5511,59 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->obssScanPassiveDwell, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->obssScanActiveDwell, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->bssChannelWidthTriggerScanInterval, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->obssScanPassiveTotalPerChannel, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->obssScanActiveTotalPerChannel, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->bssWidthChannelTransitionDelayFactor, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->obssScanActivityThreshold, pBuf, 0);
(void)pCtx;
return status;
@@ -3968,6 +5579,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp59__ = *pBuf;
pDst->chanWidth = tmp59__ >> 0 & 0x3;
pDst->reserved = tmp59__ >> 2 & 0x3;
@@ -4399,9 +6015,19 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->tid = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->sequence_control, pBuf, 0);
(void)pCtx;
return status;
@@ -4417,6 +6043,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp60__ = *pBuf;
pDst->ac_bk_traffic_aval = tmp60__ >> 0 & 0x1;
pDst->ac_be_traffic_aval = tmp60__ >> 1 & 0x1;
@@ -4436,9 +6067,19 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->minTxPower = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->maxTxPower = *pBuf;
(void)pCtx;
return status;
@@ -4453,6 +6094,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->localPowerConstraints = *pBuf;
(void)pCtx;
return status;
@@ -4467,12 +6113,27 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->stacount, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->chautil = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->avail, pBuf, 0);
(void)pCtx;
return status;
@@ -4488,6 +6149,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp61__ = *pBuf;
pDst->count = tmp61__ >> 0 & 0xf;
pDst->qack = tmp61__ >> 4 & 0x1;
@@ -4508,6 +6174,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp62__ = *pBuf;
pDst->acvo_uapsd = tmp62__ >> 0 & 0x1;
pDst->acvi_uapsd = tmp62__ >> 1 & 0x1;
@@ -4549,15 +6220,35 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->count = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->period = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->duration, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->offset, pBuf, 0);
(void)pCtx;
return status;
@@ -4572,6 +6263,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->rcpi = *pBuf;
(void)pCtx;
return status;
@@ -4626,6 +6322,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->version, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
@@ -4634,6 +6335,11 @@
pDst->present = 0;
return ( status | DOT11F_BAD_FIXED_VALUE );
}
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->gp_cipher_suite, pBuf, 4);
pBuf += 4;
ielen -= (tANI_U8)4;
@@ -4646,10 +6352,20 @@
}
else
{
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->pwise_cipher_suite_count, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
}
+ if (unlikely(ielen < pDst->pwise_cipher_suite_count * 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
if (pDst->pwise_cipher_suite_count > 4){
pDst->present = 0;
return DOT11F_SKIPPED_BAD_IE;
@@ -4666,10 +6382,20 @@
}
else
{
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->akm_suite_count, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
}
+ if (unlikely(ielen < pDst->akm_suite_count * 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
if (pDst->akm_suite_count > 4){
pDst->present = 0;
return DOT11F_SKIPPED_BAD_IE;
@@ -4685,6 +6411,11 @@
}
else
{
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->RSN_Cap, pBuf, 2);
pBuf += 2;
ielen -= (tANI_U8)2;
@@ -4696,10 +6427,20 @@
}
else
{
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->pmkid_count, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
}
+ if (unlikely(ielen < pDst->pmkid_count * 16)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
if (pDst->pmkid_count > 4){
pDst->present = 0;
return DOT11F_SKIPPED_BAD_IE;
@@ -4714,6 +6455,11 @@
}
else
{
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->gp_mgmt_cipher_suite, pBuf, 4);
}
(void)pCtx;
@@ -4729,6 +6475,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->rsni = *pBuf;
(void)pCtx;
return status;
@@ -4831,12 +6582,27 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->dtim_count = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->dtim_period = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->bmpctl = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
@@ -4860,9 +6626,19 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->tx_power = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->link_margin = *pBuf;
(void)pCtx;
return status;
@@ -4890,9 +6666,19 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->timeoutType = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &pDst->timeoutValue, pBuf, 0);
(void)pCtx;
return status;
@@ -4910,6 +6696,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohl(pCtx, &tmp63__, pBuf, 0);
pBuf += 4;
ielen -= 4;
@@ -4933,17 +6724,37 @@
pDst->rxAntPattern = tmp63__ >> 28 & 0x1;
pDst->txAntPattern = tmp63__ >> 29 & 0x1;
pDst->reserved1 = tmp63__ >> 30 & 0x3;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->rxMCSMap, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &tmp64__, pBuf, 0);
pBuf += 2;
ielen -= 2;
pDst->rxHighSupDataRate = tmp64__ >> 0 & 0x1fff;
pDst->reserved2 = tmp64__ >> 13 & 0x7;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->txMCSMap, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &tmp65__, pBuf, 0);
pDst->txSupDataRate = tmp65__ >> 0 & 0x1fff;
pDst->reserved3 = tmp65__ >> 13 & 0x7;
@@ -4960,18 +6771,43 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->muMIMOCapStaCount = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->ssUnderUtil = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->FortyMHzUtil = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->EightyMHzUtil = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->OneSixtyMHzUtil = *pBuf;
(void)pCtx;
return status;
@@ -4986,15 +6822,35 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->chanWidth = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->chanCenterFreqSeg1 = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->chanCenterFreqSeg2 = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->basicMCSSet, pBuf, 0);
(void)pCtx;
return status;
@@ -5010,6 +6866,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->version, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
@@ -5018,9 +6879,19 @@
pDst->present = 0;
return ( status | DOT11F_BAD_FIXED_VALUE );
}
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->akm_suite_count, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < pDst->akm_suite_count * 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
if (pDst->akm_suite_count > 4){
pDst->present = 0;
return DOT11F_SKIPPED_BAD_IE;
@@ -5029,9 +6900,19 @@
DOT11F_MEMCPY(pCtx, pDst->akm_suites, pBuf, ( pDst->akm_suite_count * 4 ) );
pBuf += ( pDst->akm_suite_count * 4 );
ielen -= ( pDst->akm_suite_count * 4 );
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->unicast_cipher_suite_count, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < pDst->unicast_cipher_suite_count * 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
if (pDst->unicast_cipher_suite_count > 4){
pDst->present = 0;
return DOT11F_SKIPPED_BAD_IE;
@@ -5040,9 +6921,19 @@
DOT11F_MEMCPY(pCtx, pDst->unicast_cipher_suites, pBuf, ( pDst->unicast_cipher_suite_count * 4 ) );
pBuf += ( pDst->unicast_cipher_suite_count * 4 );
ielen -= ( pDst->unicast_cipher_suite_count * 4 );
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->multicast_cipher_suite, pBuf, 4);
pBuf += 4;
ielen -= (tANI_U8)4;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &tmp66__, pBuf, 0);
pBuf += 2;
ielen -= 2;
@@ -5055,10 +6946,20 @@
}
else
{
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->bkid_count, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
}
+ if (unlikely(ielen < pDst->bkid_count * 16)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
if (pDst->bkid_count > 4){
pDst->present = 0;
return DOT11F_SKIPPED_BAD_IE;
@@ -5098,9 +6999,19 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->txPower = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->linkMargin = *pBuf;
(void)pCtx;
return status;
@@ -5136,6 +7047,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->version = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
@@ -5144,6 +7060,11 @@
pDst->present = 0;
return ( status | DOT11F_BAD_FIXED_VALUE );
}
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp67__ = *pBuf;
pDst->reserved = tmp67__ >> 0 & 0xf;
pDst->qack = tmp67__ >> 4 & 0x1;
@@ -5164,9 +7085,19 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->version = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp68__ = *pBuf;
pDst->param_set_count = tmp68__ >> 0 & 0xf;
pDst->reserved = tmp68__ >> 4 & 0x7;
@@ -5185,9 +7116,19 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->version = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp69__ = *pBuf;
pDst->acvo_uapsd = tmp69__ >> 0 & 0x1;
pDst->acvi_uapsd = tmp69__ >> 1 & 0x1;
@@ -5217,6 +7158,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->version = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
@@ -5225,12 +7171,27 @@
pDst->present = 0;
return ( status | DOT11F_BAD_FIXED_VALUE );
}
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->qosInfo = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->reserved2 = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp70__ = *pBuf;
pBuf += 1;
ielen -= 1;
@@ -5238,14 +7199,29 @@
pDst->acbe_acm = tmp70__ >> 4 & 0x1;
pDst->acbe_aci = tmp70__ >> 5 & 0x3;
pDst->unused1 = tmp70__ >> 7 & 0x1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp71__ = *pBuf;
pBuf += 1;
ielen -= 1;
pDst->acbe_acwmin = tmp71__ >> 0 & 0xf;
pDst->acbe_acwmax = tmp71__ >> 4 & 0xf;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->acbe_txoplimit, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp72__ = *pBuf;
pBuf += 1;
ielen -= 1;
@@ -5253,14 +7229,29 @@
pDst->acbk_acm = tmp72__ >> 4 & 0x1;
pDst->acbk_aci = tmp72__ >> 5 & 0x3;
pDst->unused2 = tmp72__ >> 7 & 0x1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp73__ = *pBuf;
pBuf += 1;
ielen -= 1;
pDst->acbk_acwmin = tmp73__ >> 0 & 0xf;
pDst->acbk_acwmax = tmp73__ >> 4 & 0xf;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->acbk_txoplimit, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp74__ = *pBuf;
pBuf += 1;
ielen -= 1;
@@ -5268,14 +7259,29 @@
pDst->acvi_acm = tmp74__ >> 4 & 0x1;
pDst->acvi_aci = tmp74__ >> 5 & 0x3;
pDst->unused3 = tmp74__ >> 7 & 0x1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp75__ = *pBuf;
pBuf += 1;
ielen -= 1;
pDst->acvi_acwmin = tmp75__ >> 0 & 0xf;
pDst->acvi_acwmax = tmp75__ >> 4 & 0xf;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->acvi_txoplimit, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp76__ = *pBuf;
pBuf += 1;
ielen -= 1;
@@ -5283,11 +7289,21 @@
pDst->acvo_acm = tmp76__ >> 4 & 0x1;
pDst->acvo_aci = tmp76__ >> 5 & 0x3;
pDst->unused4 = tmp76__ >> 7 & 0x1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp77__ = *pBuf;
pBuf += 1;
ielen -= 1;
pDst->acvo_acwmin = tmp77__ >> 0 & 0xf;
pDst->acvo_acwmax = tmp77__ >> 4 & 0xf;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->acvo_txoplimit, pBuf, 0);
(void)pCtx;
return status;
@@ -5302,6 +7318,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->version, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
@@ -5320,6 +7341,11 @@
else
{
pDst->multicast_cipher_present = 1U;
+ if (unlikely(ielen < 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
DOT11F_MEMCPY(pCtx, pDst->multicast_cipher, pBuf, 4);
pBuf += 4;
ielen -= (tANI_U8)4;
@@ -5332,10 +7358,20 @@
}
else
{
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->unicast_cipher_count, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
}
+ if (unlikely(ielen < pDst->unicast_cipher_count * 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
if (pDst->unicast_cipher_count > 4){
pDst->present = 0;
return DOT11F_SKIPPED_BAD_IE;
@@ -5351,10 +7387,20 @@
}
else
{
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->auth_suite_count, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
}
+ if (unlikely(ielen < pDst->auth_suite_count * 4)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
if (pDst->auth_suite_count > 4){
pDst->present = 0;
return DOT11F_SKIPPED_BAD_IE;
@@ -5369,6 +7415,11 @@
}
else
{
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->caps, pBuf, 0);
}
(void)pCtx;
@@ -5442,12 +7493,27 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->newChanWidth = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->newCenterChanFreq0 = *pBuf;
pBuf += 1;
ielen -= (tANI_U8)1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
pDst->newCenterChanFreq1 = *pBuf;
(void)pCtx;
return status;
@@ -5662,6 +7728,11 @@
(void) pBuf; (void)ielen; /* Shutup the compiler */
if (pDst->present) status = DOT11F_DUPLICATE_IE;
pDst->present = 1;
+ if (unlikely(ielen < 1)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
tmp78__ = *pBuf;
pBuf += 1;
ielen -= 1;
@@ -5678,11 +7749,21 @@
switch (pDst->hs_id_present)
{
case 1:
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->hs_id.pps_mo.pps_mo_id, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
break;
case 2:
+ if (unlikely(ielen < 2)) {
+ pDst->present = 0;
+ return DOT11F_INCOMPLETE_IE;
+ }
+
framesntohs(pCtx, &pDst->hs_id.anqp_domain.anqp_domain_id, pBuf, 0);
pBuf += 2;
ielen -= (tANI_U8)2;
@@ -21864,11 +23945,8 @@
}
else break;
*pnNeeded += ( pIe->akm_suite_count * 4 );
- if ( pIe->RSN_Cap )
- {
- *pnNeeded += 2;
- }
- else break;
+ /* RSN_Cap */
+ *pnNeeded += 2;
if ( pIe->pmkid_count )
{
*pnNeeded += 2;
@@ -23971,6 +26049,9 @@
tmp86__ = 0U;
tmp86__ |= ( pSrc->minor << 0 );
tmp86__ |= ( pSrc->major << 4 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp86__;
*pnConsumed += 1;
pBuf += 1;
@@ -25192,6 +27273,9 @@
tmp87__ = 0U;
tmp87__ |= ( pSrc->minor << 0 );
tmp87__ |= ( pSrc->major << 4 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp87__;
*pnConsumed += 1;
pBuf += 1;
@@ -25410,6 +27494,9 @@
tmp88__ = 0U;
tmp88__ |= ( pSrc->keyId << 0 );
tmp88__ |= ( pSrc->reserved << 2 );
+ if (unlikely(nBuf < 2))
+ return DOT11F_INCOMPLETE_IE;
+
frameshtons(pCtx, pBuf, tmp88__, 0);
*pnConsumed += 2;
pBuf += 2;
@@ -25733,6 +27820,9 @@
tmp89__ |= ( pSrc->acbe_acm << 4 );
tmp89__ |= ( pSrc->acbe_aci << 5 );
tmp89__ |= ( pSrc->unused1 << 7 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp89__;
*pnConsumed += 1;
pBuf += 1;
@@ -25740,6 +27830,9 @@
tmp90__ = 0U;
tmp90__ |= ( pSrc->acbe_min << 0 );
tmp90__ |= ( pSrc->acbe_max << 4 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp90__;
*pnConsumed += 1;
pBuf += 1;
@@ -25752,6 +27845,9 @@
tmp91__ |= ( pSrc->acbk_acm << 4 );
tmp91__ |= ( pSrc->acbk_aci << 5 );
tmp91__ |= ( pSrc->unused2 << 7 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp91__;
*pnConsumed += 1;
pBuf += 1;
@@ -25759,6 +27855,9 @@
tmp92__ = 0U;
tmp92__ |= ( pSrc->acbk_min << 0 );
tmp92__ |= ( pSrc->acbk_max << 4 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp92__;
*pnConsumed += 1;
pBuf += 1;
@@ -25771,6 +27870,9 @@
tmp93__ |= ( pSrc->acvi_acm << 4 );
tmp93__ |= ( pSrc->acvi_aci << 5 );
tmp93__ |= ( pSrc->unused3 << 7 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp93__;
*pnConsumed += 1;
pBuf += 1;
@@ -25778,6 +27880,9 @@
tmp94__ = 0U;
tmp94__ |= ( pSrc->acvi_min << 0 );
tmp94__ |= ( pSrc->acvi_max << 4 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp94__;
*pnConsumed += 1;
pBuf += 1;
@@ -25790,6 +27895,9 @@
tmp95__ |= ( pSrc->acvo_acm << 4 );
tmp95__ |= ( pSrc->acvo_aci << 5 );
tmp95__ |= ( pSrc->unused4 << 7 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp95__;
*pnConsumed += 1;
pBuf += 1;
@@ -25797,6 +27905,9 @@
tmp96__ = 0U;
tmp96__ |= ( pSrc->acvo_min << 0 );
tmp96__ |= ( pSrc->acvo_max << 4 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp96__;
*pnConsumed += 1;
pBuf += 1;
@@ -26003,6 +28114,9 @@
tmp97__ = 0U;
tmp97__ |= ( pSrc->baBufferSize << 0 );
tmp97__ |= ( pSrc->rsvd << 12 );
+ if (unlikely(nBuf < 2))
+ return DOT11F_INCOMPLETE_IE;
+
frameshtons(pCtx, pBuf, tmp97__, 0);
*pnConsumed += 2;
// fieldsEndFlag = 1
@@ -26444,6 +28558,9 @@
tmp98__ |= ( pSrc->BeaconActive << 5 );
tmp98__ |= ( pSrc->BeaconTable << 6 );
tmp98__ |= ( pSrc->BeaconRepCond << 7 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp98__;
*pnConsumed += 1;
pBuf += 1;
@@ -26457,6 +28574,9 @@
tmp99__ |= ( pSrc->LCIAzimuth << 5 );
tmp99__ |= ( pSrc->TCMCapability << 6 );
tmp99__ |= ( pSrc->triggeredTCM << 7 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp99__;
*pnConsumed += 1;
pBuf += 1;
@@ -26466,6 +28586,9 @@
tmp100__ |= ( pSrc->RRMMIBEnabled << 1 );
tmp100__ |= ( pSrc->operatingChanMax << 2 );
tmp100__ |= ( pSrc->nonOperatinChanMax << 5 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp100__;
*pnConsumed += 1;
pBuf += 1;
@@ -26477,6 +28600,9 @@
tmp101__ |= ( pSrc->RCPIMeasurement << 5 );
tmp101__ |= ( pSrc->RSNIMeasurement << 6 );
tmp101__ |= ( pSrc->BssAvgAccessDelay << 7 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp101__;
*pnConsumed += 1;
pBuf += 1;
@@ -26485,6 +28611,9 @@
tmp102__ |= ( pSrc->BSSAvailAdmission << 0 );
tmp102__ |= ( pSrc->AntennaInformation << 1 );
tmp102__ |= ( pSrc->reserved << 2 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp102__;
*pnConsumed += 1;
// fieldsEndFlag = 1
@@ -26582,6 +28711,9 @@
tmp103__ |= ( pSrc->tsid << 1 );
tmp103__ |= ( pSrc->direction << 5 );
tmp103__ |= ( pSrc->reserved << 7 );
+ if (unlikely(nBuf < 2))
+ return DOT11F_INCOMPLETE_IE;
+
frameshtons(pCtx, pBuf, tmp103__, 0);
*pnConsumed += 2;
pBuf += 2;
@@ -26802,6 +28934,9 @@
tmp104__ |= ( pSrc->psb << 10 );
tmp104__ |= ( pSrc->user_priority << 11 );
tmp104__ |= ( pSrc->tsinfo_ack_pol << 14 );
+ if (unlikely(nBuf < 2))
+ return DOT11F_INCOMPLETE_IE;
+
frameshtons(pCtx, pBuf, tmp104__, 0);
*pnConsumed += 2;
pBuf += 2;
@@ -26809,6 +28944,9 @@
tmp105__ = 0U;
tmp105__ |= ( pSrc->schedule << 0 );
tmp105__ |= ( pSrc->unused << 1 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp105__;
*pnConsumed += 1;
pBuf += 1;
@@ -26816,6 +28954,9 @@
tmp106__ = 0U;
tmp106__ |= ( pSrc->size << 0 );
tmp106__ |= ( pSrc->fixed << 15 );
+ if (unlikely(nBuf < 2))
+ return DOT11F_INCOMPLETE_IE;
+
frameshtons(pCtx, pBuf, tmp106__, 0);
*pnConsumed += 2;
pBuf += 2;
@@ -26908,6 +29049,9 @@
tmp107__ |= ( pSrc->tsid << 1 );
tmp107__ |= ( pSrc->direction << 5 );
tmp107__ |= ( pSrc->reserved << 7 );
+ if (unlikely(nBuf < 2))
+ return DOT11F_INCOMPLETE_IE;
+
frameshtons(pCtx, pBuf, tmp107__, 0);
*pnConsumed += 2;
pBuf += 2;
@@ -27180,6 +29324,9 @@
tmp108__ |= ( pSrc->psb << 10 );
tmp108__ |= ( pSrc->user_priority << 11 );
tmp108__ |= ( pSrc->tsinfo_ack_pol << 14 );
+ if (unlikely(nBuf < 2))
+ return DOT11F_INCOMPLETE_IE;
+
frameshtons(pCtx, pBuf, tmp108__, 0);
*pnConsumed += 2;
pBuf += 2;
@@ -27187,6 +29334,9 @@
tmp109__ = 0U;
tmp109__ |= ( pSrc->tsinfo_rsvd << 0 );
tmp109__ |= ( pSrc->burst_size_defn << 7 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp109__;
*pnConsumed += 1;
pBuf += 1;
@@ -27194,6 +29344,9 @@
tmp110__ = 0U;
tmp110__ |= ( pSrc->size << 0 );
tmp110__ |= ( pSrc->fixed << 15 );
+ if (unlikely(nBuf < 2))
+ return DOT11F_INCOMPLETE_IE;
+
frameshtons(pCtx, pBuf, tmp110__, 0);
*pnConsumed += 2;
pBuf += 2;
@@ -27531,6 +29684,9 @@
tmp111__ |= ( pSrc->acbe_acm << 4 );
tmp111__ |= ( pSrc->acbe_aci << 5 );
tmp111__ |= ( pSrc->unused1 << 7 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp111__;
*pnConsumed += 1;
pBuf += 1;
@@ -27538,6 +29694,9 @@
tmp112__ = 0U;
tmp112__ |= ( pSrc->acbe_acwmin << 0 );
tmp112__ |= ( pSrc->acbe_acwmax << 4 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp112__;
*pnConsumed += 1;
pBuf += 1;
@@ -27550,6 +29709,9 @@
tmp113__ |= ( pSrc->acbk_acm << 4 );
tmp113__ |= ( pSrc->acbk_aci << 5 );
tmp113__ |= ( pSrc->unused2 << 7 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp113__;
*pnConsumed += 1;
pBuf += 1;
@@ -27557,6 +29719,9 @@
tmp114__ = 0U;
tmp114__ |= ( pSrc->acbk_acwmin << 0 );
tmp114__ |= ( pSrc->acbk_acwmax << 4 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp114__;
*pnConsumed += 1;
pBuf += 1;
@@ -27569,6 +29734,9 @@
tmp115__ |= ( pSrc->acvi_acm << 4 );
tmp115__ |= ( pSrc->acvi_aci << 5 );
tmp115__ |= ( pSrc->unused3 << 7 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp115__;
*pnConsumed += 1;
pBuf += 1;
@@ -27576,6 +29744,9 @@
tmp116__ = 0U;
tmp116__ |= ( pSrc->acvi_acwmin << 0 );
tmp116__ |= ( pSrc->acvi_acwmax << 4 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp116__;
*pnConsumed += 1;
pBuf += 1;
@@ -27588,6 +29759,9 @@
tmp117__ |= ( pSrc->acvo_acm << 4 );
tmp117__ |= ( pSrc->acvo_aci << 5 );
tmp117__ |= ( pSrc->unused4 << 7 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp117__;
*pnConsumed += 1;
pBuf += 1;
@@ -27595,6 +29769,9 @@
tmp118__ = 0U;
tmp118__ |= ( pSrc->acvo_acwmin << 0 );
tmp118__ |= ( pSrc->acvo_acwmax << 4 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp118__;
*pnConsumed += 1;
pBuf += 1;
@@ -27635,6 +29812,9 @@
tmp119__ |= ( pSrc->use_prot << 1 );
tmp119__ |= ( pSrc->barker_preamble << 2 );
tmp119__ |= ( pSrc->unused << 3 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp119__;
*pnConsumed += 1;
// fieldsEndFlag = 1
@@ -27719,6 +29899,9 @@
tmp120__ = 0U;
tmp120__ |= ( pSrc->mbssid_mask << 0 );
tmp120__ |= ( pSrc->reserved << 3 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp120__;
*pnConsumed += 1;
// fieldsEndFlag = 1
@@ -28124,6 +30307,9 @@
tmp121__ = 0U;
tmp121__ |= ( pSrc->reserved << 0 );
tmp121__ |= ( pSrc->IECount << 8 );
+ if (unlikely(nBuf < 2))
+ return DOT11F_INCOMPLETE_IE;
+
frameshtons(pCtx, pBuf, tmp121__, 0);
*pnConsumed += 2;
pBuf += 2;
@@ -28179,6 +30365,9 @@
tmp122__ |= ( pSrc->obssScanExemptionReq << 3 );
tmp122__ |= ( pSrc->obssScanExemptionGrant << 4 );
tmp122__ |= ( pSrc->unused << 5 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp122__;
*pnConsumed += 1;
// fieldsEndFlag = 1
@@ -28263,6 +30452,9 @@
tmp123__ |= ( pSrc->psmp << 13 );
tmp123__ |= ( pSrc->stbcControlFrame << 14 );
tmp123__ |= ( pSrc->lsigTXOPProtection << 15 );
+ if (unlikely(nBuf < 2))
+ return DOT11F_INCOMPLETE_IE;
+
frameshtons(pCtx, pBuf, tmp123__, 0);
*pnConsumed += 2;
pBuf += 2;
@@ -28271,6 +30463,9 @@
tmp124__ |= ( pSrc->maxRxAMPDUFactor << 0 );
tmp124__ |= ( pSrc->mpduDensity << 2 );
tmp124__ |= ( pSrc->reserved1 << 5 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp124__;
*pnConsumed += 1;
pBuf += 1;
@@ -28284,6 +30479,9 @@
tmp125__ |= ( pSrc->reserved2 << 3 );
tmp125__ |= ( pSrc->mcsFeedback << 8 );
tmp125__ |= ( pSrc->reserved3 << 10 );
+ if (unlikely(nBuf < 2))
+ return DOT11F_INCOMPLETE_IE;
+
frameshtons(pCtx, pBuf, tmp125__, 0);
*pnConsumed += 2;
pBuf += 2;
@@ -28305,6 +30503,9 @@
tmp126__ |= ( pSrc->uncompressedSteeringMatrixBFAntennae << 21 );
tmp126__ |= ( pSrc->compressedSteeringMatrixBFAntennae << 23 );
tmp126__ |= ( pSrc->reserved4 << 25 );
+ if (unlikely(nBuf < 4))
+ return DOT11F_INCOMPLETE_IE;
+
frameshtonl(pCtx, pBuf, tmp126__, 0);
*pnConsumed += 4;
pBuf += 4;
@@ -28318,6 +30519,9 @@
tmp127__ |= ( pSrc->rxAS << 5 );
tmp127__ |= ( pSrc->txSoundingPPDUs << 6 );
tmp127__ |= ( pSrc->reserved5 << 7 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp127__;
*pnConsumed += 1;
pBuf += 1;
@@ -28364,6 +30568,9 @@
tmp128__ |= ( pSrc->rifsMode << 3 );
tmp128__ |= ( pSrc->controlledAccessOnly << 4 );
tmp128__ |= ( pSrc->serviceIntervalGranularity << 5 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp128__;
*pnConsumed += 1;
pBuf += 1;
@@ -28374,6 +30581,9 @@
tmp129__ |= ( pSrc->transmitBurstLimit << 3 );
tmp129__ |= ( pSrc->obssNonHTStaPresent << 4 );
tmp129__ |= ( pSrc->reserved << 5 );
+ if (unlikely(nBuf < 2))
+ return DOT11F_INCOMPLETE_IE;
+
frameshtons(pCtx, pBuf, tmp129__, 0);
*pnConsumed += 2;
pBuf += 2;
@@ -28386,6 +30596,9 @@
tmp130__ |= ( pSrc->pcoActive << 10 );
tmp130__ |= ( pSrc->pcoPhase << 11 );
tmp130__ |= ( pSrc->reserved2 << 12 );
+ if (unlikely(nBuf < 2))
+ return DOT11F_INCOMPLETE_IE;
+
frameshtons(pCtx, pBuf, tmp130__, 0);
*pnConsumed += 2;
pBuf += 2;
@@ -28502,6 +30715,9 @@
tmp131__ |= ( pSrc->incapable << 1 );
tmp131__ |= ( pSrc->refused << 2 );
tmp131__ |= ( pSrc->unused << 3 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp131__;
*pnConsumed += 1;
pBuf += 1;
@@ -28529,6 +30745,9 @@
tmp132__ |= ( pSrc->report.Basic.rader << 3 );
tmp132__ |= ( pSrc->report.Basic.unmeasured << 4 );
tmp132__ |= ( pSrc->report.Basic.unused << 5 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp132__;
*pnConsumed += 1;
// fieldsEndFlag = 1
@@ -28599,6 +30818,9 @@
tmp133__ = 0U;
tmp133__ |= ( pSrc->report.Beacon.condensed_PHY << 0 );
tmp133__ |= ( pSrc->report.Beacon.reported_frame_type << 7 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp133__;
*pnConsumed += 1;
pBuf += 1;
@@ -28669,6 +30891,9 @@
tmp134__ |= ( pSrc->report << 3 );
tmp134__ |= ( pSrc->durationMandatory << 4 );
tmp134__ |= ( pSrc->unused << 5 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp134__;
*pnConsumed += 1;
pBuf += 1;
@@ -28774,6 +30999,9 @@
tmp135__ |= ( pSrc->overDSCap << 0 );
tmp135__ |= ( pSrc->resourceReqCap << 1 );
tmp135__ |= ( pSrc->reserved << 2 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp135__;
*pnConsumed += 1;
// fieldsEndFlag = 1
@@ -28820,6 +31048,9 @@
tmp136__ |= ( pSrc->QosCap << 5 );
tmp136__ |= ( pSrc->apsd << 6 );
tmp136__ |= ( pSrc->rrm << 7 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp136__;
*pnConsumed += 1;
pBuf += 1;
@@ -28829,6 +31060,9 @@
tmp137__ |= ( pSrc->ImmBA << 1 );
tmp137__ |= ( pSrc->MobilityDomain << 2 );
tmp137__ |= ( pSrc->reserved << 3 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp137__;
*pnConsumed += 1;
pBuf += 1;
@@ -28933,6 +31167,9 @@
tmp138__ |= ( pSrc->reserved << 2 );
tmp138__ |= ( pSrc->rxNSS << 4 );
tmp138__ |= ( pSrc->rxNSSType << 7 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp138__;
*pnConsumed += 1;
// fieldsEndFlag = 1
@@ -29902,6 +32139,9 @@
tmp139__ |= ( pSrc->ac_vi_traffic_aval << 2 );
tmp139__ |= ( pSrc->ac_vo_traffic_aval << 3 );
tmp139__ |= ( pSrc->reserved << 4 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp139__;
*pnConsumed += 1;
// fieldsEndFlag = 1
@@ -30039,6 +32279,9 @@
tmp140__ |= ( pSrc->qreq << 5 );
tmp140__ |= ( pSrc->txopreq << 6 );
tmp140__ |= ( pSrc->reserved << 7 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp140__;
*pnConsumed += 1;
// fieldsEndFlag = 1
@@ -30079,6 +32322,9 @@
tmp141__ |= ( pSrc->qack << 4 );
tmp141__ |= ( pSrc->max_sp_length << 5 );
tmp141__ |= ( pSrc->more_data_ack << 7 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp141__;
*pnConsumed += 1;
// fieldsEndFlag = 1
@@ -30261,12 +32507,10 @@
DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->akm_suites ), ( pSrc->akm_suite_count * 4 ));
*pnConsumed += ( pSrc->akm_suite_count * 4 );
pBuf += ( pSrc->akm_suite_count * 4 );
- if ( pSrc->RSN_Cap ) {
- DOT11F_MEMCPY(pCtx, pBuf, pSrc->RSN_Cap, 2);
- *pnConsumed += 2;
- pBuf += 2;
- }
- else break;
+ /* RSN_Cap */
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->RSN_Cap, 2);
+ *pnConsumed += 2;
+ pBuf += 2;
if ( pSrc->pmkid_count ) {
frameshtons(pCtx, pBuf, pSrc->pmkid_count, 0);
*pnConsumed += 2;
@@ -30615,6 +32859,9 @@
tmp142__ |= ( pSrc->rxAntPattern << 28 );
tmp142__ |= ( pSrc->txAntPattern << 29 );
tmp142__ |= ( pSrc->reserved1 << 30 );
+ if (unlikely(nBuf < 4))
+ return DOT11F_INCOMPLETE_IE;
+
frameshtonl(pCtx, pBuf, tmp142__, 0);
*pnConsumed += 4;
pBuf += 4;
@@ -30625,6 +32872,9 @@
tmp143__ = 0U;
tmp143__ |= ( pSrc->rxHighSupDataRate << 0 );
tmp143__ |= ( pSrc->reserved2 << 13 );
+ if (unlikely(nBuf < 2))
+ return DOT11F_INCOMPLETE_IE;
+
frameshtons(pCtx, pBuf, tmp143__, 0);
*pnConsumed += 2;
pBuf += 2;
@@ -30635,6 +32885,9 @@
tmp144__ = 0U;
tmp144__ |= ( pSrc->txSupDataRate << 0 );
tmp144__ |= ( pSrc->reserved3 << 13 );
+ if (unlikely(nBuf < 2))
+ return DOT11F_INCOMPLETE_IE;
+
frameshtons(pCtx, pBuf, tmp144__, 0);
*pnConsumed += 2;
// fieldsEndFlag = 1
@@ -30771,6 +33024,9 @@
tmp145__ = 0U;
tmp145__ |= ( pSrc->preauth << 0 );
tmp145__ |= ( pSrc->reserved << 1 );
+ if (unlikely(nBuf < 2))
+ return DOT11F_INCOMPLETE_IE;
+
frameshtons(pCtx, pBuf, tmp145__, 0);
*pnConsumed += 2;
pBuf += 2;
@@ -30942,6 +33198,9 @@
tmp146__ |= ( pSrc->queue_request << 5 );
tmp146__ |= ( pSrc->txop_request << 6 );
tmp146__ |= ( pSrc->more_ack << 7 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp146__;
*pnConsumed += 1;
// fieldsEndFlag = 1
@@ -30991,6 +33250,9 @@
tmp147__ |= ( pSrc->param_set_count << 0 );
tmp147__ |= ( pSrc->reserved << 4 );
tmp147__ |= ( pSrc->uapsd << 7 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp147__;
*pnConsumed += 1;
// fieldsEndFlag = 1
@@ -31044,6 +33306,9 @@
tmp148__ |= ( pSrc->reserved1 << 4 );
tmp148__ |= ( pSrc->max_sp_length << 5 );
tmp148__ |= ( pSrc->reserved2 << 7 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp148__;
*pnConsumed += 1;
// fieldsEndFlag = 1
@@ -31107,6 +33372,9 @@
tmp149__ |= ( pSrc->acbe_acm << 4 );
tmp149__ |= ( pSrc->acbe_aci << 5 );
tmp149__ |= ( pSrc->unused1 << 7 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp149__;
*pnConsumed += 1;
pBuf += 1;
@@ -31114,6 +33382,9 @@
tmp150__ = 0U;
tmp150__ |= ( pSrc->acbe_acwmin << 0 );
tmp150__ |= ( pSrc->acbe_acwmax << 4 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp150__;
*pnConsumed += 1;
pBuf += 1;
@@ -31126,6 +33397,9 @@
tmp151__ |= ( pSrc->acbk_acm << 4 );
tmp151__ |= ( pSrc->acbk_aci << 5 );
tmp151__ |= ( pSrc->unused2 << 7 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp151__;
*pnConsumed += 1;
pBuf += 1;
@@ -31133,6 +33407,9 @@
tmp152__ = 0U;
tmp152__ |= ( pSrc->acbk_acwmin << 0 );
tmp152__ |= ( pSrc->acbk_acwmax << 4 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp152__;
*pnConsumed += 1;
pBuf += 1;
@@ -31145,6 +33422,9 @@
tmp153__ |= ( pSrc->acvi_acm << 4 );
tmp153__ |= ( pSrc->acvi_aci << 5 );
tmp153__ |= ( pSrc->unused3 << 7 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp153__;
*pnConsumed += 1;
pBuf += 1;
@@ -31152,6 +33432,9 @@
tmp154__ = 0U;
tmp154__ |= ( pSrc->acvi_acwmin << 0 );
tmp154__ |= ( pSrc->acvi_acwmax << 4 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp154__;
*pnConsumed += 1;
pBuf += 1;
@@ -31164,6 +33447,9 @@
tmp155__ |= ( pSrc->acvo_acm << 4 );
tmp155__ |= ( pSrc->acvo_aci << 5 );
tmp155__ |= ( pSrc->unused4 << 7 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp155__;
*pnConsumed += 1;
pBuf += 1;
@@ -31171,6 +33457,9 @@
tmp156__ = 0U;
tmp156__ |= ( pSrc->acvo_acwmin << 0 );
tmp156__ |= ( pSrc->acvo_acwmax << 4 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp156__;
*pnConsumed += 1;
pBuf += 1;
@@ -31747,6 +34036,9 @@
tmp157__ |= ( pSrc->hs_id_present << 1 );
tmp157__ |= ( pSrc->reserved << 3 );
tmp157__ |= ( pSrc->release_num << 4 );
+ if (unlikely(nBuf < 1))
+ return DOT11F_INCOMPLETE_IE;
+
*pBuf = tmp157__;
*pnConsumed += 1;
pBuf += 1;
diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c
index 929ac29..fb476c0 100644
--- a/drivers/staging/rtl8192u/r8192U_core.c
+++ b/drivers/staging/rtl8192u/r8192U_core.c
@@ -1682,6 +1682,8 @@
priv->rx_urb[16] = usb_alloc_urb(0, GFP_KERNEL);
priv->oldaddr = kmalloc(16, GFP_KERNEL);
+ if (!priv->oldaddr)
+ return -ENOMEM;
oldaddr = priv->oldaddr;
align = ((long)oldaddr) & 3;
if (align) {
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index 450a8ca..0b9f255 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -137,6 +137,9 @@
struct mutex mutex;
/* Link layer */
+ int mode;
+#define DLCI_MODE_ABM 0 /* Normal Asynchronous Balanced Mode */
+#define DLCI_MODE_ADM 1 /* Asynchronous Disconnected Mode */
spinlock_t lock; /* Protects the internal state */
struct timer_list t1; /* Retransmit timer for SABM and UA */
int retries;
@@ -1380,7 +1383,13 @@
ctrl->data = data;
ctrl->len = clen;
gsm->pending_cmd = ctrl;
- gsm->cretries = gsm->n2;
+
+ /* If DLCI0 is in ADM mode skip retries, it won't respond */
+ if (gsm->dlci[0]->mode == DLCI_MODE_ADM)
+ gsm->cretries = 1;
+ else
+ gsm->cretries = gsm->n2;
+
mod_timer(&gsm->t2_timer, jiffies + gsm->t2 * HZ / 100);
gsm_control_transmit(gsm, ctrl);
spin_unlock_irqrestore(&gsm->control_lock, flags);
@@ -1488,6 +1497,7 @@
if (debug & 8)
pr_info("DLCI %d opening in ADM mode.\n",
dlci->addr);
+ dlci->mode = DLCI_MODE_ADM;
gsm_dlci_open(dlci);
} else {
gsm_dlci_close(dlci);
@@ -2882,11 +2892,22 @@
static int gsm_carrier_raised(struct tty_port *port)
{
struct gsm_dlci *dlci = container_of(port, struct gsm_dlci, port);
+ struct gsm_mux *gsm = dlci->gsm;
+
/* Not yet open so no carrier info */
if (dlci->state != DLCI_OPEN)
return 0;
if (debug & 2)
return 1;
+
+ /*
+ * Basic mode with control channel in ADM mode may not respond
+ * to CMD_MSC at all and modem_rx is empty.
+ */
+ if (gsm->encoding == 0 && gsm->dlci[0]->mode == DLCI_MODE_ADM &&
+ !dlci->modem_rx)
+ return 1;
+
return dlci->modem_rx & TIOCM_CD;
}
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index 79d8e27..389a577 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -128,6 +128,8 @@
struct mutex output_lock;
};
+#define MASK(x) ((x) & (N_TTY_BUF_SIZE - 1))
+
static inline size_t read_cnt(struct n_tty_data *ldata)
{
return ldata->read_head - ldata->read_tail;
@@ -1028,14 +1030,15 @@
}
seen_alnums = 0;
- while (ldata->read_head != ldata->canon_head) {
+ while (MASK(ldata->read_head) != MASK(ldata->canon_head)) {
head = ldata->read_head;
/* erase a single possibly multibyte character */
do {
head--;
c = read_buf(ldata, head);
- } while (is_continuation(c, tty) && head != ldata->canon_head);
+ } while (is_continuation(c, tty) &&
+ MASK(head) != MASK(ldata->canon_head));
/* do not partially erase */
if (is_continuation(c, tty))
@@ -1077,7 +1080,7 @@
* This info is used to go back the correct
* number of columns.
*/
- while (tail != ldata->canon_head) {
+ while (MASK(tail) != MASK(ldata->canon_head)) {
tail--;
c = read_buf(ldata, tail);
if (c == '\t') {
@@ -1334,7 +1337,7 @@
finish_erasing(ldata);
echo_char(c, tty);
echo_char_raw('\n', ldata);
- while (tail != ldata->read_head) {
+ while (MASK(tail) != MASK(ldata->read_head)) {
echo_char(read_buf(ldata, tail), tty);
tail++;
}
@@ -2503,7 +2506,7 @@
tail = ldata->read_tail;
nr = head - tail;
/* Skip EOF-chars.. */
- while (head != tail) {
+ while (MASK(head) != MASK(tail)) {
if (test_bit(tail & (N_TTY_BUF_SIZE - 1), ldata->read_flags) &&
read_buf(ldata, tail) == __DISABLED_CHAR)
nr--;
diff --git a/drivers/tty/serial/arc_uart.c b/drivers/tty/serial/arc_uart.c
index a59d1d7..f6f9a03 100644
--- a/drivers/tty/serial/arc_uart.c
+++ b/drivers/tty/serial/arc_uart.c
@@ -597,6 +597,11 @@
if (dev_id < 0)
dev_id = 0;
+ if (dev_id >= ARRAY_SIZE(arc_uart_ports)) {
+ dev_err(&pdev->dev, "serial%d out of range\n", dev_id);
+ return -EINVAL;
+ }
+
uart = &arc_uart_ports[dev_id];
port = &uart->port;
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 1883478..af3047d 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -1791,6 +1791,10 @@
dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret);
return ret;
}
+ if (ret >= ARRAY_SIZE(lpuart_ports)) {
+ dev_err(&pdev->dev, "serial%d out of range\n", ret);
+ return -EINVAL;
+ }
sport->port.line = ret;
sport->lpuart32 = of_device_is_compatible(np, "fsl,ls1021a-lpuart");
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 696d4b5..99126b8 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -1899,6 +1899,12 @@
else if (ret < 0)
return ret;
+ if (sport->port.line >= ARRAY_SIZE(imx_ports)) {
+ dev_err(&pdev->dev, "serial%d out of range\n",
+ sport->port.line);
+ return -EINVAL;
+ }
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(base))
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c
index c751604..ba59a76 100644
--- a/drivers/tty/serial/samsung.c
+++ b/drivers/tty/serial/samsung.c
@@ -1288,6 +1288,10 @@
dbg("s3c24xx_serial_probe(%p) %d\n", pdev, index);
+ if (index >= ARRAY_SIZE(s3c24xx_serial_ports)) {
+ dev_err(&pdev->dev, "serial%d out of range\n", index);
+ return -EINVAL;
+ }
ourport = &s3c24xx_serial_ports[index];
ourport->drv_data = s3c24xx_get_driver_data(pdev);
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index fabde0e..df28ef1 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -1001,7 +1001,7 @@
struct uart_port *port;
/* Try the given port id if failed use default method */
- if (cdns_uart_port[id].mapbase != 0) {
+ if (id < CDNS_UART_NR_PORTS && cdns_uart_port[id].mapbase != 0) {
/* Find the next unused port */
for (id = 0; id < CDNS_UART_NR_PORTS; id++)
if (cdns_uart_port[id].mapbase == 0)
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c
index 2bf0836..6572db5 100644
--- a/drivers/tty/tty_ldisc.c
+++ b/drivers/tty/tty_ldisc.c
@@ -171,12 +171,11 @@
return ERR_CAST(ldops);
}
- ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL);
- if (ld == NULL) {
- put_ldops(ldops);
- return ERR_PTR(-ENOMEM);
- }
-
+ /*
+ * There is no way to handle allocation failure of only 16 bytes.
+ * Let's simplify error handling and save more memory.
+ */
+ ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL | __GFP_NOFAIL);
ld->ops = ldops;
ld->tty = tty;
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 2607129..b094d39 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -1613,11 +1613,14 @@
}
static DEVICE_ATTR(dtds, S_IWUSR, NULL, print_dtds);
+#define CI_PM_RESUME_RETRIES 5 /* Max Number of retries */
+
static int ci13xxx_wakeup(struct usb_gadget *_gadget)
{
struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget);
unsigned long flags;
int ret = 0;
+ static int retry_count;
trace();
@@ -1629,7 +1632,27 @@
}
spin_unlock_irqrestore(udc->lock, flags);
- pm_runtime_get_sync(&_gadget->dev);
+ ret = pm_runtime_get_sync(&_gadget->dev);
+ if (ret) {
+ /* pm_runtime_get_sync returns -EACCES error between
+ * late_suspend and early_resume, wait for system resume to
+ * finish and perform resume from work_queue again
+ */
+ pr_debug("PM runtime get sync failed, ret %d\n", ret);
+ if (ret == -EACCES) {
+ pm_runtime_put_noidle(&_gadget->dev);
+ if (retry_count == CI_PM_RESUME_RETRIES) {
+ pr_err("pm_runtime_get_sync timed out\n");
+ retry_count = 0;
+ return 0;
+ }
+ retry_count++;
+ schedule_delayed_work(&udc->rw_work,
+ REMOTE_WAKEUP_DELAY);
+ return 0;
+ }
+ }
+ retry_count = 0;
udc->udc_driver->notify_event(udc,
CI13XXX_CONTROLLER_REMOTE_WAKEUP_EVENT);
diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c
index 94157ea..1b920f6 100644
--- a/drivers/usb/gadget/function/f_gsi.c
+++ b/drivers/usb/gadget/function/f_gsi.c
@@ -1279,8 +1279,9 @@
{
struct gsi_ctrl_pkt *cpkt = NULL;
struct list_head *act, *tmp;
+ unsigned long flags;
- spin_lock(&gsi->c_port.lock);
+ spin_lock_irqsave(&gsi->c_port.lock, flags);
if (skip_req_q)
goto clean_resp_q;
@@ -1295,7 +1296,7 @@
list_del(&cpkt->list);
gsi_ctrl_pkt_free(cpkt);
}
- spin_unlock(&gsi->c_port.lock);
+ spin_unlock_irqrestore(&gsi->c_port.lock, flags);
}
static int gsi_ctrl_send_cpkt_tomodem(struct f_gsi *gsi, void *buf, size_t len)
diff --git a/drivers/usb/gadget/function/f_rmnet.c b/drivers/usb/gadget/function/f_rmnet.c
index e9def8a..e946cfa 100644
--- a/drivers/usb/gadget/function/f_rmnet.c
+++ b/drivers/usb/gadget/function/f_rmnet.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -611,7 +611,7 @@
__func__, xport_to_str(dxport),
dev, dev->port_num, remote_wakeup_allowed);
- usb_ep_fifo_flush(dev->notify);
+ usb_ep_dequeue(dev->notify, dev->notify_req);
frmnet_purge_responses(dev);
port_num = rmnet_ports[dev->port_num].data_xport_num;
@@ -921,7 +921,7 @@
return;
}
- usb_ep_fifo_flush(dev->notify);
+ usb_ep_dequeue(dev->notify, dev->notify_req);
event = dev->notify_req->buf;
event->bmRequestType = USB_DIR_IN | USB_TYPE_CLASS
diff --git a/drivers/usb/gadget/function/u_smd.c b/drivers/usb/gadget/function/u_smd.c
index e27854f..20df934 100644
--- a/drivers/usb/gadget/function/u_smd.c
+++ b/drivers/usb/gadget/function/u_smd.c
@@ -295,6 +295,21 @@
return;
}
+static inline bool gsmd_remote_wakeup_allowed(struct usb_function *f)
+{
+ bool remote_wakeup_allowed;
+
+ if (f->config->cdev->gadget->speed == USB_SPEED_SUPER)
+ remote_wakeup_allowed = f->func_wakeup_allowed;
+ else
+ remote_wakeup_allowed = f->config->cdev->gadget->remote_wakeup;
+
+ pr_debug("%s: remote_wakeup_allowed:%s", __func__,
+ remote_wakeup_allowed ? "true" : "false");
+
+ return remote_wakeup_allowed;
+}
+
static void gsmd_tx_pull(struct work_struct *w)
{
struct gsmd_port *port = container_of(w, struct gsmd_port, pull);
@@ -320,6 +335,13 @@
in = port->port_usb->in;
func = &port->port_usb->func;
gadget = func->config->cdev->gadget;
+
+ /* Bail-out is suspended without remote-wakeup enable */
+ if (port->is_suspended && !gsmd_remote_wakeup_allowed(func)) {
+ spin_unlock_irq(&port->port_lock);
+ return;
+ }
+
if (port->is_suspended) {
spin_unlock_irq(&port->port_lock);
if ((gadget->speed == USB_SPEED_SUPER) &&
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index 5520de7..fb37f76 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -1,6 +1,6 @@
/* ehci-msm-hsic.c - HSUSB Host Controller Driver Implementation
*
- * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
*
* Partly derived from ehci-fsl.c and ehci-hcd.c
* Copyright (c) 2000-2004 by David Brownell
@@ -1066,6 +1066,7 @@
struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
u32 status;
int ret;
+ static bool runtime_pm_enabled;
if (atomic_read(&mehci->in_lpm)) {
dev_dbg(mehci->dev, "phy async intr\n");
@@ -1115,6 +1116,13 @@
ehci_writel(ehci, STS_GPTIMER0_INTERRUPT, &ehci->regs->status);
}
+ /* Allow RuntimePM if device connected */
+ if (!runtime_pm_enabled && (readl_relaxed(USB_PORTSC) & PORT_PE)) {
+ pr_debug("enable runtime PM for HSIC rhub\n");
+ pm_runtime_allow(&hcd->self.root_hub->dev);
+ runtime_pm_enabled = true;
+ }
+
return ehci_irq(hcd);
}
@@ -2166,6 +2174,9 @@
goto destroy_wq;
}
+ /* RuntimePM will be disabled until HSIC device connects */
+ pm_runtime_forbid(&hcd->self.root_hub->dev);
+
/* Check whether target uses pinctrl */
mehci->hsic_pinctrl = devm_pinctrl_get(&pdev->dev);
if (IS_ERR(mehci->hsic_pinctrl)) {
diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c
index a5273f0..df319b7 100644
--- a/drivers/usb/phy/phy-msm-usb.c
+++ b/drivers/usb/phy/phy-msm-usb.c
@@ -1553,6 +1553,8 @@
}
disable_irq(motg->irq);
+ if (motg->phy_irq)
+ disable_irq(motg->phy_irq);
wake_lock(&motg->wlock);
/*
@@ -1680,6 +1682,8 @@
enable_irq(motg->async_int);
motg->async_int = 0;
}
+ if (motg->phy_irq)
+ enable_irq(motg->phy_irq);
enable_irq(motg->irq);
/* Enable ASYNC_IRQ only during LPM */
@@ -2931,10 +2935,10 @@
msm_otg_start_peripheral(otg, 0);
msm_otg_dbg_log_event(&motg->phy, "RT PM: B_PERI A PUT",
get_pm_runtime_counter(dev), 0);
- /* _put for _get done on cable connect in B_IDLE */
- pm_runtime_put_noidle(dev);
/* Schedule work to finish cable disconnect processing*/
otg->phy->state = OTG_STATE_B_IDLE;
+ /* _put for _get done on cable connect in B_IDLE */
+ pm_runtime_put_noidle(dev);
work = 1;
} else if (test_bit(A_BUS_SUSPEND, &motg->inputs)) {
pr_debug("a_bus_suspend\n");
diff --git a/drivers/video/backlight/as3711_bl.c b/drivers/video/backlight/as3711_bl.c
index 734a915..e55304d 100644
--- a/drivers/video/backlight/as3711_bl.c
+++ b/drivers/video/backlight/as3711_bl.c
@@ -262,10 +262,10 @@
static int as3711_backlight_parse_dt(struct device *dev)
{
struct as3711_bl_pdata *pdata = dev_get_platdata(dev);
- struct device_node *bl =
- of_find_node_by_name(dev->parent->of_node, "backlight"), *fb;
+ struct device_node *bl, *fb;
int ret;
+ bl = of_get_child_by_name(dev->parent->of_node, "backlight");
if (!bl) {
dev_dbg(dev, "backlight node not found\n");
return -ENODEV;
@@ -279,7 +279,7 @@
if (pdata->su1_max_uA <= 0)
ret = -EINVAL;
if (ret < 0)
- return ret;
+ goto err_put_bl;
}
fb = of_parse_phandle(bl, "su2-dev", 0);
@@ -292,7 +292,7 @@
if (pdata->su2_max_uA <= 0)
ret = -EINVAL;
if (ret < 0)
- return ret;
+ goto err_put_bl;
if (of_find_property(bl, "su2-feedback-voltage", NULL)) {
pdata->su2_feedback = AS3711_SU2_VOLTAGE;
@@ -314,8 +314,10 @@
pdata->su2_feedback = AS3711_SU2_CURR_AUTO;
count++;
}
- if (count != 1)
- return -EINVAL;
+ if (count != 1) {
+ ret = -EINVAL;
+ goto err_put_bl;
+ }
count = 0;
if (of_find_property(bl, "su2-fbprot-lx-sd4", NULL)) {
@@ -334,8 +336,10 @@
pdata->su2_fbprot = AS3711_SU2_GPIO4;
count++;
}
- if (count != 1)
- return -EINVAL;
+ if (count != 1) {
+ ret = -EINVAL;
+ goto err_put_bl;
+ }
count = 0;
if (of_find_property(bl, "su2-auto-curr1", NULL)) {
@@ -355,11 +359,20 @@
* At least one su2-auto-curr* must be specified iff
* AS3711_SU2_CURR_AUTO is used
*/
- if (!count ^ (pdata->su2_feedback != AS3711_SU2_CURR_AUTO))
- return -EINVAL;
+ if (!count ^ (pdata->su2_feedback != AS3711_SU2_CURR_AUTO)) {
+ ret = -EINVAL;
+ goto err_put_bl;
+ }
}
+ of_node_put(bl);
+
return 0;
+
+err_put_bl:
+ of_node_put(bl);
+
+ return ret;
}
static int as3711_backlight_probe(struct platform_device *pdev)
diff --git a/drivers/video/backlight/max8925_bl.c b/drivers/video/backlight/max8925_bl.c
index 7b738d6..f3aa608 100644
--- a/drivers/video/backlight/max8925_bl.c
+++ b/drivers/video/backlight/max8925_bl.c
@@ -116,7 +116,7 @@
if (!pdata)
return;
- np = of_find_node_by_name(nproot, "backlight");
+ np = of_get_child_by_name(nproot, "backlight");
if (!np) {
dev_err(&pdev->dev, "failed to find backlight node\n");
return;
@@ -125,6 +125,8 @@
if (!of_property_read_u32(np, "maxim,max8925-dual-string", &val))
pdata->dual_string = val;
+ of_node_put(np);
+
pdev->dev.platform_data = pdata;
}
diff --git a/drivers/video/backlight/tps65217_bl.c b/drivers/video/backlight/tps65217_bl.c
index 61d72bf..dc920e2a 100644
--- a/drivers/video/backlight/tps65217_bl.c
+++ b/drivers/video/backlight/tps65217_bl.c
@@ -184,11 +184,11 @@
tps65217_bl_parse_dt(struct platform_device *pdev)
{
struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent);
- struct device_node *node = of_node_get(tps->dev->of_node);
+ struct device_node *node;
struct tps65217_bl_pdata *pdata, *err;
u32 val;
- node = of_find_node_by_name(node, "backlight");
+ node = of_get_child_by_name(tps->dev->of_node, "backlight");
if (!node)
return ERR_PTR(-ENODEV);
diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c
index 509d452..74ac73d 100644
--- a/drivers/video/fbdev/uvesafb.c
+++ b/drivers/video/fbdev/uvesafb.c
@@ -1059,7 +1059,8 @@
info->cmap.len || cmap->start < info->cmap.start)
return -EINVAL;
- entries = kmalloc(sizeof(*entries) * cmap->len, GFP_KERNEL);
+ entries = kmalloc_array(cmap->len, sizeof(*entries),
+ GFP_KERNEL);
if (!entries)
return -ENOMEM;
diff --git a/drivers/video/msm/mdss/mdp3.c b/drivers/video/msm/mdss/mdp3.c
index 29bb2f8..c0a0ff1 100644
--- a/drivers/video/msm/mdss/mdp3.c
+++ b/drivers/video/msm/mdss/mdp3.c
@@ -3198,7 +3198,7 @@
atomic_read(&mdp3_res->active_intf_cnt));
/* do not resume panels when coming out of idle power collapse */
- if (!mdp3_res->idle_pc)
+ if (!mdp3_is_idle_pc())
device_for_each_child(dev, &device_on, mdss_fb_suspres_panel);
MDSS_XLOG(XLOG_FUNC_ENTRY);
@@ -3230,7 +3230,7 @@
mdp3_footswitch_ctrl(0);
/* do not suspend panels when going in to idle power collapse */
- if (!mdp3_res->idle_pc)
+ if (!mdp3_is_idle_pc())
device_for_each_child(dev, &device_on, mdss_fb_suspres_panel);
return 0;
diff --git a/drivers/video/msm/mdss/mdp3.h b/drivers/video/msm/mdss/mdp3.h
index bea5d0a..2118f86 100644
--- a/drivers/video/msm/mdss/mdp3.h
+++ b/drivers/video/msm/mdss/mdp3.h
@@ -249,6 +249,20 @@
extern struct mdp3_hw_resource *mdp3_res;
+/*
+ * mdp3_is_idle_pc: - checks if a panel is idle
+ */
+static inline bool mdp3_is_idle_pc(void)
+{
+ bool ret = 0;
+
+ mutex_lock(&mdp3_res->fs_idle_pc_lock);
+ ret = mdp3_res->idle_pc;
+ mutex_unlock(&mdp3_res->fs_idle_pc_lock);
+
+ return ret;
+}
+
struct mdp3_dma *mdp3_get_dma_pipe(int capability);
struct mdp3_intf *mdp3_get_display_intf(int type);
void mdp3_irq_enable(int type);
diff --git a/drivers/video/msm/mdss/mdp3_ctrl.c b/drivers/video/msm/mdss/mdp3_ctrl.c
index 8558bb3..8e8bf66 100644
--- a/drivers/video/msm/mdss/mdp3_ctrl.c
+++ b/drivers/video/msm/mdss/mdp3_ctrl.c
@@ -1364,7 +1364,7 @@
pr_debug("mdp3_ctrl_reset idle_pc %s FS_EN %s\n",
mdp3_res->idle_pc ? "True":"False",
mdp3_res->fs_ena ? "True":"False");
- if (mdp3_res->idle_pc) {
+ if (mdp3_is_idle_pc()) {
mdp3_clk_enable(1, 0);
mdp3_dynamic_clock_gating_ctrl(0);
mdp3_qos_remapper_setup(panel);
@@ -1383,7 +1383,7 @@
rc = mdp3_iommu_enable(MDP3_CLIENT_DMA_P);
if (rc) {
pr_err("fail to attach dma iommu\n");
- if (mdp3_res->idle_pc)
+ if (mdp3_is_idle_pc())
mdp3_clk_enable(0, 0);
goto reset_error;
}
@@ -1397,7 +1397,7 @@
if (vsync_client.handler)
mdp3_dma->vsync_enable(mdp3_dma, &vsync_client);
- if (!mdp3_res->idle_pc) {
+ if (!mdp3_is_idle_pc()) {
mdp3_session->first_commit = true;
mfd->panel_info->cont_splash_enabled = 0;
mdp3_session->in_splash_screen = 0;
@@ -1405,7 +1405,9 @@
/* Disable Auto refresh */
mdp3_autorefresh_disable(mfd->panel_info);
} else {
+ mutex_lock(&mdp3_res->fs_idle_pc_lock);
mdp3_res->idle_pc = false;
+ mutex_unlock(&mdp3_res->fs_idle_pc_lock);
mdp3_clk_enable(0, 0);
mdp3_iommu_disable(MDP3_CLIENT_DMA_P);
}
@@ -1605,6 +1607,7 @@
int stride;
bool null_commit = false;
bool is_panel_type_cmd = false;
+ int prev_bl;
if (!mfd || !mfd->mdp.private1)
return -EINVAL;
@@ -1649,6 +1652,34 @@
return 0;
}
+ panel = mdp3_session->panel;
+ if (mdp3_session->in_splash_screen ||
+ mdp3_is_idle_pc()) {
+ pr_debug("%s: reset- in_splash = %d, idle_pc = %d", __func__,
+ mdp3_session->in_splash_screen, mdp3_res->idle_pc);
+ rc = mdp3_ctrl_reset(mfd);
+ if (rc) {
+ pr_err("fail to reset display\n");
+ return -EINVAL;
+ }
+ if ((mdp3_session->dma->roi.x || mdp3_session->dma->roi.y) &&
+ panel_info->partial_update_enabled)
+ mdp3_session->dma->update_src_cfg = true;
+ }
+
+ cancel_work_sync(&mdp3_session->clk_off_work);
+ mutex_lock(&mdp3_session->lock);
+
+ if (!mdp3_session->status) {
+ pr_err("%s, display off!\n", __func__);
+ mutex_unlock(&mdp3_session->lock);
+ return -EPERM;
+ }
+ MDSS_XLOG(0x111, mdp3_session->dma->vsync_period);
+
+ if (mfd->panel.type == MIPI_CMD_PANEL || client == MDP3_CLIENT_SPI)
+ is_panel_type_cmd = true;
+
if (panel_info->partial_update_enabled &&
is_roi_valid(mdp3_session->dma->source_config, cmt_data->l_roi)
&& update_roi(mdp3_session->dma->roi, cmt_data->l_roi)) {
@@ -1664,34 +1695,6 @@
mdp3_session->dma->roi.h);
}
- panel = mdp3_session->panel;
- mutex_lock(&mdp3_res->fs_idle_pc_lock);
- if (mdp3_session->in_splash_screen ||
- mdp3_res->idle_pc) {
- pr_debug("%s: reset- in_splash = %d, idle_pc = %d", __func__,
- mdp3_session->in_splash_screen, mdp3_res->idle_pc);
- rc = mdp3_ctrl_reset(mfd);
- if (rc) {
- pr_err("fail to reset display\n");
- mutex_unlock(&mdp3_res->fs_idle_pc_lock);
- return -EINVAL;
- }
- }
- mutex_unlock(&mdp3_res->fs_idle_pc_lock);
-
- cancel_work_sync(&mdp3_session->clk_off_work);
- mutex_lock(&mdp3_session->lock);
-
- if (!mdp3_session->status) {
- pr_err("%s, display off!\n", __func__);
- mutex_unlock(&mdp3_session->lock);
- return -EPERM;
- }
- MDSS_XLOG(0x111, mdp3_session->dma->vsync_period);
-
- if (mfd->panel.type == MIPI_CMD_PANEL || client == MDP3_CLIENT_SPI)
- is_panel_type_cmd = true;
-
mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_BEGIN);
data = mdp3_bufq_pop(&mdp3_session->bufq_in);
if (data) {
@@ -1817,9 +1820,15 @@
}
mdp3_session->vsync_before_commit = 0;
+ prev_bl = mfd->bl_level;
if (!splash_done || mdp3_session->esd_recovery == true) {
- if (panel && panel->set_backlight)
- panel->set_backlight(panel, panel->panel_info.bl_max);
+ if (panel && panel->set_backlight) {
+ if (mdp3_session->esd_recovery == true && prev_bl > 0)
+ panel->set_backlight(panel, prev_bl);
+ else
+ panel->set_backlight(panel,
+ panel->panel_info.bl_max);
+ }
splash_done = true;
mdp3_session->esd_recovery = false;
}
@@ -1888,19 +1897,16 @@
if (!mdp3_session || !mdp3_session->dma)
return;
- mutex_lock(&mdp3_res->fs_idle_pc_lock);
if (mdp3_session->in_splash_screen ||
- mdp3_res->idle_pc) {
+ mdp3_is_idle_pc()) {
pr_debug("%s: reset- in_splash = %d, idle_pc = %d", __func__,
mdp3_session->in_splash_screen, mdp3_res->idle_pc);
rc = mdp3_ctrl_reset(mfd);
if (rc) {
pr_err("fail to reset display\n");
- mutex_unlock(&mdp3_res->fs_idle_pc_lock);
return;
}
}
- mutex_unlock(&mdp3_res->fs_idle_pc_lock);
mutex_lock(&mdp3_session->lock);
@@ -2997,23 +3003,19 @@
}
break;
case MSMFB_ASYNC_BLIT:
- mutex_lock(&mdp3_res->fs_idle_pc_lock);
- if (mdp3_session->in_splash_screen || mdp3_res->idle_pc) {
+ if (mdp3_session->in_splash_screen || mdp3_is_idle_pc()) {
pr_debug("%s: reset- in_splash = %d, idle_pc = %d",
__func__, mdp3_session->in_splash_screen,
mdp3_res->idle_pc);
mdp3_ctrl_reset(mfd);
}
- mutex_unlock(&mdp3_res->fs_idle_pc_lock);
rc = mdp3_ctrl_async_blit_req(mfd, argp);
if (!rc)
cancel_work_sync(&mdp3_session->clk_off_work);
break;
case MSMFB_BLIT:
- mutex_lock(&mdp3_res->fs_idle_pc_lock);
if (mdp3_session->in_splash_screen)
mdp3_ctrl_reset(mfd);
- mutex_unlock(&mdp3_res->fs_idle_pc_lock);
rc = mdp3_ctrl_blit_req(mfd, argp);
if (!rc)
cancel_work_sync(&mdp3_session->clk_off_work);
@@ -3062,10 +3064,8 @@
break;
case MSMFB_OVERLAY_PLAY:
rc = copy_from_user(&ov_data, argp, sizeof(ov_data));
- mutex_lock(&mdp3_res->fs_idle_pc_lock);
if (mdp3_session->in_splash_screen)
mdp3_ctrl_reset(mfd);
- mutex_unlock(&mdp3_res->fs_idle_pc_lock);
if (!rc)
rc = mdp3_overlay_play(mfd, &ov_data);
if (rc)
diff --git a/drivers/video/msm/mdss/mdss_compat_utils.c b/drivers/video/msm/mdss/mdss_compat_utils.c
index 558c2d7..7a93d29 100644
--- a/drivers/video/msm/mdss/mdss_compat_utils.c
+++ b/drivers/video/msm/mdss/mdss_compat_utils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
* Copyright (C) 1994 Martin Schaller
*
* 2001 - Documented with DocBook
@@ -2878,26 +2878,28 @@
*pp = compat_alloc_user_space(alloc_size);
if (NULL == *pp)
return -ENOMEM;
- memset(*pp, 0, alloc_size);
-
- (*pp)->data.lut_cfg_data.data.pgc_lut_data.r_data =
- (struct mdp_ar_gc_lut_data *)
- ((unsigned long) *pp +
- sizeof(struct msmfb_mdp_pp));
- (*pp)->data.lut_cfg_data.data.pgc_lut_data.g_data =
- (struct mdp_ar_gc_lut_data *)
+ if (clear_user(*pp, alloc_size))
+ return -EFAULT;
+ if (put_user((struct mdp_ar_gc_lut_data *)
+ ((unsigned long) *pp +
+ sizeof(struct msmfb_mdp_pp)),
+ &(*pp)->data.lut_cfg_data.data.pgc_lut_data.r_data) ||
+ put_user((struct mdp_ar_gc_lut_data *)
((unsigned long) *pp +
sizeof(struct msmfb_mdp_pp) +
- pgc_size);
- (*pp)->data.lut_cfg_data.data.pgc_lut_data.b_data =
- (struct mdp_ar_gc_lut_data *)
+ pgc_size),
+ &(*pp)->data.lut_cfg_data.data.pgc_lut_data.g_data) ||
+ put_user((struct mdp_ar_gc_lut_data *)
((unsigned long) *pp +
sizeof(struct msmfb_mdp_pp) +
- (2 * pgc_size));
- (*pp)->data.lut_cfg_data.data.pgc_lut_data.cfg_payload
- = (void *)((unsigned long) *pp +
+ (2 * pgc_size)),
+ &(*pp)->data.lut_cfg_data.data.pgc_lut_data.b_data) ||
+ put_user((void *)((unsigned long) *pp +
sizeof(struct msmfb_mdp_pp) +
- (3 * pgc_size));
+ (3 * pgc_size)),
+ &(*pp)->data.lut_cfg_data.data.
+ pgc_lut_data.cfg_payload))
+ return -EFAULT;
break;
case mdp_lut_igc:
alloc_size += __pp_compat_size_igc();
@@ -2907,10 +2909,13 @@
alloc_size);
return -ENOMEM;
}
- memset(*pp, 0, alloc_size);
- (*pp)->data.lut_cfg_data.data.igc_lut_data.cfg_payload
- = (void *)((unsigned long)(*pp) +
- sizeof(struct msmfb_mdp_pp));
+ if (clear_user(*pp, alloc_size))
+ return -EFAULT;
+ if (put_user((void *)((unsigned long)(*pp) +
+ sizeof(struct msmfb_mdp_pp)),
+ &(*pp)->data.lut_cfg_data.data.
+ igc_lut_data.cfg_payload))
+ return -EFAULT;
break;
case mdp_lut_hist:
alloc_size += __pp_compat_size_hist_lut();
@@ -2920,10 +2925,13 @@
alloc_size);
return -ENOMEM;
}
- memset(*pp, 0, alloc_size);
- (*pp)->data.lut_cfg_data.data.hist_lut_data.cfg_payload
- = (void *)((unsigned long)(*pp) +
- sizeof(struct msmfb_mdp_pp));
+ if (clear_user(*pp, alloc_size))
+ return -EFAULT;
+ if (put_user((void *)((unsigned long)(*pp) +
+ sizeof(struct msmfb_mdp_pp)),
+ &(*pp)->data.lut_cfg_data.data.
+ hist_lut_data.cfg_payload))
+ return -EFAULT;
break;
default:
*pp = compat_alloc_user_space(alloc_size);
@@ -2932,7 +2940,8 @@
alloc_size, lut_type);
return -ENOMEM;
}
- memset(*pp, 0, alloc_size);
+ if (clear_user(*pp, alloc_size))
+ return -EFAULT;
break;
}
break;
@@ -2944,10 +2953,12 @@
alloc_size);
return -ENOMEM;
}
- memset(*pp, 0, alloc_size);
- (*pp)->data.pcc_cfg_data.cfg_payload =
- (void *)((unsigned long)(*pp) +
- sizeof(struct msmfb_mdp_pp));
+ if (clear_user(*pp, alloc_size))
+ return -EFAULT;
+ if (put_user((void *)((unsigned long)(*pp) +
+ sizeof(struct msmfb_mdp_pp)),
+ &(*pp)->data.pcc_cfg_data.cfg_payload))
+ return -EFAULT;
break;
case mdp_op_gamut_cfg:
alloc_size += __pp_compat_size_gamut();
@@ -2957,10 +2968,12 @@
alloc_size);
return -ENOMEM;
}
- memset(*pp, 0, alloc_size);
- (*pp)->data.gamut_cfg_data.cfg_payload =
- (void *)((unsigned long)(*pp) +
- sizeof(struct msmfb_mdp_pp));
+ if (clear_user(*pp, alloc_size))
+ return -EFAULT;
+ if (put_user((void *)((unsigned long)(*pp) +
+ sizeof(struct msmfb_mdp_pp)),
+ &(*pp)->data.gamut_cfg_data.cfg_payload))
+ return -EFAULT;
break;
case mdp_op_pa_v2_cfg:
alloc_size += __pp_compat_size_pa();
@@ -2970,16 +2983,19 @@
alloc_size);
return -ENOMEM;
}
- memset(*pp, 0, alloc_size);
- (*pp)->data.pa_v2_cfg_data.cfg_payload =
- (void *)((unsigned long)(*pp) +
- sizeof(struct msmfb_mdp_pp));
+ if (clear_user(*pp, alloc_size))
+ return -EFAULT;
+ if (put_user((void *)((unsigned long)(*pp) +
+ sizeof(struct msmfb_mdp_pp)),
+ &(*pp)->data.pa_v2_cfg_data.cfg_payload))
+ return -EFAULT;
break;
default:
*pp = compat_alloc_user_space(alloc_size);
if (NULL == *pp)
return -ENOMEM;
- memset(*pp, 0, alloc_size);
+ if (clear_user(*pp, alloc_size))
+ return -EFAULT;
break;
}
return 0;
@@ -3397,7 +3413,9 @@
sizeof(struct mdp_histogram_start_req));
return -EINVAL;
}
- memset(hist_req, 0, sizeof(struct mdp_histogram_start_req));
+ if (clear_user(hist_req,
+ sizeof(struct mdp_histogram_start_req)))
+ return -EFAULT;
ret = __from_user_hist_start_req(hist_req32, hist_req);
if (ret)
goto histo_compat_err;
@@ -3417,7 +3435,8 @@
sizeof(struct mdp_histogram_data));
return -EINVAL;
}
- memset(hist, 0, sizeof(struct mdp_histogram_data));
+ if (clear_user(hist, sizeof(struct mdp_histogram_data)))
+ return -EFAULT;
ret = __from_user_hist_data(hist32, hist);
if (ret)
goto histo_compat_err;
@@ -3920,7 +3939,7 @@
}
-static int __from_user_mdp_overlay(struct mdp_overlay *ov,
+static int __from_user_mdp_overlay(struct mdp_overlay __user *ov,
struct mdp_overlay32 __user *ov32)
{
__u32 data;
@@ -3979,12 +3998,12 @@
return 0;
}
-static int __from_user_mdp_overlaylist(struct mdp_overlay_list *ovlist,
- struct mdp_overlay_list32 *ovlist32,
+static int __from_user_mdp_overlaylist(struct mdp_overlay_list __user *ovlist,
+ struct mdp_overlay_list32 __user *ovlist32,
struct mdp_overlay **to_list_head)
{
__u32 i, ret;
- unsigned long data, from_list_head;
+ unsigned long data, from_list_head, num_overlays;
struct mdp_overlay32 *iter;
if (!to_list_head || !ovlist32 || !ovlist) {
@@ -4005,11 +4024,13 @@
sizeof(ovlist32->processed_overlays)))
return -EFAULT;
- if (get_user(data, &ovlist32->overlay_list)) {
+ if (get_user(data, &ovlist32->overlay_list) ||
+ get_user(num_overlays, &ovlist32->num_overlays)) {
ret = -EFAULT;
goto validate_exit;
}
- for (i = 0; i < ovlist32->num_overlays; i++) {
+
+ for (i = 0; i < num_overlays; i++) {
if (get_user(from_list_head, (__u32 *)data + i)) {
ret = -EFAULT;
goto validate_exit;
@@ -4022,7 +4043,8 @@
goto validate_exit;
}
}
- ovlist->overlay_list = to_list_head;
+ if (put_user(to_list_head, &ovlist->overlay_list))
+ return -EFAULT;
return 0;
@@ -4031,8 +4053,8 @@
return -EFAULT;
}
-static int __to_user_mdp_overlaylist(struct mdp_overlay_list32 *ovlist32,
- struct mdp_overlay_list *ovlist,
+static int __to_user_mdp_overlaylist(struct mdp_overlay_list32 __user *ovlist32,
+ struct mdp_overlay_list __user *ovlist,
struct mdp_overlay **l_ptr)
{
__u32 i, ret;
@@ -4105,31 +4127,33 @@
return size;
}
-static int __pp_sspp_set_offsets(struct mdp_overlay *ov)
+static int __pp_sspp_set_offsets(struct mdp_overlay __user *ov)
{
if (!ov) {
pr_err("invalid overlay pointer\n");
return -EFAULT;
}
- ov->overlay_pp_cfg.igc_cfg.cfg_payload = (void *)((unsigned long)ov +
- sizeof(struct mdp_overlay));
- ov->overlay_pp_cfg.pa_v2_cfg_data.cfg_payload =
- ov->overlay_pp_cfg.igc_cfg.cfg_payload +
- sizeof(struct mdp_igc_lut_data_v1_7);
- ov->overlay_pp_cfg.pcc_cfg_data.cfg_payload =
- ov->overlay_pp_cfg.pa_v2_cfg_data.cfg_payload +
- sizeof(struct mdp_pa_data_v1_7);
- ov->overlay_pp_cfg.hist_lut_cfg.cfg_payload =
- ov->overlay_pp_cfg.pcc_cfg_data.cfg_payload +
- sizeof(struct mdp_pcc_data_v1_7);
+ if (put_user((void *)((unsigned long)ov + sizeof(struct mdp_overlay)),
+ &(ov->overlay_pp_cfg.igc_cfg.cfg_payload)) ||
+ put_user(ov->overlay_pp_cfg.igc_cfg.cfg_payload +
+ sizeof(struct mdp_igc_lut_data_v1_7),
+ &(ov->overlay_pp_cfg.pa_v2_cfg_data.cfg_payload)) ||
+ put_user(ov->overlay_pp_cfg.pa_v2_cfg_data.cfg_payload +
+ sizeof(struct mdp_pa_data_v1_7),
+ &(ov->overlay_pp_cfg.pcc_cfg_data.cfg_payload)) ||
+ put_user(ov->overlay_pp_cfg.pcc_cfg_data.cfg_payload +
+ sizeof(struct mdp_pcc_data_v1_7),
+ &(ov->overlay_pp_cfg.hist_lut_cfg.cfg_payload)))
+ return -EFAULT;
return 0;
}
int mdss_compat_overlay_ioctl(struct fb_info *info, unsigned int cmd,
unsigned long arg, struct file *file)
{
- struct mdp_overlay *ov, **layers_head;
- struct mdp_overlay32 *ov32;
+ struct mdp_overlay **layers_head;
+ struct mdp_overlay __user *ov;
+ struct mdp_overlay32 __user *ov32;
struct mdp_overlay_list __user *ovlist;
struct mdp_overlay_list32 __user *ovlist32;
size_t layers_refs_sz, layers_sz, prepare_sz;
diff --git a/drivers/video/msm/mdss/mdss_dba_utils.c b/drivers/video/msm/mdss/mdss_dba_utils.c
index 8804244..3fecf12 100644
--- a/drivers/video/msm/mdss/mdss_dba_utils.c
+++ b/drivers/video/msm/mdss/mdss_dba_utils.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -734,7 +734,6 @@
struct mdss_dba_utils_data *udata = NULL;
struct msm_dba_reg_info info;
struct cec_abstract_init_data cec_abst_init_data;
- void *cec_abst_data;
int ret = 0;
if (!uid) {
@@ -823,7 +822,7 @@
udata->cec_abst_data = cec_abstract_init(&cec_abst_init_data);
if (IS_ERR_OR_NULL(udata->cec_abst_data)) {
pr_err("error initializing cec abstract module\n");
- ret = PTR_ERR(cec_abst_data);
+ ret = PTR_ERR(udata->cec_abst_data);
goto error;
}
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index 53d133c..1e1e5a1 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -782,7 +782,7 @@
int mdss_mdp_irq_enable(u32 intr_type, u32 intf_num)
{
- int irq_idx, idx;
+ int irq_idx = 0;
unsigned long irq_flags;
int ret = 0;
struct mdss_data_type *mdata = mdss_mdp_get_mdata();
@@ -801,7 +801,7 @@
spin_lock_irqsave(&mdp_lock, irq_flags);
if (mdata->mdp_irq_mask[irq.reg_idx] & irq.irq_mask) {
pr_warn("MDSS MDP IRQ-0x%x is already set, mask=%x\n",
- irq.irq_mask, mdata->mdp_irq_mask[idx]);
+ irq.irq_mask, mdata->mdp_irq_mask[irq.reg_idx]);
ret = -EBUSY;
} else {
pr_debug("MDP IRQ mask old=%x new=%x\n",
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index e9f5252..01d06f2 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -76,13 +76,15 @@
u64 result = val;
if (val) {
- u64 temp = -1UL;
+ u64 temp = U64_MAX;
do_div(temp, val);
if (temp > numer) {
/* no overflow, so we can do the operation*/
result = (val * (u64)numer);
do_div(result, denom);
+ } else {
+ pr_warn("Overflow, skip fudge factor\n");
}
}
return result;
@@ -933,7 +935,7 @@
{
u32 prefill_us = 0;
u32 prefill_amortized = 0;
- struct mdss_data_type *mdata;
+ struct mdss_data_type *mdata = mdss_mdp_get_mdata();
struct mdss_mdp_mixer *mixer;
struct mdss_panel_info *pinfo;
u32 fps, v_total;
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index 80dce69..ba4604b 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -1755,7 +1755,7 @@
int mdss_mode_switch(struct msm_fb_data_type *mfd, u32 mode)
{
- struct mdss_rect l_roi, r_roi;
+ struct mdss_rect l_roi = {0}, r_roi = {0};
struct mdss_mdp_ctl *ctl = mfd_to_ctl(mfd);
struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
struct mdss_mdp_ctl *sctl;
@@ -6080,6 +6080,7 @@
goto end;
}
+ctl_stop:
/*
* If retire fences are still active wait for a vsync time
* for retire fence to be updated.
@@ -6111,7 +6112,6 @@
flush_kthread_work(&mdp5_data->vsync_work);
}
-ctl_stop:
mutex_lock(&mdp5_data->ov_lock);
/* set the correct pipe_mapped before ctl_stop */
mdss_mdp_mixer_update_pipe_map(mdp5_data->ctl,
diff --git a/drivers/w1/masters/mxc_w1.c b/drivers/w1/masters/mxc_w1.c
index da3d0f0..0e98361 100644
--- a/drivers/w1/masters/mxc_w1.c
+++ b/drivers/w1/masters/mxc_w1.c
@@ -113,6 +113,10 @@
if (IS_ERR(mdev->clk))
return PTR_ERR(mdev->clk);
+ err = clk_prepare_enable(mdev->clk);
+ if (err)
+ return err;
+
clkrate = clk_get_rate(mdev->clk);
if (clkrate < 10000000)
dev_warn(&pdev->dev,
@@ -126,12 +130,10 @@
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mdev->regs = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(mdev->regs))
- return PTR_ERR(mdev->regs);
-
- err = clk_prepare_enable(mdev->clk);
- if (err)
- return err;
+ if (IS_ERR(mdev->regs)) {
+ err = PTR_ERR(mdev->regs);
+ goto out_disable_clk;
+ }
/* Software reset 1-Wire module */
writeb(MXC_W1_RESET_RST, mdev->regs + MXC_W1_RESET);
@@ -147,8 +149,12 @@
err = w1_add_master_device(&mdev->bus_master);
if (err)
- clk_disable_unprepare(mdev->clk);
+ goto out_disable_clk;
+ return 0;
+
+out_disable_clk:
+ clk_disable_unprepare(mdev->clk);
return err;
}
diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c
index aa93df5..2048aad 100644
--- a/drivers/watchdog/f71808e_wdt.c
+++ b/drivers/watchdog/f71808e_wdt.c
@@ -520,7 +520,8 @@
char c;
if (get_user(c, buf + i))
return -EFAULT;
- expect_close = (c == 'V');
+ if (c == 'V')
+ expect_close = true;
}
/* Properly order writes across fork()ed processes */
diff --git a/drivers/watchdog/sp5100_tco.h b/drivers/watchdog/sp5100_tco.h
index 2b28c00..dfe20b8 100644
--- a/drivers/watchdog/sp5100_tco.h
+++ b/drivers/watchdog/sp5100_tco.h
@@ -54,7 +54,7 @@
#define SB800_PM_WATCHDOG_CONFIG 0x4C
#define SB800_PCI_WATCHDOG_DECODE_EN (1 << 0)
-#define SB800_PM_WATCHDOG_DISABLE (1 << 2)
+#define SB800_PM_WATCHDOG_DISABLE (1 << 1)
#define SB800_PM_WATCHDOG_SECOND_RES (3 << 0)
#define SB800_ACPI_MMIO_DECODE_EN (1 << 0)
#define SB800_ACPI_MMIO_SEL (1 << 1)
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index 4bf7a34..f729721 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -636,8 +636,6 @@
xen_irq_info_cleanup(info);
}
- BUG_ON(info_for_irq(irq)->type == IRQT_UNBOUND);
-
xen_free_irq(irq);
}
@@ -763,8 +761,8 @@
mutex_unlock(&irq_mapping_update_lock);
return irq;
error_irq:
- for (; i >= 0; i--)
- __unbind_from_irq(irq + i);
+ while (nvec--)
+ __unbind_from_irq(irq + nvec);
mutex_unlock(&irq_mapping_update_lock);
return ret;
}
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
index 7786291..abdb152 100644
--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
@@ -322,7 +322,7 @@
if (entry->page) {
pr_debug("freeing g.e. %#x (pfn %#lx)\n",
entry->ref, page_to_pfn(entry->page));
- __free_page(entry->page);
+ put_page(entry->page);
} else
pr_info("freeing g.e. %#x\n", entry->ref);
kfree(entry);
@@ -378,7 +378,7 @@
if (gnttab_end_foreign_access_ref(ref, readonly)) {
put_free_entry(ref);
if (page != 0)
- free_page(page);
+ put_page(virt_to_page(page));
} else
gnttab_add_deferred(ref, readonly,
page ? virt_to_page(page) : NULL);
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index c6d47e5..898a730 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -366,7 +366,7 @@
* physical address */
phys = xen_bus_to_phys(dev_addr);
- if (((dev_addr + size - 1 > dma_mask)) ||
+ if (((dev_addr + size - 1 <= dma_mask)) ||
range_straddles_page_boundary(phys, size))
xen_destroy_contiguous_region(phys, order);
diff --git a/drivers/xen/xen-acpi-processor.c b/drivers/xen/xen-acpi-processor.c
index 57dbeef..f999548 100644
--- a/drivers/xen/xen-acpi-processor.c
+++ b/drivers/xen/xen-acpi-processor.c
@@ -362,9 +362,9 @@
}
/* There are more ACPI Processor objects than in x2APIC or MADT.
* This can happen with incorrect ACPI SSDT declerations. */
- if (acpi_id > nr_acpi_bits) {
- pr_debug("We only have %u, trying to set %u\n",
- nr_acpi_bits, acpi_id);
+ if (acpi_id >= nr_acpi_bits) {
+ pr_debug("max acpi id %u, trying to set %u\n",
+ nr_acpi_bits - 1, acpi_id);
return AE_OK;
}
/* OK, There is a ACPI Processor object */
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index 5390a67..5e23fcd 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -470,8 +470,11 @@
/* Register with generic device framework. */
err = device_register(&xendev->dev);
- if (err)
+ if (err) {
+ put_device(&xendev->dev);
+ xendev = NULL;
goto fail;
+ }
return 0;
fail:
diff --git a/drivers/zorro/zorro.c b/drivers/zorro/zorro.c
index 707c1a5..71f96d4 100644
--- a/drivers/zorro/zorro.c
+++ b/drivers/zorro/zorro.c
@@ -16,6 +16,7 @@
#include <linux/bitops.h>
#include <linux/string.h>
#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <asm/byteorder.h>
@@ -185,6 +186,17 @@
z->dev.parent = &bus->dev;
z->dev.bus = &zorro_bus_type;
z->dev.id = i;
+ switch (z->rom.er_Type & ERT_TYPEMASK) {
+ case ERT_ZORROIII:
+ z->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+ break;
+
+ case ERT_ZORROII:
+ default:
+ z->dev.coherent_dma_mask = DMA_BIT_MASK(24);
+ break;
+ }
+ z->dev.dma_mask = &z->dev.coherent_dma_mask;
}
/* ... then register them */
diff --git a/fs/affs/namei.c b/fs/affs/namei.c
index 035bd31..5f15d97 100644
--- a/fs/affs/namei.c
+++ b/fs/affs/namei.c
@@ -224,9 +224,10 @@
affs_lock_dir(dir);
bh = affs_find_entry(dir, dentry);
- affs_unlock_dir(dir);
- if (IS_ERR(bh))
+ if (IS_ERR(bh)) {
+ affs_unlock_dir(dir);
return ERR_CAST(bh);
+ }
if (bh) {
u32 ino = bh->b_blocknr;
@@ -240,10 +241,13 @@
}
affs_brelse(bh);
inode = affs_iget(sb, ino);
- if (IS_ERR(inode))
+ if (IS_ERR(inode)) {
+ affs_unlock_dir(dir);
return ERR_CAST(inode);
+ }
}
d_add(dentry, inode);
+ affs_unlock_dir(dir);
return NULL;
}
diff --git a/fs/aio.c b/fs/aio.c
index 151bc7b..70d04f4 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -561,9 +561,8 @@
while (!list_empty(&ctx->active_reqs)) {
req = list_first_entry(&ctx->active_reqs,
struct kiocb, ki_list);
-
- list_del_init(&req->ki_list);
kiocb_cancel(req);
+ list_del_init(&req->ki_list);
}
spin_unlock_irq(&ctx->ctx_lock);
@@ -1007,8 +1006,8 @@
ctx = rcu_dereference(table->table[id]);
if (ctx && ctx->user_id == ctx_id) {
- percpu_ref_get(&ctx->users);
- ret = ctx;
+ if (percpu_ref_tryget_live(&ctx->users))
+ ret = ctx;
}
out:
rcu_read_unlock();
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index fd8beb9..ed99503 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -334,8 +334,13 @@
char *s = strchr(p, del);
if (!s)
goto Einval;
- *s++ = '\0';
- e->offset = simple_strtoul(p, &p, 10);
+ *s = '\0';
+ if (p != s) {
+ int r = kstrtoint(p, 10, &e->offset);
+ if (r != 0 || e->offset < 0)
+ goto Einval;
+ }
+ p = s;
if (*p++)
goto Einval;
e->magic = p;
@@ -356,7 +361,8 @@
if (e->mask &&
string_unescape_inplace(e->mask, UNESCAPE_HEX) != e->size)
goto Einval;
- if (e->size + e->offset > BINPRM_BUF_SIZE)
+ if (e->size > BINPRM_BUF_SIZE ||
+ BINPRM_BUF_SIZE - e->size < e->offset)
goto Einval;
} else {
p = strchr(p, del);
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 39c68ef..c221d37 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -2758,6 +2758,8 @@
* contention with the cow code
*/
if (cow) {
+ bool last_level = (level == (BTRFS_MAX_LEVEL - 1));
+
/*
* if we don't really need to cow this block
* then we don't want to set the path blocking,
@@ -2782,9 +2784,13 @@
}
btrfs_set_path_blocking(p);
- err = btrfs_cow_block(trans, root, b,
- p->nodes[level + 1],
- p->slots[level + 1], &b);
+ if (last_level)
+ err = btrfs_cow_block(trans, root, b, NULL, 0,
+ &b);
+ else
+ err = btrfs_cow_block(trans, root, b,
+ p->nodes[level + 1],
+ p->slots[level + 1], &b);
if (err) {
ret = err;
goto done;
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 5177954..7d98640 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1194,7 +1194,7 @@
if (!writers)
return ERR_PTR(-ENOMEM);
- ret = percpu_counter_init(&writers->counter, 0, GFP_KERNEL);
+ ret = percpu_counter_init(&writers->counter, 0, GFP_NOFS);
if (ret < 0) {
kfree(writers);
return ERR_PTR(ret);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 131fe19..3f5fc15 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3946,6 +3946,7 @@
if (wait_for_alloc) {
mutex_unlock(&fs_info->chunk_mutex);
wait_for_alloc = 0;
+ cond_resched();
goto again;
}
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index eecdb1d..3061a3e 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -5996,8 +5996,7 @@
goto out_unlock_inode;
} else {
btrfs_update_inode(trans, root, inode);
- unlock_new_inode(inode);
- d_instantiate(dentry, inode);
+ d_instantiate_new(dentry, inode);
}
out_unlock:
@@ -6073,8 +6072,7 @@
goto out_unlock_inode;
BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops;
- unlock_new_inode(inode);
- d_instantiate(dentry, inode);
+ d_instantiate_new(dentry, inode);
out_unlock:
btrfs_end_transaction(trans, root);
@@ -6217,12 +6215,7 @@
if (err)
goto out_fail_inode;
- d_instantiate(dentry, inode);
- /*
- * mkdir is special. We're unlocking after we call d_instantiate
- * to avoid a race with nfsd calling d_instantiate.
- */
- unlock_new_inode(inode);
+ d_instantiate_new(dentry, inode);
drop_on_err = 0;
out_fail:
@@ -9251,8 +9244,7 @@
goto out_unlock_inode;
}
- unlock_new_inode(inode);
- d_instantiate(dentry, inode);
+ d_instantiate_new(dentry, inode);
out_unlock:
btrfs_end_transaction(trans, root);
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index efa0831..05d9436 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -2207,7 +2207,7 @@
have_csum = scrub_find_csum(sctx, logical, l, csum);
if (have_csum == 0)
++sctx->stat.no_csum;
- if (sctx->is_dev_replace && !have_csum) {
+ if (0 && sctx->is_dev_replace && !have_csum) {
ret = copy_nocow_pages(sctx, logical, l,
mirror_num,
physical_for_dev_replace);
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index a7c4e2f..b0350e2 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -4485,6 +4485,9 @@
u64 len;
int ret = 0;
+ if (sctx->flags & BTRFS_SEND_FLAG_NO_FILE_DATA)
+ return send_update_extent(sctx, offset, end - offset);
+
p = fs_path_alloc();
if (!p)
return -ENOMEM;
diff --git a/fs/btrfs/tests/qgroup-tests.c b/fs/btrfs/tests/qgroup-tests.c
index ec3dcb2..84f5ddd 100644
--- a/fs/btrfs/tests/qgroup-tests.c
+++ b/fs/btrfs/tests/qgroup-tests.c
@@ -69,7 +69,7 @@
btrfs_set_extent_generation(leaf, item, 1);
btrfs_set_extent_flags(leaf, item, BTRFS_EXTENT_FLAG_TREE_BLOCK);
block_info = (struct btrfs_tree_block_info *)(item + 1);
- btrfs_set_tree_block_level(leaf, block_info, 1);
+ btrfs_set_tree_block_level(leaf, block_info, 0);
iref = (struct btrfs_extent_inline_ref *)(block_info + 1);
if (parent > 0) {
btrfs_set_extent_inline_ref_type(leaf, iref,
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index cf5d682..6c2a51b 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -1983,8 +1983,10 @@
nritems = btrfs_header_nritems(path->nodes[0]);
if (path->slots[0] >= nritems) {
ret = btrfs_next_leaf(root, path);
- if (ret)
+ if (ret == 1)
break;
+ else if (ret < 0)
+ goto out;
}
btrfs_item_key_to_cpu(path->nodes[0], &found_key,
path->slots[0]);
@@ -3083,8 +3085,11 @@
* from this directory and from this transaction
*/
ret = btrfs_next_leaf(root, path);
- if (ret == 1) {
- last_offset = (u64)-1;
+ if (ret) {
+ if (ret == 1)
+ last_offset = (u64)-1;
+ else
+ err = ret;
goto done;
}
btrfs_item_key_to_cpu(path->nodes[0], &tmp, path->slots[0]);
@@ -3534,6 +3539,7 @@
ASSERT(ret == 0);
src = src_path->nodes[0];
i = 0;
+ need_find_last_extent = true;
}
btrfs_item_key_to_cpu(src, &key, i);
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index b2218b7..949deb9 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -150,8 +150,14 @@
* greater than cifs socket timeout which is 7 seconds
*/
while (server->tcpStatus == CifsNeedReconnect) {
- wait_event_interruptible_timeout(server->response_q,
- (server->tcpStatus != CifsNeedReconnect), 10 * HZ);
+ rc = wait_event_interruptible_timeout(server->response_q,
+ (server->tcpStatus != CifsNeedReconnect),
+ 10 * HZ);
+ if (rc < 0) {
+ cifs_dbg(FYI, "%s: aborting reconnect due to a received"
+ " signal by the process\n", __func__);
+ return -ERESTARTSYS;
+ }
/* are we still trying to reconnect? */
if (server->tcpStatus != CifsNeedReconnect)
@@ -6413,9 +6419,7 @@
pSMB->InformationLevel =
cpu_to_le16(SMB_SET_FILE_EA);
- parm_data =
- (struct fealist *) (((char *) &pSMB->hdr.Protocol) +
- offset);
+ parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
pSMB->ParameterOffset = cpu_to_le16(param_offset);
pSMB->DataOffset = cpu_to_le16(offset);
pSMB->SetupCount = 1;
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index f0488ba..b58ba87 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -144,7 +144,7 @@
static int
smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon)
{
- int rc = 0;
+ int rc;
struct nls_table *nls_codepage;
struct cifs_ses *ses;
struct TCP_Server_Info *server;
@@ -155,10 +155,10 @@
* for those three - in the calling routine.
*/
if (tcon == NULL)
- return rc;
+ return 0;
if (smb2_command == SMB2_TREE_CONNECT)
- return rc;
+ return 0;
if (tcon->tidStatus == CifsExiting) {
/*
@@ -201,8 +201,14 @@
return -EAGAIN;
}
- wait_event_interruptible_timeout(server->response_q,
- (server->tcpStatus != CifsNeedReconnect), 10 * HZ);
+ rc = wait_event_interruptible_timeout(server->response_q,
+ (server->tcpStatus != CifsNeedReconnect),
+ 10 * HZ);
+ if (rc < 0) {
+ cifs_dbg(FYI, "%s: aborting reconnect due to a received"
+ " signal by the process\n", __func__);
+ return -ERESTARTSYS;
+ }
/* are we still trying to reconnect? */
if (server->tcpStatus != CifsNeedReconnect)
@@ -220,7 +226,7 @@
}
if (!tcon->ses->need_reconnect && !tcon->need_reconnect)
- return rc;
+ return 0;
nls_codepage = load_nls_default();
diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h
index 484aac1..af036bf 100644
--- a/fs/crypto/fscrypt_private.h
+++ b/fs/crypto/fscrypt_private.h
@@ -116,6 +116,10 @@
filenames_mode == FS_ENCRYPTION_MODE_AES_256_CTS)
return true;
+ if (contents_mode == FS_ENCRYPTION_MODE_SPECK128_256_XTS &&
+ filenames_mode == FS_ENCRYPTION_MODE_SPECK128_256_CTS)
+ return true;
+
return false;
}
diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c
index d54ed1c..d66978e 100644
--- a/fs/crypto/keyinfo.c
+++ b/fs/crypto/keyinfo.c
@@ -147,6 +147,8 @@
FS_AES_128_CBC_KEY_SIZE },
[FS_ENCRYPTION_MODE_AES_128_CTS] = { "cts(cbc(aes))",
FS_AES_128_CTS_KEY_SIZE },
+ [FS_ENCRYPTION_MODE_SPECK128_256_XTS] = { "xts(speck128)", 64 },
+ [FS_ENCRYPTION_MODE_SPECK128_256_CTS] = { "cts(cbc(speck128))", 32 },
};
static int determine_cipher_type(struct fscrypt_info *ci, struct inode *inode,
diff --git a/fs/dcache.c b/fs/dcache.c
index 536b9e8..ff9cc2f 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1873,6 +1873,28 @@
return alias;
}
+/*
+ * This should be equivalent to d_instantiate() + unlock_new_inode(),
+ * with lockdep-related part of unlock_new_inode() done before
+ * anything else. Use that instead of open-coding d_instantiate()/
+ * unlock_new_inode() combinations.
+ */
+void d_instantiate_new(struct dentry *entry, struct inode *inode)
+{
+ BUG_ON(!hlist_unhashed(&entry->d_u.d_alias));
+ BUG_ON(!inode);
+ lockdep_annotate_inode_mutex_key(inode);
+ security_d_instantiate(entry, inode);
+ spin_lock(&inode->i_lock);
+ __d_instantiate(entry, inode);
+ WARN_ON(!(inode->i_state & I_NEW));
+ inode->i_state &= ~I_NEW;
+ smp_mb();
+ wake_up_bit(&inode->i_state, __I_NEW);
+ spin_unlock(&inode->i_lock);
+}
+EXPORT_SYMBOL(d_instantiate_new);
+
/**
* d_find_any_alias - find any alias for a given inode
* @inode: inode to find an alias for
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index 1df4e3b..ed8f812 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -293,15 +293,13 @@
iput(ecryptfs_inode);
goto out;
}
- unlock_new_inode(ecryptfs_inode);
-
crypt_stat = &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat;
if (get_events() && get_events()->open_cb)
get_events()->open_cb(
ecryptfs_inode_to_lower(ecryptfs_inode),
crypt_stat);
- d_instantiate(ecryptfs_dentry, ecryptfs_inode);
+ d_instantiate_new(ecryptfs_dentry, ecryptfs_inode);
out:
return rc;
}
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 36d35c3..d52de28 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -1169,21 +1169,11 @@
static void ext2_truncate_blocks(struct inode *inode, loff_t offset)
{
- /*
- * XXX: it seems like a bug here that we don't allow
- * IS_APPEND inode to have blocks-past-i_size trimmed off.
- * review and fix this.
- *
- * Also would be nice to be able to handle IO errors and such,
- * but that's probably too much to ask.
- */
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
S_ISLNK(inode->i_mode)))
return;
if (ext2_inode_is_fast_symlink(inode))
return;
- if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
- return;
__ext2_truncate_blocks(inode, offset);
}
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index c268d0a..b31b12d 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -41,8 +41,7 @@
{
int err = ext2_add_link(dentry, inode);
if (!err) {
- unlock_new_inode(inode);
- d_instantiate(dentry, inode);
+ d_instantiate_new(dentry, inode);
return 0;
}
inode_dec_link_count(inode);
@@ -265,8 +264,7 @@
if (err)
goto out_fail;
- unlock_new_inode(inode);
- d_instantiate(dentry, inode);
+ d_instantiate_new(dentry, inode);
out:
return err;
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index 0a46c50..e19719e 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -321,6 +321,7 @@
struct ext4_sb_info *sbi = EXT4_SB(sb);
ext4_grpblk_t offset;
ext4_grpblk_t next_zero_bit;
+ ext4_grpblk_t max_bit = EXT4_CLUSTERS_PER_GROUP(sb);
ext4_fsblk_t blk;
ext4_fsblk_t group_first_block;
@@ -338,20 +339,25 @@
/* check whether block bitmap block number is set */
blk = ext4_block_bitmap(sb, desc);
offset = blk - group_first_block;
- if (!ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data))
+ if (offset < 0 || EXT4_B2C(sbi, offset) >= max_bit ||
+ !ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data))
/* bad block bitmap */
return blk;
/* check whether the inode bitmap block number is set */
blk = ext4_inode_bitmap(sb, desc);
offset = blk - group_first_block;
- if (!ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data))
+ if (offset < 0 || EXT4_B2C(sbi, offset) >= max_bit ||
+ !ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data))
/* bad block bitmap */
return blk;
/* check whether the inode table block number is set */
blk = ext4_inode_table(sb, desc);
offset = blk - group_first_block;
+ if (offset < 0 || EXT4_B2C(sbi, offset) >= max_bit ||
+ EXT4_B2C(sbi, offset + sbi->s_itb_per_group) >= max_bit)
+ return blk;
next_zero_bit = ext4_find_next_zero_bit(bh->b_data,
EXT4_B2C(sbi, offset + EXT4_SB(sb)->s_itb_per_group),
EXT4_B2C(sbi, offset));
@@ -414,6 +420,7 @@
ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group)
{
struct ext4_group_desc *desc;
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
struct buffer_head *bh;
ext4_fsblk_t bitmap_blk;
@@ -421,6 +428,12 @@
if (!desc)
return NULL;
bitmap_blk = ext4_block_bitmap(sb, desc);
+ if ((bitmap_blk <= le32_to_cpu(sbi->s_es->s_first_data_block)) ||
+ (bitmap_blk >= ext4_blocks_count(sbi->s_es))) {
+ ext4_error(sb, "Invalid block bitmap block %llu in "
+ "block_group %u", bitmap_blk, block_group);
+ return ERR_PTR(-EUCLEAN);
+ }
bh = sb_getblk(sb, bitmap_blk);
if (unlikely(!bh)) {
ext4_error(sb, "Cannot get buffer for block bitmap - "
diff --git a/fs/ext4/crypto.c b/fs/ext4/crypto.c
index 79959f1c..478413b 100644
--- a/fs/ext4/crypto.c
+++ b/fs/ext4/crypto.c
@@ -457,9 +457,15 @@
return err;
}
-bool ext4_valid_contents_enc_mode(uint32_t mode)
+bool ext4_valid_enc_modes(uint32_t contents_mode, uint32_t filenames_mode)
{
- return (mode == EXT4_ENCRYPTION_MODE_AES_256_XTS);
+ if (contents_mode == EXT4_ENCRYPTION_MODE_AES_256_XTS)
+ return filenames_mode == EXT4_ENCRYPTION_MODE_AES_256_CTS;
+
+ if (contents_mode == EXT4_ENCRYPTION_MODE_SPECK128_256_XTS)
+ return filenames_mode == EXT4_ENCRYPTION_MODE_SPECK128_256_CTS;
+
+ return false;
}
/**
diff --git a/fs/ext4/crypto_fname.c b/fs/ext4/crypto_fname.c
index 2cfe3ff..5e5afb6 100644
--- a/fs/ext4/crypto_fname.c
+++ b/fs/ext4/crypto_fname.c
@@ -42,11 +42,6 @@
complete(&ecr->completion);
}
-bool ext4_valid_filenames_enc_mode(uint32_t mode)
-{
- return (mode == EXT4_ENCRYPTION_MODE_AES_256_CTS);
-}
-
static unsigned max_name_len(struct inode *inode)
{
return S_ISLNK(inode->i_mode) ? inode->i_sb->s_blocksize :
diff --git a/fs/ext4/crypto_key.c b/fs/ext4/crypto_key.c
index abcc717..020ca60 100644
--- a/fs/ext4/crypto_key.c
+++ b/fs/ext4/crypto_key.c
@@ -170,6 +170,12 @@
case EXT4_ENCRYPTION_MODE_AES_256_CTS:
cipher_str = "cts(cbc(aes))";
break;
+ case EXT4_ENCRYPTION_MODE_SPECK128_256_XTS:
+ cipher_str = "xts(speck128)";
+ break;
+ case EXT4_ENCRYPTION_MODE_SPECK128_256_CTS:
+ cipher_str = "cts(cbc(speck128))";
+ break;
default:
printk_once(KERN_WARNING
"ext4: unsupported key mode %d (ino %u)\n",
diff --git a/fs/ext4/crypto_policy.c b/fs/ext4/crypto_policy.c
index e4f4fc4..818fa45 100644
--- a/fs/ext4/crypto_policy.c
+++ b/fs/ext4/crypto_policy.c
@@ -60,16 +60,12 @@
ctx.format = EXT4_ENCRYPTION_CONTEXT_FORMAT_V1;
memcpy(ctx.master_key_descriptor, policy->master_key_descriptor,
EXT4_KEY_DESCRIPTOR_SIZE);
- if (!ext4_valid_contents_enc_mode(policy->contents_encryption_mode)) {
+ if (!ext4_valid_enc_modes(policy->contents_encryption_mode,
+ policy->filenames_encryption_mode)) {
printk(KERN_WARNING
- "%s: Invalid contents encryption mode %d\n", __func__,
- policy->contents_encryption_mode);
- return -EINVAL;
- }
- if (!ext4_valid_filenames_enc_mode(policy->filenames_encryption_mode)) {
- printk(KERN_WARNING
- "%s: Invalid filenames encryption mode %d\n", __func__,
- policy->filenames_encryption_mode);
+ "%s: Invalid encryption modes (contents %d, filenames %d)\n",
+ __func__, policy->contents_encryption_mode,
+ policy->filenames_encryption_mode);
return -EINVAL;
}
if (policy->flags & ~EXT4_POLICY_FLAGS_VALID)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 79c2c5f..11bfa65 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -600,6 +600,8 @@
#define EXT4_ENCRYPTION_MODE_AES_256_GCM 2
#define EXT4_ENCRYPTION_MODE_AES_256_CBC 3
#define EXT4_ENCRYPTION_MODE_AES_256_CTS 4
+#define EXT4_ENCRYPTION_MODE_SPECK128_256_XTS 7
+#define EXT4_ENCRYPTION_MODE_SPECK128_256_CTS 8
#include "ext4_crypto.h"
@@ -2081,7 +2083,7 @@
/* crypto.c */
extern struct kmem_cache *ext4_crypt_info_cachep;
-bool ext4_valid_contents_enc_mode(uint32_t mode);
+bool ext4_valid_enc_modes(uint32_t contents_mode, uint32_t filenames_mode);
uint32_t ext4_validate_encryption_key_size(uint32_t mode, uint32_t size);
extern struct workqueue_struct *ext4_read_workqueue;
struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode,
@@ -2112,7 +2114,6 @@
#endif
/* crypto_fname.c */
-bool ext4_valid_filenames_enc_mode(uint32_t mode);
u32 ext4_fname_crypto_round_up(u32 size, u32 blksize);
unsigned ext4_fname_encrypted_size(struct inode *inode, u32 ilen);
int ext4_fname_crypto_alloc_buffer(struct inode *inode,
diff --git a/fs/ext4/ext4_crypto.h b/fs/ext4/ext4_crypto.h
index 1b17b05..d37e7146 100644
--- a/fs/ext4/ext4_crypto.h
+++ b/fs/ext4/ext4_crypto.h
@@ -120,6 +120,10 @@
return EXT4_AES_256_CBC_KEY_SIZE;
case EXT4_ENCRYPTION_MODE_AES_256_CTS:
return EXT4_AES_256_CTS_KEY_SIZE;
+ case EXT4_ENCRYPTION_MODE_SPECK128_256_XTS:
+ return 64;
+ case EXT4_ENCRYPTION_MODE_SPECK128_256_CTS:
+ return 32;
default:
BUG();
}
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index f2be3a1..881c5e4 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -84,16 +84,22 @@
ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
{
struct ext4_group_desc *desc;
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
struct buffer_head *bh = NULL;
ext4_fsblk_t bitmap_blk;
struct ext4_group_info *grp;
- struct ext4_sb_info *sbi = EXT4_SB(sb);
desc = ext4_get_group_desc(sb, block_group, NULL);
if (!desc)
return NULL;
bitmap_blk = ext4_inode_bitmap(sb, desc);
+ if ((bitmap_blk <= le32_to_cpu(sbi->s_es->s_first_data_block)) ||
+ (bitmap_blk >= ext4_blocks_count(sbi->s_es))) {
+ ext4_error(sb, "Invalid inode bitmap blk %llu in "
+ "block_group %u", bitmap_blk, block_group);
+ return ERR_PTR(-EUCLEAN);
+ }
bh = sb_getblk(sb, bitmap_blk);
if (unlikely(!bh)) {
ext4_error(sb, "Cannot read inode bitmap - "
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
index 4be5b04..fcdf2df 100644
--- a/fs/ext4/inline.c
+++ b/fs/ext4/inline.c
@@ -434,6 +434,7 @@
memset((void *)ext4_raw_inode(&is.iloc)->i_block,
0, EXT4_MIN_INLINE_DATA_SIZE);
+ memset(ei->i_data, 0, EXT4_MIN_INLINE_DATA_SIZE);
if (EXT4_HAS_INCOMPAT_FEATURE(inode->i_sb,
EXT4_FEATURE_INCOMPAT_EXTENTS)) {
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 169f058..153adab 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3721,28 +3721,28 @@
EXT4_BLOCK_SIZE_BITS(sb);
stop_block = (offset + length) >> EXT4_BLOCK_SIZE_BITS(sb);
- /* If there are no blocks to remove, return now */
- if (first_block >= stop_block)
- goto out_stop;
+ /* If there are blocks to remove, do it */
+ if (stop_block > first_block) {
- down_write(&EXT4_I(inode)->i_data_sem);
- ext4_discard_preallocations(inode);
+ down_write(&EXT4_I(inode)->i_data_sem);
+ ext4_discard_preallocations(inode);
- ret = ext4_es_remove_extent(inode, first_block,
- stop_block - first_block);
- if (ret) {
+ ret = ext4_es_remove_extent(inode, first_block,
+ stop_block - first_block);
+ if (ret) {
+ up_write(&EXT4_I(inode)->i_data_sem);
+ goto out_stop;
+ }
+
+ if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
+ ret = ext4_ext_remove_space(inode, first_block,
+ stop_block - 1);
+ else
+ ret = ext4_ind_remove_space(handle, inode, first_block,
+ stop_block);
+
up_write(&EXT4_I(inode)->i_data_sem);
- goto out_stop;
}
-
- if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
- ret = ext4_ext_remove_space(inode, first_block,
- stop_block - 1);
- else
- ret = ext4_ind_remove_space(handle, inode, first_block,
- stop_block);
-
- up_write(&EXT4_I(inode)->i_data_sem);
if (IS_SYNC(inode))
ext4_handle_sync(handle);
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 7fa9a67..c6788bf 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -2423,8 +2423,7 @@
int err = ext4_add_entry(handle, dentry, inode);
if (!err) {
ext4_mark_inode_dirty(handle, inode);
- unlock_new_inode(inode);
- d_instantiate(dentry, inode);
+ d_instantiate_new(dentry, inode);
return 0;
}
drop_nlink(inode);
@@ -2658,8 +2657,7 @@
err = ext4_mark_inode_dirty(handle, dir);
if (err)
goto out_clear_inode;
- unlock_new_inode(inode);
- d_instantiate(dentry, inode);
+ d_instantiate_new(dentry, inode);
if (IS_DIRSYNC(dir))
ext4_handle_sync(handle);
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 7015aa3..397b0ff 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -1906,7 +1906,7 @@
return 0;
n_group = ext4_get_group_number(sb, n_blocks_count - 1);
- if (n_group > (0xFFFFFFFFUL / EXT4_INODES_PER_GROUP(sb))) {
+ if (n_group >= (0xFFFFFFFFUL / EXT4_INODES_PER_GROUP(sb))) {
ext4_warning(sb, "resize would cause inodes_count overflow");
return -EINVAL;
}
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 8e92cab..c8e75fb 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -2083,6 +2083,7 @@
struct ext4_sb_info *sbi = EXT4_SB(sb);
ext4_fsblk_t first_block = le32_to_cpu(sbi->s_es->s_first_data_block);
ext4_fsblk_t last_block;
+ ext4_fsblk_t last_bg_block = sb_block + ext4_bg_num_gdb(sb, 0) + 1;
ext4_fsblk_t block_bitmap;
ext4_fsblk_t inode_bitmap;
ext4_fsblk_t inode_table;
@@ -2115,6 +2116,14 @@
if (!(sb->s_flags & MS_RDONLY))
return 0;
}
+ if (block_bitmap >= sb_block + 1 &&
+ block_bitmap <= last_bg_block) {
+ ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
+ "Block bitmap for group %u overlaps "
+ "block group descriptors", i);
+ if (!(sb->s_flags & MS_RDONLY))
+ return 0;
+ }
if (block_bitmap < first_block || block_bitmap > last_block) {
ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
"Block bitmap for group %u not in group "
@@ -2129,6 +2138,14 @@
if (!(sb->s_flags & MS_RDONLY))
return 0;
}
+ if (inode_bitmap >= sb_block + 1 &&
+ inode_bitmap <= last_bg_block) {
+ ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
+ "Inode bitmap for group %u overlaps "
+ "block group descriptors", i);
+ if (!(sb->s_flags & MS_RDONLY))
+ return 0;
+ }
if (inode_bitmap < first_block || inode_bitmap > last_block) {
ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
"Inode bitmap for group %u not in group "
@@ -2143,6 +2160,14 @@
if (!(sb->s_flags & MS_RDONLY))
return 0;
}
+ if (inode_table >= sb_block + 1 &&
+ inode_table <= last_bg_block) {
+ ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
+ "Inode table for group %u overlaps "
+ "block group descriptors", i);
+ if (!(sb->s_flags & MS_RDONLY))
+ return 0;
+ }
if (inode_table < first_block ||
inode_table + sbi->s_itb_per_group - 1 > last_block) {
ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
@@ -3734,6 +3759,13 @@
le32_to_cpu(es->s_log_block_size));
goto failed_mount;
}
+ if (le32_to_cpu(es->s_log_cluster_size) >
+ (EXT4_MAX_CLUSTER_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) {
+ ext4_msg(sb, KERN_ERR,
+ "Invalid log cluster size: %u",
+ le32_to_cpu(es->s_log_cluster_size));
+ goto failed_mount;
+ }
if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_ENCRYPT) &&
es->s_encryption_level) {
@@ -3871,13 +3903,6 @@
"block size (%d)", clustersize, blocksize);
goto failed_mount;
}
- if (le32_to_cpu(es->s_log_cluster_size) >
- (EXT4_MAX_CLUSTER_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) {
- ext4_msg(sb, KERN_ERR,
- "Invalid log cluster size: %u",
- le32_to_cpu(es->s_log_cluster_size));
- goto failed_mount;
- }
sbi->s_cluster_bits = le32_to_cpu(es->s_log_cluster_size) -
le32_to_cpu(es->s_log_block_size);
sbi->s_clusters_per_group =
@@ -3898,10 +3923,10 @@
}
} else {
if (clustersize != blocksize) {
- ext4_warning(sb, "fragment/cluster size (%d) != "
- "block size (%d)", clustersize,
- blocksize);
- clustersize = blocksize;
+ ext4_msg(sb, KERN_ERR,
+ "fragment/cluster size (%d) != "
+ "block size (%d)", clustersize, blocksize);
+ goto failed_mount;
}
if (sbi->s_blocks_per_group > blocksize * 8) {
ext4_msg(sb, KERN_ERR,
@@ -3955,6 +3980,13 @@
ext4_blocks_count(es));
goto failed_mount;
}
+ if ((es->s_first_data_block == 0) && (es->s_log_block_size == 0) &&
+ (sbi->s_cluster_ratio == 1)) {
+ ext4_msg(sb, KERN_WARNING, "bad geometry: first data "
+ "block is 0 with a 1k block and cluster size");
+ goto failed_mount;
+ }
+
blocks_count = (ext4_blocks_count(es) -
le32_to_cpu(es->s_first_data_block) +
EXT4_BLOCKS_PER_GROUP(sb) - 1);
@@ -3990,6 +4022,14 @@
ret = -ENOMEM;
goto failed_mount;
}
+ if (((u64)sbi->s_groups_count * sbi->s_inodes_per_group) !=
+ le32_to_cpu(es->s_inodes_count)) {
+ ext4_msg(sb, KERN_ERR, "inodes count not valid: %u vs %llu",
+ le32_to_cpu(es->s_inodes_count),
+ ((u64)sbi->s_groups_count * sbi->s_inodes_per_group));
+ ret = -EINVAL;
+ goto failed_mount;
+ }
if (ext4_proc_root)
sbi->s_proc = proc_mkdir(sb->s_id, ext4_proc_root);
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 18233dc..e2e560e 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -1886,7 +1886,13 @@
redirty_out:
redirty_page_for_writepage(wbc, page);
- if (!err)
+ /*
+ * pageout() in MM traslates EAGAIN, so calls handle_write_error()
+ * -> mapping_set_error() -> set_bit(AS_EIO, ...).
+ * file_write_and_wait_range() will see EIO error, which is critical
+ * to return value of fsync() followed by atomic_write failure to user.
+ */
+ if (!err || wbc->for_reclaim)
return AOP_WRITEPAGE_ACTIVATE;
unlock_page(page);
return err;
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 39f7456..b28951d 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -274,15 +274,12 @@
#define CP_DISCARD 0x00000010
#define CP_TRIMMED 0x00000020
-#define DEF_BATCHED_TRIM_SECTIONS 2048
-#define BATCHED_TRIM_SEGMENTS(sbi) \
- (GET_SEG_FROM_SEC(sbi, SM_I(sbi)->trim_sections))
-#define BATCHED_TRIM_BLOCKS(sbi) \
- (BATCHED_TRIM_SEGMENTS(sbi) << (sbi)->log_blocks_per_seg)
#define MAX_DISCARD_BLOCKS(sbi) BLKS_PER_SEC(sbi)
#define DEF_MAX_DISCARD_REQUEST 8 /* issue 8 discards per round */
+#define DEF_MAX_DISCARD_LEN 512 /* Max. 2MB per discard */
#define DEF_MIN_DISCARD_ISSUE_TIME 50 /* 50 ms, if exists */
#define DEF_MAX_DISCARD_ISSUE_TIME 60000 /* 60 s, if no candidates */
+#define DEF_DISCARD_URGENT_UTIL 80 /* do more discard over 80% */
#define DEF_CP_INTERVAL 60 /* 60 secs */
#define DEF_IDLE_INTERVAL 5 /* 5 secs */
@@ -787,7 +784,8 @@
static inline bool __is_discard_mergeable(struct discard_info *back,
struct discard_info *front)
{
- return back->lstart + back->len == front->lstart;
+ return (back->lstart + back->len == front->lstart) &&
+ (back->len + front->len < DEF_MAX_DISCARD_LEN);
}
static inline bool __is_discard_back_mergeable(struct discard_info *cur,
@@ -1173,6 +1171,7 @@
enum fsync_mode {
FSYNC_MODE_POSIX, /* fsync follows posix semantics */
FSYNC_MODE_STRICT, /* fsync behaves in line with ext4 */
+ FSYNC_MODE_NOBARRIER, /* fsync behaves nobarrier based on posix */
};
#ifdef CONFIG_F2FS_FS_ENCRYPTION
@@ -2905,8 +2904,6 @@
void destroy_flush_cmd_control(struct f2fs_sb_info *sbi, bool free);
void invalidate_blocks(struct f2fs_sb_info *sbi, block_t addr);
bool is_checkpointed_data(struct f2fs_sb_info *sbi, block_t blkaddr);
-void init_discard_policy(struct discard_policy *dpolicy, int discard_type,
- unsigned int granularity);
void drop_discard_cmd(struct f2fs_sb_info *sbi);
void stop_discard_thread(struct f2fs_sb_info *sbi);
bool f2fs_wait_discard_bios(struct f2fs_sb_info *sbi);
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 7a5f157..c742a3d 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -310,7 +310,7 @@
remove_ino_entry(sbi, ino, APPEND_INO);
clear_inode_flag(inode, FI_APPEND_WRITE);
flush_out:
- if (!atomic)
+ if (!atomic && F2FS_OPTION(sbi).fsync_mode != FSYNC_MODE_NOBARRIER)
ret = f2fs_issue_flush(sbi, inode->i_ino);
if (!ret) {
remove_ino_entry(sbi, ino, UPDATE_INO);
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 604d3fc..66044fa 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -693,6 +693,7 @@
dec_page_count(fio.sbi, F2FS_DIRTY_META);
set_page_writeback(fio.encrypted_page);
+ ClearPageError(page);
/* allocate block address */
f2fs_wait_on_page_writeback(dn.node_page, NODE, true);
diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c
index feb96e6..3337bfe 100644
--- a/fs/f2fs/inline.c
+++ b/fs/f2fs/inline.c
@@ -157,6 +157,7 @@
/* write data page to try to make data consistent */
set_page_writeback(page);
+ ClearPageError(page);
fio.old_blkaddr = dn->data_blkaddr;
set_inode_flag(dn->inode, FI_HOT_DATA);
write_data_page(dn, &fio);
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
index 1ca2b6c..4a27f1c 100644
--- a/fs/f2fs/namei.c
+++ b/fs/f2fs/namei.c
@@ -290,8 +290,7 @@
alloc_nid_done(sbi, ino);
- unlock_new_inode(inode);
- d_instantiate(dentry, inode);
+ d_instantiate_new(dentry, inode);
if (IS_DIRSYNC(dir))
f2fs_sync_fs(sbi->sb, 1);
@@ -591,8 +590,7 @@
err = page_symlink(inode, disk_link.name, disk_link.len);
err_out:
- unlock_new_inode(inode);
- d_instantiate(dentry, inode);
+ d_instantiate_new(dentry, inode);
/*
* Let's flush symlink data in order to avoid broken symlink as much as
@@ -653,8 +651,7 @@
alloc_nid_done(sbi, inode->i_ino);
- unlock_new_inode(inode);
- d_instantiate(dentry, inode);
+ d_instantiate_new(dentry, inode);
if (IS_DIRSYNC(dir))
f2fs_sync_fs(sbi->sb, 1);
@@ -705,8 +702,7 @@
alloc_nid_done(sbi, inode->i_ino);
- unlock_new_inode(inode);
- d_instantiate(dentry, inode);
+ d_instantiate_new(dentry, inode);
if (IS_DIRSYNC(dir))
f2fs_sync_fs(sbi->sb, 1);
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index d1503dd..5c5575d 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1399,6 +1399,7 @@
fio.op_flags |= WRITE_FLUSH_FUA;
set_page_writeback(page);
+ ClearPageError(page);
fio.old_blkaddr = ni.blk_addr;
write_node_page(nid, &fio);
set_node_addr(sbi, &ni, fio.new_blkaddr, is_fsync_dnode(page));
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 127bd48..d7d248c 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -997,6 +997,39 @@
#endif
}
+static void __init_discard_policy(struct f2fs_sb_info *sbi,
+ struct discard_policy *dpolicy,
+ int discard_type, unsigned int granularity)
+{
+ /* common policy */
+ dpolicy->type = discard_type;
+ dpolicy->sync = true;
+ dpolicy->granularity = granularity;
+
+ dpolicy->max_requests = DEF_MAX_DISCARD_REQUEST;
+ dpolicy->io_aware_gran = MAX_PLIST_NUM;
+
+ if (discard_type == DPOLICY_BG) {
+ dpolicy->min_interval = DEF_MIN_DISCARD_ISSUE_TIME;
+ dpolicy->max_interval = DEF_MAX_DISCARD_ISSUE_TIME;
+ dpolicy->io_aware = true;
+ dpolicy->sync = false;
+ if (utilization(sbi) > DEF_DISCARD_URGENT_UTIL) {
+ dpolicy->granularity = 1;
+ dpolicy->max_interval = DEF_MIN_DISCARD_ISSUE_TIME;
+ }
+ } else if (discard_type == DPOLICY_FORCE) {
+ dpolicy->min_interval = DEF_MIN_DISCARD_ISSUE_TIME;
+ dpolicy->max_interval = DEF_MAX_DISCARD_ISSUE_TIME;
+ dpolicy->io_aware = false;
+ } else if (discard_type == DPOLICY_FSTRIM) {
+ dpolicy->io_aware = false;
+ } else if (discard_type == DPOLICY_UMOUNT) {
+ dpolicy->io_aware = false;
+ }
+}
+
+
/* this function is copied from blkdev_issue_discard from block/blk-lib.c */
static void __submit_discard_cmd(struct f2fs_sb_info *sbi,
struct discard_policy *dpolicy,
@@ -1211,68 +1244,6 @@
return 0;
}
-static void __issue_discard_cmd_range(struct f2fs_sb_info *sbi,
- struct discard_policy *dpolicy,
- unsigned int start, unsigned int end)
-{
- struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
- struct discard_cmd *prev_dc = NULL, *next_dc = NULL;
- struct rb_node **insert_p = NULL, *insert_parent = NULL;
- struct discard_cmd *dc;
- struct blk_plug plug;
- int issued;
-
-next:
- issued = 0;
-
- mutex_lock(&dcc->cmd_lock);
- f2fs_bug_on(sbi, !__check_rb_tree_consistence(sbi, &dcc->root));
-
- dc = (struct discard_cmd *)__lookup_rb_tree_ret(&dcc->root,
- NULL, start,
- (struct rb_entry **)&prev_dc,
- (struct rb_entry **)&next_dc,
- &insert_p, &insert_parent, true);
- if (!dc)
- dc = next_dc;
-
- blk_start_plug(&plug);
-
- while (dc && dc->lstart <= end) {
- struct rb_node *node;
-
- if (dc->len < dpolicy->granularity)
- goto skip;
-
- if (dc->state != D_PREP) {
- list_move_tail(&dc->list, &dcc->fstrim_list);
- goto skip;
- }
-
- __submit_discard_cmd(sbi, dpolicy, dc);
-
- if (++issued >= dpolicy->max_requests) {
- start = dc->lstart + dc->len;
-
- blk_finish_plug(&plug);
- mutex_unlock(&dcc->cmd_lock);
-
- schedule();
-
- goto next;
- }
-skip:
- node = rb_next(&dc->rb_node);
- dc = rb_entry_safe(node, struct discard_cmd, rb_node);
-
- if (fatal_signal_pending(current))
- break;
- }
-
- blk_finish_plug(&plug);
- mutex_unlock(&dcc->cmd_lock);
-}
-
static int __issue_discard_cmd(struct f2fs_sb_info *sbi,
struct discard_policy *dpolicy)
{
@@ -1413,7 +1384,18 @@
static void __wait_all_discard_cmd(struct f2fs_sb_info *sbi,
struct discard_policy *dpolicy)
{
- __wait_discard_cmd_range(sbi, dpolicy, 0, UINT_MAX);
+ struct discard_policy dp;
+
+ if (dpolicy) {
+ __wait_discard_cmd_range(sbi, dpolicy, 0, UINT_MAX);
+ return;
+ }
+
+ /* wait all */
+ __init_discard_policy(sbi, &dp, DPOLICY_FSTRIM, 1);
+ __wait_discard_cmd_range(sbi, &dp, 0, UINT_MAX);
+ __init_discard_policy(sbi, &dp, DPOLICY_UMOUNT, 1);
+ __wait_discard_cmd_range(sbi, &dp, 0, UINT_MAX);
}
/* This should be covered by global mutex, &sit_i->sentry_lock */
@@ -1458,11 +1440,13 @@
struct discard_policy dpolicy;
bool dropped;
- init_discard_policy(&dpolicy, DPOLICY_UMOUNT, dcc->discard_granularity);
+ __init_discard_policy(sbi, &dpolicy, DPOLICY_UMOUNT,
+ dcc->discard_granularity);
__issue_discard_cmd(sbi, &dpolicy);
dropped = __drop_discard_cmd(sbi);
- __wait_all_discard_cmd(sbi, &dpolicy);
+ /* just to make sure there is no pending discard commands */
+ __wait_all_discard_cmd(sbi, NULL);
return dropped;
}
@@ -1478,7 +1462,7 @@
set_freezable();
do {
- init_discard_policy(&dpolicy, DPOLICY_BG,
+ __init_discard_policy(sbi, &dpolicy, DPOLICY_BG,
dcc->discard_granularity);
wait_event_interruptible_timeout(*q,
@@ -1496,7 +1480,7 @@
dcc->discard_wake = 0;
if (sbi->gc_thread && sbi->gc_thread->gc_urgent)
- init_discard_policy(&dpolicy, DPOLICY_FORCE, 1);
+ __init_discard_policy(sbi, &dpolicy, DPOLICY_FORCE, 1);
sb_start_intwrite(sbi->sb);
@@ -1789,32 +1773,6 @@
wake_up_discard_thread(sbi, false);
}
-void init_discard_policy(struct discard_policy *dpolicy,
- int discard_type, unsigned int granularity)
-{
- /* common policy */
- dpolicy->type = discard_type;
- dpolicy->sync = true;
- dpolicy->granularity = granularity;
-
- dpolicy->max_requests = DEF_MAX_DISCARD_REQUEST;
- dpolicy->io_aware_gran = MAX_PLIST_NUM;
-
- if (discard_type == DPOLICY_BG) {
- dpolicy->min_interval = DEF_MIN_DISCARD_ISSUE_TIME;
- dpolicy->max_interval = DEF_MAX_DISCARD_ISSUE_TIME;
- dpolicy->io_aware = true;
- } else if (discard_type == DPOLICY_FORCE) {
- dpolicy->min_interval = DEF_MIN_DISCARD_ISSUE_TIME;
- dpolicy->max_interval = DEF_MAX_DISCARD_ISSUE_TIME;
- dpolicy->io_aware = false;
- } else if (discard_type == DPOLICY_FSTRIM) {
- dpolicy->io_aware = false;
- } else if (discard_type == DPOLICY_UMOUNT) {
- dpolicy->io_aware = false;
- }
-}
-
static int create_discard_cmd_control(struct f2fs_sb_info *sbi)
{
dev_t dev = sbi->sb->s_bdev->bd_dev;
@@ -2454,11 +2412,72 @@
return has_candidate;
}
+static void __issue_discard_cmd_range(struct f2fs_sb_info *sbi,
+ struct discard_policy *dpolicy,
+ unsigned int start, unsigned int end)
+{
+ struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
+ struct discard_cmd *prev_dc = NULL, *next_dc = NULL;
+ struct rb_node **insert_p = NULL, *insert_parent = NULL;
+ struct discard_cmd *dc;
+ struct blk_plug plug;
+ int issued;
+
+next:
+ issued = 0;
+
+ mutex_lock(&dcc->cmd_lock);
+ f2fs_bug_on(sbi, !__check_rb_tree_consistence(sbi, &dcc->root));
+
+ dc = (struct discard_cmd *)__lookup_rb_tree_ret(&dcc->root,
+ NULL, start,
+ (struct rb_entry **)&prev_dc,
+ (struct rb_entry **)&next_dc,
+ &insert_p, &insert_parent, true);
+ if (!dc)
+ dc = next_dc;
+
+ blk_start_plug(&plug);
+
+ while (dc && dc->lstart <= end) {
+ struct rb_node *node;
+
+ if (dc->len < dpolicy->granularity)
+ goto skip;
+
+ if (dc->state != D_PREP) {
+ list_move_tail(&dc->list, &dcc->fstrim_list);
+ goto skip;
+ }
+
+ __submit_discard_cmd(sbi, dpolicy, dc);
+
+ if (++issued >= dpolicy->max_requests) {
+ start = dc->lstart + dc->len;
+
+ blk_finish_plug(&plug);
+ mutex_unlock(&dcc->cmd_lock);
+ __wait_all_discard_cmd(sbi, NULL);
+ congestion_wait(BLK_RW_ASYNC, HZ/50);
+ goto next;
+ }
+skip:
+ node = rb_next(&dc->rb_node);
+ dc = rb_entry_safe(node, struct discard_cmd, rb_node);
+
+ if (fatal_signal_pending(current))
+ break;
+ }
+
+ blk_finish_plug(&plug);
+ mutex_unlock(&dcc->cmd_lock);
+}
+
int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range)
{
__u64 start = F2FS_BYTES_TO_BLK(range->start);
__u64 end = start + F2FS_BYTES_TO_BLK(range->len) - 1;
- unsigned int start_segno, end_segno, cur_segno;
+ unsigned int start_segno, end_segno;
block_t start_block, end_block;
struct cp_control cpc;
struct discard_policy dpolicy;
@@ -2484,40 +2503,36 @@
cpc.reason = CP_DISCARD;
cpc.trim_minlen = max_t(__u64, 1, F2FS_BYTES_TO_BLK(range->minlen));
+ cpc.trim_start = start_segno;
+ cpc.trim_end = end_segno;
- /* do checkpoint to issue discard commands safely */
- for (cur_segno = start_segno; cur_segno <= end_segno;
- cur_segno = cpc.trim_end + 1) {
- cpc.trim_start = cur_segno;
+ if (sbi->discard_blks == 0)
+ goto out;
- if (sbi->discard_blks == 0)
- break;
- else if (sbi->discard_blks < BATCHED_TRIM_BLOCKS(sbi))
- cpc.trim_end = end_segno;
- else
- cpc.trim_end = min_t(unsigned int,
- rounddown(cur_segno +
- BATCHED_TRIM_SEGMENTS(sbi),
- sbi->segs_per_sec) - 1, end_segno);
-
- mutex_lock(&sbi->gc_mutex);
- err = write_checkpoint(sbi, &cpc);
- mutex_unlock(&sbi->gc_mutex);
- if (err)
- break;
-
- schedule();
- }
+ mutex_lock(&sbi->gc_mutex);
+ err = write_checkpoint(sbi, &cpc);
+ mutex_unlock(&sbi->gc_mutex);
+ if (err)
+ goto out;
start_block = START_BLOCK(sbi, start_segno);
- end_block = START_BLOCK(sbi, min(cur_segno, end_segno) + 1);
+ end_block = START_BLOCK(sbi, end_segno + 1);
- init_discard_policy(&dpolicy, DPOLICY_FSTRIM, cpc.trim_minlen);
+ __init_discard_policy(sbi, &dpolicy, DPOLICY_FSTRIM, cpc.trim_minlen);
__issue_discard_cmd_range(sbi, &dpolicy, start_block, end_block);
- trimmed = __wait_discard_cmd_range(sbi, &dpolicy,
+
+ /*
+ * We filed discard candidates, but actually we don't need to wait for
+ * all of them, since they'll be issued in idle time along with runtime
+ * discard option. User configuration looks like using runtime discard
+ * or periodic fstrim instead of it.
+ */
+ if (!test_opt(sbi, DISCARD)) {
+ trimmed = __wait_discard_cmd_range(sbi, &dpolicy,
start_block, end_block);
+ range->len = F2FS_BLK_TO_BYTES(trimmed);
+ }
out:
- range->len = F2FS_BLK_TO_BYTES(trimmed);
return err;
}
@@ -2840,6 +2855,7 @@
fio.op_flags &= ~REQ_META;
set_page_writeback(page);
+ ClearPageError(page);
f2fs_submit_page_write(&fio);
f2fs_update_iostat(sbi, io_type, F2FS_BLKSIZE);
@@ -3905,8 +3921,6 @@
sm_info->min_hot_blocks = DEF_MIN_HOT_BLOCKS;
sm_info->min_ssr_sections = reserved_sections(sbi);
- sm_info->trim_sections = DEF_BATCHED_TRIM_SECTIONS;
-
INIT_LIST_HEAD(&sm_info->sit_entry_set);
init_rwsem(&sm_info->curseg_lock);
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 1e3cb3a..ca08759 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -756,6 +756,10 @@
} else if (strlen(name) == 6 &&
!strncmp(name, "strict", 6)) {
F2FS_OPTION(sbi).fsync_mode = FSYNC_MODE_STRICT;
+ } else if (strlen(name) == 9 &&
+ !strncmp(name, "nobarrier", 9)) {
+ F2FS_OPTION(sbi).fsync_mode =
+ FSYNC_MODE_NOBARRIER;
} else {
kfree(name);
return -EINVAL;
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 1eb2dfa..5a68f5a 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -245,6 +245,9 @@
return count;
}
+ if (!strcmp(a->attr.name, "trim_sections"))
+ return -EINVAL;
+
*ui = t;
if (!strcmp(a->attr.name, "iostat_enable") && *ui == 0)
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 6b93daf..0289173 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -1765,8 +1765,19 @@
return err;
if (attr->ia_valid & ATTR_OPEN) {
- if (fc->atomic_o_trunc)
+ /* This is coming from open(..., ... | O_TRUNC); */
+ WARN_ON(!(attr->ia_valid & ATTR_SIZE));
+ WARN_ON(attr->ia_size != 0);
+ if (fc->atomic_o_trunc) {
+ /*
+ * No need to send request to userspace, since actual
+ * truncation has already been done by OPEN. But still
+ * need to truncate page cache.
+ */
+ i_size_write(inode, 0);
+ truncate_pagecache(inode, 0);
return 0;
+ }
file = NULL;
}
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index d84be5a..d706777 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -1131,6 +1131,7 @@
err_put_conn:
fuse_bdi_destroy(fc);
fuse_conn_put(fc);
+ sb->s_fs_info = NULL;
err_fput:
fput(file);
err:
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index 4cf2024..2de895f 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -582,6 +582,7 @@
return 0;
out_put_hidden_dir:
+ cancel_delayed_work_sync(&sbi->sync_work);
iput(sbi->hidden_dir);
out_put_root:
dput(sb->s_root);
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 350f67f..e86145b 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -394,7 +394,10 @@
break;
#ifdef CONFIG_JOLIET
case Opt_iocharset:
+ kfree(popt->iocharset);
popt->iocharset = match_strdup(&args[0]);
+ if (!popt->iocharset)
+ return 0;
break;
#endif
case Opt_map_a:
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index 2abbb2b..f3818e7 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -515,6 +515,7 @@
*/
ret = start_this_handle(journal, handle, GFP_NOFS);
if (ret < 0) {
+ handle->h_journal = journal;
jbd2_journal_free_reserved(handle);
return ret;
}
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index 9385560..1313e32 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -207,8 +207,7 @@
__func__, inode->i_ino, inode->i_mode, inode->i_nlink,
f->inocache->pino_nlink, inode->i_mapping->nrpages);
- unlock_new_inode(inode);
- d_instantiate(dentry, inode);
+ d_instantiate_new(dentry, inode);
return 0;
fail:
@@ -427,8 +426,7 @@
mutex_unlock(&dir_f->sem);
jffs2_complete_reservation(c);
- unlock_new_inode(inode);
- d_instantiate(dentry, inode);
+ d_instantiate_new(dentry, inode);
return 0;
fail:
@@ -572,8 +570,7 @@
mutex_unlock(&dir_f->sem);
jffs2_complete_reservation(c);
- unlock_new_inode(inode);
- d_instantiate(dentry, inode);
+ d_instantiate_new(dentry, inode);
return 0;
fail:
@@ -747,8 +744,7 @@
mutex_unlock(&dir_f->sem);
jffs2_complete_reservation(c);
- unlock_new_inode(inode);
- d_instantiate(dentry, inode);
+ d_instantiate_new(dentry, inode);
return 0;
fail:
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 601afd1..c0ff490 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -363,7 +363,6 @@
ret = -EIO;
error:
mutex_unlock(&f->sem);
- jffs2_do_clear_inode(c, f);
iget_failed(inode);
return ERR_PTR(ret);
}
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index d59c7de..d071500 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -176,8 +176,7 @@
unlock_new_inode(ip);
iput(ip);
} else {
- unlock_new_inode(ip);
- d_instantiate(dentry, ip);
+ d_instantiate_new(dentry, ip);
}
out2:
@@ -309,8 +308,7 @@
unlock_new_inode(ip);
iput(ip);
} else {
- unlock_new_inode(ip);
- d_instantiate(dentry, ip);
+ d_instantiate_new(dentry, ip);
}
out2:
@@ -1043,8 +1041,7 @@
unlock_new_inode(ip);
iput(ip);
} else {
- unlock_new_inode(ip);
- d_instantiate(dentry, ip);
+ d_instantiate_new(dentry, ip);
}
out2:
@@ -1424,8 +1421,7 @@
unlock_new_inode(ip);
iput(ip);
} else {
- unlock_new_inode(ip);
- d_instantiate(dentry, ip);
+ d_instantiate_new(dentry, ip);
}
out1:
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 12d339e..bdbe84f 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -271,6 +271,8 @@
if (ln->nlmsvc_users) {
if (--ln->nlmsvc_users == 0) {
nlm_shutdown_hosts_net(net);
+ cancel_delayed_work_sync(&ln->grace_period_end);
+ locks_end_grace(&ln->lockd_manager);
svc_shutdown_net(serv, net);
dprintk("lockd_down_net: per-net data destroyed; net=%p\n", net);
}
diff --git a/fs/nfs/nfs4sysctl.c b/fs/nfs/nfs4sysctl.c
index b6ebe7e..b830563 100644
--- a/fs/nfs/nfs4sysctl.c
+++ b/fs/nfs/nfs4sysctl.c
@@ -31,7 +31,7 @@
.data = &nfs_idmap_cache_timeout,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = proc_dointvec_jiffies,
+ .proc_handler = proc_dointvec,
},
{ }
};
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 660c813..c4010a7 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -3358,7 +3358,8 @@
nfserr = nfserr_resource;
goto err_no_verf;
}
- maxcount = min_t(u32, readdir->rd_maxcount, INT_MAX);
+ maxcount = svc_max_payload(resp->rqstp);
+ maxcount = min_t(u32, readdir->rd_maxcount, maxcount);
/*
* Note the rfc defines rd_maxcount as the size of the
* READDIR4resok structure, which includes the verifier above
@@ -3372,7 +3373,7 @@
/* RFC 3530 14.2.24 allows us to ignore dircount when it's 0: */
if (!readdir->rd_dircount)
- readdir->rd_dircount = INT_MAX;
+ readdir->rd_dircount = svc_max_payload(resp->rqstp);
readdir->xdr = xdr;
readdir->rd_maxcount = maxcount;
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c
index 0f84b25..da65882 100644
--- a/fs/nilfs2/namei.c
+++ b/fs/nilfs2/namei.c
@@ -50,8 +50,7 @@
{
int err = nilfs_add_link(dentry, inode);
if (!err) {
- d_instantiate(dentry, inode);
- unlock_new_inode(inode);
+ d_instantiate_new(dentry, inode);
return 0;
}
inode_dec_link_count(inode);
@@ -249,8 +248,7 @@
goto out_fail;
nilfs_mark_inode_dirty(inode);
- d_instantiate(dentry, inode);
- unlock_new_inode(inode);
+ d_instantiate_new(dentry, inode);
out:
if (!err)
err = nilfs_transaction_commit(dir->i_sb);
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index e1f24ed..3fb323e 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -135,8 +135,9 @@
const unsigned char *file_name)
{
struct fsnotify_group *group = NULL;
- __u32 inode_test_mask = 0;
- __u32 vfsmount_test_mask = 0;
+ __u32 test_mask = (mask & ~FS_EVENT_ON_CHILD);
+ __u32 marks_mask = 0;
+ __u32 marks_ignored_mask = 0;
if (unlikely(!inode_mark && !vfsmount_mark)) {
BUG();
@@ -156,29 +157,25 @@
/* does the inode mark tell us to do something? */
if (inode_mark) {
group = inode_mark->group;
- inode_test_mask = (mask & ~FS_EVENT_ON_CHILD);
- inode_test_mask &= inode_mark->mask;
- inode_test_mask &= ~inode_mark->ignored_mask;
+ marks_mask |= inode_mark->mask;
+ marks_ignored_mask |= inode_mark->ignored_mask;
}
/* does the vfsmount_mark tell us to do something? */
if (vfsmount_mark) {
- vfsmount_test_mask = (mask & ~FS_EVENT_ON_CHILD);
group = vfsmount_mark->group;
- vfsmount_test_mask &= vfsmount_mark->mask;
- vfsmount_test_mask &= ~vfsmount_mark->ignored_mask;
- if (inode_mark)
- vfsmount_test_mask &= ~inode_mark->ignored_mask;
+ marks_mask |= vfsmount_mark->mask;
+ marks_ignored_mask |= vfsmount_mark->ignored_mask;
}
pr_debug("%s: group=%p to_tell=%p mask=%x inode_mark=%p"
- " inode_test_mask=%x vfsmount_mark=%p vfsmount_test_mask=%x"
+ " vfsmount_mark=%p marks_mask=%x marks_ignored_mask=%x"
" data=%p data_is=%d cookie=%d\n",
- __func__, group, to_tell, mask, inode_mark,
- inode_test_mask, vfsmount_mark, vfsmount_test_mask, data,
+ __func__, group, to_tell, mask, inode_mark, vfsmount_mark,
+ marks_mask, marks_ignored_mask, data,
data_is, cookie);
- if (!inode_test_mask && !vfsmount_test_mask)
+ if (!(test_mask & marks_mask & ~marks_ignored_mask))
return 0;
return group->ops->handle_event(group, to_tell, inode_mark,
diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c
index badbf8b..bc79df2 100644
--- a/fs/ocfs2/acl.c
+++ b/fs/ocfs2/acl.c
@@ -298,7 +298,9 @@
if (ret < 0)
return ERR_PTR(ret);
+ down_read(&OCFS2_I(inode)->ip_xattr_sem);
acl = ocfs2_get_acl_nolock(inode, type, di_bh);
+ up_read(&OCFS2_I(inode)->ip_xattr_sem);
brelse(di_bh);
@@ -317,7 +319,9 @@
if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL))
return 0;
+ down_read(&OCFS2_I(inode)->ip_xattr_sem);
acl = ocfs2_get_acl_nolock(inode, ACL_TYPE_ACCESS, bh);
+ up_read(&OCFS2_I(inode)->ip_xattr_sem);
if (IS_ERR(acl) || !acl)
return PTR_ERR(acl);
ret = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
@@ -348,8 +352,10 @@
if (!S_ISLNK(inode->i_mode)) {
if (osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) {
+ down_read(&OCFS2_I(dir)->ip_xattr_sem);
acl = ocfs2_get_acl_nolock(dir, ACL_TYPE_DEFAULT,
dir_bh);
+ up_read(&OCFS2_I(dir)->ip_xattr_sem);
if (IS_ERR(acl))
return PTR_ERR(acl);
}
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 93c85bc..c8d4934 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -467,9 +467,8 @@
new = ocfs2_get_system_file_inode(osb, i, osb->slot_num);
if (!new) {
ocfs2_release_system_inodes(osb);
- status = -EINVAL;
+ status = ocfs2_is_soft_readonly(osb) ? -EROFS : -EINVAL;
mlog_errno(status);
- /* FIXME: Should ERROR_RO_FS */
mlog(ML_ERROR, "Unable to load system inode %d, "
"possibly corrupt fs?", i);
goto bail;
@@ -498,7 +497,7 @@
new = ocfs2_get_system_file_inode(osb, i, osb->slot_num);
if (!new) {
ocfs2_release_system_inodes(osb);
- status = -EINVAL;
+ status = ocfs2_is_soft_readonly(osb) ? -EROFS : -EINVAL;
mlog(ML_ERROR, "status=%d, sysfile=%d, slot=%d\n",
status, i, osb->slot_num);
goto bail;
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index c237008..068e8af 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -645,9 +645,11 @@
si->value_len);
if (osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) {
+ down_read(&OCFS2_I(dir)->ip_xattr_sem);
acl_len = ocfs2_xattr_get_nolock(dir, dir_bh,
OCFS2_XATTR_INDEX_POSIX_ACL_DEFAULT,
"", NULL, 0);
+ up_read(&OCFS2_I(dir)->ip_xattr_sem);
if (acl_len > 0) {
a_size = ocfs2_xattr_entry_real_size(0, acl_len);
if (S_ISDIR(mode))
diff --git a/fs/pipe.c b/fs/pipe.c
index a0cb844..d2717fb 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -618,6 +618,9 @@
unsigned long pipe_bufs = PIPE_DEF_BUFFERS;
struct user_struct *user = get_current_user();
+ if (pipe_bufs * PAGE_SIZE > pipe_max_size && !capable(CAP_SYS_RESOURCE))
+ pipe_bufs = pipe_max_size >> PAGE_SHIFT;
+
if (!too_many_pipe_buffers_hard(user)) {
if (too_many_pipe_buffers_soft(user))
pipe_bufs = 1;
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 077550b..f3858e3 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -94,6 +94,8 @@
#include "internal.h"
#include "fd.h"
+#include "../../lib/kstrtox.h"
+
/* NOTE:
* Implementing inode permission operations in /proc is almost
* certainly an error. Permission checks need to happen during
@@ -1846,8 +1848,33 @@
static int dname_to_vma_addr(struct dentry *dentry,
unsigned long *start, unsigned long *end)
{
- if (sscanf(dentry->d_name.name, "%lx-%lx", start, end) != 2)
+ const char *str = dentry->d_name.name;
+ unsigned long long sval, eval;
+ unsigned int len;
+
+ len = _parse_integer(str, 16, &sval);
+ if (len & KSTRTOX_OVERFLOW)
return -EINVAL;
+ if (sval != (unsigned long)sval)
+ return -EINVAL;
+ str += len;
+
+ if (*str != '-')
+ return -EINVAL;
+ str++;
+
+ len = _parse_integer(str, 16, &eval);
+ if (len & KSTRTOX_OVERFLOW)
+ return -EINVAL;
+ if (eval != (unsigned long)eval)
+ return -EINVAL;
+ str += len;
+
+ if (*str != '\0')
+ return -EINVAL;
+
+ *start = sval;
+ *end = eval;
return 0;
}
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index 35f3864..7c24d73 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -618,7 +618,10 @@
struct ctl_table *table)
{
bool ret = true;
+
head = sysctl_head_grab(head);
+ if (IS_ERR(head))
+ return false;
if (S_ISLNK(table->mode)) {
/* It is not an error if we can not follow the link ignore it */
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index cd11358..2e9d82f 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -682,8 +682,7 @@
reiserfs_update_inode_transaction(inode);
reiserfs_update_inode_transaction(dir);
- unlock_new_inode(inode);
- d_instantiate(dentry, inode);
+ d_instantiate_new(dentry, inode);
retval = journal_end(&th);
out_failed:
@@ -763,8 +762,7 @@
goto out_failed;
}
- unlock_new_inode(inode);
- d_instantiate(dentry, inode);
+ d_instantiate_new(dentry, inode);
retval = journal_end(&th);
out_failed:
@@ -857,8 +855,7 @@
/* the above add_entry did not update dir's stat data */
reiserfs_update_sd(&th, dir);
- unlock_new_inode(inode);
- d_instantiate(dentry, inode);
+ d_instantiate_new(dentry, inode);
retval = journal_end(&th);
out_failed:
reiserfs_write_unlock(dir->i_sb);
@@ -1162,8 +1159,7 @@
goto out_failed;
}
- unlock_new_inode(inode);
- d_instantiate(dentry, inode);
+ d_instantiate_new(dentry, inode);
retval = journal_end(&th);
out_failed:
reiserfs_write_unlock(parent_dir->i_sb);
diff --git a/fs/sdcardfs/dentry.c b/fs/sdcardfs/dentry.c
index 8c265ea..5327579 100644
--- a/fs/sdcardfs/dentry.c
+++ b/fs/sdcardfs/dentry.c
@@ -51,7 +51,6 @@
* whether the base obbpath has been changed or not
*/
if (is_obbpath_invalid(dentry)) {
- d_drop(dentry);
return 0;
}
@@ -65,7 +64,6 @@
if ((lower_dentry->d_flags & DCACHE_OP_REVALIDATE)) {
err = lower_dentry->d_op->d_revalidate(lower_dentry, flags);
if (err == 0) {
- d_drop(dentry);
goto out;
}
}
@@ -73,14 +71,12 @@
spin_lock(&lower_dentry->d_lock);
if (d_unhashed(lower_dentry)) {
spin_unlock(&lower_dentry->d_lock);
- d_drop(dentry);
err = 0;
goto out;
}
spin_unlock(&lower_dentry->d_lock);
if (parent_lower_dentry != lower_cur_parent_dentry) {
- d_drop(dentry);
err = 0;
goto out;
}
@@ -94,7 +90,6 @@
}
if (!qstr_case_eq(&dentry->d_name, &lower_dentry->d_name)) {
- __d_drop(dentry);
err = 0;
}
@@ -113,7 +108,6 @@
if (inode) {
data = top_data_get(SDCARDFS_I(inode));
if (!data || data->abandoned) {
- d_drop(dentry);
err = 0;
}
if (data)
diff --git a/fs/sdcardfs/inode.c b/fs/sdcardfs/inode.c
index 771b402..89423d0 100644
--- a/fs/sdcardfs/inode.c
+++ b/fs/sdcardfs/inode.c
@@ -270,6 +270,7 @@
struct dentry *lower_dentry;
struct vfsmount *lower_mnt;
struct dentry *lower_parent_dentry = NULL;
+ struct dentry *parent_dentry = NULL;
struct path lower_path;
struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb);
const struct cred *saved_cred = NULL;
@@ -289,11 +290,14 @@
OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred, SDCARDFS_I(dir));
/* check disk space */
- if (!check_min_free_space(dentry, 0, 1)) {
+ parent_dentry = dget_parent(dentry);
+ if (!check_min_free_space(parent_dentry, 0, 1)) {
pr_err("sdcardfs: No minimum free space.\n");
err = -ENOSPC;
+ dput(parent_dentry);
goto out_revert;
}
+ dput(parent_dentry);
/* the lower_dentry is negative here */
sdcardfs_get_lower_path(dentry, &lower_path);
diff --git a/fs/sdcardfs/main.c b/fs/sdcardfs/main.c
index a2c906e..d143391 100644
--- a/fs/sdcardfs/main.c
+++ b/fs/sdcardfs/main.c
@@ -264,7 +264,7 @@
pr_info("sdcardfs: dev_name -> %s\n", dev_name);
pr_info("sdcardfs: options -> %s\n", (char *)raw_data);
- pr_info("sdcardfs: mnt -> %p\n", mnt);
+ pr_info("sdcardfs: mnt -> %pK\n", mnt);
/* parse lower path */
err = kern_path(dev_name, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
diff --git a/fs/sdcardfs/super.c b/fs/sdcardfs/super.c
index cffcdb1..fa7d9d2 100644
--- a/fs/sdcardfs/super.c
+++ b/fs/sdcardfs/super.c
@@ -144,7 +144,7 @@
pr_err("sdcardfs: remount flags 0x%x unsupported\n", *flags);
err = -EINVAL;
}
- pr_info("Remount options were %s for vfsmnt %p.\n", options, mnt);
+ pr_info("Remount options were %s for vfsmnt %pK.\n", options, mnt);
err = parse_options_remount(sb, options, *flags & ~MS_SILENT, mnt->data);
diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c
index 90ae1a8..ff53c03 100644
--- a/fs/ubifs/journal.c
+++ b/fs/ubifs/journal.c
@@ -1107,7 +1107,7 @@
int err, len, compr_type, out_len;
out_len = le32_to_cpu(dn->size);
- buf = kmalloc(out_len * WORST_COMPR_FACTOR, GFP_NOFS);
+ buf = kmalloc_array(out_len, WORST_COMPR_FACTOR, GFP_NOFS);
if (!buf)
return -ENOMEM;
diff --git a/fs/udf/directory.c b/fs/udf/directory.c
index 3e44f57..f59003b1a 100644
--- a/fs/udf/directory.c
+++ b/fs/udf/directory.c
@@ -151,6 +151,9 @@
sizeof(struct fileIdentDesc));
}
}
+ /* Got last entry outside of dir size - fs is corrupted! */
+ if (*nf_pos > dir->i_size)
+ return NULL;
return fi;
}
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index 6ff19b5..3bff8a2 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -574,8 +574,7 @@
if (fibh.sbh != fibh.ebh)
brelse(fibh.ebh);
brelse(fibh.sbh);
- unlock_new_inode(inode);
- d_instantiate(dentry, inode);
+ d_instantiate_new(dentry, inode);
return 0;
}
@@ -684,8 +683,7 @@
udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
inc_nlink(dir);
mark_inode_dirty(dir);
- unlock_new_inode(inode);
- d_instantiate(dentry, inode);
+ d_instantiate_new(dentry, inode);
if (fibh.sbh != fibh.ebh)
brelse(fibh.ebh);
brelse(fibh.sbh);
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 592918e..1ed8f0d 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -2067,8 +2067,9 @@
struct udf_sb_info *sbi;
uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT);
- uopt.uid = INVALID_UID;
- uopt.gid = INVALID_GID;
+ /* By default we'll use overflow[ug]id when UDF inode [ug]id == -1 */
+ uopt.uid = make_kuid(current_user_ns(), overflowuid);
+ uopt.gid = make_kgid(current_user_ns(), overflowgid);
uopt.umask = 0;
uopt.fmode = UDF_INVALID_MODE;
uopt.dmode = UDF_INVALID_MODE;
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c
index e8ee298..2f446e7 100644
--- a/fs/ufs/namei.c
+++ b/fs/ufs/namei.c
@@ -38,8 +38,7 @@
{
int err = ufs_add_link(dentry, inode);
if (!err) {
- unlock_new_inode(inode);
- d_instantiate(dentry, inode);
+ d_instantiate_new(dentry, inode);
return 0;
}
inode_dec_link_count(inode);
@@ -212,8 +211,7 @@
goto out_fail;
unlock_ufs(dir->i_sb);
- unlock_new_inode(inode);
- d_instantiate(dentry, inode);
+ d_instantiate_new(dentry, inode);
out:
return err;
diff --git a/fs/xfs/xfs_discard.c b/fs/xfs/xfs_discard.c
index 13d08a1..cfa6bb1 100644
--- a/fs/xfs/xfs_discard.c
+++ b/fs/xfs/xfs_discard.c
@@ -51,6 +51,13 @@
pag = xfs_perag_get(mp, agno);
+ /*
+ * Force out the log. This means any transactions that might have freed
+ * space before we take the AGF buffer lock are now on disk, and the
+ * volatile disk cache is flushed.
+ */
+ xfs_log_force(mp, XFS_LOG_SYNC);
+
error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agbp);
if (error || !agbp)
goto out_put_perag;
@@ -58,13 +65,6 @@
cur = xfs_allocbt_init_cursor(mp, NULL, agbp, agno, XFS_BTNUM_CNT);
/*
- * Force out the log. This means any transactions that might have freed
- * space before we took the AGF buffer lock are now on disk, and the
- * volatile disk cache is flushed.
- */
- xfs_log_force(mp, XFS_LOG_SYNC);
-
- /*
* Look up the longest btree in the AGF and start with it.
*/
error = xfs_alloc_lookup_ge(cur, 0,
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index 752e30d..d33fdae 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -181,6 +181,21 @@
extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp);
#endif
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+/*
+ * This is an implementation of pmdp_establish() that is only suitable for an
+ * architecture that doesn't have hardware dirty/accessed bits. In this case we
+ * can't race with CPU which sets these bits and non-atomic aproach is fine.
+ */
+static inline pmd_t generic_pmdp_establish(struct vm_area_struct *vma,
+ unsigned long address, pmd_t *pmdp, pmd_t pmd)
+{
+ pmd_t old_pmd = *pmdp;
+ set_pmd_at(vma->vm_mm, address, pmdp, pmd);
+ return old_pmd;
+}
+#endif
+
#ifndef __HAVE_ARCH_PMDP_INVALIDATE
extern void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
pmd_t *pmdp);
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 901ded7..6bf4176 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -924,8 +924,8 @@
if (!q->limits.chunk_sectors)
return q->limits.max_sectors;
- return q->limits.chunk_sectors -
- (offset & (q->limits.chunk_sectors - 1));
+ return min(q->limits.max_sectors, (unsigned int)(q->limits.chunk_sectors -
+ (offset & (q->limits.chunk_sectors - 1))));
}
static inline unsigned int blk_rq_get_max_sectors(struct request *rq)
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index a8a9ece..4c981ad 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -105,7 +105,7 @@
#define unlikely_notrace(x) __builtin_expect(!!(x), 0)
#define __branch_check__(x, expect) ({ \
- int ______r; \
+ long ______r; \
static struct ftrace_branch_data \
__attribute__((__aligned__(4))) \
__attribute__((section("_ftrace_annotated_branch"))) \
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 331c1d6..cca7e92 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -234,6 +234,7 @@
* These are the low-level FS interfaces to the dcache..
*/
extern void d_instantiate(struct dentry *, struct inode *);
+extern void d_instantiate_new(struct dentry *, struct inode *);
extern struct dentry * d_instantiate_unique(struct dentry *, struct inode *);
#define d_materialise_unique(d, i) d_splice_alias(i, d)
extern int d_instantiate_no_diralias(struct dentry *, struct inode *);
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 0e20fd1..9b0a645 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -360,8 +360,8 @@
u32 attributes;
u32 get_bar_attributes;
u32 set_bar_attributes;
- uint64_t romsize;
- void *romimage;
+ u64 romsize;
+ u32 romimage;
} efi_pci_io_protocol_32;
typedef struct {
@@ -380,8 +380,8 @@
u64 attributes;
u64 get_bar_attributes;
u64 set_bar_attributes;
- uint64_t romsize;
- void *romimage;
+ u64 romsize;
+ u64 romimage;
} efi_pci_io_protocol_64;
typedef struct {
diff --git a/include/linux/input/synaptics_dsx_v2_6.h b/include/linux/input/synaptics_dsx_v2_6.h
index eb26111..7cf0a16 100644
--- a/include/linux/input/synaptics_dsx_v2_6.h
+++ b/include/linux/input/synaptics_dsx_v2_6.h
@@ -5,7 +5,7 @@
*
* Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
* Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com>
- * Copyright (C) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2016, 2018 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -115,6 +115,7 @@
const char *bus_reg_name;
struct synaptics_dsx_button_map *cap_button_map;
struct synaptics_dsx_button_map *vir_button_map;
+ const char *fw_name;
};
#endif
diff --git a/include/linux/msm_mhi_dev.h b/include/linux/msm_mhi_dev.h
index 7eb1d06..e765697 100644
--- a/include/linux/msm_mhi_dev.h
+++ b/include/linux/msm_mhi_dev.h
@@ -135,6 +135,7 @@
MHI_CLIENT_RESERVED_2_LOWER = 102,
MHI_CLIENT_RESERVED_2_UPPER = 127,
MHI_MAX_CHANNELS = 102,
+ MHI_CLIENT_INVALID = 0xFFFFFFFF
};
struct mhi_dev_client_cb_data {
diff --git a/include/linux/mtd/flashchip.h b/include/linux/mtd/flashchip.h
index b63fa45..3529683 100644
--- a/include/linux/mtd/flashchip.h
+++ b/include/linux/mtd/flashchip.h
@@ -85,6 +85,7 @@
unsigned int write_suspended:1;
unsigned int erase_suspended:1;
unsigned long in_progress_block_addr;
+ unsigned long in_progress_block_mask;
struct mutex mutex;
wait_queue_head_t wq; /* Wait on here when we're waiting for the chip
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index 57b77c1..85322c3 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -341,6 +341,8 @@
extern void swsusp_set_page_free(struct page *);
extern void swsusp_unset_page_free(struct page *);
extern unsigned long get_safe_page(gfp_t gfp_mask);
+extern asmlinkage int swsusp_arch_suspend(void);
+extern asmlinkage int swsusp_arch_resume(void);
extern void hibernation_set_ops(const struct platform_hibernation_ops *ops);
extern int hibernate(void);
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 9891c30..4a2578f 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -292,7 +292,7 @@
/* Receiver queue space */
struct {
- int space;
+ u32 space;
u32 seq;
u32 time;
} rcvq_space;
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
index a2c92b6..fe3fc7c 100644
--- a/include/linux/usb/composite.h
+++ b/include/linux/usb/composite.h
@@ -60,6 +60,9 @@
/* big enough to hold our biggest descriptor */
#define USB_COMP_EP0_BUFSIZ 4096
+/* OS feature descriptor length <= 4kB */
+#define USB_COMP_EP0_OS_DESC_BUFSIZ 4096
+
#define USB_MS_TO_HS_INTERVAL(x) (ilog2((x * 1000 / 125)) + 1)
struct usb_configuration;
diff --git a/include/linux/virtio.h b/include/linux/virtio.h
index 65261a7..8ffec6d 100644
--- a/include/linux/virtio.h
+++ b/include/linux/virtio.h
@@ -122,6 +122,9 @@
int virtio_device_restore(struct virtio_device *dev);
#endif
+#define virtio_device_for_each_vq(vdev, vq) \
+ list_for_each_entry(vq, &vdev->vqs, list)
+
/**
* virtio_driver - operations for a virtio I/O driver
* @driver: underlying device driver (populate name and owner).
diff --git a/include/net/cnss.h b/include/net/cnss.h
index 0ed1908..c7f41e3 100644
--- a/include/net/cnss.h
+++ b/include/net/cnss.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -37,11 +37,6 @@
CNSS_SOURCE_USER
};
-enum cnss_wlan_status {
- CNSS_WLAN_LINK_DOWN,
- CNSS_WLAN_SSR_FAIL
-};
-
/* FW image files */
struct cnss_fw_files {
char image_file[CNSS_MAX_FILE_NAME];
@@ -107,11 +102,14 @@
u32 cap_flag;
};
-/* WLAN driver status */
+/* WLAN driver status, keep it aligned with cnss2 */
enum cnss_driver_status {
CNSS_UNINITIALIZED,
CNSS_INITIALIZED,
- CNSS_LOAD_UNLOAD
+ CNSS_LOAD_UNLOAD,
+ CNSS_RECOVERY,
+ CNSS_FW_DOWN,
+ CNSS_SSR_FAIL,
};
enum cnss_runtime_request {
diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h
index d3be7d3..b035f5d 100644
--- a/include/net/inet_timewait_sock.h
+++ b/include/net/inet_timewait_sock.h
@@ -55,6 +55,7 @@
#define tw_family __tw_common.skc_family
#define tw_state __tw_common.skc_state
#define tw_reuse __tw_common.skc_reuse
+#define tw_reuseport __tw_common.skc_reuseport
#define tw_ipv6only __tw_common.skc_ipv6only
#define tw_bound_dev_if __tw_common.skc_bound_dev_if
#define tw_node __tw_common.skc_nulls_node
diff --git a/include/net/llc_conn.h b/include/net/llc_conn.h
index 72f26e8a..b0aa903 100644
--- a/include/net/llc_conn.h
+++ b/include/net/llc_conn.h
@@ -104,7 +104,7 @@
/* Access to a connection */
int llc_conn_state_process(struct sock *sk, struct sk_buff *skb);
-void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb);
+int llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb);
void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb);
void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr, u8 first_p_bit);
void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr, u8 first_f_bit);
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 48ad5de..03decda 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -3397,7 +3397,7 @@
* The TX headroom reserved by mac80211 for its own tx_status functions.
* This is enough for the radiotap header.
*/
-#define IEEE80211_TX_STATUS_HEADROOM 14
+#define IEEE80211_TX_STATUS_HEADROOM ALIGN(14, 4)
/**
* ieee80211_sta_set_buffered - inform mac80211 about driver-buffered frames
diff --git a/include/net/nexthop.h b/include/net/nexthop.h
index 3334dbf..7fc7866 100644
--- a/include/net/nexthop.h
+++ b/include/net/nexthop.h
@@ -6,7 +6,7 @@
static inline int rtnh_ok(const struct rtnexthop *rtnh, int remaining)
{
- return remaining >= sizeof(*rtnh) &&
+ return remaining >= (int)sizeof(*rtnh) &&
rtnh->rtnh_len >= sizeof(*rtnh) &&
rtnh->rtnh_len <= remaining;
}
diff --git a/include/net/regulatory.h b/include/net/regulatory.h
index dad7ab2..c95dcba 100644
--- a/include/net/regulatory.h
+++ b/include/net/regulatory.h
@@ -78,7 +78,7 @@
int wiphy_idx;
enum nl80211_reg_initiator initiator;
enum nl80211_user_reg_hint_type user_reg_hint_type;
- char alpha2[2];
+ char alpha2[3];
enum nl80211_dfs_regions dfs_region;
bool intersect;
bool processed;
diff --git a/include/trace/events/timer.h b/include/trace/events/timer.h
index 68c2c20..9e4af35 100644
--- a/include/trace/events/timer.h
+++ b/include/trace/events/timer.h
@@ -121,6 +121,20 @@
TP_ARGS(timer)
);
+#define decode_clockid(type) \
+ __print_symbolic(type, \
+ { CLOCK_REALTIME, "CLOCK_REALTIME" }, \
+ { CLOCK_MONOTONIC, "CLOCK_MONOTONIC" }, \
+ { CLOCK_BOOTTIME, "CLOCK_BOOTTIME" }, \
+ { CLOCK_TAI, "CLOCK_TAI" })
+
+#define decode_hrtimer_mode(mode) \
+ __print_symbolic(mode, \
+ { HRTIMER_MODE_ABS, "ABS" }, \
+ { HRTIMER_MODE_REL, "REL" }, \
+ { HRTIMER_MODE_ABS_PINNED, "ABS|PINNED" }, \
+ { HRTIMER_MODE_REL_PINNED, "REL|PINNED" })
+
/**
* hrtimer_init - called when the hrtimer is initialized
* @hrtimer: pointer to struct hrtimer
@@ -147,10 +161,8 @@
),
TP_printk("hrtimer=%p clockid=%s mode=%s", __entry->hrtimer,
- __entry->clockid == CLOCK_REALTIME ?
- "CLOCK_REALTIME" : "CLOCK_MONOTONIC",
- __entry->mode == HRTIMER_MODE_ABS ?
- "HRTIMER_MODE_ABS" : "HRTIMER_MODE_REL")
+ decode_clockid(__entry->clockid),
+ decode_hrtimer_mode(__entry->mode))
);
/**
diff --git a/include/trace/events/xen.h b/include/trace/events/xen.h
index d06b6da..79c42ed 100644
--- a/include/trace/events/xen.h
+++ b/include/trace/events/xen.h
@@ -377,22 +377,6 @@
DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_pin);
DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_unpin);
-TRACE_EVENT(xen_mmu_flush_tlb_all,
- TP_PROTO(int x),
- TP_ARGS(x),
- TP_STRUCT__entry(__array(char, x, 0)),
- TP_fast_assign((void)x),
- TP_printk("%s", "")
- );
-
-TRACE_EVENT(xen_mmu_flush_tlb,
- TP_PROTO(int x),
- TP_ARGS(x),
- TP_STRUCT__entry(__array(char, x, 0)),
- TP_fast_assign((void)x),
- TP_printk("%s", "")
- );
-
TRACE_EVENT(xen_mmu_flush_tlb_single,
TP_PROTO(unsigned long addr),
TP_ARGS(addr),
diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
index 60d2749..d122ea5 100644
--- a/include/uapi/linux/fs.h
+++ b/include/uapi/linux/fs.h
@@ -193,6 +193,8 @@
#define FS_ENCRYPTION_MODE_AES_256_CTS 4
#define FS_ENCRYPTION_MODE_AES_128_CBC 5
#define FS_ENCRYPTION_MODE_AES_128_CTS 6
+#define FS_ENCRYPTION_MODE_SPECK128_256_XTS 7
+#define FS_ENCRYPTION_MODE_SPECK128_256_CTS 8
struct fscrypt_policy {
diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h
index dd28482..8c964e2 100644
--- a/include/uapi/linux/if_ether.h
+++ b/include/uapi/linux/if_ether.h
@@ -29,6 +29,7 @@
*/
#define ETH_ALEN 6 /* Octets in one ethernet addr */
+#define ETH_TLEN 2 /* Octets in ethernet type field */
#define ETH_HLEN 14 /* Total octets in header. */
#define ETH_ZLEN 60 /* Min. octets in frame sans FCS */
#define ETH_DATA_LEN 1500 /* Max. octets in payload */
diff --git a/include/uapi/linux/msm_ipa.h b/include/uapi/linux/msm_ipa.h
index 3f48157..df4e6b2 100644
--- a/include/uapi/linux/msm_ipa.h
+++ b/include/uapi/linux/msm_ipa.h
@@ -475,7 +475,13 @@
IPA_SSR_EVENT_MAX,
};
-#define IPA_EVENT_MAX_NUM (IPA_SSR_EVENT_MAX)
+enum ipa_wlan_fw_ssr_event {
+ WLAN_FWR_SSR_BEFORE_SHUTDOWN = IPA_SSR_EVENT_MAX,
+ IPA_WLAN_FW_SSR_EVENT_MAX
+#define IPA_WLAN_FW_SSR_EVENT_MAX IPA_WLAN_FW_SSR_EVENT_MAX
+};
+
+#define IPA_EVENT_MAX_NUM (IPA_WLAN_FW_SSR_EVENT_MAX)
/**
* enum ipa_rm_resource_name - IPA RM clients identification names
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 9e6ad4a..468899e 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2358,6 +2358,8 @@
#define NL80211_ATTR_KEYS NL80211_ATTR_KEYS
#define NL80211_ATTR_FEATURE_FLAGS NL80211_ATTR_FEATURE_FLAGS
+#define NL80211_WIPHY_NAME_MAXLEN 64
+
#define NL80211_MAX_SUPP_RATES 32
#define NL80211_MAX_SUPP_HT_RATES 77
#define NL80211_MAX_SUPP_REG_RULES 32
diff --git a/include/uapi/linux/smcinvoke.h b/include/uapi/linux/smcinvoke.h
index 1dc9a63..1b0a754 100644
--- a/include/uapi/linux/smcinvoke.h
+++ b/include/uapi/linux/smcinvoke.h
@@ -30,11 +30,11 @@
* @args - args is pointer to buffer having all arguments
*/
struct smcinvoke_cmd_req {
- uint32_t op;
- uint32_t counts;
- int32_t result;
- uint32_t argsize;
- uint64_t __user args;
+ uint32_t op;
+ uint32_t counts;
+ int32_t result;
+ uint32_t argsize;
+ uint64_t args;
};
#define SMCINVOKE_IOC_MAGIC 0x98
diff --git a/include/uapi/media/msm_vidc.h b/include/uapi/media/msm_vidc.h
index 06924f8..8965647 100644
--- a/include/uapi/media/msm_vidc.h
+++ b/include/uapi/media/msm_vidc.h
@@ -345,6 +345,15 @@
MSM_VIDC_TRANSFER_SRGB = 13,
MSM_VIDC_TRANSFER_BT_2020_10 = 14,
MSM_VIDC_TRANSFER_BT_2020_12 = 15,
+#define MSM_VIDC_TRANSFER_SMPTE_ST2084 \
+ MSM_VIDC_TRANSFER_SMPTE_ST2084
+ MSM_VIDC_TRANSFER_SMPTE_ST2084 = 16,
+#define MSM_VIDC_TRANSFER_SMPTE_ST428_1 \
+ MSM_VIDC_TRANSFER_SMPTE_ST428_1
+ MSM_VIDC_TRANSFER_SMPTE_ST428_1 = 17,
+#define MSM_VIDC_TRANSFER_HLG \
+ MSM_VIDC_TRANSFER_HLG
+ MSM_VIDC_TRANSFER_HLG = 18,
};
enum msm_vidc_pixel_depth {
diff --git a/kernel/audit.c b/kernel/audit.c
index bc06f64..a2c3dec 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -738,6 +738,8 @@
return;
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_FEATURE_CHANGE);
+ if (!ab)
+ return;
audit_log_task_info(ab, current);
audit_log_format(ab, " feature=%s old=%u new=%u old_lock=%u new_lock=%u res=%d",
audit_feature_names[which], !!old_feature, !!new_feature,
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c
index 6ffdc96..f7968ca 100644
--- a/kernel/debug/kdb/kdb_main.c
+++ b/kernel/debug/kdb/kdb_main.c
@@ -1524,6 +1524,7 @@
int symbolic = 0;
int valid = 0;
int phys = 0;
+ int raw = 0;
kdbgetintenv("MDCOUNT", &mdcount);
kdbgetintenv("RADIX", &radix);
@@ -1533,9 +1534,10 @@
repeat = mdcount * 16 / bytesperword;
if (strcmp(argv[0], "mdr") == 0) {
- if (argc != 2)
+ if (argc == 2 || (argc == 0 && last_addr != 0))
+ valid = raw = 1;
+ else
return KDB_ARGCOUNT;
- valid = 1;
} else if (isdigit(argv[0][2])) {
bytesperword = (int)(argv[0][2] - '0');
if (bytesperword == 0) {
@@ -1571,7 +1573,10 @@
radix = last_radix;
bytesperword = last_bytesperword;
repeat = last_repeat;
- mdcount = ((repeat * bytesperword) + 15) / 16;
+ if (raw)
+ mdcount = repeat;
+ else
+ mdcount = ((repeat * bytesperword) + 15) / 16;
}
if (argc) {
@@ -1588,7 +1593,10 @@
diag = kdbgetularg(argv[nextarg], &val);
if (!diag) {
mdcount = (int) val;
- repeat = mdcount * 16 / bytesperword;
+ if (raw)
+ repeat = mdcount;
+ else
+ repeat = mdcount * 16 / bytesperword;
}
}
if (argc >= nextarg+1) {
@@ -1598,8 +1606,15 @@
}
}
- if (strcmp(argv[0], "mdr") == 0)
- return kdb_mdr(addr, mdcount);
+ if (strcmp(argv[0], "mdr") == 0) {
+ int ret;
+ last_addr = addr;
+ ret = kdb_mdr(addr, mdcount);
+ last_addr += mdcount;
+ last_repeat = mdcount;
+ last_bytesperword = bytesperword; // to make REPEAT happy
+ return ret;
+ }
switch (radix) {
case 10:
diff --git a/kernel/events/callchain.c b/kernel/events/callchain.c
index d659487..d37acf8 100644
--- a/kernel/events/callchain.c
+++ b/kernel/events/callchain.c
@@ -107,14 +107,8 @@
goto exit;
}
- if (count > 1) {
- /* If the allocation failed, give up */
- if (!callchain_cpus_entries)
- err = -ENOMEM;
- goto exit;
- }
-
- err = alloc_callchain_buffers();
+ if (count == 1)
+ err = alloc_callchain_buffers();
exit:
if (err)
atomic_dec(&nr_callchain_events);
diff --git a/kernel/events/core.c b/kernel/events/core.c
index de4a75c..267e451 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -230,7 +230,7 @@
void __user *buffer, size_t *lenp,
loff_t *ppos)
{
- int ret = proc_dointvec(table, write, buffer, lenp, ppos);
+ int ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
if (ret || !write)
return ret;
@@ -3331,18 +3331,16 @@
* Returns a matching context with refcount and pincount.
*/
static struct perf_event_context *
-find_get_context(struct perf_event *event, struct task_struct *task, int cpu)
+find_get_context(struct pmu *pmu, struct task_struct *task, int cpu, bool check)
{
struct perf_event_context *ctx, *clone_ctx = NULL;
struct perf_cpu_context *cpuctx;
- struct pmu *pmu = event->pmu;
unsigned long flags;
int ctxn, err;
if (!task) {
/* Must be root to operate on a CPU event: */
- if (event->owner != EVENT_OWNER_KERNEL && perf_paranoid_cpu() &&
- !capable(CAP_SYS_ADMIN))
+ if (check && perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN))
return ERR_PTR(-EACCES);
/*
@@ -4910,7 +4908,8 @@
if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
values[n++] = running;
- if (leader != event)
+ if ((leader != event) &&
+ (leader->state == PERF_EVENT_STATE_ACTIVE))
leader->pmu->read(leader);
values[n++] = perf_event_count(leader);
@@ -7613,7 +7612,7 @@
/*
* Get the target context (task or percpu):
*/
- ctx = find_get_context(event, task, event->cpu);
+ ctx = find_get_context(pmu, task, event->cpu, true);
if (IS_ERR(ctx)) {
err = PTR_ERR(ctx);
goto err_alloc;
@@ -7810,8 +7809,12 @@
event->owner = EVENT_OWNER_KERNEL;
account_event(event);
+ /* Skip security check on kernel owned event */
+ if (event->owner == EVENT_OWNER_KERNEL)
+ ctx = find_get_context(event->pmu, task, cpu, false);
+ else
+ ctx = find_get_context(event->pmu, task, cpu, true);
- ctx = find_get_context(event, task, cpu);
if (IS_ERR(ctx)) {
err = PTR_ERR(ctx);
goto err_free;
diff --git a/kernel/exit.c b/kernel/exit.c
index 2e29c55..f629ea0 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -1639,6 +1639,10 @@
__WNOTHREAD|__WCLONE|__WALL))
return -EINVAL;
+ /* -INT_MIN is not defined */
+ if (upid == INT_MIN)
+ return -ESRCH;
+
if (upid == -1)
type = PIDTYPE_MAX;
else if (upid < 0) {
diff --git a/kernel/kthread.c b/kernel/kthread.c
index 7c40a18..7989b21 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -156,12 +156,13 @@
static void __kthread_parkme(struct kthread *self)
{
- __set_current_state(TASK_PARKED);
- while (test_bit(KTHREAD_SHOULD_PARK, &self->flags)) {
+ for (;;) {
+ set_current_state(TASK_PARKED);
+ if (!test_bit(KTHREAD_SHOULD_PARK, &self->flags))
+ break;
if (!test_and_set_bit(KTHREAD_IS_PARKED, &self->flags))
complete(&self->parked);
schedule();
- __set_current_state(TASK_PARKED);
}
clear_bit(KTHREAD_IS_PARKED, &self->flags);
__set_current_state(TASK_RUNNING);
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 26d7f74..d637c5a 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -85,9 +85,6 @@
extern dev_t swsusp_resume_device;
extern sector_t swsusp_resume_block;
-extern asmlinkage int swsusp_arch_suspend(void);
-extern asmlinkage int swsusp_arch_resume(void);
-
extern int create_basic_memory_bitmaps(void);
extern void free_basic_memory_bitmaps(void);
extern int hibernate_preallocate_memory(void);
diff --git a/kernel/relay.c b/kernel/relay.c
index 5a56d3c..42d06d1 100644
--- a/kernel/relay.c
+++ b/kernel/relay.c
@@ -166,7 +166,7 @@
{
struct rchan_buf *buf;
- if (chan->n_subbufs > UINT_MAX / sizeof(size_t *))
+ if (chan->n_subbufs > KMALLOC_MAX_SIZE / sizeof(size_t *))
return NULL;
buf = kzalloc(sizeof(struct rchan_buf), GFP_KERNEL);
diff --git a/kernel/sched/qhmp_sched.h b/kernel/sched/qhmp_sched.h
index 767f63d..9269df4 100644
--- a/kernel/sched/qhmp_sched.h
+++ b/kernel/sched/qhmp_sched.h
@@ -1084,6 +1084,12 @@
#endif /* CONFIG_SCHED_HMP */
+/* cycle counter based accounting is not available in QHMP. */
+static inline void sched_account_irqstart(int cpu, struct task_struct *curr,
+ u64 wallclock)
+{
+}
+
#ifdef CONFIG_SCHED_FREQ_INPUT
extern void check_for_freq_change(struct rq *rq);
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index ce5fe4a..965960f 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -819,6 +819,8 @@
struct rq *rq = rq_of_rt_rq(rt_rq);
raw_spin_lock(&rq->lock);
+ update_rq_clock(rq);
+
if (rt_rq->rt_time) {
u64 runtime;
diff --git a/kernel/signal.c b/kernel/signal.c
index f172762..4af5302 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1435,6 +1435,10 @@
return ret;
}
+ /* -INT_MIN is undefined. Exclude this case to avoid a UBSAN warning */
+ if (pid == INT_MIN)
+ return -ESRCH;
+
read_lock(&tasklist_lock);
if (pid != -1) {
ret = __kill_pgrp_info(sig, info,
diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
index 0a359d6..0c524eb 100644
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -509,6 +509,10 @@
alarm->timer.function = alarmtimer_fired;
alarm->function = function;
alarm->type = type;
+ if (type >= ALARM_NUMTYPE) {
+ /* use ALARM_BOOTTIME as the default */
+ alarm->type = ALARM_BOOTTIME;
+ }
alarm->state = ALARMTIMER_STATE_INACTIVE;
}
EXPORT_SYMBOL_GPL(alarm_init);
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
index 25fb004..9f5c3f6 100644
--- a/kernel/time/tick-broadcast.c
+++ b/kernel/time/tick-broadcast.c
@@ -585,6 +585,14 @@
now = ktime_get();
/* Find all expired events */
for_each_cpu(cpu, tick_broadcast_oneshot_mask) {
+ /*
+ * Required for !SMP because for_each_cpu() reports
+ * unconditionally CPU0 as set on UP kernels.
+ */
+ if (!IS_ENABLED(CONFIG_SMP) &&
+ cpumask_empty(tick_broadcast_oneshot_mask))
+ break;
+
td = &per_cpu(tick_cpu_device, cpu);
if (td->evtdev->next_event.tv64 <= now.tv64) {
cpumask_set_cpu(cpu, tmpmask);
diff --git a/kernel/time/time.c b/kernel/time/time.c
index 22d5d3b..0325e66 100644
--- a/kernel/time/time.c
+++ b/kernel/time/time.c
@@ -28,6 +28,7 @@
*/
#include <linux/export.h>
+#include <linux/kernel.h>
#include <linux/timex.h>
#include <linux/capability.h>
#include <linux/timekeeper_internal.h>
@@ -254,9 +255,10 @@
return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC);
#else
# if BITS_PER_LONG == 32
- return (HZ_TO_MSEC_MUL32 * j) >> HZ_TO_MSEC_SHR32;
+ return (HZ_TO_MSEC_MUL32 * j + (1ULL << HZ_TO_MSEC_SHR32) - 1) >>
+ HZ_TO_MSEC_SHR32;
# else
- return (j * HZ_TO_MSEC_NUM) / HZ_TO_MSEC_DEN;
+ return DIV_ROUND_UP(j * HZ_TO_MSEC_NUM, HZ_TO_MSEC_DEN);
# endif
#endif
}
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
index fee491d..27b7bf0 100644
--- a/kernel/trace/trace_events_filter.c
+++ b/kernel/trace/trace_events_filter.c
@@ -273,6 +273,9 @@
static int regex_match_front(char *str, struct regex *r, int len)
{
+ if (len < r->len)
+ return 0;
+
if (strncmp(str, r->pattern, r->len) == 0)
return 1;
return 0;
diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c
index 4747b47..b743e75 100644
--- a/kernel/trace/trace_events_trigger.c
+++ b/kernel/trace/trace_events_trigger.c
@@ -469,9 +469,10 @@
struct ftrace_event_file *file;
list_for_each_entry(file, &tr->events, list) {
- struct event_trigger_data *data;
- list_for_each_entry_rcu(data, &file->triggers, list) {
+ struct event_trigger_data *data, *n;
+ list_for_each_entry_safe(data, n, &file->triggers, list) {
trace_event_trigger_enable_disable(file, 0);
+ list_del_rcu(&data->list);
if (data->ops->free)
data->ops->free(data->ops, data);
}
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index 94bc5ea..c2af9b9 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -149,6 +149,8 @@
return;
ret = strncpy_from_user(dst, src, maxlen);
+ if (ret == maxlen)
+ dst[--ret] = '\0';
if (ret < 0) { /* Failed to fetch string */
((u8 *)get_rloc_data(dest))[0] = '\0';
diff --git a/lib/kobject.c b/lib/kobject.c
index 58751bb..69acdbc 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -234,14 +234,12 @@
/* be noisy on error issues */
if (error == -EEXIST)
- WARN(1, "%s failed for %s with "
- "-EEXIST, don't try to register things with "
- "the same name in the same directory.\n",
- __func__, kobject_name(kobj));
+ pr_err("%s failed for %s with -EEXIST, don't try to register things with the same name in the same directory.\n",
+ __func__, kobject_name(kobj));
else
- WARN(1, "%s failed for %s (error: %d parent: %s)\n",
- __func__, kobject_name(kobj), error,
- parent ? kobject_name(parent) : "'none'");
+ pr_err("%s failed for %s (error: %d parent: %s)\n",
+ __func__, kobject_name(kobj), error,
+ parent ? kobject_name(parent) : "'none'");
} else
kobj->state_in_sysfs = 1;
diff --git a/mm/ksm.c b/mm/ksm.c
index 720798f..6dfd99f9 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -1493,8 +1493,22 @@
tree_rmap_item =
unstable_tree_search_insert(rmap_item, page, &tree_page);
if (tree_rmap_item) {
+ bool split;
+
kpage = try_to_merge_two_pages(rmap_item, page,
tree_rmap_item, tree_page);
+ /*
+ * If both pages we tried to merge belong to the same compound
+ * page, then we actually ended up increasing the reference
+ * count of the same compound page twice, and split_huge_page
+ * failed.
+ * Here we set a flag if that happened, and we use it later to
+ * try split_huge_page again. Since we call put_page right
+ * afterwards, the reference count will be correct and
+ * split_huge_page should succeed.
+ */
+ split = PageTransCompound(page)
+ && compound_head(page) == compound_head(tree_page);
put_page(tree_page);
if (kpage) {
/*
@@ -1519,6 +1533,20 @@
break_cow(tree_rmap_item);
break_cow(rmap_item);
}
+ } else if (split) {
+ /*
+ * We are here if we tried to merge two pages and
+ * failed because they both belonged to the same
+ * compound page. We will split the page now, but no
+ * merging will take place.
+ * We do not want to add the cost of a full lock; if
+ * the page is locked, it is better to skip it and
+ * perhaps try again later.
+ */
+ if (!trylock_page(page))
+ return;
+ split_huge_page(page);
+ unlock_page(page);
}
}
}
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 660d1e8..1733406 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -1286,6 +1286,7 @@
unsigned long maxnode)
{
unsigned long k;
+ unsigned long t;
unsigned long nlongs;
unsigned long endmask;
@@ -1302,13 +1303,19 @@
else
endmask = (1UL << (maxnode % BITS_PER_LONG)) - 1;
- /* When the user specified more nodes than supported just check
- if the non supported part is all zero. */
+ /*
+ * When the user specified more nodes than supported just check
+ * if the non supported part is all zero.
+ *
+ * If maxnode have more longs than MAX_NUMNODES, check
+ * the bits in that area first. And then go through to
+ * check the rest bits which equal or bigger than MAX_NUMNODES.
+ * Otherwise, just check bits [MAX_NUMNODES, maxnode).
+ */
if (nlongs > BITS_TO_LONGS(MAX_NUMNODES)) {
if (nlongs > PAGE_SIZE/sizeof(long))
return -EINVAL;
for (k = BITS_TO_LONGS(MAX_NUMNODES); k < nlongs; k++) {
- unsigned long t;
if (get_user(t, nmask + k))
return -EFAULT;
if (k == nlongs - 1) {
@@ -1321,6 +1328,16 @@
endmask = ~0UL;
}
+ if (maxnode > MAX_NUMNODES && MAX_NUMNODES % BITS_PER_LONG != 0) {
+ unsigned long valid_mask = endmask;
+
+ valid_mask &= ~((1UL << (MAX_NUMNODES % BITS_PER_LONG)) - 1);
+ if (get_user(t, nmask + nlongs - 1))
+ return -EFAULT;
+ if (t & valid_mask)
+ return -EINVAL;
+ }
+
if (copy_from_user(nodes_addr(*nodes), nmask, nlongs*sizeof(unsigned long)))
return -EFAULT;
nodes_addr(*nodes)[nlongs-1] &= endmask;
@@ -1447,10 +1464,14 @@
goto out_put;
}
- if (!nodes_subset(*new, node_states[N_MEMORY])) {
- err = -EINVAL;
+ task_nodes = cpuset_mems_allowed(current);
+ nodes_and(*new, *new, task_nodes);
+ if (nodes_empty(*new))
goto out_put;
- }
+
+ nodes_and(*new, *new, node_states[N_MEMORY]);
+ if (nodes_empty(*new))
+ goto out_put;
err = security_task_movememory(task);
if (err)
@@ -2148,6 +2169,9 @@
case MPOL_INTERLEAVE:
return !!nodes_equal(a->v.nodes, b->v.nodes);
case MPOL_PREFERRED:
+ /* a's ->flags is the same as b's */
+ if (a->flags & MPOL_F_LOCAL)
+ return true;
return a->v.preferred_node == b->v.preferred_node;
default:
BUG();
diff --git a/mm/mmap.c b/mm/mmap.c
index c082556..14c95a1 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1293,6 +1293,35 @@
return 0;
}
+static inline u64 file_mmap_size_max(struct file *file, struct inode *inode)
+{
+ if (S_ISREG(inode->i_mode))
+ return MAX_LFS_FILESIZE;
+
+ if (S_ISBLK(inode->i_mode))
+ return MAX_LFS_FILESIZE;
+
+ /* Special "we do even unsigned file positions" case */
+ if (file->f_mode & FMODE_UNSIGNED_OFFSET)
+ return 0;
+
+ /* Yes, random drivers might want more. But I'm tired of buggy drivers */
+ return ULONG_MAX;
+}
+
+static inline bool file_mmap_ok(struct file *file, struct inode *inode,
+ unsigned long pgoff, unsigned long len)
+{
+ u64 maxsize = file_mmap_size_max(file, inode);
+
+ if (maxsize && len > maxsize)
+ return false;
+ maxsize -= len;
+ if (pgoff > maxsize >> PAGE_SHIFT)
+ return false;
+ return true;
+}
+
/*
* The caller must hold down_write(¤t->mm->mmap_sem).
*/
@@ -1364,6 +1393,9 @@
if (file) {
struct inode *inode = file_inode(file);
+ if (!file_mmap_ok(file, inode, pgoff, len))
+ return -EOVERFLOW;
+
switch (flags & MAP_TYPE) {
case MAP_SHARED:
if ((prot&PROT_WRITE) && !(file->f_mode&FMODE_WRITE))
diff --git a/mm/percpu.c b/mm/percpu.c
index f7da3a3..ac0b633e 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -68,6 +68,7 @@
#include <linux/vmalloc.h>
#include <linux/workqueue.h>
#include <linux/kmemleak.h>
+#include <linux/sched.h>
#include <asm/cacheflush.h>
#include <asm/sections.h>
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 911b8e1..ecf427a 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -2302,6 +2302,10 @@
maxpages = swp_offset(pte_to_swp_entry(
swp_entry_to_pte(swp_entry(0, ~0UL)))) + 1;
last_page = swap_header->info.last_page;
+ if (!last_page) {
+ pr_warn("Empty swap-file\n");
+ return 0;
+ }
if (last_page > maxpages) {
pr_warn("Truncating oversized swap area, only using %luk out of %luk\n",
maxpages << (PAGE_SHIFT - 10),
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 3e0dd07..0746c06 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1280,6 +1280,7 @@
if (PageDirty(page)) {
struct address_space *mapping;
+ bool migrate_dirty;
/* ISOLATE_CLEAN means only clean pages */
if (mode & ISOLATE_CLEAN)
@@ -1288,10 +1289,19 @@
/*
* Only pages without mappings or that have a
* ->migratepage callback are possible to migrate
- * without blocking
+ * without blocking. However, we can be racing with
+ * truncation so it's necessary to lock the page
+ * to stabilise the mapping as truncation holds
+ * the page lock until after the page is removed
+ * from the page cache.
*/
+ if (!trylock_page(page))
+ return ret;
+
mapping = page_mapping(page);
- if (mapping && !mapping->a_ops->migratepage)
+ migrate_dirty = !mapping || mapping->a_ops->migratepage;
+ unlock_page(page);
+ if (!migrate_dirty)
return ret;
}
}
@@ -3846,7 +3856,13 @@
*/
int page_evictable(struct page *page)
{
- return !mapping_unevictable(page_mapping(page)) && !PageMlocked(page);
+ int ret;
+
+ /* Prevent address_space of inode and swap cache from being freed */
+ rcu_read_lock();
+ ret = !mapping_unevictable(page_mapping(page)) && !PageMlocked(page);
+ rcu_read_unlock();
+ return ret;
}
#ifdef CONFIG_SHMEM
diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c
index 4bbd72e..069eb73 100644
--- a/net/batman-adv/distributed-arp-table.c
+++ b/net/batman-adv/distributed-arp-table.c
@@ -343,7 +343,7 @@
batadv_arp_hw_src(skb, hdr_size), &ip_src,
batadv_arp_hw_dst(skb, hdr_size), &ip_dst);
- if (hdr_size == 0)
+ if (hdr_size < sizeof(struct batadv_unicast_packet))
return;
unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data;
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c
index 00f9e14..4eef690 100644
--- a/net/batman-adv/fragmentation.c
+++ b/net/batman-adv/fragmentation.c
@@ -260,7 +260,8 @@
/* Move the existing MAC header to just before the payload. (Override
* the fragment header.)
*/
- skb_pull_rcsum(skb_out, hdr_size);
+ skb_pull(skb_out, hdr_size);
+ skb_out->ip_summed = CHECKSUM_NONE;
memmove(skb_out->data - ETH_HLEN, skb_mac_header(skb_out), ETH_HLEN);
skb_set_mac_header(skb_out, -ETH_HLEN);
skb_reset_network_header(skb_out);
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
index e0bcf9e..b22ba87 100644
--- a/net/batman-adv/gateway_client.c
+++ b/net/batman-adv/gateway_client.c
@@ -804,6 +804,9 @@
vid = batadv_get_vid(skb, 0);
+ if (is_multicast_ether_addr(ethhdr->h_dest))
+ goto out;
+
orig_dst_node = batadv_transtable_search(bat_priv, ethhdr->h_source,
ethhdr->h_dest, vid);
if (!orig_dst_node)
diff --git a/net/batman-adv/multicast.c b/net/batman-adv/multicast.c
index ab6bb2a..5fa532e 100644
--- a/net/batman-adv/multicast.c
+++ b/net/batman-adv/multicast.c
@@ -394,8 +394,8 @@
batadv_mcast_forw_tt_node_get(struct batadv_priv *bat_priv,
struct ethhdr *ethhdr)
{
- return batadv_transtable_search(bat_priv, ethhdr->h_source,
- ethhdr->h_dest, BATADV_NO_FLAGS);
+ return batadv_transtable_search(bat_priv, NULL, ethhdr->h_dest,
+ BATADV_NO_FLAGS);
}
/**
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 0bb7cae..6c08801 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -401,13 +401,7 @@
/* skb->dev & skb->pkt_type are set here */
skb->protocol = eth_type_trans(skb, soft_iface);
-
- /* should not be necessary anymore as we use skb_pull_rcsum()
- * TODO: please verify this and remove this TODO
- * -- Dec 21st 2009, Simon Wunderlich
- */
-
- /* skb->ip_summed = CHECKSUM_UNNECESSARY; */
+ skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
batadv_inc_counter(bat_priv, BATADV_CNT_RX);
batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES,
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 4e297ad..ad67ad6 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -445,8 +445,8 @@
if (dev->netdev_ops->ndo_start_xmit == br_dev_xmit)
return -ELOOP;
- /* Device is already being bridged */
- if (br_port_exists(dev))
+ /* Device has master upper dev */
+ if (netdev_master_upper_dev_get(dev))
return -EBUSY;
/* No bridging devices that dislike that (e.g. wireless) */
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index 653d729..6fad606 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -1612,7 +1612,8 @@
int off = ebt_compat_match_offset(match, m->match_size);
compat_uint_t msize = m->match_size - off;
- BUG_ON(off >= m->match_size);
+ if (WARN_ON(off >= m->match_size))
+ return -EINVAL;
if (copy_to_user(cm->u.name, match->name,
strlen(match->name) + 1) || put_user(msize, &cm->match_size))
@@ -1639,7 +1640,8 @@
int off = xt_compat_target_offset(target);
compat_uint_t tsize = t->target_size - off;
- BUG_ON(off >= t->target_size);
+ if (WARN_ON(off >= t->target_size))
+ return -EINVAL;
if (copy_to_user(cm->u.name, target->name,
strlen(target->name) + 1) || put_user(tsize, &cm->match_size))
@@ -1867,7 +1869,8 @@
if (state->buf_kern_start == NULL)
goto count_only;
- BUG_ON(state->buf_kern_offset + sz > state->buf_kern_len);
+ if (WARN_ON(state->buf_kern_offset + sz > state->buf_kern_len))
+ return -EINVAL;
memcpy(state->buf_kern_start + state->buf_kern_offset, data, sz);
@@ -1880,7 +1883,8 @@
{
char *b = state->buf_kern_start;
- BUG_ON(b && state->buf_kern_offset > state->buf_kern_len);
+ if (WARN_ON(b && state->buf_kern_offset > state->buf_kern_len))
+ return -EINVAL;
if (b != NULL && sz > 0)
memset(b + state->buf_kern_offset, 0, sz);
@@ -1906,7 +1910,8 @@
int off, pad = 0;
unsigned int size_kern, match_size = mwt->match_size;
- strlcpy(name, mwt->u.name, sizeof(name));
+ if (strscpy(name, mwt->u.name, sizeof(name)) < 0)
+ return -EINVAL;
if (state->buf_kern_start)
dst = state->buf_kern_start + state->buf_kern_offset;
@@ -1957,8 +1962,10 @@
pad = XT_ALIGN(size_kern) - size_kern;
if (pad > 0 && dst) {
- BUG_ON(state->buf_kern_len <= pad);
- BUG_ON(state->buf_kern_offset - (match_size + off) + size_kern > state->buf_kern_len - pad);
+ if (WARN_ON(state->buf_kern_len <= pad))
+ return -EINVAL;
+ if (WARN_ON(state->buf_kern_offset - (match_size + off) + size_kern > state->buf_kern_len - pad))
+ return -EINVAL;
memset(dst + size_kern, 0, pad);
}
return off + match_size;
@@ -2009,7 +2016,8 @@
if (ret < 0)
return ret;
- BUG_ON(ret < match32->match_size);
+ if (WARN_ON(ret < match32->match_size))
+ return -EINVAL;
growth += ret - match32->match_size;
growth += ebt_compat_entry_padsize();
@@ -2079,8 +2087,12 @@
* offsets are relative to beginning of struct ebt_entry (i.e., 0).
*/
for (i = 0; i < 4 ; ++i) {
- if (offsets[i] >= *total)
+ if (offsets[i] > *total)
return -EINVAL;
+
+ if (i < 3 && offsets[i] == *total)
+ return -EINVAL;
+
if (i == 0)
continue;
if (offsets[i-1] > offsets[i])
@@ -2119,7 +2131,8 @@
startoff = state->buf_user_offset - startoff;
- BUG_ON(*total < startoff);
+ if (WARN_ON(*total < startoff))
+ return -EINVAL;
*total -= startoff;
return 0;
}
@@ -2247,7 +2260,8 @@
state.buf_kern_len = size64;
ret = compat_copy_entries(entries_tmp, tmp.entries_size, &state);
- BUG_ON(ret < 0); /* parses same data again */
+ if (WARN_ON(ret < 0))
+ goto out_unlock;
vfree(entries_tmp);
tmp.entries_size = size64;
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index 0861598..2dc4e06 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -2449,6 +2449,11 @@
int ret = 1;
dout("try_write start %p state %lu\n", con, con->state);
+ if (con->state != CON_STATE_PREOPEN &&
+ con->state != CON_STATE_CONNECTING &&
+ con->state != CON_STATE_NEGOTIATING &&
+ con->state != CON_STATE_OPEN)
+ return 0;
more:
dout("try_write out_kvec_bytes %d\n", con->out_kvec_bytes);
@@ -2474,6 +2479,8 @@
}
more_kvec:
+ BUG_ON(!con->sock);
+
/* kvec data queued? */
if (con->out_skip) {
ret = write_partial_skip(con);
diff --git a/net/compat.c b/net/compat.c
index 3bb039e..f5027aa 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -387,7 +387,8 @@
if (optname == SO_ATTACH_FILTER)
return do_set_attach_filter(sock, level, optname,
optval, optlen);
- if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)
+ if (!COMPAT_USE_64BIT_TIME &&
+ (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO))
return do_set_sock_timeout(sock, level, optname, optval, optlen);
return sock_setsockopt(sock, level, optname, optval, optlen);
@@ -452,7 +453,8 @@
static int compat_sock_getsockopt(struct socket *sock, int level, int optname,
char __user *optval, int __user *optlen)
{
- if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)
+ if (!COMPAT_USE_64BIT_TIME &&
+ (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO))
return do_get_sock_timeout(sock, level, optname, optval, optlen);
return sock_getsockopt(sock, level, optname, optval, optlen);
}
diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c
index b6b2306..41aad22 100644
--- a/net/core/dev_addr_lists.c
+++ b/net/core/dev_addr_lists.c
@@ -57,8 +57,8 @@
return -EINVAL;
list_for_each_entry(ha, &list->list, list) {
- if (!memcmp(ha->addr, addr, addr_len) &&
- ha->type == addr_type) {
+ if (ha->type == addr_type &&
+ !memcmp(ha->addr, addr, addr_len)) {
if (global) {
/* check if addr is already used as global */
if (ha->global_use)
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 617ca06..b39fe64f 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1294,17 +1294,14 @@
struct neighbour *neigh = __neigh_lookup(tbl, saddr, dev,
lladdr || !dev->addr_len);
if (neigh) {
+ neigh_update(neigh, lladdr, NUD_STALE,
+ NEIGH_UPDATE_F_OVERRIDE);
if (neigh_probe_enable) {
if (!(neigh->nud_state == NUD_REACHABLE)) {
- neigh_update(neigh, lladdr, NUD_STALE,
- NEIGH_UPDATE_F_OVERRIDE);
write_lock(&neigh->lock);
neigh_probe(neigh);
neigh_update_notify(neigh);
}
- } else {
- neigh_update(neigh, lladdr, NUD_STALE,
- NEIGH_UPDATE_F_OVERRIDE);
}
}
return neigh;
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index ff864ce..9fd2c9e 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1503,6 +1503,10 @@
const struct net_device_ops *ops = dev->netdev_ops;
int err;
+ err = validate_linkmsg(dev, tb);
+ if (err < 0)
+ return err;
+
if (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD]) {
struct net *net = rtnl_link_get_net(dev_net(dev), tb);
if (IS_ERR(net)) {
@@ -1783,10 +1787,6 @@
goto errout;
}
- err = validate_linkmsg(dev, tb);
- if (err < 0)
- goto errout;
-
err = do_setlink(skb, dev, ifm, tb, ifname, 0);
errout:
return err;
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 88f76fe..7f13431 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -802,6 +802,7 @@
n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len;
n->cloned = 1;
n->nohdr = 0;
+ n->peeked = 0;
n->destructor = NULL;
C(tail);
C(end);
@@ -4151,13 +4152,18 @@
static struct sk_buff *skb_reorder_vlan_header(struct sk_buff *skb)
{
+ int mac_len;
+
if (skb_cow(skb, skb_headroom(skb)) < 0) {
kfree_skb(skb);
return NULL;
}
- memmove(skb->data - ETH_HLEN, skb->data - skb->mac_len - VLAN_HLEN,
- 2 * ETH_ALEN);
+ mac_len = skb->data - skb_mac_header(skb);
+ if (likely(mac_len > VLAN_HLEN + ETH_TLEN)) {
+ memmove(skb_mac_header(skb) + VLAN_HLEN, skb_mac_header(skb),
+ mac_len - VLAN_HLEN - ETH_TLEN);
+ }
skb->mac_header += VLAN_HLEN;
return skb;
}
diff --git a/net/core/sockev_nlmcast.c b/net/core/sockev_nlmcast.c
index 749ffb8..1e92c56 100644
--- a/net/core/sockev_nlmcast.c
+++ b/net/core/sockev_nlmcast.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2015, 2018 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -36,6 +36,7 @@
static void _sockev_event(unsigned long event, __u8 *evstr, int buflen)
{
+
switch (event) {
case SOCKEV_SOCKET:
strlcpy(evstr, "SOCKEV_SOCKET", buflen);
@@ -68,14 +69,17 @@
struct nlmsghdr *nlh;
struct sknlsockevmsg *smsg;
struct socket *sock;
+ struct sock *sk;
sock = (struct socket *)data;
- if (socknlmsgsk == 0)
- goto done;
- if ((socknlmsgsk == NULL) || (sock == NULL) || (sock->sk == NULL))
+ if (!socknlmsgsk || !sock)
goto done;
- if (sock->sk->sk_family != AF_INET && sock->sk->sk_family != AF_INET6)
+ sk = sock->sk;
+ if (!sk)
+ goto done;
+
+ if (sk->sk_family != AF_INET && sk->sk_family != AF_INET6)
goto done;
if (event != SOCKEV_BIND && event != SOCKEV_LISTEN)
@@ -94,14 +98,14 @@
NETLINK_CB(skb).dst_group = SKNLGRP_SOCKEV;
smsg = nlmsg_data(nlh);
+ memset(smsg, 0, sizeof(struct sknlsockevmsg));
smsg->pid = current->pid;
_sockev_event(event, smsg->event, sizeof(smsg->event));
- smsg->skfamily = sock->sk->sk_family;
- smsg->skstate = sock->sk->sk_state;
- smsg->skprotocol = sock->sk->sk_protocol;
- smsg->sktype = sock->sk->sk_type;
- smsg->skflags = sock->sk->sk_flags;
-
+ smsg->skfamily = sk->sk_family;
+ smsg->skstate = sk->sk_state;
+ smsg->skprotocol = sk->sk_protocol;
+ smsg->sktype = sk->sk_type;
+ smsg->skflags = sk->sk_flags;
nlmsg_notify(socknlmsgsk, skb, 0, SKNLGRP_SOCKEV, 0, GFP_KERNEL);
done:
return 0;
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c
index 7753681..86a2ed0 100644
--- a/net/dccp/ccids/ccid2.c
+++ b/net/dccp/ccids/ccid2.c
@@ -126,6 +126,16 @@
DCCPF_SEQ_WMAX));
}
+static void dccp_tasklet_schedule(struct sock *sk)
+{
+ struct tasklet_struct *t = &dccp_sk(sk)->dccps_xmitlet;
+
+ if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
+ sock_hold(sk);
+ __tasklet_schedule(t);
+ }
+}
+
static void ccid2_hc_tx_rto_expire(unsigned long data)
{
struct sock *sk = (struct sock *)data;
@@ -166,7 +176,7 @@
/* if we were blocked before, we may now send cwnd=1 packet */
if (sender_was_blocked)
- tasklet_schedule(&dccp_sk(sk)->dccps_xmitlet);
+ dccp_tasklet_schedule(sk);
/* restart backed-off timer */
sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto);
out:
@@ -706,7 +716,7 @@
done:
/* check if incoming Acks allow pending packets to be sent */
if (sender_was_blocked && !ccid2_cwnd_network_limited(hc))
- tasklet_schedule(&dccp_sk(sk)->dccps_xmitlet);
+ dccp_tasklet_schedule(sk);
dccp_ackvec_parsed_cleanup(&hc->tx_av_chunks);
}
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index 2b8fd8c..bf5646d 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -280,9 +280,7 @@
dccp_clear_xmit_timers(sk);
ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk);
- ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
dp->dccps_hc_rx_ccid = NULL;
- dp->dccps_hc_tx_ccid = NULL;
__skb_queue_purge(&sk->sk_receive_queue);
__skb_queue_purge(&sk->sk_write_queue);
diff --git a/net/dccp/timer.c b/net/dccp/timer.c
index 1cd46a3..851a212 100644
--- a/net/dccp/timer.c
+++ b/net/dccp/timer.c
@@ -252,12 +252,12 @@
else
dccp_write_xmit(sk);
bh_unlock_sock(sk);
+ sock_put(sk);
}
static void dccp_write_xmit_timer(unsigned long data)
{
dccp_write_xmitlet(data);
- sock_put((struct sock *)data);
}
void dccp_init_xmit_timers(struct sock *sk)
diff --git a/net/ipc_router/ipc_router_socket.c b/net/ipc_router/ipc_router_socket.c
index 9392a81..6ebd987 100644
--- a/net/ipc_router/ipc_router_socket.c
+++ b/net/ipc_router/ipc_router_socket.c
@@ -155,6 +155,7 @@
return -EINVAL;
}
ctl_msg = (union rr_control_msg *)(temp->data);
+ memset(addr, 0x0, sizeof(*addr));
addr->family = AF_MSM_IPC;
addr->address.addrtype = MSM_IPC_ADDR_ID;
addr->address.addr.port_addr.node_id = ctl_msg->cli.node_id;
@@ -163,6 +164,7 @@
return offset;
}
if (addr && (hdr->type == IPC_ROUTER_CTRL_CMD_DATA)) {
+ memset(addr, 0x0, sizeof(*addr));
addr->family = AF_MSM_IPC;
addr->address.addrtype = MSM_IPC_ADDR_ID;
addr->address.addr.port_addr.node_id = hdr->src_node_id;
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c
index cbeb022..2f00872 100644
--- a/net/ipv4/inet_timewait_sock.c
+++ b/net/ipv4/inet_timewait_sock.c
@@ -181,6 +181,7 @@
tw->tw_dport = inet->inet_dport;
tw->tw_family = sk->sk_family;
tw->tw_reuse = sk->sk_reuse;
+ tw->tw_reuseport = sk->sk_reuseport;
tw->tw_hash = sk->sk_hash;
tw->tw_ipv6only = 0;
tw->tw_transparent = inet->transparent;
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 77477b1c..7f7bf44 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1028,7 +1028,8 @@
if (copy > length)
copy = length;
- if (!(rt->dst.dev->features&NETIF_F_SG)) {
+ if (!(rt->dst.dev->features&NETIF_F_SG) &&
+ skb_tailroom(skb) >= copy) {
unsigned int off;
off = skb->len;
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c
index 1b8a82f..c35e0aa 100644
--- a/net/ipv4/ip_vti.c
+++ b/net/ipv4/ip_vti.c
@@ -365,7 +365,6 @@
memcpy(dev->dev_addr, &iph->saddr, 4);
memcpy(dev->broadcast, &iph->daddr, 4);
- dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr);
dev->mtu = ETH_DATA_LEN;
dev->flags = IFF_NOARP;
dev->iflink = 0;
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index 420e511..db82036 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -778,8 +778,10 @@
ipc.addr = faddr = daddr;
if (ipc.opt && ipc.opt->opt.srr) {
- if (!daddr)
- return -EINVAL;
+ if (!daddr) {
+ err = -EINVAL;
+ goto out_free;
+ }
faddr = ipc.opt->opt.faddr;
}
tos = get_rttos(&ipc, inet);
@@ -845,6 +847,7 @@
out:
ip_rt_put(rt);
+out_free:
if (free)
kfree(ipc.opt);
if (!err) {
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 6d20bc0..179506f 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1112,7 +1112,7 @@
lock_sock(sk);
flags = msg->msg_flags;
- if (flags & MSG_FASTOPEN) {
+ if ((flags & MSG_FASTOPEN) && !tp->repair) {
err = tcp_sendmsg_fastopen(sk, msg, &copied_syn, size);
if (err == -EINPROGRESS && copied_syn > 0)
goto out;
@@ -2484,7 +2484,7 @@
case TCP_REPAIR_QUEUE:
if (!tp->repair)
err = -EPERM;
- else if (val < TCP_QUEUES_NR)
+ else if ((unsigned int)val < TCP_QUEUES_NR)
tp->repair_queue = val;
else
err = -EINVAL;
diff --git a/net/ipv4/tcp_illinois.c b/net/ipv4/tcp_illinois.c
index 1d5a30a..82fe6b5 100644
--- a/net/ipv4/tcp_illinois.c
+++ b/net/ipv4/tcp_illinois.c
@@ -6,7 +6,7 @@
* The algorithm is described in:
* "TCP-Illinois: A Loss and Delay-Based Congestion Control Algorithm
* for High-Speed Networks"
- * http://www.ifp.illinois.edu/~srikant/Papers/liubassri06perf.pdf
+ * http://tamerbasar.csl.illinois.edu/LiuBasarSrikantPerfEvalArtJun2008.pdf
*
* Implemented from description in paper and ns-2 simulation.
* Copyright (C) 2007 Stephen Hemminger <shemminger@linux-foundation.org>
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 2de1221..f0fb884 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -551,8 +551,8 @@
void tcp_rcv_space_adjust(struct sock *sk)
{
struct tcp_sock *tp = tcp_sk(sk);
+ u32 copied;
int time;
- int copied;
time = tcp_time_stamp - tp->rcvq_space.time;
if (time < (tp->rcv_rtt_est.rtt >> 3) || tp->rcv_rtt_est.rtt == 0)
@@ -574,12 +574,13 @@
if (sysctl_tcp_moderate_rcvbuf &&
!(sk->sk_userlocks & SOCK_RCVBUF_LOCK)) {
- int rcvwin, rcvmem, rcvbuf;
+ int rcvmem, rcvbuf;
+ u64 rcvwin;
/* minimal window to cope with packet losses, assuming
* steady state. Add some cushion because of small variations.
*/
- rcvwin = (copied << 1) + 16 * tp->advmss;
+ rcvwin = ((u64)copied << 1) + 16 * tp->advmss;
/* If rate increased by 25%,
* assume slow start, rcvwin = 3 * copied
@@ -599,12 +600,13 @@
while (tcp_win_from_space(rcvmem) < tp->advmss)
rcvmem += 128;
- rcvbuf = min(rcvwin / tp->advmss * rcvmem, sysctl_tcp_rmem[2]);
+ do_div(rcvwin, tp->advmss);
+ rcvbuf = min_t(u64, rcvwin * rcvmem, sysctl_tcp_rmem[2]);
if (rcvbuf > sk->sk_rcvbuf) {
sk->sk_rcvbuf = rcvbuf;
/* Make the window clamp follow along. */
- tp->window_clamp = rcvwin;
+ tp->window_clamp = tcp_win_from_space(rcvbuf);
}
}
tp->rcvq_space.space = copied;
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 4e59443..3d4e828 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -2497,8 +2497,10 @@
return -EBUSY;
if (before(TCP_SKB_CB(skb)->seq, tp->snd_una)) {
- if (before(TCP_SKB_CB(skb)->end_seq, tp->snd_una))
- BUG();
+ if (unlikely(before(TCP_SKB_CB(skb)->end_seq, tp->snd_una))) {
+ WARN_ON_ONCE(1);
+ return -EINVAL;
+ }
if (tcp_trim_head(sk, skb, tp->snd_una - TCP_SKB_CB(skb)->seq))
return -ENOMEM;
}
@@ -2989,6 +2991,7 @@
sock_reset_flag(sk, SOCK_DONE);
tp->snd_wnd = 0;
tcp_init_wl(tp, 0);
+ tcp_write_queue_purge(sk);
tp->snd_una = tp->write_seq;
tp->snd_sml = tp->write_seq;
tp->snd_up = tp->write_seq;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 3034ff9..4cd352a 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -980,8 +980,10 @@
ipc.addr = faddr = daddr;
if (ipc.opt && ipc.opt->opt.srr) {
- if (!daddr)
- return -EINVAL;
+ if (!daddr) {
+ err = -EINVAL;
+ goto out_free;
+ }
faddr = ipc.opt->opt.faddr;
connected = 0;
}
@@ -1087,6 +1089,7 @@
out:
ip_rt_put(rt);
+out_free:
if (free)
kfree(ipc.opt);
if (!err)
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 506cefe..08c58e4 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1474,7 +1474,8 @@
if (copy > length)
copy = length;
- if (!(rt->dst.dev->features&NETIF_F_SG)) {
+ if (!(rt->dst.dev->features&NETIF_F_SG) &&
+ skb_tailroom(skb) >= copy) {
unsigned int off;
off = skb->len;
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 61bc48c..7b963b0 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -1788,7 +1788,8 @@
ret = 0;
if (!ip6mr_new_table(net, v))
ret = -ENOMEM;
- raw6_sk(sk)->ip6mr_table = v;
+ else
+ raw6_sk(sk)->ip6mr_table = v;
rtnl_unlock();
return ret;
}
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 7d19286..f7edc30 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -1572,6 +1572,13 @@
if (err < 0)
return err;
+ if (tb[IFLA_MTU]) {
+ u32 mtu = nla_get_u32(tb[IFLA_MTU]);
+
+ if (mtu >= IPV6_MIN_MTU && mtu <= 0xFFF8 - dev->hard_header_len)
+ dev->mtu = mtu;
+ }
+
#ifdef CONFIG_IPV6_SIT_6RD
if (ipip6_netlink_6rd_parms(data, &ip6rd))
err = ipip6_tunnel_update_6rd(nt, &ip6rd);
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 64dbf0d..fbd25f5 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -437,6 +437,24 @@
return 0;
}
+static inline int sadb_key_len(const struct sadb_key *key)
+{
+ int key_bytes = DIV_ROUND_UP(key->sadb_key_bits, 8);
+
+ return DIV_ROUND_UP(sizeof(struct sadb_key) + key_bytes,
+ sizeof(uint64_t));
+}
+
+static int verify_key_len(const void *p)
+{
+ const struct sadb_key *key = p;
+
+ if (sadb_key_len(key) > key->sadb_key_len)
+ return -EINVAL;
+
+ return 0;
+}
+
static inline int pfkey_sec_ctx_len(const struct sadb_x_sec_ctx *sec_ctx)
{
return DIV_ROUND_UP(sizeof(struct sadb_x_sec_ctx) +
@@ -533,16 +551,25 @@
return -EINVAL;
if (ext_hdrs[ext_type-1] != NULL)
return -EINVAL;
- if (ext_type == SADB_EXT_ADDRESS_SRC ||
- ext_type == SADB_EXT_ADDRESS_DST ||
- ext_type == SADB_EXT_ADDRESS_PROXY ||
- ext_type == SADB_X_EXT_NAT_T_OA) {
+ switch (ext_type) {
+ case SADB_EXT_ADDRESS_SRC:
+ case SADB_EXT_ADDRESS_DST:
+ case SADB_EXT_ADDRESS_PROXY:
+ case SADB_X_EXT_NAT_T_OA:
if (verify_address_len(p))
return -EINVAL;
- }
- if (ext_type == SADB_X_EXT_SEC_CTX) {
+ break;
+ case SADB_X_EXT_SEC_CTX:
if (verify_sec_ctx_len(p))
return -EINVAL;
+ break;
+ case SADB_EXT_KEY_AUTH:
+ case SADB_EXT_KEY_ENCRYPT:
+ if (verify_key_len(p))
+ return -EINVAL;
+ break;
+ default:
+ break;
}
ext_hdrs[ext_type-1] = (void *) p;
}
@@ -1111,14 +1138,12 @@
key = ext_hdrs[SADB_EXT_KEY_AUTH - 1];
if (key != NULL &&
sa->sadb_sa_auth != SADB_X_AALG_NULL &&
- ((key->sadb_key_bits+7) / 8 == 0 ||
- (key->sadb_key_bits+7) / 8 > key->sadb_key_len * sizeof(uint64_t)))
+ key->sadb_key_bits == 0)
return ERR_PTR(-EINVAL);
key = ext_hdrs[SADB_EXT_KEY_ENCRYPT-1];
if (key != NULL &&
sa->sadb_sa_encrypt != SADB_EALG_NULL &&
- ((key->sadb_key_bits+7) / 8 == 0 ||
- (key->sadb_key_bits+7) / 8 > key->sadb_key_len * sizeof(uint64_t)))
+ key->sadb_key_bits == 0)
return ERR_PTR(-EINVAL);
x = xfrm_state_alloc(net);
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c
index 9afeec7..0ac907a 100644
--- a/net/l2tp/l2tp_netlink.c
+++ b/net/l2tp/l2tp_netlink.c
@@ -633,8 +633,6 @@
if ((session->ifname[0] &&
nla_put_string(skb, L2TP_ATTR_IFNAME, session->ifname)) ||
- (session->offset &&
- nla_put_u16(skb, L2TP_ATTR_OFFSET, session->offset)) ||
(session->cookie_len &&
nla_put(skb, L2TP_ATTR_COOKIE, session->cookie_len,
&session->cookie[0])) ||
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index ce669f2..12cbc98 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -928,6 +928,9 @@
if (size > llc->dev->mtu)
size = llc->dev->mtu;
copied = size - hdrlen;
+ rc = -EINVAL;
+ if (copied < 0)
+ goto release;
release_sock(sk);
skb = sock_alloc_send_skb(sk, size, noblock, &rc);
lock_sock(sk);
diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c
index f8d4ab8..4b60f68 100644
--- a/net/llc/llc_c_ac.c
+++ b/net/llc/llc_c_ac.c
@@ -389,7 +389,7 @@
llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR);
rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
if (likely(!rc)) {
- llc_conn_send_pdu(sk, skb);
+ rc = llc_conn_send_pdu(sk, skb);
llc_conn_ac_inc_vs_by_1(sk, skb);
}
return rc;
@@ -916,7 +916,7 @@
llc_pdu_init_as_i_cmd(skb, llc->ack_pf, llc->vS, llc->vR);
rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
if (likely(!rc)) {
- llc_conn_send_pdu(sk, skb);
+ rc = llc_conn_send_pdu(sk, skb);
llc_conn_ac_inc_vs_by_1(sk, skb);
}
return rc;
@@ -935,14 +935,17 @@
int llc_conn_ac_send_i_as_ack(struct sock *sk, struct sk_buff *skb)
{
struct llc_sock *llc = llc_sk(sk);
+ int ret;
if (llc->ack_must_be_send) {
- llc_conn_ac_send_i_rsp_f_set_ackpf(sk, skb);
+ ret = llc_conn_ac_send_i_rsp_f_set_ackpf(sk, skb);
llc->ack_must_be_send = 0 ;
llc->ack_pf = 0;
- } else
- llc_conn_ac_send_i_cmd_p_set_0(sk, skb);
- return 0;
+ } else {
+ ret = llc_conn_ac_send_i_cmd_p_set_0(sk, skb);
+ }
+
+ return ret;
}
/**
diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c
index f36b07a..bb9938c 100644
--- a/net/llc/llc_conn.c
+++ b/net/llc/llc_conn.c
@@ -30,7 +30,7 @@
#endif
static int llc_find_offset(int state, int ev_type);
-static void llc_conn_send_pdus(struct sock *sk);
+static int llc_conn_send_pdus(struct sock *sk, struct sk_buff *skb);
static int llc_conn_service(struct sock *sk, struct sk_buff *skb);
static int llc_exec_conn_trans_actions(struct sock *sk,
struct llc_conn_state_trans *trans,
@@ -193,11 +193,11 @@
return rc;
}
-void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb)
+int llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb)
{
/* queue PDU to send to MAC layer */
skb_queue_tail(&sk->sk_write_queue, skb);
- llc_conn_send_pdus(sk);
+ return llc_conn_send_pdus(sk, skb);
}
/**
@@ -255,7 +255,7 @@
if (howmany_resend > 0)
llc->vS = (llc->vS + 1) % LLC_2_SEQ_NBR_MODULO;
/* any PDUs to re-send are queued up; start sending to MAC */
- llc_conn_send_pdus(sk);
+ llc_conn_send_pdus(sk, NULL);
out:;
}
@@ -296,7 +296,7 @@
if (howmany_resend > 0)
llc->vS = (llc->vS + 1) % LLC_2_SEQ_NBR_MODULO;
/* any PDUs to re-send are queued up; start sending to MAC */
- llc_conn_send_pdus(sk);
+ llc_conn_send_pdus(sk, NULL);
out:;
}
@@ -340,12 +340,16 @@
/**
* llc_conn_send_pdus - Sends queued PDUs
* @sk: active connection
+ * @hold_skb: the skb held by caller, or NULL if does not care
*
- * Sends queued pdus to MAC layer for transmission.
+ * Sends queued pdus to MAC layer for transmission. When @hold_skb is
+ * NULL, always return 0. Otherwise, return 0 if @hold_skb is sent
+ * successfully, or 1 for failure.
*/
-static void llc_conn_send_pdus(struct sock *sk)
+static int llc_conn_send_pdus(struct sock *sk, struct sk_buff *hold_skb)
{
struct sk_buff *skb;
+ int ret = 0;
while ((skb = skb_dequeue(&sk->sk_write_queue)) != NULL) {
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
@@ -357,10 +361,20 @@
skb_queue_tail(&llc_sk(sk)->pdu_unack_q, skb);
if (!skb2)
break;
- skb = skb2;
+ dev_queue_xmit(skb2);
+ } else {
+ bool is_target = skb == hold_skb;
+ int rc;
+
+ if (is_target)
+ skb_get(skb);
+ rc = dev_queue_xmit(skb);
+ if (is_target)
+ ret = rc;
}
- dev_queue_xmit(skb);
}
+
+ return ret;
}
/**
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 156e8e1..690fbac 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -34,6 +34,7 @@
#define IEEE80211_AUTH_TIMEOUT (HZ / 5)
#define IEEE80211_AUTH_TIMEOUT_LONG (HZ / 2)
#define IEEE80211_AUTH_TIMEOUT_SHORT (HZ / 10)
+#define IEEE80211_AUTH_TIMEOUT_SAE (HZ * 2)
#define IEEE80211_AUTH_MAX_TRIES 3
#define IEEE80211_AUTH_WAIT_ASSOC (HZ * 5)
#define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
@@ -3464,16 +3465,19 @@
}
if (tx_flags == 0) {
- auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
- auth_data->timeout_started = true;
- run_again(sdata, auth_data->timeout);
+ if (auth_data->algorithm == WLAN_AUTH_SAE)
+ auth_data->timeout = jiffies +
+ IEEE80211_AUTH_TIMEOUT_SAE;
+ else
+ auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
} else {
auth_data->timeout =
round_jiffies_up(jiffies + IEEE80211_AUTH_TIMEOUT_LONG);
- auth_data->timeout_started = true;
- run_again(sdata, auth_data->timeout);
}
+ auth_data->timeout_started = true;
+ run_again(sdata, auth_data->timeout);
+
return 0;
}
@@ -3545,8 +3549,15 @@
if (ifmgd->auth_data &&
(ieee80211_is_probe_req(fc) || ieee80211_is_auth(fc))) {
if (status_acked) {
- ifmgd->auth_data->timeout =
- jiffies + IEEE80211_AUTH_TIMEOUT_SHORT;
+ if (ifmgd->auth_data->algorithm ==
+ WLAN_AUTH_SAE)
+ ifmgd->auth_data->timeout =
+ jiffies +
+ IEEE80211_AUTH_TIMEOUT_SAE;
+ else
+ ifmgd->auth_data->timeout =
+ jiffies +
+ IEEE80211_AUTH_TIMEOUT_SHORT;
run_again(sdata, ifmgd->auth_data->timeout);
} else {
ifmgd->auth_data->timeout = jiffies - 1;
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
index cfe93c2..ee15f31 100644
--- a/net/netfilter/nf_log.c
+++ b/net/netfilter/nf_log.c
@@ -387,14 +387,17 @@
rcu_assign_pointer(net->nf.nf_loggers[tindex], logger);
mutex_unlock(&nf_log_mutex);
} else {
+ struct ctl_table tmp = *table;
+
+ tmp.data = buf;
mutex_lock(&nf_log_mutex);
logger = nft_log_dereference(net->nf.nf_loggers[tindex]);
if (!logger)
- table->data = "NONE";
+ strlcpy(buf, "NONE", sizeof(buf));
else
- table->data = logger->name;
- r = proc_dostring(table, write, buffer, lenp, ppos);
+ strlcpy(buf, logger->name, sizeof(buf));
mutex_unlock(&nf_log_mutex);
+ r = proc_dostring(&tmp, write, buffer, lenp, ppos);
}
return r;
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index 78a63c1..ff803bf 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -1472,6 +1472,16 @@
iface = rcu_dereference(netlbl_unlhsh_def);
if (iface == NULL || !iface->valid)
goto unlabel_getattr_nolabel;
+
+#if IS_ENABLED(CONFIG_IPV6)
+ /* When resolving a fallback label, check the sk_buff version as
+ * it is possible (e.g. SCTP) to have family = PF_INET6 while
+ * receiving ip_hdr(skb)->version = 4.
+ */
+ if (family == PF_INET6 && ip_hdr(skb)->version == 4)
+ family = PF_INET;
+#endif /* IPv6 */
+
switch (family) {
case PF_INET: {
struct iphdr *hdr4;
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index b4cc956..1c12e21 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1641,6 +1641,8 @@
if (msg->msg_namelen) {
err = -EINVAL;
+ if (msg->msg_namelen < sizeof(struct sockaddr_nl))
+ goto out;
if (addr->nl_family != AF_NETLINK)
goto out;
dst_portid = addr->nl_pid;
diff --git a/net/nfc/llcp_commands.c b/net/nfc/llcp_commands.c
index a3ad69a..1e72457 100644
--- a/net/nfc/llcp_commands.c
+++ b/net/nfc/llcp_commands.c
@@ -149,6 +149,10 @@
pr_debug("uri: %s, len: %zu\n", uri, uri_len);
+ /* sdreq->tlv_len is u8, takes uri_len, + 3 for header, + 1 for NULL */
+ if (WARN_ON_ONCE(uri_len > U8_MAX - 4))
+ return NULL;
+
sdreq = kzalloc(sizeof(struct nfc_llcp_sdp_tlv), GFP_KERNEL);
if (sdreq == NULL)
return NULL;
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
index c4dc313..982db48 100644
--- a/net/nfc/netlink.c
+++ b/net/nfc/netlink.c
@@ -60,7 +60,8 @@
};
static const struct nla_policy nfc_sdp_genl_policy[NFC_SDP_ATTR_MAX + 1] = {
- [NFC_SDP_ATTR_URI] = { .type = NLA_STRING },
+ [NFC_SDP_ATTR_URI] = { .type = NLA_STRING,
+ .len = U8_MAX - 4 },
[NFC_SDP_ATTR_SAP] = { .type = NLA_U8 },
};
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index cfbaafd..154cc05 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -3897,7 +3897,7 @@
goto out;
if (po->tp_version >= TPACKET_V3 &&
req->tp_block_size <=
- BLK_PLUS_PRIV((u64)req_u->req3.tp_sizeof_priv))
+ BLK_PLUS_PRIV((u64)req_u->req3.tp_sizeof_priv) + sizeof(struct tpacket3_hdr))
goto out;
if (unlikely(req->tp_frame_size < po->tp_hdrlen +
po->tp_reserve))
diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c
index 6621224..0e54a766 100644
--- a/net/rds/ib_cm.c
+++ b/net/rds/ib_cm.c
@@ -396,7 +396,7 @@
rdsdebug("conn %p pd %p mr %p cq %p %p\n", conn, ic->i_pd, ic->i_mr,
ic->i_send_cq, ic->i_recv_cq);
- return ret;
+ goto out;
sends_out:
vfree(ic->i_sends);
@@ -421,6 +421,7 @@
ic->i_send_cq = NULL;
rds_ibdev_out:
rds_ib_remove_conn(rds_ibdev, conn);
+out:
rds_ib_dev_put(rds_ibdev);
return ret;
diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c
index 0f62326..ffa7a20 100644
--- a/net/rfkill/rfkill-gpio.c
+++ b/net/rfkill/rfkill-gpio.c
@@ -134,13 +134,18 @@
ret = rfkill_register(rfkill->rfkill_dev);
if (ret < 0)
- return ret;
+ goto err_destroy;
platform_set_drvdata(pdev, rfkill);
dev_info(&pdev->dev, "%s device registered.\n", rfkill->name);
return 0;
+
+err_destroy:
+ rfkill_destroy(rfkill->rfkill_dev);
+
+ return ret;
}
static int rfkill_gpio_remove(struct platform_device *pdev)
diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c
index 01fe9d5..7d45ac7cf 100644
--- a/net/sched/sch_fq.c
+++ b/net/sched/sch_fq.c
@@ -124,6 +124,28 @@
return f->next == &detached;
}
+static bool fq_flow_is_throttled(const struct fq_flow *f)
+{
+ return f->next == &throttled;
+}
+
+static void fq_flow_add_tail(struct fq_flow_head *head, struct fq_flow *flow)
+{
+ if (head->first)
+ head->last->next = flow;
+ else
+ head->first = flow;
+ head->last = flow;
+ flow->next = NULL;
+}
+
+static void fq_flow_unset_throttled(struct fq_sched_data *q, struct fq_flow *f)
+{
+ rb_erase(&f->rate_node, &q->delayed);
+ q->throttled_flows--;
+ fq_flow_add_tail(&q->old_flows, f);
+}
+
static void fq_flow_set_throttled(struct fq_sched_data *q, struct fq_flow *f)
{
struct rb_node **p = &q->delayed.rb_node, *parent = NULL;
@@ -151,15 +173,6 @@
static struct kmem_cache *fq_flow_cachep __read_mostly;
-static void fq_flow_add_tail(struct fq_flow_head *head, struct fq_flow *flow)
-{
- if (head->first)
- head->last->next = flow;
- else
- head->first = flow;
- head->last = flow;
- flow->next = NULL;
-}
/* limit number of collected flows per round */
#define FQ_GC_MAX 8
@@ -251,6 +264,8 @@
f->socket_hash != sk->sk_hash)) {
f->credit = q->initial_quantum;
f->socket_hash = sk->sk_hash;
+ if (fq_flow_is_throttled(f))
+ fq_flow_unset_throttled(q, f);
f->time_next_packet = 0ULL;
}
return f;
@@ -405,9 +420,7 @@
q->time_next_delayed_flow = f->time_next_packet;
break;
}
- rb_erase(p, &q->delayed);
- q->throttled_flows--;
- fq_flow_add_tail(&q->old_flows, f);
+ fq_flow_unset_throttled(q, f);
}
}
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 26d06db..16911a8 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -1001,9 +1001,10 @@
struct sctp_endpoint *ep;
struct sctp_chunk *chunk;
struct sctp_inq *inqueue;
- int state;
sctp_subtype_t subtype;
+ int first_time = 1; /* is this the first time through the loop */
int error = 0;
+ int state;
/* The association should be held so we should be safe. */
ep = asoc->ep;
@@ -1014,6 +1015,30 @@
state = asoc->state;
subtype = SCTP_ST_CHUNK(chunk->chunk_hdr->type);
+ /* If the first chunk in the packet is AUTH, do special
+ * processing specified in Section 6.3 of SCTP-AUTH spec
+ */
+ if (first_time && subtype.chunk == SCTP_CID_AUTH) {
+ struct sctp_chunkhdr *next_hdr;
+
+ next_hdr = sctp_inq_peek(inqueue);
+ if (!next_hdr)
+ goto normal;
+
+ /* If the next chunk is COOKIE-ECHO, skip the AUTH
+ * chunk while saving a pointer to it so we can do
+ * Authentication later (during cookie-echo
+ * processing).
+ */
+ if (next_hdr->type == SCTP_CID_COOKIE_ECHO) {
+ chunk->auth_chunk = skb_clone(chunk->skb,
+ GFP_ATOMIC);
+ chunk->auth = 1;
+ continue;
+ }
+ }
+
+normal:
/* SCTP-AUTH, Section 6.3:
* The receiver has a list of chunk types which it expects
* to be received only after an AUTH-chunk. This list has
@@ -1052,6 +1077,9 @@
/* If there is an error on chunk, discard this packet. */
if (error && chunk)
chunk->pdiscard = 1;
+
+ if (first_time)
+ first_time = 0;
}
sctp_association_put(asoc);
}
diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c
index 7e8a16c..8d9b7ad 100644
--- a/net/sctp/inqueue.c
+++ b/net/sctp/inqueue.c
@@ -178,7 +178,7 @@
skb_pull(chunk->skb, sizeof(sctp_chunkhdr_t));
chunk->subh.v = NULL; /* Subheader is no longer valid. */
- if (chunk->chunk_end + sizeof(sctp_chunkhdr_t) <
+ if (chunk->chunk_end + sizeof(sctp_chunkhdr_t) <=
skb_tail_pointer(chunk->skb)) {
/* This is not a singleton */
chunk->singleton = 0;
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 690a973b..cfc832d 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -144,10 +144,8 @@
void *arg,
sctp_cmd_seq_t *commands);
-static sctp_ierror_t sctp_sf_authenticate(struct net *net,
- const struct sctp_endpoint *ep,
+static sctp_ierror_t sctp_sf_authenticate(
const struct sctp_association *asoc,
- const sctp_subtype_t type,
struct sctp_chunk *chunk);
static sctp_disposition_t __sctp_sf_do_9_1_abort(struct net *net,
@@ -615,6 +613,38 @@
return SCTP_DISPOSITION_CONSUME;
}
+static bool sctp_auth_chunk_verify(struct net *net, struct sctp_chunk *chunk,
+ const struct sctp_association *asoc)
+{
+ struct sctp_chunk auth;
+
+ if (!chunk->auth_chunk)
+ return true;
+
+ /* SCTP-AUTH: auth_chunk pointer is only set when the cookie-echo
+ * is supposed to be authenticated and we have to do delayed
+ * authentication. We've just recreated the association using
+ * the information in the cookie and now it's much easier to
+ * do the authentication.
+ */
+
+ /* Make sure that we and the peer are AUTH capable */
+ if (!net->sctp.auth_enable || !asoc->peer.auth_capable)
+ return false;
+
+ /* set-up our fake chunk so that we can process it */
+ auth.skb = chunk->auth_chunk;
+ auth.asoc = chunk->asoc;
+ auth.sctp_hdr = chunk->sctp_hdr;
+ auth.chunk_hdr = (struct sctp_chunkhdr *)
+ skb_push(chunk->auth_chunk,
+ sizeof(struct sctp_chunkhdr));
+ skb_pull(chunk->auth_chunk, sizeof(struct sctp_chunkhdr));
+ auth.transport = chunk->transport;
+
+ return sctp_sf_authenticate(asoc, &auth) == SCTP_IERROR_NO_ERROR;
+}
+
/*
* Respond to a normal COOKIE ECHO chunk.
* We are the side that is being asked for an association.
@@ -751,36 +781,9 @@
if (error)
goto nomem_init;
- /* SCTP-AUTH: auth_chunk pointer is only set when the cookie-echo
- * is supposed to be authenticated and we have to do delayed
- * authentication. We've just recreated the association using
- * the information in the cookie and now it's much easier to
- * do the authentication.
- */
- if (chunk->auth_chunk) {
- struct sctp_chunk auth;
- sctp_ierror_t ret;
-
- /* Make sure that we and the peer are AUTH capable */
- if (!net->sctp.auth_enable || !new_asoc->peer.auth_capable) {
- sctp_association_free(new_asoc);
- return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
- }
-
- /* set-up our fake chunk so that we can process it */
- auth.skb = chunk->auth_chunk;
- auth.asoc = chunk->asoc;
- auth.sctp_hdr = chunk->sctp_hdr;
- auth.chunk_hdr = (sctp_chunkhdr_t *)skb_push(chunk->auth_chunk,
- sizeof(sctp_chunkhdr_t));
- skb_pull(chunk->auth_chunk, sizeof(sctp_chunkhdr_t));
- auth.transport = chunk->transport;
-
- ret = sctp_sf_authenticate(net, ep, new_asoc, type, &auth);
- if (ret != SCTP_IERROR_NO_ERROR) {
- sctp_association_free(new_asoc);
- return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
- }
+ if (!sctp_auth_chunk_verify(net, chunk, new_asoc)) {
+ sctp_association_free(new_asoc);
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
}
repl = sctp_make_cookie_ack(new_asoc, chunk);
@@ -1717,13 +1720,15 @@
GFP_ATOMIC))
goto nomem;
+ if (!sctp_auth_chunk_verify(net, chunk, new_asoc))
+ return SCTP_DISPOSITION_DISCARD;
+
/* Make sure no new addresses are being added during the
* restart. Though this is a pretty complicated attack
* since you'd have to get inside the cookie.
*/
- if (!sctp_sf_check_restart_addrs(new_asoc, asoc, chunk, commands)) {
+ if (!sctp_sf_check_restart_addrs(new_asoc, asoc, chunk, commands))
return SCTP_DISPOSITION_CONSUME;
- }
/* If the endpoint is in the SHUTDOWN-ACK-SENT state and recognizes
* the peer has restarted (Action A), it MUST NOT setup a new
@@ -1828,6 +1833,9 @@
GFP_ATOMIC))
goto nomem;
+ if (!sctp_auth_chunk_verify(net, chunk, new_asoc))
+ return SCTP_DISPOSITION_DISCARD;
+
/* Update the content of current association. */
sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc));
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
@@ -1920,6 +1928,9 @@
* a COOKIE ACK.
*/
+ if (!sctp_auth_chunk_verify(net, chunk, asoc))
+ return SCTP_DISPOSITION_DISCARD;
+
/* Don't accidentally move back into established state. */
if (asoc->state < SCTP_STATE_ESTABLISHED) {
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
@@ -1959,7 +1970,7 @@
}
}
- repl = sctp_make_cookie_ack(new_asoc, chunk);
+ repl = sctp_make_cookie_ack(asoc, chunk);
if (!repl)
goto nomem;
@@ -3985,10 +3996,8 @@
*
* The return value is the disposition of the chunk.
*/
-static sctp_ierror_t sctp_sf_authenticate(struct net *net,
- const struct sctp_endpoint *ep,
+static sctp_ierror_t sctp_sf_authenticate(
const struct sctp_association *asoc,
- const sctp_subtype_t type,
struct sctp_chunk *chunk)
{
struct sctp_authhdr *auth_hdr;
@@ -4087,7 +4096,7 @@
commands);
auth_hdr = (struct sctp_authhdr *)chunk->skb->data;
- error = sctp_sf_authenticate(net, ep, asoc, type, chunk);
+ error = sctp_sf_authenticate(asoc, chunk);
switch (error) {
case SCTP_IERROR_AUTH_BAD_HMAC:
/* Generate the ERROR chunk and discard the rest
diff --git a/net/wireless/core.c b/net/wireless/core.c
index d2c35e1..304f310 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -94,6 +94,9 @@
ASSERT_RTNL();
+ if (strlen(newname) > NL80211_WIPHY_NAME_MAXLEN)
+ return -EINVAL;
+
/* prohibit calling the thing phy%d when %d is not its number */
sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken);
if (taken == strlen(newname) && wiphy_idx != rdev->wiphy_idx) {
diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c
index d662652..23cd5ce 100644
--- a/scripts/kconfig/expr.c
+++ b/scripts/kconfig/expr.c
@@ -106,7 +106,7 @@
break;
case E_NOT:
expr_free(e->left.expr);
- return;
+ break;
case E_EQUAL:
case E_UNEQUAL:
break;
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 72c9dba..095a609 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -364,6 +364,7 @@
menu->parent = parent;
last_menu = menu;
}
+ expr_free(basedep);
if (last_menu) {
parent->list = parent->next;
parent->next = last_menu->next;
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
index 0f683cf..52dda77 100644
--- a/scripts/kconfig/zconf.y
+++ b/scripts/kconfig/zconf.y
@@ -102,7 +102,27 @@
%%
input: nl start | start;
-start: mainmenu_stmt stmt_list | stmt_list;
+start: mainmenu_stmt stmt_list | no_mainmenu_stmt stmt_list;
+
+/* mainmenu entry */
+
+mainmenu_stmt: T_MAINMENU prompt nl
+{
+ menu_add_prompt(P_MENU, $2, NULL);
+};
+
+/* Default main menu, if there's no mainmenu entry */
+
+no_mainmenu_stmt: /* empty */
+{
+ /*
+ * Hack: Keep the main menu title on the heap so we can safely free it
+ * later regardless of whether it comes from the 'prompt' in
+ * mainmenu_stmt or here
+ */
+ menu_add_prompt(P_MENU, strdup("Linux Kernel Configuration"), NULL);
+};
+
stmt_list:
/* empty */
@@ -339,13 +359,6 @@
| if_block choice_stmt
;
-/* mainmenu entry */
-
-mainmenu_stmt: T_MAINMENU prompt nl
-{
- menu_add_prompt(P_MENU, $2, NULL);
-};
-
/* menu entry */
menu: T_MENU prompt T_EOL
@@ -486,6 +499,7 @@
void conf_parse(const char *name)
{
+ const char *tmp;
struct symbol *sym;
int i;
@@ -493,7 +507,6 @@
sym_init();
_menu_init();
- rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL);
if (getenv("ZCONF_DEBUG"))
zconfdebug = 1;
@@ -503,8 +516,10 @@
if (!modules_sym)
modules_sym = sym_find( "n" );
+ tmp = rootmenu.prompt->text;
rootmenu.prompt->text = _(rootmenu.prompt->text);
rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text);
+ free((char*)tmp);
menu_finalize(&rootmenu);
for_all_symbols(i, sym) {
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index 78d66da..21845e1 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -108,6 +108,8 @@
hash_algo_name[ima_hash_algo], rc);
return rc;
}
+ pr_info("Allocated hash algorithm: %s\n",
+ hash_algo_name[ima_hash_algo]);
return 0;
}
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 0159094..f3b9653 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -16,6 +16,9 @@
* implements the IMA hooks: ima_bprm_check, ima_file_mmap,
* and ima_file_check.
*/
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/file.h>
#include <linux/binfmts.h>
@@ -351,6 +354,16 @@
hash_setup(CONFIG_IMA_DEFAULT_HASH);
error = ima_init();
+
+ if (error && strcmp(hash_algo_name[ima_hash_algo],
+ CONFIG_IMA_DEFAULT_HASH) != 0) {
+ pr_info("Allocating %s failed, going to use default hash algorithm %s\n",
+ hash_algo_name[ima_hash_algo], CONFIG_IMA_DEFAULT_HASH);
+ hash_setup_done = 0;
+ hash_setup(CONFIG_IMA_DEFAULT_HASH);
+ error = ima_init();
+ }
+
if (!error) {
ima_initialized = 1;
ima_update_policy_flag();
diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c
index 0608f21..ac0a40b 100644
--- a/sound/core/control_compat.c
+++ b/sound/core/control_compat.c
@@ -400,8 +400,7 @@
if (copy_from_user(&data->id, &data32->id, sizeof(data->id)) ||
copy_from_user(&data->type, &data32->type, 3 * sizeof(u32)))
goto error;
- if (get_user(data->owner, &data32->owner) ||
- get_user(data->type, &data32->type))
+ if (get_user(data->owner, &data32->owner))
goto error;
switch (data->type) {
case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c
index af0f4526..2d01d8b 100644
--- a/sound/core/pcm_compat.c
+++ b/sound/core/pcm_compat.c
@@ -333,6 +333,8 @@
return -ENOTTY;
if (substream->stream != dir)
return -EINVAL;
+ if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)
+ return -EBADFD;
if ((ch = substream->runtime->channels) > 128)
return -EINVAL;
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index bf866f8..2556680 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -2737,6 +2737,7 @@
sync_ptr.s.status.hw_ptr = status->hw_ptr;
sync_ptr.s.status.tstamp = status->tstamp;
sync_ptr.s.status.suspended_state = status->suspended_state;
+ sync_ptr.s.status.audio_tstamp = status->audio_tstamp;
snd_pcm_stream_unlock_irq(substream);
if (copy_to_user(_sync_ptr, &sync_ptr, sizeof(sync_ptr)))
return -EFAULT;
diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c
index ac3d7d2..760b3409 100644
--- a/sound/core/seq/oss/seq_oss_synth.c
+++ b/sound/core/seq/oss/seq_oss_synth.c
@@ -363,10 +363,14 @@
return NULL;
if (! dp->synths[dev].opened)
return NULL;
- if (dp->synths[dev].is_midi)
- return &midi_synth_dev;
- if ((rec = get_sdev(dev)) == NULL)
- return NULL;
+ if (dp->synths[dev].is_midi) {
+ rec = &midi_synth_dev;
+ snd_use_lock_use(&rec->use_lock);
+ } else {
+ rec = get_sdev(dev);
+ if (!rec)
+ return NULL;
+ }
if (! rec->opened) {
snd_use_lock_free(&rec->use_lock);
return NULL;
diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c
index 3b126af..ef494ff 100644
--- a/sound/core/seq/seq_virmidi.c
+++ b/sound/core/seq/seq_virmidi.c
@@ -174,12 +174,12 @@
}
return;
}
+ spin_lock_irqsave(&substream->runtime->lock, flags);
if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) {
if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0)
- return;
+ goto out;
vmidi->event.type = SNDRV_SEQ_EVENT_NONE;
}
- spin_lock_irqsave(&substream->runtime->lock, flags);
while (1) {
count = __snd_rawmidi_transmit_peek(substream, buf, sizeof(buf));
if (count <= 0)
diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c
index 6c58e6f..7c6ef87 100644
--- a/sound/core/vmaster.c
+++ b/sound/core/vmaster.c
@@ -68,10 +68,13 @@
return -ENOMEM;
uctl->id = slave->slave.id;
err = slave->slave.get(&slave->slave, uctl);
+ if (err < 0)
+ goto error;
for (ch = 0; ch < slave->info.count; ch++)
slave->vals[ch] = uctl->value.integer.value[ch];
+ error:
kfree(uctl);
- return 0;
+ return err < 0 ? err : 0;
}
/* get the slave ctl info and save the initial values */
diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c
index 6c5b4e0..835f309 100644
--- a/sound/drivers/aloop.c
+++ b/sound/drivers/aloop.c
@@ -297,6 +297,8 @@
cable->pause |= stream;
loopback_timer_stop(dpcm);
spin_unlock(&cable->lock);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ loopback_active_notify(dpcm);
break;
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
case SNDRV_PCM_TRIGGER_RESUME:
@@ -305,6 +307,8 @@
cable->pause &= ~stream;
loopback_timer_start(dpcm);
spin_unlock(&cable->lock);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ loopback_active_notify(dpcm);
break;
default:
return -EINVAL;
@@ -829,9 +833,11 @@
{
struct loopback *loopback = snd_kcontrol_chip(kcontrol);
+ mutex_lock(&loopback->cable_lock);
ucontrol->value.integer.value[0] =
loopback->setup[kcontrol->id.subdevice]
[kcontrol->id.device].rate_shift;
+ mutex_unlock(&loopback->cable_lock);
return 0;
}
@@ -863,9 +869,11 @@
{
struct loopback *loopback = snd_kcontrol_chip(kcontrol);
+ mutex_lock(&loopback->cable_lock);
ucontrol->value.integer.value[0] =
loopback->setup[kcontrol->id.subdevice]
[kcontrol->id.device].notify;
+ mutex_unlock(&loopback->cable_lock);
return 0;
}
@@ -877,12 +885,14 @@
int change = 0;
val = ucontrol->value.integer.value[0] ? 1 : 0;
+ mutex_lock(&loopback->cable_lock);
if (val != loopback->setup[kcontrol->id.subdevice]
[kcontrol->id.device].notify) {
loopback->setup[kcontrol->id.subdevice]
[kcontrol->id.device].notify = val;
change = 1;
}
+ mutex_unlock(&loopback->cable_lock);
return change;
}
@@ -890,13 +900,18 @@
struct snd_ctl_elem_value *ucontrol)
{
struct loopback *loopback = snd_kcontrol_chip(kcontrol);
- struct loopback_cable *cable = loopback->cables
- [kcontrol->id.subdevice][kcontrol->id.device ^ 1];
+ struct loopback_cable *cable;
+
unsigned int val = 0;
- if (cable != NULL)
- val = (cable->running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ?
- 1 : 0;
+ mutex_lock(&loopback->cable_lock);
+ cable = loopback->cables[kcontrol->id.subdevice][kcontrol->id.device ^ 1];
+ if (cable != NULL) {
+ unsigned int running = cable->running ^ cable->pause;
+
+ val = (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ? 1 : 0;
+ }
+ mutex_unlock(&loopback->cable_lock);
ucontrol->value.integer.value[0] = val;
return 0;
}
@@ -939,9 +954,11 @@
{
struct loopback *loopback = snd_kcontrol_chip(kcontrol);
+ mutex_lock(&loopback->cable_lock);
ucontrol->value.integer.value[0] =
loopback->setup[kcontrol->id.subdevice]
[kcontrol->id.device].rate;
+ mutex_unlock(&loopback->cable_lock);
return 0;
}
@@ -961,9 +978,11 @@
{
struct loopback *loopback = snd_kcontrol_chip(kcontrol);
+ mutex_lock(&loopback->cable_lock);
ucontrol->value.integer.value[0] =
loopback->setup[kcontrol->id.subdevice]
[kcontrol->id.device].channels;
+ mutex_unlock(&loopback->cable_lock);
return 0;
}
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
index 20aa52b..3f804d1 100644
--- a/sound/pci/hda/hda_controller.c
+++ b/sound/pci/hda/hda_controller.c
@@ -915,8 +915,10 @@
return err;
strlcpy(pcm->name, cpcm->name, sizeof(pcm->name));
apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
- if (apcm == NULL)
+ if (apcm == NULL) {
+ snd_device_free(chip->card, pcm);
return -ENOMEM;
+ }
apcm->chip = chip;
apcm->pcm = pcm;
apcm->codec = codec;
diff --git a/sound/soc/au1x/ac97c.c b/sound/soc/au1x/ac97c.c
index c8a2de1..7591e48 100644
--- a/sound/soc/au1x/ac97c.c
+++ b/sound/soc/au1x/ac97c.c
@@ -91,8 +91,8 @@
do {
mutex_lock(&ctx->lock);
- tmo = 5;
- while ((RD(ctx, AC97_STATUS) & STAT_CP) && tmo--)
+ tmo = 6;
+ while ((RD(ctx, AC97_STATUS) & STAT_CP) && --tmo)
udelay(21); /* wait an ac97 frame time */
if (!tmo) {
pr_debug("ac97rd timeout #1\n");
@@ -105,7 +105,7 @@
* poll, Forrest, poll...
*/
tmo = 0x10000;
- while ((RD(ctx, AC97_STATUS) & STAT_CP) && tmo--)
+ while ((RD(ctx, AC97_STATUS) & STAT_CP) && --tmo)
asm volatile ("nop");
data = RD(ctx, AC97_CMDRESP);
diff --git a/sound/soc/cirrus/edb93xx.c b/sound/soc/cirrus/edb93xx.c
index 4f900ef..7b7fc9f 100644
--- a/sound/soc/cirrus/edb93xx.c
+++ b/sound/soc/cirrus/edb93xx.c
@@ -67,7 +67,7 @@
.cpu_dai_name = "ep93xx-i2s",
.codec_name = "spi0.0",
.codec_dai_name = "cs4271-hifi",
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF |
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS,
.ops = &edb93xx_ops,
};
diff --git a/sound/soc/cirrus/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c
index 943145f..ff10d49 100644
--- a/sound/soc/cirrus/ep93xx-i2s.c
+++ b/sound/soc/cirrus/ep93xx-i2s.c
@@ -51,7 +51,9 @@
#define EP93XX_I2S_WRDLEN_24 (1 << 0)
#define EP93XX_I2S_WRDLEN_32 (2 << 0)
-#define EP93XX_I2S_LINCTRLDATA_R_JUST (1 << 2) /* Right justify */
+#define EP93XX_I2S_RXLINCTRLDATA_R_JUST BIT(1) /* Right justify */
+
+#define EP93XX_I2S_TXLINCTRLDATA_R_JUST BIT(2) /* Right justify */
#define EP93XX_I2S_CLKCFG_LRS (1 << 0) /* lrclk polarity */
#define EP93XX_I2S_CLKCFG_CKP (1 << 1) /* Bit clock polarity */
@@ -170,25 +172,25 @@
unsigned int fmt)
{
struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(cpu_dai);
- unsigned int clk_cfg, lin_ctrl;
+ unsigned int clk_cfg;
+ unsigned int txlin_ctrl = 0;
+ unsigned int rxlin_ctrl = 0;
clk_cfg = ep93xx_i2s_read_reg(info, EP93XX_I2S_RXCLKCFG);
- lin_ctrl = ep93xx_i2s_read_reg(info, EP93XX_I2S_RXLINCTRLDATA);
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S:
clk_cfg |= EP93XX_I2S_CLKCFG_REL;
- lin_ctrl &= ~EP93XX_I2S_LINCTRLDATA_R_JUST;
break;
case SND_SOC_DAIFMT_LEFT_J:
clk_cfg &= ~EP93XX_I2S_CLKCFG_REL;
- lin_ctrl &= ~EP93XX_I2S_LINCTRLDATA_R_JUST;
break;
case SND_SOC_DAIFMT_RIGHT_J:
clk_cfg &= ~EP93XX_I2S_CLKCFG_REL;
- lin_ctrl |= EP93XX_I2S_LINCTRLDATA_R_JUST;
+ rxlin_ctrl |= EP93XX_I2S_RXLINCTRLDATA_R_JUST;
+ txlin_ctrl |= EP93XX_I2S_TXLINCTRLDATA_R_JUST;
break;
default:
@@ -213,32 +215,32 @@
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
case SND_SOC_DAIFMT_NB_NF:
/* Negative bit clock, lrclk low on left word */
- clk_cfg &= ~(EP93XX_I2S_CLKCFG_CKP | EP93XX_I2S_CLKCFG_REL);
+ clk_cfg &= ~(EP93XX_I2S_CLKCFG_CKP | EP93XX_I2S_CLKCFG_LRS);
break;
case SND_SOC_DAIFMT_NB_IF:
/* Negative bit clock, lrclk low on right word */
clk_cfg &= ~EP93XX_I2S_CLKCFG_CKP;
- clk_cfg |= EP93XX_I2S_CLKCFG_REL;
+ clk_cfg |= EP93XX_I2S_CLKCFG_LRS;
break;
case SND_SOC_DAIFMT_IB_NF:
/* Positive bit clock, lrclk low on left word */
clk_cfg |= EP93XX_I2S_CLKCFG_CKP;
- clk_cfg &= ~EP93XX_I2S_CLKCFG_REL;
+ clk_cfg &= ~EP93XX_I2S_CLKCFG_LRS;
break;
case SND_SOC_DAIFMT_IB_IF:
/* Positive bit clock, lrclk low on right word */
- clk_cfg |= EP93XX_I2S_CLKCFG_CKP | EP93XX_I2S_CLKCFG_REL;
+ clk_cfg |= EP93XX_I2S_CLKCFG_CKP | EP93XX_I2S_CLKCFG_LRS;
break;
}
/* Write new register values */
ep93xx_i2s_write_reg(info, EP93XX_I2S_RXCLKCFG, clk_cfg);
ep93xx_i2s_write_reg(info, EP93XX_I2S_TXCLKCFG, clk_cfg);
- ep93xx_i2s_write_reg(info, EP93XX_I2S_RXLINCTRLDATA, lin_ctrl);
- ep93xx_i2s_write_reg(info, EP93XX_I2S_TXLINCTRLDATA, lin_ctrl);
+ ep93xx_i2s_write_reg(info, EP93XX_I2S_RXLINCTRLDATA, rxlin_ctrl);
+ ep93xx_i2s_write_reg(info, EP93XX_I2S_TXLINCTRLDATA, txlin_ctrl);
return 0;
}
diff --git a/sound/soc/cirrus/snappercl15.c b/sound/soc/cirrus/snappercl15.c
index 5b68b10..8f2515c 100644
--- a/sound/soc/cirrus/snappercl15.c
+++ b/sound/soc/cirrus/snappercl15.c
@@ -72,7 +72,7 @@
.codec_dai_name = "tlv320aic23-hifi",
.codec_name = "tlv320aic23-codec.0-001a",
.platform_name = "ep93xx-i2s",
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF |
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS,
.ops = &snappercl15_ops,
};
diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c
index 4a83595..23236ae8 100644
--- a/sound/soc/codecs/wcd9335.c
+++ b/sound/soc/codecs/wcd9335.c
@@ -108,7 +108,7 @@
/* Convert from vout ctl to micbias voltage in mV */
#define WCD_VOUT_CTL_TO_MICB(v) (1000 + v * 50)
-#define TASHA_ZDET_NUM_MEASUREMENTS 150
+#define TASHA_ZDET_NUM_MEASUREMENTS 900
#define TASHA_MBHC_GET_C1(c) ((c & 0xC000) >> 14)
#define TASHA_MBHC_GET_X1(x) (x & 0x3FFF)
/* z value compared in milliOhm */
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index a645e29..ebfa6a7 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -143,6 +143,13 @@
psr = ratio <= 256 * maxfp ? ESAI_xCCR_xPSR_BYPASS : ESAI_xCCR_xPSR_DIV8;
+ /* Do not loop-search if PM (1 ~ 256) alone can serve the ratio */
+ if (ratio <= 256) {
+ pm = ratio;
+ fp = 1;
+ goto out;
+ }
+
/* Set the max fluctuation -- 0.1% of the max devisor */
savesub = (psr ? 1 : 8) * 256 * maxfp / 1000;
diff --git a/sound/soc/msm/apq8009-i2s-ext-codec.c b/sound/soc/msm/apq8009-i2s-ext-codec.c
index 47f22a4..9d8e4aa 100644
--- a/sound/soc/msm/apq8009-i2s-ext-codec.c
+++ b/sound/soc/msm/apq8009-i2s-ext-codec.c
@@ -2111,6 +2111,7 @@
.platform_name = "msm-compress-dsp",
.dynamic = 1,
.dpcm_playback = 1,
+ .dpcm_capture = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
.codec_dai_name = "snd-soc-dummy-dai",
@@ -2390,6 +2391,55 @@
},
};
+static struct snd_soc_dai_link msm_compr_fe_dai[] = {
+ /* FE TDM DAI links */
+ {/* hw:x,43 */
+ .name = "APQ8009 Compress3",
+ .stream_name = "Compress3",
+ .cpu_dai_name = "MultiMedia17",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA17,
+ },
+ {/* hw:x,44 */
+ .name = "APQ8009 Compress4",
+ .stream_name = "Compress4",
+ .cpu_dai_name = "MultiMedia18",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA18,
+ },
+ {/* hw:x,45 */
+ .name = "APQ8009 Compress5",
+ .stream_name = "Compress5",
+ .cpu_dai_name = "MultiMedia19",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA19,
+ },
+};
+
static struct snd_soc_dai_link msm_tdm_be_dai[] = {
/* TDM be dai links */
{
@@ -2425,6 +2475,7 @@
static struct snd_soc_dai_link apq8009_9326_dai_links[
ARRAY_SIZE(apq8009_dai) +
ARRAY_SIZE(msm_tdm_fe_dai) +
+ ARRAY_SIZE(msm_compr_fe_dai) +
ARRAY_SIZE(apq8009_9326_dai) +
ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link) +
ARRAY_SIZE(msm_tdm_be_dai)];
@@ -2447,7 +2498,7 @@
struct snd_soc_card *populate_snd_card_dailinks(struct device *dev)
{
struct snd_soc_card *card = &snd_soc_card_9326_apq8009;
- int ret, len1, len2, len3;
+ int ret, len1, len2, len3, len4;
card->dev = dev;
ret = snd_soc_of_parse_card_name(card, "qcom,model");
@@ -2460,34 +2511,37 @@
len1 = ARRAY_SIZE(apq8009_dai);
len2 = len1 + ARRAY_SIZE(msm_tdm_fe_dai);
- len3 = len2 + ARRAY_SIZE(apq8009_9326_dai);
+ len3 = len2 + ARRAY_SIZE(msm_compr_fe_dai);
+ len4 = len3 + ARRAY_SIZE(apq8009_9326_dai);
memcpy(apq8009_9326_dai_links, apq8009_dai,
sizeof(apq8009_dai));
memcpy(apq8009_9326_dai_links + len1, msm_tdm_fe_dai,
sizeof(msm_tdm_fe_dai));
- memcpy(apq8009_9326_dai_links + len2, apq8009_9326_dai,
+ memcpy(apq8009_9326_dai_links + len2, msm_compr_fe_dai,
+ sizeof(msm_compr_fe_dai));
+ memcpy(apq8009_9326_dai_links + len3, apq8009_9326_dai,
sizeof(apq8009_9326_dai));
if (of_property_read_bool(dev->of_node, "qcom,afe-rxtx-lb")) {
dev_dbg(dev, "%s(): AFE RX to TX loopback supported\n",
__func__);
- memcpy(apq8009_9326_dai_links + len3,
+ memcpy(apq8009_9326_dai_links + len4,
msm_afe_rxtx_lb_be_dai_link,
sizeof(msm_afe_rxtx_lb_be_dai_link));
- len3 += ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link);
+ len4 += ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link);
}
if (of_property_read_bool(dev->of_node, "qcom,tdm-audio-intf")) {
dev_dbg(dev, "%s(): TDM support present\n",
__func__);
- memcpy(apq8009_9326_dai_links + len3, msm_tdm_be_dai,
+ memcpy(apq8009_9326_dai_links + len4, msm_tdm_be_dai,
sizeof(msm_tdm_be_dai));
- len3 += ARRAY_SIZE(msm_tdm_be_dai);
+ len4 += ARRAY_SIZE(msm_tdm_be_dai);
}
card->dai_link = apq8009_9326_dai_links;
- card->num_links = len3;
+ card->num_links = len4;
card->dev = dev;
return card;
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
index 9888f2f..51ef01c 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
@@ -293,7 +293,7 @@
struct msm_audio *prtd = runtime->private_data;
struct msm_plat_data *pdata;
struct snd_pcm_hw_params *params;
- int ret;
+ int ret = 0;
uint16_t bits_per_sample;
uint16_t sample_word_size;
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index 172f62f..ed7d4ed 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -6316,6 +6316,18 @@
SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX,
MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0,
+ MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new mmul18_mixer_controls[] = {
@@ -6349,6 +6361,18 @@
SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX,
MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0,
+ MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new mmul19_mixer_controls[] = {
@@ -6382,6 +6406,18 @@
SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0,
+ MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new mmul20_mixer_controls[] = {
@@ -11419,6 +11455,18 @@
{"MultiMedia17 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
{"MultiMedia18 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
{"MultiMedia19 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"MultiMedia17 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
+ {"MultiMedia18 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
+ {"MultiMedia19 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
+ {"MultiMedia17 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
+ {"MultiMedia18 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
+ {"MultiMedia19 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
+ {"MultiMedia17 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"},
+ {"MultiMedia18 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"},
+ {"MultiMedia19 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"},
+ {"MultiMedia17 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
+ {"MultiMedia18 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
+ {"MultiMedia19 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
{"MultiMedia28 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
{"MultiMedia29 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
{"MultiMedia3 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
diff --git a/sound/soc/msm/qdsp6v2/rtac.c b/sound/soc/msm/qdsp6v2/rtac.c
index 4a32565..441b68e 100644
--- a/sound/soc/msm/qdsp6v2/rtac.c
+++ b/sound/soc/msm/qdsp6v2/rtac.c
@@ -127,6 +127,11 @@
struct mutex rtac_voice_apr_mutex;
struct mutex rtac_afe_apr_mutex;
+static struct mutex rtac_asm_cal_mutex;
+static struct mutex rtac_adm_cal_mutex;
+static struct mutex rtac_afe_cal_mutex;
+static struct mutex rtac_voice_cal_mutex;
+
int rtac_clear_mapping(uint32_t cal_type)
{
int result = 0;
@@ -1693,42 +1698,62 @@
}
case AUDIO_GET_RTAC_ADM_CAL:
+ mutex_lock(&rtac_adm_cal_mutex);
result = send_adm_apr((void *)arg, ADM_CMD_GET_PP_PARAMS_V5);
+ mutex_unlock(&rtac_adm_cal_mutex);
break;
case AUDIO_SET_RTAC_ADM_CAL:
+ mutex_lock(&rtac_adm_cal_mutex);
result = send_adm_apr((void *)arg, ADM_CMD_SET_PP_PARAMS_V5);
+ mutex_unlock(&rtac_adm_cal_mutex);
break;
case AUDIO_GET_RTAC_ASM_CAL:
+ mutex_lock(&rtac_asm_cal_mutex);
result = send_rtac_asm_apr((void *)arg,
ASM_STREAM_CMD_GET_PP_PARAMS_V2);
+ mutex_unlock(&rtac_asm_cal_mutex);
break;
case AUDIO_SET_RTAC_ASM_CAL:
+ mutex_lock(&rtac_asm_cal_mutex);
result = send_rtac_asm_apr((void *)arg,
ASM_STREAM_CMD_SET_PP_PARAMS_V2);
+ mutex_unlock(&rtac_asm_cal_mutex);
break;
case AUDIO_GET_RTAC_CVS_CAL:
+ mutex_lock(&rtac_voice_cal_mutex);
result = send_voice_apr(RTAC_CVS, (void *)arg,
VOICE_CMD_GET_PARAM);
+ mutex_unlock(&rtac_voice_cal_mutex);
break;
case AUDIO_SET_RTAC_CVS_CAL:
+ mutex_lock(&rtac_voice_cal_mutex);
result = send_voice_apr(RTAC_CVS, (void *)arg,
VOICE_CMD_SET_PARAM);
+ mutex_unlock(&rtac_voice_cal_mutex);
break;
case AUDIO_GET_RTAC_CVP_CAL:
+ mutex_lock(&rtac_voice_cal_mutex);
result = send_voice_apr(RTAC_CVP, (void *)arg,
VOICE_CMD_GET_PARAM);
+ mutex_unlock(&rtac_voice_cal_mutex);
break;
case AUDIO_SET_RTAC_CVP_CAL:
+ mutex_lock(&rtac_voice_cal_mutex);
result = send_voice_apr(RTAC_CVP, (void *)arg,
VOICE_CMD_SET_PARAM);
+ mutex_unlock(&rtac_voice_cal_mutex);
break;
case AUDIO_GET_RTAC_AFE_CAL:
+ mutex_lock(&rtac_afe_cal_mutex);
result = send_rtac_afe_apr((void *)arg,
AFE_PORT_CMD_GET_PARAM_V2);
+ mutex_unlock(&rtac_afe_cal_mutex);
break;
case AUDIO_SET_RTAC_AFE_CAL:
+ mutex_lock(&rtac_afe_cal_mutex);
result = send_rtac_afe_apr((void *)arg,
AFE_PORT_CMD_SET_PARAM_V2);
+ mutex_unlock(&rtac_afe_cal_mutex);
break;
default:
pr_err("%s: Invalid IOCTL, command = %d!\n",
@@ -1860,6 +1885,7 @@
init_waitqueue_head(&rtac_adm_apr_data.cmd_wait);
mutex_init(&rtac_adm_mutex);
mutex_init(&rtac_adm_apr_mutex);
+ mutex_init(&rtac_adm_cal_mutex);
rtac_adm_buffer = kzalloc(
rtac_cal[ADM_RTAC_CAL].map_data.map_size, GFP_KERNEL);
@@ -1876,6 +1902,7 @@
init_waitqueue_head(&rtac_asm_apr_data[i].cmd_wait);
}
mutex_init(&rtac_asm_apr_mutex);
+ mutex_init(&rtac_asm_cal_mutex);
rtac_asm_buffer = kzalloc(
rtac_cal[ASM_RTAC_CAL].map_data.map_size, GFP_KERNEL);
@@ -1891,6 +1918,7 @@
atomic_set(&rtac_afe_apr_data.cmd_state, 0);
init_waitqueue_head(&rtac_afe_apr_data.cmd_wait);
mutex_init(&rtac_afe_apr_mutex);
+ mutex_init(&rtac_afe_cal_mutex);
rtac_afe_buffer = kzalloc(
rtac_cal[AFE_RTAC_CAL].map_data.map_size, GFP_KERNEL);
@@ -1911,6 +1939,7 @@
}
mutex_init(&rtac_voice_mutex);
mutex_init(&rtac_voice_apr_mutex);
+ mutex_init(&rtac_voice_cal_mutex);
rtac_voice_buffer = kzalloc(
rtac_cal[VOICE_RTAC_CAL].map_data.map_size, GFP_KERNEL);
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index b76cf63..c1b527e 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -256,6 +256,8 @@
static void dapm_kcontrol_free(struct snd_kcontrol *kctl)
{
struct dapm_kcontrol_data *data = snd_kcontrol_chip(kctl);
+
+ list_del(&data->paths);
kfree(data->wlist);
kfree(data);
}
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index f40fba3..bf80239 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -883,6 +883,14 @@
}
break;
+ case USB_ID(0x0d8c, 0x0103):
+ if (!strcmp(kctl->id.name, "PCM Playback Volume")) {
+ usb_audio_info(chip,
+ "set volume quirk for CM102-A+/102S+\n");
+ cval->min = -256;
+ }
+ break;
+
case USB_ID(0x0471, 0x0101):
case USB_ID(0x0471, 0x0104):
case USB_ID(0x0471, 0x0105):
diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c
index c758638..2f075cd 100644
--- a/sound/usb/mixer_maps.c
+++ b/sound/usb/mixer_maps.c
@@ -353,8 +353,11 @@
/*
* Dell usb dock with ALC4020 codec had a firmware problem where it got
* screwed up when zero volume is passed; just skip it as a workaround
+ *
+ * Also the extension unit gives an access error, so skip it as well.
*/
static const struct usbmix_name_map dell_alc4020_map[] = {
+ { 4, NULL }, /* extension unit */
{ 16, NULL },
{ 19, NULL },
{ 0 }
diff --git a/tools/Makefile b/tools/Makefile
index f0fd70a..6a014da 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -1,3 +1,8 @@
+# Some of the tools (perf) use same make variables
+# as in kernel build.
+export srctree=
+export objtree=
+
include scripts/Makefile.include
help:
@@ -51,11 +56,16 @@
liblockdep: FORCE
$(call descend,lib/lockdep)
-libapikfs: FORCE
+libapi: FORCE
$(call descend,lib/api)
-perf: libapikfs FORCE
- $(call descend,$@)
+# The perf build does not follow the descend function setup,
+# invoking it via it's own make rule.
+PERF_O = $(if $(O),$(O)/tools/perf,)
+
+perf: FORCE
+ $(Q)mkdir -p $(PERF_O) .
+ $(Q)$(MAKE) --no-print-directory -C perf O=$(PERF_O) subdir=
selftests: FORCE
$(call descend,testing/$@)
@@ -106,10 +116,10 @@
liblockdep_clean:
$(call descend,lib/lockdep,clean)
-libapikfs_clean:
+libapi_clean:
$(call descend,lib/api,clean)
-perf_clean: libapikfs_clean
+perf_clean:
$(call descend,$(@:_clean=),clean)
selftests_clean:
diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c
index 88cccea..64309d7 100644
--- a/tools/lib/traceevent/parse-filter.c
+++ b/tools/lib/traceevent/parse-filter.c
@@ -1867,17 +1867,25 @@
struct pevent *pevent;
unsigned long long addr;
const char *val = NULL;
+ unsigned int size;
char hex[64];
/* If the field is not a string convert it */
if (arg->str.field->flags & FIELD_IS_STRING) {
val = record->data + arg->str.field->offset;
+ size = arg->str.field->size;
+
+ if (arg->str.field->flags & FIELD_IS_DYNAMIC) {
+ addr = *(unsigned int *)val;
+ val = record->data + (addr & 0xffff);
+ size = addr >> 16;
+ }
/*
* We need to copy the data since we can't be sure the field
* is null terminated.
*/
- if (*(val + arg->str.field->size - 1)) {
+ if (*(val + size - 1)) {
/* copy it */
memcpy(arg->str.buffer, val, arg->str.field->size);
/* the buffer is already NULL terminated */
diff --git a/tools/net/bpf_dbg.c b/tools/net/bpf_dbg.c
index 9a287be..7ad831f 100644
--- a/tools/net/bpf_dbg.c
+++ b/tools/net/bpf_dbg.c
@@ -1063,7 +1063,7 @@
static int cmd_load(char *arg)
{
- char *subcmd, *cont, *tmp = strdup(arg);
+ char *subcmd, *cont = NULL, *tmp = strdup(arg);
int ret = CMD_OK;
subcmd = strtok_r(tmp, " ", &cont);
@@ -1073,7 +1073,10 @@
bpf_reset();
bpf_reset_breakpoints();
- ret = cmd_load_bpf(cont);
+ if (!cont)
+ ret = CMD_ERR;
+ else
+ ret = cmd_load_bpf(cont);
} else if (matches(subcmd, "pcap") == 0) {
ret = cmd_load_pcap(cont);
} else {
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index 28dfd1f..67f2d63 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -141,8 +141,6 @@
unsigned char buf2[BUFSZ];
size_t ret_len;
u64 objdump_addr;
- const char *objdump_name;
- char decomp_name[KMOD_DECOMP_LEN];
int ret;
pr_debug("Reading object code for memory address: %#"PRIx64"\n", addr);
@@ -204,25 +202,9 @@
state->done[state->done_cnt++] = al.map->start;
}
- objdump_name = al.map->dso->long_name;
- if (dso__needs_decompress(al.map->dso)) {
- if (dso__decompress_kmodule_path(al.map->dso, objdump_name,
- decomp_name,
- sizeof(decomp_name)) < 0) {
- pr_debug("decompression failed\n");
- return -1;
- }
-
- objdump_name = decomp_name;
- }
-
/* Read the object code using objdump */
objdump_addr = map__rip_2objdump(al.map, al.addr);
- ret = read_via_objdump(objdump_name, objdump_addr, buf2, len);
-
- if (dso__needs_decompress(al.map->dso))
- unlink(objdump_name);
-
+ ret = read_via_objdump(al.map->dso->long_name, objdump_addr, buf2, len);
if (ret > 0) {
/*
* The kernel maps are inaccurate - assume objdump is right in
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index dc3d3b1..c2d4a7ec 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1073,6 +1073,7 @@
static int __perf_session__process_pipe_events(struct perf_session *session,
struct perf_tool *tool)
{
+ struct ordered_events *oe = &session->ordered_events;
int fd = perf_data_file__fd(session->file);
union perf_event *event;
uint32_t size, cur_size = 0;
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_string.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_string.tc
new file mode 100644
index 0000000..5ba7303
--- /dev/null
+++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_string.tc
@@ -0,0 +1,46 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+# description: Kprobe event string type argument
+
+[ -f kprobe_events ] || exit_unsupported # this is configurable
+
+echo 0 > events/enable
+echo > kprobe_events
+
+case `uname -m` in
+x86_64)
+ ARG2=%si
+ OFFS=8
+;;
+i[3456]86)
+ ARG2=%cx
+ OFFS=4
+;;
+aarch64)
+ ARG2=%x1
+ OFFS=8
+;;
+arm*)
+ ARG2=%r1
+ OFFS=4
+;;
+*)
+ echo "Please implement other architecture here"
+ exit_untested
+esac
+
+: "Test get argument (1)"
+echo "p:testprobe create_trace_kprobe arg1=+0(+0(${ARG2})):string" > kprobe_events
+echo 1 > events/kprobes/testprobe/enable
+! echo test >> kprobe_events
+tail -n 1 trace | grep -qe "testprobe.* arg1=\"test\""
+
+echo 0 > events/kprobes/testprobe/enable
+: "Test get argument (2)"
+echo "p:testprobe create_trace_kprobe arg1=+0(+0(${ARG2})):string arg2=+0(+${OFFS}(${ARG2})):string" > kprobe_events
+echo 1 > events/kprobes/testprobe/enable
+! echo test1 test2 >> kprobe_events
+tail -n 1 trace | grep -qe "testprobe.* arg1=\"test1\" arg2=\"test2\""
+
+echo 0 > events/enable
+echo > kprobe_events
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_syntax.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_syntax.tc
new file mode 100644
index 0000000..231bcd2
--- /dev/null
+++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_syntax.tc
@@ -0,0 +1,97 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+# description: Kprobe event argument syntax
+
+[ -f kprobe_events ] || exit_unsupported # this is configurable
+
+grep "x8/16/32/64" README > /dev/null || exit_unsupported # version issue
+
+echo 0 > events/enable
+echo > kprobe_events
+
+PROBEFUNC="vfs_read"
+GOODREG=
+BADREG=
+GOODSYM="_sdata"
+if ! grep -qw ${GOODSYM} /proc/kallsyms ; then
+ GOODSYM=$PROBEFUNC
+fi
+BADSYM="deaqswdefr"
+SYMADDR=0x`grep -w ${GOODSYM} /proc/kallsyms | cut -f 1 -d " "`
+GOODTYPE="x16"
+BADTYPE="y16"
+
+case `uname -m` in
+x86_64|i[3456]86)
+ GOODREG=%ax
+ BADREG=%ex
+;;
+aarch64)
+ GOODREG=%x0
+ BADREG=%ax
+;;
+arm*)
+ GOODREG=%r0
+ BADREG=%ax
+;;
+esac
+
+test_goodarg() # Good-args
+{
+ while [ "$1" ]; do
+ echo "p ${PROBEFUNC} $1" > kprobe_events
+ shift 1
+ done;
+}
+
+test_badarg() # Bad-args
+{
+ while [ "$1" ]; do
+ ! echo "p ${PROBEFUNC} $1" > kprobe_events
+ shift 1
+ done;
+}
+
+echo > kprobe_events
+
+: "Register access"
+test_goodarg ${GOODREG}
+test_badarg ${BADREG}
+
+: "Symbol access"
+test_goodarg "@${GOODSYM}" "@${SYMADDR}" "@${GOODSYM}+10" "@${GOODSYM}-10"
+test_badarg "@" "@${BADSYM}" "@${GOODSYM}*10" "@${GOODSYM}/10" \
+ "@${GOODSYM}%10" "@${GOODSYM}&10" "@${GOODSYM}|10"
+
+: "Stack access"
+test_goodarg "\$stack" "\$stack0" "\$stack1"
+test_badarg "\$stackp" "\$stack0+10" "\$stack1-10"
+
+: "Retval access"
+echo "r ${PROBEFUNC} \$retval" > kprobe_events
+! echo "p ${PROBEFUNC} \$retval" > kprobe_events
+
+: "Comm access"
+test_goodarg "\$comm"
+
+: "Indirect memory access"
+test_goodarg "+0(${GOODREG})" "-0(${GOODREG})" "+10(\$stack)" \
+ "+0(\$stack1)" "+10(@${GOODSYM}-10)" "+0(+10(+20(\$stack)))"
+test_badarg "+(${GOODREG})" "(${GOODREG}+10)" "-(${GOODREG})" "(${GOODREG})" \
+ "+10(\$comm)" "+0(${GOODREG})+10"
+
+: "Name assignment"
+test_goodarg "varname=${GOODREG}"
+test_badarg "varname=varname2=${GOODREG}"
+
+: "Type syntax"
+test_goodarg "${GOODREG}:${GOODTYPE}"
+test_badarg "${GOODREG}::${GOODTYPE}" "${GOODREG}:${BADTYPE}" \
+ "${GOODTYPE}:${GOODREG}"
+
+: "Combination check"
+
+test_goodarg "\$comm:string" "+0(\$stack):string"
+test_badarg "\$comm:x64" "\$stack:string" "${GOODREG}:string"
+
+echo > kprobe_events
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/probepoint.tc b/tools/testing/selftests/ftrace/test.d/kprobe/probepoint.tc
new file mode 100644
index 0000000..4fda01a
--- /dev/null
+++ b/tools/testing/selftests/ftrace/test.d/kprobe/probepoint.tc
@@ -0,0 +1,43 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+# description: Kprobe events - probe points
+
+[ -f kprobe_events ] || exit_unsupported # this is configurable
+
+TARGET_FUNC=create_trace_kprobe
+
+dec_addr() { # hexaddr
+ printf "%d" "0x"`echo $1 | tail -c 8`
+}
+
+set_offs() { # prev target next
+ A1=`dec_addr $1`
+ A2=`dec_addr $2`
+ A3=`dec_addr $3`
+ TARGET="0x$2" # an address
+ PREV=`expr $A1 - $A2` # offset to previous symbol
+ NEXT=+`expr $A3 - $A2` # offset to next symbol
+ OVERFLOW=+`printf "0x%x" ${PREV}` # overflow offset to previous symbol
+}
+
+# We have to decode symbol addresses to get correct offsets.
+# If the offset is not an instruction boundary, it cause -EILSEQ.
+set_offs `grep -A1 -B1 ${TARGET_FUNC} /proc/kallsyms | cut -f 1 -d " " | xargs`
+
+UINT_TEST=no
+# printf "%x" -1 returns (unsigned long)-1.
+if [ `printf "%x" -1 | wc -c` != 9 ]; then
+ UINT_TEST=yes
+fi
+
+echo 0 > events/enable
+echo > kprobe_events
+echo "p:testprobe ${TARGET_FUNC}" > kprobe_events
+echo "p:testprobe ${TARGET}" > kprobe_events
+echo "p:testprobe ${TARGET_FUNC}${NEXT}" > kprobe_events
+! echo "p:testprobe ${TARGET_FUNC}${PREV}" > kprobe_events
+if [ "${UINT_TEST}" = yes ]; then
+! echo "p:testprobe ${TARGET_FUNC}${OVERFLOW}" > kprobe_events
+fi
+echo > kprobe_events
+clear_trace
diff --git a/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-multi-actions-accept.tc b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-multi-actions-accept.tc
new file mode 100644
index 0000000..c193dce
--- /dev/null
+++ b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-multi-actions-accept.tc
@@ -0,0 +1,44 @@
+#!/bin/sh
+# description: event trigger - test multiple actions on hist trigger
+
+
+do_reset() {
+ reset_trigger
+ echo > set_event
+ clear_trace
+}
+
+fail() { #msg
+ do_reset
+ echo $1
+ exit_fail
+}
+
+if [ ! -f set_event ]; then
+ echo "event tracing is not supported"
+ exit_unsupported
+fi
+
+if [ ! -f synthetic_events ]; then
+ echo "synthetic event is not supported"
+ exit_unsupported
+fi
+
+clear_synthetic_events
+reset_tracer
+do_reset
+
+echo "Test multiple actions on hist trigger"
+echo 'wakeup_latency u64 lat; pid_t pid' >> synthetic_events
+TRIGGER1=events/sched/sched_wakeup/trigger
+TRIGGER2=events/sched/sched_switch/trigger
+
+echo 'hist:keys=pid:ts0=common_timestamp.usecs if comm=="cyclictest"' > $TRIGGER1
+echo 'hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0 if next_comm=="cyclictest"' >> $TRIGGER2
+echo 'hist:keys=next_pid:onmatch(sched.sched_wakeup).wakeup_latency(sched.sched_switch.$wakeup_lat,next_pid) if next_comm=="cyclictest"' >> $TRIGGER2
+echo 'hist:keys=next_pid:onmatch(sched.sched_wakeup).wakeup_latency(sched.sched_switch.$wakeup_lat,prev_pid) if next_comm=="cyclictest"' >> $TRIGGER2
+echo 'hist:keys=next_pid if next_comm=="cyclictest"' >> $TRIGGER2
+
+do_reset
+
+exit 0
diff --git a/tools/testing/selftests/memfd/config b/tools/testing/selftests/memfd/config
new file mode 100644
index 0000000..835c7f4d
--- /dev/null
+++ b/tools/testing/selftests/memfd/config
@@ -0,0 +1 @@
+CONFIG_FUSE_FS=m
diff --git a/tools/thermal/tmon/sysfs.c b/tools/thermal/tmon/sysfs.c
index dfe4548..b4e366e 100644
--- a/tools/thermal/tmon/sysfs.c
+++ b/tools/thermal/tmon/sysfs.c
@@ -486,6 +486,7 @@
int update_thermal_data()
{
int i;
+ int next_thermal_record = cur_thermal_record + 1;
char tz_name[256];
static unsigned long samples;
@@ -495,9 +496,9 @@
}
/* circular buffer for keeping historic data */
- if (cur_thermal_record >= NR_THERMAL_RECORDS)
- cur_thermal_record = 0;
- gettimeofday(&trec[cur_thermal_record].tv, NULL);
+ if (next_thermal_record >= NR_THERMAL_RECORDS)
+ next_thermal_record = 0;
+ gettimeofday(&trec[next_thermal_record].tv, NULL);
if (tmon_log) {
fprintf(tmon_log, "%lu ", ++samples);
fprintf(tmon_log, "%3.1f ", p_param.t_target);
@@ -507,11 +508,12 @@
snprintf(tz_name, 256, "%s/%s%d", THERMAL_SYSFS, TZONE,
ptdata.tzi[i].instance);
sysfs_get_ulong(tz_name, "temp",
- &trec[cur_thermal_record].temp[i]);
+ &trec[next_thermal_record].temp[i]);
if (tmon_log)
fprintf(tmon_log, "%lu ",
- trec[cur_thermal_record].temp[i]/1000);
+ trec[next_thermal_record].temp[i] / 1000);
}
+ cur_thermal_record = next_thermal_record;
for (i = 0; i < ptdata.nr_cooling_dev; i++) {
char cdev_name[256];
unsigned long val;
diff --git a/tools/thermal/tmon/tmon.c b/tools/thermal/tmon/tmon.c
index 09b7c32..b1f6dc6 100644
--- a/tools/thermal/tmon/tmon.c
+++ b/tools/thermal/tmon/tmon.c
@@ -326,7 +326,6 @@
show_data_w();
show_cooling_device();
}
- cur_thermal_record++;
time_elapsed += ticktime;
controller_handler(trec[0].temp[target_tz_index] / 1000,
&yk);