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

📄 gspi_io.c

📁 marvell wifi driver GSPI-8385-LINUX-OMAP1510-5.0.10.p0-144-src.rar
💻 C
📖 第 1 页 / 共 2 页
字号:
	mcbsp_set_transmitter();
	mcbsp_set_receiver();

	omap_start_dma(gspiinfop -> d . dma_regs_rx, gspiinfop -> d . dmaphys_rx,
		       		(size + g_dummy_clk_ioport) * 2);
	gspi_write_for_read(gspiinfop, reg, size + g_dummy_clk_ioport); 
	wait_event_interruptible(gspiinfop -> d . queue_rx, 
			gspiinfop -> d . dma_rxack);
	gspiinfop -> d.dma_rxack = 0;

	gpio_set_high(GPIO(0));
	mcbsp_reset_receiver();
	mcbsp_reset_transmitter();
	memcpy(data,gspiinfop -> d . dmabuf_rx + (g_dummy_clk_ioport + 1) * 2, 
							size * 2);

#ifdef OMAP1510_TIMER_DEBUG
	if(tm_ind[4] + 1 < 10)
		times[4][(tm_ind[4])++] = inw(0xFFFEC500 + 0x08);
#endif

	gspi_release_io(gspiinfop);

	ret = 0;

error:	LEAVE();
	return ret;
}

int gspi_read_data(gspi_card_rec_p cardp, 
			u16 *data, u16 size)
{
	int    		ret;
	gspihost_info_p	gspiinfop;

	ENTER();

	if(!cardp) {
		ret = -EINVAL;
		goto error;
	}

	gspiinfop = cardp->ctrlr;

	if((ret = gspi_acquire_io(gspiinfop)) != GSPI_OK){
		GSPI_DEBUG("gspi_acquire_io failed\n");
		goto error;
	}

	gpio_set_low(GPIO(0));
	mcbsp_set_transmitter();
	mcbsp_set_receiver();

	omap_start_dma(gspiinfop -> d . dma_regs_rx, gspiinfop -> d . dmaphys_rx, 
				(size + g_dummy_clk_reg) * 2);
	gspi_write_for_read(gspiinfop, data[0], size + g_dummy_clk_reg); 
	wait_event_interruptible(gspiinfop -> d . queue_rx, gspiinfop -> d . dma_rxack);
	gspiinfop -> d.dma_rxack = 0;

	gpio_set_high(GPIO(0));
	mcbsp_reset_receiver();
	mcbsp_reset_transmitter();

	memcpy(data, gspiinfop -> d . dmabuf_rx + (g_dummy_clk_reg * 2), size * 2);
	gspi_release_io(gspiinfop);

	ret = 0;

error:	LEAVE();
	return ret;
}

int gspi_write_data(gspi_card_rec_p cardp, 
			u16 *data, u16 size)
{
	int    		ret;
	gspihost_info_p	gspiinfop;

	ENTER();

	if(!cardp) {
		ret = -EINVAL;
		goto error;
	}

	gspiinfop = cardp->ctrlr;

	if((ret = gspi_acquire_io(gspiinfop)) != GSPI_OK){
		GSPI_DEBUG("gspi_acquire_io failed\n");
		goto error;
	}

	gpio_set_low(GPIO(0));
	mcbsp_set_transmitter();

	data[0] |= GSPI_WRITE;

	memcpy(gspiinfop -> d . dmabuf_tx, data, size * 2);	
	omap_start_dma(gspiinfop -> d . dma_regs_tx, gspiinfop -> d . dmaphys_tx, size * 2);
	wait_event_interruptible(gspiinfop -> d . queue_tx, gspiinfop -> d . dma_txack);
	gspiinfop -> d.dma_txack = 0;

	gpio_set_high(GPIO(0));
	mcbsp_reset_transmitter();

	gspi_release_io(gspiinfop);

	ret = 0;
	
error:	LEAVE();
	return ret;
}

int gspi_write_data_direct(gspi_card_rec_p cardp, 
			u8 *data, u16 reg, u16 size)
{
	int    		ret;
	gspihost_info_p	gspiinfop;

	ENTER();

	if(!cardp) {
		ret = -EINVAL;
		goto error;
	}

	gspiinfop = cardp->ctrlr;

	if((ret = gspi_acquire_io(gspiinfop)) != GSPI_OK){
		GSPI_DEBUG("gspi_acquire_io failed\n");
		goto error;
	}

#ifdef OMAP1510_TIMER_DEBUG
	if(tm_ind[1] + 1 < 10)
		times[1][(tm_ind[1])++] = inw(0xFFFEC500 + 0x08);
#endif

	mcbsp_set_transmitter();
	gpio_set_low(GPIO(0));

	reg |= GSPI_WRITE;

	memcpy(gspiinfop -> d . dmabuf_tx, &reg, 2);	
	memcpy(gspiinfop -> d . dmabuf_tx + 2, data, (size-1) * 2);	

	omap_start_dma(gspiinfop -> d . dma_regs_tx, gspiinfop -> d . dmaphys_tx, size * 2);
	wait_event_interruptible(gspiinfop -> d . queue_tx, gspiinfop -> d . dma_txack);
	gspiinfop -> d.dma_txack = 0;

	mcbsp_reset_transmitter();
	gpio_set_high(GPIO(0));

#ifdef OMAP1510_TIMER_DEBUG
	if(tm_ind[2] + 1 < 10)
		times[2][(tm_ind[2])++] = inw(0xFFFEC500 + 0x08);
#endif

	gspi_release_io(gspiinfop);

	ret = 0;
	
error:	LEAVE();
	return ret;
}

static __inline__ void gspihost_exit(struct gspihost_info *gspiinfo)
{
	ENTER1();

	del_timer(&gspiinfo->timer);
	gspihost_close_hw(gspiinfo);
	unregister_chrdev(major, "gspihost");
	omap_free_dma(gspiinfo -> d . dma_regs_tx);
	omap_free_dma(gspiinfo -> d . dma_regs_rx);

	if(gspiinfo -> d . dmabuf_tx)
		consistent_free(gspiinfo -> d . dmabuf_tx, BUFSIZE, gspiinfo -> d . dmaphys_tx);

	if(gspiinfo -> d . dmabuf_tx_rx)
		consistent_free(gspiinfo -> d . dmabuf_tx_rx, BUFSIZE, gspiinfo -> d . dmaphys_tx_rx);

	if(gspiinfo -> d . dmabuf_rx)
		consistent_free(gspiinfo -> d . dmabuf_rx, BUFSIZE, gspiinfo -> d . dmaphys_rx);

	if (gspiinfo->card)
		kfree(gspiinfo->card);

	if (gspiinfo)
		kfree(gspiinfo);

	LEAVE1();
}

static struct gspihost_info *gspihost_init(void)
{
	struct gspihost_info 	*gspiinfo;

	ENTER();

	if ((gspiinfo = kmalloc(sizeof(gspihost_info_t), GFP_KERNEL)) == NULL) {
		GSPI_DEBUG("No memory for gspiinfo!!!\n");
		return NULL;	
	}

	memset(gspiinfo, 0, sizeof *gspiinfo);
	gspihost_init_hw(gspiinfo);
	init_timer(&gspiinfo->timer);
	init_timer(&gspiinfo->dmatimer);
	init_MUTEX(&gspiinfo->host_sem);
	gspiinfo -> d.dma_txack = 0;
	gspiinfo -> d.dma_rxack = 0;
	gspiinfo -> timer.function    = gspihost_timeout;
	gspiinfo -> timer.data        = (unsigned long)gspiinfo;
	gspiinfo -> dmatimer.function = gspihost_dma_timeout;
	gspiinfo -> dmatimer.data     = (unsigned long)gspiinfo;

	LEAVE();

	return gspiinfo;
}

gspi_notifier_rec_p register_user(gspi_notifier_rec_p notifierp)
{
	gspi_notifier_rec_p	ret;
	struct gspihost_info 	*gspiinfo = g_gspiinfo;
	gspi_card_rec_p		cardp = gspiinfo->card;

	ENTER();
	
	if (!notifierp) {
		ret = NULL;
		goto done;
	}

	if (!notifierp->add || !notifierp->remove || !notifierp->user_isr) {
		ret = NULL;
		goto done;
	}
	
	cardp->add = notifierp->add;
	cardp->remove = notifierp->remove;
	cardp->user_isr = notifierp->user_isr;

	if (notifierp->add(cardp)) {
		ret = NULL;
		goto done;
	}

	ret = notifierp;

done:
	LEAVE();

	return ret;
}

void unregister_user(gspi_notifier_rec_p notifierp)
{
	struct gspihost_info 	*gspiinfo = g_gspiinfo;
	gspi_card_rec_p		cardp = gspiinfo->card;

	if (notifierp->add == cardp->add) {
		cardp->remove(cardp);

		cardp->add =
		cardp->remove = NULL;
		cardp->user_isr = NULL;
		cardp->user_arg = NULL;
	}
}

int gspi_init_card(gspi_card_rec_p cardp)
{
	ENTER();

	/* Take the card out of reset */
	gpio_dir_output(GPIO(2));
	gpio_set_high(GPIO(2));

	LEAVE();

	return 0;
}

