/*
 * Copyright (c) 2015 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.
 */

/**
 * @file I2C driver for Quark SE Sensor Subsystem.
 *
 * The I2C on Quark SE Sensor Subsystem is similar to DesignWare I2C IP block,
 * but with a different register set and different workflow.
 */

#include <errno.h>
#include <stdint.h>
#include <stdbool.h>

#include <i2c.h>
#include <nanokernel.h>
#include <arch/cpu.h>

#include <sys_io.h>

#include <board.h>
#include <misc/util.h>

#include "i2c_quark_se_ss.h"
#include "i2c_quark_se_ss_registers.h"

#define SYS_LOG_LEVEL CONFIG_SYS_LOG_I2C_LEVEL
#include <misc/sys_log.h>

static inline uint32_t _i2c_qse_ss_memory_read(uint32_t base_addr,
					       uint32_t offset)
{
	return sys_read32(base_addr + offset);
}


static inline void _i2c_qse_ss_memory_write(uint32_t base_addr,
					    uint32_t offset, uint32_t val)
{
	sys_write32(val, base_addr + offset);
}

static inline uint32_t _i2c_qse_ss_reg_read(struct device *dev,
					    uint32_t reg)
{
	struct i2c_qse_ss_rom_config * const rom = dev->config->config_info;

	return _arc_v2_aux_reg_read(rom->base_address + reg);
}

static inline void _i2c_qse_ss_reg_write(struct device *dev,
					 uint32_t reg, uint32_t val)
{
	struct i2c_qse_ss_rom_config * const rom = dev->config->config_info;

	_arc_v2_aux_reg_write(rom->base_address + reg, val);
}

static inline void _i2c_qse_ss_reg_write_and(struct device *dev,
					     uint32_t reg, uint32_t mask)
{
	uint32_t r;

	r = _i2c_qse_ss_reg_read(dev, reg);
	r &= mask;
	_i2c_qse_ss_reg_write(dev, reg, r);
}

static inline void _i2c_qse_ss_reg_write_or(struct device *dev,
					    uint32_t reg, uint32_t mask)
{
	uint32_t r;

	r = _i2c_qse_ss_reg_read(dev, reg);
	r |= mask;
	_i2c_qse_ss_reg_write(dev, reg, r);
}

static inline int _i2c_qse_ss_reg_check_bit(struct device *dev,
					    uint32_t reg, uint32_t mask)
{
	return _i2c_qse_ss_reg_read(dev, reg) & mask;
}

/* Is the controller busy? */
static inline bool _i2c_qse_ss_is_busy(struct device *dev)
{
	return _i2c_qse_ss_reg_check_bit(dev, REG_STATUS, IC_STATUS_ACTIVITY);
}

/* Is RX FIFO not empty? */
static inline bool _i2c_qse_ss_is_rfne(struct device *dev)
{
	return _i2c_qse_ss_reg_check_bit(dev, REG_STATUS, IC_STATUS_RFNE);
}

/* Is TX FIFO not full? */
static inline bool _i2c_qse_ss_is_tfnf(struct device *dev)
{
	return _i2c_qse_ss_reg_check_bit(dev, REG_STATUS, IC_STATUS_TFNF);
}

/* Is TX FIFO empty? */
static inline bool _i2c_qse_ss_is_tfe(struct device *dev)
{
	return _i2c_qse_ss_reg_check_bit(dev, REG_STATUS, IC_STATUS_TFE);
}

/* Check a certain bit in the interrupt register */
static inline bool _i2c_qse_ss_check_irq(struct device *dev, uint32_t mask)
{
	return _i2c_qse_ss_reg_check_bit(dev, REG_INTR_STAT, mask);
}

