⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 miropcm20-rds-core.c

📁 linux-2.6.15.6
💻 C
字号:
/* *  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 <asm/semaphore.h>#include <asm/io.h>#include "../../../sound/oss/aci.h"#include "miropcm20-rds-core.h"#define DEBUG 0static struct semaphore aci_rds_sem;#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 DEBUGstatic 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 (down_interruptible(&aci_rds_sem))		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;	up(&aci_rds_sem);		return ret;}EXPORT_SYMBOL(aci_rds_cmd);int __init attach_aci_rds(void){	init_MUTEX(&aci_rds_sem);	return 0;}void __exit unload_aci_rds(void){}MODULE_LICENSE("GPL");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -