/*
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <device.h>
#include <drivers/gpio.h>
#include <sys/util.h>
#include <kernel.h>
#include <drivers/sensor.h>

#include "bmc150_magn.h"

#include <logging/log.h>
LOG_MODULE_DECLARE(BMC150_MAGN, CONFIG_SENSOR_LOG_LEVEL);

static inline void setup_drdy(struct device *dev,
			      bool enable)
{
	struct bmc150_magn_data *data = dev->driver_data;
	const struct bmc150_magn_config *const cfg =
		dev->config_info;

	gpio_pin_interrupt_configure(data->gpio_drdy,
				     cfg->gpio_drdy_int_pin,
				     enable
				     ? GPIO_INT_EDGE_TO_ACTIVE
				     : GPIO_INT_DISABLE);
}


int bmc150_magn_trigger_set(struct device *dev,
			    const struct sensor_trigger *trig,
			    sensor_trigger_handler_t handler)
{
	struct bmc150_magn_data *data = dev->driver_data;
	const struct bmc150_magn_config * const config =
					dev->config_info;
	u8_t state;

#if defined(CONFIG_BMC150_MAGN_TRIGGER_DRDY)
	if (trig->type == SENSOR_TRIG_DATA_READY) {
		setup_drdy(dev, false);

		state = 0U;
		if (handler) {
			state = 1U;
		}

		data->handler_drdy = handler;
		data->trigger_drdy = *trig;

		if (i2c_reg_update_byte(data->i2c_master,
					config->i2c_slave_addr,
					BMC150_MAGN_REG_INT_DRDY,
					BMC150_MAGN_MASK_DRDY_EN,
					state << BMC150_MAGN_SHIFT_DRDY_EN)
					< 0) {
			LOG_DBG("failed to set DRDY interrupt");
			return -EIO;
		}

		setup_drdy(dev, true);
	}
#endif

	return 0;
}

static void bmc150_magn_gpio_drdy_callback(struct device *dev,
					   struct gpio_callback *cb,
					   u32_t pins)
{
	struct bmc150_magn_data *data =
		CONTAINER_OF(cb, struct bmc150_magn_data, gpio_cb);

	ARG_UNUSED(pins);

	setup_drdy(data->dev, false);

	k_sem_give(&data->sem);
}

static void bmc150_magn_thread_main(void *arg1, void *arg2, void *arg3)
{
	struct device *dev = (struct device *) arg1;
	struct bmc150_magn_data *data = dev->driver_data;
	const struct bmc150_magn_config *config = dev->config_info;
	u8_t reg_val;

	while (1) {
		k_sem_take(&data->sem, K_FOREVER);

		while (i2c_reg_read_byte(data->i2c_master,
					 config->i2c_slave_addr,
					 BMC150_MAGN_REG_INT_STATUS,
					 &reg_val) < 0) {
			LOG_DBG("failed to clear data ready interrupt");
		}

		if (data->handler_drdy) {
			data->handler_drdy(dev, &data->trigger_drdy);
		}

		setup_drdy(dev, true);
	}
}

static int bmc150_magn_set_drdy_polarity(struct device *dev, int state)
{
	struct bmc150_magn_data *data = dev->driver_data;
	const struct bmc150_magn_config *config = dev->config_info;

	if (state) {
		state = 1;
	}

	return i2c_reg_update_byte(data->i2c_master, config->i2c_slave_addr,
				   BMC150_MAGN_REG_INT_DRDY,
				   BMC150_MAGN_MASK_DRDY_DR_POLARITY,
				   state << BMC150_MAGN_SHIFT_DRDY_DR_POLARITY);
}

int bmc150_magn_init_interrupt(struct device *dev)
{
	const struct bmc150_magn_config * const config =
						dev->config_info;
	struct bmc150_magn_data *data = dev->driver_data;


#if defined(CONFIG_BMC150_MAGN_TRIGGER_DRDY)
	if (bmc150_magn_set_drdy_polarity(dev, 0) < 0) {
		LOG_DBG("failed to set DR polarity");
		return -EIO;
	}

	if (i2c_reg_update_byte(data->i2c_master, config->i2c_slave_addr,
				BMC150_MAGN_REG_INT_DRDY,
				BMC150_MAGN_MASK_DRDY_EN,
				0 << BMC150_MAGN_SHIFT_DRDY_EN) < 0) {
		LOG_DBG("failed to set data ready interrupt enabled bit");
		return -EIO;
	}
#endif

	data->handler_drdy = NULL;

	k_sem_init(&data->sem, 0, UINT_MAX);

	k_thread_create(&data->thread, data->thread_stack,
			CONFIG_BMC150_MAGN_TRIGGER_THREAD_STACK,
			bmc150_magn_thread_main, dev, NULL, NULL,
			K_PRIO_COOP(10), 0, K_NO_WAIT);

	data->gpio_drdy = device_get_binding(config->gpio_drdy_dev_name);
	if (!data->gpio_drdy) {
		LOG_DBG("gpio controller %s not found",
			    config->gpio_drdy_dev_name);
		return -EINVAL;
	}

	gpio_pin_configure(data->gpio_drdy, config->gpio_drdy_int_pin,
			   config->gpio_drdy_int_flags
			   | GPIO_INT_EDGE_TO_ACTIVE);

	gpio_init_callback(&data->gpio_cb,
			   bmc150_magn_gpio_drdy_callback,
			   BIT(config->gpio_drdy_int_pin));

	if (gpio_add_callback(data->gpio_drdy, &data->gpio_cb) < 0) {
		LOG_DBG("failed to set gpio callback");
		return -EIO;
	}

	data->dev = dev;

	return 0;
}