static inline void _i2c_qse_ss_data_ask(struct device *dev)
{
	struct i2c_qse_ss_dev_config * const dw = dev->driver_data;
	uint32_t data;
	uint8_t tx_empty;
	int8_t rx_empty;
	uint8_t cnt;

	/* No more bytes to request, so command queue is no longer needed */
	if (dw->request_bytes == 0) {
		_i2c_qse_ss_reg_write_and(dev, REG_INTR_MASK,
					  ~(IC_INTR_TX_EMPTY));

		return;
	}

	/* How many bytes we can actually ask */
	rx_empty = I2C_QSE_SS_FIFO_DEPTH
		   - _i2c_qse_ss_reg_read(dev, REG_RXFLR);
	rx_empty -= dw->rx_pending;

	if (rx_empty <= 0) {
		/* RX FIFO expected to be full.
		 * So don't request any bytes, yet.
		 */
		return;
	}

	/* How many empty slots in TX FIFO (as command queue) */
	tx_empty = I2C_QSE_SS_FIFO_DEPTH
		   - _i2c_qse_ss_reg_read(dev, REG_TXFLR);

	/* Figure out how many bytes we can request */
	cnt = min(I2C_QSE_SS_FIFO_DEPTH, dw->request_bytes);
	cnt = min(min(tx_empty, rx_empty), cnt);

	while (cnt > 0) {
		/* Tell controller to get another byte */
		data = IC_DATA_CMD_CMD | IC_DATA_CMD_STROBE | IC_DATA_CMD_POP;

		/* Send RESTART if needed */
		if (dw->xfr_flags & I2C_MSG_RESTART) {
			data |= IC_DATA_CMD_RESTART;
			dw->xfr_flags &= ~(I2C_MSG_RESTART);
		}

		/* After receiving the last byte, send STOP if needed */
		if ((dw->xfr_flags & I2C_MSG_STOP)
		    && (dw->request_bytes == 1)) {
			data |= IC_DATA_CMD_STOP;
		}

		_i2c_qse_ss_reg_write(dev, REG_DATA_CMD, data);

		dw->rx_pending++;
		dw->request_bytes--;
		cnt--;
	}
}

static void _i2c_qse_ss_data_read(struct device *dev)
{
	struct i2c_qse_ss_dev_config * const dw = dev->driver_data;

	while (_i2c_qse_ss_is_rfne(dev) && (dw->xfr_len > 0)) {
		/* Need to write 0 to POP bit to
		 * "pop" one byte from RX FIFO.
		 */
		_i2c_qse_ss_reg_write(dev, REG_DATA_CMD,
				      IC_DATA_CMD_STROBE);

		dw->xfr_buf[0] = _i2c_qse_ss_reg_read(dev, REG_DATA_CMD)
				 & IC_DATA_CMD_DATA_MASK;

		dw->xfr_buf++;
		dw->xfr_len--;
		dw->rx_pending--;

		if (dw->xfr_len == 0) {
			break;
		}
	}

	/* Nothing to receive anymore */
	if (dw->xfr_len == 0) {
		dw->state &= ~I2C_QSE_SS_CMD_RECV;
		return;
	}
}

static int _i2c_qse_ss_data_send(struct device *dev)
{
	struct i2c_qse_ss_dev_config * const dw = dev->driver_data;
	uint32_t data;

	/* Nothing to send anymore, mask the interrupt */
	if (dw->xfr_len == 0) {
		_i2c_qse_ss_reg_write_and(dev, REG_INTR_MASK,
					  ~(IC_INTR_TX_EMPTY));

		dw->state &= ~I2C_QSE_SS_CMD_SEND;

		return 0;
	}

	while (_i2c_qse_ss_is_tfnf(dev) && (dw->xfr_len > 0)) {
		/* We have something to transmit to a specific host */
		data = dw->xfr_buf[0] | IC_DATA_CMD_STROBE | IC_DATA_CMD_POP;

		/* Send RESTART if needed */
		if (dw->xfr_flags & I2C_MSG_RESTART) {
			data |= IC_DATA_CMD_RESTART;
			dw->xfr_flags &= ~(I2C_MSG_RESTART);
		}

		/* Send STOP if needed */
		if ((dw->xfr_len == 1) && (dw->xfr_flags & I2C_MSG_STOP)) {
			data |= IC_DATA_CMD_STOP;
		}

		_i2c_qse_ss_reg_write(dev, REG_DATA_CMD, data);

		dw->xfr_len--;
		dw->xfr_buf++;

		if (_i2c_qse_ss_check_irq(dev, IC_INTR_TX_ABRT)) {
			return -EIO;
		}

	}

	return 0;
}

