[Feature][T8TSK-26][TCAM_T800_SW_0253]Add imu/smi230 sensor

Change-Id: Ic071e46b8a31273235cbd4117d06295db7e188c3
diff --git a/src/kernel/linux/v4.19/arch/arm64/boot/dts/mediatek/auto2735evb_gsw.dts b/src/kernel/linux/v4.19/arch/arm64/boot/dts/mediatek/auto2735evb_gsw.dts
index b313cff..1e8f584 100755
--- a/src/kernel/linux/v4.19/arch/arm64/boot/dts/mediatek/auto2735evb_gsw.dts
+++ b/src/kernel/linux/v4.19/arch/arm64/boot/dts/mediatek/auto2735evb_gsw.dts
@@ -247,20 +247,40 @@
 	//	status = "okay";
 	//};
 
+        //dongyu@2022.12.13 Modify the dts of imu/smi230 start
+        /*
 	kxtj3@0e {
 		compatible = "mediatek,kxtj3_gsensor";
 		reg = <0x68>;
 		direction = <2>;
 		status = "okay";
 	};
-	/*
-	mtk-iicd@74 {
+        */
+        //dongyu@2022.12.13 Modify the dts of imu/smi230 end
+
+        /*
+        mtk-iicd@74 {
 		compatible = "mediatek,mtk-iicd";
 		reg = <0x74>;
 		status = "okay";
 	};
 	*/
