/* radio-aztech.c - Aztech radio card driver for Linux 2.2 
 *
 * Adapted to support the Video for Linux API by 
 * Russell Kroll <rkroll@exploits.org>.  Based on original tuner code by:
 *
 * 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)
 *
 * The basis for this code may be found at http://bigbang.vtc.vsc.edu/fmradio/
 * along with more information on the card itself.
 *
 * History:
 * 1999-02-24	Russell Kroll <rkroll@exploits.org>
 *		Fine tuning/VIDEO_TUNER_LOW
 * 		Range expanded to 87-108 MHz (from 87.9-107.8)
 *
 * Notable changes from the original source:
 * - includes stripped down to the essentials
 * - for loops used as delays replaced with udelay()
 * - #defines removed, changed to static values
 * - tuning structure changed - no more character arrays, other changes
*/

#include <linux/module.h>	/* Modules 			*/
#include <linux/init.h>		/* Initdata			*/
#include <linux/ioport.h>	/* 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/config.h>	/* CONFIG_RADIO_AZTECH_PORT 	*/

/* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */

#ifndef CONFIG_RADIO_AZTECH_PORT
#define CONFIG_RADIO_AZTECH_PORT -1
#endif

static int io = CONFIG_RADIO_AZTECH_PORT; 
static int radio_nr = -1;
static int radio_wait_time = 1000;
static struct mutex lock;

struct az_device
{
	int curvol;
	unsigned long curfreq;
	int stereo;
};

static int volconvert(int level)
{
	level>>=14;	 	/* Map 16bits down to 2 bit */
 	level&=3;
	
	/* convert to card-friendly values */
	switch (level) 
	{
		case 0: 
			return 0;
		case 1: 
			return 1;
		case 2:
			return 4;
		case 3:
			return 5;
	}
	return 0;	/* Quieten gcc */
}

static void send_0_byte (struct az_device *dev)
{
	udelay(radio_wait_time);
	outb_p(2+volconvert(dev->curvol), io);
	outb_p(64+2+volconvert(dev->curvol), io);
}

static void send_1_byte (struct az_device *dev)
{
	udelay (radio_wait_time);
	outb_p(128+2+volconvert(dev->curvol), io);
	outb_p(128+64+2+volconvert(dev->curvol), io);
}

static int az_setvol(struct az_device *dev, int vol)
{
	mutex_lock(&lock);
	outb (volconvert(vol), io);
	mutex_unlock(&lock);
	return 0;
}

/* thanks to Michael Dwyer for giving me a dose of clues in
 * the signal strength department..
 *
 * This card has a stereo bit - bit 0 set = mono, not set = stereo
 * It also has a "signal" bit - bit 1 set = bad signal, not set = good
 *
 */

static int az_getsigstr(struct az_device *dev)
{
	if (inb(io) & 2)	/* bit set = no signal present */
		return 0;
	return 1;		/* signal present */
}

static int az_getstereo(struct az_device *dev)
{
	if (inb(io) & 1) 	/* bit set = mono */
		return 0;
	return 1;		/* stereo */
}

static int az_setfreq(struct az_device *dev, unsigned long frequency)
{
	int  i;

	frequency += 171200;		/* Add 10.7 MHz IF		*/
	frequency /= 800;		/* Convert to 50 kHz units	*/
					
	mutex_lock(&lock);
	
	send_0_byte (dev);		/*  0: LSB of frequency       */

	for (i = 0; i < 13; i++)	/*   : frequency bits (1-13)  */
		if (frequency & (1 << i))
			send_1_byte (dev);
		else
			send_0_byte (dev);

	send_0_byte (dev);		/* 14: test bit - always 0    */
	send_0_byte (dev);		/* 15: test bit - always 0    */
	send_0_byte (dev);		/* 16: band data 0 - always 0 */
	if (dev->stereo)		/* 17: stereo (1 to enable)   */
		send_1_byte (dev);
	else
		send_0_byte (dev);

	send_1_byte (dev);		/* 18: band data 1 - unknown  */
	send_0_byte (dev);		/* 19: time base - always 0   */
	send_0_byte (dev);		/* 20: spacing (0 = 25 kHz)   */
	send_1_byte (dev);		/* 21: spacing (1 = 25 kHz)   */
	send_0_byte (dev);		/* 22: spacing (0 = 25 kHz)   */
	send_1_byte (dev);		/* 23: AM/FM (FM = 1, always) */

	/* latch frequency */

	udelay (radio_wait_time);
	outb_p(128+64+volconvert(dev->curvol), io);
	
	mutex_unlock(&lock);

	return 0;
}