static inline void _i2c_qse_ss_transfer_complete(struct device *dev)
{
	struct i2c_qse_ss_dev_config * const dw = dev->driver_data;

	/* Disable and clear all pending interrupts */
	_i2c_qse_ss_reg_write(dev, REG_INTR_MASK, IC_INTR_MASK_ALL);
	_i2c_qse_ss_reg_write(dev, REG_INTR_CLR, IC_INTR_CLR_ALL);

	device_sync_call_complete(&dw->sync);
}


void i2c_qse_ss_isr(void *arg)
{
	struct device *dev = (struct device *)arg;
	struct i2c_qse_ss_dev_config * const dw = dev->driver_data;
	uint32_t ic_intr_stat;
	int ret = 0;

	/*
	 * Causes of an intterrupts:
	 *   - STOP condition is detected
	 *   - Transfer is aborted
	 *   - Transmit FIFO is empy
	 *   - Transmit FIFO is overflowing
	 *   - Receive FIFO is full
	 *   - Receive FIFO overflow
	 *   - Received FIFO underrun
	 */

	SYS_LOG_DBG("I2C_SS: interrupt received");

	ic_intr_stat = _i2c_qse_ss_reg_read(dev, REG_INTR_STAT);

	/* Error conditions */
	if ((IC_INTR_TX_ABRT | IC_INTR_TX_OVER |
	     IC_INTR_RX_OVER | IC_INTR_RX_UNDER) &
	    ic_intr_stat) {
		dw->state = I2C_QSE_SS_CMD_ERROR;
		goto done;
	}

	/* Check if the RX FIFO reached threshold */
	if (ic_intr_stat & IC_INTR_RX_FULL) {
		_i2c_qse_ss_data_read(dev);
		_i2c_qse_ss_reg_write(dev, REG_INTR_CLR, IC_INTR_RX_FULL);
	}

	/* Check if the TX FIFO is ready for commands.
	 * TX FIFO also serves as command queue where read requests
	 * are written to TX FIFO.
	 */
	if (ic_intr_stat & IC_INTR_TX_EMPTY) {
		if ((dw->xfr_flags & I2C_MSG_RW_MASK) == I2C_MSG_WRITE) {
			ret = _i2c_qse_ss_data_send(dev);
		} else {
			_i2c_qse_ss_data_ask(dev);
		}
		_i2c_qse_ss_reg_write(dev, REG_INTR_CLR, IC_INTR_TX_EMPTY);

		/* If STOP is not expected, finish processing this
		 * message if there is nothing left to do anymore.
		 * Or bail if there is any error.
		 */
		if (((dw->xfr_len == 0)
		     && !(dw->xfr_flags & I2C_MSG_STOP))
		    || (ret != 0)) {
			goto done;
		}
	}

	/* STOP detected */
	if (ic_intr_stat & IC_INTR_STOP_DET) {
		_i2c_qse_ss_reg_write(dev, REG_INTR_CLR, IC_INTR_STOP_DET);
		goto done;
	}

	return;

done:
	_i2c_qse_ss_transfer_complete(dev);
}

