/*
 * STMicroelectronics pressures driver
 *
 * Copyright 2013 STMicroelectronics Inc.
 *
 * Denis Ciocca <denis.ciocca@st.com>
 *
 * Licensed under the GPL-2.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/mutex.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/trigger.h>
#include <linux/iio/buffer.h>
#include <asm/unaligned.h>

#include <linux/iio/common/st_sensors.h>
#include "st_pressure.h"

#define ST_PRESS_LSB_PER_MBAR			4096UL
#define ST_PRESS_KPASCAL_NANO_SCALE		(100000000UL / \
						 ST_PRESS_LSB_PER_MBAR)
#define ST_PRESS_NUMBER_DATA_CHANNELS		1

/* DEFAULT VALUE FOR SENSORS */
#define ST_PRESS_DEFAULT_OUT_XL_ADDR		0x28
#define ST_TEMP_DEFAULT_OUT_L_ADDR		0x2b

/* FULLSCALE */
#define ST_PRESS_FS_AVL_1260MB			1260

/* CUSTOM VALUES FOR SENSOR 1 */
#define ST_PRESS_1_WAI_EXP			0xbb
#define ST_PRESS_1_ODR_ADDR			0x20
#define ST_PRESS_1_ODR_MASK			0x70
#define ST_PRESS_1_ODR_AVL_1HZ_VAL		0x01
#define ST_PRESS_1_ODR_AVL_7HZ_VAL		0x05
#define ST_PRESS_1_ODR_AVL_13HZ_VAL		0x06
#define ST_PRESS_1_ODR_AVL_25HZ_VAL		0x07
#define ST_PRESS_1_PW_ADDR			0x20
#define ST_PRESS_1_PW_MASK			0x80
#define ST_PRESS_1_FS_ADDR			0x23
#define ST_PRESS_1_FS_MASK			0x30
#define ST_PRESS_1_FS_AVL_1260_VAL		0x00
#define ST_PRESS_1_FS_AVL_TEMP_GAIN		2083000
#define ST_PRESS_1_FS_AVL_1260_GAIN		ST_PRESS_KPASCAL_NANO_SCALE
#define ST_PRESS_1_BDU_ADDR			0x20
#define ST_PRESS_1_BDU_MASK			0x04
#define ST_PRESS_1_DRDY_IRQ_ADDR		0x22
#define ST_PRESS_1_DRDY_IRQ_MASK		0x04
#define ST_PRESS_1_MULTIREAD_BIT		true
#define ST_PRESS_1_TEMP_OFFSET			42500

static const struct iio_chan_spec st_press_channels[] = {
	ST_SENSORS_LSM_CHANNELS(IIO_PRESSURE,
			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
			ST_SENSORS_SCAN_X, 0, IIO_NO_MOD, 'u', IIO_LE, 24, 24,
			ST_PRESS_DEFAULT_OUT_XL_ADDR),
	ST_SENSORS_LSM_CHANNELS(IIO_TEMP,
			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) |
						BIT(IIO_CHAN_INFO_OFFSET),
			-1, 0, IIO_NO_MOD, 's', IIO_LE, 16, 16,
			ST_TEMP_DEFAULT_OUT_L_ADDR),
	IIO_CHAN_SOFT_TIMESTAMP(1)
};

static const struct st_sensors st_press_sensors[] = {
	{
		.wai = ST_PRESS_1_WAI_EXP,
		.sensors_supported = {
			[0] = LPS331AP_PRESS_DEV_NAME,
		},
		.ch = (struct iio_chan_spec *)st_press_channels,
		.odr = {
			.addr = ST_PRESS_1_ODR_ADDR,
			.mask = ST_PRESS_1_ODR_MASK,
			.odr_avl = {
				{ 1, ST_PRESS_1_ODR_AVL_1HZ_VAL, },
				{ 7, ST_PRESS_1_ODR_AVL_7HZ_VAL, },
				{ 13, ST_PRESS_1_ODR_AVL_13HZ_VAL, },
				{ 25, ST_PRESS_1_ODR_AVL_25HZ_VAL, },
			},
		},
		.pw = {
			.addr = ST_PRESS_1_PW_ADDR,
			.mask = ST_PRESS_1_PW_MASK,
			.value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
			.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
		},
		.fs = {
			.addr = ST_PRESS_1_FS_ADDR,
			.mask = ST_PRESS_1_FS_MASK,
			.fs_avl = {
				[0] = {
					.num = ST_PRESS_FS_AVL_1260MB,
					.value = ST_PRESS_1_FS_AVL_1260_VAL,
					.gain = ST_PRESS_1_FS_AVL_1260_GAIN,
					.gain2 = ST_PRESS_1_FS_AVL_TEMP_GAIN,
				},
			},
		},
		.bdu = {
			.addr = ST_PRESS_1_BDU_ADDR,
			.mask = ST_PRESS_1_BDU_MASK,
		},
		.drdy_irq = {
			.addr = ST_PRESS_1_DRDY_IRQ_ADDR,
			.mask = ST_PRESS_1_DRDY_IRQ_MASK,
		},
		.multi_read_bit = ST_PRESS_1_MULTIREAD_BIT,
		.bootime = 2,
	},
};

static int st_press_read_raw(struct iio_dev *indio_dev,
			struct iio_chan_spec const *ch, int *val,
							int *val2, long mask)
{
	int err;
	struct st_sensor_data *pdata = iio_priv(indio_dev);

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		err = st_sensors_read_info_raw(indio_dev, ch, val);
		if (err < 0)
			goto read_error;

		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SCALE:
		*val = 0;

		switch (ch->type) {
		case IIO_PRESSURE:
			*val2 = pdata->current_fullscale->gain;
			break;
		case IIO_TEMP:
			*val2 = pdata->current_fullscale->gain2;
			break;
		default:
			err = -EINVAL;
			goto read_error;
		}

		return IIO_VAL_INT_PLUS_NANO;
	case IIO_CHAN_INFO_OFFSET:
		switch (ch->type) {
		case IIO_TEMP:
			*val = 425;
			*val2 = 10;
			break;
		default:
			err = -EINVAL;
			goto read_error;
		}

		return IIO_VAL_FRACTIONAL;
	default:
		return -EINVAL;
	}

read_error:
	return err;
}

static ST_SENSOR_DEV_ATTR_SAMP_FREQ();
static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();

static struct attribute *st_press_attributes[] = {
	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
	&iio_dev_attr_sampling_frequency.dev_attr.attr,
	NULL,
};

static const struct attribute_group st_press_attribute_group = {
	.attrs = st_press_attributes,
};

static const struct iio_info press_info = {
	.driver_module = THIS_MODULE,
	.attrs = &st_press_attribute_group,
	.read_raw = &st_press_read_raw,
};

#ifdef CONFIG_IIO_TRIGGER
static const struct iio_trigger_ops st_press_trigger_ops = {
	.owner = THIS_MODULE,
	.set_trigger_state = ST_PRESS_TRIGGER_SET_STATE,
};
#define ST_PRESS_TRIGGER_OPS (&st_press_trigger_ops)
#else
#define ST_PRESS_TRIGGER_OPS NULL
#endif

int st_press_common_probe(struct iio_dev *indio_dev)
{
	int err;
	struct st_sensor_data *pdata = iio_priv(indio_dev);

	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->info = &press_info;

	err = st_sensors_check_device_support(indio_dev,
				ARRAY_SIZE(st_press_sensors), st_press_sensors);
	if (err < 0)
		goto st_press_common_probe_error;

	pdata->num_data_channels = ST_PRESS_NUMBER_DATA_CHANNELS;
	pdata->multiread_bit = pdata->sensor->multi_read_bit;
	indio_dev->channels = pdata->sensor->ch;
	indio_dev->num_channels = ARRAY_SIZE(st_press_channels);

	pdata->current_fullscale = (struct st_sensor_fullscale_avl *)
						&pdata->sensor->fs.fs_avl[0];
	pdata->odr = pdata->sensor->odr.odr_avl[0].hz;

	err = st_sensors_init_sensor(indio_dev);
	if (err < 0)
		goto st_press_common_probe_error;

	if (pdata->get_irq_data_ready(indio_dev) > 0) {
		err = st_press_allocate_ring(indio_dev);
		if (err < 0)
			goto st_press_common_probe_error;

		err = st_sensors_allocate_trigger(indio_dev,
							ST_PRESS_TRIGGER_OPS);
		if (err < 0)
			goto st_press_probe_trigger_error;
	}

	err = iio_device_register(indio_dev);
	if (err)
		goto st_press_device_register_error;

	return err;

st_press_device_register_error:
	if (pdata->get_irq_data_ready(indio_dev) > 0)
		st_sensors_deallocate_trigger(indio_dev);
st_press_probe_trigger_error:
	if (pdata->get_irq_data_ready(indio_dev) > 0)
		st_press_deallocate_ring(indio_dev);
st_press_common_probe_error:
	return err;
}
EXPORT_SYMBOL(st_press_common_probe);

void st_press_common_remove(struct iio_dev *indio_dev)
{
	struct st_sensor_data *pdata = iio_priv(indio_dev);

	iio_device_unregister(indio_dev);
	if (pdata->get_irq_data_ready(indio_dev) > 0) {
		st_sensors_deallocate_trigger(indio_dev);
		st_press_deallocate_ring(indio_dev);
	}
	iio_device_free(indio_dev);
}
EXPORT_SYMBOL(st_press_common_remove);

MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
MODULE_DESCRIPTION("STMicroelectronics pressures driver");
MODULE_LICENSE("GPL v2");
