2012-01-16 12:24:08 +04:00
/*
* RadioTrack II driver
* Copyright 1998 Ben Pfaff
2006-04-08 23:06:16 +04:00
*
2005-04-17 02:20:36 +04:00
* Based on RadioTrack I / RadioReveal ( C ) 1997 M . Kirkwood
2008-10-27 21:13:47 +03:00
* Converted to new API by Alan Cox < alan @ lxorguk . ukuu . org . uk >
2005-04-17 02:20:36 +04:00
* Various bugfixes and enhancements by Russell Kroll < rkroll @ exploits . org >
*
2012-01-16 12:24:08 +04:00
* Converted to the radio - isa framework by Hans Verkuil < hans . verkuil @ cisco . com >
2006-08-08 16:10:02 +04:00
* Converted to V4L2 API by Mauro Carvalho Chehab < mchehab @ infradead . org >
2013-02-25 15:00:15 +04:00
*
* Fully tested with actual hardware and the v4l2 - compliance tool .
2005-04-17 02:20:36 +04:00
*/
# include <linux/module.h> /* Modules */
# include <linux/init.h> /* Initdata */
2005-09-13 12:25:15 +04:00
# include <linux/ioport.h> /* request_region */
2005-04-17 02:20:36 +04:00
# include <linux/delay.h> /* udelay */
2006-08-08 16:10:02 +04:00
# include <linux/videodev2.h> /* kernel radio structs */
2009-03-06 19:52:06 +03:00
# include <linux/mutex.h>
# include <linux/io.h> /* outb, outb_p */
2012-03-27 12:39:21 +04:00
# include <linux/slab.h>
2009-03-06 19:52:06 +03:00
# include <media/v4l2-device.h>
2008-07-20 15:12:02 +04:00
# include <media/v4l2-ioctl.h>
2012-01-16 12:24:08 +04:00
# include "radio-isa.h"
2005-04-17 02:20:36 +04:00
2009-03-06 19:52:06 +03:00
MODULE_AUTHOR ( " Ben Pfaff " ) ;
MODULE_DESCRIPTION ( " A driver for the RadioTrack II radio card. " ) ;
MODULE_LICENSE ( " GPL " ) ;
2012-01-16 12:24:08 +04:00
MODULE_VERSION ( " 0.1.99 " ) ;
2006-08-08 16:10:02 +04:00
2005-04-17 02:20:36 +04:00
# ifndef CONFIG_RADIO_RTRACK2_PORT
# define CONFIG_RADIO_RTRACK2_PORT -1
# endif
2012-01-16 12:24:08 +04:00
# define RTRACK2_MAX 2
2005-04-17 02:20:36 +04:00
2012-01-16 12:24:08 +04:00
static int io [ RTRACK2_MAX ] = { [ 0 ] = CONFIG_RADIO_RTRACK2_PORT ,
[ 1 . . . ( RTRACK2_MAX - 1 ) ] = - 1 } ;
static int radio_nr [ RTRACK2_MAX ] = { [ 0 . . . ( RTRACK2_MAX - 1 ) ] = - 1 } ;
2009-03-06 19:52:06 +03:00
2012-01-16 12:24:08 +04:00
module_param_array ( io , int , NULL , 0444 ) ;
MODULE_PARM_DESC ( io , " I/O addresses of the RadioTrack card (0x20f or 0x30f) " ) ;
module_param_array ( radio_nr , int , NULL , 0444 ) ;
MODULE_PARM_DESC ( radio_nr , " Radio device numbers " ) ;
2005-04-17 02:20:36 +04:00
2012-01-16 12:24:08 +04:00
static struct radio_isa_card * rtrack2_alloc ( void )
2005-04-17 02:20:36 +04:00
{
2012-01-16 12:24:08 +04:00
return kzalloc ( sizeof ( struct radio_isa_card ) , GFP_KERNEL ) ;
2005-04-17 02:20:36 +04:00
}
2012-01-16 12:24:08 +04:00
static void zero ( struct radio_isa_card * isa )
2005-04-17 02:20:36 +04:00
{
2012-01-16 12:24:08 +04:00
outb_p ( 1 , isa - > io ) ;
outb_p ( 3 , isa - > io ) ;
outb_p ( 1 , isa - > io ) ;
2005-04-17 02:20:36 +04:00
}
2012-01-16 12:24:08 +04:00
static void one ( struct radio_isa_card * isa )
2005-04-17 02:20:36 +04:00
{
2012-01-16 12:24:08 +04:00
outb_p ( 5 , isa - > io ) ;
outb_p ( 7 , isa - > io ) ;
outb_p ( 5 , isa - > io ) ;
2005-04-17 02:20:36 +04:00
}
2012-01-16 12:24:08 +04:00
static int rtrack2_s_frequency ( struct radio_isa_card * isa , u32 freq )
2005-04-17 02:20:36 +04:00
{
int i ;
freq = freq / 200 + 856 ;
2006-04-08 23:06:16 +04:00
2012-01-16 12:24:08 +04:00
outb_p ( 0xc8 , isa - > io ) ;
outb_p ( 0xc9 , isa - > io ) ;
outb_p ( 0xc9 , isa - > io ) ;
2005-04-17 02:20:36 +04:00
for ( i = 0 ; i < 10 ; i + + )
2012-01-16 12:24:08 +04:00
zero ( isa ) ;
2005-04-17 02:20:36 +04:00
for ( i = 14 ; i > = 0 ; i - - )
if ( freq & ( 1 < < i ) )
2012-01-16 12:24:08 +04:00
one ( isa ) ;
2005-04-17 02:20:36 +04:00
else
2012-01-16 12:24:08 +04:00
zero ( isa ) ;
2007-04-19 23:42:25 +04:00
2012-01-16 12:24:08 +04:00
outb_p ( 0xc8 , isa - > io ) ;
2013-02-25 15:00:15 +04:00
outb_p ( v4l2_ctrl_g_ctrl ( isa - > mute ) , isa - > io ) ;
2007-04-19 23:42:25 +04:00
return 0 ;
}
2006-08-08 16:10:02 +04:00
2012-01-16 12:24:08 +04:00
static u32 rtrack2_g_signal ( struct radio_isa_card * isa )
2007-04-19 23:42:25 +04:00
{
2012-01-16 12:24:08 +04:00
/* bit set = no signal present */
return ( inb ( isa - > io ) & 2 ) ? 0 : 0xffff ;
2007-04-19 23:42:25 +04:00
}
2006-08-08 16:10:02 +04:00
2012-01-16 12:24:08 +04:00
static int rtrack2_s_mute_volume ( struct radio_isa_card * isa , bool mute , int vol )
2007-04-19 23:42:25 +04:00
{
2012-01-16 12:24:08 +04:00
outb ( mute , isa - > io ) ;
2007-04-19 23:42:25 +04:00
return 0 ;
}
2006-08-08 16:10:02 +04:00
2012-01-16 12:24:08 +04:00
static const struct radio_isa_ops rtrack2_ops = {
. alloc = rtrack2_alloc ,
. s_mute_volume = rtrack2_s_mute_volume ,
. s_frequency = rtrack2_s_frequency ,
. g_signal = rtrack2_g_signal ,
2005-04-17 02:20:36 +04:00
} ;
2012-01-16 12:24:08 +04:00
static const int rtrack2_ioports [ ] = { 0x20f , 0x30f } ;
static struct radio_isa_driver rtrack2_driver = {
. driver = {
. match = radio_isa_match ,
. probe = radio_isa_probe ,
. remove = radio_isa_remove ,
. driver = {
. name = " radio-rtrack2 " ,
} ,
} ,
. io_params = io ,
. radio_nr_params = radio_nr ,
. io_ports = rtrack2_ioports ,
. num_of_io_ports = ARRAY_SIZE ( rtrack2_ioports ) ,
. region_size = 4 ,
. card = " AIMSlab RadioTrack II " ,
. ops = & rtrack2_ops ,
. has_stereo = true ,
2005-04-17 02:20:36 +04:00
} ;
static int __init rtrack2_init ( void )
{
2012-01-16 12:24:08 +04:00
return isa_register_driver ( & rtrack2_driver . driver , RTRACK2_MAX ) ;
2005-04-17 02:20:36 +04:00
}
2009-03-06 19:52:06 +03:00
static void __exit rtrack2_exit ( void )
2005-04-17 02:20:36 +04:00
{
2012-01-16 12:24:08 +04:00
isa_unregister_driver ( & rtrack2_driver . driver ) ;
2005-04-17 02:20:36 +04:00
}
module_init ( rtrack2_init ) ;
2009-03-06 19:52:06 +03:00
module_exit ( rtrack2_exit ) ;