/*
 * Copyright (c) 2016 Intel Corporation.
 * Copyright (c) 2013-2015 Wind River Systems, Inc.
 *
 * 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.
 */

/**
 * @brief Driver for UART on Atmel SAM3 family processor.
 *
 * Note that there is only one UART controller on the SoC.
 * It has two wires for RX and TX, and does not have other such as
 * CTS or RTS. Also, the RX and TX are connected directly to
 * bit shifters and there is no FIFO.
 *
 * For full serial function, use the USART controller.
 *
 * (used uart_stellaris.c as template)
 */

#include <nanokernel.h>
#include <arch/cpu.h>
#include <misc/__assert.h>
#include <board.h>
#include <init.h>
#include <uart.h>
#include <sections.h>

/* UART registers struct */
struct _uart {
	/* UART registers */
	uint32_t	cr;	/* 0x00 Control Register */
	uint32_t	mr;	/* 0x04 Mode Register */
	uint32_t	ier;	/* 0x08 Interrupt Enable Register */
	uint32_t	idr;	/* 0x0C Interrupt Disable Register */
	uint32_t	imr;	/* 0x10 Interrupt Mask Register */
	uint32_t	sr;	/* 0x14 Status Register */
	uint32_t	rhr;	/* 0x18 Receive Holding Register */
	uint32_t	thr;	/* 0x1C Transmit Holding Register */
	uint32_t	brgr;	/* 0x20 Baud Rate Generator Register */

	uint32_t	reserved[55];	/* 0x24 - 0xFF */

	/* PDC related registers */
	uint32_t	pdc_rpr;	/* 0x100 Receive Pointer Reg */
	uint32_t	pdc_rcr;	/* 0x104 Receive Counter Reg */
	uint32_t	pdc_tpr;	/* 0x108 Transmit Pointer Reg */
	uint32_t	pdc_tcr;	/* 0x10C Transmit Counter Reg */
	uint32_t	pdc_rnpr;	/* 0x110 Receive Next Pointer */
	uint32_t	pdc_rncr;	/* 0x114 Receive Next Counter */
	uint32_t	pdc_tnpr;	/* 0x118 Transmit Next Pointer */
	uint32_t	pdc_tncr;	/* 0x11C Transmit Next Counter */
	uint32_t	pdc_ptcr;	/* 0x120 Transfer Control Reg */
	uint32_t	pdc_ptsr;	/* 0x124 Transfer Status Reg */
};

/* Device data structure */
struct uart_sam3_dev_data_t {
	uint32_t baud_rate;	/* Baud rate */
};

/* convenience defines */
#define DEV_CFG(dev) \
	((struct uart_device_config * const)(dev)->config->config_info)
#define DEV_DATA(dev) \
	((struct uart_sam3_dev_data_t * const)(dev)->driver_data)
#define UART_STRUCT(dev) \
	((volatile struct _uart *)(DEV_CFG(dev))->base)

/* Registers */
#define UART_CR(dev)	(*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x00)))
#define UART_MR(dev)	(*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x04)))
#define UART_IER(dev)	(*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x08)))
#define UART_IDR(dev)	(*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x0C)))
#define UART_IMR(dev)	(*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x10)))
#define UART_SR(dev)	(*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x14)))
#define UART_RHR(dev)	(*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x18)))
#define UART_THR(dev)	(*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x1C)))
#define UART_BRGR(dev)	(*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x20)))

/* bits */
#define UART_CR_RSTRX	(1 << 2)
#define UART_CR_RSTTX	(1 << 3)
#define UART_CR_RXEN	(1 << 4)
#define UART_CR_RXDIS	(1 << 5)
#define UART_CR_TXEN	(1 << 6)
#define UART_CR_TXDIS	(1 << 7)
#define UART_CR_RSTSTA	(1 << 8)

#define UART_MR_PARTIY_MASK	(0x0E00)
#define UART_MR_PARITY_EVEN	(0 << 9)
#define UART_MR_PARITY_ODD	(1 << 9)
#define UART_MR_PARITY_SPACE	(2 << 9)
#define UART_MR_PARITY_MARK	(3 << 9)
#define UART_MR_PARITY_NO	(4 << 9)

#define UART_MR_CHMODE_MASK		(0xC000)
#define UART_MR_CHMODE_NORMAL		(0 << 14)
#define UART_MR_CHMODE_AUTOMATIC	(1 << 14)
#define UART_MR_CHMODE_LOCAL_LOOPBACK	(2 << 14)
#define UART_MR_CHMODE_REMOTE_LOOPBACK	(3 << 14)

#define UART_INT_RXRDY		(1 << 0)
#define UART_INT_TXRDY		(1 << 1)
#define UART_INT_ENDRX		(1 << 3)
#define UART_INT_ENDTX		(1 << 4)
#define UART_INT_OVRE		(1 << 5)
#define UART_INT_FRAME		(1 << 6)
#define UART_INT_PARE		(1 << 7)
#define UART_INT_TXEMPTY	(1 << 9)
#define UART_INT_TXBUFE		(1 << 11)
#define UART_INT_RXBUFF		(1 << 12)

