Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1138039
  • 博文数量: 241
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 2279
  • 用 户 组: 普通用户
  • 注册时间: 2012-11-27 19:53
个人简介

JustForFun

文章分类

全部博文(241)

文章存档

2023年(8)

2022年(2)

2021年(3)

2020年(30)

2019年(11)

2018年(27)

2017年(54)

2016年(83)

2015年(23)

我的朋友

分类: LINUX

2018-12-16 21:52:10

drivers/spi/spi_test.c 这个文件可以细看,是详细分析spi驱动的好文件。
//ili9225g.c驱动,屏驱动芯片ili9225芯片
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#include
//#include "ili9225g.h"

/* IOCTL commands */

#define ILI9225G_IOC_MAGIC            's'

#define ILI9225G_IOC_WR_BUFFER_SIZE        _IOW(ILI9225G_IOC_MAGIC, 2, __u32)
#define ILI9225G_IOC_BACKLIGHT_CONTROL    _IOW(ILI9225G_IOC_MAGIC, 3, __u32)

static struct spi_device    *spi;
static unsigned long        buffer_size=220*176*2;
static unsigned char        *buffer;


struct ili9225g_board_info
{
    int reset_gpio;
    int rs_gpio;
    int backlight_gpio;
    int te_gpio;
};

#define SPIDEV_MAJOR            153    /* assigned */

static struct class *ili9225g_class;

struct ili9225g_board_info ili9225g_board = {
    .reset_gpio = GPIO_PB(17),
    .rs_gpio = GPIO_PB(18),
    .backlight_gpio = GPIO_PC(9),
    .te_gpio = GPIO_PA(22),
};

#define RESET(a) do{gpio_direction_output(ili9225g_board.reset_gpio, a);}while(0)
#define RS(a) do{gpio_direction_output(ili9225g_board.rs_gpio, a);}while(0)
#define TE(a) do{gpio_direction_output(ili9225g_board.te_gpio, a);}while(0)
#define BACKLIGHT(a) do{gpio_direction_output(ili9225g_board.backlight_gpio, a);}while(0)

static int write_command(unsigned char value_l,unsigned char value_h)
{
    unsigned short data;
    int ret;
    struct spi_message msg;
    struct spi_transfer t[] = {
        {
            .tx_buf = &data,
            .len = 2,
            .delay_usecs = 0,
        }
    };

    RS(0);
    data = value_l|(value_h<<8);
    spi_message_init(&msg);
    spi_message_add_tail(&t[0], &msg);
    ret = spi_sync(spi, &msg); 
  
    RS(1);
    if (ret < 0)
    {
       return -1;
    }
    return 0;
}

static int write_data(unsigned char value_l,unsigned char value_h)
{
    unsigned short data;
    int ret;
    struct spi_message msg;
    struct spi_transfer t[] = {
        {
            .tx_buf = &data,
            .len = 2,
            .delay_usecs = 0,
        }
    };
    data = value_l|(value_h<<8);
    spi_message_init(&msg);
    spi_message_add_tail(&t[0], &msg);
    ret = spi_sync(spi, &msg);   
    if (ret < 0)
    {
       return -1;
    }
    return 0;
}

static void inti_ili9225g(void)
{
    printk("inti_ili9225g\n");       
    RESET(1);                                                            
    mdelay(1);                                                         
    RESET(0);                                                            
    mdelay(10);                                                        
    RESET(1);                                                           
    mdelay(200);                                                       
    write_command(0x00,0xD0),
    write_data(0x00,0x03),

    write_command(0x00,0xEB),
    write_data(0x0B,0x00),
   
    write_command(0x00,0xEC),
    write_data(0x00,0x4F),

    write_command(0x00,0xC7),
    write_data(0x03,0x0F), //**

    write_command(0x00,0x01),
    write_data(0x01,0x1C),

    write_command(0x00,0x02),
    write_data(0x01,0x00),

    write_command(0x00,0x03),
    write_data(0x10,0x30), //1230 RGB/BGR  16/18Bit

    write_command(0x00,0x07),
    write_data(0x00,0x00),
   
    write_command(0x00,0x08),
    write_data(0x08,0x08),
   
    write_command(0x00,0x0F),
    write_data(0x09,0x01),

    mdelay(50);   //delay 50 ms;


    write_command(0x00,0x10),
    write_data(0x00,0x00),
   
    write_command(0x00,0x11),
    write_data(0x1B,0x41),

    mdelay(50);

    write_command(0x00,0x12),
    write_data(0x20,0x0E),

    write_command(0x00,0x13),
    write_data(0x00,0x58),  //GVDD4.4
   
    write_command(0x00,0x14),
    write_data(0x4A,0x47),  //VCOM


    write_command(0x00,0x30),
    write_data(0x00,0x00),

    write_command(0x00,0x31),
    write_data(0x00,0xdb),

    write_command(0x00,0x32),
    write_data(0x00,0x00),

    write_command(0x00,0x33),
    write_data(0x00,0x00),

    write_command(0x00,0x34),
    write_data(0x00,0xdb),

    write_command(0x00,0x35),
    write_data(0x00,0x00),

    write_command(0x00,0x36),
    write_data(0x00,0xAF),

    write_command(0x00,0x37),
    write_data(0x00,0x00),

    write_command(0x00,0x38),
    write_data(0x00,0xDB),

    write_command(0x00,0x39),
    write_data(0x00,0x00),



    write_command(0x00,0x50),
    write_data(0x00,0x00),

    write_command(0x00,0x51),
    write_data(0x05,0x03),

    write_command(0x00,0x52),
    write_data(0x0C,0x06),

    write_command(0x00,0x53),
    write_data(0x04,0x00),

    write_command(0x00,0x54),
    write_data(0x06,0x0C),

    write_command(0x00,0x55),
    write_data(0x03,0x05),

    write_command(0x00,0x56),
    write_data(0x00,0x00),

    write_command(0x00,0x57),
    write_data(0x00,0x04),

    write_command(0x00,0x58),
    write_data(0x0E,0x00),

    write_command(0x00,0x59),
    write_data(0x00,0x0E),

    write_command(0x00,0x20),
    write_data(0x00,0x00),

    write_command(0x00,0x21),
    write_data(0x00,0x00),

    write_command(0x00,0x07),
    write_data(0x10,0x17),
   
    mdelay(200);                                                     
    write_command(0x00,0x22);                                        
   
}                            

