📄 gspi_io_cpu_new.c
字号:
//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 + -