/* sensor_mcp9808_trigger.c - Trigger support for MCP9808 */

/*
 * 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 <errno.h>
#include <nanokernel.h>
#include <i2c.h>
#include <misc/byteorder.h>
#include <misc/__assert.h>

#include "sensor_mcp9808.h"

static int mcp9808_reg_write(struct mcp9808_data *data, uint8_t reg, uint16_t val)
{
	uint16_t be_val = sys_cpu_to_be16(val);

	struct i2c_msg msgs[2] = {
		{
			.buf = &reg,
			.len = 1,
			.flags = I2C_MSG_WRITE | I2C_MSG_RESTART,
		},
		{
			.buf = (uint8_t *) &be_val,
			.len = 2,
			.flags = I2C_MSG_WRITE | I2C_MSG_STOP,
		},
	};

	return i2c_transfer(data->i2c_master, msgs, 2, data->i2c_slave_addr);
}

static int mcp9808_reg_update(struct mcp9808_data *data, uint8_t reg,
			      uint16_t mask, uint16_t val)
{
	uint16_t old_val, new_val;

	if (mcp9808_reg_read(data, reg, &old_val) < 0) {
		return -EIO;
	}

	new_val = old_val & ~mask;
	new_val |= val;

	if (new_val == old_val) {
		return 0;
	}

	return mcp9808_reg_write(data, reg, new_val);
}

int mcp9808_attr_set(struct device *dev, enum sensor_channel chan,
		     enum sensor_attribute attr,
		     const struct sensor_value *val)
{
	struct mcp9808_data *data = dev->driver_data;
	uint16_t reg_val = 0;
	uint8_t reg_addr;
	int32_t val2;

	__ASSERT_NO_MSG(chan == SENSOR_CHAN_TEMP);

	switch (val->type) {
	case SENSOR_VALUE_TYPE_INT_PLUS_MICRO:
		val2 = val->val2;
		while (val2 > 0) {
			reg_val += (1 << 2);
			val2 -= 250000;
		}
		/* Fall through. */
	case SENSOR_VALUE_TYPE_INT:
		reg_val |= val->val1 << 4;
		break;
	default:
		return -EINVAL;
	}

	switch (attr) {
	case SENSOR_ATTR_LOWER_THRESH:
		reg_addr = MCP9808_REG_LOWER_LIMIT;
		break;
	case SENSOR_ATTR_UPPER_THRESH:
		reg_addr = MCP9808_REG_UPPER_LIMIT;
		break;
	default:
		return -EINVAL;
	}

	return mcp9808_reg_write(data, reg_addr, reg_val);
}

int mcp9808_trigger_set(struct device *dev,
			const struct sensor_trigger *trig,
			sensor_trigger_handler_t handler)
{
	struct mcp9808_data *data = dev->driver_data;

	data->trig = *trig;
	data->trigger_handler = handler;

	return mcp9808_reg_update(data, MCP9808_REG_CONFIG, MCP9808_ALERT_CNT,
				  handler == NULL ? 0 : MCP9808_ALERT_CNT);
}

#ifdef CONFIG_MCP9808_TRIGGER_OWN_FIBER

static void mcp9808_gpio_cb(struct device *dev,
			    struct gpio_callback *cb, uint32_t pins)
{
	struct mcp9808_data *data =
		CONTAINER_OF(cb, struct mcp9808_data, gpio_cb);

	ARG_UNUSED(pins);

	nano_isr_sem_give(&data->sem);
}

static void mcp9808_fiber_main(int arg1, int arg2)
{
	struct device *dev = INT_TO_POINTER(arg1);
	struct mcp9808_data *data = dev->driver_data;

	ARG_UNUSED(arg2);

	while (1) {
		nano_fiber_sem_take(&data->sem, TICKS_UNLIMITED);
		data->trigger_handler(dev, &data->trig);
		mcp9808_reg_update(data, MCP9808_REG_CONFIG,
				   MCP9808_INT_CLEAR, MCP9808_INT_CLEAR);
	}
}

static char __stack mcp9808_fiber_stack[CONFIG_MCP9808_FIBER_STACK_SIZE];

#else /* CONFIG_MCP9808_TRIGGER_GLOBAL_FIBER */

static void mcp9808_gpio_cb(struct device *dev,
			    struct gpio_callback *cb, uint32_t pins)
{
	struct mcp9808_data *data =
		CONTAINER_OF(cb, struct mcp9808_data, gpio_cb);

	ARG_UNUSED(pins);

	nano_work_submit(&data->work);
}

static void mcp9808_gpio_fiber_cb(struct nano_work *work)
{
	struct mcp9808_data *data =
		CONTAINER_OF(work, struct mcp9808_data, work);
	struct device *dev = data->dev;

	data->trigger_handler(dev, &data->trig);
	mcp9808_reg_update(data, MCP9808_REG_CONFIG,
			   MCP9808_INT_CLEAR, MCP9808_INT_CLEAR);
}

#endif /* CONFIG_MCP9808_TRIGGER_GLOBAL_FIBER */

void mcp9808_setup_interrupt(struct device *dev)
{
	struct mcp9808_data *data = dev->driver_data;
	struct device *gpio;

	mcp9808_reg_update(data, MCP9808_REG_CONFIG, MCP9808_ALERT_INT,
			   MCP9808_ALERT_INT);
	mcp9808_reg_write(data, MCP9808_REG_CRITICAL, MCP9808_TEMP_MAX);
	mcp9808_reg_update(data, MCP9808_REG_CONFIG, MCP9808_INT_CLEAR,
			   MCP9808_INT_CLEAR);

#ifdef CONFIG_MCP9808_TRIGGER_OWN_FIBER
	nano_sem_init(&data->sem);

	fiber_fiber_start(mcp9808_fiber_stack,
			  CONFIG_MCP9808_FIBER_STACK_SIZE,
			  mcp9808_fiber_main, POINTER_TO_INT(dev), 0,
			  CONFIG_MCP9808_FIBER_PRIORITY, 0);
#else /* CONFIG_MCP9808_TRIGGER_GLOBAL_FIBER */
	data->work.handler = mcp9808_gpio_fiber_cb;
	data->dev = dev;
#endif

	gpio = device_get_binding(CONFIG_MCP9808_GPIO_CONTROLLER);
	gpio_pin_configure(gpio, CONFIG_MCP9808_GPIO_PIN,
			   GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE |
			   GPIO_INT_ACTIVE_LOW | GPIO_INT_DEBOUNCE);

	gpio_init_callback(&data->gpio_cb,
			   mcp9808_gpio_cb,
			   BIT(CONFIG_MCP9808_GPIO_PIN));

	gpio_add_callback(gpio, &data->gpio_cb);
	gpio_pin_enable_callback(gpio, CONFIG_MCP9808_GPIO_PIN);
}
