/*
 * Copyright (c) 2018 Diego Sueiro
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <errno.h>
#include <i2c.h>
#include <misc/util.h>
#include <em_cmu.h>
#include <em_i2c.h>
#include <em_gpio.h>
#include <soc.h>

#define LOG_LEVEL CONFIG_I2C_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(i2c_gecko);

#include "i2c-priv.h"

#define DEV_CFG(dev) \
	((struct i2c_gecko_config * const)(dev)->config->config_info)
#define DEV_DATA(dev) \
	((struct i2c_gecko_data * const)(dev)->driver_data)
#define DEV_BASE(dev) \
	((I2C_TypeDef *)(DEV_CFG(dev))->base)

struct i2c_gecko_config {
	I2C_TypeDef *base;
	CMU_Clock_TypeDef clock;
	I2C_Init_TypeDef i2cInit;
	u32_t bitrate;
	struct soc_gpio_pin pin_sda;
	struct soc_gpio_pin pin_scl;
#ifdef CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION
	u8_t loc_sda;
	u8_t loc_scl;
#else
	u8_t loc;
#endif
};

struct i2c_gecko_data {
	struct k_sem device_sync_sem;
	u32_t dev_config;
};

void i2c_gecko_config_pins(struct device *dev,
			   const struct soc_gpio_pin *pin_sda,
			   const struct soc_gpio_pin *pin_scl)
{
	I2C_TypeDef *base = DEV_BASE(dev);
	struct i2c_gecko_config *config = DEV_CFG(dev);

	soc_gpio_configure(pin_scl);
	soc_gpio_configure(pin_sda);

#ifdef CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION
	base->ROUTEPEN = I2C_ROUTEPEN_SDAPEN | I2C_ROUTEPEN_SCLPEN;
	base->ROUTELOC0 = (config->loc_sda << _I2C_ROUTELOC0_SDALOC_SHIFT) |
			  (config->loc_scl << _I2C_ROUTELOC0_SCLLOC_SHIFT);
#else
	base->ROUTE = I2C_ROUTE_SDAPEN | I2C_ROUTE_SCLPEN | (config->loc << 8);
#endif
}

static int i2c_gecko_configure(struct device *dev, u32_t dev_config_raw)
{
	I2C_TypeDef *base = DEV_BASE(dev);
	struct i2c_gecko_config *config = DEV_CFG(dev);
	struct i2c_gecko_data *data = DEV_DATA(dev);
	u32_t baudrate;

	if (!(I2C_MODE_MASTER & dev_config_raw)) {
		return -EINVAL;
	}

	switch (I2C_SPEED_GET(dev_config_raw)) {
	case I2C_SPEED_STANDARD:
		baudrate = KHZ(100);
		break;
	case I2C_SPEED_FAST:
		baudrate = MHZ(1);
		break;
	default:
		return -EINVAL;
	}

	data->dev_config = dev_config_raw;
	config->i2cInit.freq = baudrate;

	I2C_Init(base, &config->i2cInit);

	return 0;
}

static int i2c_gecko_transfer(struct device *dev, struct i2c_msg *msgs,
			      u8_t num_msgs, u16_t addr)
{
	I2C_TypeDef *base = DEV_BASE(dev);
	struct i2c_gecko_data *data = DEV_DATA(dev);
	I2C_TransferSeq_TypeDef seq;
	I2C_TransferReturn_TypeDef ret = -EIO;
	u32_t timeout = 300000U;

	if (!num_msgs) {
		return 0;
	}

	seq.addr = addr << 1;

	do {
		seq.buf[0].data = msgs->buf;
		seq.buf[0].len	= msgs->len;

		if ((msgs->flags & I2C_MSG_RW_MASK) == I2C_MSG_READ) {
			seq.flags = I2C_FLAG_READ;
		} else {
			seq.flags = I2C_FLAG_WRITE;
			if (num_msgs > 1) {
				/* Next message */
				msgs++;
				num_msgs--;
				if ((msgs->flags & I2C_MSG_RW_MASK)
				    == I2C_MSG_READ) {
					seq.flags = I2C_FLAG_WRITE_READ;
				} else {
					seq.flags = I2C_FLAG_WRITE_WRITE;
				}
				seq.buf[1].data = msgs->buf;
				seq.buf[1].len	= msgs->len;
			}
		}

		if (data->dev_config & I2C_ADDR_10_BITS) {
			seq.flags |= I2C_FLAG_10BIT_ADDR;
		}

		/* Do a polled transfer */
		ret = I2C_TransferInit(base, &seq);
		while (ret == i2cTransferInProgress && timeout--) {
			ret = I2C_Transfer(base);
		}

		if (ret != i2cTransferDone) {
			goto finish;
		}

		/* Next message */
		msgs++;
		num_msgs--;
	} while (num_msgs);

finish:
	if (ret != i2cTransferDone) {
		ret = -EIO;
	}
	return ret;
}