-	
+
+        //dongyu@2022.12.13 Add imu/smi230 sensor start
+        smi230acc@18 {
+                compatible = "SMI230ACC";
+                reg = <0x18>;
+                smi-pwr-gpios = <&pio 200 GPIO_ACTIVE_HIGH>;
+                gpio_irq = <&pio 29 GPIO_ACTIVE_LOW>;
+                status = "okay";
+        };
+        smi230gyro@68 {
+                compatible = "SMI230GYRO";
+                reg = <0x68>;
+                gpio_irq = <&pio 177 GPIO_ACTIVE_LOW>;
+                status = "okay";
+        };
+        //dongyu@2022.12.13 Add imu/smi230 sensor end
 };
 
 &i2c2 {
diff --git a/src/kernel/linux/v4.19/arch/arm64/configs/auto2735evb_gsw_defconfig b/src/kernel/linux/v4.19/arch/arm64/configs/auto2735evb_gsw_defconfig
index b862b32..351e1c0 100644
--- a/src/kernel/linux/v4.19/arch/arm64/configs/auto2735evb_gsw_defconfig
+++ b/src/kernel/linux/v4.19/arch/arm64/configs/auto2735evb_gsw_defconfig
@@ -816,3 +816,17 @@
 CONFIG_PHY_DRIVER_GSW=y
 CONFIG_AHEAD_PHY_RESUME=y
 #xf.li@2022.12.13 modify for phy-merge end
+
+#dongyu@2022.12.13 Add imu/smi230 sensor start
+CONFIG_IIO_BUFFER=y
+CONFIG_IIO_BUFFER_HW_CONSUMER=y
+CONFIG_IIO_KFIFO_BUF=y
+CONFIG_IIO_TRIGGER=y
+CONFIG_IIO_SW_DEVICE=y
+CONFIG_IIO_SW_TRIGGER=y
+CONFIG_ROCKCHIP_SARADC=y
+CONFIG_IIO_SMI230_ACC=y
+CONFIG_IIO_SMI230_ACC_I2C=y
+CONFIG_SMI230_GYRO=y
+CONFIG_SMI230_GYRO_I2C=y
+#dongyu@2022.12.13 Add imu/smi230 sensor end
diff --git a/src/kernel/linux/v4.19/drivers/iio/accel/Kconfig b/src/kernel/linux/v4.19/drivers/iio/accel/Kconfig
index 829dc96..aa8f733 100644
--- a/src/kernel/linux/v4.19/drivers/iio/accel/Kconfig
+++ b/src/kernel/linux/v4.19/drivers/iio/accel/Kconfig
@@ -408,4 +408,38 @@
 	  Choosing M will build the driver as a module. If so, the module
 	  will be called stk8ba50.
 
+config IIO_SMI230_ACC
+	tristate "Bosch Sensor SMI230 Accelerometer"
+	depends on (I2C || SPI_MASTER)
+	select IIO_BUFFER
+	select IIO_TRIGGER
+	help
+	  Build driver for Bosch SMI230 tri-axis accelerometer sensor.
+
+choice
+	prompt "Select communication interface"
+	depends on IIO_SMI230_ACC
+	help
+	  Note: SPI and I2C are not supported at the same time, that is to say:
+	  Choose either SPI or I2C to build the driver.
+
+    config IIO_SMI230_ACC_SPI
+		bool "Enable SPI connection"
+		depends on SPI_MASTER
+
+    config IIO_SMI230_ACC_I2C
+		bool "Enable I2C connection"
+		depends on I2C
+endchoice
+
+if IIO_SMI230_ACC
+
+config IIO_SMI230_ACC_MAX_BUFFER_LEN
+	int "configue read buffer size"
+	default "1024"
+	help
+	  Considering using FIFO, 1024 bytes are big enough for most cases. Do not change this value if not sure.
+
+endif
+
 endmenu
diff --git a/src/kernel/linux/v4.19/drivers/iio/accel/Makefile b/src/kernel/linux/v4.19/drivers/iio/accel/Makefile
index 636d4d1..1d55902 100644
--- a/src/kernel/linux/v4.19/drivers/iio/accel/Makefile
+++ b/src/kernel/linux/v4.19/drivers/iio/accel/Makefile
@@ -56,3 +56,14 @@
 
 obj-$(CONFIG_IIO_ST_ACCEL_I2C_3AXIS) += st_accel_i2c.o
 obj-$(CONFIG_IIO_ST_ACCEL_SPI_3AXIS) += st_accel_spi.o
+
+#dongyu@2022.12.13 Add imu/smi230 sensor start
+obj-$(CONFIG_IIO_SMI230_ACC) += smi230_acc.o
+smi230_acc-objs := smi230_acc_core.o
+
+ifeq ($(CONFIG_IIO_SMI230_ACC_I2C),y)
+    smi230_acc-objs += smi230_acc_i2c.o
+else
+    smi230_acc-objs += smi230_acc_spi.o
+endif
+#dongyu@2022.12.13 Add imu/smi230 sensor end
diff --git a/src/kernel/linux/v4.19/drivers/iio/accel/smi230_acc.h b/src/kernel/linux/v4.19/drivers/iio/accel/smi230_acc.h
new file mode 100644
index 0000000..915e40d
--- /dev/null
+++ b/src/kernel/linux/v4.19/drivers/iio/accel/smi230_acc.h
@@ -0,0 +1,589 @@
+/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
+/**
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE
+ * Copyright (c) 2022 Robert Bosch GmbH. All rights reserved.
+ * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved.
+ *
+ * This file is free software licensed under the terms of version 2
+ * of the GNU General Public License, available from the file LICENSE-GPL
+ * in the main directory of this source tree.
+ *
+ * BSD LICENSE
+ * Copyright (c) 2022 Robert Bosch GmbH. All rights reserved.
+ * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved.
+ *
+ * BSD-3-Clause
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **/
+
+#ifndef _SMI230_ACC_H
+#define _SMI230_ACC_H
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#include <linux/kernel.h>
+#else
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+#endif
+
+#include <linux/device.h>
+
+#define DRIVER_VERSION "1.0.0"
+#define MODULE_NAME "SMI230ACC"
+#define SENSOR_ACC_NAME "SMI230ACC"
+
+#if !defined(UINT8_C) && !defined(INT8_C)
+#define INT8_C(x)   S8_C(x)
+#define UINT8_C(x)  U8_C(x)
+#endif
+
+#if !defined(UINT16_C) && !defined(INT16_C)
+#define INT16_C(x)  S16_C(x)
+#define UINT16_C(x) U16_C(x)
+#endif
+
+#if !defined(INT32_C) && !defined(UINT32_C)
+#define INT32_C(x)  S32_C(x)
+#define UINT32_C(x) U32_C(x)
+#endif
+
+#if !defined(INT64_C) && !defined(UINT64_C)
+#define INT64_C(x)  S64_C(x)
+#define UINT64_C(x) U64_C(x)
+#endif
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL                 0
+#else
+#define NULL                 ((void *) 0)
+#endif
+#endif
+
+#ifndef TRUE
+#define TRUE                 UINT8_C(1)
+#endif
+
+#ifndef FALSE
+#define FALSE                UINT8_C(0)
+#endif
+
+#define SMI230_ACCEL_CHIP_ID_REG            UINT8_C(0x00)
+#define SMI230_ACCEL_ERR_REG                UINT8_C(0x02)
+#define SMI230_ACCEL_STATUS_REG             UINT8_C(0x03)
+#define SMI230_ACCEL_X_LSB_REG              UINT8_C(0x12)
+#define SMI230_ACCEL_X_MSB_REG              UINT8_C(0x13)
+#define SMI230_ACCEL_Y_LSB_REG              UINT8_C(0x14)
+#define SMI230_ACCEL_Y_MSB_REG              UINT8_C(0x15)
+#define SMI230_ACCEL_Z_LSB_REG              UINT8_C(0x16)
+#define SMI230_ACCEL_Z_MSB_REG              UINT8_C(0x17)
+#define SMI230_ACCEL_SENSORTIME_0_REG       UINT8_C(0x18)
+#define SMI230_ACCEL_SENSORTIME_1_REG       UINT8_C(0x19)
+#define SMI230_ACCEL_SENSORTIME_2_REG       UINT8_C(0x1A)
+#define SMI230_ACCEL_INT_STAT_0_REG         UINT8_C(0x1C)
+#define SMI230_ACCEL_INT_STAT_1_REG         UINT8_C(0x1D)
+#define SMI230_ACCEL_GP_0_REG               UINT8_C(0x1E)
+#define SMI230_TEMP_MSB_REG                 UINT8_C(0x22)
+#define SMI230_TEMP_LSB_REG                 UINT8_C(0x23)
+#define SMI230_ACCEL_GP_4_REG               UINT8_C(0x27)
+#define SMI230_REG_ORIENT_HIGHG_OUT        UINT8_C(0x29)
+#define SMI230_ACCEL_INTERNAL_STAT_REG      UINT8_C(0x2A)
+#define SMI230_ACCEL_CONF_REG               UINT8_C(0x40)
+#define SMI230_ACCEL_RANGE_REG              UINT8_C(0x41)
+#define SMI230_ACCEL_INT1_IO_CONF_REG       UINT8_C(0x53)
+#define SMI230_ACCEL_INT2_IO_CONF_REG       UINT8_C(0x54)
+#define SMI230_ACCEL_INT_LATCH_CONF_REG     UINT8_C(0x55)
+#define SMI230_ACCEL_INT1_MAP_REG           UINT8_C(0x56)
+#define SMI230_ACCEL_INT2_MAP_REG           UINT8_C(0x57)
+#define SMI230_ACCEL_INT1_INT2_MAP_DATA_REG UINT8_C(0x58)
+#define SMI230_ACCEL_INIT_CTRL_REG          UINT8_C(0x59)
+#define SMI230_ACCEL_SELF_TEST_REG          UINT8_C(0x6D)
+#define SMI230_ACCEL_PWR_CONF_REG           UINT8_C(0x7C)
+#define SMI230_ACCEL_PWR_CTRL_REG           UINT8_C(0x7D)
+#define SMI230_ACCEL_SOFTRESET_REG          UINT8_C(0x7E)
+#define SMI230_ACCEL_CHIP_ID                UINT8_C(0x1F)
+#define SMI230_ACCEL_I2C_ADDR_PRIMARY       UINT8_C(0x18)
+#define SMI230_ACCEL_I2C_ADDR_SECONDARY     UINT8_C(0x19)
+#define SMI230_ACCEL_RESERVED_5B_REG        UINT8_C(0x5B)
+#define SMI230_ACCEL_RESERVED_5C_REG        UINT8_C(0x5C)
+#define SMI230_ACCEL_FEATURE_CFG_REG        UINT8_C(0x5E)
+#define SMI230_ACCEL_DATA_READY_INT         UINT8_C(0x80)
+
+#define SMI230_ACCEL_BW_OSR4                UINT8_C(0x00)
+#define SMI230_ACCEL_BW_OSR2                UINT8_C(0x01)
+#define SMI230_ACCEL_BW_NORMAL              UINT8_C(0x02)
+
+#define SMI230_ACCEL_RANGE_2G               UINT8_C(0x00)
+#define SMI230_ACCEL_RANGE_4G               UINT8_C(0x01)
+#define SMI230_ACCEL_RANGE_8G               UINT8_C(0x02)
+#define SMI230_ACCEL_RANGE_16G              UINT8_C(0x03)
+
+#define SMI230_ACCEL_ODR_12_5_HZ            UINT8_C(0x05)
+#define SMI230_ACCEL_ODR_25_HZ              UINT8_C(0x06)
+#define SMI230_ACCEL_ODR_50_HZ              UINT8_C(0x07)
+#define SMI230_ACCEL_ODR_100_HZ             UINT8_C(0x08)
+#define SMI230_ACCEL_ODR_200_HZ             UINT8_C(0x09)
+#define SMI230_ACCEL_ODR_400_HZ             UINT8_C(0x0A)
+#define SMI230_ACCEL_ODR_800_HZ             UINT8_C(0x0B)
+#define SMI230_ACCEL_ODR_1600_HZ            UINT8_C(0x0C)
+
+#define SMI230_ACCEL_SWITCH_OFF_SELF_TEST   UINT8_C(0x00)
+#define SMI230_ACCEL_POSITIVE_SELF_TEST     UINT8_C(0x0D)
+#define SMI230_ACCEL_NEGATIVE_SELF_TEST     UINT8_C(0x09)
+
+#define SMI230_ACCEL_PM_ACTIVE              UINT8_C(0x00)
+#define SMI230_ACCEL_PM_SUSPEND             UINT8_C(0x03)
+
+#define SMI230_ACCEL_POWER_DISABLE          UINT8_C(0x00)
+#define SMI230_ACCEL_POWER_ENABLE           UINT8_C(0x04)
+
+#define SMI230_ACCEL_INTA_DISABLE           UINT8_C(0x00)
+#define SMI230_ACCEL_INTA_ENABLE            UINT8_C(0x01)
+#define SMI230_ACCEL_INTB_DISABLE           UINT8_C(0x00)
+#define SMI230_ACCEL_INTB_ENABLE            UINT8_C(0x02)
+
+#define SMI230_ACCEL_DATA_SYNC_INT_DISABLE          UINT8_C(0x00)
+#define SMI230_ACCEL_DATA_SYNC_INT_ENABLE           UINT8_C(0x01)
+#define SMI230_ACCEL_ANY_MOT_INT_DISABLE            UINT8_C(0x00)
+#define SMI230_ACCEL_ANY_MOT_INT_ENABLE             UINT8_C(0x02)
+#define SMI230_ACCEL_HIGH_G_INT_DISABLE             UINT8_C(0x00)
+#define SMI230_ACCEL_HIGH_G_INT_ENABLE              UINT8_C(0x04)
+#define SMI230_ACCEL_LOW_G_INT_DISABLE              UINT8_C(0x00)
+#define SMI230_ACCEL_LOW_G_INT_ENABLE               UINT8_C(0x08)
+#define SMI230_ACCEL_ORIENT_INT_DISABLE             UINT8_C(0x00)
+#define SMI230_ACCEL_ORIENT_INT_ENABLE              UINT8_C(0x10)
+#define SMI230_ACCEL_NO_MOT_INT_DISABLE             UINT8_C(0x00)
+#define SMI230_ACCEL_NO_MOT_INT_ENABLE              UINT8_C(0x20)
+#define SMI230_ACCEL_ERR_INT_DISABLE                UINT8_C(0x00)
+#define SMI230_ACCEL_ERR_INT_ENABLE                 UINT8_C(0x80)
+
+#define SMI230_ACCEL_SOFTRESET_DELAY_MS     UINT8_C(1)
+
+#define SMI230_FATAL_ERR_MASK               UINT8_C(0x01)
+#define SMI230_ERR_CODE_MASK                UINT8_C(0x1C)
+
+#define SMI230_CMD_ERR_POS                  UINT8_C(1)
+#define SMI230_ERR_CODE_POS                 UINT8_C(2)
+
+#define SMI230_ACCEL_STATUS_MASK            UINT8_C(0x80)
+#define SMI230_ACCEL_STATUS_POS             UINT8_C(7)
+
+#define SMI230_ACCEL_ODR_MASK               UINT8_C(0x0F)
+#define SMI230_ACCEL_BW_MASK                UINT8_C(0x70)
+#define SMI230_ACCEL_RANGE_MASK             UINT8_C(0x03)
+
+#define SMI230_ACCEL_BW_POS                 UINT8_C(4)
+
+#define SMI230_ACCEL_INT_EDGE_MASK          UINT8_C(0x01)
+#define SMI230_ACCEL_INT_LVL_MASK           UINT8_C(0x02)
+#define SMI230_ACCEL_INT_OD_MASK            UINT8_C(0x04)
+#define SMI230_ACCEL_INT_IO_MASK            UINT8_C(0x08)
+#define SMI230_ACCEL_INT_IN_MASK            UINT8_C(0x10)
+
+#define SMI230_ACCEL_INT_EDGE_POS           UINT8_C(0)
+#define SMI230_ACCEL_INT_LVL_POS            UINT8_C(1)
+#define SMI230_ACCEL_INT_OD_POS             UINT8_C(2)
+#define SMI230_ACCEL_INT_IO_POS             UINT8_C(3)
+#define SMI230_ACCEL_INT_IN_POS             UINT8_C(4)
+
+#define SMI230_ACCEL_MAP_INTA_MASK          UINT8_C(0x01)
+#define SMI230_ACCEL_MAP_INTA_POS           UINT8_C(0x00)
+
+#define SMI230_ACCEL_INT1_DRDY_MASK         UINT8_C(0x04)
+#define SMI230_ACCEL_INT2_DRDY_MASK         UINT8_C(0x40)
+#define SMI230_ACCEL_INT1_DRDY_POS          UINT8_C(2)
+#define SMI230_ACCEL_INT2_DRDY_POS          UINT8_C(6)
+
+#define SMI230_ASIC_INITIALIZED             UINT8_C(0x01)
+
+#define SMI230_SPI_RD_MASK                     UINT8_C(0x80)
+#define SMI230_SPI_WR_MASK                     UINT8_C(0x7F)
+
+#define SMI230_OK                              INT8_C(0)
+#define SMI230_E_NULL_PTR                      INT8_C(-1)
+#define SMI230_E_COM_FAIL                      INT8_C(-2)
+#define SMI230_E_DEV_NOT_FOUND                 INT8_C(-3)
+#define SMI230_E_OUT_OF_RANGE                  INT8_C(-4)
+#define SMI230_E_INVALID_INPUT                 INT8_C(-5)
+#define SMI230_E_CONFIG_STREAM_ERROR           INT8_C(-6)
+#define SMI230_E_RD_WR_LENGTH_INVALID          INT8_C(-7)
+#define SMI230_E_INVALID_CONFIG                INT8_C(-8)
+#define SMI230_E_FEATURE_NOT_SUPPORTED         INT8_C(-9)
+
+#define SMI230_W_SELF_TEST_FAIL                INT8_C(1)
+
+#define SMI230_SOFT_RESET_CMD                  UINT8_C(0xB6)
+#define SMI230_FIFO_RESET_CMD                  UINT8_C(0xB0)
+
+#define SMI230_DISABLE                         UINT8_C(0)
+#define SMI230_ENABLE                          UINT8_C(1)
+
+#define SMI230_SENSOR_DATA_SYNC_TIME_MS        UINT8_C(1)
+#define SMI230_DELAY_BETWEEN_WRITES_MS         UINT8_C(1)
+#define SMI230_SELF_TEST_DELAY_MS              UINT8_C(3)
+#define SMI230_POWER_CONFIG_DELAY              UINT8_C(5)
+#define SMI230_SENSOR_SETTLE_TIME_MS           UINT8_C(30)
+#define SMI230_SELF_TEST_DATA_READ_MS          UINT8_C(50)
+#define SMI230_ASIC_INIT_TIME_MS               UINT8_C(150)
+
+#define SMI230_CONFIG_STREAM_SIZE              UINT16_C(6144)
+
+#define SMI230_SENSOR_TIME_MSB_BYTE            UINT8_C(2)
+#define SMI230_SENSOR_TIME_XLSB_BYTE           UINT8_C(1)
+#define SMI230_SENSOR_TIME_LSB_BYTE            UINT8_C(0)
+
+#define SMI230_INT_ACTIVE_LOW                  UINT8_C(0)
+#define SMI230_INT_ACTIVE_HIGH                 UINT8_C(1)
+#define SMI230_INT_MODE_PUSH_PULL              UINT8_C(0)
+#define SMI230_INT_MODE_OPEN_DRAIN             UINT8_C(1)
+
+#define SMI230_16_BIT_RESOLUTION               UINT8_C(16)
+
+#ifndef SMI230_ABS
+#define SMI230_ABS(a) ((a) > 0 ? (a) : -(a))
+#endif
+
+#define SMI230_SET_LOW_BYTE   UINT16_C(0x00FF)
+#define SMI230_SET_HIGH_BYTE  UINT16_C(0xFF00)
+#define SMI230_SET_LOW_NIBBLE UINT8_C(0x0F)
+
+#define SMI230_ACCEL_ANYMOTION_ADR                  UINT8_C(0x00)
+#define SMI230_ACCEL_DATA_SYNC_ADR                  UINT8_C(0x02)
+#define SMI230_HIGH_G_START_ADR                     UINT8_C(0x03)
+#define SMI230_LOW_G_START_ADR                      UINT8_C(0x06)
+#define SMI230_ORIENT_START_ADR                     UINT8_C(0x09)
+#define SMI230_NO_MOTION_START_ADR                  UINT8_C(0x0B)
+
+#define SMI230_ACCEL_ANYMOTION_LEN                  UINT8_C(0x02)
+#define SMI230_ACCEL_ANYMOTION_THRESHOLD_MASK       UINT16_C(0x07FF)
+#define SMI230_ACCEL_ANYMOTION_THRESHOLD_SHIFT      UINT8_C(0x00)
+#define SMI230_ACCEL_ANYMOTION_NOMOTION_SEL_MASK    UINT16_C(0x0800)
+#define SMI230_ACCEL_ANYMOTION_NOMOTION_SEL_SHIFT   UINT8_C(0x0B)
+#define SMI230_ACCEL_ANYMOTION_DURATION_MASK        UINT16_C(0x1FFF)
+#define SMI230_ACCEL_ANYMOTION_DURATION_SHIFT       UINT8_C(0x00)
+#define SMI230_ACCEL_ANYMOTION_X_EN_MASK            UINT16_C(0x2000)
+#define SMI230_ACCEL_ANYMOTION_X_EN_SHIFT           UINT8_C(0x0D)
+#define SMI230_ACCEL_ANYMOTION_Y_EN_MASK            UINT16_C(0x4000)
+#define SMI230_ACCEL_ANYMOTION_Y_EN_SHIFT           UINT8_C(0x0E)
+#define SMI230_ACCEL_ANYMOTION_Z_EN_MASK            UINT16_C(0x8000)
+#define SMI230_ACCEL_ANYMOTION_Z_EN_SHIFT           UINT8_C(0x0F)
+
+#define SMI230_HIGH_G_THRES_MASK                    UINT16_C(0x7FFF)
+#define SMI230_HIGH_G_HYST_MASK                     UINT16_C(0x0FFF)
+#define SMI230_HIGH_G_X_SEL_MASK                    UINT16_C(0x1000)
+#define SMI230_HIGH_G_Y_SEL_MASK                    UINT16_C(0x2000)
+#define SMI230_HIGH_G_Z_SEL_MASK                    UINT16_C(0x4000)
+#define SMI230_HIGH_G_ENABLE_MASK                   UINT16_C(0x8000)
+#define SMI230_HIGH_G_DUR_MASK                      UINT16_C(0x0FFF)
+#define SMI230_HIGH_G_OUT_CONF_MASK                 UINT16_C(0xF000)
+
+#define SMI230_HIGH_G_THRES_POS                     UINT8_C(0x00)
+#define SMI230_HIGH_G_HYST_POS                      UINT8_C(0x00)
+#define SMI230_HIGH_G_OUT_CONF_POS                  UINT8_C(0x0C)
+#define SMI230_HIGH_G_X_SEL_POS                     UINT8_C(0x0C)
+#define SMI230_HIGH_G_Y_SEL_POS                     UINT8_C(0x0D)
+#define SMI230_HIGH_G_Z_SEL_POS                     UINT8_C(0x0E)
+#define SMI230_HIGH_G_ENABLE_POS                    UINT8_C(0x0F)
+#define SMI230_HIGH_G_DUR_POS                       UINT8_C(0x00)
+#define SMI230_HIGH_G_AXIS_X_POS                    UINT8_C(0x03)
+#define SMI230_HIGH_G_AXIS_Y_POS                    UINT8_C(0x04)
+#define SMI230_HIGH_G_AXIS_Z_POS                    UINT8_C(0x05)
+#define SMI230_HIGH_G_AXIS_DIRECTION_POS            UINT8_C(0x06)
+
+#define SMI230_HIGH_G_AXIS_X_MASK                   UINT8_C(0x08)
+#define SMI230_HIGH_G_AXIS_Y_MASK                   UINT8_C(0x10)
+#define SMI230_HIGH_G_AXIS_Z_MASK                   UINT8_C(0x20)
+#define SMI230_HIGH_G_AXIS_DIRECTION_MASK           UINT8_C(0x80)
+
+#define SMI230_LOW_G_THRES_MASK                     UINT16_C(0x7FFF)
+#define SMI230_LOW_G_HYST_MASK                      UINT16_C(0x0FFF)
+#define SMI230_LOW_G_DUR_MASK                       UINT16_C(0x0FFF)
+#define SMI230_LOW_G_ENABLE_MASK                    UINT16_C(0x1000)
+
+#define SMI230_LOW_G_THRES_POS                      UINT16_C(0x00)
+#define SMI230_LOW_G_HYST_POS                       UINT16_C(0x00)
+#define SMI230_LOW_G_DUR_POS                        UINT16_C(0x00)
+#define SMI230_LOW_G_ENABLE_POS                     UINT16_C(0x0C)
+
+#define SMI230_ORIENT_ENABLE_MASK                   UINT16_C(0x0001)
+#define SMI230_ORIENT_UP_DOWN_MASK                  UINT16_C(0x0002)
+#define SMI230_ORIENT_SYMM_MODE_MASK                UINT16_C(0x000C)
+#define SMI230_ORIENT_BLOCK_MODE_MASK               UINT16_C(0x0030)
+#define SMI230_ORIENT_THETA_MASK                    UINT16_C(0x0FC0)
+#define SMI230_ORIENT_HYST_MASK                     UINT16_C(0x07FF)
+#define SMI230_ORIENT_PORTRAIT_LANDSCAPE_MASK       UINT8_C(0x03)
+#define SMI230_ORIENT_FACEUP_DOWN_MASK              UINT8_C(0x04)
+
+#define SMI230_ORIENT_ENABLE_POS                    UINT8_C(0x00)
+#define SMI230_ORIENT_UP_DOWN_POS                   UINT8_C(0x01)
+#define SMI230_ORIENT_SYMM_MODE_POS                 UINT8_C(0x02)
+#define SMI230_ORIENT_BLOCK_MODE_POS                UINT8_C(0x04)
+#define SMI230_ORIENT_THETA_POS                     UINT8_C(0x06)
+#define SMI230_ORIENT_HYST_POS                      UINT8_C(0x00)
+#define SMI230_ORIENT_PORTRAIT_LANDSCAPE_POS        UINT8_C(0x00)
+#define SMI230_ORIENT_FACEUP_DOWN_POS               UINT8_C(0x02)
+
+#define SMI230_ORIENT_PORTRAIT_UPRIGHT              UINT8_C(0x00)
+#define SMI230_ORIENT_LANDSCAPE_LEFT                UINT8_C(0x01)
+#define SMI230_ORIENT_PORTRAIT_UPSIDE_DOWN          UINT8_C(0x02)
+#define SMI230_ORIENT_LANDSCAPE_RIGHT               UINT8_C(0x03)
+#define SMI230_ORIENT_FACE_UP                       UINT8_C(0x00)
+#define SMI230_ORIENT_FACE_DOWN                     UINT8_C(0x01)
+
+#define SMI230_NO_MOTION_THRESHOLD_MASK             UINT16_C(0x07FF)
+#define SMI230_NO_MOTION_SEL_MASK                   UINT16_C(0x0800)
+#define SMI230_NO_MOTION_DURATION_MASK              UINT16_C(0x1FFF)
+#define SMI230_NO_MOTION_X_EN_MASK                  UINT16_C(0x2000)
+#define SMI230_NO_MOTION_Y_EN_MASK                  UINT16_C(0x4000)
+#define SMI230_NO_MOTION_Z_EN_MASK                  UINT16_C(0x8000)
+
+#define SMI230_NO_MOTION_THRESHOLD_POS              UINT8_C(0)
+#define SMI230_NO_MOTION_SEL_POS                    UINT8_C(11)
+#define SMI230_NO_MOTION_DURATION_POS               UINT8_C(0)
+#define SMI230_NO_MOTION_X_EN_POS                   UINT8_C(13)
+#define SMI230_NO_MOTION_Y_EN_POS                   UINT8_C(14)
+#define SMI230_NO_MOTION_Z_EN_POS                   UINT8_C(15)
+
+#define SMI230_ACCEL_DATA_SYNC_LEN         1
+#define SMI230_ACCEL_DATA_SYNC_MODE_MASK   0x0003
+#define SMI230_ACCEL_DATA_SYNC_MODE_SHIFT  0
+
+#define SMI230_ACCEL_DATA_SYNC_MODE_OFF    0x00
+#define SMI230_ACCEL_DATA_SYNC_MODE_400HZ  0x01
+#define SMI230_ACCEL_DATA_SYNC_MODE_1000HZ 0x02
+#define SMI230_ACCEL_DATA_SYNC_MODE_2000HZ 0x03
+
+#define SMI230_SET_BITS(reg_var, bitname, val) \
+		((reg_var & ~(bitname##_MASK)) | \
+				((val << bitname##_POS) & bitname##_MASK))
+
+#define SMI230_GET_BITS(reg_var, bitname) \
+	((reg_var & (bitname##_MASK)) >> \
+		(bitname##_POS))
+
+#define SMI230_SET_BITS_POS_0(reg_var, bitname, val) \
+		((reg_var & ~(bitname##_MASK)) | \
+				(val & bitname##_MASK))
+
+#define SMI230_GET_BITS_POS_0(reg_var, bitname) (reg_var & (bitname##_MASK))
+#define SMI230_SET_BIT_VAL_0(reg_var, bitname)  (reg_var & ~(bitname##_MASK))
+
+#define SMI230_GET_DIFF(x, y) ((x) - (y))
+
+#define SMI230_GET_LSB(var) (uint8_t)(var & SMI230_SET_LOW_BYTE)
+#define SMI230_GET_MSB(var) (uint8_t)((var & SMI230_SET_HIGH_BYTE) >> 8)
+
+enum smi230_intf {
+	SMI230_I2C_INTF,
+	SMI230_SPI_INTF
+};
+
+typedef int8_t(*smi230_com_fptr_t) (uint8_t dev_addr, uint8_t reg_addr,
+				    uint8_t *data, uint16_t len);
+
+typedef void (*smi230_delay_fptr_t)(uint32_t period);
+
+struct smi230_sensor_data {
+	int16_t x;
+	int16_t y;
+	int16_t z;
+};
+
+struct smi230_sensor_data_f {
+	float x;
+	float y;
+	float z;
+};
+
+struct smi230_cfg {
+	uint8_t power;
+	uint8_t range;
+	uint8_t bw;
+	uint8_t odr;
+};
+
+struct smi230_err_reg {
+	uint8_t fatal_err;
+	uint8_t err_code;
+};
+
+struct smi230_anymotion_cfg {
+	/* 11 bit threshold of anymotion detection
+	 * (threshold = X mg * 2,048 (5.11 format))
+	 */
+	uint16_t threshold;
+	uint16_t enable;
+
+	/* 13 bit set the duration for any- and nomotion
+	 * (time = duration * 20ms (@50Hz))
+	 */
+	uint16_t duration;
+	uint16_t x_en;
+	uint16_t y_en;
+	uint16_t z_en;
+};
+
+struct smi230_data_sync_cfg {
+	/*! Mode (0 = off, 1 = 400Hz, 2 = 1kHz, 3 = 2kHz) */
+	uint8_t mode;
+};
+
+struct smi230_high_g_cfg {
+	uint16_t threshold;
+	uint16_t hysteresis;
+	uint16_t select_x;
+	uint16_t select_y;
+	uint16_t select_z;
+	uint16_t enable;
+	uint16_t duration;
+};
+
+struct smi230_low_g_cfg {
+	uint16_t threshold;
+	uint16_t hysteresis;
+	uint16_t duration;
+	uint16_t enable;
+
+};
+
+struct smi230_high_g_out {
+	uint8_t x;
+	uint8_t y;
+	uint8_t z;
+	uint8_t direction;
+};
+
+struct smi230_orient_cfg {
+	uint16_t ud_en;
+	uint16_t mode;
+	uint16_t blocking;
+	uint16_t theta;
+	uint16_t hysteresis;
+	uint16_t enable;
+};
+
+struct smi230_orient_out {
+	uint8_t portrait_landscape;
+	uint8_t faceup_down;
+};
+
+struct smi230_no_motion_cfg {
+	uint16_t duration;
+	uint16_t threshold;
+	uint16_t select_x;
+	uint16_t select_y;
+	uint16_t select_z;
+	uint16_t enable;
+
+};
+
+enum smi230_accel_int_channel {
+	SMI230_INT_CHANNEL_1,
+	SMI230_INT_CHANNEL_2
+};
+
+enum smi230_accel_int_types {
+	SMI230_ACCEL_DATA_RDY_INT,
+	SMI230_ACCEL_SYNC_DATA_RDY_INT,
+	SMI230_ACCEL_SYNC_INPUT,
+	SMI230_ACCEL_FIFO_WM_INT,
+	SMI230_ACCEL_FIFO_FULL_INT,
+	//SMI230_ACCEL_INT_FIFO_FULL,
+	SMI230_ACCEL_ANYMOTION_INT,
+	SMI230_ACCEL_HIGH_G_INT,
+	SMI230_ACCEL_LOW_G_INT,
+	SMI230_ACCEL_ORIENT_INT,
+	SMI230_ACCEL_NO_MOTION_INT,
+	SMI230_ACCEL_ERROR_INT
+};
+
+struct smi230_int_pin_cfg {
+
+	/*! interrupt pin level configuration
+	 * Assignable macros :
+	 * - SMI230_INT_ACTIVE_LOW
+	 * - SMI230_INT_ACTIVE_HIGH
+	 */
+	uint8_t lvl:1;
+
+	/*! interrupt pin mode configuration
+	 * Assignable macros :
+	 * - SMI230_INT_MODE_PUSH_PULL
+	 * - SMI230_INT_MODE_OPEN_DRAIN
+	 */
+	uint8_t output_mode:1;
+
+	/*! Enable interrupt pin
+	 * Assignable Macros :
+	 * - SMI230_ENABLE
+	 * - SMI230_DISABLE
+	 */
+	uint8_t enable_int_pin:1;
+};
+
+struct smi230_accel_int_channel_cfg {
+	enum smi230_accel_int_channel int_channel;
+	enum smi230_accel_int_types int_type;
+	struct smi230_int_pin_cfg int_pin_cfg;
+};
+
+struct smi230_int_cfg {
+	struct smi230_accel_int_channel_cfg accel_int_config_1;
+	struct smi230_accel_int_channel_cfg accel_int_config_2;
+};
+
+struct smi230_dev {
+	uint8_t accel_chip_id;
+	uint8_t gyro_chip_id;
+	uint8_t accel_id;
+	uint8_t gyro_id;
+	enum smi230_intf intf;
+	uint8_t dummy_byte;
+	struct smi230_cfg accel_cfg;
+	struct smi230_cfg gyro_cfg;
+	const uint8_t *config_file_ptr;
+	uint8_t read_write_len;
+	smi230_com_fptr_t read;
+	smi230_com_fptr_t write;
+	smi230_delay_fptr_t delay_ms;
+};
+
+void smi230_delay(uint32_t msec);
+
+int smi230_acc_probe(struct device *dev, struct smi230_dev *p_smi230_dev);
+
+int8_t smi230_acc_init(struct smi230_dev *dev);
+
+#endif /* _SMI230_ACC_H */
diff --git a/src/kernel/linux/v4.19/drivers/iio/accel/smi230_acc_core.c b/src/kernel/linux/v4.19/drivers/iio/accel/smi230_acc_core.c
new file mode 100644
index 0000000..fe4e0e9
--- /dev/null
+++ b/src/kernel/linux/v4.19/drivers/iio/accel/smi230_acc_core.c
@@ -0,0 +1,1227 @@
+// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+/**
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE
+ * Copyright (c) 2022 Robert Bosch GmbH. All rights reserved.
+ *
+ * This file is free software licensed under the terms of version 2
+ * of the GNU General Public License, available from the file LICENSE-GPL
+ * in the main directory of this source tree.
+ *
+ * BSD LICENSE
+ * Copyright (c) 2022 Robert Bosch GmbH. All rights reserved.
+ *
+ * BSD-3-Clause
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **/
+
+#include <linux/delay.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger.h>
+#include <linux/of_gpio.h>
+#include <linux/ioport.h>
+
+#include "smi230_acc.h"
+
+#define SMI230_CHANNEL(_type, _axis, _index) {			\
+	.type = _type,						\
+	.modified = 1,						\
+	.channel2 = IIO_MOD_##_axis,				\
+	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+	.scan_index = _index,					\
+	.scan_type = {						\
+		.sign = 's',					\
+		.realbits = 16,					\
+		.storagebits = 16,				\
+		.endianness = IIO_LE,				\
+	},							\
+}
+
+static uint8_t temp_buff[CONFIG_IIO_SMI230_ACC_MAX_BUFFER_LEN + 1];
+
+static const struct iio_chan_spec smi230_channels[] = {
+	SMI230_CHANNEL(IIO_ACCEL, X, 0),
+	SMI230_CHANNEL(IIO_ACCEL, Y, 1),
+	SMI230_CHANNEL(IIO_ACCEL, Z, 2),
+	IIO_CHAN_SOFT_TIMESTAMP(3),
+};
+
+static struct smi230_int_cfg int_config;
+
+int8_t null_ptr_check(const struct smi230_dev *dev)
+{
+	int8_t rslt;
+
+	if ((dev == NULL) || (dev->read == NULL) || (dev->write == NULL)
+	    || (dev->delay_ms == NULL))
+		rslt = SMI230_E_NULL_PTR;
+	else
+		rslt = SMI230_OK;
+
+	return rslt;
+}
+
+static int8_t get_regs(uint8_t reg_addr, uint8_t *reg_data, uint16_t len,
+		       const struct smi230_dev *dev)
+{
+	int8_t rslt;
+	uint16_t index;
+	uint16_t temp_len = len + dev->dummy_byte;
+
+	if (WARN(temp_len > CONFIG_IIO_SMI230_ACC_MAX_BUFFER_LEN,
+			"SMI230 buffer overflow\n"))
+		return SMI230_E_COM_FAIL;
+
+	if (dev->intf == SMI230_SPI_INTF)
+		reg_addr = reg_addr | SMI230_SPI_RD_MASK;
+
+	rslt = dev->read(dev->accel_id, reg_addr, temp_buff, temp_len);
+
+	if (rslt == SMI230_OK) {
+		for (index = 0; index < len; index++)
+			reg_data[index] = temp_buff[index + dev->dummy_byte];
+	} else {
+		rslt = SMI230_E_COM_FAIL;
+	}
+
+	return rslt;
+}
+
+static int8_t set_regs(uint8_t reg_addr, uint8_t *reg_data, uint16_t len,
+		       const struct smi230_dev *dev)
+{
+	int8_t rslt;
+
+	if (dev->intf == SMI230_SPI_INTF) {
+		reg_addr = (reg_addr & SMI230_SPI_WR_MASK);
+	}
+
+	rslt = dev->write(dev->accel_id, reg_addr, reg_data, len);
+
+	if (rslt != SMI230_OK)
+		rslt = SMI230_E_COM_FAIL;
+
+	return rslt;
+}
+
+static int8_t set_int_pin_config(
+		const struct smi230_accel_int_channel_cfg *int_config,
+		const struct smi230_dev *dev)
+{
+	int8_t rslt;
+	uint8_t reg_addr = 0;
+	uint8_t data;
+	uint8_t is_channel_invalid = FALSE;
+
+	switch (int_config->int_channel) {
+	case SMI230_INT_CHANNEL_1:
+		reg_addr = SMI230_ACCEL_INT1_IO_CONF_REG;
+		break;
+
+	case SMI230_INT_CHANNEL_2:
+		reg_addr = SMI230_ACCEL_INT2_IO_CONF_REG;
+		break;
+
+	default:
+		is_channel_invalid = TRUE;
+		break;
+	}
+
+	if (!is_channel_invalid) {
+		rslt = get_regs(reg_addr, &data, 1, dev);
+
+		if (rslt == SMI230_OK) {
+			data = SMI230_SET_BITS(data, SMI230_ACCEL_INT_LVL,
+					int_config->int_pin_cfg.lvl);
+
+			data = SMI230_SET_BITS(data, SMI230_ACCEL_INT_OD,
+					    int_config->int_pin_cfg.output_mode);
+
+			if (int_config->int_type == SMI230_ACCEL_SYNC_INPUT) {
+				data = SMI230_SET_BITS_POS_0(data, SMI230_ACCEL_INT_EDGE,
+							  SMI230_ENABLE);
+
+				data = SMI230_SET_BITS(data, SMI230_ACCEL_INT_IN,
+						    int_config->int_pin_cfg.enable_int_pin);
+
+				data = SMI230_SET_BIT_VAL_0(data, SMI230_ACCEL_INT_IO);
+			} else {
+				data = SMI230_SET_BITS(data, SMI230_ACCEL_INT_IO,
+						int_config->int_pin_cfg.enable_int_pin);
+
+				data = SMI230_SET_BIT_VAL_0(data, SMI230_ACCEL_INT_IN);
+			}
+
+			rslt = set_regs(reg_addr, &data, 1, dev);
+		}
+	} else {
+		rslt = SMI230_E_INVALID_INPUT;
+	}
+
+	return rslt;
+}
+
+static int8_t set_accel_data_ready_int(
+		const struct smi230_accel_int_channel_cfg *int_config,
+		const struct smi230_dev *dev)
+{
+	int8_t rslt;
+	uint8_t data = 0, conf;
+
+	rslt = get_regs(SMI230_ACCEL_INT1_INT2_MAP_DATA_REG, &data, 1, dev);
+
+	if (rslt == SMI230_OK) {
+		conf = int_config->int_pin_cfg.enable_int_pin;
+
+		switch (int_config->int_channel) {
+		case SMI230_INT_CHANNEL_1:
+			data = SMI230_SET_BITS(data, SMI230_ACCEL_INT1_DRDY, conf);
+			break;
+
+		case SMI230_INT_CHANNEL_2:
+			data = SMI230_SET_BITS(data, SMI230_ACCEL_INT2_DRDY, conf);
+			break;
+
+		default:
+			rslt = SMI230_E_INVALID_INPUT;
+			break;
+		}
+
+		if (rslt == SMI230_OK) {
+			rslt = set_int_pin_config(int_config, dev);
+			if (rslt == SMI230_OK)
+				rslt = set_regs(SMI230_ACCEL_INT1_INT2_MAP_DATA_REG,
+						&data, 1, dev);
+		}
+	}
+
+	return rslt;
+}
+
+static int8_t set_accel_sync_data_ready_int(
+		const struct smi230_accel_int_channel_cfg *int_config,
+		const struct smi230_dev *dev)
+{
+	int8_t rslt;
+	uint8_t data, reg_addr = 0;
+
+	rslt = null_ptr_check(dev);
+	if (rslt == SMI230_OK) {
+
+		data = SMI230_ACCEL_INTA_DISABLE;
+
+		switch (int_config->int_channel) {
+		case SMI230_INT_CHANNEL_1:
+			reg_addr = SMI230_ACCEL_INT1_MAP_REG;
+			break;
+
+		case SMI230_INT_CHANNEL_2:
+			reg_addr = SMI230_ACCEL_INT2_MAP_REG;
+			break;
+
+		default:
+			rslt = SMI230_E_INVALID_INPUT;
+			break;
+		}
+
+		if (rslt == SMI230_OK) {
+			if (int_config->int_pin_cfg.enable_int_pin == SMI230_ENABLE)
+				data = SMI230_ACCEL_INTA_ENABLE;
+
+			rslt = set_regs(reg_addr, &data, 1, dev);
+			if (rslt == SMI230_OK)
+				rslt = set_int_pin_config(int_config, dev);
+		}
+	}
+
+	return rslt;
+}
+
+static int8_t set_accel_sync_input(
+		const struct smi230_accel_int_channel_cfg *int_config,
+		const struct smi230_dev *dev)
+{
+	int8_t rslt;
+
+	rslt = null_ptr_check(dev);
+	if (rslt == SMI230_OK)
+		rslt = set_int_pin_config(int_config, dev);
+
+	return rslt;
+}
+
+static int8_t set_accel_anymotion_int(
+		const struct smi230_accel_int_channel_cfg *int_config,
+		const struct smi230_dev *dev)
+{
+	int8_t rslt;
+	uint8_t data, reg_addr = 0;
+
+	rslt = null_ptr_check(dev);
+	if (rslt == SMI230_OK) {
+		data = SMI230_ACCEL_INTB_DISABLE;
+
+		switch (int_config->int_channel) {
+		case SMI230_INT_CHANNEL_1:
+			reg_addr = SMI230_ACCEL_INT1_MAP_REG;
+			break;
+
+		case SMI230_INT_CHANNEL_2:
+			reg_addr = SMI230_ACCEL_INT2_MAP_REG;
+			break;
+
+		default:
+			rslt = SMI230_E_INVALID_INPUT;
+			break;
+		}
+
+		if (rslt == SMI230_OK) {
+			if (int_config->int_pin_cfg.enable_int_pin == SMI230_ENABLE)
+				data = SMI230_ACCEL_INTB_ENABLE;
+
+			rslt = set_regs(reg_addr, &data, 1, dev);
+			if (rslt == SMI230_OK)
+				rslt = set_int_pin_config(int_config, dev);
+		}
+	}
+
+	return rslt;
+}
+
+static int8_t set_accel_high_g_int(
+		const struct smi230_accel_int_channel_cfg *int_config,
+		const struct smi230_dev *dev)
+{
+	int8_t rslt;
+	uint8_t data, reg_addr = 0;
+
+	rslt = null_ptr_check(dev);
+	if (rslt == SMI230_OK) {
+		data = SMI230_ACCEL_HIGH_G_INT_DISABLE;
+
+		switch (int_config->int_channel) {
+		case SMI230_INT_CHANNEL_1:
+			reg_addr = SMI230_ACCEL_INT1_MAP_REG;
+			break;
+
+		case SMI230_INT_CHANNEL_2:
+			reg_addr = SMI230_ACCEL_INT2_MAP_REG;
+			break;
+
+		default:
+			rslt = SMI230_E_INVALID_INPUT;
+			break;
+		}
+
+		if (rslt == SMI230_OK) {
+			rslt = get_regs(reg_addr, &data, 1, dev);
+
+			if (int_config->int_pin_cfg.enable_int_pin == SMI230_ENABLE)
+				data |= SMI230_ACCEL_HIGH_G_INT_ENABLE;
+			else
+				data &= ~SMI230_ACCEL_HIGH_G_INT_ENABLE;
+
+			if (rslt == SMI230_OK)
+				rslt = set_regs(reg_addr, &data, 1, dev);
+
+			if (rslt == SMI230_OK)
+				rslt = set_int_pin_config(int_config, dev);
+		}
+	}
+
+	return rslt;
+}
+
+static int8_t set_accel_low_g_int(
+		const struct smi230_accel_int_channel_cfg *int_config,
+		const struct smi230_dev *dev)
+{
+	int8_t rslt;
+	uint8_t data, reg_addr = 0;
+
+	rslt = null_ptr_check(dev);
+	if (rslt == SMI230_OK) {
+		data = SMI230_ACCEL_LOW_G_INT_DISABLE;
+
+		switch (int_config->int_channel) {
+		case SMI230_INT_CHANNEL_1:
+			reg_addr = SMI230_ACCEL_INT1_MAP_REG;
+			break;
+
+		case SMI230_INT_CHANNEL_2:
+			reg_addr = SMI230_ACCEL_INT2_MAP_REG;
+			break;
+
+		default:
+			rslt = SMI230_E_INVALID_INPUT;
+			break;
+		}
+
+		if (rslt == SMI230_OK) {
+			rslt = get_regs(reg_addr, &data, 1, dev);
+
+			if (int_config->int_pin_cfg.enable_int_pin == SMI230_ENABLE)
+				data |= SMI230_ACCEL_LOW_G_INT_ENABLE;
+			else
+				data &= ~SMI230_ACCEL_LOW_G_INT_DISABLE;
+
+			if (rslt == SMI230_OK)
+				rslt = set_regs(reg_addr, &data, 1, dev);
+
+			if (rslt == SMI230_OK)
+				rslt = set_int_pin_config(int_config, dev);
+		}
+	}
+
+	return rslt;
+}
+
+static int8_t set_accel_orient_int(
+		const struct smi230_accel_int_channel_cfg *int_config,
+		const struct smi230_dev *dev)
+{
+	int8_t rslt;
+	uint8_t data, reg_addr = 0;
+
+	rslt = null_ptr_check(dev);
+	if (rslt == SMI230_OK) {
+		data = SMI230_ACCEL_ORIENT_INT_DISABLE;
+
+		switch (int_config->int_channel) {
+		case SMI230_INT_CHANNEL_1:
+			reg_addr = SMI230_ACCEL_INT1_MAP_REG;
+			break;
+
+		case SMI230_INT_CHANNEL_2:
+			reg_addr = SMI230_ACCEL_INT2_MAP_REG;
+			break;
+
+		default:
+			rslt = SMI230_E_INVALID_INPUT;
+			break;
+		}
+
+		if (rslt == SMI230_OK) {
+			rslt = get_regs(reg_addr, &data, 1, dev);
+
+			if (int_config->int_pin_cfg.enable_int_pin == SMI230_ENABLE)
+				data |= SMI230_ACCEL_ORIENT_INT_ENABLE;
+			else
+				data &= ~SMI230_ACCEL_ORIENT_INT_ENABLE;
+
+			if (rslt == SMI230_OK)
+				rslt = set_regs(reg_addr, &data, 1, dev);
+
+			if (rslt == SMI230_OK)
+				rslt = set_int_pin_config(int_config, dev);
+		}
+	}
+
+	return rslt;
+}
+
+static int8_t set_accel_no_motion_int(
+		const struct smi230_accel_int_channel_cfg *int_config,
+		const struct smi230_dev *dev)
+{
+	int8_t rslt;
+	uint8_t data, reg_addr = 0;
+
+	rslt = null_ptr_check(dev);
+	if (rslt == SMI230_OK) {
+		data = SMI230_ACCEL_NO_MOT_INT_DISABLE;
+
+		switch (int_config->int_channel) {
+		case SMI230_INT_CHANNEL_1:
+			reg_addr = SMI230_ACCEL_INT1_MAP_REG;
+			break;
+
+		case SMI230_INT_CHANNEL_2:
+			reg_addr = SMI230_ACCEL_INT2_MAP_REG;
+			break;
+
+		default:
+			rslt = SMI230_E_INVALID_INPUT;
+			break;
+		}
+
+		if (rslt == SMI230_OK) {
+			rslt = get_regs(reg_addr, &data, 1, dev);
+
+			if (int_config->int_pin_cfg.enable_int_pin == SMI230_ENABLE)
+				data |= SMI230_ACCEL_NO_MOT_INT_ENABLE;
+			else
+				data &= ~SMI230_ACCEL_NO_MOT_INT_ENABLE;
+
+			if (rslt == SMI230_OK)
+				rslt = set_regs(reg_addr, &data, 1, dev);
+
+			if (rslt == SMI230_OK)
+				rslt = set_int_pin_config(int_config, dev);
+		}
+	}
+
+	return rslt;
+}
+
+static int8_t set_accel_err_int(
+		const struct smi230_accel_int_channel_cfg *int_config,
+		const struct smi230_dev *dev)
+{
+	int8_t rslt;
+	uint8_t data, reg_addr = 0;
+
+	rslt = null_ptr_check(dev);
+	if (rslt == SMI230_OK) {
+		data = SMI230_ACCEL_ERR_INT_DISABLE;
+
+		switch (int_config->int_channel) {
+		case SMI230_INT_CHANNEL_1:
+			reg_addr = SMI230_ACCEL_INT1_MAP_REG;
+			break;
+
+		case SMI230_INT_CHANNEL_2:
+			reg_addr = SMI230_ACCEL_INT2_MAP_REG;
+			break;
+
+		default:
+			rslt = SMI230_E_INVALID_INPUT;
+			break;
+		}
+
+		if (rslt == SMI230_OK) {
+			rslt = get_regs(reg_addr, &data, 1, dev);
+
+			if (int_config->int_pin_cfg.enable_int_pin == SMI230_ENABLE)
+				data |= SMI230_ACCEL_ERR_INT_ENABLE;
+			else
+				data &= ~SMI230_ACCEL_ERR_INT_ENABLE;
+
+			if (rslt == SMI230_OK)
+				rslt = set_regs(reg_addr, &data, 1, dev);
+
+			if (rslt == SMI230_OK)
+				rslt = set_int_pin_config(int_config, dev);
+		}
+	}
+
+	return rslt;
+}
+
+static int8_t smi230_acc_soft_reset(const struct smi230_dev *dev)
+{
+	int8_t rslt;
+	uint8_t data;
+
+	rslt = null_ptr_check(dev);
+
+	if (rslt == SMI230_OK) {
+		data = SMI230_SOFT_RESET_CMD;
+		rslt = set_regs(SMI230_ACCEL_SOFTRESET_REG, &data, 1, dev);
+
+		if (rslt == SMI230_OK) {
+			dev->delay_ms(SMI230_ACCEL_SOFTRESET_DELAY_MS);
+
+			/* After soft reset SPI mode in the initialization phase, need to
+			 * perform a dummy SPI read operation.
+			 * The soft-reset performs a fundamental reset to the device,
+			 * which is largely equivalent to a power cycle.
+			 */
+			if (dev->intf == SMI230_SPI_INTF) {
+				/* Dummy SPI read operation of Chip-ID */
+				rslt = get_regs(SMI230_ACCEL_CHIP_ID_REG, &data, 1, dev);
+			}
+		}
+	}
+
+	return rslt;
+}
+
+static int8_t smi230_acc_get_meas_conf(struct smi230_dev *dev)
+{
+	int8_t rslt;
+	uint8_t data[2];
+
+	rslt = null_ptr_check(dev);
+
+	if (rslt == SMI230_OK) {
+		rslt = get_regs(SMI230_ACCEL_CONF_REG, data, 2, dev);
+
+		if (rslt == SMI230_OK) {
+			dev->accel_cfg.odr = data[0] & SMI230_ACCEL_ODR_MASK;
+			dev->accel_cfg.bw = (data[0] & SMI230_ACCEL_BW_MASK) >> 4;
+			dev->accel_cfg.range = data[1] & SMI230_ACCEL_RANGE_MASK;
+		}
+	}
+
+	return rslt;
+}
+
+static int8_t smi230_acc_set_meas_conf(const struct smi230_dev *dev)
+{
+	int8_t rslt;
+	uint8_t data[2] = { 0 };
+	uint8_t bw, range, odr;
+	uint8_t is_odr_invalid = FALSE;
+	uint8_t is_bw_invalid = FALSE;
+	uint8_t is_range_invalid = FALSE;
+
+	rslt = null_ptr_check(dev);
+
+	if (rslt == SMI230_OK) {
+		odr = dev->accel_cfg.odr;
+		bw = dev->accel_cfg.bw;
+		range = dev->accel_cfg.range;
+
+		if ((odr < SMI230_ACCEL_ODR_12_5_HZ)
+				|| (odr > SMI230_ACCEL_ODR_1600_HZ)) {
+			is_odr_invalid = TRUE;
+		}
+
+		if (bw > SMI230_ACCEL_BW_NORMAL)
+			is_bw_invalid = TRUE;
+
+		if (range > SMI230_ACCEL_RANGE_16G)
+			is_range_invalid = TRUE;
+
+		/* If ODR, BW and Range are valid, write it to accel config registers */
+		if ((!is_odr_invalid) && (!is_bw_invalid) && (!is_range_invalid)) {
+			rslt = get_regs(SMI230_ACCEL_CONF_REG, data, 2, dev);
+			if (rslt == SMI230_OK) {
+				/* Update data with new odr and bw values */
+				data[0] = SMI230_SET_BITS_POS_0(data[0], SMI230_ACCEL_ODR, odr);
+				data[0] = SMI230_SET_BITS(data[0], SMI230_ACCEL_BW, bw);
+
+				/* Update data with current range values */
+				data[1] = SMI230_SET_BITS_POS_0(data[1], SMI230_ACCEL_RANGE,
+						range);
+
+				/* write to range register */
+				rslt = set_regs(SMI230_ACCEL_CONF_REG, data, 2, dev);
+			}
+		} else {
+			rslt = SMI230_E_INVALID_CONFIG;
+		}
+	}
+
+	return rslt;
+}
+
+static int8_t smi230_acc_set_power_mode(const struct smi230_dev *dev)
+{
+	int8_t rslt;
+	uint8_t data[2];
+
+	rslt = null_ptr_check(dev);
+
+	if (rslt == SMI230_OK) {
+		if (dev->accel_cfg.power == SMI230_ACCEL_PM_ACTIVE) {
+			data[0] = SMI230_ACCEL_PM_ACTIVE;
+			data[1] = SMI230_ACCEL_POWER_ENABLE;
+		} else if (dev->accel_cfg.power == SMI230_ACCEL_PM_SUSPEND) {
+			data[0] = SMI230_ACCEL_PM_SUSPEND;
+			data[1] = SMI230_ACCEL_POWER_DISABLE;
+		} else {
+			rslt = SMI230_E_INVALID_INPUT;
+		}
+
+		if (rslt == SMI230_OK) {
+			rslt = set_regs(SMI230_ACCEL_PWR_CONF_REG, &data[0], 1, dev);
+
+			if (rslt == SMI230_OK) {
+				dev->delay_ms(SMI230_POWER_CONFIG_DELAY);
+				rslt = set_regs(SMI230_ACCEL_PWR_CTRL_REG, &data[1], 1, dev);
+				if (rslt == SMI230_OK)
+					dev->delay_ms(SMI230_POWER_CONFIG_DELAY);
+			}
+
+		}
+	}
+
+	return rslt;
+}
+
+static int8_t smi230_acc_get_data(struct smi230_sensor_data *accel,
+				  const struct smi230_dev *dev)
+{
+	int8_t rslt;
+	uint8_t data[6];
+	uint8_t lsb, msb;
+	uint16_t msblsb;
+
+	rslt = null_ptr_check(dev);
+
+	if ((rslt == SMI230_OK) && (accel != NULL)) {
+		rslt = get_regs(SMI230_ACCEL_X_LSB_REG, data, 6, dev);
+
+		if (rslt == SMI230_OK) {
+			lsb = data[0];
+			msb = data[1];
+			msblsb = (msb << 8) | lsb;
+			accel->x = ((int16_t) msblsb);	/* Data in X axis */
+
+			lsb = data[2];
+			msb = data[3];
+			msblsb = (msb << 8) | lsb;
+			accel->y = ((int16_t) msblsb);	/* Data in Y axis */
+
+			lsb = data[4];
+			msb = data[5];
+			msblsb = (msb << 8) | lsb;
+			accel->z = ((int16_t) msblsb);	/* Data in Z axis */
+		}
+
+	} else {
+		rslt = SMI230_E_NULL_PTR;
+	}
+
+	return rslt;
+}
+
+static int8_t smi230_acc_set_int_config(
+		const struct smi230_accel_int_channel_cfg *int_config,
+		const struct smi230_dev *dev)
+{
+	int8_t rslt;
+
+	rslt = null_ptr_check(dev);
+
+	if ((rslt == SMI230_OK) && (int_config != NULL)) {
+		switch (int_config->int_type) {
+		case SMI230_ACCEL_DATA_RDY_INT:
+			rslt = set_accel_data_ready_int(int_config, dev);
+			break;
+		case SMI230_ACCEL_SYNC_DATA_RDY_INT:
+			rslt = set_accel_sync_data_ready_int(int_config, dev);
+			break;
+		case SMI230_ACCEL_SYNC_INPUT:
+			rslt = set_accel_sync_input(int_config, dev);
+			break;
+		case SMI230_ACCEL_ANYMOTION_INT:
+			rslt = set_accel_anymotion_int(int_config, dev);
+			break;
+		case SMI230_ACCEL_HIGH_G_INT:
+			rslt = set_accel_high_g_int(int_config, dev);
+			break;
+		case SMI230_ACCEL_LOW_G_INT:
+			rslt = set_accel_low_g_int(int_config, dev);
+			break;
+		case SMI230_ACCEL_ORIENT_INT:
+			rslt = set_accel_orient_int(int_config, dev);
+			break;
+		case SMI230_ACCEL_NO_MOTION_INT:
+			rslt = set_accel_no_motion_int(int_config, dev);
+			break;
+		case SMI230_ACCEL_ERROR_INT:
+			rslt = set_accel_err_int(int_config, dev);
+			break;
+		default:
+			rslt = SMI230_E_INVALID_CONFIG;
+			break;
+		}
+	} else {
+		rslt = SMI230_E_NULL_PTR;
+	}
+
+	return rslt;
+}
+
+void smi230_delay(uint32_t msec)
+{
+	unsigned long mseond = msec;
+	unsigned long min = mseond * (1000);
+	if (msec <= 20)
+		usleep_range(min, (min + 1000));
+	else
+		msleep(msec);
+}
+
+int8_t smi230_acc_init(struct smi230_dev *dev)
+{
+	int8_t rslt;
+	uint8_t chip_id = 0;
+
+	rslt = null_ptr_check(dev);
+	if (rslt == SMI230_OK) {
+		if (dev->intf == SMI230_SPI_INTF) {
+			/* Set dummy byte in case of SPI interface */
+			dev->dummy_byte = SMI230_ENABLE;
+
+			/* Dummy read of Chip-ID in SPI mode */
+			rslt = get_regs(SMI230_ACCEL_CHIP_ID_REG, &chip_id, 1, dev);
+		} else {
+			/* Make dummy byte 0 in case of I2C interface */
+			dev->dummy_byte = SMI230_DISABLE;
+		}
+
+		if (rslt == SMI230_OK) {
+			rslt = get_regs(SMI230_ACCEL_CHIP_ID_REG, &chip_id, 1, dev);
+
+			if (rslt == SMI230_OK) {
+				if (chip_id == SMI230_ACCEL_CHIP_ID) {
+					dev->accel_chip_id = chip_id;
+				} else
+					rslt = SMI230_E_DEV_NOT_FOUND;
+			}
+		}
+	}
+
+	return rslt;
+}
+
+static int smi230_read_raw(struct iio_dev *indio_dev,
+			   struct iio_chan_spec const *chan,
+			   int *val, int *val2, long mask)
+{
+	int ret;
+	struct smi230_dev *p_smi230_dev = iio_device_get_drvdata(indio_dev);
+	struct smi230_sensor_data data = { 0 };
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		ret = smi230_acc_get_data(&data, p_smi230_dev);
+		if (ret != SMI230_OK)
+			return 0;
+		switch (chan->channel2) {
+		case IIO_MOD_X:
+			*val = data.x;
+			break;
+		case IIO_MOD_Y:
+			*val = data.y;
+			break;
+		case IIO_MOD_Z:
+			*val = data.z;
+			break;
+		}
+		return IIO_VAL_INT;
+
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		ret = smi230_acc_get_meas_conf(p_smi230_dev);
+		if (ret)
+			return ret;
+
+		switch (p_smi230_dev->accel_cfg.odr) {
+		case SMI230_ACCEL_ODR_12_5_HZ:
+			*val = 12;
+			*val2 = 5000000;
+			break;
+		case SMI230_ACCEL_ODR_25_HZ:
+			*val = 25;
+			*val2 = 0;
+			break;
+		case SMI230_ACCEL_ODR_50_HZ:
+			*val = 50;
+			*val2 = 0;
+			break;
+		case SMI230_ACCEL_ODR_100_HZ:
+			*val = 100;
+			*val2 = 0;
+			break;
+		case SMI230_ACCEL_ODR_200_HZ:
+			*val = 200;
+			*val2 = 0;
+			break;
+		case SMI230_ACCEL_ODR_400_HZ:
+			*val = 400;
+			*val2 = 0;
+			break;
+		case SMI230_ACCEL_ODR_800_HZ:
+			*val = 800;
+			*val2 = 0;
+			break;
+		case SMI230_ACCEL_ODR_1600_HZ:
+			*val = 1600;
+			*val2 = 0;
+			break;
+		}
+		return IIO_VAL_INT_PLUS_MICRO;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int smi230_write_raw(struct iio_dev *indio_dev,
+			    struct iio_chan_spec const *chan,
+			    int val, int val2, long mask)
+{
+	int ret;
+	struct smi230_dev *p_smi230_dev = iio_device_get_drvdata(indio_dev);
+
+	switch (mask) {
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		switch (val) {
+		case 12:
+			p_smi230_dev->accel_cfg.odr = SMI230_ACCEL_ODR_12_5_HZ;
+			break;
+		case 25:
+			p_smi230_dev->accel_cfg.odr = SMI230_ACCEL_ODR_25_HZ;
+			break;
+		case 50:
+			p_smi230_dev->accel_cfg.odr = SMI230_ACCEL_ODR_50_HZ;
+			break;
+		case 100:
+			p_smi230_dev->accel_cfg.odr = SMI230_ACCEL_ODR_100_HZ;
+			break;
+		case 200:
+			p_smi230_dev->accel_cfg.odr = SMI230_ACCEL_ODR_200_HZ;
+			break;
+		case 400:
+			p_smi230_dev->accel_cfg.odr = SMI230_ACCEL_ODR_400_HZ;
+			break;
+		case 800:
+			p_smi230_dev->accel_cfg.odr = SMI230_ACCEL_ODR_800_HZ;
+			break;
+		case 1600:
+			p_smi230_dev->accel_cfg.odr = SMI230_ACCEL_ODR_1600_HZ;
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		ret = smi230_acc_set_meas_conf(p_smi230_dev);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return ret;
+
+}
+
+static
+IIO_CONST_ATTR(in_accel_sampling_frequency_available,
+	       "12.5 25 50 100 200 400 800 1600");
+
+/* 8192 LSB/g */
+static IIO_CONST_ATTR(in_accel_scale_available, "0.0001221");
+
+//dongyu@2022.11.03 Add smi230_set_accel_power_mode start
+static int8_t smi230_acc_get_power_mode(struct smi230_dev *dev)
+{
+    int8_t rslt;
+    uint8_t data;
+
+    rslt = null_ptr_check(dev);
+    if (rslt == SMI230_OK) {
+        rslt = get_regs(SMI230_ACCEL_PWR_CONF_REG, &data, 1, dev);
+        if (rslt == SMI230_OK)
+            dev->accel_cfg.power = data;
+    }
+
+    return rslt;
+}
+
+static ssize_t smi230_get_accel_power_mode(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	int ret;
+	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+	struct smi230_dev *p_smi230_dev = iio_device_get_drvdata(indio_dev);
+
+	ret = smi230_acc_get_power_mode(p_smi230_dev);
+	if (ret) {
+		dev_err(dev, "Failed to read power config.");
+		return ret;
+	}
+
+	switch (p_smi230_dev->accel_cfg.power) {
+	case SMI230_ACCEL_PM_ACTIVE:
+		return sprintf(buf, "normal\n");
+	case SMI230_ACCEL_PM_SUSPEND:
+		return sprintf(buf, "suspend\n");
+	default:
+		return sprintf(buf, "error\n");
+	}
+}
+
+static ssize_t smi230_set_accel_power_mode(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	int ret;
+	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+	struct smi230_dev *p_smi230_dev = iio_device_get_drvdata(indio_dev);
+
+	if (strncmp(buf, "normal", 6) == 0) {
+		p_smi230_dev->accel_cfg.power = SMI230_ACCEL_PM_ACTIVE;
+	} else if (strncmp(buf, "suspend", 7) == 0) {
+		p_smi230_dev->accel_cfg.power = SMI230_ACCEL_PM_SUSPEND;
+	} else {
+		dev_err(dev, "Invalid argument for power mode.");
+		return -EINVAL;
+	}
+
+	ret = smi230_acc_set_power_mode(p_smi230_dev);
+	if (ret)
+		dev_err(dev, "Failed to set power mode.");
+
+	return count;
+}
+
+static IIO_DEVICE_ATTR(in_accel_power_mode, S_IRUGO|S_IWUSR|S_IWGRP,
+		smi230_get_accel_power_mode, smi230_set_accel_power_mode, 0);
+
+static struct attribute *smi230_attrs[] = {
+	&iio_const_attr_in_accel_sampling_frequency_available.dev_attr.attr,
+	&iio_const_attr_in_accel_scale_available.dev_attr.attr,
+	&iio_dev_attr_in_accel_power_mode.dev_attr.attr,
+	NULL,
+};
+//dongyu@2022.11.03 Add smi230_set_accel_power_mode end
+
+static const struct attribute_group smi230_attrs_group = {
+	.attrs = smi230_attrs,
+};
+
+static const struct iio_info smi230_info = {
+	.read_raw = smi230_read_raw,
+	.write_raw = smi230_write_raw,
+	.attrs = &smi230_attrs_group,
+};
+
+static int smi230_init(struct smi230_dev *dev)
+{
+	int err = 0;
+
+	/* Reset the accelerometer and wait for 1 ms
+	 * delay taken care inside the function
+	 */
+	err |= smi230_acc_soft_reset(dev);
+
+	/*set accel power mode */
+	dev->accel_cfg.power = SMI230_ACCEL_PM_ACTIVE;
+	err |= smi230_acc_set_power_mode(dev);
+
+	/*disable acc int1 */
+	int_config.accel_int_config_1.int_pin_cfg.enable_int_pin =
+	    SMI230_DISABLE;
+
+	/*configure int2 as accel FIFO interrupt pin */
+	int_config.accel_int_config_2.int_pin_cfg.enable_int_pin =
+	    SMI230_ENABLE;
+
+	dev->accel_cfg.odr = SMI230_ACCEL_ODR_100_HZ;
+	dev->accel_cfg.bw = SMI230_ACCEL_BW_NORMAL;
+	dev->accel_cfg.range = SMI230_ACCEL_RANGE_4G;
+
+	err |= smi230_acc_set_meas_conf(dev);
+	smi230_delay(100);
+
+	int_config.accel_int_config_2.int_channel = SMI230_INT_CHANNEL_1;
+	int_config.accel_int_config_2.int_type = SMI230_ACCEL_DATA_RDY_INT;
+	int_config.accel_int_config_2.int_pin_cfg.output_mode =
+	    SMI230_INT_MODE_PUSH_PULL;
+	int_config.accel_int_config_2.int_pin_cfg.lvl = SMI230_INT_ACTIVE_HIGH;
+
+	err |= smi230_acc_set_int_config(&int_config.accel_int_config_2, dev);
+
+	smi230_delay(100);
+
+	return err;
+}
+
+static int smi230_read_channel(struct smi230_sensor_data *sdata, int i,
+			       s16 *sample)
+{
+	switch (i) {
+	case 0:
+		*sample = sdata->x;
+		break;
+	case 1:
+		*sample = sdata->y;
+		break;
+	case 2:
+		*sample = sdata->z;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static irqreturn_t smi230_trigger_handler(int irq, void *p)
+{
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->indio_dev;
+	struct smi230_dev *p_smi230_dev = iio_device_get_drvdata(indio_dev);
+
+	s16 buf[8];
+	s16 sample;
+	int ret, i, j = 0;
+
+	struct smi230_sensor_data sensor_data = { 0 };
+
+	ret = smi230_acc_get_data(&sensor_data, p_smi230_dev);
+	if (ret) {
+		pr_err("Reading sensor data failed");
+		goto done;
+	}
+
+	for_each_set_bit(i, indio_dev->active_scan_mask, indio_dev->masklength) {
+		ret = smi230_read_channel(&sensor_data, i, &sample);
+		if (ret) {
+			pr_err("Read channel %d failed", i);
+			goto done;
+		}
+		buf[j++] = sample;
+	}
+
+	ret = iio_push_to_buffers_with_timestamp(indio_dev, buf, pf->timestamp);
+	if (ret)
+		pr_err("Push to buffer failed");
+done:
+	iio_trigger_notify_done(indio_dev->trig);
+	return IRQ_HANDLED;
+}
+
+static int smi230_get_irq(struct device *dev, int *irq)
+{
+	int gpio_pin, ret;
+
+	gpio_pin = of_get_named_gpio_flags(dev->of_node, "gpio_irq", 0, NULL);
+
+	ret = gpio_request_one(gpio_pin, GPIOF_IN, "smi230_acc_interrupt");
+	if (ret) {
+		pr_err("Request GPIO pin %d failed", gpio_pin);
+		return ret;
+	}
+
+	ret = gpio_direction_input(gpio_pin);
+	if (ret)
+		return ret;
+
+	*irq = gpio_to_irq(gpio_pin);
+
+	return ret;
+}
+
+static int smi230_new_data_trigger_set_state(
+		struct iio_trigger *trig, bool enable)
+{
+	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+	struct smi230_dev *p_smi230_dev = iio_device_get_drvdata(indio_dev);
+	u8 en;
+
+	dev_dbg(indio_dev->dev.parent, "trigger set state %d", enable);
+	if (enable)
+		en = SMI230_ENABLE;
+	else
+		en = SMI230_DISABLE;
+
+	int_config.accel_int_config_2.int_pin_cfg.enable_int_pin = en;
+	return smi230_acc_set_int_config(
+			&int_config.accel_int_config_2, p_smi230_dev);
+}
+
+static const struct iio_trigger_ops smi230_trigger_ops = {
+	.set_trigger_state = &smi230_new_data_trigger_set_state,
+};
+
+int smi230_acc_probe(struct device *dev, struct smi230_dev *p_smi230_dev)
+{
+	int ret = 0;
+	int irq;
+	struct iio_dev *indio_dev;
+
+	ret = smi230_init(p_smi230_dev);
+	if (ret == SMI230_OK) {
+		dev_dbg(dev, "Bosch Sensor %s hardware initialized", SENSOR_ACC_NAME);
+	} else {
+		dev_dbg(dev, "Bosch Sensor %s initialization failed %d",
+				SENSOR_ACC_NAME, ret);
+		return ret;
+	}
+
+	indio_dev = devm_iio_device_alloc(dev, 0);
+	if (!indio_dev)
+		return -ENOMEM;
+
+	iio_device_set_drvdata(indio_dev, p_smi230_dev);
+	dev_set_drvdata(dev, indio_dev);
+
+	indio_dev->dev.parent = dev;
+	indio_dev->channels = smi230_channels;
+	indio_dev->num_channels = ARRAY_SIZE(smi230_channels);
+	indio_dev->name = MODULE_NAME;
+	indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_TRIGGERED;
+	indio_dev->info = &smi230_info;
+	indio_dev->trig = devm_iio_trigger_alloc(&indio_dev->dev, "%s-dev%d",
+			indio_dev->name, indio_dev->id);
+
+	if (indio_dev->trig == NULL)
+		return -ENOMEM;
+
+	ret = smi230_get_irq(dev, &irq);
+	if (ret) {
+		dev_dbg(dev, "Failed to request GPIO pin");
+		return ret;
+	}
+
+	ret = devm_request_irq(&indio_dev->dev, irq,
+			&iio_trigger_generic_data_rdy_poll,
+			IRQF_TRIGGER_RISING,
+			indio_dev->name,
+			indio_dev->trig);
+
+	if (ret) {
+		dev_dbg(dev, "Failed to request irq for pin %d", irq);
+		return ret;
+	}
+
+	indio_dev->trig->dev.parent = dev;
+	indio_dev->trig->ops = &smi230_trigger_ops;
+	iio_trigger_set_drvdata(indio_dev->trig, indio_dev);
+
+	ret = devm_iio_trigger_register(&indio_dev->dev, indio_dev->trig);
+	if (ret) {
+		dev_dbg(dev, "Failed to register trigger");
+		return ret;
+	}
+
+	ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
+					      iio_pollfunc_store_time,
+					      smi230_trigger_handler, NULL);
+	if (ret) {
+		dev_dbg(dev, "Setup triggered buffer failed");
+		return ret;
+	}
+
+	ret = devm_iio_device_register(dev, indio_dev);
+	return ret;
+}
diff --git a/src/kernel/linux/v4.19/drivers/iio/accel/smi230_acc_i2c.c b/src/kernel/linux/v4.19/drivers/iio/accel/smi230_acc_i2c.c
new file mode 100644
index 0000000..11f1552
--- /dev/null
+++ b/src/kernel/linux/v4.19/drivers/iio/accel/smi230_acc_i2c.c
@@ -0,0 +1,210 @@
+// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+/**
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE
+ * Copyright (c) 2022 Robert Bosch GmbH. All rights reserved.
+ *
+ * This file is free software licensed under the terms of version 2
+ * of the GNU General Public License, available from the file LICENSE-GPL
+ * in the main directory of this source tree.
+ *
+ * BSD LICENSE
+ * Copyright (c) 2022 Robert Bosch GmbH. All rights reserved.
+ *
+ * BSD-3-Clause
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **/
+
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include "smi230_acc.h"
+
+#define SMI230_MAX_RETRY_I2C_XFER 10
+#define SMI230_I2C_WRITE_DELAY_TIME 10
+
+static struct i2c_adapter *smi230_i2c_adapter;
+
+static struct smi230_dev smi230_i2c_dev;
+
+static int8_t smi230_i2c_read(uint8_t dev_addr, uint8_t reg_addr,
+		uint8_t *data, uint16_t len)
+{
+	int32_t retry;
+
+	struct i2c_msg msg[] = {
+		{
+		 .addr = dev_addr,
+		 .flags = 0,
+		 .len = 1,
+		 .buf = &reg_addr,
+		  },
+
+		{
+		 .addr = dev_addr,
+		 .flags = I2C_M_RD,
+		 .len = len,
+		 .buf = data,
+		  },
+	};
+	for (retry = 0; retry < SMI230_MAX_RETRY_I2C_XFER; retry++) {
+		if (i2c_transfer(smi230_i2c_adapter, msg, ARRAY_SIZE(msg)) > 0)
+			break;
+
+		usleep_range(SMI230_I2C_WRITE_DELAY_TIME * 1000,
+				 SMI230_I2C_WRITE_DELAY_TIME * 1000);
+	}
+
+	if (retry >= SMI230_MAX_RETRY_I2C_XFER) {
+		pr_err("I2C xfer error");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int8_t smi230_i2c_write(uint8_t dev_addr,
+			       uint8_t reg_addr, uint8_t *data, uint16_t len)
+{
+	int32_t retry;
+	struct i2c_msg msg = {
+		.addr = dev_addr,
+		.flags = 0,
+		.len = len + 1,
+		.buf = NULL,
+	};
+
+	msg.buf = kmalloc(len + 1, GFP_KERNEL);
+	if (!msg.buf)
+		return -ENOMEM;
+
+	msg.buf[0] = reg_addr;
+	memcpy(&msg.buf[1], data, len);
+
+	for (retry = 0; retry < SMI230_MAX_RETRY_I2C_XFER; retry++) {
+		if (i2c_transfer(smi230_i2c_adapter, &msg, 1) > 0)
+			break;
+
+		usleep_range(SMI230_I2C_WRITE_DELAY_TIME * 1000,
+				 SMI230_I2C_WRITE_DELAY_TIME * 1000);
+	}
+
+	kfree(msg.buf);
+
+	if (retry >= SMI230_MAX_RETRY_I2C_XFER) {
+		pr_err("I2C xfer error");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int smi230_acc_i2c_probe(struct i2c_client *client,
+				const struct i2c_device_id *id)
+{
+	int err = 0;
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		pr_err("i2c_check_functionality error!");
+		err = -EIO;
+		return err;
+	}
+
+	smi230_i2c_adapter = client->adapter;
+	smi230_i2c_dev.accel_id = client->addr;
+
+	err = smi230_acc_init(&smi230_i2c_dev);
+	if (err == SMI230_OK)
+		pr_info("Bosch Sensor Device %s initialized", SENSOR_ACC_NAME);
+	else {
+		pr_err("Bosch Sensor Device %s initialization failed, error %d",
+		       SENSOR_ACC_NAME, err);
+	}
+
+	return smi230_acc_probe(&client->dev, &smi230_i2c_dev);
+}
+
+static const struct i2c_device_id smi230_acc_id[] = {
+	{ SENSOR_ACC_NAME, 0 },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(i2c, smi230_acc_id);
+
+static const struct of_device_id smi230_acc_of_match[] = {
+	{.compatible = SENSOR_ACC_NAME, },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(of, smi230_acc_of_match);
+
+struct i2c_driver smi230_acc_driver = {
+	.driver = {
+		   .owner = THIS_MODULE,
+		   .name = SENSOR_ACC_NAME,
+		   .of_match_table = smi230_acc_of_match,
+		    },
+	.class = I2C_CLASS_HWMON,
+	.id_table = smi230_acc_id,
+	.probe = smi230_acc_i2c_probe,
+	.remove = NULL,
+};
+
+static int __init smi230_module_init(void)
+{
+	int err = 0;
+
+	smi230_i2c_dev.delay_ms = smi230_delay;
+	smi230_i2c_dev.read_write_len = 32;
+	smi230_i2c_dev.intf = SMI230_I2C_INTF;
+	smi230_i2c_dev.read = smi230_i2c_read;
+	smi230_i2c_dev.write = smi230_i2c_write;
+
+	err |= i2c_add_driver(&smi230_acc_driver);
+
+	return err;
+}
+
+static void __exit smi230_module_exit(void)
+{
+	i2c_del_driver(&smi230_acc_driver);
+}
+
+module_init(smi230_module_init);
+module_exit(smi230_module_exit);
+
+MODULE_DESCRIPTION("SMI230 ACC SENSOR DRIVER");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_VERSION(DRIVER_VERSION);
diff --git a/src/kernel/linux/v4.19/drivers/iio/accel/smi230_acc_spi.c b/src/kernel/linux/v4.19/drivers/iio/accel/smi230_acc_spi.c
new file mode 100644
index 0000000..1b43ce5
--- /dev/null
+++ b/src/kernel/linux/v4.19/drivers/iio/accel/smi230_acc_spi.c
@@ -0,0 +1,211 @@
+// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+/**
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE
+ * Copyright (c) 2022 Robert Bosch GmbH. All rights reserved.
+ *
+ * This file is free software licensed under the terms of version 2
+ * of the GNU General Public License, available from the file LICENSE-GPL
+ * in the main directory of this source tree.
+ *
+ * BSD LICENSE
+ * Copyright (c) 2022 Robert Bosch GmbH. All rights reserved.
+ *
+ * BSD-3-Clause
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **/
+
+#include <linux/types.h>
+#include <linux/spi/spi.h>
+#include <linux/module.h>
+
+#include "smi230_acc.h"
+
+#define SMI230_SPI_MAX_BUFFER_SIZE      32
+
+static uint8_t *read_buf;
+static struct spi_device *smi230_acc_device;
+
+static struct smi230_dev smi230_spi_dev;
+
+static int8_t smi230_spi_write(uint8_t dev_addr, uint8_t reg_addr,
+		uint8_t *data, uint16_t len)
+{
+	struct spi_message msg;
+	uint8_t buffer[SMI230_SPI_MAX_BUFFER_SIZE + 1];
+	struct spi_transfer xfer = {
+		.tx_buf = buffer,
+		.len = len + 1,
+	};
+
+	if (len > SMI230_SPI_MAX_BUFFER_SIZE)
+		return -EINVAL;
+
+	buffer[0] = reg_addr;
+	memcpy(&buffer[1], data, len);
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+
+	if (dev_addr == SMI230_ACCEL_CHIP_ID)
+		return spi_sync(smi230_acc_device, &msg);
+	else
+		return -EINVAL;
+}
+
+static int8_t smi230_spi_read(uint8_t dev_addr,
+			      uint8_t reg_addr, uint8_t *data, uint16_t len)
+{
+	int ret;
+	uint16_t index;
+	struct spi_message msg;
+	struct spi_transfer xfer[2] = {
+		[0] = {
+		       .tx_buf = &reg_addr,
+		       .len = 1,
+		},
+		[1] = {
+		       .rx_buf = read_buf,
+		       .len = len,
+		}
+	};
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer[0], &msg);
+	spi_message_add_tail(&xfer[1], &msg);
+
+	if (dev_addr == SMI230_ACCEL_CHIP_ID)
+		ret = spi_sync(smi230_acc_device, &msg);
+	else
+		return -EINVAL;
+
+	for (index = 0; index < len; index++)
+		data[index] = read_buf[index];
+
+	return ret;
+}
+
+static int smi230_acc_spi_probe(struct spi_device *device)
+{
+	int err;
+
+	device->bits_per_word = 8;
+	err = spi_setup(device);
+	if (err < 0) {
+		pr_err("spi_setup err!\n");
+		return err;
+	}
+
+	if (read_buf == NULL)
+		read_buf =
+		    kmalloc(CONFIG_IIO_SMI230_ACC_MAX_BUFFER_LEN + 1, GFP_KERNEL);
+	if (!read_buf)
+		return SMI230_E_NULL_PTR;
+
+	/* chip_id is used to differentiate acc/gyro on spi read/write */
+	smi230_spi_dev.accel_id = SMI230_ACCEL_CHIP_ID;
+
+	smi230_acc_device = device;
+
+	err = smi230_acc_init(&smi230_spi_dev);
+	if (err == SMI230_OK)
+		pr_info("Bosch Sensor Device %s initialized", SENSOR_ACC_NAME);
+	else {
+		kfree(read_buf);
+		read_buf = NULL;
+		smi230_acc_device = NULL;
+		pr_err("Bosch Sensor Device %s initialization failed, error %d",
+		       SENSOR_ACC_NAME, err);
+		return err;
+	}
+
+	return smi230_acc_probe(&device->dev, &smi230_spi_dev);
+}
+
+static int smi230_acc_spi_remove(struct spi_device *device)
+{
+	if (read_buf != NULL) {
+		kfree(read_buf);
+		read_buf = NULL;
+	}
+	return 0;
+}
+
+static const struct spi_device_id smi230_acc_id[] = {
+	{ SENSOR_ACC_NAME, 0 },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(spi, smi230_acc_id);
+
+static const struct of_device_id smi230_acc_of_match[] = {
+	{.compatible = SENSOR_ACC_NAME, },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(of, smi230_acc_of_match);
+
+static struct spi_driver smi230_acc_driver = {
+	.driver = {
+		   .owner = THIS_MODULE,
+		   .name = SENSOR_ACC_NAME,
+		   .of_match_table = smi230_acc_of_match,
+		    },
+	.id_table = smi230_acc_id,
+	.probe = smi230_acc_spi_probe,
+	.remove = smi230_acc_spi_remove,
+};
+
+static int __init smi230_module_init(void)
+{
+	int err = 0;
+
+	smi230_spi_dev.delay_ms = smi230_delay;
+	smi230_spi_dev.read_write_len = 32;
+	smi230_spi_dev.intf = SMI230_SPI_INTF;
+	smi230_spi_dev.read = smi230_spi_read;
+	smi230_spi_dev.write = smi230_spi_write;
+
+	err |= spi_register_driver(&smi230_acc_driver);
+	return err;
+}
+
+static void __exit smi230_module_exit(void)
+{
+	spi_unregister_driver(&smi230_acc_driver);
+}
+
+module_init(smi230_module_init);
+module_exit(smi230_module_exit);
+
+MODULE_DESCRIPTION("SMI230 ACC SENSOR DRIVER");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_VERSION(DRIVER_VERSION);
diff --git a/src/kernel/linux/v4.19/drivers/iio/gyro/Kconfig b/src/kernel/linux/v4.19/drivers/iio/gyro/Kconfig
index 3126cf0..b86f56e 100644
--- a/src/kernel/linux/v4.19/drivers/iio/gyro/Kconfig
+++ b/src/kernel/linux/v4.19/drivers/iio/gyro/Kconfig
@@ -139,4 +139,34 @@
 	  Say yes here to add support for the InvenSense ITG3200 digital
 	  3-axis gyroscope sensor.
 
+config SMI230_GYRO
+	tristate "BOSCH SMI230 Gyro Sensor"
+	depends on (I2C || SPI_MASTER)
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
+	help
+	  Say yes here to build support for BOSCH SMI230GYRO Tri-axis Gyro Sensor
+	  driver connected via I2C or SPI.
+
+choice
+        prompt "Select communication interface"
+        depends on SMI230_GYRO
+        help
+          Note: SPI and I2C are not supported at the same time, that is to say:
+          Choose either SPI or I2C to build the driver.
+
+    config SMI230_GYRO_SPI
+        bool "Enable SPI connection"
+        depends on SPI_MASTER
+    config SMI230_GYRO_I2C
+        bool "Enable I2C connection"
+        depends on I2C
+endchoice
+
+config SMI230_MAX_BUFFER_LEN
+        int "configue read buffer size"
+        default "1024"
+        help
+          Considering using FIFO, 1024 bytes are big enough for most cases. Do not change this value if not sure.
+
 endmenu
diff --git a/src/kernel/linux/v4.19/drivers/iio/gyro/Makefile b/src/kernel/linux/v4.19/drivers/iio/gyro/Makefile
index 295ec78..a1578be 100644
--- a/src/kernel/linux/v4.19/drivers/iio/gyro/Makefile
+++ b/src/kernel/linux/v4.19/drivers/iio/gyro/Makefile
@@ -32,3 +32,14 @@
 
 obj-$(CONFIG_IIO_ST_GYRO_I2C_3AXIS) += st_gyro_i2c.o
 obj-$(CONFIG_IIO_ST_GYRO_SPI_3AXIS) += st_gyro_spi.o
+
+#dongyu@2022.12.13 Add imu/smi230 sensor start
+obj-$(CONFIG_SMI230_GYRO) += smi230_gyro.o
+smi230_gyro-objs := smi230_gyro_core.o
+
+ifeq ($(CONFIG_SMI230_GYRO_I2C),y)
+    smi230_gyro-objs += smi230_gyro_i2c.o
+else
+    smi230_gyro-objs += smi230_gyro_spi.o
+endif
+#dongyu@2022.12.13 Add imu/smi230 sensor end
diff --git a/src/kernel/linux/v4.19/drivers/iio/gyro/smi230_gyro.h b/src/kernel/linux/v4.19/drivers/iio/gyro/smi230_gyro.h
new file mode 100644
index 0000000..d0d06bc
--- /dev/null
+++ b/src/kernel/linux/v4.19/drivers/iio/gyro/smi230_gyro.h
@@ -0,0 +1,153 @@
+/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
+/**
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE
+ * Copyright (c) 2022 Robert Bosch GmbH. All rights reserved.
+ * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved.
+ *
+ * This file is free software licensed under the terms of version 2 
+ * of the GNU General Public License, available from the file LICENSE-GPL 
+ * in the main directory of this source tree.
+ *
+ * BSD LICENSE
+ * Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved.
+ * Copyright (c) 2022 Robert Bosch GmbH. All rights reserved.
+ *
+ * BSD-3-Clause
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **/
+
+/*! \file smi230.h
+ * \brief Sensor Driver for SMI230 sensors */
+#ifndef _SMI230_GYRO_H
+#define _SMI230_GYRO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*********************************************************************/
+/* header files */
+#include <linux/module.h>
+#include <linux/delay.h>
+
+#define DRIVER_VERSION "1.0.0"
+#define MODULE_NAME "SMI230GYRO"
+#define SENSOR_GYRO_NAME "SMI230GYRO"
+
+enum smi230_intf {
+    /*! I2C interface */
+    SMI230_I2C_INTF,
+
+    /*! SPI interface */
+    SMI230_SPI_INTF
+};
+
+struct smi230_cfg
+{
+    /*! power mode */
+    uint8_t power;
+
+    /*! range */
+    uint8_t range;
+
+    /*! bandwidth */
+    uint8_t bw;
+
+    /*! output data rate */
+    uint8_t odr;
+};
+
+typedef int8_t (*smi230_com_fptr_t)(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint16_t len);
+
+typedef void (*smi230_delay_fptr_t)(uint32_t period);
+
+struct smi230_dev
+{
+
+    /*! Accel chip Id */
+    uint8_t accel_chip_id;
+
+    /*! Gyro chip Id */
+    uint8_t gyro_chip_id;
+
+    /*! Accel device Id */
+    uint8_t accel_id;
+
+    /*! Gyro device Id */
+    uint8_t gyro_id;
+
+    /*! 0 - I2C , 1 - SPI Interface */
+    enum smi230_intf intf;
+
+    /*! Decide SPI or I2C read mechanism */
+    uint8_t dummy_byte;
+
+    /*! Structure to configure gyro sensor  */
+    struct smi230_cfg gyro_cfg;
+
+    /*! Config stream data buffer address will be assigned */
+    const uint8_t *config_file_ptr;
+
+    /*! Max read/write length (maximum supported length is 32).
+     * To be set by the user */
+    uint8_t read_write_len;
+
+    /*! Read function pointer */
+    smi230_com_fptr_t read;
+
+    /*! Write function pointer */
+    smi230_com_fptr_t write;
+
+    /*! Delay function pointer */
+    smi230_delay_fptr_t delay_ms;
+};
+
+int smi230_gyro_core_probe(struct device *dev, struct smi230_dev *p_smi230_dev);
+
+static inline void smi230_delay(uint32_t msec)
+{
+        unsigned long mseond = msec;
+        unsigned long min = mseond * (1000);
+        /* if the time less than 20ms */
+        if (msec <= 20)
+                usleep_range(min, (min + 1000));
+        else
+                msleep(msec);
+}
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SMI230_GRYO_H */
+
+/** @}*/
diff --git a/src/kernel/linux/v4.19/drivers/iio/gyro/smi230_gyro_core.c b/src/kernel/linux/v4.19/drivers/iio/gyro/smi230_gyro_core.c
new file mode 100644
index 0000000..1b5eab8
--- /dev/null
+++ b/src/kernel/linux/v4.19/drivers/iio/gyro/smi230_gyro_core.c
@@ -0,0 +1,1084 @@
+// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+/**
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE
+ * Copyright (c) 2022 Robert Bosch GmbH. All rights reserved.
+ *
+ * This file is free software licensed under the terms of version 2
+ * of the GNU General Public License, available from the file LICENSE-GPL
+ * in the main directory of this source tree.
+ *
+ * BSD LICENSE
+ * Copyright (c) 2022 Robert Bosch GmbH. All rights reserved.
+ *
+ * BSD-3-Clause
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **/
+
+#include <linux/iio/iio.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger.h>
+#include <linux/of_gpio.h>
+#include <linux/ioport.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+
+#include "smi230_gyro.h"
+
+#if !defined(UINT8_C) && !defined(INT8_C)
+#define INT8_C(x)   S8_C(x)
+#define UINT8_C(x)  U8_C(x)
+#endif
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL                 0
+#else
+#define NULL                 ((void *) 0)
+#endif
+#endif
+
+#ifndef TRUE
+#define TRUE                 UINT8_C(1)
+#endif
+
+#ifndef FALSE
+#define FALSE                UINT8_C(0)
+#endif
+
+/* Gyro registers */
+#define SMI230_GYRO_CHIP_ID_REG                UINT8_C(0x00)
+#define SMI230_GYRO_X_LSB_REG                  UINT8_C(0x02)
+#define SMI230_GYRO_X_MSB_REG                  UINT8_C(0x03)
+#define SMI230_GYRO_Y_LSB_REG                  UINT8_C(0x04)
+#define SMI230_GYRO_Y_MSB_REG                  UINT8_C(0x05)
+#define SMI230_GYRO_Z_LSB_REG                  UINT8_C(0x06)
+#define SMI230_GYRO_Z_MSB_REG                  UINT8_C(0x07)
+#define SMI230_GYRO_INT_STAT_1_REG             UINT8_C(0x0A)
+#define SMI230_GYRO_RANGE_REG                  UINT8_C(0x0F)
+#define SMI230_GYRO_BANDWIDTH_REG              UINT8_C(0x10)
+#define SMI230_GYRO_LPM1_REG                   UINT8_C(0x11)
+#define SMI230_GYRO_SOFTRESET_REG              UINT8_C(0x14)
+#define SMI230_GYRO_INT_CTRL_REG               UINT8_C(0x15)
+#define SMI230_GYRO_INT3_INT4_IO_CONF_REG      UINT8_C(0x16)
+#define SMI230_GYRO_INT3_INT4_IO_MAP_REG       UINT8_C(0x18)
+#define SMI230_GYRO_WM_INT_REG                 UINT8_C(0x1E)
+#define SMI230_GYRO_FIFO_EXT_INT_S_REG		UINT8_C(0x34)
+#define SMI230_GYRO_SELF_TEST_REG              UINT8_C(0x3C)
+#define SMI230_GYRO_CHIP_ID                    UINT8_C(0x0F)
+#define SMI230_GYRO_I2C_ADDR_PRIMARY           UINT8_C(0x68)
+#define SMI230_GYRO_I2C_ADDR_SECONDARY         UINT8_C(0x69)
+#define SMI230_GYRO_RANGE_2000_DPS             UINT8_C(0x00)
+#define SMI230_GYRO_RANGE_1000_DPS             UINT8_C(0x01)
+#define SMI230_GYRO_RANGE_500_DPS              UINT8_C(0x02)
+#define SMI230_GYRO_RANGE_250_DPS              UINT8_C(0x03)
+#define SMI230_GYRO_RANGE_125_DPS              UINT8_C(0x04)
+#define SMI230_GYRO_BW_523_ODR_2000_HZ         UINT8_C(0x00)
+#define SMI230_GYRO_BW_230_ODR_2000_HZ         UINT8_C(0x01)
+#define SMI230_GYRO_BW_116_ODR_1000_HZ         UINT8_C(0x02)
+#define SMI230_GYRO_BW_47_ODR_400_HZ           UINT8_C(0x03)
+#define SMI230_GYRO_BW_23_ODR_200_HZ           UINT8_C(0x04)
+#define SMI230_GYRO_BW_12_ODR_100_HZ           UINT8_C(0x05)
+#define SMI230_GYRO_BW_64_ODR_200_HZ           UINT8_C(0x06)
+#define SMI230_GYRO_BW_32_ODR_100_HZ           UINT8_C(0x07)
+#define SMI230_GYRO_ODR_RESET_VAL              UINT8_C(0x80)
+#define SMI230_GYRO_PM_NORMAL                  UINT8_C(0x00)
+#define SMI230_GYRO_PM_DEEP_SUSPEND            UINT8_C(0x20)
+#define SMI230_GYRO_PM_SUSPEND                 UINT8_C(0x80)
+#define SMI230_GYRO_DRDY_INT_DISABLE_VAL       UINT8_C(0x00)
+#define SMI230_GYRO_DRDY_INT_ENABLE_VAL        UINT8_C(0x80)
+#define SMI230_GYRO_FIFO_INT_DISABLE_VAL       UINT8_C(0x00)
+#define SMI230_GYRO_FIFO_INT_ENABLE_VAL        UINT8_C(0x40)
+#define SMI230_GYRO_MAP_DRDY_TO_INT3           UINT8_C(0x01)
+#define SMI230_GYRO_MAP_DRDY_TO_INT4           UINT8_C(0x80)
+#define SMI230_GYRO_MAP_DRDY_TO_BOTH_INT3_INT4 UINT8_C(0x81)
+#define SMI230_GYRO_MAP_FIFO_TO_BOTH_INT3_INT4 UINT8_C(0x24)
+#define SMI230_GYRO_SOFTRESET_DELAY            UINT8_C(30)
+#define SMI230_GYRO_POWER_MODE_CONFIG_DELAY    UINT8_C(30)
+#define SMI230_GYRO_RANGE_MASK                 UINT8_C(0x07)
+#define SMI230_GYRO_BW_MASK                    UINT8_C(0x0F)
+#define SMI230_GYRO_POWER_MASK                 UINT8_C(0xA0)
+#define SMI230_GYRO_POWER_POS                  UINT8_C(5)
+#define SMI230_GYRO_DATA_EN_MASK               UINT8_C(0x80)
+#define SMI230_GYRO_DATA_EN_POS                UINT8_C(7)
+#define SMI230_GYRO_FIFO_EN_MASK               UINT8_C(0x40)
+#define SMI230_GYRO_FIFO_EN_POS                UINT8_C(6)
+#define SMI230_GYRO_INT3_LVL_MASK              UINT8_C(0x01)
+#define SMI230_GYRO_INT3_OD_MASK               UINT8_C(0x02)
+#define SMI230_GYRO_INT4_LVL_MASK              UINT8_C(0x04)
+#define SMI230_GYRO_INT4_OD_MASK               UINT8_C(0x08)
+#define SMI230_GYRO_INT3_OD_POS                UINT8_C(1)
+#define SMI230_GYRO_INT4_LVL_POS               UINT8_C(2)
+#define SMI230_GYRO_INT4_OD_POS                UINT8_C(3)
+#define SMI230_GYRO_INT_EN_MASK                UINT8_C(0x80)
+#define SMI230_GYRO_INT_EN_POS                 UINT8_C(7)
+#define SMI230_GYRO_INT3_MAP_MASK              UINT8_C(0x01)
+#define SMI230_GYRO_INT4_MAP_MASK              UINT8_C(0x80)
+#define SMI230_GYRO_FIFO_INT3_MAP_MASK              UINT8_C(0x04)
+#define SMI230_GYRO_FIFO_INT4_MAP_MASK              UINT8_C(0x20)
+#define SMI230_GYRO_INT3_MAP_POS               UINT8_C(0)
+#define SMI230_GYRO_INT4_MAP_POS               UINT8_C(7)
+#define SMI230_GYRO_FIFO_INT3_MAP_POS               UINT8_C(2)
+#define SMI230_GYRO_FIFO_INT4_MAP_POS               UINT8_C(5)
+#define SMI230_GYRO_SELF_TEST_EN_MASK          UINT8_C(0x01)
+#define SMI230_GYRO_SELF_TEST_RDY_MASK         UINT8_C(0x02)
+#define SMI230_GYRO_SELF_TEST_RESULT_MASK      UINT8_C(0x04)
+#define SMI230_GYRO_SELF_TEST_FUNCTION_MASK    UINT8_C(0x08)
+#define SMI230_GYRO_SELF_TEST_RDY_POS          UINT8_C(1)
+#define SMI230_GYRO_SELF_TEST_RESULT_POS       UINT8_C(2)
+#define SMI230_GYRO_SELF_TEST_FUNCTION_POS     UINT8_C(3)
+
+#define SMI230_INT_MODE_PUSH_PULL              UINT8_C(0)
+#define SMI230_INT_MODE_OPEN_DRAIN             UINT8_C(1)
+#define SMI230_INT_ACTIVE_LOW                  UINT8_C(0)
+#define SMI230_INT_ACTIVE_HIGH                 UINT8_C(1)
+
+#define SMI230_SPI_RD_MASK                     UINT8_C(0x80)
+#define SMI230_SPI_WR_MASK                     UINT8_C(0x7F)
+
+#define SMI230_OK                              INT8_C(0)
+#define SMI230_E_NULL_PTR                      INT8_C(-1)
+#define SMI230_E_COM_FAIL                      INT8_C(-2)
+#define SMI230_E_DEV_NOT_FOUND                 INT8_C(-3)
+#define SMI230_E_OUT_OF_RANGE                  INT8_C(-4)
+#define SMI230_E_INVALID_INPUT                 INT8_C(-5)
+#define SMI230_E_CONFIG_STREAM_ERROR           INT8_C(-6)
+#define SMI230_E_RD_WR_LENGTH_INVALID          INT8_C(-7)
+#define SMI230_E_INVALID_CONFIG                INT8_C(-8)
+#define SMI230_E_FEATURE_NOT_SUPPORTED         INT8_C(-9)
+
+#define SMI230_DISABLE                         UINT8_C(0)
+#define SMI230_ENABLE                          UINT8_C(1)
+
+#define SMI230_SET_BITS(reg_var, bitname, val) \
+    ((reg_var & ~(bitname##_MASK)) | \
+     ((val << bitname##_POS) & bitname##_MASK))
+
+#define SMI230_GET_BITS(reg_var, bitname)       ((reg_var & (bitname##_MASK)) >> \
+                                                 (bitname##_POS))
+
+#define SMI230_SET_BITS_POS_0(reg_var, bitname, val) \
+    ((reg_var & ~(bitname##_MASK)) | \
+     (val & bitname##_MASK))
+
+#define SMI230_GET_BITS_POS_0(reg_var, bitname) (reg_var & (bitname##_MASK))
+
+#define SMI230_SET_BIT_VAL_0(reg_var, bitname)  (reg_var & ~(bitname##_MASK))
+
+
+
+
+
+#define SMI230_CHANNEL(_type, _axis, _index) {			\
+	.type = _type,						\
+	.modified = 1,						\
+	.channel2 = IIO_MOD_##_axis,				\
+	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+	.scan_index = _index,					\
+	.scan_type = {						\
+		.sign = 's',					\
+		.realbits = 16,					\
+		.storagebits = 16,				\
+		.endianness = IIO_LE,				\
+	},							\
+}
+
+enum smi230_gyro_int_channel {
+    SMI230_INT_CHANNEL_3,
+    SMI230_INT_CHANNEL_4
+};
+
+enum smi230_gyro_int_types {
+    SMI230_GYRO_DATA_RDY_INT,
+    SMI230_GYRO_FIFO_INT
+};
+
+struct smi230_int_pin_cfg
+{
+    uint8_t lvl : 1;
+    uint8_t output_mode : 1;
+    uint8_t enable_int_pin : 1;
+};
+
+struct smi230_gyro_int_channel_cfg
+{
+    enum smi230_gyro_int_channel int_channel;
+    enum smi230_gyro_int_types int_type;
+    struct smi230_int_pin_cfg int_pin_cfg;
+};
+
+struct smi230_int_cfg
+{
+    struct smi230_gyro_int_channel_cfg gyro_int_config_1;
+    struct smi230_gyro_int_channel_cfg gyro_int_config_2;
+};
+
+enum smi230_scan_axis {
+        SMI230_SCAN_GYRO_X = 0,
+        SMI230_SCAN_GYRO_Y,
+        SMI230_SCAN_GYRO_Z,
+        SMI230_SCAN_TIMESTAMP,
+};
+
+static const struct iio_chan_spec smi230_channels[] = {
+	SMI230_CHANNEL(IIO_ANGL_VEL, X, SMI230_SCAN_GYRO_X),
+	SMI230_CHANNEL(IIO_ANGL_VEL, Y, SMI230_SCAN_GYRO_Y),
+	SMI230_CHANNEL(IIO_ANGL_VEL, Z, SMI230_SCAN_GYRO_Z),
+	IIO_CHAN_SOFT_TIMESTAMP(SMI230_SCAN_TIMESTAMP),
+};
+
+struct smi230_sensor_data
+{
+    int16_t x;
+    int16_t y;
+    int16_t z;
+};
+
+static int8_t null_ptr_check(const struct smi230_dev *dev)
+{
+    int8_t rslt;
+
+    if ((dev == NULL) || (dev->read == NULL) || (dev->write == NULL) || (dev->delay_ms == NULL))
+    {
+        rslt = SMI230_E_NULL_PTR;
+    }
+    else
+    {
+        rslt = SMI230_OK;
+    }
+
+    return rslt;
+}
+
+static int8_t get_regs(uint8_t reg_addr, uint8_t *reg_data, uint16_t len, const struct smi230_dev *dev)
+{
+    int8_t rslt;
+
+    if (dev->intf == SMI230_SPI_INTF)
+    {
+        /* Configuring reg_addr for SPI Interface */
+        reg_addr = (reg_addr | SMI230_SPI_RD_MASK);
+    }
+
+    /* read a gyro register */
+    rslt = dev->read(dev->gyro_id, reg_addr, reg_data, len);
+
+    if (rslt != SMI230_OK)
+    {
+        /* Updating the error */
+        rslt = SMI230_E_COM_FAIL;
+    }
+
+    return rslt;
+}
+
+static int8_t set_regs(uint8_t reg_addr, uint8_t *reg_data, uint16_t len, const struct smi230_dev *dev)
+{
+    int8_t rslt;
+
+    if (dev->intf == SMI230_SPI_INTF)
+    {
+        /* Configuring reg_addr for SPI Interface */
+        reg_addr = (reg_addr & SMI230_SPI_WR_MASK);
+    }
+
+    /* write to a gyro register */
+    rslt = dev->write(dev->gyro_id, reg_addr, reg_data, len);
+
+    if (rslt != SMI230_OK)
+    {
+        /* Updating the error */
+        rslt = SMI230_E_COM_FAIL;
+    }
+
+    return rslt;
+}
+
+int8_t smi230_gyro_chip_id_check(struct smi230_dev *dev)
+{
+    int8_t rslt;
+    uint8_t chip_id = 0;
+
+    rslt = null_ptr_check(dev);
+
+    if (rslt == SMI230_OK)
+    {
+        rslt = get_regs(SMI230_GYRO_CHIP_ID_REG, &chip_id, 1, dev);
+
+        if (rslt == SMI230_OK)
+        {
+            if (chip_id == SMI230_GYRO_CHIP_ID)
+            {
+                dev->gyro_chip_id = chip_id;
+            }
+            else
+            {
+                rslt = SMI230_E_DEV_NOT_FOUND;
+            }
+        }
+    }
+
+    return rslt;
+}
+
+int8_t smi230_gyro_get_meas_conf(struct smi230_dev *dev)
+{
+    int8_t rslt;
+    uint8_t data[2];
+
+    rslt = null_ptr_check(dev);
+
+    if (rslt == SMI230_OK)
+    {
+        rslt = get_regs(SMI230_GYRO_RANGE_REG, data, 2, dev);
+
+        if (rslt == SMI230_OK)
+        {
+            dev->gyro_cfg.range = data[0];
+            dev->gyro_cfg.odr = (data[1] & SMI230_GYRO_BW_MASK);
+            dev->gyro_cfg.bw = dev->gyro_cfg.odr;
+        }
+    }
+
+    return rslt;
+}
+
+int8_t smi230_gyro_set_meas_conf(const struct smi230_dev *dev)
+{
+    int8_t rslt;
+    uint8_t data;
+    uint8_t odr, range;
+    uint8_t is_range_invalid = FALSE, is_odr_invalid = FALSE;
+
+    rslt = null_ptr_check(dev);
+
+    if (rslt == SMI230_OK)
+    {
+        odr = dev->gyro_cfg.odr;
+        range = dev->gyro_cfg.range;
+
+        if (odr > SMI230_GYRO_BW_32_ODR_100_HZ)
+        {
+            is_odr_invalid = TRUE;
+        }
+
+        if (range > SMI230_GYRO_RANGE_125_DPS)
+        {
+            is_range_invalid = TRUE;
+        }
+
+        if ((!is_odr_invalid) && (!is_range_invalid))
+        {
+            rslt = get_regs(SMI230_GYRO_BANDWIDTH_REG, &data, 1, dev);
+            if (rslt == SMI230_OK)
+            {
+                data = SMI230_SET_BITS_POS_0(data, SMI230_GYRO_BW, odr);
+                rslt = set_regs(SMI230_GYRO_BANDWIDTH_REG, &data, 1, dev);
+                if (rslt == SMI230_OK)
+                {
+                    rslt = get_regs(SMI230_GYRO_RANGE_REG, &data, 1, dev);
+                    if (rslt == SMI230_OK)
+                    {
+                        data = SMI230_SET_BITS_POS_0(data, SMI230_GYRO_RANGE, range);
+                        rslt = set_regs(SMI230_GYRO_RANGE_REG, &data, 1, dev);
+                    }
+                }
+            }
+
+        }
+        else
+        {
+            rslt = SMI230_E_INVALID_CONFIG;
+        }
+    }
+
+    return rslt;
+}
+
+static int8_t set_int_pin_config(const struct smi230_gyro_int_channel_cfg *int_config, const struct smi230_dev *dev)
+{
+    int8_t rslt;
+    uint8_t data;
+
+    rslt = get_regs(SMI230_GYRO_INT3_INT4_IO_CONF_REG, &data, 1, dev);
+
+    if (rslt == SMI230_OK)
+    {
+        switch (int_config->int_channel)
+        {
+            case SMI230_INT_CHANNEL_3:
+                data = SMI230_SET_BITS_POS_0(data, SMI230_GYRO_INT3_LVL, int_config->int_pin_cfg.lvl);
+                data = SMI230_SET_BITS(data, SMI230_GYRO_INT3_OD, int_config->int_pin_cfg.output_mode);
+                break;
+
+            case SMI230_INT_CHANNEL_4:
+                data = SMI230_SET_BITS(data, SMI230_GYRO_INT4_LVL, int_config->int_pin_cfg.lvl);
+                data = SMI230_SET_BITS(data, SMI230_GYRO_INT4_OD, int_config->int_pin_cfg.output_mode);
+                break;
+
+            default:
+                break;
+        }
+
+        rslt = set_regs(SMI230_GYRO_INT3_INT4_IO_CONF_REG, &data, 1, dev);
+    }
+
+    return rslt;
+}
+
+static int8_t set_gyro_data_ready_int(const struct smi230_gyro_int_channel_cfg *int_config,
+                                      const struct smi230_dev *dev)
+{
+    int8_t rslt;
+    uint8_t conf, data[2] = { 0 };
+
+    rslt = get_regs(SMI230_GYRO_INT3_INT4_IO_MAP_REG, &data[0], 1, dev);
+
+    if (rslt == SMI230_OK)
+    {
+        conf = int_config->int_pin_cfg.enable_int_pin;
+
+        switch (int_config->int_channel)
+        {
+            case SMI230_INT_CHANNEL_3:
+                data[0] = SMI230_SET_BITS_POS_0(data[0], SMI230_GYRO_INT3_MAP, conf);
+                break;
+
+            case SMI230_INT_CHANNEL_4:
+                data[0] = SMI230_SET_BITS(data[0], SMI230_GYRO_INT4_MAP, conf);
+                break;
+
+            default:
+                rslt = SMI230_E_INVALID_INPUT;
+                break;
+        }
+
+        if (rslt == SMI230_OK)
+        {
+            /*condition to check disabling the interrupt in single channel when both
+             * interrupts channels are enabled*/
+            if (data[0] & SMI230_GYRO_MAP_DRDY_TO_BOTH_INT3_INT4)
+            {
+                data[1] = SMI230_GYRO_DRDY_INT_ENABLE_VAL;
+            }
+            else
+            {
+                data[1] = SMI230_GYRO_DRDY_INT_DISABLE_VAL;
+            }
+
+            rslt = set_regs(SMI230_GYRO_INT3_INT4_IO_MAP_REG, &data[0], 1, dev);
+            if (rslt == SMI230_OK)
+            {
+                rslt = set_int_pin_config(int_config, dev);
+                if (rslt == SMI230_OK)
+                    rslt = set_regs(SMI230_GYRO_INT_CTRL_REG, &data[1], 1, dev);
+            }
+        }
+
+    }
+
+    return rslt;
+}
+
+static int8_t set_gyro_fifo_int(const struct smi230_gyro_int_channel_cfg *int_config,
+                                      const struct smi230_dev *dev)
+{
+    int8_t rslt;
+    uint8_t conf, data[2] = { 0 };
+
+    rslt = get_regs(SMI230_GYRO_INT3_INT4_IO_MAP_REG, &data[0], 1, dev);
+    if (rslt == SMI230_OK)
+    {
+        conf = int_config->int_pin_cfg.enable_int_pin;
+        switch (int_config->int_channel)
+        {
+            case SMI230_INT_CHANNEL_3:
+                data[0] = SMI230_SET_BITS(data[0], SMI230_GYRO_FIFO_INT3_MAP, conf);
+                break;
+
+            case SMI230_INT_CHANNEL_4:
+                data[0] = SMI230_SET_BITS(data[0], SMI230_GYRO_FIFO_INT4_MAP, conf);
+                break;
+
+            default:
+                rslt = SMI230_E_INVALID_INPUT;
+                break;
+        }
+
+        if (rslt == SMI230_OK)
+        {
+            if (data[0] & SMI230_GYRO_MAP_FIFO_TO_BOTH_INT3_INT4)
+            {
+                data[1] = SMI230_GYRO_FIFO_INT_ENABLE_VAL;
+            }
+            else
+            {
+                data[1] = SMI230_GYRO_DRDY_INT_DISABLE_VAL;
+            }
+
+            rslt = set_regs(SMI230_GYRO_INT3_INT4_IO_MAP_REG, &data[0], 1, dev);
+            if (rslt == SMI230_OK)
+            {
+                rslt = set_int_pin_config(int_config, dev);
+                if (rslt == SMI230_OK)
+                {
+                    rslt = set_regs(SMI230_GYRO_INT_CTRL_REG, &data[1], 1, dev);
+                }
+
+            }
+        }
+
+    }
+
+    return rslt;
+}
+
+int8_t smi230_gyro_set_int_config(const struct smi230_gyro_int_channel_cfg *int_config, const struct smi230_dev *dev)
+{
+    int8_t rslt;
+
+    rslt = null_ptr_check(dev);
+    if ((rslt == SMI230_OK) && (int_config != NULL))
+    {
+        switch (int_config->int_type)
+        {
+            case SMI230_GYRO_DATA_RDY_INT:
+                rslt = set_gyro_data_ready_int(int_config, dev);
+            break;
+            case SMI230_GYRO_FIFO_INT:
+                rslt = set_gyro_fifo_int(int_config, dev);
+            break;
+
+            default:
+                rslt = SMI230_E_INVALID_CONFIG;
+                break;
+        }
+    }
+    else
+    {
+        rslt = SMI230_E_NULL_PTR;
+    }
+
+    return rslt;
+}
+
+int8_t smi230_gyro_get_data(struct smi230_sensor_data *gyro, const struct smi230_dev *dev)
+{
+    int8_t rslt;
+    uint8_t data[6];
+    uint8_t lsb, msb;
+    uint16_t msblsb;
+
+    rslt = null_ptr_check(dev);
+    if ((rslt == SMI230_OK) && (gyro != NULL))
+    {
+        rslt = get_regs(SMI230_GYRO_X_LSB_REG, data, 6, dev);
+        if (rslt == SMI230_OK)
+        {
+            lsb = data[0];
+            msb = data[1];
+            msblsb = (msb << 8) | lsb;
+            gyro->x = (int16_t)msblsb; /* Data in X axis */
+
+            lsb = data[2];
+            msb = data[3];
+            msblsb = (msb << 8) | lsb;
+            gyro->y = (int16_t)msblsb; /* Data in Y axis */
+
+            lsb = data[4];
+            msb = data[5];
+            msblsb = (msb << 8) | lsb;
+            gyro->z = (int16_t)msblsb; /* Data in Z axis */
+        }
+
+    }
+    else
+    {
+        rslt = SMI230_E_NULL_PTR;
+    }
+
+    return rslt;
+}
+
+int8_t smi230_gyro_set_power_mode(const struct smi230_dev *dev)
+{
+    int8_t rslt;
+    uint8_t power_mode, data;
+    uint8_t is_power_switching_mode_valid = TRUE;
+
+    rslt = null_ptr_check(dev);
+    if (rslt == SMI230_OK)
+    {
+        rslt = get_regs(SMI230_GYRO_LPM1_REG, &data, 1, dev);
+        if (rslt == SMI230_OK)
+        {
+            power_mode = dev->gyro_cfg.power;
+
+            /*switching between normal mode and the suspend modes is allowed, it is not possible to switch
+             * between suspend and deep suspend and vice versa. Check for invalid power switching (i.e)
+             * deep suspend to suspend */
+            if ((power_mode == SMI230_GYRO_PM_SUSPEND) && (data == SMI230_GYRO_PM_DEEP_SUSPEND))
+                is_power_switching_mode_valid = FALSE;
+
+            /* Check for invalid power switching (i.e) from suspend to deep suspend */
+            if ((power_mode == SMI230_GYRO_PM_DEEP_SUSPEND) && (data == SMI230_GYRO_PM_SUSPEND))
+                is_power_switching_mode_valid = FALSE;
+
+            /* Check if power switching mode is valid*/
+            if (is_power_switching_mode_valid)
+            {
+                rslt = set_regs(SMI230_GYRO_LPM1_REG, &power_mode, 1, dev);
+                if (rslt == SMI230_OK)
+                    dev->delay_ms(SMI230_GYRO_POWER_MODE_CONFIG_DELAY);
+
+            }
+            else
+                rslt = SMI230_E_INVALID_INPUT;
+        }
+    }
+
+    return rslt;
+}
+
+
+static int smi230_read_raw(struct iio_dev *indio_dev,
+		   struct iio_chan_spec const *chan,
+		   int *val, int *val2, long mask)
+{
+	int ret;
+	struct smi230_dev *p_smi230_dev = iio_device_get_drvdata(indio_dev);
+	struct smi230_sensor_data data = {0};
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		ret = smi230_gyro_get_data(&data, p_smi230_dev);
+		if (ret != SMI230_OK)
+			return 0;
+		switch (chan->channel2) {
+		case IIO_MOD_X:
+			*val = data.x;
+			break;
+		case IIO_MOD_Y:
+			*val = data.y;
+			break;
+		case IIO_MOD_Z:
+			*val = data.z;
+			break;
+		}
+		return IIO_VAL_INT;
+
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		ret = smi230_gyro_get_meas_conf(p_smi230_dev);
+		if (ret)
+			return ret;
+		switch(p_smi230_dev->gyro_cfg.odr) {
+		case SMI230_GYRO_BW_523_ODR_2000_HZ:
+			*val = 2000;
+			break;
+		case SMI230_GYRO_BW_116_ODR_1000_HZ:
+			*val = 1000;
+			break;
+		case SMI230_GYRO_BW_47_ODR_400_HZ:
+			*val = 400;
+			break;
+		case SMI230_GYRO_BW_64_ODR_200_HZ:
+			*val = 200;
+			break;
+		case SMI230_GYRO_BW_32_ODR_100_HZ:
+			*val = 100;
+			break;
+		default:
+			return -EINVAL;
+		}
+		*val2 = 0;
+		return IIO_VAL_INT_PLUS_MICRO;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int smi230_write_raw(struct iio_dev *indio_dev,
+	    struct iio_chan_spec const *chan,
+	    int val, int val2, long mask)
+{
+	int ret;
+	struct smi230_dev *p_smi230_dev = iio_device_get_drvdata(indio_dev);
+
+	switch (mask) {
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		switch(val) {
+		case 2000:
+			p_smi230_dev->gyro_cfg.odr = SMI230_GYRO_BW_523_ODR_2000_HZ;
+			break;
+		case 1000:
+			p_smi230_dev->gyro_cfg.odr = SMI230_GYRO_BW_116_ODR_1000_HZ;
+			break;
+		case 400:
+			p_smi230_dev->gyro_cfg.odr = SMI230_GYRO_BW_47_ODR_400_HZ;
+			break;
+		case 200:
+			p_smi230_dev->gyro_cfg.odr = SMI230_GYRO_BW_64_ODR_200_HZ;
+			break;
+		case 100:
+			p_smi230_dev->gyro_cfg.odr = SMI230_GYRO_BW_32_ODR_100_HZ;
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		ret = smi230_gyro_set_meas_conf(p_smi230_dev);
+		if (ret)
+			return ret;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return ret;
+
+}
+
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("100 200 400 1000 2000");
+
+//dongyu@2022.11.03 Add smi230_gyro_get_power_mode start
+int8_t smi230_gyro_get_power_mode(struct smi230_dev *dev)
+{
+    int8_t rslt;
+    uint8_t data;
+
+    rslt = null_ptr_check(dev);
+    if (rslt == SMI230_OK)
+    {
+        rslt = get_regs(SMI230_GYRO_LPM1_REG, &data, 1, dev);
+
+        if (rslt == SMI230_OK)
+        {
+            dev->gyro_cfg.power = data;
+        }
+    }
+	
+    return rslt;
+}
+
+static ssize_t smi230_gyro_store_pwr_cfg(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	int err = 0;
+	unsigned long pwr_cfg;
+	struct smi230_dev *p_smi230_dev = dev_get_drvdata(dev);
+
+	err = kstrtoul(buf, 10, &pwr_cfg);
+	if (err)
+		return err;
+	if (pwr_cfg == 0) {
+		p_smi230_dev->gyro_cfg.power = SMI230_GYRO_PM_NORMAL;
+		err = smi230_gyro_set_power_mode(p_smi230_dev);
+	}
+	else if (pwr_cfg == 1) {
+		p_smi230_dev->gyro_cfg.power = SMI230_GYRO_PM_SUSPEND;
+		err = smi230_gyro_set_power_mode(p_smi230_dev);
+	}
+	else if (pwr_cfg == 2) {
+		p_smi230_dev->gyro_cfg.power = SMI230_GYRO_PM_DEEP_SUSPEND;
+		err = smi230_gyro_set_power_mode(p_smi230_dev);
+	}
+	else {
+		dev_info(dev, "invalid param");
+		return count;
+	}
+
+
+	dev_info(dev, "set power cfg to %ld, err %d", pwr_cfg, err);
+
+	if (err) {
+		dev_info(dev, "setting power config failed");
+		return err;
+	}
+	return count;
+}
+
+static ssize_t smi230_gyro_show_pwr_cfg(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	int err;
+	struct smi230_dev *p_smi230_dev = dev_get_drvdata(dev);
+
+	err = smi230_gyro_get_power_mode(p_smi230_dev);
+	if (err) {
+		dev_info(dev, "read failed");
+		return err;
+	}
+	return snprintf(buf, PAGE_SIZE, "%x (0:active 1:suspend 2:deep suspend)\n", p_smi230_dev->gyro_cfg.power);
+}
+
+static DEVICE_ATTR(pwr_cfg, S_IRUGO|S_IWUSR|S_IWGRP,
+	smi230_gyro_show_pwr_cfg, smi230_gyro_store_pwr_cfg);
+
+static IIO_CONST_ATTR(in_anglvel_scale_available,
+                      "0.008 0.004 0.002 0.001 0.0005");
+
+static struct attribute *smi230_attrs[] = {
+        &iio_const_attr_sampling_frequency_available.dev_attr.attr,
+        &iio_const_attr_in_anglvel_scale_available.dev_attr.attr,
+        &dev_attr_pwr_cfg.attr,
+        NULL,
+};
+//dongyu@2022.11.03 Add smi230_gyro_get_power_mode end
+
+static const struct attribute_group smi230_attrs_group = {
+	.attrs = smi230_attrs,
+};
+
+static const struct iio_info smi230_info = {
+	.read_raw = smi230_read_raw,
+	.write_raw = smi230_write_raw,
+	.attrs = &smi230_attrs_group,
+};
+
+static struct smi230_int_cfg int_config;
+
+static int smi230_gyro_init(struct smi230_dev *dev)
+{
+	int err = 0;
+
+	err = smi230_gyro_chip_id_check(dev);
+
+	dev->gyro_cfg.power = SMI230_GYRO_PM_NORMAL;
+	err |= smi230_gyro_set_power_mode(dev);
+
+	int_config.gyro_int_config_1.int_pin_cfg.enable_int_pin = SMI230_DISABLE;
+	int_config.gyro_int_config_2.int_pin_cfg.enable_int_pin = SMI230_ENABLE;
+
+	dev->gyro_cfg.odr = SMI230_GYRO_BW_32_ODR_100_HZ;
+	dev->gyro_cfg.range = SMI230_GYRO_RANGE_125_DPS;
+
+	err |= smi230_gyro_set_meas_conf(dev);
+	smi230_delay(100);
+
+	int_config.gyro_int_config_2.int_channel = SMI230_INT_CHANNEL_3;
+	int_config.gyro_int_config_2.int_type = SMI230_GYRO_DATA_RDY_INT;
+	int_config.gyro_int_config_2.int_pin_cfg.output_mode = SMI230_INT_MODE_PUSH_PULL;
+	int_config.gyro_int_config_2.int_pin_cfg.lvl = SMI230_INT_ACTIVE_HIGH;
+
+	err |= smi230_gyro_set_int_config(&int_config.gyro_int_config_2, dev);
+
+	smi230_delay(100);
+
+	return err;
+}
+
+static int smi230_read_channel(struct smi230_sensor_data *data, int i, s16 *sample)
+{
+
+	switch (i) {
+	case 0:
+		*sample = data->x;
+		break;
+	case 1:
+		*sample = data->y;
+		break;
+	case 2:
+		*sample = data->z;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static irqreturn_t smi230_trigger_handler(int irq, void *p)
+{
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->indio_dev;
+	struct smi230_dev *p_smi230_dev = iio_device_get_drvdata(indio_dev);
+
+	/* hand code the buffer size for now */
+	s16 buf[8];
+	s16 sample;
+	int ret, i, j = 0;
+
+	struct smi230_sensor_data sensor_data = {0};
+	ret = smi230_gyro_get_data(&sensor_data, p_smi230_dev);
+	if (ret) {
+		dev_dbg(indio_dev->dev.parent, "Reading sensor data failed");
+		goto done;
+	}
+
+	for_each_set_bit(i, indio_dev->active_scan_mask, indio_dev->masklength) {
+		ret = smi230_read_channel(&sensor_data, i, &sample);
+		if (ret) {
+			dev_dbg(indio_dev->dev.parent, "Read channel %d failed", i);
+			goto done;
+		}
+		buf[j++] = sample;
+	}
+
+
+	ret = iio_push_to_buffers_with_timestamp(indio_dev, buf, pf->timestamp);
+	if (ret)
+		dev_dbg(indio_dev->dev.parent, "Push to buffer failed");
+done:
+	iio_trigger_notify_done(indio_dev->trig);
+	return IRQ_HANDLED;
+}
+
+static int smi230_new_data_trigger_set_state(struct iio_trigger *trig, bool enable)
+{
+	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+	struct smi230_dev *p_smi230_dev = iio_device_get_drvdata(indio_dev);
+	u8 en;
+
+	dev_dbg(indio_dev->dev.parent, "trigger set state %d", enable);
+	if (enable)
+		en = SMI230_ENABLE;
+	else
+		en = SMI230_DISABLE;
+
+	int_config.gyro_int_config_2.int_pin_cfg.enable_int_pin = en;
+	return smi230_gyro_set_int_config(&int_config.gyro_int_config_2, p_smi230_dev);
+}
+
+static const struct iio_trigger_ops smi230_trigger_ops = {
+	.set_trigger_state = &smi230_new_data_trigger_set_state,
+};
+
+static int smi230_get_irq(struct device *dev, int *irq)
+{
+	int gpio_pin, ret;
+
+	gpio_pin = of_get_named_gpio_flags(dev->of_node,
+					"gpio_irq", 0, NULL);
+
+	dev_dbg(dev, "gpio pin %d", gpio_pin);
+	//return 0;
+	ret = gpio_request_one(gpio_pin,
+				GPIOF_IN, "smi230_gyro_interrupt");
+	if (ret) {
+		dev_dbg(dev, "Request GPIO pin %d failed", gpio_pin);
+		return ret;
+	}
+
+	ret = gpio_direction_input(gpio_pin);
+	if (ret)
+		return ret;
+
+	*irq = gpio_to_irq(gpio_pin);
+
+
+	return ret;
+}
+
+int smi230_gyro_core_probe(struct device *dev, struct smi230_dev *p_smi230_dev)
+{
+	int ret = 0;
+	int irq;
+	struct iio_dev *indio_dev;
+
+	ret = smi230_gyro_init(p_smi230_dev);
+        if (ret == SMI230_OK)
+		dev_dbg(dev, "Bosch Sensor %s hardware initialized", SENSOR_GYRO_NAME);
+	else {
+		dev_dbg(dev, "Bosch Sensor %s hardware initialization failed, error %d",
+				SENSOR_GYRO_NAME, ret);
+	}
+
+	indio_dev = devm_iio_device_alloc(dev, 0);
+	if (!indio_dev) {
+		dev_dbg(dev, "Bosch Sensor %s iio device alloc failed", SENSOR_GYRO_NAME);
+		return -ENOMEM;
+	}
+
+	iio_device_set_drvdata(indio_dev, p_smi230_dev);
+	dev_set_drvdata(dev, indio_dev);
+	indio_dev->dev.parent = dev;
+	indio_dev->channels = smi230_channels;
+	indio_dev->num_channels = ARRAY_SIZE(smi230_channels);
+	indio_dev->name = MODULE_NAME;
+	indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_TRIGGERED;
+	indio_dev->info = &smi230_info;
+	indio_dev->trig = devm_iio_trigger_alloc(&indio_dev->dev, "%s-dev%d",
+						    indio_dev->name, indio_dev->id);
+
+	if (indio_dev->trig == NULL)
+		return -ENOMEM;
+
+	dev_dbg(dev, "Bosch Sensor %s device alloced", SENSOR_GYRO_NAME);
+
+	ret = smi230_get_irq(dev, &irq);
+	dev_dbg(dev, "irq number %d", irq);
+	
+	ret = devm_request_irq(&indio_dev->dev, irq,
+				   &iio_trigger_generic_data_rdy_poll,
+				   IRQF_TRIGGER_RISING, indio_dev->name,
+				   indio_dev->trig);
+
+	if (ret)
+		return ret;
+
+	dev_dbg(dev, "Bosch Sensor %s irq alloced", SENSOR_GYRO_NAME);
+
+	indio_dev->trig->dev.parent = dev;
+	indio_dev->trig->ops = &smi230_trigger_ops;
+
+	iio_trigger_set_drvdata(indio_dev->trig, indio_dev);
+
+	ret = devm_iio_trigger_register(&indio_dev->dev, indio_dev->trig);
+	if (ret)
+		return ret;
+
+	dev_dbg(dev, "Bosch Sensor %s trigger registered", SENSOR_GYRO_NAME);
+
+	ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
+							  iio_pollfunc_store_time,
+							  smi230_trigger_handler,
+							  NULL);
+	if (ret) {
+		dev_dbg(dev, "Setup triggered buffer failed");
+		return ret;
+	}
+
+	dev_dbg(dev, "Bosch Sensor %s trigger buffer registered", SENSOR_GYRO_NAME);
+
+	ret = devm_iio_device_register(dev, indio_dev);
+	return ret;
+}
+
+MODULE_DESCRIPTION("SMI230 GYRO SENSOR DRIVER");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/src/kernel/linux/v4.19/drivers/iio/gyro/smi230_gyro_i2c.c b/src/kernel/linux/v4.19/drivers/iio/gyro/smi230_gyro_i2c.c
new file mode 100644
index 0000000..2308af8
--- /dev/null
+++ b/src/kernel/linux/v4.19/drivers/iio/gyro/smi230_gyro_i2c.c
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+/**
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE
+ * Copyright (c) 2022 Robert Bosch GmbH. All rights reserved.
+ *
+ * This file is free software licensed under the terms of version 2 
+ * of the GNU General Public License, available from the file LICENSE-GPL 
+ * in the main directory of this source tree.
+ *
+ * BSD LICENSE
+ * Copyright (c) 2022 Robert Bosch GmbH. All rights reserved.
+ *
+ * BSD-3-Clause
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **/
+
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+
+#include "smi230_gyro.h"
+
+#define SMI230_MAX_RETRY_I2C_XFER 10
+#define SMI230_I2C_WRITE_DELAY_TIME 10
+
+static struct i2c_adapter *smi230_i2c_adapter;
+static struct smi230_dev smi230_i2c_dev;
+
+static int8_t smi230_i2c_read(uint8_t dev_addr,
+	uint8_t reg_addr, uint8_t *data, uint16_t len)
+{
+	int32_t retry;
+
+	struct i2c_msg msg[] = {
+		{
+		.addr = dev_addr,
+		.flags = 0,
+		.len = 1,
+		.buf = &reg_addr,
+		},
+
+		{
+		.addr = dev_addr,
+		.flags = I2C_M_RD,
+		.len = len,
+		.buf = data,
+		},
+	};
+	for (retry = 0; retry < SMI230_MAX_RETRY_I2C_XFER; retry++) {
+		if (i2c_transfer(smi230_i2c_adapter, msg, ARRAY_SIZE(msg)) > 0)
+			break;
+		else
+			usleep_range(SMI230_I2C_WRITE_DELAY_TIME * 1000,
+				SMI230_I2C_WRITE_DELAY_TIME * 1000);
+	}
+
+	if (SMI230_MAX_RETRY_I2C_XFER <= retry) {
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int8_t smi230_i2c_write(uint8_t dev_addr,
+	uint8_t reg_addr, uint8_t *data, uint16_t len)
+{
+	int32_t retry;
+	struct i2c_msg msg = {
+		.addr = dev_addr,
+		.flags = 0,
+		.len = len + 1,
+		.buf = NULL,
+	};
+
+	msg.buf = kmalloc(len + 1, GFP_KERNEL);
+	if (!msg.buf) {
+		return -ENOMEM;
+	}
+	msg.buf[0] = reg_addr;
+	memcpy(&msg.buf[1], data, len);
+	for (retry = 0; retry < SMI230_MAX_RETRY_I2C_XFER; retry++) {
+		if (i2c_transfer(smi230_i2c_adapter, &msg, 1) > 0)
+			break;
+		else
+			usleep_range(SMI230_I2C_WRITE_DELAY_TIME * 1000,
+				SMI230_I2C_WRITE_DELAY_TIME * 1000);
+	}
+	kfree(msg.buf);
+	if (SMI230_MAX_RETRY_I2C_XFER <= retry) {
+		dump_stack();
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int smi230_gyro_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		dev_dbg(&client->dev, "i2c_check_functionality error!");
+		return -EIO;
+	}
+
+	smi230_i2c_adapter = client->adapter;
+	dev_dbg(&client->dev, "%s i2c adapter is at %px", SENSOR_GYRO_NAME, client->adapter);
+
+	smi230_i2c_dev.gyro_id = client->addr;
+
+	return smi230_gyro_core_probe(&client->dev, &smi230_i2c_dev);
+}
+
+static const struct i2c_device_id smi230_gyro_id[] = {
+	{ SENSOR_GYRO_NAME, 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, smi230_gyro_id);
+
+static const struct of_device_id smi230_gyro_of_match[] = {
+	{ .compatible = SENSOR_GYRO_NAME, },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, smi230_gyro_of_match);
+
+static struct i2c_driver smi230_gyro_driver = {
+	.driver = {
+		.owner = THIS_MODULE,
+		.name  = SENSOR_GYRO_NAME,
+		.of_match_table = smi230_gyro_of_match,
+	},
+	.id_table = smi230_gyro_id,
+	.probe    = smi230_gyro_i2c_probe,
+};
+
+static int __init smi230_gyro_module_init(void)
+{
+	int err = 0;
+
+	smi230_i2c_dev.delay_ms = smi230_delay;
+	smi230_i2c_dev.read_write_len = 32;
+	smi230_i2c_dev.intf = SMI230_I2C_INTF;
+	smi230_i2c_dev.read = smi230_i2c_read;
+	smi230_i2c_dev.write = smi230_i2c_write;
+
+	err |= i2c_add_driver(&smi230_gyro_driver);
+
+	return err;
+}
+
+static void __exit smi230_gyro_module_exit(void)
+{
+	i2c_del_driver(&smi230_gyro_driver);
+}
+
+module_init(smi230_gyro_module_init);
+module_exit(smi230_gyro_module_exit);
+
+MODULE_DESCRIPTION("SMI230 GYRO SENSOR I2C DRIVER");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_VERSION(DRIVER_VERSION);
diff --git a/src/kernel/linux/v4.19/drivers/iio/gyro/smi230_gyro_spi.c b/src/kernel/linux/v4.19/drivers/iio/gyro/smi230_gyro_spi.c
new file mode 100644
index 0000000..1261735
--- /dev/null
+++ b/src/kernel/linux/v4.19/drivers/iio/gyro/smi230_gyro_spi.c
@@ -0,0 +1,190 @@
+// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+/**
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE
+ * Copyright (c) 2022 Robert Bosch GmbH. All rights reserved.
+ *
+ * This file is free software licensed under the terms of version 2 
+ * of the GNU General Public License, available from the file LICENSE-GPL 
+ * in the main directory of this source tree.
+ *
+ * BSD LICENSE
+ * Copyright (c) 2022 Robert Bosch GmbH. All rights reserved.
+ *
+ * BSD-3-Clause
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **/
+ 
+#include <linux/types.h>
+#include <linux/spi/spi.h>
+#include <linux/module.h>
+
+#include "smi230_gyro.h"
+#define MODULE_TAG MODULE_NAME
+#define SMI230_SPI_MAX_BUFFER_SIZE      32
+
+static uint8_t *read_buf = NULL;
+static struct spi_device *smi230_gyro_device;
+static struct smi230_dev smi230_spi_dev;
+
+static int8_t smi230_spi_write(uint8_t dev_addr,
+	uint8_t reg_addr, uint8_t *data, uint16_t len)
+{
+	struct spi_message msg;
+	uint8_t buffer[SMI230_SPI_MAX_BUFFER_SIZE + 1];
+	struct spi_transfer xfer = {
+		.tx_buf = buffer,
+		.len = len + 1,
+	};
+
+	if (len > SMI230_SPI_MAX_BUFFER_SIZE)
+		return -EINVAL;
+
+	buffer[0] = reg_addr;
+	memcpy(&buffer[1], data, len);
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+
+	return spi_sync(smi230_gyro_device, &msg);
+}
+
+static int8_t smi230_spi_read(uint8_t dev_addr,
+	uint8_t reg_addr, uint8_t *data, uint16_t len)
+{
+	int ret;
+	uint16_t index;
+	struct spi_message msg;
+	struct spi_transfer xfer[2] = {
+		[0] = {
+			.tx_buf = &reg_addr,
+			.len = 1,
+		},
+		[1] = {
+			.rx_buf = read_buf,
+			.len = len,
+		}
+	};
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer[0], &msg);
+	spi_message_add_tail(&xfer[1], &msg);
+
+	ret = spi_sync(smi230_gyro_device, &msg);
+
+	for (index = 0; index < len; index++)
+	{
+		data[index] = read_buf[index];
+	}
+
+	return ret;
+}
+
+static int smi230_gyro_spi_probe(struct spi_device *device)
+{
+	int err;
+
+	dev_dbg(&device->dev, "smi230 gyro spi probe!");
+	device->bits_per_word = 8;
+	err = spi_setup(device);
+	if (err < 0) {
+		dev_dbg(&device->dev, "spi_setup err!");
+		return err;
+	}
+
+	if (read_buf == NULL)
+		read_buf = kmalloc(CONFIG_SMI230_MAX_BUFFER_LEN + 1, GFP_KERNEL);
+        if (!read_buf) {
+		return -ENOMEM;
+        }
+
+	smi230_gyro_device = device;
+
+	return smi230_gyro_core_probe(&device->dev, &smi230_spi_dev);
+}
+
+static int smi230_gyro_spi_remove(struct spi_device *device)
+{
+	if (read_buf != NULL) {
+		kfree(read_buf);
+		read_buf = NULL;
+	}
+	return 0;
+}
+
+static const struct spi_device_id smi230_gyro_id[] = {
+	{ SENSOR_GYRO_NAME, 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(spi, smi230_gyro_id);
+
+static const struct of_device_id smi230_gyro_of_match[] = {
+	{ .compatible = SENSOR_GYRO_NAME, },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, smi230_gyro_of_match);
+
+static struct spi_driver smi230_gyro_driver = {
+	.driver = {
+		.owner = THIS_MODULE,
+		.name  = SENSOR_GYRO_NAME,
+		.of_match_table = smi230_gyro_of_match,
+	},
+	.id_table = smi230_gyro_id,
+	.probe    = smi230_gyro_spi_probe,
+	.remove	= smi230_gyro_spi_remove,
+};
+
+static int __init smi230_module_init(void)
+{
+	int err = 0;
+
+	smi230_spi_dev.delay_ms = smi230_delay;
+	smi230_spi_dev.read_write_len = 32;
+	smi230_spi_dev.intf = SMI230_SPI_INTF;
+	smi230_spi_dev.read = smi230_spi_read;
+	smi230_spi_dev.write = smi230_spi_write;
+
+	err |= spi_register_driver(&smi230_gyro_driver);
+	return err;
+}
+
+static void __exit smi230_module_exit(void)
+{
+	spi_unregister_driver(&smi230_gyro_driver);
+}
+
+module_init(smi230_module_init);
+module_exit(smi230_module_exit);
+
+MODULE_DESCRIPTION("SMI230 GYRO SENSOR SPI DRIVER");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_VERSION(DRIVER_VERSION);