2010-06-16 14:46:09 +01:00
/*
2010-09-13 15:39:48 +08:00
* mrst_max3110 . c - spi uart protocol driver for Maxim 3110
2010-06-16 14:46:09 +01:00
*
2010-09-13 15:39:48 +08:00
* Copyright ( c ) 2008 - 2010 , Intel Corporation .
2010-06-16 14:46:09 +01:00
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms and conditions of the GNU General Public License ,
* version 2 , as published by the Free Software Foundation .
*
* This program is distributed in the hope it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License for
* more details .
*
* You should have received a copy of the GNU General Public License along with
* this program ; if not , write to the Free Software Foundation , Inc . ,
* 51 Franklin St - Fifth Floor , Boston , MA 02110 - 1301 USA .
*/
/*
* Note :
* 1. From Max3110 spec , the Rx FIFO has 8 words , while the Tx FIFO only has
* 1 word . If SPI master controller doesn ' t support sclk frequency change ,
* then the char need be sent out one by one with some delay
*
2011-06-23 20:01:55 +03:00
* 2. Currently only RX available interrupt is used , no need for waiting TXE
2010-06-16 14:46:09 +01:00
* interrupt for a low speed UART device
*/
2011-08-26 11:25:35 +01:00
# ifdef CONFIG_MAGIC_SYSRQ
# define SUPPORT_SYSRQ
# endif
2010-06-16 14:46:09 +01:00
# include <linux/module.h>
# include <linux/ioport.h>
2010-09-30 15:15:29 -07:00
# include <linux/irq.h>
2010-06-16 14:46:09 +01:00
# include <linux/init.h>
# include <linux/console.h>
# include <linux/tty.h>
# include <linux/tty_flip.h>
# include <linux/serial_core.h>
# include <linux/serial_reg.h>
# include <linux/kthread.h>
# include <linux/spi/spi.h>
# include "mrst_max3110.h"
# define PR_FMT "mrst_max3110: "
2010-06-17 11:02:15 +01:00
# define UART_TX_NEEDED 1
# define CON_TX_NEEDED 2
# define BIT_IRQ_PENDING 3
2010-06-16 14:46:09 +01:00
struct uart_max3110 {
struct uart_port port ;
struct spi_device * spi ;
2011-01-25 14:15:11 +00:00
char name [ SPI_NAME_SIZE ] ;
2010-06-16 14:46:09 +01:00
wait_queue_head_t wq ;
struct task_struct * main_thread ;
struct task_struct * read_thread ;
2011-04-08 19:49:08 -07:00
struct mutex thread_mutex ;
2010-06-16 14:46:09 +01:00
u32 baud ;
u16 cur_conf ;
u8 clock ;
u8 parity , word_7bits ;
2010-09-13 15:39:48 +08:00
u16 irq ;
2010-06-16 14:46:09 +01:00
2010-06-17 11:02:15 +01:00
unsigned long uart_flags ;
2010-06-16 14:46:09 +01:00
/* console related */
struct circ_buf con_xmit ;
} ;
/* global data structure, may need be removed */
2010-09-13 15:39:48 +08:00
static struct uart_max3110 * pmax ;
2011-08-26 11:25:35 +01:00
static int receive_chars ( struct uart_max3110 * max ,
unsigned short * str , int len ) ;
static int max3110_read_multi ( struct uart_max3110 * max ) ;
2010-09-13 15:39:48 +08:00
static void max3110_con_receive ( struct uart_max3110 * max ) ;
2010-06-16 14:46:09 +01:00
2010-09-13 15:39:48 +08:00
static int max3110_write_then_read ( struct uart_max3110 * max ,
const void * txbuf , void * rxbuf , unsigned len , int always_fast )
2010-06-16 14:46:09 +01:00
{
struct spi_device * spi = max - > spi ;
struct spi_message message ;
struct spi_transfer x ;
int ret ;
spi_message_init ( & message ) ;
memset ( & x , 0 , sizeof x ) ;
x . len = len ;
x . tx_buf = txbuf ;
x . rx_buf = rxbuf ;
spi_message_add_tail ( & x , & message ) ;
if ( always_fast )
2010-09-13 15:39:48 +08:00
x . speed_hz = spi - > max_speed_hz ;
2010-06-16 14:46:09 +01:00
else if ( max - > baud )
x . speed_hz = max - > baud ;
/* Do the i/o */
ret = spi_sync ( spi , & message ) ;
return ret ;
}
2010-09-13 15:39:48 +08:00
/* Write a 16b word to the device */
static int max3110_out ( struct uart_max3110 * max , const u16 out )
2010-06-16 14:46:09 +01:00
{
2010-09-13 15:39:48 +08:00
void * buf ;
u16 * obuf , * ibuf ;
2010-06-16 14:46:09 +01:00
int ret ;
2010-09-13 15:39:48 +08:00
buf = kzalloc ( 8 , GFP_KERNEL | GFP_DMA ) ;
if ( ! buf )
return - ENOMEM ;
obuf = buf ;
ibuf = buf + 4 ;
* obuf = out ;
ret = max3110_write_then_read ( max , obuf , ibuf , 2 , 1 ) ;
if ( ret ) {
pr_warning ( PR_FMT " %s(): get err msg %d when sending 0x%x \n " ,
__func__ , ret , out ) ;
goto exit ;
}
2010-06-16 14:46:09 +01:00
2011-08-26 11:25:35 +01:00
receive_chars ( max , ibuf , 1 ) ;
2010-06-16 14:46:09 +01:00
2010-09-13 15:39:48 +08:00
exit :
kfree ( buf ) ;
2010-06-16 14:46:09 +01:00
return ret ;
}
/*
* This is usually used to read data from SPIC RX FIFO , which doesn ' t
2010-09-13 15:39:48 +08:00
* need any delay like flushing character out .
*
* Return how many valide bytes are read back
2010-06-16 14:46:09 +01:00
*/
2011-08-26 11:25:35 +01:00
static int max3110_read_multi ( struct uart_max3110 * max )
2010-06-16 14:46:09 +01:00
{
2010-09-13 15:39:48 +08:00
void * buf ;
u16 * obuf , * ibuf ;
2011-08-26 11:25:35 +01:00
int ret , blen ;
2010-06-16 14:46:09 +01:00
2010-09-13 15:39:48 +08:00
blen = M3110_RX_FIFO_DEPTH * sizeof ( u16 ) ;
buf = kzalloc ( blen * 2 , GFP_KERNEL | GFP_DMA ) ;
if ( ! buf ) {
pr_warning ( PR_FMT " %s(): fail to alloc dma buffer \n " , __func__ ) ;
2010-06-16 14:46:09 +01:00
return 0 ;
}
2010-09-13 15:39:48 +08:00
/* tx/rx always have the same length */
obuf = buf ;
ibuf = buf + blen ;
2010-06-16 14:46:09 +01:00
2010-09-13 15:39:48 +08:00
if ( max3110_write_then_read ( max , obuf , ibuf , blen , 1 ) ) {
kfree ( buf ) ;
2010-06-16 14:46:09 +01:00
return 0 ;
2010-09-13 15:39:48 +08:00
}
2010-06-16 14:46:09 +01:00
2011-08-26 11:25:35 +01:00
ret = receive_chars ( max , ibuf , M3110_RX_FIFO_DEPTH ) ;
2010-06-16 14:46:09 +01:00
2010-09-13 15:39:48 +08:00
kfree ( buf ) ;
2011-08-26 11:25:35 +01:00
return ret ;
2010-06-16 14:46:09 +01:00
}
static void serial_m3110_con_putchar ( struct uart_port * port , int ch )
{
struct uart_max3110 * max =
container_of ( port , struct uart_max3110 , port ) ;
struct circ_buf * xmit = & max - > con_xmit ;
if ( uart_circ_chars_free ( xmit ) ) {
xmit - > buf [ xmit - > head ] = ( char ) ch ;
xmit - > head = ( xmit - > head + 1 ) & ( PAGE_SIZE - 1 ) ;
}
}
/*
* Print a string to the serial port trying not to disturb
* any possible real use of the port . . .
*
* The console_lock must be held when we get here .
*/
static void serial_m3110_con_write ( struct console * co ,
const char * s , unsigned int count )
{
if ( ! pmax )
return ;
uart_console_write ( & pmax - > port , s , count , serial_m3110_con_putchar ) ;
2010-09-13 15:39:48 +08:00
if ( ! test_and_set_bit ( CON_TX_NEEDED , & pmax - > uart_flags ) )
2011-08-26 11:24:49 +01:00
wake_up ( & pmax - > wq ) ;
2010-06-16 14:46:09 +01:00
}
static int __init
serial_m3110_con_setup ( struct console * co , char * options )
{
struct uart_max3110 * max = pmax ;
int baud = 115200 ;
int bits = 8 ;
int parity = ' n ' ;
int flow = ' n ' ;
pr_info ( PR_FMT " setting up console \n " ) ;
2010-09-13 15:39:48 +08:00
if ( co - > index = = - 1 )
co - > index = 0 ;
2010-06-16 14:46:09 +01:00
if ( ! max ) {
pr_err ( PR_FMT " pmax is NULL, return " ) ;
return - ENODEV ;
}
if ( options )
uart_parse_options ( options , & baud , & parity , & bits , & flow ) ;
return uart_set_options ( & max - > port , co , baud , parity , bits , flow ) ;
}
static struct tty_driver * serial_m3110_con_device ( struct console * co ,
int * index )
{
struct uart_driver * p = co - > data ;
* index = co - > index ;
return p - > tty_driver ;
}
static struct uart_driver serial_m3110_reg ;
static struct console serial_m3110_console = {
. name = " ttyS " ,
. write = serial_m3110_con_write ,
. device = serial_m3110_con_device ,
. setup = serial_m3110_con_setup ,
. flags = CON_PRINTBUFFER ,
. index = - 1 ,
. data = & serial_m3110_reg ,
} ;
static unsigned int serial_m3110_tx_empty ( struct uart_port * port )
{
return 1 ;
}
static void serial_m3110_stop_tx ( struct uart_port * port )
{
return ;
}
/* stop_rx will be called in spin_lock env */
static void serial_m3110_stop_rx ( struct uart_port * port )
{
return ;
}
# define WORDS_PER_XFER 128
2010-09-13 15:39:48 +08:00
static void send_circ_buf ( struct uart_max3110 * max ,
2010-06-16 14:46:09 +01:00
struct circ_buf * xmit )
{
2010-09-13 15:39:48 +08:00
void * buf ;
u16 * obuf , * ibuf ;
2011-08-26 11:25:35 +01:00
int i , len , blen , dma_size , left , ret = 0 ;
2010-09-13 15:39:48 +08:00
dma_size = WORDS_PER_XFER * sizeof ( u16 ) * 2 ;
buf = kzalloc ( dma_size , GFP_KERNEL | GFP_DMA ) ;
if ( ! buf )
return ;
obuf = buf ;
ibuf = buf + dma_size / 2 ;
2010-06-16 14:46:09 +01:00
while ( ! uart_circ_empty ( xmit ) ) {
left = uart_circ_chars_pending ( xmit ) ;
while ( left ) {
2010-09-13 15:39:48 +08:00
len = min ( left , WORDS_PER_XFER ) ;
blen = len * sizeof ( u16 ) ;
memset ( ibuf , 0 , blen ) ;
2010-06-16 14:46:09 +01:00
for ( i = 0 ; i < len ; i + + ) {
obuf [ i ] = ( u8 ) xmit - > buf [ xmit - > tail ] | WD_TAG ;
xmit - > tail = ( xmit - > tail + 1 ) &
( UART_XMIT_SIZE - 1 ) ;
}
2010-09-13 15:39:48 +08:00
/* Fail to send msg to console is not very critical */
2011-08-26 11:24:49 +01:00
2010-09-13 15:39:48 +08:00
ret = max3110_write_then_read ( max , obuf , ibuf , blen , 0 ) ;
if ( ret )
pr_warning ( PR_FMT " %s(): get err msg %d \n " ,
__func__ , ret ) ;
2010-06-16 14:46:09 +01:00
2011-08-26 11:25:35 +01:00
receive_chars ( max , ibuf , len ) ;
2010-06-16 14:46:09 +01:00
max - > port . icount . tx + = len ;
left - = len ;
}
}
2010-09-13 15:39:48 +08:00
kfree ( buf ) ;
2010-06-16 14:46:09 +01:00
}
static void transmit_char ( struct uart_max3110 * max )
{
struct uart_port * port = & max - > port ;
struct circ_buf * xmit = & port - > state - > xmit ;
if ( uart_circ_empty ( xmit ) | | uart_tx_stopped ( port ) )
return ;
send_circ_buf ( max , xmit ) ;
if ( uart_circ_chars_pending ( xmit ) < WAKEUP_CHARS )
uart_write_wakeup ( port ) ;
if ( uart_circ_empty ( xmit ) )
serial_m3110_stop_tx ( port ) ;
}
2010-09-13 15:39:48 +08:00
/*
* This will be called by uart_write ( ) and tty_write , can ' t
* go to sleep
*/
2010-06-16 14:46:09 +01:00
static void serial_m3110_start_tx ( struct uart_port * port )
{
struct uart_max3110 * max =
container_of ( port , struct uart_max3110 , port ) ;
2010-06-17 11:02:15 +01:00
if ( ! test_and_set_bit ( UART_TX_NEEDED , & max - > uart_flags ) )
2011-08-26 11:24:49 +01:00
wake_up ( & max - > wq ) ;
2010-06-16 14:46:09 +01:00
}
2011-08-26 11:25:35 +01:00
static int
receive_chars ( struct uart_max3110 * max , unsigned short * str , int len )
2010-06-16 14:46:09 +01:00
{
struct uart_port * port = & max - > port ;
2013-01-03 15:53:01 +01:00
struct tty_port * tport ;
2011-08-26 11:25:35 +01:00
char buf [ M3110_RX_FIFO_DEPTH ] ;
int r , w , usable ;
2010-06-16 14:46:09 +01:00
/* If uart is not opened, just return */
if ( ! port - > state )
2011-08-26 11:25:35 +01:00
return 0 ;
2010-06-16 14:46:09 +01:00
2013-01-03 15:53:01 +01:00
tport = & port - > state - > port ;
2010-06-16 14:46:09 +01:00
2011-08-26 11:25:35 +01:00
for ( r = 0 , w = 0 ; r < len ; r + + ) {
if ( str [ r ] & MAX3110_BREAK & &
uart_handle_break ( port ) )
continue ;
if ( str [ r ] & MAX3110_READ_DATA_AVAILABLE ) {
if ( uart_handle_sysrq_char ( port , str [ r ] & 0xff ) )
continue ;
buf [ w + + ] = str [ r ] & 0xff ;
}
}
2013-01-03 15:53:06 +01:00
if ( ! w )
2011-08-26 11:25:35 +01:00
return 0 ;
for ( r = 0 ; w ; r + = usable , w - = usable ) {
2013-01-03 15:53:01 +01:00
usable = tty_buffer_request_room ( tport , w ) ;
2010-06-16 14:46:09 +01:00
if ( usable ) {
2013-01-03 15:53:04 +01:00
tty_insert_flip_string ( tport , buf + r , usable ) ;
2010-06-16 14:46:09 +01:00
port - > icount . rx + = usable ;
}
}
2013-01-03 15:53:06 +01:00
tty_flip_buffer_push ( tport ) ;
2011-08-26 11:25:35 +01:00
return r ;
2010-06-16 14:46:09 +01:00
}
2010-09-13 15:39:48 +08:00
/*
* This routine will be used in read_thread or RX IRQ handling ,
* it will first do one round buffer read ( 8 words ) , if there is some
* valid RX data , will try to read 5 more rounds till all data
* is read out .
*
* Use stack space as data buffer to save some system load , and chose
* 504 Btyes as a threadhold to do a bulk push to upper tty layer when
* receiving bulk data , a much bigger buffer may cause stack overflow
*/
static void max3110_con_receive ( struct uart_max3110 * max )
2010-06-16 14:46:09 +01:00
{
2011-08-26 11:25:35 +01:00
int loop = 1 , num ;
2010-06-16 14:46:09 +01:00
do {
2011-08-26 11:25:35 +01:00
num = max3110_read_multi ( max ) ;
2010-06-16 14:46:09 +01:00
if ( num ) {
2010-09-13 15:39:48 +08:00
loop = 5 ;
2010-06-16 14:46:09 +01:00
}
} while ( - - loop ) ;
}
static int max3110_main_thread ( void * _max )
{
struct uart_max3110 * max = _max ;
wait_queue_head_t * wq = & max - > wq ;
int ret = 0 ;
struct circ_buf * xmit = & max - > con_xmit ;
pr_info ( PR_FMT " start main thread \n " ) ;
do {
2011-08-26 11:24:49 +01:00
wait_event_interruptible ( * wq ,
max - > uart_flags | | kthread_should_stop ( ) ) ;
2010-06-17 11:02:06 +01:00
mutex_lock ( & max - > thread_mutex ) ;
2010-06-16 14:46:09 +01:00
2010-06-17 11:02:15 +01:00
if ( test_and_clear_bit ( BIT_IRQ_PENDING , & max - > uart_flags ) )
2010-09-13 15:39:48 +08:00
max3110_con_receive ( max ) ;
2010-06-16 14:46:09 +01:00
/* first handle console output */
2010-06-17 11:02:15 +01:00
if ( test_and_clear_bit ( CON_TX_NEEDED , & max - > uart_flags ) )
2010-06-16 14:46:09 +01:00
send_circ_buf ( max , xmit ) ;
/* handle uart output */
2010-06-17 11:02:15 +01:00
if ( test_and_clear_bit ( UART_TX_NEEDED , & max - > uart_flags ) )
2010-06-16 14:46:09 +01:00
transmit_char ( max ) ;
2010-06-17 11:02:15 +01:00
2010-06-17 11:02:06 +01:00
mutex_unlock ( & max - > thread_mutex ) ;
2010-06-17 11:02:15 +01:00
2010-06-16 14:46:09 +01:00
} while ( ! kthread_should_stop ( ) ) ;
return ret ;
}
static irqreturn_t serial_m3110_irq ( int irq , void * dev_id )
{
struct uart_max3110 * max = dev_id ;
/* max3110's irq is a falling edge, not level triggered,
* so no need to disable the irq */
2011-08-26 11:24:49 +01:00
2010-06-17 11:02:15 +01:00
if ( ! test_and_set_bit ( BIT_IRQ_PENDING , & max - > uart_flags ) )
2011-08-26 11:24:49 +01:00
wake_up ( & max - > wq ) ;
2010-06-17 11:02:15 +01:00
2010-06-16 14:46:09 +01:00
return IRQ_HANDLED ;
}
2010-09-13 15:39:56 +08:00
2010-06-16 14:46:09 +01:00
/* if don't use RX IRQ, then need a thread to polling read */
static int max3110_read_thread ( void * _max )
{
struct uart_max3110 * max = _max ;
pr_info ( PR_FMT " start read thread \n " ) ;
do {
2010-09-13 15:39:48 +08:00
/*
* If can ' t acquire the mutex , it means the main thread
* is running which will also perform the rx job
*/
if ( mutex_trylock ( & max - > thread_mutex ) ) {
max3110_con_receive ( max ) ;
mutex_unlock ( & max - > thread_mutex ) ;
}
2010-06-16 14:46:09 +01:00
set_current_state ( TASK_INTERRUPTIBLE ) ;
schedule_timeout ( HZ / 20 ) ;
} while ( ! kthread_should_stop ( ) ) ;
return 0 ;
}
static int serial_m3110_startup ( struct uart_port * port )
{
struct uart_max3110 * max =
container_of ( port , struct uart_max3110 , port ) ;
u16 config = 0 ;
int ret = 0 ;
2010-09-13 15:39:48 +08:00
if ( port - > line ! = 0 ) {
2010-06-16 14:46:09 +01:00
pr_err ( PR_FMT " uart port startup failed \n " ) ;
2010-09-13 15:39:48 +08:00
return - 1 ;
}
2010-06-16 14:46:09 +01:00
2010-09-13 15:39:48 +08:00
/* Disable all IRQ and config it to 115200, 8n1 */
2010-06-16 14:46:09 +01:00
config = WC_TAG | WC_FIFO_ENABLE
| WC_1_STOPBITS
| WC_8BIT_WORD
| WC_BAUD_DR2 ;
/* as we use thread to handle tx/rx, need set low latency */
2013-01-03 15:53:05 +01:00
port - > state - > port . low_latency = 1 ;
2010-06-16 14:46:09 +01:00
2010-09-13 15:39:56 +08:00
if ( max - > irq ) {
max - > read_thread = NULL ;
ret = request_irq ( max - > irq , serial_m3110_irq ,
2010-06-16 14:46:09 +01:00
IRQ_TYPE_EDGE_FALLING , " max3110 " , max ) ;
2010-09-13 15:39:56 +08:00
if ( ret ) {
max - > irq = 0 ;
pr_err ( PR_FMT " unable to allocate IRQ, polling \n " ) ;
} else {
/* Enable RX IRQ only */
config | = WC_RXA_IRQ_ENABLE ;
}
}
2010-06-16 14:46:09 +01:00
2010-09-13 15:39:56 +08:00
if ( max - > irq = = 0 ) {
/* If IRQ is disabled, start a read thread for input data */
max - > read_thread =
kthread_run ( max3110_read_thread , max , " max3110_read " ) ;
if ( IS_ERR ( max - > read_thread ) ) {
ret = PTR_ERR ( max - > read_thread ) ;
max - > read_thread = NULL ;
pr_err ( PR_FMT " Can't create read thread! \n " ) ;
return ret ;
}
2010-09-13 15:39:48 +08:00
}
ret = max3110_out ( max , config ) ;
if ( ret ) {
2010-09-13 15:39:56 +08:00
if ( max - > irq )
free_irq ( max - > irq , max ) ;
if ( max - > read_thread )
kthread_stop ( max - > read_thread ) ;
2010-09-13 15:39:48 +08:00
max - > read_thread = NULL ;
return ret ;
}
2010-06-16 14:46:09 +01:00
max - > cur_conf = config ;
return 0 ;
}
static void serial_m3110_shutdown ( struct uart_port * port )
{
struct uart_max3110 * max =
container_of ( port , struct uart_max3110 , port ) ;
u16 config ;
if ( max - > read_thread ) {
kthread_stop ( max - > read_thread ) ;
max - > read_thread = NULL ;
}
2010-09-13 15:39:56 +08:00
if ( max - > irq )
free_irq ( max - > irq , max ) ;
2010-06-16 14:46:09 +01:00
/* Disable interrupts from this port */
config = WC_TAG | WC_SW_SHDI ;
max3110_out ( max , config ) ;
}
static void serial_m3110_release_port ( struct uart_port * port )
{
}
static int serial_m3110_request_port ( struct uart_port * port )
{
return 0 ;
}
static void serial_m3110_config_port ( struct uart_port * port , int flags )
{
2010-09-13 15:39:48 +08:00
port - > type = PORT_MAX3100 ;
2010-06-16 14:46:09 +01:00
}
static int
serial_m3110_verify_port ( struct uart_port * port , struct serial_struct * ser )
{
/* we don't want the core code to modify any port params */
return - EINVAL ;
}
static const char * serial_m3110_type ( struct uart_port * port )
{
struct uart_max3110 * max =
container_of ( port , struct uart_max3110 , port ) ;
return max - > name ;
}
static void
serial_m3110_set_termios ( struct uart_port * port , struct ktermios * termios ,
struct ktermios * old )
{
struct uart_max3110 * max =
container_of ( port , struct uart_max3110 , port ) ;
unsigned char cval ;
unsigned int baud , parity = 0 ;
int clk_div = - 1 ;
u16 new_conf = max - > cur_conf ;
switch ( termios - > c_cflag & CSIZE ) {
case CS7 :
cval = UART_LCR_WLEN7 ;
new_conf | = WC_7BIT_WORD ;
break ;
default :
2010-09-13 15:39:48 +08:00
/* We only support CS7 & CS8 */
termios - > c_cflag & = ~ CSIZE ;
termios - > c_cflag | = CS8 ;
2010-06-16 14:46:09 +01:00
case CS8 :
cval = UART_LCR_WLEN8 ;
new_conf | = WC_8BIT_WORD ;
break ;
}
baud = uart_get_baud_rate ( port , termios , old , 0 , 230400 ) ;
2010-09-13 15:39:48 +08:00
/* First calc the div for 1.8MHZ clock case */
2010-06-16 14:46:09 +01:00
switch ( baud ) {
case 300 :
clk_div = WC_BAUD_DR384 ;
break ;
case 600 :
clk_div = WC_BAUD_DR192 ;
break ;
case 1200 :
clk_div = WC_BAUD_DR96 ;
break ;
case 2400 :
clk_div = WC_BAUD_DR48 ;
break ;
case 4800 :
clk_div = WC_BAUD_DR24 ;
break ;
case 9600 :
clk_div = WC_BAUD_DR12 ;
break ;
case 19200 :
clk_div = WC_BAUD_DR6 ;
break ;
case 38400 :
clk_div = WC_BAUD_DR3 ;
break ;
case 57600 :
clk_div = WC_BAUD_DR2 ;
break ;
case 115200 :
clk_div = WC_BAUD_DR1 ;
break ;
case 230400 :
if ( max - > clock & MAX3110_HIGH_CLK )
break ;
default :
2010-09-13 15:39:48 +08:00
/* Pick the previous baud rate */
2010-06-16 14:46:09 +01:00
baud = max - > baud ;
clk_div = max - > cur_conf & WC_BAUD_DIV_MASK ;
tty_termios_encode_baud_rate ( termios , baud , baud ) ;
}
if ( max - > clock & MAX3110_HIGH_CLK ) {
clk_div + = 1 ;
2010-09-13 15:39:48 +08:00
/* High clk version max3110 doesn't support B300 */
if ( baud = = 300 ) {
2010-06-16 14:46:09 +01:00
baud = 600 ;
2010-09-13 15:39:48 +08:00
clk_div = WC_BAUD_DR384 ;
}
2010-06-16 14:46:09 +01:00
if ( baud = = 230400 )
clk_div = WC_BAUD_DR1 ;
tty_termios_encode_baud_rate ( termios , baud , baud ) ;
}
new_conf = ( new_conf & ~ WC_BAUD_DIV_MASK ) | clk_div ;
2010-09-13 15:39:48 +08:00
if ( unlikely ( termios - > c_cflag & CMSPAR ) )
termios - > c_cflag & = ~ CMSPAR ;
2010-06-16 14:46:09 +01:00
if ( termios - > c_cflag & CSTOPB )
new_conf | = WC_2_STOPBITS ;
else
new_conf & = ~ WC_2_STOPBITS ;
if ( termios - > c_cflag & PARENB ) {
new_conf | = WC_PARITY_ENABLE ;
parity | = UART_LCR_PARITY ;
} else
new_conf & = ~ WC_PARITY_ENABLE ;
if ( ! ( termios - > c_cflag & PARODD ) )
parity | = UART_LCR_EPAR ;
max - > parity = parity ;
uart_update_timeout ( port , termios - > c_cflag , baud ) ;
new_conf | = WC_TAG ;
if ( new_conf ! = max - > cur_conf ) {
2010-09-13 15:39:48 +08:00
if ( ! max3110_out ( max , new_conf ) ) {
max - > cur_conf = new_conf ;
max - > baud = baud ;
}
2010-06-16 14:46:09 +01:00
}
}
2010-09-13 15:39:48 +08:00
/* Don't handle hw handshaking */
2010-06-16 14:46:09 +01:00
static unsigned int serial_m3110_get_mctrl ( struct uart_port * port )
{
return TIOCM_DSR | TIOCM_CAR | TIOCM_DSR ;
}
static void serial_m3110_set_mctrl ( struct uart_port * port , unsigned int mctrl )
{
}
static void serial_m3110_break_ctl ( struct uart_port * port , int break_state )
{
}
static void serial_m3110_pm ( struct uart_port * port , unsigned int state ,
unsigned int oldstate )
{
}
static void serial_m3110_enable_ms ( struct uart_port * port )
{
}
struct uart_ops serial_m3110_ops = {
. tx_empty = serial_m3110_tx_empty ,
. set_mctrl = serial_m3110_set_mctrl ,
. get_mctrl = serial_m3110_get_mctrl ,
. stop_tx = serial_m3110_stop_tx ,
. start_tx = serial_m3110_start_tx ,
. stop_rx = serial_m3110_stop_rx ,
. enable_ms = serial_m3110_enable_ms ,
. break_ctl = serial_m3110_break_ctl ,
. startup = serial_m3110_startup ,
. shutdown = serial_m3110_shutdown ,
2010-09-13 15:39:48 +08:00
. set_termios = serial_m3110_set_termios ,
2010-06-16 14:46:09 +01:00
. pm = serial_m3110_pm ,
. type = serial_m3110_type ,
. release_port = serial_m3110_release_port ,
. request_port = serial_m3110_request_port ,
. config_port = serial_m3110_config_port ,
. verify_port = serial_m3110_verify_port ,
} ;
static struct uart_driver serial_m3110_reg = {
. owner = THIS_MODULE ,
. driver_name = " MRST serial " ,
. dev_name = " ttyS " ,
. major = TTY_MAJOR ,
. minor = 64 ,
. nr = 1 ,
2010-09-13 15:39:48 +08:00
. cons = & serial_m3110_console ,
2010-06-16 14:46:09 +01:00
} ;
2013-03-11 18:44:51 +01:00
# ifdef CONFIG_PM_SLEEP
static int serial_m3110_suspend ( struct device * dev )
2010-06-16 14:46:09 +01:00
{
2013-03-11 18:44:51 +01:00
struct spi_device * spi = to_spi_device ( dev ) ;
2010-09-13 15:39:48 +08:00
struct uart_max3110 * max = spi_get_drvdata ( spi ) ;
disable_irq ( max - > irq ) ;
uart_suspend_port ( & serial_m3110_reg , & max - > port ) ;
max3110_out ( max , max - > cur_conf | WC_SW_SHDI ) ;
2010-06-16 14:46:09 +01:00
return 0 ;
}
2013-03-11 18:44:51 +01:00
static int serial_m3110_resume ( struct device * dev )
2010-06-16 14:46:09 +01:00
{
2013-03-11 18:44:51 +01:00
struct spi_device * spi = to_spi_device ( dev ) ;
2010-09-13 15:39:48 +08:00
struct uart_max3110 * max = spi_get_drvdata ( spi ) ;
max3110_out ( max , max - > cur_conf ) ;
uart_resume_port ( & serial_m3110_reg , & max - > port ) ;
enable_irq ( max - > irq ) ;
2010-06-16 14:46:09 +01:00
return 0 ;
}
2013-03-11 18:44:51 +01:00
static SIMPLE_DEV_PM_OPS ( serial_m3110_pm_ops , serial_m3110_suspend ,
serial_m3110_resume ) ;
# define SERIAL_M3110_PM_OPS (&serial_m3110_pm_ops)
2010-09-13 15:39:48 +08:00
# else
2013-03-11 18:44:51 +01:00
# define SERIAL_M3110_PM_OPS NULL
2010-09-13 15:39:48 +08:00
# endif
2010-06-16 14:46:09 +01:00
2012-11-19 13:21:50 -05:00
static int serial_m3110_probe ( struct spi_device * spi )
2010-06-16 14:46:09 +01:00
{
struct uart_max3110 * max ;
2010-09-13 15:39:48 +08:00
void * buffer ;
2010-06-16 14:46:49 +01:00
u16 res ;
2010-09-13 15:39:48 +08:00
int ret = 0 ;
2010-06-16 14:46:09 +01:00
max = kzalloc ( sizeof ( * max ) , GFP_KERNEL ) ;
if ( ! max )
return - ENOMEM ;
2010-09-13 15:39:48 +08:00
/* Set spi info */
2010-06-16 14:46:09 +01:00
spi - > bits_per_word = 16 ;
max - > clock = MAX3110_HIGH_CLK ;
spi_setup ( spi ) ;
2010-09-13 15:39:48 +08:00
max - > port . type = PORT_MAX3100 ;
max - > port . fifosize = 2 ; /* Only have 16b buffer */
2010-06-16 14:46:09 +01:00
max - > port . ops = & serial_m3110_ops ;
max - > port . line = 0 ;
max - > port . dev = & spi - > dev ;
max - > port . uartclk = 115200 ;
max - > spi = spi ;
2010-09-13 15:39:48 +08:00
strcpy ( max - > name , spi - > modalias ) ;
2010-06-16 14:46:09 +01:00
max - > irq = ( u16 ) spi - > irq ;
2010-06-17 11:02:06 +01:00
mutex_init ( & max - > thread_mutex ) ;
2010-06-16 14:46:09 +01:00
max - > word_7bits = 0 ;
max - > parity = 0 ;
max - > baud = 0 ;
max - > cur_conf = 0 ;
2010-06-17 11:02:15 +01:00
max - > uart_flags = 0 ;
2010-06-16 14:46:49 +01:00
/* Check if reading configuration register returns something sane */
res = RC_TAG ;
ret = max3110_write_then_read ( max , ( u8 * ) & res , ( u8 * ) & res , 2 , 0 ) ;
if ( ret < 0 | | res = = 0 | | res = = 0xffff ) {
2011-06-23 13:38:36 +01:00
dev_dbg ( & spi - > dev , " MAX3111 deemed not present (conf reg %04x) " ,
2010-06-16 14:46:49 +01:00
res ) ;
ret = - ENODEV ;
goto err_get_page ;
}
2010-09-13 15:39:48 +08:00
buffer = ( void * ) __get_free_page ( GFP_KERNEL ) ;
2010-06-16 14:46:09 +01:00
if ( ! buffer ) {
ret = - ENOMEM ;
goto err_get_page ;
}
2010-09-13 15:39:48 +08:00
max - > con_xmit . buf = buffer ;
max - > con_xmit . head = 0 ;
max - > con_xmit . tail = 0 ;
2010-06-16 14:46:09 +01:00
2011-06-23 13:39:00 +01:00
init_waitqueue_head ( & max - > wq ) ;
2010-06-16 14:46:09 +01:00
max - > main_thread = kthread_run ( max3110_main_thread ,
max , " max3110_main " ) ;
if ( IS_ERR ( max - > main_thread ) ) {
ret = PTR_ERR ( max - > main_thread ) ;
goto err_kthread ;
}
2010-09-13 15:39:48 +08:00
spi_set_drvdata ( spi , max ) ;
2010-06-16 14:46:09 +01:00
pmax = max ;
2010-09-13 15:39:48 +08:00
/* Give membase a psudo value to pass serial_core's check */
2010-06-16 14:46:09 +01:00
max - > port . membase = ( void * ) 0xff110000 ;
uart_add_one_port ( & serial_m3110_reg , & max - > port ) ;
return 0 ;
err_kthread :
free_page ( ( unsigned long ) buffer ) ;
err_get_page :
kfree ( max ) ;
return ret ;
}
2012-11-19 13:26:18 -05:00
static int serial_m3110_remove ( struct spi_device * dev )
2010-06-16 14:46:09 +01:00
{
2010-09-13 15:39:48 +08:00
struct uart_max3110 * max = spi_get_drvdata ( dev ) ;
2010-06-16 14:46:09 +01:00
2010-09-13 15:39:48 +08:00
if ( ! max )
2010-06-16 14:46:09 +01:00
return 0 ;
uart_remove_one_port ( & serial_m3110_reg , & max - > port ) ;
free_page ( ( unsigned long ) max - > con_xmit . buf ) ;
if ( max - > main_thread )
kthread_stop ( max - > main_thread ) ;
kfree ( max ) ;
return 0 ;
}
static struct spi_driver uart_max3110_driver = {
. driver = {
. name = " spi_max3111 " ,
. owner = THIS_MODULE ,
2013-03-11 18:44:51 +01:00
. pm = SERIAL_M3110_PM_OPS ,
2010-06-16 14:46:09 +01:00
} ,
. probe = serial_m3110_probe ,
2012-11-19 13:21:34 -05:00
. remove = serial_m3110_remove ,
2010-06-16 14:46:09 +01:00
} ;
2010-09-13 15:39:48 +08:00
static int __init serial_m3110_init ( void )
2010-06-16 14:46:09 +01:00
{
int ret = 0 ;
ret = uart_register_driver ( & serial_m3110_reg ) ;
if ( ret )
return ret ;
ret = spi_register_driver ( & uart_max3110_driver ) ;
if ( ret )
uart_unregister_driver ( & serial_m3110_reg ) ;
return ret ;
}
2010-09-13 15:39:48 +08:00
static void __exit serial_m3110_exit ( void )
2010-06-16 14:46:09 +01:00
{
spi_unregister_driver ( & uart_max3110_driver ) ;
uart_unregister_driver ( & serial_m3110_reg ) ;
}
module_init ( serial_m3110_init ) ;
module_exit ( serial_m3110_exit ) ;
2010-09-13 15:39:48 +08:00
MODULE_LICENSE ( " GPL v2 " ) ;
2011-08-01 21:20:10 +08:00
MODULE_ALIAS ( " spi:max3110-uart " ) ;