#include <linux/platform_device.h> #include <linux/delay.h> #include <linux/fs.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/uaccess.h> #include <linux/clk.h> #include <asm-arm/plat-s3c24xx/regs-spi.h> #include <asm-arm/arch-s3c2410/regs-gpio.h> #include <asm/io.h> #include <asm/arch/map.h> #include <asm-arm/plat-s3c24xx/clock.h> #include <asm/arch/regs-clock.h>
#define DEVICE_NAME "s3c2410-spi" static char tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x8e}; static int opencount=0; static void __iomem *spi_base; static struct clk *spi_clock; //就是这个地方,浪费了我好多时间
static inline void spi_send(unsigned char val) { unsigned long flags; local_irq_save(flags); clk_enable(spi_clock); //就是这个地方,浪费了我好多时间
while((readb(spi_base+S3C2410_SPSTA)&0x01) != 0x01); writeb(val, spi_base+S3C2410_SPTDAT); s3c2410_gpio_setpin(S3C2410_GPH1, 0); udelay(10); s3c2410_gpio_setpin(S3C2410_GPH1, 1); local_irq_restore(flags); } static ssize_t s3c2410_hc595_write(struct file *file, const char *buffer, size_t count,loff_t * ppos) { char sendbuffer[4]; char num=0; int tensdigit=0; int singledigit=0; if( copy_from_user(sendbuffer, buffer, count)) { kfree( sendbuffer ); printk(" return -EFAULT;\n"); return -EFAULT; } singledigit=(sendbuffer[0])%10; tensdigit=(int)(sendbuffer[0]/10); num=tab[singledigit]; spi_send(num); udelay(100); num=tab[tensdigit]; spi_send(num); udelay(100); return 0; } static int s3c2410_hc595_open(struct inode *inode, struct file *file) { if(opencount==1) return -EBUSY; opencount++; s3c2410_gpio_setpin(S3C2410_GPH1, 0); printk("device open\n"); return 0; } static int s3c2410_hc595_release(struct inode *inode, struct file *filp) { opencount--; s3c2410_gpio_setpin(S3C2410_GPH1, 1); printk("device release\n"); return 0; }
static struct file_operations s3c2410_595_fops = { .owner = THIS_MODULE, .write = s3c2410_hc595_write, .open = s3c2410_hc595_open, .release = s3c2410_hc595_release, }; static int s3c2410_tube_probe(struct platform_device *pdev) { unsigned long base; unsigned char value; int ret; s3c2410_gpio_cfgpin(S3C2410_GPE11, S3C2410_GPE11_SPIMISO0); s3c2410_gpio_pullup(S3C2410_GPE11, 0); s3c2410_gpio_cfgpin(S3C2410_GPE12, S3C2410_GPE12_SPIMOSI0); s3c2410_gpio_pullup(S3C2410_GPE12, 0); s3c2410_gpio_cfgpin(S3C2410_GPE13, S3C2410_GPE13_SPICLK0); s3c2410_gpio_pullup(S3C2410_GPE13, 1); base = pdev->resource[0].start; if (!request_mem_region(base, 0x20, DEVICE_NAME)) { ret = -EBUSY; printk("---------------failed-----------------\n"); return ret; } spi_base = ioremap(base, 0x40); //就是这个地方,浪费了我好多时间
spi_clock = clk_get(&pdev->dev, "spi"); if (spi_clock == NULL) { printk(KERN_INFO "failed to find clock source\n"); return -ENOENT; } clk_enable(spi_clock); //就是这个地方,浪费了我好多时间
value = (0<<5)|(1<<4)|(1<<3)|(0<<2)|(0<<1); writeb(value, spi_base+S3C2410_SPCON); value = 33; writeb(value, spi_base+S3C2410_SPPRE); value = 2; writeb(value, spi_base+S3C2410_SPPIN); s3c2410_gpio_cfgpin(S3C2410_GPH1, S3C2410_GPH1_OUTP); s3c2410_gpio_pullup(S3C2410_GPH1, 1); ret = register_chrdev(0, DEVICE_NAME, &s3c2410_595_fops); if(!ret) printk("--------------failed-----------------\n"); printk("74HC595 initialized for tubes!\n"); return 0; } static struct platform_driver s3c2410_tube = { .probe = s3c2410_tube_probe, .driver = { .name = "s3c2410-spi", .owner = THIS_MODULE, }, }; int __init s3c2410tube_init(void) { return platform_driver_register(&s3c2410_tube); } void __exit s3c2410tube_exit(void) { platform_driver_unregister(&s3c2410_tube); } module_init(s3c2410tube_init); module_exit(s3c2410tube_exit); MODULE_AUTHOR("yanqiang-liu@163.com"); MODULE_DESCRIPTION("Tube driver for the s3c2410"); MODULE_LICENSE("GPL");
|