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

📄 gspi_io_cpu_new.c

📁 linux 基于mips 架构cpu 的红外驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
                        //while(!(readb(spi_base+REG_SPSR) & 0x04));    //wait until empty
                }
        }


	spi_chipsel(spi, 1);
	enable_irq(spi->irq);

	return 0;
}
EXPORT_SYMBOL(gspi_write_data_direct);

int gspi_read_reg(gspi_card_rec_p cardp, u16 reg, u16 * val)
{
	gspi_read_data_direct(cardp, (u8 *)val, reg, 2);
	return 0;
}
EXPORT_SYMBOL(gspi_read_reg);

int gspi_write_reg(gspi_card_rec_p cardp, u16 reg, u16 val)
{
	gspi_write_data_direct(cardp, (u8 *)&val, reg, 2);
	return 0;
}
EXPORT_SYMBOL(gspi_write_reg);

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

	s3c2410_gpio_cfgpin(S3C2410_GPG12, S3C2410_GPG12_EINT20);
	gspiinfo->irq = IRQ_EINT20;
	

	err = request_irq(gspiinfo->irq, cardp->user_isr, SA_SHIRQ, "W8686 interrupt", cardp->user_arg);
	if (err) {
		printk("Cannot claim IRQ %d\n", gspiinfo->irq);
		return -1;
	}

	set_irq_type(gspiinfo->irq, IRQT_FALLING);
	
	schedule_timeout(3 * HZ);

	return 0;
}
EXPORT_SYMBOL(gspi_register_irq);
		
void gspi_unregister_irq(gspihost_info_p gspihost)
{
	gspi_card_rec_p cardp = gspihost->card;
	free_irq(gspihost->irq, cardp->user_arg);
}
EXPORT_SYMBOL(gspi_unregister_irq);

gspi_notifier_rec_p register_user(gspi_notifier_rec_p notifierp)
{
	gspi_notifier_rec_p ret;
	gspihost_info_p gspiinfo = G_gspiinfo;
	gspi_card_rec_p cardp = gspiinfo->card;

	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:

	return ret;
}
EXPORT_SYMBOL(register_user);

void unregister_user(gspi_notifier_rec_p notifierp)
{
	gspihost_info_p gspiinfo = G_gspiinfo;
	gspi_card_rec_p cardp = gspiinfo->card;

	if (notifierp->add == cardp->add) {
		cardp->remove(cardp);
		cardp->add = NULL;
		cardp->remove = NULL;
		cardp->user_isr = NULL;
		cardp->user_arg = NULL;
	}
}
EXPORT_SYMBOL(unregister_user);

void gspi_reset(void)
{
}
EXPORT_SYMBOL(gspi_reset);


/*************************************************************************/

