Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ac4c66f2 authored by Dilip Gudlur's avatar Dilip Gudlur
Browse files

Merge remote-tracking branch 'origin/caf/hal/linux-4.14.y-gh' into msm-4.14



* origin/caf/hal/linux-4.14.y-gh:
  Updated README file
  Moved SensorHAL in a separate project
  Removed any GPLv2 reference
  Add SensorHAL configuration info in README.md
  Split iio_utils to separate shared library
  Moved README.md into asm330lhh driver directory
  Moved LDD driver into new folder drivers
  Added README.md file
  SensorHAL: Added ASM330LHH Android and Linux sensor Hal
  iio: imu: Add support to ASM330LHH

Change-Id: I33a98e3e201bdbe44caa79f47d5003999da1ed84
Signed-off-by: default avatarDilip Gudlur <dgudlur@codeaurora.org>
parents ddd8ee59 dd915cfc
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line

config IIO_ST_ASM330LHH
	tristate "STMicroelectronics ASM330LHH sensor"
	depends on (I2C || SPI)
	select IIO_BUFFER
	select IIO_KFIFO_BUF
	select IIO_ST_ASM330LHH_I2C if (I2C)
	select IIO_ST_ASM330LHH_SPI if (SPI_MASTER)
	help
	  Say yes here to build support for STMicroelectronics ASM330LHH imu
	  sensor.

	  To compile this driver as a module, choose M here: the module
	  will be called st_asm330lhh.

config IIO_ST_ASM330LHH_I2C
	tristate
	depends on IIO_ST_ASM330LHH

config IIO_ST_ASM330LHH_SPI
	tristate
	depends on IIO_ST_ASM330LHH
+5 −0
Original line number Diff line number Diff line
st_asm330lhh-y := st_asm330lhh_core.o st_asm330lhh_buffer.o

obj-$(CONFIG_IIO_ST_ASM330LHH) += st_asm330lhh.o
obj-$(CONFIG_IIO_ST_ASM330LHH_I2C) += st_asm330lhh_i2c.o
obj-$(CONFIG_IIO_ST_ASM330LHH_SPI) += st_asm330lhh_spi.o
+201 −0
Original line number Diff line number Diff line
Index
=======
	* Introduction
	* Driver Integration details
	* Android SensorHAL integration
	* Linux SensorHAL integration
	* More information
	* Copyright


Introduction
==============
This repository contains asm330lhh IMU STMicroelectronics MEMS sensor linux driver support for kernel version 4.14.

Data collected by asm330lhh STM sensor are pushed to userland through the kernel buffers of Linux IIO framework. User space applications can get sensor events by reading the related IIO devices created in the /dev directory (*/dev/iio{x}*). Please see [IIO][1] for more information.

Asm330lhh IMU STM MEMS sensor support *I2C/SPI* digital interface. Please refer to [I2C][2] and [SPI][3] for detailed documentation.