#define UART_PDC_PTCR_RXTDIS	(1 << 1)
#define UART_PDC_PTCR_TXTDIS	(1 << 9)

static struct uart_driver_api uart_sam3_driver_api;

/**
 * @brief Set the baud rate
 *
 * This routine set the given baud rate for the UART.
 *
 * @param dev UART device struct
 * @param baudrate Baud rate
 * @param sys_clk_freq_hz System clock frequency in Hz
 *
 * @return N/A
 */
static void baudrate_set(struct device *dev,
			 uint32_t baudrate, uint32_t sys_clk_freq_hz)
{
	volatile struct _uart *uart = UART_STRUCT(dev);
	struct uart_device_config * const dev_cfg = DEV_CFG(dev);
	struct uart_sam3_dev_data_t * const dev_data = DEV_DATA(dev);
	uint32_t divisor; /* baud rate divisor */

	if ((baudrate != 0) && (dev_cfg->sys_clk_freq != 0)) {
		/* calculate baud rate divisor */
		divisor = (dev_cfg->sys_clk_freq / baudrate) >> 4;
		divisor &= 0xFFFF;

		uart->brgr = divisor;

		dev_data->baud_rate = baudrate;
	}
}

/**
 * @brief Initialize UART channel
 *
 * This routine is called to reset the chip in a quiescent state.
 * It is assumed that this function is called only once per UART.
 *
 * @param dev UART device struct
 *
 * @return 0
 */
static int uart_sam3_init(struct device *dev)
{
	volatile struct _uart *uart = UART_STRUCT(dev);

	/* Enable UART clock in PMC */
	__PMC->pcer0 = (1 << PID_UART);

	/* Detach pins PA8 and PA9 from PIO controller */
	__PIOA->pdr = (1 << 8) | (1 << 9);

	/* Disable PDC (DMA) */
	uart->pdc_ptcr = UART_PDC_PTCR_RXTDIS | UART_PDC_PTCR_TXTDIS;

	/* Reset and disable UART */
	uart->cr = UART_CR_RSTRX | UART_CR_RSTTX
		   | UART_CR_RXDIS | UART_CR_TXDIS | UART_CR_RSTSTA;

	/* No parity and normal mode */
	uart->mr = UART_MR_PARITY_NO | UART_MR_CHMODE_NORMAL;

	/* Set baud rate */
	baudrate_set(dev, DEV_DATA(dev)->baud_rate,
		     DEV_CFG(dev)->sys_clk_freq);

	/* Enable receiver and transmitter */
	uart->cr = UART_CR_RXEN | UART_CR_TXEN;

	return 0;
}

/**
 * @brief Poll the device for input.
 *
 * @param dev UART device struct
 * @param c Pointer to character
 *
 * @return 0 if a character arrived, -1 if the input buffer if empty.
 */

static int uart_sam3_poll_in(struct device *dev, unsigned char *c)
{
	volatile struct _uart *uart = UART_STRUCT(dev);

	if (uart->sr & UART_INT_RXRDY)
		return (-1);

	/* got a character */
	*c = (unsigned char)uart->rhr;

	return 0;
}

/**
 * @brief Output a character in polled mode.
 *
 * Checks if the transmitter is empty. If empty, a character is written to
 * the data register.
 *
 * @param dev UART device struct
 * @param c Character to send
 *
 * @return Sent character
 */
static unsigned char uart_sam3_poll_out(struct device *dev,
					     unsigned char c)
{
	volatile struct _uart *uart = UART_STRUCT(dev);

	/* Wait for transmitter to be ready */
	while (!(uart->sr & UART_INT_TXRDY))
		;

	/* send a character */
	uart->thr = (uint32_t)c;
	return c;
}

static struct uart_driver_api uart_sam3_driver_api = {
	.poll_in = uart_sam3_poll_in,
	.poll_out = uart_sam3_poll_out,
};

static struct uart_device_config uart_sam3_dev_cfg_0 = {
	.base = (uint8_t *)UART_ADDR,
	.sys_clk_freq = CONFIG_UART_ATMEL_SAM3_CLK_FREQ,
};

static struct uart_sam3_dev_data_t uart_sam3_dev_data_0 = {
	.baud_rate = CONFIG_UART_ATMEL_SAM3_BAUD_RATE,
};

DEVICE_AND_API_INIT(uart_sam3_0, CONFIG_UART_ATMEL_SAM3_NAME, &uart_sam3_init,
		    &uart_sam3_dev_data_0, &uart_sam3_dev_cfg_0,
		    PRIMARY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
		    &uart_sam3_driver_api);