static int _i2c_qse_ss_setup(struct device *dev, uint16_t addr)
{
	struct i2c_qse_ss_dev_config * const dw = dev->driver_data;
	uint32_t ic_con;
	int rc = 0;

	/* Disable the device controller but enable clock
	 * so we can setup the controller.
	 */
	_i2c_qse_ss_reg_write_and(dev, REG_CON, ~(IC_CON_ENABLE));

	/* Disable and clear all pending interrupts */
	_i2c_qse_ss_reg_write(dev, REG_INTR_MASK, IC_INTR_MASK_ALL);
	_i2c_qse_ss_reg_write(dev, REG_INTR_CLR, IC_INTR_CLR_ALL);

	ic_con = _i2c_qse_ss_reg_read(dev, REG_CON);
	ic_con &= IC_CON_SPKLEN_MASK;
	ic_con |= IC_CON_RESTART_EN | IC_CON_CLK_ENA;

	/* Set addressing mode - (initialization = 7 bit) */
	if (dw->app_config.bits.use_10_bit_addr) {
		SYS_LOG_DBG("I2C: using 10-bit address");
		ic_con |= IC_CON_10BIT_ADDR;
	}

	/* Setup the clock frequency and speed mode */
	switch (dw->app_config.bits.speed) {
	case I2C_SPEED_STANDARD:
		SYS_LOG_DBG("I2C: speed set to STANDARD");
		_i2c_qse_ss_reg_write(dev, REG_SS_SCL_CNT,
				      (dw->hcnt << 16) | (dw->lcnt & 0xFFFF));
		ic_con |= I2C_QSE_SS_SPEED_STANDARD << IC_CON_SPEED_POS;

		break;
	case I2C_SPEED_FAST:
		/* fall through */
	case I2C_SPEED_FAST_PLUS:
		SYS_LOG_DBG("I2C: speed set to FAST or FAST_PLUS");
		_i2c_qse_ss_reg_write(dev, REG_FS_SCL_CNT,
				      (dw->hcnt << 16) | (dw->lcnt & 0xFFFF));
		ic_con |= I2C_QSE_SS_SPEED_FAST << IC_CON_SPEED_POS;

		break;
	default:
		SYS_LOG_DBG("I2C: invalid speed requested");
		/* TODO change */
		rc = -EINVAL;
		goto done;
	}

	/* Set the target address */
	ic_con |= addr << IC_CON_TAR_SAR_POS;

	_i2c_qse_ss_reg_write(dev, REG_CON, ic_con);

	/* Set TX/RX fifo threshold level.
	 *
	 * RX:
	 * Setting it to 1 so RX_FULL is set whenever there is
	 * data in RX FIFO. (actual value is reg value +1)
	 *
	 * TX:
	 * Setting it to 0 so TX_EMPTY is set only when
	 * TX FIFO is truly empty. So that we can let
	 * the controller do the transfers for longer period
	 * before we need to fill the FIFO again. This may
	 * cause some pauses during transfers, but this keeps
	 * the device from interrupting often.
	 *
	 * TODO: extend the threshold for multi-byte RX FIFO.
	 */
	_i2c_qse_ss_reg_write(dev, REG_TL, 0x00000000);

	/* SDA Hold time has to setup to minimal 2 according to spec. */
	_i2c_qse_ss_reg_write(dev, REG_SDA_CONFIG, 0x00020000);

done:
	return rc;
}

static int i2c_qse_ss_intr_transfer(struct device *dev,
				    struct i2c_msg *msgs, uint8_t num_msgs,
				    uint16_t slave_address)
{
	struct i2c_qse_ss_dev_config * const dw = dev->driver_data;
	struct i2c_msg *cur_msg = msgs;
	uint8_t msg_left = num_msgs;
	uint8_t pflags;
	int ret;

	/* Why bother processing no messages */
	if (!msgs || !num_msgs) {
		return -ENOTSUP;
	}

	/* First step, check if device is idle */
	if (_i2c_qse_ss_is_busy(dev) || (dw->state & I2C_QSE_SS_BUSY)) {
		return -EBUSY;
	}

	dw->state |= I2C_QSE_SS_BUSY;

	ret = _i2c_qse_ss_setup(dev, slave_address);
	if (ret) {
		dw->state = I2C_QSE_SS_STATE_READY;
		return ret;
	}

	/* To prevent RESTART for first message */
	dw->xfr_flags = msgs[0].flags;

	/* Enable controller */
	_i2c_qse_ss_reg_write_or(dev, REG_CON, IC_CON_ENABLE);

	/* Process all the messages */
	while (msg_left > 0) {
		pflags = dw->xfr_flags;

		dw->xfr_buf = cur_msg->buf;
		dw->xfr_len = cur_msg->len;
		dw->xfr_flags = cur_msg->flags;
		dw->rx_pending = 0;

		/* Need to RESTART if changing transfer direction */
		if ((pflags & I2C_MSG_RW_MASK)
		    != (dw->xfr_flags & I2C_MSG_RW_MASK)) {
			dw->xfr_flags |= I2C_MSG_RESTART;
		}

		/* Send STOP if this is the last message */
		if (msg_left == 1) {
			dw->xfr_flags |= I2C_MSG_STOP;
		}

		dw->state &= ~(I2C_QSE_SS_CMD_SEND | I2C_QSE_SS_CMD_RECV);

		if ((dw->xfr_flags & I2C_MSG_RW_MASK) == I2C_MSG_WRITE) {
			dw->state |= I2C_QSE_SS_CMD_SEND;
			dw->request_bytes = 0;
		} else {
			dw->state |= I2C_QSE_SS_CMD_RECV;
			dw->request_bytes = dw->xfr_len;
		}

		/* Enable interrupts to trigger ISR */
		_i2c_qse_ss_reg_write(dev, REG_INTR_MASK,
				      (IC_INTR_MASK_TX | IC_INTR_MASK_RX));

		/* Wait for transfer to be done */
		device_sync_call_wait(&dw->sync);
		if (dw->state & I2C_QSE_SS_CMD_ERROR) {
			ret = -EIO;
			break;
		}

		/* Something wrong if there is something left to do */
		if (dw->xfr_len > 0) {
			ret = -EIO;
			break;
		}

		cur_msg++;
		msg_left--;
	}

	dw->state = I2C_QSE_SS_STATE_READY;
	return ret;
}

