1d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca/* 2d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca * STMicroelectronics accelerometers driver 3d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca * 4d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca * Copyright 2012-2013 STMicroelectronics Inc. 5d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca * 6d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca * Denis Ciocca <denis.ciocca@st.com> 7d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca * 8d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca * Licensed under the GPL-2. 9d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca */ 10d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca 11d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca#include <linux/module.h> 12d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca#include <linux/kernel.h> 13d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca#include <linux/slab.h> 14d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca#include <linux/stat.h> 15d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca#include <linux/interrupt.h> 16d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca#include <linux/i2c.h> 17d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca#include <linux/delay.h> 18d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca#include <linux/iio/iio.h> 19d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca#include <linux/iio/buffer.h> 20d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca#include <linux/iio/trigger_consumer.h> 21d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca#include <linux/iio/triggered_buffer.h> 22d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca 23d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca#include <linux/iio/common/st_sensors.h> 24d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca#include "st_accel.h" 25d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca 26d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Cioccaint st_accel_trig_set_state(struct iio_trigger *trig, bool state) 27d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca{ 281e9663c62b32f695af37fec4afc473b59f5ca9b4Lars-Peter Clausen struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); 29d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca 30d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca return st_sensors_set_dataready_irq(indio_dev, state); 31d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca} 32d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca 33d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Cioccastatic int st_accel_buffer_preenable(struct iio_dev *indio_dev) 34d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca{ 35d0894cab0f70e53c0b8d24680452a801497b2a4fLars-Peter Clausen return st_sensors_set_enable(indio_dev, true); 36d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca} 37d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca 38d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Cioccastatic int st_accel_buffer_postenable(struct iio_dev *indio_dev) 39d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca{ 40d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca int err; 41d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca struct st_sensor_data *adata = iio_priv(indio_dev); 42d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca 43d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca adata->buffer_data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); 44d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca if (adata->buffer_data == NULL) { 45d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca err = -ENOMEM; 46d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca goto allocate_memory_error; 47d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca } 48d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca 49d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca err = st_sensors_set_axis_enable(indio_dev, 50d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca (u8)indio_dev->active_scan_mask[0]); 51d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca if (err < 0) 52d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca goto st_accel_buffer_postenable_error; 53d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca 54d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca err = iio_triggered_buffer_postenable(indio_dev); 55d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca if (err < 0) 56d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca goto st_accel_buffer_postenable_error; 57d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca 58d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca return err; 59d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca 60d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Cioccast_accel_buffer_postenable_error: 61d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca kfree(adata->buffer_data); 62d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Cioccaallocate_memory_error: 63d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca return err; 64d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca} 65d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca 66d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Cioccastatic int st_accel_buffer_predisable(struct iio_dev *indio_dev) 67d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca{ 68d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca int err; 69d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca struct st_sensor_data *adata = iio_priv(indio_dev); 70d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca 71d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca err = iio_triggered_buffer_predisable(indio_dev); 72d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca if (err < 0) 73d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca goto st_accel_buffer_predisable_error; 74d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca 75d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca err = st_sensors_set_axis_enable(indio_dev, ST_SENSORS_ENABLE_ALL_AXIS); 76d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca if (err < 0) 77d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca goto st_accel_buffer_predisable_error; 78d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca 79d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca err = st_sensors_set_enable(indio_dev, false); 80d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca 81d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Cioccast_accel_buffer_predisable_error: 82d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca kfree(adata->buffer_data); 83d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca return err; 84d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca} 85d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca 86d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Cioccastatic const struct iio_buffer_setup_ops st_accel_buffer_setup_ops = { 87d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca .preenable = &st_accel_buffer_preenable, 88d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca .postenable = &st_accel_buffer_postenable, 89d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca .predisable = &st_accel_buffer_predisable, 90d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca}; 91d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca 92d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Cioccaint st_accel_allocate_ring(struct iio_dev *indio_dev) 93d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca{ 94d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, 95d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca &st_sensors_trigger_handler, &st_accel_buffer_setup_ops); 96d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca} 97d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca 98d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Cioccavoid st_accel_deallocate_ring(struct iio_dev *indio_dev) 99d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca{ 100d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca iio_triggered_buffer_cleanup(indio_dev); 101d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca} 102d62511689de5d34d3a07c43db1f46a234bb77b5fDenis Ciocca 103d62511689de5d34d3a07c43db1f46a234bb77b5fDenis CioccaMODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>"); 104d62511689de5d34d3a07c43db1f46a234bb77b5fDenis CioccaMODULE_DESCRIPTION("STMicroelectronics accelerometers buffer"); 105d62511689de5d34d3a07c43db1f46a234bb77b5fDenis CioccaMODULE_LICENSE("GPL v2"); 106