static int i2c_gecko_init(struct device *dev)
{
	struct i2c_gecko_config *config = DEV_CFG(dev);
	u32_t bitrate_cfg;
	int error;

	CMU_ClockEnable(config->clock, true);

	i2c_gecko_config_pins(dev, &config->pin_sda, &config->pin_scl);

	bitrate_cfg = _i2c_map_dt_bitrate(config->bitrate);

	error = i2c_gecko_configure(dev, I2C_MODE_MASTER | bitrate_cfg);
	if (error) {
		return error;
	}

	return 0;
}

static const struct i2c_driver_api i2c_gecko_driver_api = {
	.configure = i2c_gecko_configure,
	.transfer = i2c_gecko_transfer,
};

#ifdef DT_SILABS_GECKO_I2C_0

#define PIN_I2C_0_SDA {DT_SILABS_GECKO_I2C_0_LOCATION_SDA_1, \
		DT_SILABS_GECKO_I2C_0_LOCATION_SDA_2, gpioModeWiredAnd, 1}
#define PIN_I2C_0_SCL {DT_SILABS_GECKO_I2C_0_LOCATION_SCL_1, \
		DT_SILABS_GECKO_I2C_0_LOCATION_SCL_2, gpioModeWiredAnd, 1}

static struct i2c_gecko_config i2c_gecko_config_0 = {
	.base = (I2C_TypeDef *)DT_SILABS_GECKO_I2C_0_BASE_ADDRESS,
	.clock = cmuClock_I2C0,
	.i2cInit = I2C_INIT_DEFAULT,
	.pin_sda = PIN_I2C_0_SDA,
	.pin_scl = PIN_I2C_0_SCL,
#ifdef CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION
	.loc_sda = DT_SILABS_GECKO_I2C_0_LOCATION_SDA_0,
	.loc_scl = DT_SILABS_GECKO_I2C_0_LOCATION_SCL_0,
#else
#if DT_SILABS_GECKO_I2C_0_LOCATION_SDA_0 \
	!= DT_SILABS_GECKO_I2C_0_LOCATION_SCL_0
#error I2C_0 DTS location-* properties must have identical value
#endif
	.loc = DT_SILABS_GECKO_I2C_0_LOCATION_SCL_0,
#endif
	.bitrate = DT_SILABS_GECKO_I2C_0_CLOCK_FREQUENCY,
};

static struct i2c_gecko_data i2c_gecko_data_0;

DEVICE_AND_API_INIT(i2c_gecko_0, DT_SILABS_GECKO_I2C_0_LABEL,
		    &i2c_gecko_init, &i2c_gecko_data_0, &i2c_gecko_config_0,
		    POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
		    &i2c_gecko_driver_api);
#endif /* DT_SILABS_GECKO_I2C_0 */

#ifdef DT_SILABS_GECKO_I2C_1

#define PIN_I2C_1_SDA {DT_SILABS_GECKO_I2C_1_LOCATION_SDA_1, \
		DT_SILABS_GECKO_I2C_1_LOCATION_SDA_2, gpioModeWiredAnd, 1}
#define PIN_I2C_1_SCL {DT_SILABS_GECKO_I2C_1_LOCATION_SCL_1, \
		DT_SILABS_GECKO_I2C_1_LOCATION_SCL_2, gpioModeWiredAnd, 1}

static struct i2c_gecko_config i2c_gecko_config_1 = {
	.base = (I2C_TypeDef *)DT_SILABS_GECKO_I2C_1_BASE_ADDRESS,
	.clock = cmuClock_I2C1,
	.i2cInit = I2C_INIT_DEFAULT,
	.pin_sda = PIN_I2C_1_SDA,
	.pin_scl = PIN_I2C_1_SCL,
#ifdef CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION
	.loc_sda = DT_SILABS_GECKO_I2C_1_LOCATION_SDA_0,
	.loc_scl = DT_SILABS_GECKO_I2C_1_LOCATION_SCL_0,
#else
#if DT_SILABS_GECKO_I2C_1_LOCATION_SDA_0 \
	!= DT_SILABS_GECKO_I2C_1_LOCATION_SCL_0
#error I2C_1 DTS location-* properties must have identical value
#endif
	.loc = DT_SILABS_GECKO_I2C_1_LOCATION_SCL_0,
#endif
	.bitrate = DT_SILABS_GECKO_I2C_1_CLOCK_FREQUENCY,
};

static struct i2c_gecko_data i2c_gecko_data_1;

DEVICE_AND_API_INIT(i2c_gecko_1, DT_SILABS_GECKO_I2C_1_LABEL,
		    &i2c_gecko_init, &i2c_gecko_data_1, &i2c_gecko_config_1,
		    POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
		    &i2c_gecko_driver_api);
#endif /* DT_SILABS_GECKO_I2C_1 */