static int i2c_qse_ss_runtime_configure(struct device *dev, uint32_t config)
{
	struct i2c_qse_ss_dev_config * const dw = dev->driver_data;
	uint32_t	value = 0;
	uint32_t	rc = 0;
	uint32_t	ic_con;
	uint32_t	spklen;

	dw->app_config.raw = config;

	ic_con = _i2c_qse_ss_reg_read(dev, REG_CON);

	spklen = (ic_con & IC_CON_SPKLEN_MASK) >> IC_CON_SPKLEN_POS;

	/* Make sure we have a supported speed for the DesignWare model */
	/* and have setup the clock frequency and speed mode */
	switch (dw->app_config.bits.speed) {
	case I2C_SPEED_STANDARD:
		/* Following the directions on DW spec page 59, IC_SS_SCL_LCNT
		 * must have register values larger than IC_FS_SPKLEN + 7
		 */
		if (I2C_STD_LCNT <= (spklen + 7)) {
			value = spklen + 8;
		} else {
			value = I2C_STD_LCNT;
		}

		dw->lcnt = value;

		/* Following the directions on DW spec page 59, IC_SS_SCL_HCNT
		 * must have register values larger than IC_FS_SPKLEN + 5
		 */
		if (I2C_STD_HCNT <= (spklen + 5)) {
			value = spklen + 6;
		} else {
			value = I2C_STD_HCNT;
		}

		dw->hcnt = value;
		break;
	case I2C_SPEED_FAST:
		/* fall through */
	case I2C_SPEED_FAST_PLUS:
		/*
		 * Following the directions on DW spec page 59, IC_FS_SCL_LCNT
		 * must have register values larger than IC_FS_SPKLEN + 7
		 */
		if (I2C_FS_LCNT <= (spklen + 7)) {
			value = spklen + 8;
		} else {
			value = I2C_FS_LCNT;
		}

		dw->lcnt = value;

		/*
		 * Following the directions on DW spec page 59, IC_FS_SCL_HCNT
		 * must have register values larger than IC_FS_SPKLEN + 5
		 */
		if (I2C_FS_HCNT <= (spklen + 5)) {
			value = spklen + 6;
		} else {
			value = I2C_FS_HCNT;
		}

		dw->hcnt = value;
		break;
	default:
		/* TODO change */
		rc = -EINVAL;
	}

	/*
	 * Clear any interrupts currently waiting in the controller
	 */
	_i2c_qse_ss_reg_write(dev, REG_INTR_CLR, IC_INTR_CLR_ALL);

	return rc;
}

static int i2c_qse_ss_suspend(struct device *dev)
{
	SYS_LOG_DBG("I2C_SS: suspend called - function not yet implemented");
	/* TODO - add this code */
	return 0;
}

