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

📄 omap24xx-ir.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 2 页
字号:
	case SIOCSMEDIABUSY:		ret = -EPERM;		if (capable(CAP_NET_ADMIN)) {			irda_device_set_media_busy(dev, TRUE);			ret = 0;		}		break;	case SIOCGRECEIVING:		rq->ifr_receiving = rx_state;		break;	default:		break;	}	__ECHO_OUT;	return ret;}static struct net_device_stats *omap24xx_irda_stats(struct net_device *dev){	struct omap24xx_irda *si = dev->priv;	return &si->stats;}#if 1staticint omap24xx_irda_setup(void){	omap2_cfg_reg(K15_2420_UART3_TX);	omap2_cfg_reg(K14_2420_UART3_RX);#if 0	reg_val = omap_prcmreg_read(PRCM_FCLK_EN2_CORE);	omap_prcmreg_write(reg_val | (1 << 2), PRCM_FCLK_EN2_CORE);	reg_val = omap_prcmreg_read(PRCM_ICLK_EN2_CORE);	omap_prcmreg_write(reg_val | (1 << 2), PRCM_ICLK_EN2_CORE);#endif}#endifstaticint omap24xx_irda_start(struct net_device *dev){	struct omap24xx_irda *si = dev->priv;	int err;	unsigned long flags = 0;	u8 ioExpanderVal = 0;	__ECHO_IN;	si->speed = 9600;	omap24xx_irda_setup();	err = request_irq(dev->irq, omap24xx_irda_irq, 0, dev->name, dev);	if (err)		goto err_irq;	/*	 * The interrupt must remain disabled for now.	 */	disable_irq(dev->irq);	/*  Request DMA channels for IrDA hardware */	if (omap_request_dma(OMAP24XX_TRIGGER_RX, "IrDA Rx DMA",			     (void *)omap24xx_irda_rx_dma_callback,			     dev, &(si->rx_dma_channel))) {		printk(KERN_ERR "Failed to request IrDA Rx DMA \n");		goto err_irq;	}	if (omap_request_dma(OMAP24XX_TRIGGER_TX, "IrDA Tx DMA",			     (void *)omap24xx_irda_tx_dma_callback,			     dev, &(si->tx_dma_channel))) {		printk(KERN_ERR "Failed to request IrDA Tx DMA \n");		goto err_irq;	}	/* Allocate TX and RX buffers for DMA channels */	si->rx_buf_dma_virt =	    dma_alloc_coherent(NULL, 4096, &(si->rx_buf_dma_phys), flags);	si->tx_buf_dma_virt =	    dma_alloc_coherent(NULL, 4096, &(si->tx_buf_dma_phys), flags);	/*	 * Setup the serial port for the specified config.	 */	if ((err = read_gpio_expa(&ioExpanderVal, 0x21))) {		printk(KERN_ERR ": Error reading from I/O EXPANDER \n");		return err;	}	ioExpanderVal |= 0x01;	/* 'P6' Enable IRDA_TX and IRDA_RX */	if ((err = write_gpio_expa(ioExpanderVal, 0x21))) {		printk(KERN_ERR ": Error writing to I/O EXPANDER \n");		return err;	}	if ((err = read_gpio_expa(&ioExpanderVal, 0x21))) {		printk(KERN_ERR " Error reading from I/O EXPANDER \n");		return err;	}	err = omap24xx_irda_startup(dev);	if (err)		goto err_startup;	omap24xx_irda_set_speed(dev, si->speed = 9600);	/*	 * Open a new IrLAP layer instance.	 */	si->irlap = irlap_open(dev, &si->qos, "omap_sir");	err = -ENOMEM;	if (!si->irlap)		goto err_irlap;	/* Now enable the interrupt and start the queue  */	si->open = 1;	/* Start RX DMA */	omap24xx_irda_start_rx_dma(si);	enable_irq(dev->irq);	netif_start_queue(dev);	__ECHO_OUT;	return 0;      err_irlap:	si->open = 0;	omap24xx_irda_shutdown(si);      err_startup:      err_irq:	free_irq(dev->irq, dev);	MOD_DEC_USE_COUNT;	return err;}staticint omap24xx_irda_stop(struct net_device *dev){	struct omap24xx_irda *si = dev->priv;	__ECHO_IN;	disable_irq(dev->irq);	netif_stop_queue(dev);	omap_free_dma(si->rx_dma_channel);	omap_free_dma(si->tx_dma_channel);	dma_free_coherent(NULL, 4096, si->rx_buf_dma_virt, si->rx_buf_dma_phys);	dma_free_coherent(NULL, 4096, si->tx_buf_dma_virt, si->tx_buf_dma_phys);	omap24xx_irda_shutdown(si);	/* Stop IrLAP */	if (si->irlap) {		irlap_close(si->irlap);		si->irlap = NULL;	}	si->open = 0;	/*	 * Free resources	 */	free_irq(dev->irq, dev);	__ECHO_OUT;	return 0;}static void set_h4_gpio_expa(u8 FIR_SEL){	u8 ioExpanderVal = 0;	if (read_gpio_expa(&ioExpanderVal, 0x20) != 0) {		printk("Error reading from I/O EXPANDER \n");		return;	}	ioExpanderVal &= ~0x01;	ioExpanderVal |= FIR_SEL;	if (write_gpio_expa(ioExpanderVal, 0x20) != 0) {		printk("Error writing to I/O EXPANDER \n");		return;	}	if (read_gpio_expa(&ioExpanderVal, 0x20) != 0) {		printk("Error reading from I/O EXPANDER \n");		return;	}}static int which_speed;static void set_h4_gpio_expa_handler(void *data){	int *mode = data;	if (*mode == SIR_MODE)		set_h4_gpio_expa(0);	else if (*mode == MIR_MODE)		set_h4_gpio_expa(1);	else if (*mode == FIR_MODE)		set_h4_gpio_expa(1);}DECLARE_WORK(set_h4_gpio_expa_work, &set_h4_gpio_expa_handler, &which_speed);staticint omap24xx_irda_set_speed(struct net_device *dev, int speed){	struct omap24xx_irda *si = dev->priv;	int divisor;	__ECHO_IN;	/* Set IrDA speed */	if (speed <= 115200) {		if (in_interrupt()) {			cancel_delayed_work(&set_h4_gpio_expa_work);			which_speed = SIR_MODE;			schedule_work(&set_h4_gpio_expa_work);		} else			set_h4_gpio_expa(0);		/* SIR mode */		printk("Set SIR Mode! Speed: %d\n", speed);		writeb(1, UART3_MDR1);	/* Set SIR mode */		writeb(1, UART3_EBLR);		divisor = BASE_CLK / (16 * speed);	/* Base clock 48 MHz */		writeb(1 << 7, UART3_LCR);		writeb((divisor & 0xFF), UART3_DLL);		writeb((divisor >> 8), UART3_DLH);		writeb(0x03, UART3_LCR);		writeb(0, UART3_MCR);	} else if (speed <= 1152000) {		printk("Set MIR Mode! Speed: %d\n", speed);		writeb((1 << 2) | (1 << 6), UART3_MDR1);	/* Set MIR mode with								   SIP after each frame */		writeb(2, UART3_EBLR);		divisor = BASE_CLK / (41 * speed);		writeb(1 << 7, UART3_LCR);		writeb((divisor & 0xFF), UART3_DLL);		writeb((divisor >> 8), UART3_DLH);		writeb(0x03, UART3_LCR);		if (in_interrupt()) {			cancel_delayed_work(&set_h4_gpio_expa_work);			which_speed = MIR_MODE;			schedule_work(&set_h4_gpio_expa_work);		} else			set_h4_gpio_expa(1);	} else {		/* FIR mode */		if (in_interrupt()) {			cancel_delayed_work(&set_h4_gpio_expa_work);			which_speed = MIR_MODE;			schedule_work(&set_h4_gpio_expa_work);		} else			set_h4_gpio_expa(1);		printk("Set FIR Mode! Speed: %d\n", speed);		writeb((1 << 2) | (1 << 6) | 1, UART3_MDR1);	/* Set FIR mode								   with SIP after each frame */	}	si->speed = speed;	__ECHO_OUT;	return 0;}staticint omap24xx_irda_net_init(struct net_device *dev){	struct omap24xx_irda *si = dev->priv;	unsigned int baudrate_mask;	int err = -ENOMEM;	si = kmalloc(sizeof(struct omap24xx_irda), GFP_KERNEL);	if (!si)		goto out;	memset(si, 0, sizeof(*si));	/*	 * Initialize structures	 */	dev->priv = si;	dev->hard_start_xmit = omap24xx_irda_hard_xmit;	dev->open = omap24xx_irda_start;	dev->stop = omap24xx_irda_stop;	dev->do_ioctl = omap24xx_irda_ioctl;	dev->get_stats = omap24xx_irda_stats;	irda_device_setup(dev);	irda_init_max_qos_capabilies(&si->qos);	baudrate_mask = IR_9600 | IR_19200 | IR_38400 | IR_57600 | IR_115200;	baudrate_mask |= (IR_4000000 << 8);	si->qos.baud_rate.bits &= baudrate_mask;	si->qos.min_turn_time.bits = 7;	uart3_base =	    (unsigned long)ioremap(OMAP2420_UART3_BASE, OMAP24XX_REG_SIZE);	irda_qos_bits_to_value(&si->qos);	return 0;      out:	kfree(si);	return err;}/* * Remove all traces of this driver module from the kernel, so we can't be * called.  Note that the device has already been stopped, so we don't have * to worry about interrupts or dma. */static void omap24xx_irda_net_uninit(struct net_device *dev){	struct omap24xx_irda *si = dev->priv;	dev->hard_start_xmit = NULL;	dev->open = NULL;	dev->stop = NULL;	dev->do_ioctl = NULL;	dev->get_stats = NULL;	dev->priv = NULL;	kfree(si);}#ifdef MODULEstatic#endifint __init omap24xx_irda_init(void){	struct net_device *dev;	int err = 0;	/* OMAP24xx IR  net device register stage */	dev = alloc_irdadev(sizeof(struct omap24xx_irda));	if (dev) {		dev->irq = INT_IRDA;		dev->init = omap24xx_irda_net_init;		dev->uninit = omap24xx_irda_net_uninit;		err = register_netdev(dev);		if (err) {			kfree(dev);		} else {			netdev = dev;		}	}	return err;}#ifdef MODULEstatic#endifvoid __exit omap24xx_irda_exit(void){	struct net_device *dev = netdev;	if (dev) {		unregister_netdev(dev);		free_netdev(dev);	}	/*	 * We now know that the netdevice is no longer in use, and all	 * references to our driver have been removed.  The only structure	 * which may still be present is the netdevice, which will get	 * cleaned up by net/core/dev.c	 */}int write_gpio_expa(u8 val, int addr){	struct i2c_adapter *adap;	int err;	struct i2c_msg msg[1];	unsigned char data[1];	adap = i2c_get_adapter(0);	if (!adap)		return -ENODEV;	msg->addr = addr;	/* I2C address of GPIO EXPA */	msg->flags = 0;	msg->len = 1;	msg->buf = data;	data[0] = val;	err = i2c_transfer(adap, msg, 1);	if (err >= 0)		return 0;	return err;}int read_gpio_expa(u8 * val, int addr){	struct i2c_adapter *adap;	int err;	struct i2c_msg msg[1];	unsigned char data[1];	adap = i2c_get_adapter(0);	if (!adap)		return -ENODEV;	msg->addr = addr;	/* I2C address of GPIO EXPA */	msg->flags = I2C_M_RD;	msg->len = 2;	msg->buf = data;	err = i2c_transfer(adap, msg, 1);	*val = data[0];	printk("IRDA: I2C: Read data is %x", (u8) * data);	if (err >= 0)		return 0;	return err;}module_init(omap24xx_irda_init);module_exit(omap24xx_irda_exit);MODULE_AUTHOR("MontaVista");MODULE_DESCRIPTION("OMAP24XX IR");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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