/*
 * 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];
	int rc;

	__ASSERT(chan == SENSOR_CHAN_ALL);

	gpio_pin_enable_callback(drv_data->gpio, CONFIG_HDC1008_GPIO_PIN_NUM);

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

	nano_sem_take(&drv_data->data_sem, TICKS_UNLIMITED);

	rc = i2c_read(drv_data->i2c, buf, 4, HDC1008_I2C_ADDRESS);
	if (rc != 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;
	int rc;

	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));

	rc = gpio_add_callback(drv_data->gpio, &drv_data->gpio_cb);
	if (rc != 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);