static int w8686_probe(struct platform_device *pdev)
{
	struct s3c24xx_spi *spi;
	gspi_card_rec_p cardp;
	struct resource *res;
	int err = 0;

	spi = kmalloc(sizeof(*spi), GFP_KERNEL);
	if (spi == NULL){
		dev_err(&pdev->dev, "No memory for spi info\n");
		err = -ENOMEM;
		goto err_no_mem; 
	}

	G_gspiinfo = spi;

	cardp = kmalloc(sizeof(io_card_rec_t), GFP_KERNEL);
	if (cardp == NULL){
		dev_err(&pdev->dev, "No memory for card record\n");
		err = -ENOMEM;
		goto err_no_card_mem;
	}
	memset(cardp, 0, sizeof(io_card_rec_t));
	memcpy(cardp->magic, "GSPI", 4); 

	cardp->ctrlr = spi;
	spi->card = cardp;
/*
	if (pdev->dev.platform_data == NULL) {
		dev_err(&pdev->dev, "No platform data supplied\n");
		err = -ENOENT;
		goto err_no_pdata;
	}
*/
	spi->pdev = pdev;
	spi->dev = &pdev->dev;
//	spi->pdata = pdev->dev.platform_data;

//	platform_set_drvdata(pdev, spi);
	
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL) {
		dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n");
		err = -ENOENT;
		goto err_no_iores;
	}

	spi->ioarea = request_mem_region(res->start,
					(res->end - res->start) + 1,
					pdev->name);

	if (spi->ioarea == NULL) {
		dev_err(&pdev->dev, "Cannot reserve region\n");
		err = -ENXIO;
		goto err_no_iores;
	}
	
	spi->regs = ioremap(res->start, (res->end - res->start) + 1);
	if (spi->regs == NULL) {
		dev_err(&pdev->dev, "Cannot map IO\n");
		err = -ENXIO;
		goto err_no_iomap;
	}

	spi->clk = clk_get(&pdev->dev, "spi");
	if (IS_ERR(spi->clk)) {
		dev_err(&pdev->dev, "No clock for device\n");
		err = PTR_ERR(spi->clk);
		goto err_no_clk;
	}

	clk_enable(spi->clk);

	//if (!spi->pdata->set_cs)
	//	s3c2410_gpio_cfgpin(spi->pdata->pin_cs, S3C2410_GPIO_OUTPUT);

	//CS
	s3c2410_gpio_cfgpin(S3C2410_GPG2, S3C2410_GPG2_OUTP);
	//-------------
	s3c2410_gpio_cfgpin(S3C2410_GPE11, S3C2410_GPE11_SPIMISO0);
	s3c2410_gpio_cfgpin(S3C2410_GPE12, S3C2410_GPE12_SPIMOSI0);
	s3c2410_gpio_cfgpin(S3C2410_GPE13, S3C2410_GPE13_SPICLK0);

	spi_chipsel(spi, 1);
	
	writeb(S3C2400_SPPIN_nCS, spi->regs + S3C2410_SPPIN);
	writeb(0x07, spi->regs + S3C2410_SPPRE); //0x01

	spi_poll_setup(spi);

	spi->dma_chan = SPI_DMA_CHAN;
	err = s3c2410_dma_request(spi->dma_chan, &spi_dma_client, spi->dev);
	if (err) {
		dev_err(&pdev->dev, "Failed to get dma channel\n");
		goto err_dma_request;
	}

	spi->dma_map = kmalloc(MAX_DMA_SIZE, GFP_DMA);
	if (!spi->dma_map) {
		dev_err(&pdev->dev, "not enough dma memory!\n");
		goto err_no_dma_mem;
	}

	init_completion(&spi->dma_done);

	return 0;

err_no_dma_mem:
	s3c2410_dma_free(spi->dma_chan, &spi_dma_client);
	
err_dma_request:
	clk_disable(spi->clk);
	clk_put(spi->clk);

err_no_clk:
	iounmap(spi->regs);

err_no_iomap:
	release_resource(spi->ioarea);
	kfree(spi->ioarea);

err_no_iores:
err_no_pdata:
	kfree(cardp);

err_no_card_mem:
	kfree(spi);

err_no_mem:
	return err;
}

static int w8686_remove(struct platform_device *pdev)
{
	struct s3c24xx_spi *spi = platform_get_drvdata(pdev);

	if (spi) {

		platform_set_drvdata(pdev, NULL);

		kfree(spi->dma_map);

		s3c2410_dma_free(spi->dma_chan, &spi_dma_client);
	
		clk_disable(spi->clk);
		clk_put(spi->clk);

		iounmap(spi->regs);
	
		release_resource(spi->ioarea);
		kfree(spi->ioarea);

		kfree(spi->card);

		kfree(spi);
	}

	return 0;
}

#ifdef CONFIG_PM
static int w8686_suspend(struct platform_device *dev, pm_message_t state)
{
	return 0;
}

static int w8686_resume(struct platform_device *dev)
{
	return 0;
}

#else
#define w8686_suspend	NULL
#define w8686_resume	NULL
#endif

static struct platform_driver w8686_driver = {
	.driver		= {
		.name	= "s3c2410-spi0",
		.owner	= THIS_MODULE,
	},
	.probe		= w8686_probe,
	.remove		= w8686_remove,
	.suspend	= w8686_suspend,
	.resume		= w8686_resume,
};

static int __init gspihost_module_init(void)
{
	return platform_driver_register(&w8686_driver);
}

static void __exit gspihost_module_exit(void)
{
	platform_driver_unregister(&w8686_driver);
}

module_init(gspihost_module_init);
module_exit(gspihost_module_exit);

MODULE_DESCRIPTION("Marvell 88W8686 on S3C2442 Driver");
MODULE_AUTHOR("lost panjet, <panjet@gmail.com");
MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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