/* sensor_lps25hb.c - Driver for LPS25HB pressure and temperature sensor */

/*
 * Copyright (c) 2016 Intel Corporation
 *
 * 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.
 */

#include <sensor.h>
#include <kernel.h>
#include <device.h>
#include <init.h>
#include <misc/byteorder.h>
#include <misc/__assert.h>

#include "lps25hb.h"

static inline int lps25hb_power_ctrl(struct device *dev, uint8_t value)
{
	struct lps25hb_data *data = dev->driver_data;
	const struct lps25hb_config *config = dev->config->config_info;

	return i2c_reg_update_byte(data->i2c_master, config->i2c_slave_addr,
				   LPS25HB_REG_CTRL_REG1,
				   LPS25HB_MASK_CTRL_REG1_PD,
				   value << LPS25HB_SHIFT_CTRL_REG1_PD);
}

static inline int lps25hb_set_odr_raw(struct device *dev, uint8_t odr)
{
	struct lps25hb_data *data = dev->driver_data;
	const struct lps25hb_config *config = dev->config->config_info;

	return i2c_reg_update_byte(data->i2c_master, config->i2c_slave_addr,
				   LPS25HB_REG_CTRL_REG1,
				   LPS25HB_MASK_CTRL_REG1_ODR,
				   odr << LPS25HB_SHIFT_CTRL_REG1_ODR);
}

static int lps25hb_sample_fetch(struct device *dev,
				enum sensor_channel chan)
{
	struct lps25hb_data *data = dev->driver_data;
	const struct lps25hb_config *config = dev->config->config_info;
	uint8_t out[5];
	int offset;

	__ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL);

	for (offset = 0; offset < sizeof(out); ++offset) {
		if (i2c_reg_read_byte(data->i2c_master, config->i2c_slave_addr,
				      LPS25HB_REG_PRESS_OUT_XL + offset,
				      out + offset) < 0) {
			SYS_LOG_DBG("failed to read sample");
			return -EIO;
		}
	}

	data->sample_press = (int32_t)((uint32_t)(out[0]) |
					((uint32_t)(out[1]) << 8) |
					((uint32_t)(out[2]) << 16));
	data->sample_temp = (int16_t)((uint16_t)(out[3]) |
					((uint16_t)(out[4]) << 8));

	return 0;
}

static inline void lps25hb_press_convert(struct sensor_value *val,
					 int32_t raw_val)
{
	val->type = SENSOR_VALUE_TYPE_DOUBLE;
	val->dval = (double)(raw_val) / 40960.0;
}

static inline void lps25hb_temp_convert(struct sensor_value *val,
					int16_t raw_val)
{
	val->type = SENSOR_VALUE_TYPE_DOUBLE;
	val->dval = (double)(raw_val) / 480.0 + 42.5;
}

static int lps25hb_channel_get(struct device *dev,
			       enum sensor_channel chan,
			       struct sensor_value *val)
{
	struct lps25hb_data *data = dev->driver_data;

	if (chan == SENSOR_CHAN_PRESS) {
		lps25hb_press_convert(val, data->sample_press);
	} else if (chan == SENSOR_CHAN_TEMP) {
		lps25hb_temp_convert(val, data->sample_temp);
	} else {
		return -ENOTSUP;
	}

	return 0;
}

static const struct sensor_driver_api lps25hb_api_funcs = {
	.sample_fetch = lps25hb_sample_fetch,
	.channel_get = lps25hb_channel_get,
};

static int lps25hb_init_chip(struct device *dev)
{
	struct lps25hb_data *data = dev->driver_data;
	const struct lps25hb_config *config = dev->config->config_info;
	uint8_t chip_id;

	lps25hb_power_ctrl(dev, 0);
	sys_thread_busy_wait(50 * USEC_PER_MSEC);

	if (lps25hb_power_ctrl(dev, 1) < 0) {
		SYS_LOG_DBG("failed to power on device");
		return -EIO;
	}

	sys_thread_busy_wait(20 * USEC_PER_MSEC);

	if (i2c_reg_read_byte(data->i2c_master, config->i2c_slave_addr,
			      LPS25HB_REG_WHO_AM_I, &chip_id) < 0) {
		SYS_LOG_DBG("failed reading chip id");
		goto err_poweroff;
	}
	if (chip_id != LPS25HB_VAL_WHO_AM_I) {
		SYS_LOG_DBG("invalid chip id 0x%x", chip_id);
		goto err_poweroff;
	}

	SYS_LOG_DBG("chip id 0x%x", chip_id);

	if (lps25hb_set_odr_raw(dev, LPS25HB_DEFAULT_SAMPLING_RATE)
				< 0) {
		SYS_LOG_DBG("failed to set sampling rate");
		goto err_poweroff;
	}

	if (i2c_reg_update_byte(data->i2c_master, config->i2c_slave_addr,
				LPS25HB_REG_CTRL_REG1,
				LPS25HB_MASK_CTRL_REG1_BDU,
				(1 << LPS25HB_SHIFT_CTRL_REG1_BDU)) < 0) {
		SYS_LOG_DBG("failed to set BDU");
		goto err_poweroff;
	}

	return 0;

err_poweroff:
	lps25hb_power_ctrl(dev, 0);
	return -EIO;
}

int lps25hb_init(struct device *dev)
{
	const struct lps25hb_config * const config = dev->config->config_info;
	struct lps25hb_data *data = dev->driver_data;

	data->i2c_master = device_get_binding(config->i2c_master_dev_name);
	if (!data->i2c_master) {
		SYS_LOG_DBG("i2c master not found: %s",
			    config->i2c_master_dev_name);
		return -EINVAL;
	}

	if (lps25hb_init_chip(dev) < 0) {
		SYS_LOG_DBG("failed to initialize chip");
		return -EIO;
	}

	dev->driver_api = &lps25hb_api_funcs;

	return 0;
}

static const struct lps25hb_config lps25hb_config = {
	.i2c_master_dev_name = CONFIG_LPS25HB_I2C_MASTER_DEV_NAME,
	.i2c_slave_addr = CONFIG_LPS25HB_I2C_ADDR,
};

struct lps25hb_data lps25hb_data;

DEVICE_INIT(lps25hb, CONFIG_LPS25HB_DEV_NAME, lps25hb_init,
	    &lps25hb_data, &lps25hb_config, NANOKERNEL,
	    CONFIG_SENSOR_INIT_PRIORITY);