static void *register_card(gspi_card_rec_p cardp)
{
	void	*ret;

	ENTER1();

	if (gspi_init_card(cardp))
		ret = NULL;
	else
		ret = cardp;

	LEAVE1();

	return ret;
}

void gspi_reset(void)
{
	gpio_set_low(GPIO(2));
	udelay(10);
	gpio_set_high(GPIO(2));
}

void enable_int_gpio(int gpio_num)
{
	int gpio_reg;

	gpio_reg = inw(GPIO_INT_MASK_REG);
	outw(gpio_reg & ~(gpio_num) , GPIO_INT_MASK_REG);	
}

void disable_int_gpio(int gpio_num)
{
	int gpio_reg;

	gpio_reg = inw(GPIO_INT_MASK_REG);
	outw(gpio_reg | gpio_num , GPIO_INT_MASK_REG);	
}

int gspi_register_irq(gspihost_info_p gspiinfo)
{
	gspi_card_rec_p cardp = gspiinfo -> card;

	gspiinfo -> irq = INT_GPIO1;
	if(request_irq(gspiinfo->irq, cardp->user_isr, 0, "GPIO-IRQ", cardp->user_arg) < 0) {
		printk("gpio_irq failed \n");
		return -1;
	} 

	enable_int_gpio(GPIO(1));
	schedule_timeout(3*HZ);
	return 0;
}

void gspi_unregister_irq(gspihost_info_p gspihost)
{
	gspi_card_rec_p cardp = gspihost -> card;

	disable_int_gpio(GPIO(1));
	free_irq(gspihost -> irq, cardp -> user_arg);
}

void omap1510_timertest(void)
{
	unsigned long times1[10];
	int i=0, j;

	outl(0x22, OMAP1510_TIMER1_BASE + CNTL_TIMER);
	outl(0xFFFFFFFF, OMAP1510_TIMER1_BASE + LOAD_TIM);
	outl(0x23, OMAP1510_TIMER1_BASE + CNTL_TIMER);

	times1[i++] = inl(OMAP1510_TIMER1_BASE + READ_TIM);
	udelay(1000);
	times1[i++] = inl(OMAP1510_TIMER1_BASE + READ_TIM);
	mdelay(10);
	times1[i++] = inl(OMAP1510_TIMER1_BASE + READ_TIM);
	outl(0x2A, OMAP1510_TIMER1_BASE + CNTL_TIMER);
	times1[i++] = inl(OMAP1510_TIMER1_BASE + READ_TIM);

	for(j=0;j < i-1; ++j)
		printk("The diff b/w %d and %d is %lu\n", j, j+1, times1[j]-times1[j+1]);
}

static int __init gspihost_module_init(void)
{
	int			ret = -ENODEV;
	struct gspihost_info 	*gspiinfo;
	gspi_card_rec_p		cardp;

	ENTER();
	
	if(!(gspiinfo = gspihost_init())) {
		GSPI_DEBUG("gspihost_init failed\n");
		goto out;
	}
	
	g_gspiinfo = gspiinfo;
	
	if(!(cardp = kmalloc(sizeof(io_card_rec_t), GFP_KERNEL))) {
		GSPI_DEBUG("No memory for Card Record!!!\n");
		ret = -ENOMEM;
		goto out;
	}

	if (register_chrdev(major, "gspihost", &gspihost_fops) < 0) {
		GSPI_DEBUG1("register_chrdev failed\n");
		goto err_free;
	}

	memset(cardp, 0, sizeof(io_card_rec_t));
	memcpy(cardp->magic, "GSPI", 4);
	init_waitqueue_head(&gspiinfo -> d . queue_tx);
        init_waitqueue_head(&gspiinfo -> d . queue_rx);
	
	cardp->ctrlr = gspiinfo;
	gspiinfo->card = cardp;

	if (!register_card(cardp)) {
		GSPI_DEBUG("gspihost_register failed\n");
		goto err_free;
	}

	ret = 0;
	goto out;
	
err_free:
	kfree(cardp);
	gspiinfo->card = NULL;

out:
	LEAVE();
	return ret;
}

static void __exit gspihost_module_exit(void)
{
	ENTER();

	gspihost_exit(g_gspiinfo);

	printk("GSPI Host Controller Driver for Linux removed.\n");
	LEAVE();
}

module_init(gspihost_module_init);
module_exit(gspihost_module_exit);
MODULE_LICENSE("Proprietary");

MODULE_PARM(clkdiv, "i");
MODULE_PARM_DESC(clkdiv, "Will specify SPI bus CLKDIV(Clock divisor) value."
			 "Usage insmod gspi.o clkdiv=0 / 1 / 2...(20 Mhz, 10 Mhz, 5 Mhz ..) ");

⌨️ 快捷键说明

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