2009-12-11 20:41:07 -03:00
/*
Mantis PCI bridge driver
Copyright ( C ) Manu Abraham ( abraham . manu @ gmail . com )
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that 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 . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
2009-12-04 05:41:11 -03:00
# include <linux/kernel.h>
2009-12-04 05:39:57 -03:00
# include <linux/spinlock.h>
2011-06-16 11:01:34 +00:00
# include <asm/io.h>
2009-12-04 05:41:11 -03:00
# include <linux/signal.h>
# include <linux/sched.h>
# include <linux/interrupt.h>
2015-06-06 16:58:13 -03:00
# include <linux/pci.h>
2009-12-04 05:41:11 -03:00
2017-12-28 13:03:51 -05:00
# include <media/dmxdev.h>
# include <media/dvbdev.h>
# include <media/dvb_demux.h>
# include <media/dvb_frontend.h>
# include <media/dvb_net.h>
2009-12-04 05:41:11 -03:00
2009-12-04 05:39:57 -03:00
# include "mantis_common.h"
2009-12-04 05:41:11 -03:00
# include "mantis_reg.h"
# include "mantis_uart.h"
2015-06-06 16:58:13 -03:00
# include "mantis_input.h"
2009-12-04 05:39:57 -03:00
struct mantis_uart_params {
enum mantis_baud baud_rate ;
enum mantis_parity parity ;
} ;
2009-12-11 20:41:07 -03:00
static struct {
char string [ 7 ] ;
} rates [ 5 ] = {
{ " 9600 " } ,
{ " 19200 " } ,
{ " 38400 " } ,
{ " 57600 " } ,
{ " 115200 " }
} ;
static struct {
char string [ 5 ] ;
} parity [ 3 ] = {
{ " NONE " } ,
{ " ODD " } ,
{ " EVEN " }
} ;
2015-06-06 16:58:13 -03:00
static void mantis_uart_read ( struct mantis_pci * mantis )
2009-12-04 05:39:57 -03:00
{
struct mantis_hwconfig * config = mantis - > hwconfig ;
2015-06-06 16:58:13 -03:00
int i , scancode = 0 , err = 0 ;
2009-12-04 05:39:57 -03:00
/* get data */
2015-06-06 16:58:13 -03:00
dprintk ( MANTIS_DEBUG , 1 , " UART Reading ... " ) ;
2009-12-04 05:39:57 -03:00
for ( i = 0 ; i < ( config - > bytes + 1 ) ; i + + ) {
2015-06-06 16:58:13 -03:00
int data = mmread ( MANTIS_UART_RXD ) ;
2015-06-10 12:06:34 -03:00
2015-06-06 16:58:13 -03:00
dprintk ( MANTIS_DEBUG , 0 , " <%02x> " , data ) ;
2009-12-04 05:39:57 -03:00
2015-06-06 16:58:13 -03:00
scancode = ( scancode < < 8 ) | ( data & 0x3f ) ;
err | = data ;
2009-12-04 05:39:57 -03:00
2015-06-06 16:58:13 -03:00
if ( data & ( 1 < < 7 ) )
2009-12-04 05:41:11 -03:00
dprintk ( MANTIS_ERROR , 1 , " UART framing error " ) ;
2015-06-06 16:58:13 -03:00
if ( data & ( 1 < < 6 ) )
2009-12-04 05:41:11 -03:00
dprintk ( MANTIS_ERROR , 1 , " UART parity error " ) ;
2009-12-04 05:39:57 -03:00
}
2015-06-06 16:58:13 -03:00
dprintk ( MANTIS_DEBUG , 0 , " \n " ) ;
2009-12-04 05:39:57 -03:00
2015-06-06 16:58:13 -03:00
if ( ( err & 0xC0 ) = = 0 )
mantis_input_process ( mantis , scancode ) ;
2009-12-04 05:39:57 -03:00
}
static void mantis_uart_work ( struct work_struct * work )
{
struct mantis_pci * mantis = container_of ( work , struct mantis_pci , uart_work ) ;
2015-06-06 16:58:13 -03:00
u32 stat ;
2018-04-12 08:28:33 -04:00
unsigned long timeout ;
2009-12-04 05:39:57 -03:00
2015-06-06 16:58:13 -03:00
stat = mmread ( MANTIS_UART_STAT ) ;
2009-12-04 05:39:57 -03:00
2015-06-06 16:58:13 -03:00
if ( stat & MANTIS_UART_RXFIFO_FULL )
dprintk ( MANTIS_ERROR , 1 , " RX Fifo FULL " ) ;
2009-12-04 05:39:57 -03:00
2015-06-06 16:58:13 -03:00
/*
2015-06-10 12:06:34 -03:00
* MANTIS_UART_RXFIFO_DATA is only set if at least
* config - > bytes + 1 bytes are in the FIFO .
2015-06-06 16:58:13 -03:00
*/
2018-04-12 08:28:33 -04:00
/* FIXME: is 10ms good enough ? */
timeout = jiffies + msecs_to_jiffies ( 10 ) ;
2015-06-06 16:58:13 -03:00
while ( stat & MANTIS_UART_RXFIFO_DATA ) {
mantis_uart_read ( mantis ) ;
stat = mmread ( MANTIS_UART_STAT ) ;
2018-04-12 08:28:33 -04:00
if ( ! time_is_after_jiffies ( timeout ) )
break ;
2015-06-06 16:58:13 -03:00
}
/* re-enable UART (RX) interrupt */
mantis_unmask_ints ( mantis , MANTIS_INT_IRQ1 ) ;
2009-12-04 05:39:57 -03:00
}
static int mantis_uart_setup ( struct mantis_pci * mantis ,
struct mantis_uart_params * params )
{
u32 reg ;
mmwrite ( ( mmread ( MANTIS_UART_CTL ) | ( params - > parity & 0x3 ) ) , MANTIS_UART_CTL ) ;
reg = mmread ( MANTIS_UART_BAUD ) ;
switch ( params - > baud_rate ) {
case MANTIS_BAUD_9600 :
reg | = 0xd8 ;
break ;
case MANTIS_BAUD_19200 :
reg | = 0x6c ;
break ;
case MANTIS_BAUD_38400 :
reg | = 0x36 ;
break ;
case MANTIS_BAUD_57600 :
reg | = 0x23 ;
break ;
case MANTIS_BAUD_115200 :
reg | = 0x11 ;
break ;
default :
return - EINVAL ;
}
mmwrite ( reg , MANTIS_UART_BAUD ) ;
return 0 ;
}
int mantis_uart_init ( struct mantis_pci * mantis )
{
struct mantis_hwconfig * config = mantis - > hwconfig ;
struct mantis_uart_params params ;
/* default parity: */
params . baud_rate = config - > baud_rate ;
params . parity = config - > parity ;
2009-12-11 20:41:07 -03:00
dprintk ( MANTIS_INFO , 1 , " Initializing UART @ %sbps parity:%s " ,
rates [ params . baud_rate ] . string ,
parity [ params . parity ] . string ) ;
2009-12-04 05:39:57 -03:00
INIT_WORK ( & mantis - > uart_work , mantis_uart_work ) ;
/* disable interrupt */
mmwrite ( mmread ( MANTIS_UART_CTL ) & 0xffef , MANTIS_UART_CTL ) ;
mantis_uart_setup ( mantis , & params ) ;
/* default 1 byte */
mmwrite ( ( mmread ( MANTIS_UART_BAUD ) | ( config - > bytes < < 8 ) ) , MANTIS_UART_BAUD ) ;
/* flush buffer */
mmwrite ( ( mmread ( MANTIS_UART_CTL ) | MANTIS_UART_RXFLUSH ) , MANTIS_UART_CTL ) ;
/* enable interrupt */
mmwrite ( mmread ( MANTIS_UART_CTL ) | MANTIS_UART_RXINT , MANTIS_UART_CTL ) ;
2015-06-06 16:58:13 -03:00
mantis_unmask_ints ( mantis , MANTIS_INT_IRQ1 ) ;
2009-12-04 05:39:57 -03:00
schedule_work ( & mantis - > uart_work ) ;
2011-03-30 22:57:33 -03:00
dprintk ( MANTIS_DEBUG , 1 , " UART successfully initialized " ) ;
2009-12-04 05:39:57 -03:00
return 0 ;
}
2009-12-04 05:41:11 -03:00
EXPORT_SYMBOL_GPL ( mantis_uart_init ) ;
2009-12-04 05:39:57 -03:00
void mantis_uart_exit ( struct mantis_pci * mantis )
{
/* disable interrupt */
2015-06-06 16:58:13 -03:00
mantis_mask_ints ( mantis , MANTIS_INT_IRQ1 ) ;
2009-12-04 05:39:57 -03:00
mmwrite ( mmread ( MANTIS_UART_CTL ) & 0xffef , MANTIS_UART_CTL ) ;
2012-08-20 14:51:24 -07:00
flush_work ( & mantis - > uart_work ) ;
2009-12-04 05:39:57 -03:00
}
2009-12-04 05:41:11 -03:00
EXPORT_SYMBOL_GPL ( mantis_uart_exit ) ;