The STM Hardware Abstraction Layer (*HAL*) defines a standard interface for STM sensors allowing Android to be agnostic about low level driver implementation. The HAL library is packaged into modules (.so) file and loaded by the Android or Linux system at the appropriate time. For more information see [AOSP HAL Interface](https://source.android.com/devices/sensors/hal-interface.html) 

STM Sensor HAL is leaning on [Linux IIO framework](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/iio) to gather data from sensor device drivers and to forward samples to the Android Framework

Driver Integration details
=====================

In order to explain how to integrate Asm330lhh IMU STM sensor into the kernel, please consider the following example

### Source code integration

> * Copy driver source code into your linux kernel target directory (e.g. *drivers/iio/imu*)
> * Edit related Kconfig (e.g. *drivers/iio/imu/Kconfig*) adding *ASM330LHH* support:

>         source "drivers/iio/imu/st_asm330lhh/Kconfig"

> * Edit related Makefile (e.g. *drivers/iio/imu/Makefile*) adding the following line:

>         obj-y += st_asm330lhh/

### Device Tree configuration

> To enable driver probing, add the asm330lhh node to the platform device tree as described below.

> **Required properties:**

> *- compatible*: "st,asm330lhh"

> *- reg*: the I2C address or SPI chip select the device will respond to

> *- interrupt-parent*: phandle to the parent interrupt controller as documented in [interrupts][4]

> *- interrupts*: interrupt mapping for IRQ as documented in [interrupts][4]
> 
>**Recommended properties for SPI bus usage:**

> *- spi-max-frequency*: maximum SPI bus frequency as documented in [SPI][3]
> 
> **Optional properties:**

> *- st,drdy-int-pin*: MEMS sensor interrupt line to use (default 1)

> I2C example (based on Raspberry PI 3):

>		&i2c0 {
>			status = "ok";
>			#address-cells = <0x1>;
>			#size-cells = <0x0>;
>			asm330lhh@6b {
>				compatible = "st,asm330lhh";
>				reg = <0x6b>;
>				interrupt-parent = <&gpio>;
>				interrupts = <26 IRQ_TYPE_EDGE_RISING>;
>		};

> SPI example (based on Raspberry PI 3):

>		&spi0 {
>			status = "ok";
>			#address-cells = <0x1>;
>			#size-cells = <0x0>;
>			asm330lhh@0 {
>				spi-max-frequency = <500000>;
>				compatible = "st,asm330lhh";
>				reg = <0>;
>				interrupt-parent = <&gpio>;
>				interrupts = <26 IRQ_TYPE_EDGE_RISING>;
>			};

### Kernel configuration

Configure kernel with *make menuconfig* (alternatively use *make xconfig* or *make qconfig*)
 
>		Device Drivers  --->
>			<M> Industrial I/O support  --->
>				Inertial measurement units  --->
>				<M>   STMicroelectronics ASM330LHH sensor  --->


Android SensorHAL integration
==============

STM Sensor HAL is written in *C++* language using object-oriented design. For each hw sensor there is a custom class file (*Accelerometer.cpp*, *Gyroscope.cpp*) which extends the common base class (*SensorBase.cpp*).

Copy the HAL source code into *<AOSP_DIR\>/hardware/STMicroelectronics/SensorHAL_IIO* folder. During building process Android will include automatically the SensorHAL Android.mk.
In *<AOSP_DIR\>/device/<vendor\>/<board\>/device.mk* add package build information:

	PRODUCT_PACKAGES += sensors.{TARGET_BOARD_PLATFORM}

	Note: device.mk can not read $(TARGET_BOARD_PLATFORM) variable, read and replace the value from your BoardConfig.mk (e.g. PRODUCT_PACKAGES += sensors.msm8974 for Nexus 5)

To compile the SensorHAL_IIO just build AOSP source code from *$TOP* folder

	$ cd <AOSP_DIR>
	$ source build/envsetup.sh
	$ lunch <select target platform>
	$ make V=99

The compiled library will be placed in *<AOSP_DIR\>/out/target/product/<board\>/system/vendor/lib/hw/sensor.{TARGET_BOARD_PLATFORM}.so*

To configure sensor the Sensor HAL IIO use mm utility from HAL root folder

    since Android 7
	$mm sensors-defconfig (default configuration)
	$mm sensors-menuconfig

    after Android 7
    make -f Makefile_config sensors-defconfig (default configuration)
    make -f Makefile_config sensors-menuconfig
    
Linux SensorHAL integration
==============

Linux Sensor HAL share the same source code of Android Sensor HAL. Before compiling the Linux Sensor HAL IIO
you need to follow the same procedure listed in previous chapter "Android SensorHAL integration"
To cross compile Linux Sensor HAL must export the following shell variables 

>   export AOSP_DIR=<AOSP_DIR>
>   export ARCH=<your target architecture>
>   export CROSS_COMPILE=<toolchain for your target>

then in *<AOSP_DIR\>/hardware/STMicroelectronics/SensorHAL_IIO* folder type
>   make

it will produce a SensorHAL.so file containing the library. 
In relative pat Documentation/LinuxHal/ there are some examples explaining how to use Linux Sensor HAL

Copyright
========
Copyright (C) 2017 STMicroelectronics

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.


More Information
=================
[http://st.com](http://st.com)

[https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/iio](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/input)

[https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/i2c](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/i2c)

[https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/spi](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/spi)

[https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bings/interrupt-controller/interrupts.txt](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt)


Copyright Driver
===========
Copyright (C) 2017 STMicroelectronics

This software is distributed under the GNU General Public License - see the accompanying COPYING file for more details.

[1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/iio/iio_configfs.txt "IIO"
[2]: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/i2c "I2C"
[3]: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/spi "SPI"
[4]: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt "interrupts"

Copyright SensorHAL
========
Copyright (C) 2017 STMicroelectronics

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+238 −0
Original line number Diff line number Diff line
/*
 * STMicroelectronics st_asm330lhh sensor driver
 *
 * Copyright 2018 STMicroelectronics Inc.
 *
 * Lorenzo Bianconi <lorenzo.bianconi@st.com>
 *
 * Licensed under the GPL-2.
 */

#ifndef ST_ASM330LHH_H
#define ST_ASM330LHH_H

#include <linux/device.h>
#include <linux/iio/iio.h>

#define ST_ASM330LHH_REVISION		"2.0.1"
#define ST_ASM330LHH_PATCH		"1"

#define ST_ASM330LHH_VERSION		"v"	\
	ST_ASM330LHH_REVISION			\
	"-"					\
	ST_ASM330LHH_PATCH

#define ST_ASM330LHH_DEV_NAME		"asm330lhh"

#define ST_ASM330LHH_SAMPLE_SIZE	6
#define ST_ASM330LHH_TS_SAMPLE_SIZE	4
#define ST_ASM330LHH_TAG_SIZE		1
#define ST_ASM330LHH_FIFO_SAMPLE_SIZE	(ST_ASM330LHH_SAMPLE_SIZE + \
					 ST_ASM330LHH_TAG_SIZE)
#define ST_ASM330LHH_MAX_FIFO_DEPTH	416

#define ST_ASM330LHH_REG_FIFO_BATCH_ADDR	0x09
#define ST_ASM330LHH_REG_FIFO_CTRL4_ADDR	0x0a
#define ST_ASM330LHH_REG_STATUS_ADDR		0x1e
#define ST_ASM330LHH_REG_STATUS_TDA		BIT(2)
#define ST_ASM330LHH_REG_OUT_TEMP_L_ADDR	0x20
#define ST_ASM330LHH_REG_OUT_TEMP_H_ADDR	0x21

#define ST_ASM330LHH_MAX_ODR			416

/* Define Custom events for FIFO flush */
#define CUSTOM_IIO_EV_DIR_FIFO_EMPTY (IIO_EV_DIR_NONE + 1)
#define CUSTOM_IIO_EV_DIR_FIFO_DATA (IIO_EV_DIR_NONE + 2)
#define CUSTOM_IIO_EV_TYPE_FIFO_FLUSH (IIO_EV_TYPE_CHANGE + 1)

#define ST_ASM330LHH_CHANNEL(chan_type, addr, mod, ch2, scan_idx,	\
			   rb, sb, sg)					\
{									\
	.type = chan_type,						\
	.address = addr,						\
	.modified = mod,						\
	.channel2 = ch2,						\
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |			\
			      BIT(IIO_CHAN_INFO_SCALE),			\
	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
	.scan_index = scan_idx,						\
	.scan_type = {							\
		.sign = sg,						\
		.realbits = rb,						\
		.storagebits = sb,					\
		.endianness = IIO_LE,					\
	},								\
}

static const struct iio_event_spec st_asm330lhh_flush_event = {
	.type = CUSTOM_IIO_EV_TYPE_FIFO_FLUSH,
	.dir = IIO_EV_DIR_EITHER,
};

#define ST_ASM330LHH_FLUSH_CHANNEL(dtype)		\
{							\
	.type = dtype,					\
	.modified = 0,					\
	.scan_index = -1,				\
	.indexed = -1,					\
	.event_spec = &st_asm330lhh_flush_event,	\
	.num_event_specs = 1,				\
}

#define ST_ASM330LHH_RX_MAX_LENGTH	8
#define ST_ASM330LHH_TX_MAX_LENGTH	8

struct st_asm330lhh_transfer_buffer {
	u8 rx_buf[ST_ASM330LHH_RX_MAX_LENGTH];
	u8 tx_buf[ST_ASM330LHH_TX_MAX_LENGTH] ____cacheline_aligned;
};

struct st_asm330lhh_transfer_function {
	int (*read)(struct device *dev, u8 addr, int len, u8 *data);
	int (*write)(struct device *dev, u8 addr, int len, u8 *data);
};

struct st_asm330lhh_reg {
	u8 addr;
	u8 mask;
};

struct st_asm330lhh_odr {
	u16 hz;
	u8 val;
};

#define ST_ASM330LHH_ODR_LIST_SIZE	7
struct st_asm330lhh_odr_table_entry {
	struct st_asm330lhh_reg reg;
	struct st_asm330lhh_odr odr_avl[ST_ASM330LHH_ODR_LIST_SIZE];
};

struct st_asm330lhh_fs {
	u32 gain;
	u8 val;
};

#define ST_ASM330LHH_FS_ACC_LIST_SIZE		4
#define ST_ASM330LHH_FS_GYRO_LIST_SIZE		6
#define ST_ASM330LHH_FS_TEMP_LIST_SIZE		1
#define ST_ASM330LHH_FS_LIST_SIZE		6
struct st_asm330lhh_fs_table_entry {
	u32 size;
	struct st_asm330lhh_reg reg;
	struct st_asm330lhh_fs fs_avl[ST_ASM330LHH_FS_LIST_SIZE];
};

enum st_asm330lhh_sensor_id {
	ST_ASM330LHH_ID_ACC,
	ST_ASM330LHH_ID_GYRO,
	ST_ASM330LHH_ID_TEMP,
	ST_ASM330LHH_ID_MAX,
};

enum st_asm330lhh_fifo_mode {
	ST_ASM330LHH_FIFO_BYPASS = 0x0,
	ST_ASM330LHH_FIFO_CONT = 0x6,
};

enum {
	ST_ASM330LHH_HW_FLUSH,
	ST_ASM330LHH_HW_OPERATIONAL,
};

/**
 * struct st_asm330lhh_sensor - ST IMU sensor instance
 * @id: Sensor identifier.
 * @hw: Pointer to instance of struct st_asm330lhh_hw.
 * @gain: Configured sensor sensitivity.
 * @odr: Output data rate of the sensor [Hz].
 * @watermark: Sensor watermark level.
 * @batch_mask: Sensor mask for FIFO batching register
 */
struct st_asm330lhh_sensor {
	enum st_asm330lhh_sensor_id id;
	struct st_asm330lhh_hw *hw;

	u32 gain;
	u16 odr;
	u32 offset;

	__le16 old_data;

	u8 std_samples;
	u8 std_level;

	u16 watermark;
	u8 batch_mask;
	u8 batch_addr;
};

/**
 * struct st_asm330lhh_hw - ST IMU MEMS hw instance
 * @dev: Pointer to instance of struct device (I2C or SPI).
 * @irq: Device interrupt line (I2C or SPI).
 * @lock: Mutex to protect read and write operations.
 * @fifo_lock: Mutex to prevent concurrent access to the hw FIFO.
 * @fifo_mode: FIFO operating mode supported by the device.
 * @state: hw operational state.
 * @enable_mask: Enabled sensor bitmask.
 * @ts_offset: Hw timestamp offset.
 * @hw_ts: Latest hw timestamp from the sensor.
 * @ts: Latest timestamp from irq handler.
 * @delta_ts: Delta time between two consecutive interrupts.
 * @iio_devs: Pointers to acc/gyro iio_dev instances.
 * @tf: Transfer function structure used by I/O operations.
 * @tb: Transfer buffers used by SPI I/O operations.
 */
struct st_asm330lhh_hw {
	struct device *dev;
	int irq;

	struct mutex lock;
	struct mutex fifo_lock;

	enum st_asm330lhh_fifo_mode fifo_mode;
	unsigned long state;
	u8 enable_mask;

	s64 ts_offset;
	s64 hw_ts;
	s64 delta_ts;
	s64 ts;
	s64 tsample;
	s64 hw_ts_old;
	s64 delta_hw_ts;

	/* Timestamp sample ODR */
	u16 odr;

	struct iio_dev *iio_devs[ST_ASM330LHH_ID_MAX];

	const struct st_asm330lhh_transfer_function *tf;
	struct st_asm330lhh_transfer_buffer tb;
};

extern const struct dev_pm_ops st_asm330lhh_pm_ops;

int st_asm330lhh_probe(struct device *dev, int irq,
		       const struct st_asm330lhh_transfer_function *tf_ops);
int st_asm330lhh_sensor_set_enable(struct st_asm330lhh_sensor *sensor,
				   bool enable);
int st_asm330lhh_fifo_setup(struct st_asm330lhh_hw *hw);
int st_asm330lhh_write_with_mask(struct st_asm330lhh_hw *hw, u8 addr, u8 mask,
				 u8 val);
int st_asm330lhh_get_odr_val(enum st_asm330lhh_sensor_id id, u16 odr, u8 *val);
ssize_t st_asm330lhh_flush_fifo(struct device *dev,
				struct device_attribute *attr,
				const char *buf, size_t size);
ssize_t st_asm330lhh_get_max_watermark(struct device *dev,
				       struct device_attribute *attr, char *buf);
ssize_t st_asm330lhh_get_watermark(struct device *dev,
				   struct device_attribute *attr, char *buf);
ssize_t st_asm330lhh_set_watermark(struct device *dev,
				   struct device_attribute *attr,
				   const char *buf, size_t size);
int st_asm330lhh_set_fifo_mode(struct st_asm330lhh_hw *hw,
			       enum st_asm330lhh_fifo_mode fifo_mode);
int st_asm330lhh_suspend_fifo(struct st_asm330lhh_hw *hw);
#endif /* ST_ASM330LHH_H */
+533 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading