/* radio-cadet.c - A video4linux driver for the ADS Cadet AM/FM Radio Card
 *
 * by Fred Gleason <fredg@wava.com>
 * Version 0.3.3
 *
 * (Loosely) based on code for the Aztech radio card by
 *
 * Russell Kroll    (rkroll@exploits.org)
 * Quay Ly
 * Donald Song
 * Jason Lewis      (jlewis@twilight.vtc.vsc.edu) 
 * Scott McGrath    (smcgrath@twilight.vtc.vsc.edu)
 * William McGrath  (wmcgrath@twilight.vtc.vsc.edu)
 *
 * History:
 * 2000-04-29	Russell Kroll <rkroll@exploits.org>
 *		Added ISAPnP detection for Linux 2.3/2.4
 *
 * 2001-01-10	Russell Kroll <rkroll@exploits.org>
 *		Removed dead CONFIG_RADIO_CADET_PORT code
 *		PnP detection on load is now default (no args necessary)
 *
 * 2002-01-17	Adam Belay <ambx1@neo.rr.com>
 *		Updated to latest pnp code
 *
 * 2003-01-31	Alan Cox <alan@redhat.com>
 *		Cleaned up locking, delay code, general odds and ends
 */

#include <linux/module.h>	/* Modules 			*/
#include <linux/init.h>		/* Initdata			*/
#include <linux/ioport.h>	/* check_region, request_region	*/
#include <linux/delay.h>	/* udelay			*/
#include <asm/io.h>		/* outb, outb_p			*/
#include <asm/uaccess.h>	/* copy to/from user		*/
#include <linux/videodev.h>	/* kernel radio structs		*/
#include <linux/param.h>
#include <linux/pnp.h>

#define RDS_BUFFER 256

static int io=-1;		/* default to isapnp activation */
static int radio_nr = -1;
static int users=0;
static int curtuner=0;
static int tunestat=0;
static int sigstrength=0;
static wait_queue_head_t read_queue;
static struct timer_list readtimer;
static __u8 rdsin=0,rdsout=0,rdsstat=0;
static unsigned char rdsbuf[RDS_BUFFER];
static spinlock_t cadet_io_lock;

static int cadet_probe(void);

/*
 * Signal Strength Threshold Values
 * The V4L API spec does not define any particular unit for the signal 
 * strength value.  These values are in microvolts of RF at the tuner's input.
 */
static __u16 sigtable[2][4]={{5,10,30,150},{28,40,63,1000}};

static int cadet_getrds(void)
{
        int rdsstat=0;

	spin_lock(&cadet_io_lock);
        outb(3,io);                 /* Select Decoder Control/Status */
	outb(inb(io+1)&0x7f,io+1);  /* Reset RDS detection */
	spin_unlock(&cadet_io_lock);
	
	msleep(100);

	spin_lock(&cadet_io_lock);	
        outb(3,io);                 /* Select Decoder Control/Status */
	if((inb(io+1)&0x80)!=0) {
	        rdsstat|=VIDEO_TUNER_RDS_ON;
	}
	if((inb(io+1)&0x10)!=0) {
	        rdsstat|=VIDEO_TUNER_MBS_ON;
	}
	spin_unlock(&cadet_io_lock);
	return rdsstat;
}

static int cadet_getstereo(void)
{
	int ret = 0;
        if(curtuner != 0)	/* Only FM has stereo capability! */
	        return 0;

	spin_lock(&cadet_io_lock);
        outb(7,io);          /* Select tuner control */
	if( (inb(io+1) & 0x40) == 0)
        	ret = 1;
        spin_unlock(&cadet_io_lock);
        return ret;
}

static unsigned cadet_gettune(void)
{
        int curvol,i;
	unsigned fifo=0;

        /*
         * Prepare for read
         */

	spin_lock(&cadet_io_lock);
	
        outb(7,io);       /* Select tuner control */
        curvol=inb(io+1); /* Save current volume/mute setting */
        outb(0x00,io+1);  /* Ensure WRITE-ENABLE is LOW */
	tunestat=0xffff;

        /*
         * Read the shift register
         */
        for(i=0;i<25;i++) {
                fifo=(fifo<<1)|((inb(io+1)>>7)&0x01);
                if(i<24) {
                        outb(0x01,io+1);
			tunestat&=inb(io+1);
                        outb(0x00,io+1);
                }
        }

        /*
         * Restore volume/mute setting
         */
        outb(curvol,io+1);
	spin_unlock(&cadet_io_lock);

	return fifo;
}

static unsigned cadet_getfreq(void)
{
        int i;
        unsigned freq=0,test,fifo=0;

	/*
	 * Read current tuning
	 */
	fifo=cadet_gettune();

        /*
         * Convert to actual frequency
         */
	if(curtuner==0) {    /* FM */
	        test=12500;
                for(i=0;i<14;i++) {
                        if((fifo&0x01)!=0) {
                                freq+=test;
                        }
                        test=test<<1;
                        fifo=fifo>>1;
                }
                freq-=10700000;           /* IF frequency is 10.7 MHz */
                freq=(freq*16)/1000000;   /* Make it 1/16 MHz */
	}
	if(curtuner==1) {    /* AM */
	        freq=((fifo&0x7fff)-2010)*16;
	}

        return freq;
}

static void cadet_settune(unsigned fifo)
{
        int i;
	unsigned test;  

	spin_lock(&cadet_io_lock);
	
	outb(7,io);                /* Select tuner control */
	/*
	 * Write the shift register
	 */
	test=0;
	test=(fifo>>23)&0x02;      /* Align data for SDO */
	test|=0x1c;                /* SDM=1, SWE=1, SEN=1, SCK=0 */
	outb(7,io);                /* Select tuner control */
	outb(test,io+1);           /* Initialize for write */
	for(i=0;i<25;i++) {
   	        test|=0x01;              /* Toggle SCK High */
		outb(test,io+1);
		test&=0xfe;              /* Toggle SCK Low */
		outb(test,io+1);
		fifo=fifo<<1;            /* Prepare the next bit */
		test=0x1c|((fifo>>23)&0x02);
		outb(test,io+1);
	}
	spin_unlock(&cadet_io_lock);
}

static void cadet_setfreq(unsigned freq)
{
        unsigned fifo;
        int i,j,test;
        int curvol;

        /* 
         * Formulate a fifo command
         */
	fifo=0;
	if(curtuner==0) {    /* FM */
        	test=102400;
                freq=(freq*1000)/16;       /* Make it kHz */
                freq+=10700;               /* IF is 10700 kHz */
                for(i=0;i<14;i++) {
                        fifo=fifo<<1;
                        if(freq>=test) {
                                fifo|=0x01;
                                freq-=test;
                        }
                        test=test>>1;
                }
	}
	if(curtuner==1) {    /* AM */
                fifo=(freq/16)+2010;            /* Make it kHz */
		fifo|=0x100000;            /* Select AM Band */
	}

        /*
         * Save current volume/mute setting
         */

	spin_lock(&cadet_io_lock);
	outb(7,io);                /* Select tuner control */
        curvol=inb(io+1); 
        spin_unlock(&cadet_io_lock);

	/*
	 * Tune the card
	 */
	for(j=3;j>-1;j--) {
	        cadet_settune(fifo|(j<<16));
	        
	        spin_lock(&cadet_io_lock);
		outb(7,io);         /* Select tuner control */
		outb(curvol,io+1);
		spin_unlock(&cadet_io_lock);
		
		msleep(100);

		cadet_gettune();
		if((tunestat & 0x40) == 0) {   /* Tuned */
		        sigstrength=sigtable[curtuner][j];
			return;
		}
	}
	sigstrength=0;
}


static int cadet_getvol(void)
{
	int ret = 0;
	
	spin_lock(&cadet_io_lock);
	
        outb(7,io);                /* Select tuner control */
        if((inb(io + 1) & 0x20) != 0)
        	ret = 0xffff;
        
        spin_unlock(&cadet_io_lock);
        return ret;
}


static void cadet_setvol(int vol)
{
	spin_lock(&cadet_io_lock);
        outb(7,io);                /* Select tuner control */
        if(vol>0)
                outb(0x20,io+1);
        else
                outb(0x00,io+1);
	spin_unlock(&cadet_io_lock);
}  

static void cadet_handler(unsigned long data)
{
	/*
	 * Service the RDS fifo
	 */

	if(spin_trylock(&cadet_io_lock))
	{
	        outb(0x3,io);       /* Select RDS Decoder Control */
		if((inb(io+1)&0x20)!=0) {
		        printk(KERN_CRIT "cadet: RDS fifo overflow\n");
		}
		outb(0x80,io);      /* Select RDS fifo */
		while((inb(io)&0x80)!=0) {
		        rdsbuf[rdsin]=inb(io+1);
			if(rdsin==rdsout)
			        printk(KERN_WARNING "cadet: RDS buffer overflow\n");
			else
				rdsin++;
		}
		spin_unlock(&cadet_io_lock);
	}

	/*
	 * Service pending read
	 */
	if( rdsin!=rdsout)
	        wake_up_interruptible(&read_queue);

	/* 
	 * Clean up and exit
	 */
	init_timer(&readtimer);
	readtimer.function=cadet_handler;
	readtimer.data=(unsigned long)0;
	readtimer.expires=jiffies+(HZ/20);
	add_timer(&readtimer);
}



static ssize_t cadet_read(struct file *file, char __user *data,
			  size_t count, loff_t *ppos)
{
        int i=0;
	unsigned char readbuf[RDS_BUFFER];

        if(rdsstat==0) {
		spin_lock(&cadet_io_lock);
	        rdsstat=1;
		outb(0x80,io);        /* Select RDS fifo */
		spin_unlock(&cadet_io_lock);
		init_timer(&readtimer);
		readtimer.function=cadet_handler;
		readtimer.data=(unsigned long)0;
		readtimer.expires=jiffies+(HZ/20);
		add_timer(&readtimer);
	}
	if(rdsin==rdsout) {
  	        if (file->f_flags & O_NONBLOCK)
		        return -EWOULDBLOCK;
	        interruptible_sleep_on(&read_queue);
	}		
	while( i<count && rdsin!=rdsout)
	        readbuf[i++]=rdsbuf[rdsout++];

	if (copy_to_user(data,readbuf,i))
	        return -EFAULT;
	return i;
}



static int cadet_do_ioctl(struct inode *inode, struct file *file,
			  unsigned int cmd, void *arg)
{
	switch(cmd)
	{
		case VIDIOCGCAP:
		{
			struct video_capability *v = arg;
			memset(v,0,sizeof(*v));
			v->type=VID_TYPE_TUNER;
			v->channels=2;
			v->audios=1;
			strcpy(v->name, "ADS Cadet");
			return 0;
		}
		case VIDIOCGTUNER:
		{
			struct video_tuner *v = arg;
			if((v->tuner<0)||(v->tuner>1)) {
				return -EINVAL;
			}
			switch(v->tuner) {
			        case 0:
			        strcpy(v->name,"FM");
			        v->rangelow=1400;     /* 87.5 MHz */
			        v->rangehigh=1728;    /* 108.0 MHz */
			        v->flags=0;
			        v->mode=0;
			        v->mode|=VIDEO_MODE_AUTO;
			        v->signal=sigstrength;
			        if(cadet_getstereo()==1) {
				        v->flags|=VIDEO_TUNER_STEREO_ON;
			        }
				v->flags|=cadet_getrds();
			        break;
			        case 1:
			        strcpy(v->name,"AM");
			        v->rangelow=8320;      /* 520 kHz */
			        v->rangehigh=26400;    /* 1650 kHz */
			        v->flags=0;
			        v->flags|=VIDEO_TUNER_LOW;
			        v->mode=0;
			        v->mode|=VIDEO_MODE_AUTO;
			        v->signal=sigstrength;
			        break;
			}
			return 0;
		}
		case VIDIOCSTUNER:
		{
			struct video_tuner *v = arg;
			if((v->tuner<0)||(v->tuner>1)) {
				return -EINVAL;
			}
			curtuner=v->tuner;	
			return 0;
		}
		case VIDIOCGFREQ:
		{
		        unsigned long *freq = arg;
			*freq = cadet_getfreq();
			return 0;
		}
		case VIDIOCSFREQ:
		{
		        unsigned long *freq = arg;
			if((curtuner==0)&&((*freq<1400)||(*freq>1728))) {
			        return -EINVAL;
			}
			if((curtuner==1)&&((*freq<8320)||(*freq>26400))) {
			        return -EINVAL;
			}
			cadet_setfreq(*freq);
			return 0;
		}
		case VIDIOCGAUDIO:
		{	
			struct video_audio *v = arg;
			memset(v,0, sizeof(*v));
			v->flags=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME;
			if(cadet_getstereo()==0) {
			        v->mode=VIDEO_SOUND_MONO;
			} else {
				v->mode=VIDEO_SOUND_STEREO;
			}
			v->volume=cadet_getvol();
			v->step=0xffff;
			strcpy(v->name, "Radio");
			return 0;			
		}
		case VIDIOCSAUDIO:
		{
			struct video_audio *v = arg;
			if(v->audio) 
				return -EINVAL;
			cadet_setvol(v->volume);
			if(v->flags&VIDEO_AUDIO_MUTE) 
				cadet_setvol(0);
			else
				cadet_setvol(0xffff);
			return 0;
		}
		default:
			return -ENOIOCTLCMD;
	}
}

