/*
 *  Many thanks to Fred Seidel <seidel@metabox.de>, the
 *  designer of the RDS decoder hardware. With his help
 *  I was able to code this driver.
 *  Thanks also to Norberto Pellicci, Dominic Mounteney
 *  <DMounteney@pinnaclesys.com> and www.teleauskunft.de
 *  for good hints on finding Fred. It was somewhat hard
 *  to locate him here in Germany... [:
 *
 * Revision history:
 *
 *   2000-08-09  Robert Siemer <Robert.Siemer@gmx.de>
 *        RDS support for MiroSound PCM20 radio
 */

#include <linux/module.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/mutex.h>

#include <asm/io.h>
#include "../../../sound/oss/aci.h"
#include "miropcm20-rds-core.h"

#define DEBUG 0

static struct mutex aci_rds_mutex;

#define RDS_DATASHIFT          2   /* Bit 2 */
#define RDS_DATAMASK        (1 << RDS_DATASHIFT)
#define RDS_BUSYMASK        0x10   /* Bit 4 */
#define RDS_CLOCKMASK       0x08   /* Bit 3 */

#define RDS_DATA(x)         (((x) >> RDS_DATASHIFT) & 1) 


#if DEBUG
static void print_matrix(char array[], unsigned int length)
{
        int i, j;

        for (i=0; i<length; i++) {
                printk(KERN_DEBUG "aci-rds: ");
                for (j=7; j>=0; j--) {
                        printk("%d", (array[i] >> j) & 0x1);
                }
                if (i%8 == 0)
                        printk(" byte-border\n");
                else
                        printk("\n");
        }
}
#endif /* DEBUG */

static int byte2trans(unsigned char byte, unsigned char sendbuffer[], int size)
{
	int i;

	if (size != 8)
		return -1;
	for (i = 7; i >= 0; i--)
		sendbuffer[7-i] = (byte & (1 << i)) ? RDS_DATAMASK : 0;
	sendbuffer[0] |= RDS_CLOCKMASK;

	return 0;
}

static int rds_waitread(void)
{
	unsigned char byte;
	int i=2000;

	do {
		byte=inb(RDS_REGISTER);
		i--;
	}
	while ((byte & RDS_BUSYMASK) && i);

	if (i) {
		#if DEBUG
		printk(KERN_DEBUG "rds_waitread()");
		print_matrix(&byte, 1);
		#endif
		return (byte);
	} else {
		printk(KERN_WARNING "aci-rds: rds_waitread() timeout...\n");
		return -1;
	}
}

/* don't use any ..._nowait() function if you are not sure what you do... */

static inline void rds_rawwrite_nowait(unsigned char byte)
{
	#if DEBUG
	printk(KERN_DEBUG "rds_rawwrite()");
	print_matrix(&byte, 1);
	#endif
	outb(byte, RDS_REGISTER);
}

static int rds_rawwrite(unsigned char byte)
{
	if (rds_waitread() >= 0) {
		rds_rawwrite_nowait(byte);
		return 0;
	} else
		return -1;
}

static int rds_write(unsigned char cmd)
{
	unsigned char sendbuffer[8];
	int i;
	
	if (byte2trans(cmd, sendbuffer, 8) != 0){
		return -1;
	} else {
		for (i=0; i<8; i++) {
			rds_rawwrite(sendbuffer[i]);
		}
	}
	return 0;
}

static int rds_readcycle_nowait(void)
{
	rds_rawwrite_nowait(0);
	return rds_waitread();
}

static int rds_readcycle(void)
{
	if (rds_rawwrite(0) < 0)
		return -1;
	return rds_waitread();
}

static int rds_read(unsigned char databuffer[], int datasize)
{
	#define READSIZE (8*datasize)

	int i,j;

	if (datasize < 1)  /* nothing to read */
		return 0;

	/* to be able to use rds_readcycle_nowait()
	   I have to waitread() here */
	if (rds_waitread() < 0)
		return -1;
	
	memset(databuffer, 0, datasize);

	for (i=0; i< READSIZE; i++)
		if((j=rds_readcycle_nowait()) < 0) {
			return -1;
		} else {
			databuffer[i/8]|=(RDS_DATA(j) << (7-(i%8)));
		}

	return 0;
}

static int rds_ack(void)
{
	int i=rds_readcycle();

	if (i < 0)
		return -1;
	if (i & RDS_DATAMASK) {
		return 0;  /* ACK  */
	} else {
		printk(KERN_DEBUG "aci-rds: NACK\n");
		return 1;  /* NACK */
	}
}

int aci_rds_cmd(unsigned char cmd, unsigned char databuffer[], int datasize)
{
	int ret;

	if (mutex_lock_interruptible(&aci_rds_mutex))
		return -EINTR;

	rds_write(cmd);

	/* RDS_RESET doesn't need further processing */
	if (cmd!=RDS_RESET && (rds_ack() || rds_read(databuffer, datasize)))
		ret = -1;
	else
		ret = 0;

	mutex_unlock(&aci_rds_mutex);
	
	return ret;
}
EXPORT_SYMBOL(aci_rds_cmd);

int __init attach_aci_rds(void)
{
	mutex_init(&aci_rds_mutex);
	return 0;
}

void __exit unload_aci_rds(void)
{
}
MODULE_LICENSE("GPL");