static int i2c_qse_ss_resume(struct device *dev)
{
	SYS_LOG_DBG("I2C_SS: resume called - function not yet implemented");
	/* TODO - add this code */
	return 0;
}

static const struct i2c_driver_api api_funcs = {
	.configure = i2c_qse_ss_runtime_configure,
	.transfer = i2c_qse_ss_intr_transfer,
	.suspend = i2c_qse_ss_suspend,
	.resume = i2c_qse_ss_resume,
};

int i2c_qse_ss_initialize(struct device *dev)
{
	struct i2c_qse_ss_rom_config * const rom = dev->config->config_info;
	struct i2c_qse_ss_dev_config * const dw = dev->driver_data;

	if (rom->config_func) {
		rom->config_func(dev);
	}

	/* Enable clock for controller so we can talk to it */
	_i2c_qse_ss_reg_write_or(dev, REG_CON, IC_CON_CLK_ENA);

	device_sync_call_init(&dw->sync);

	if (i2c_qse_ss_runtime_configure(dev, dw->app_config.raw) != 0) {
		SYS_LOG_DBG("I2C_SS: Cannot set default configuration 0x%x",
		    dw->app_config.raw);
		return -EPERM;
	}

	dw->state = I2C_QSE_SS_STATE_READY;

	return 0;
}

#if CONFIG_I2C_0
#include <init.h>

static void _i2c_qse_ss_config_irq_0(struct device *port);

static const struct i2c_qse_ss_rom_config i2c_config_ss_0 = {
	.base_address = I2C_QUARK_SE_SS_0_BASE_ADDR,

	.config_func = _i2c_qse_ss_config_irq_0,
};

static struct i2c_qse_ss_dev_config i2c_ss_0_runtime = {
	.app_config.raw = CONFIG_I2C_0_DEFAULT_CFG,
};

DEVICE_AND_API_INIT(i2c_ss_0, CONFIG_I2C_0_NAME,
		    &i2c_qse_ss_initialize,
		    &i2c_ss_0_runtime, (void *)&i2c_config_ss_0,
		    SECONDARY, CONFIG_I2C_INIT_PRIORITY,
		    (void *)&api_funcs);

static void _i2c_qse_ss_config_irq_0(struct device *port)
{
	uint32_t mask = 0;

	/* Need to unmask the interrupts in System Control Subsystem (SCSS)
	 * so the interrupt controller can route these interrupts to
	 * the sensor subsystem.
	 */
	mask = _i2c_qse_ss_memory_read(SCSS_REGISTER_BASE, I2C_SS_0_ERR_MASK);
	mask &= INT_ENABLE_ARC;
	_i2c_qse_ss_memory_write(SCSS_REGISTER_BASE, I2C_SS_0_ERR_MASK, mask);

	mask = _i2c_qse_ss_memory_read(SCSS_REGISTER_BASE, I2C_SS_0_TX_MASK);
	mask &= INT_ENABLE_ARC;
	_i2c_qse_ss_memory_write(SCSS_REGISTER_BASE, I2C_SS_0_TX_MASK, mask);

	mask = _i2c_qse_ss_memory_read(SCSS_REGISTER_BASE, I2C_SS_0_RX_MASK);
	mask &= INT_ENABLE_ARC;
	_i2c_qse_ss_memory_write(SCSS_REGISTER_BASE, I2C_SS_0_RX_MASK, mask);

	mask = _i2c_qse_ss_memory_read(SCSS_REGISTER_BASE, I2C_SS_0_STOP_MASK);
	mask &= INT_ENABLE_ARC;
	_i2c_qse_ss_memory_write(SCSS_REGISTER_BASE, I2C_SS_0_STOP_MASK, mask);

	/* Connect the IRQs to ISR */
	IRQ_CONNECT(I2C_SS_0_ERR_VECTOR, 1, i2c_qse_ss_isr,
		    DEVICE_GET(i2c_ss_0), 0);
	IRQ_CONNECT(I2C_SS_0_RX_VECTOR, 1, i2c_qse_ss_isr,
		    DEVICE_GET(i2c_ss_0), 0);
	IRQ_CONNECT(I2C_SS_0_TX_VECTOR, 1, i2c_qse_ss_isr,
		    DEVICE_GET(i2c_ss_0), 0);
	IRQ_CONNECT(I2C_SS_0_STOP_VECTOR, 1, i2c_qse_ss_isr,
		    DEVICE_GET(i2c_ss_0), 0);

	irq_enable(I2C_SS_0_ERR_VECTOR);
	irq_enable(I2C_SS_0_RX_VECTOR);
	irq_enable(I2C_SS_0_TX_VECTOR);
	irq_enable(I2C_SS_0_STOP_VECTOR);
}