static int cadet_ioctl(struct inode *inode, struct file *file,
		       unsigned int cmd, unsigned long arg)
{
	return video_usercopy(inode, file, cmd, arg, cadet_do_ioctl);
}

static int cadet_open(struct inode *inode, struct file *file)
{
	if(users)
		return -EBUSY;
	users++;
	init_waitqueue_head(&read_queue);
	return 0;
}

static int cadet_release(struct inode *inode, struct file *file)
{
	del_timer_sync(&readtimer);
	rdsstat=0;
	users--;
	return 0;
}


static struct file_operations cadet_fops = {
	.owner		= THIS_MODULE,
	.open		= cadet_open,
	.release       	= cadet_release,
	.read		= cadet_read,
	.ioctl		= cadet_ioctl,
	.llseek         = no_llseek,
};

static struct video_device cadet_radio=
{
	.owner		= THIS_MODULE,
	.name		= "Cadet radio",
	.type		= VID_TYPE_TUNER,
	.hardware	= VID_HARDWARE_CADET,
	.fops           = &cadet_fops,
};

static struct pnp_device_id cadet_pnp_devices[] = {
	/* ADS Cadet AM/FM Radio Card */
	{.id = "MSM0c24", .driver_data = 0},
	{.id = ""}
};

MODULE_DEVICE_TABLE(pnp, cadet_pnp_devices);

static int cadet_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id)
{
	if (!dev)
		return -ENODEV;
	/* only support one device */
	if (io > 0)
		return -EBUSY;

	if (!pnp_port_valid(dev, 0)) {
		return -ENODEV;
	}

	io = pnp_port_start(dev, 0);

	printk ("radio-cadet: PnP reports device at %#x\n", io);

	return io;
}

static struct pnp_driver cadet_pnp_driver = {
	.name		= "radio-cadet",
	.id_table	= cadet_pnp_devices,
	.probe		= cadet_pnp_probe,
	.remove		= NULL,
};

static int cadet_probe(void)
{
        static int iovals[8]={0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e};
	int i;

	for(i=0;i<8;i++) {
	        io=iovals[i];
	        if(request_region(io,2, "cadet-probe")>=0) {
		        cadet_setfreq(1410);
			if(cadet_getfreq()==1410) {
				release_region(io, 2);
			        return io;
			}
			release_region(io, 2);
		}
	}
	return -1;
}

/* 
 * io should only be set if the user has used something like
 * isapnp (the userspace program) to initialize this card for us
 */

static int __init cadet_init(void)
{
	spin_lock_init(&cadet_io_lock);
	
	/*
	 *	If a probe was requested then probe ISAPnP first (safest)
	 */
	if (io < 0)
		pnp_register_driver(&cadet_pnp_driver);
	/*
	 *	If that fails then probe unsafely if probe is requested
	 */
	if(io < 0)
		io = cadet_probe ();

	/*
	 *	Else we bail out
	 */
	 
        if(io < 0) {
#ifdef MODULE        
		printk(KERN_ERR "You must set an I/O address with io=0x???\n");
#endif
	        goto fail;
	}
	if (!request_region(io,2,"cadet"))
		goto fail;
	if(video_register_device(&cadet_radio,VFL_TYPE_RADIO,radio_nr)==-1) {
		release_region(io,2);
		goto fail;
	}
	printk(KERN_INFO "ADS Cadet Radio Card at 0x%x\n",io);
	return 0;
fail:
	pnp_unregister_driver(&cadet_pnp_driver);
	return -1;
}



MODULE_AUTHOR("Fred Gleason, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
MODULE_DESCRIPTION("A driver for the ADS Cadet AM/FM/RDS radio card.");
MODULE_LICENSE("GPL");

module_param(io, int, 0);
MODULE_PARM_DESC(io, "I/O address of Cadet card (0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e)");
module_param(radio_nr, int, 0);

static void __exit cadet_cleanup_module(void)
{
	video_unregister_device(&cadet_radio);
	release_region(io,2);
	pnp_unregister_driver(&cadet_pnp_driver);
}

module_init(cadet_init);
module_exit(cadet_cleanup_module);

