/*
 * 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 <device.h>
#include <i2c.h>
#include <gpio.h>
#include <nanokernel.h>
#include <sensor.h>
#include <misc/util.h>
#include <misc/__assert.h>

#include "sensor_hdc1008.h"

static void hdc1008_gpio_callback(struct device *dev,
				  struct gpio_callback *cb, uint32_t pins)
{
	struct hdc1008_data *drv_data =
		CONTAINER_OF(cb, struct hdc1008_data, gpio_cb);

	ARG_UNUSED(pins);

	gpio_pin_disable_callback(dev, CONFIG_HDC1008_GPIO_PIN_NUM);
	nano_sem_give(&drv_data->data_sem);
}

static int hdc1008_sample_fetch(struct device *dev, enum sensor_channel chan)
{
	struct hdc1008_data *drv_data = dev->driver_data;
	uint8_t buf[4];

	__ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL);

	gpio_pin_enable_callback(drv_data->gpio, CONFIG_HDC1008_GPIO_PIN_NUM);

	buf[0] = HDC1008_REG_TEMP;
	if (i2c_write(drv_data->i2c, buf, 1, HDC1008_I2C_ADDRESS) < 0) {
		SYS_LOG_DBG("Failed to write address pointer");
		return -EIO;
	}

	nano_sem_take(&drv_data->data_sem, TICKS_UNLIMITED);

	if (i2c_read(drv_data->i2c, buf, 4, HDC1008_I2C_ADDRESS) < 0) {
		SYS_LOG_DBG("Failed to read sample data");
		return -EIO;
	}

	drv_data->t_sample = (buf[0] << 8) + buf[1];
	drv_data->rh_sample = (buf[2] << 8) + buf[3];

	return 0;
}


static int hdc1008_channel_get(struct device *dev,
			       enum sensor_channel chan,
			       struct sensor_value *val)
{
	struct hdc1008_data *drv_data = dev->driver_data;
	uint64_t tmp;

	/*
	 * See datasheet "Temperature Register" and "Humidity
	 * Register" sections for more details on processing
	 * sample data.
	 */
	if (chan == SENSOR_CHAN_TEMP) {
		/* val = -40 + 165 * sample / 2^16 */
		tmp = 165 * (uint64_t)drv_data->t_sample;
		val->type = SENSOR_VALUE_TYPE_INT_PLUS_MICRO;
		val->val1 = (int32_t)(tmp >> 16) - 40;
		val->val2 = (1000000 * (tmp & 0xFFFF)) >> 16;
	} else if (chan == SENSOR_CHAN_HUMIDITY) {
		/* val = 100000 * sample / 2^16 */
		tmp = 100000 * (uint64_t)drv_data->rh_sample;
		val->type = SENSOR_VALUE_TYPE_INT_PLUS_MICRO;
		val->val1 = tmp >> 16;
		val->val2 = (1000000 * (tmp & 0xFFFF)) >> 16;
	} else {
		return -ENOTSUP;
	}

	return 0;
}

static struct sensor_driver_api hdc1008_driver_api = {
	.sample_fetch = hdc1008_sample_fetch,
	.channel_get = hdc1008_channel_get,
};

int hdc1008_init(struct device *dev)
{
	struct hdc1008_data *drv_data = dev->driver_data;

	drv_data->i2c = device_get_binding(CONFIG_HDC1008_I2C_MASTER_DEV_NAME);
	if (drv_data->i2c == NULL) {
		SYS_LOG_DBG("Failed to get pointer to %s device!",
			    CONFIG_HDC1008_I2C_MASTER_DEV_NAME);
		return -EINVAL;
	}

	nano_sem_init(&drv_data->data_sem);

	/* setup data ready gpio interrupt */
	drv_data->gpio = device_get_binding(CONFIG_HDC1008_GPIO_DEV_NAME);
	if (drv_data->gpio == NULL) {
		SYS_LOG_DBG("Failed to get pointer to %s device",
			    CONFIG_HDC1008_GPIO_DEV_NAME);
		return -EINVAL;
	}

	gpio_pin_configure(drv_data->gpio, CONFIG_HDC1008_GPIO_PIN_NUM,
			   GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE |
			   GPIO_INT_ACTIVE_LOW | GPIO_INT_DEBOUNCE);

	gpio_init_callback(&drv_data->gpio_cb,
			   hdc1008_gpio_callback,
			   BIT(CONFIG_HDC1008_GPIO_PIN_NUM));

	if (gpio_add_callback(drv_data->gpio, &drv_data->gpio_cb) < 0) {
		SYS_LOG_DBG("Failed to set GPIO callback");
		return -EIO;
	}

	dev->driver_api = &hdc1008_driver_api;

	return 0;
}

struct hdc1008_data hdc1008_data;

DEVICE_INIT(hdc1008, CONFIG_HDC1008_NAME, hdc1008_init, &hdc1008_data,
	    NULL, SECONDARY, CONFIG_HDC1008_INIT_PRIORITY);