static int az_do_ioctl(struct inode *inode, struct file *file,
		       unsigned int cmd, void *arg)
{
	struct video_device *dev = video_devdata(file);
	struct az_device *az = dev->priv;
	
	switch(cmd)
	{
		case VIDIOCGCAP:
		{
			struct video_capability *v = arg;
			memset(v,0,sizeof(*v));
			v->type=VID_TYPE_TUNER;
			v->channels=1;
			v->audios=1;
			strcpy(v->name, "Aztech Radio");
			return 0;
		}
		case VIDIOCGTUNER:
		{
			struct video_tuner *v = arg;
			if(v->tuner)	/* Only 1 tuner */ 
				return -EINVAL;
			v->rangelow=(87*16000);
			v->rangehigh=(108*16000);
			v->flags=VIDEO_TUNER_LOW;
			v->mode=VIDEO_MODE_AUTO;
			v->signal=0xFFFF*az_getsigstr(az);
			if(az_getstereo(az))
				v->flags|=VIDEO_TUNER_STEREO_ON;
			strcpy(v->name, "FM");
			return 0;
		}
		case VIDIOCSTUNER:
		{
			struct video_tuner *v = arg;
			if(v->tuner!=0)
				return -EINVAL;
			return 0;
		}
		case VIDIOCGFREQ:
		{
			unsigned long *freq = arg;
			*freq = az->curfreq;
			return 0;
		}
		case VIDIOCSFREQ:
		{
			unsigned long *freq = arg;
			az->curfreq = *freq;
			az_setfreq(az, az->curfreq);
			return 0;
		}
		case VIDIOCGAUDIO:
		{	
			struct video_audio *v = arg;
			memset(v,0, sizeof(*v));
			v->flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME;
			if(az->stereo)
				v->mode=VIDEO_SOUND_STEREO;
			else
				v->mode=VIDEO_SOUND_MONO;
			v->volume=az->curvol;
			v->step=16384;
			strcpy(v->name, "Radio");
			return 0;			
		}
		case VIDIOCSAUDIO:
		{
			struct video_audio *v = arg;
			if(v->audio) 
				return -EINVAL;
			az->curvol=v->volume;

			az->stereo=(v->mode&VIDEO_SOUND_STEREO)?1:0;
			if(v->flags&VIDEO_AUDIO_MUTE) 
				az_setvol(az,0);
			else
				az_setvol(az,az->curvol);
			return 0;
		}
		default:
			return -ENOIOCTLCMD;
	}
}

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

static struct az_device aztech_unit;

static struct file_operations aztech_fops = {
	.owner		= THIS_MODULE,
	.open           = video_exclusive_open,
	.release        = video_exclusive_release,
	.ioctl		= az_ioctl,
	.compat_ioctl	= v4l_compat_ioctl32,
	.llseek         = no_llseek,
};

static struct video_device aztech_radio=
{
	.owner		= THIS_MODULE,
	.name		= "Aztech radio",
	.type		= VID_TYPE_TUNER,
	.hardware	= VID_HARDWARE_AZTECH,
	.fops           = &aztech_fops,
};

static int __init aztech_init(void)
{
	if(io==-1)
	{
		printk(KERN_ERR "You must set an I/O address with io=0x???\n");
		return -EINVAL;
	}

	if (!request_region(io, 2, "aztech")) 
	{
		printk(KERN_ERR "aztech: port 0x%x already in use\n", io);
		return -EBUSY;
	}

	mutex_init(&lock);
	aztech_radio.priv=&aztech_unit;
	
	if(video_register_device(&aztech_radio, VFL_TYPE_RADIO, radio_nr)==-1)
	{
		release_region(io,2);
		return -EINVAL;
	}
		
	printk(KERN_INFO "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n");
	/* mute card - prevents noisy bootups */
	outb (0, io);
	return 0;
}

MODULE_AUTHOR("Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
MODULE_DESCRIPTION("A driver for the Aztech radio card.");
MODULE_LICENSE("GPL");

module_param(io, int, 0);
module_param(radio_nr, int, 0);
MODULE_PARM_DESC(io, "I/O address of the Aztech card (0x350 or 0x358)");

static void __exit aztech_cleanup(void)
{
	video_unregister_device(&aztech_radio);
	release_region(io,2);
}

module_init(aztech_init);
module_exit(aztech_cleanup);
