/*
 * 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 "sensor_hdc1008.h"

#ifndef CONFIG_SENSOR_DEBUG
#define DBG(...) { ; }
#else
#include <misc/printk.h>
#define DBG printk
#endif /* CONFIG_SENSOR_DEBUG */


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)
{
	struct hdc1008_data *drv_data = dev->driver_data;
	uint8_t buf[4];
	int rc;

	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) {
		DBG("Failed to write address pointer\n");
		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) {
		DBG("Failed to read sample data\n");
		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_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_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;

	dev->driver_api = &hdc1008_driver_api;

	drv_data->i2c = device_get_binding(CONFIG_HDC1008_I2C_MASTER_DEV_NAME);
	if (drv_data->i2c == NULL) {
		DBG("Failed to get pointer to %s device!\n",
		    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) {
		DBG("Failed to get pointer to %s device\n",
		    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) {
		DBG("Failed to set GPIO callback\n");
		return -EIO;
	}

	return 0;
}

struct hdc1008_data hdc1008_data;

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