static int ili9225g_open(struct inode *inode,struct file *file)
{
    printk("ili9225g_open\n");
    return 0;   
}
static int ili9225g_read(struct file *file, char __user *user_buf, size_t size, loff_t *ppos)
{
    return 0;
}
static int spi_write_array_data(const char *buf,size_t count)
{
    int ret;
    struct spi_message msg;   
    struct spi_transfer t[]={
       {
           .tx_buf = buf,
           .len    = count,
           .delay_usecs= 0,
        },
    };
       
    spi_message_init(&msg);
    spi_message_add_tail(&t[0], &msg);
    ret = spi_sync(spi, &msg);   
    if (ret < 0)
    {
       return -1;
    }  
    return 0;
}
static int ili9225g_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)

    int ret,tmp;
    unsigned char        *p;
    tmp=count;
    if(tmp>buffer_size){
        printk("buffer size too big\n");
        tmp=buffer_size;
    }
    ret=copy_from_user(buffer,buf,tmp);
    if(ret != 0)
        return -ENOMEM;
    p=buffer;
    TE(0);
    spi_write_array_data(p,tmp);
    TE(1);
    return 0;
}

static long ili9225g_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
    int state;
    switch(cmd)
    {
        case ILI9225G_IOC_WR_BUFFER_SIZE:
            kfree(buffer);
            buffer_size=*(unsigned long*)arg;
            buffer = kmalloc(buffer_size, GFP_KERNEL);
            if (!buffer) {
                return -ENOMEM;
            }
            printk("1 args's %ld\n",*(unsigned long*)arg);
            break;

        case ILI9225G_IOC_BACKLIGHT_CONTROL:
            state=*(unsigned long*)arg;
            BACKLIGHT(state);
            break;           
           
        default:
            printk("cmd:%x,arg=%ld",cmd,*(unsigned long*)arg);       
    }
   
    return 0;
}

static const struct file_operations ili9225g_fops =
{                  
    .owner = THIS_MODULE,
    .open  = ili9225g_open,
    .read  = ili9225g_read,
    .write = ili9225g_write,
    .unlocked_ioctl = ili9225g_ioctl,
};
//字符设备
static struct cdev *ili9225g_cdev;
struct device *class_dev;

static int ili9225g_spidev_probe(struct spi_device *spi_dev)
{
    /* Initialize the driver data */
    printk("ili9225g_spidev_probe\n");   
    spi = spi_dev;
    TE(1);
    inti_ili9225g(); 
#if 0       
    int i=0;
    for(i=0;i<176*220;i++)
        write_data(0x01,0xf0);
#endif   
    buffer = kmalloc(buffer_size, GFP_KERNEL);
    if(buffer==NULL)
        printk("kmalloc error\n");
    return 0;
}

static int ili9225g_spidev_remove(struct spi_device *spi_dev)
{
    spi = NULL;
    return 0;
}


static struct spi_driver spidev_spi_driver = {
    .driver = {
        .name =        "spidev",
        .owner =    THIS_MODULE,
    },
    .probe = ili9225g_spidev_probe,
    .remove = ili9225g_spidev_remove,
};


