/*
* VKIC Ltd.
* By David Tech
* DEMO Version :1.01 Data:2014-12-25
*
*
*
* 1. compiler warnings all changes
*/
#include<linux/init.h>
#include <linux/serial_core.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/freezer.h>
//#include <linux/spi/spi.h>
#include<linux/timer.h>
#include <linux/platform_device.h>
#include <linux/workqueue.h>
#include <linux/platform_device.h>
#include <asm/io.h>
#include "wk2xxx.h"
#include <linux/clk.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <linux/pinctrl/consumer.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>
#include <linux/clk.h>
#include <linux/cpufreq.h>
#include <../../../arch/arm/mach-imx/hardware.h>
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/poll.h>
#include <linux/fs.h>
MODULE_LICENSE("Dual BSD/GPL");
//#define SPI_BUFSIZ max(32,SMP_CACHE_BYTES)
//#define _DEBUG_WK2XXX
//#define _DEBUG_WK2XXX1
//#define _DEBUG_WK2XXX2
#define CONFIG_DEVFS_FS
#define WK2XXX_PAGE1 1
#define WK2XXX_PAGE0 0
#define WK2XXX_STATUS_PE 1
#define WK2XXX_STATUS_FE 2
#define WK2XXX_STATUS_BRK 4
#define WK2XXX_STATUS_OE 8
#define GPA1CON 0xE0200020
#define IOMUXC_SW_MUX_KEY_ROW1 0x20E0204
#define IOMUXC_SW_MUX_KEY_COL1 0x20E0200
#define IOMUXC_UART5_RX_DATA_SELECT_INPUT 0x20E0940
#define IOMUXC_SW_MUX_EIM_ADDR20 0x20E00e4
#define IOMUXC_SW_PAD_EIM_ADDR20 0x20E03F8
#define NUM_2_18 IMX_GPIO_NR(2,18)
#define NUM_1_9 IMX_GPIO_NR(1,9)
extern void tty_flip_buffer_push(struct tty_port *port);
static DEFINE_MUTEX(wk2xxxs_lock); /* race on probe */
static DEFINE_MUTEX(wk2xxs_work_lock); /* work on probe */
////////////gai//////
static volatile unsigned long *gpa1con_addr;
static volatile unsigned long *mux_rx_data_io_addr;
static volatile unsigned long *mux_tx_data_io_addr;
unsigned int irq_num = IRQ_WK2XXX;
static volatile unsigned long virt,phys,S5PV210_UART3;
static volatile unsigned long *UART5_URXD,*UART5_UTXD,*UART5_UCR1,*UART5_UCR2,*UART5_UCR3,*UART5_UCR4,*UART5_UFCR,*UART5_USR1,*UART5_USR2,*UART5_UESC,*UART5_UTIM,*UART5_UBIR,*UART5_UBMR,*UART5_UBRC,*UART5_ONEMS,*UART5_UTS,*UART5_UMCR;
unsigned long reg;
unsigned char __iomem *membase;
/* Register definitions */
#define URXD0 0x0 /* Receiver Register */
#define URTX0 0x40 /* Transmitter Register */
#define UCR1 0x80 /* Control Register 1 */
#define UCR2 0x84 /* Control Register 2 */
#define UCR3 0x88 /* Control Register 3 */
#define UCR4 0x8c /* Control Register 4 */
#define UFCR 0x90 /* FIFO Control Register */
#define USR1 0x94 /* Status Register 1 */
#define USR2 0x98 /* Status Register 2 */
#define UESC 0x9c /* Escape Character Register */
#define UTIM 0xa0 /* Escape Timer Register */
#define UBIR 0xa4 /* BRM Incremental Register */
#define UBMR 0xa8 /* BRM Modulator Register */
#define UBRC 0xac /* Baud Rate Count Register */
#define IMX21_ONEMS 0xb0 /* One Millisecond register */
#define IMX1_UTS 0xd0 /* UART Test Register on i.mx1 */
#define IMX21_UTS 0xb4 /* UART Test Register on all other i.mx*/
#define UCR1_UARTEN (1<<0) /* UART enabled */
#define UCR2_WS (1<<5) /* Word size */
#define UCR2_IRTS (1<<14) /* Ignore RTS pin */
#define UCR2_TXEN (1<<2) /* Transmitter enabled */
#define UCR2_RXEN (1<<1) /* Receiver enabled */
#define UCR2_SRST (1<<0) /* SW reset */
#define UCR3_ADNIMP (1<<7) /* Autobaud Detection Not Improved */
///////////////gai////////
struct clk *clk_ipg;
struct clk *clk_per;
struct wk2xxx_port
{
//struct timer_list mytimer;
struct uart_port port;//[NR_PORTS];
//struct spi_device *spi_wk;
spinlock_t conf_lock; /* shared data */
struct workqueue_struct *workqueue;
struct work_struct work;
int suspending;
void (*wk2xxx_hw_suspend) (int suspend);
int tx_done;
int force_end_work;
int irq;
int minor; /* minor number */
int tx_empty;
int tx_empty_flag;
//int start_tx;
int start_tx_flag;
int stop_tx_flag;
int stop_rx_flag;
int irq_flag;
int conf_flag;
int tx_empty_fail;
int start_tx_fail;
int stop_tx_fail;
int stop_rx_fail;
int irq_fail;
int conf_fail;
/*
int work_tx_empty_flag;
int work_start_tx_flag;
int work_stop_rx_flag;
int work_stop_tx_flag;
int work_irq_flag;
//int work_irq_fail;
int work_conf_flag;
*/
uint8_t new_lcr;
uint8_t new_scr;
/*set baud 0f register*/
uint8_t new_baud1;
uint8_t new_baud0;
uint8_t new_pres;
};
static struct wk2xxx_port wk2xxxs[NR_PORTS]; /* the chips */
///////////////////////////gai/////////////////////////////
struct resource *s5pv210uart_resource;
//***************************** 函数声明 ********************************
void wk_s5pv210uart_InitIO(void); //初始化IO端口的函数
//static void wk_s5pv210uart_stop_tx(struct uart_port *port);
//static int vkuart_request_port(struct uart_port *port);
//***************************** 函数定义 ********************************
/*
描述 : 初始化IO端口
参数 : 无
返回值 : 无
======================================================================
*/
void wk_s5pv210uart_InitIO(void)
{
int gpio_ret = gpio_request(NUM_2_18,"fsl_gpio");
//gpio_direction_output(NUM_2_18,0);
gpio_direction_input(NUM_2_18);
//gpio_set_value(NUM_2_18, 1);
irq_num = gpio_to_irq(NUM_2_18);
printk(KERN_INFO"gpio_ret=%d;irq_num=%d\n",gpio_ret,irq_num);
gpio_request(NUM_1_9,"fsl_gpio");
//gpio_direction_output(NUM_2_18,0);
gpio_direction_output(NUM_1_9,0);
// static volatile unsigned long *gpa1con_addr;
// static volatile unsigned long virt,phys;
////////////////////////////////////////
/*
if (!request_mem_region(IOMUXC_SW_MUX_KEY_ROW1, 4, "IOMUXC_SW_MUX_KEY_ROW1")){
printk (" IOMUXC_SW_MUX_KEY_ROW1 request mem fail.\n");
return -EINVAL;
}
if (!request_mem_region(IOMUXC_SW_MUX_KEY_COL1, 4, "IOMUXC_SW_MUX_KEY_COL1")){
printk (" IOMUXC_SW_MUX_KEY_COL1 request mem1 fail.\n");
return -EINVAL;
}
//#define GPA1CON 0xE0200020
mux_rx_data_io_addr=ioremap(IOMUXC_SW_MUX_KEY_ROW1,4);
mux_tx_data_io_addr=ioremap(IOMUXC_SW_MUX_KEY_COL1,4);
printk(KERN_INFO"rx_io_addr=%p\n",*mux_rx_data_io_addr);
*mux_rx_data_io_addr=0X4;
*mux_tx_data_io_addr=0x4;
*/
//printk(KERN_INFO"gpa1con_addr=%p\n",*mux_rx_data_io_addr);
//*gpbcon_addr |= (2<<8)|(2<<12);
#ifdef _DEBUG_WK2XXX1
//printk(KERN_INFO"*GPA1CON=%p\n",GPA1CON);
//printk(KERN_INFO"*gpa1con_addr=%p\n",mux_rx_data_io_addr);
//printk(KERN_INFO"gpa1con_addr=%p\n",*mux_rx_data_io_addr);
#endif
//s3c_gpio_cfgpin(S5PV210_GPH0(0), S3C_GPIO_SFN(0xf)); //GPxCON 4-bit为0xF一般对应于INT功能. GPH1(5)对应EXT_INT[13].
#define S5PV210_UART3 0x021F4000//0xE2900C00
/*
if (!request_mem_region(S5PV210_UART3, 0x4000, "S5PV210_UART3")){
printk (" S5PV210_UART3 request mem fail.\n");
//return -EINVAL;
}
virt=(unsigned long)ioremap(S5PV210_UART3,0x4000);//0xc09a8000;//(unsigned long)ioremap(S5PV210_UART3,0x4000);//0xc09b8000;//(unsigned long)ioremap(S5PV210_UART3,0x4000);
printk( " virt map = %x\n",virt);
*/
membase = ioremap(S5PV210_UART3,0x4000);
virt = membase;
UART5_URXD=(unsigned long*)virt;
UART5_UTXD =(unsigned long*)(virt+0x40);
UART5_UCR1 =(unsigned long*)(virt+0x80);
UART5_UCR2 =(unsigned long*)(virt+0x84);
UART5_UCR3 =(unsigned long*)(virt+0x88);
UART5_UCR4 =(unsigned long*)(virt+0x8C);
UART5_UFCR =(unsigned long*)(virt+0x90);
UART5_USR1 =(unsigned long*)(virt+0x94);
UART5_USR2 =(unsigned long*)(virt+0x98);
UART5_UESC =(unsigned long*)(virt+0x9C);