#endif /* CONFIG_I2C_0 */

#if CONFIG_I2C_1
#include <init.h>

static void _i2c_qse_ss_config_irq_1(struct device *port);

static const struct i2c_qse_ss_rom_config i2c_config_ss_1 = {
	.base_address = I2C_QUARK_SE_SS_1_BASE_ADDR,

	.config_func = _i2c_qse_ss_config_irq_1,
};

static struct i2c_qse_ss_dev_config i2c_qse_ss_1_runtime = {
	.app_config.raw = CONFIG_I2C_1_DEFAULT_CFG,
};

DEVICE_AND_API_INIT(i2c_ss_1, CONFIG_I2C_1_NAME,
		    &i2c_qse_ss_initialize,
		    &i2c_qse_ss_1_runtime, (void *)&i2c_config_ss_1,
		    SECONDARY, CONFIG_I2C_INIT_PRIORITY);
		    (void *)&api_funcs);


static void _i2c_qse_ss_config_irq_1(struct device *port)
{
	uint32_t mask = 0;

	/* Need to unmask the interrupts in System Control Subsystem (SCSS)
	 * so the interrupt controller can route these interrupts to
	 * the sensor subsystem.
	 */
	mask = _i2c_qse_ss_memory_read(SCSS_REGISTER_BASE, I2C_SS_1_ERR_MASK);
	mask &= INT_ENABLE_ARC;
	_i2c_qse_ss_memory_write(SCSS_REGISTER_BASE, I2C_SS_1_ERR_MASK, mask);

	mask = _i2c_qse_ss_memory_read(SCSS_REGISTER_BASE, I2C_SS_1_TX_MASK);
	mask &= INT_ENABLE_ARC;
	_i2c_qse_ss_memory_write(SCSS_REGISTER_BASE, I2C_SS_1_TX_MASK, mask);

	mask = _i2c_qse_ss_memory_read(SCSS_REGISTER_BASE, I2C_SS_1_RX_MASK);
	mask &= INT_ENABLE_ARC;
	_i2c_qse_ss_memory_write(SCSS_REGISTER_BASE, I2C_SS_1_RX_MASK, mask);

	mask = _i2c_qse_ss_memory_read(SCSS_REGISTER_BASE, I2C_SS_1_STOP_MASK);
	mask &= INT_ENABLE_ARC;
	_i2c_qse_ss_memory_write(SCSS_REGISTER_BASE, I2C_SS_1_STOP_MASK, mask);

	/* Connect the IRQs to ISR */
	IRQ_CONNECT(I2C_SS_1_ERR_VECTOR, 1, i2c_qse_ss_isr,
		    DEVICE_GET(i2c_ss_1), 0);
	IRQ_CONNECT(I2C_SS_1_RX_VECTOR, 1, i2c_qse_ss_isr,
		    DEVICE_GET(i2c_ss_1), 0);
	IRQ_CONNECT(I2C_SS_1_TX_VECTOR, 1, i2c_qse_ss_isr,
		    DEVICE_GET(i2c_ss_1), 0);
	IRQ_CONNECT(I2C_SS_1_STOP_VECTOR, 1, i2c_qse_ss_isr,
		    DEVICE_GET(i2c_ss_1), 0);

	irq_enable(I2C_SS_1_ERR_VECTOR);
	irq_enable(I2C_SS_1_RX_VECTOR);
	irq_enable(I2C_SS_1_TX_VECTOR);
	irq_enable(I2C_SS_1_STOP_VECTOR);
}

#endif /* CONFIG_I2C_1 */