static int __init ili9225g_init(void)
{
    int ret,status;
    //这是设备号的数据类型
    dev_t ili9225g_devid;
    //申请gpio管脚资源
    ret = gpio_request(ili9225g_board.reset_gpio,"ili9225g_reset");      
    if(ret){                                                        
          printk("gpio requrest fail %d\n",ili9225g_board.reset_gpio);
    }                                                                

    ret = gpio_request(ili9225g_board.rs_gpio,"ili9225g_rs");      
    if(ret){                                                        
          printk("gpio requrest fail %d\n",ili9225g_board.rs_gpio);
    }                                                                

    ret = gpio_request(ili9225g_board.backlight_gpio,"ili9225g_backlight");      
    if(ret){                                                        
          printk("gpio requrest fail %d\n",ili9225g_board.backlight_gpio);
    }                                                                

    ret = gpio_request(ili9225g_board.te_gpio,"ili9225g_te");      
    if(ret){                                                        
          printk("gpio requrest fail %d\n",ili9225g_board.te_gpio);
    }                                                                

    //申请设备号,还有一个函数register_chrdev_region也是可以
    alloc_chrdev_region(&ili9225g_devid, 0, 32768, "ili9225g");
#if 1
    //动态申请cdev内存
    ili9225g_cdev = cdev_alloc();
    //初始化cdev成员,建立cdev与file_operations之间的联系
    cdev_init(ili9225g_cdev, &ili9225g_fops);
    ili9225g_cdev->owner = THIS_MODULE;
    //向系统添加一个cdev字符设备,完成cdev注册
    cdev_add(ili9225g_cdev, ili9225g_devid, 1); 
#else   
    register_chrdev(231, "ili9225g", &ili9225g_fops);
#endif
    //创建class目录下的文件
    ili9225g_class=class_create(THIS_MODULE, "ili9225g");
    class_dev=device_create(ili9225g_class, NULL, ili9225g_devid, NULL, "ili9225g");
   
    status = spi_register_driver(&spidev_spi_driver);
    if (status < 0) {
        unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name);
    }

    return 0;
}


static void __exit ili9225g_exit(void)
{
    printk("ili9225g_exit\n");   
   
    gpio_free(ili9225g_board.rs_gpio);
    gpio_free(ili9225g_board.reset_gpio);
    gpio_free(ili9225g_board.backlight_gpio);
   
    kfree(buffer);
      spi_unregister_driver(&spidev_spi_driver);
#if 1   
    cdev_del(ili9225g_cdev);
#else
    //    unregister_chrdev(231, "ili9225g");
#endif
    device_unregister(class_dev);
    class_destroy(ili9225g_class);
}
module_init(ili9225g_init);
module_exit(ili9225g_exit);
//MODULE_LICENSE("GPL v2");
MODULE_LICENSE("GPL");

////////////////////////////////////////////////////////////
//ili9225g_test.c
 #include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#define BUF_SIZE (220*176*2)

#define RW 20
#define RH 20

void drawRect(short * buffer ,int x,int y){
    int i ;
    for( i = 0;i<220*176;i++){
        buffer[i] = 0x001f;
    }

    for( i = 0;i         buffer[y*176+x+i]        = 0xf800;
        buffer[(y+RH)*176+x+i]    = 0xf800;
    }
   
    for( i = 0;i         buffer[x+(y+i)*176]        = 0xf800;
        buffer[RW+x+(y+i)*176]    = 0xf800;
    }
}

int main()
{
    int ret;
    int fd;
        fd=open("/dev/ili9225g",O_RDWR);
    if(fd<0){
        printf("can't open device\n");
        return -1;
    }
    unsigned char buf[BUF_SIZE];
     unsigned char buf1[BUF_SIZE];
      unsigned char buf2[BUF_SIZE];
    //   5         6                5
    //RRRR RGGG  GGGB BBBB
    //char c='a';
    int i;
#if 1    
    for(i = 0;i         buf[i++] = 0xf8;
        buf[i++] = 0x00;
    }

    for(i = 0;i         buf1[i++] = 0x07;
        buf1[i++] = 0xe0;
    }
   
    for(i = 0;i         buf2[i++] = 0x00;
        buf2[i++] = 0x1f;
    }

#endif
    struct timespec time1 = {0, 0}; 
    int j=30;
   
    clock_gettime(CLOCK_MONOTONIC, &time1); 
    long long t=((long long)time1.tv_sec*1000000 + (long long)time1.tv_nsec/1000);
//    printf("CLOCK_REALTIME: %d, %d\n", time1.tv_sec, time1.tv_nsec/1000); 
    int x=0;
    while(1){     
    x++;
    if((x+RW)>=220)x = 0;
        drawRect((short *)buf,x,30);
        write(fd,buf,BUF_SIZE);
  //      usleep(200*1000);
    }   
    clock_gettime(CLOCK_MONOTONIC, &time1); 
    long long t1=((long long)time1.tv_sec*1000000 + (long long)time1.tv_nsec/1000);
    printf("CLOCK_REALTIME1: %d\n",(t1-t)/1000);

    return 0 ;
}




阅读(2328) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~