1. 程式人生 > >ARM9 ADS8344 SPI驅動移植 (一)

ARM9 ADS8344 SPI驅動移植 (一)

#include <linux/delay.h>
#include <linux/device.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/spi/spi.h>
#include <asm/uaccess.h>
#include <linux/kernel.h>
#include <linux/cache.h>
#include <linux/mutex.h>
#include <linux/spi/spi.h>

#define AVERAGETIMES 4
static int send2user=0;

static struct {
    struct spi_device *spi;
    struct class   *ads8344_class;
    int     major;
    struct mutex  lock;
} ads38344_data;


static inline int spi_nor_setup(struct spi_device *spi, u8 bst_len)
{
 spi->bits_per_word = bst_len << 3;
 return spi_setup(spi);
}


static ssize_t ads8344_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
{
    char __user readResult[2];
    readResult[0] =(char __user)(send2user&0XFF);
    readResult[1] =(char __user)((send2user>>8)&0XFF);
    copy_to_user(buf,readResult,sizeof(readResult));
    return sizeof(readResult);
 }

static ssize_t ads8344_write(struct file *file, const char __user *data,
                                   size_t len, loff_t *ppos)
{
 return 0;
}

static int ads8344_open(struct inode *inode, struct file *file)
{
 return 0;
}

static int ads8344_release(struct inode *inode, struct file *file)
{
 return 0;
}

static int ads8344_ioctl(struct inode *inode, struct file *file,
       unsigned int cmd, unsigned long arg)
{
    send2user=0X00000000;
    u8 channel,revData[AVERAGETIMES][3];
    u8 control_word;
    int ret = 0, i,k,z;
    int temp[AVERAGETIMES][3]; 
    pr_debug("ioctl cmd %d is issued...\n", cmd);

    if((cmd>7)||(cmd<0))
    return -EINVAL;

    switch (cmd) {
         case 0: channel = 0; break;
         case 1: channel = 4; break;
         case 2: channel = 1; break;
         case 3: channel = 5; break;
         
         case 4: channel = 2; break;
         case 5: channel = 6; break;
         case 6: channel = 3; break;
         case 7: channel = 7; break;
         
        default: channel = 0; break;
    }

    mutex_lock(&ads8344_data.lock);

    for (i = 0; i < AVERAGETIMES; i++) {
            control_word = (1u << 7)|(channel << 4)|(1u << 2)|0x3;
            ret = spi_write_then_read(ads8344_data.spi, &control_word, 1,revData[i],3);
            if (ret)
            break;
    }

    mutex_unlock(&ads8344_data.lock);

    if (ret)
    return -EIO;

    for(k=0;k<AVERAGETIMES;k++)
    {
        temp[k][0]=(int)revData[k][0];
        temp[k][1]=(int)revData[k][1];
        temp[k][2]=(int)revData[k][2];
    }

    for(z=0;z<AVERAGETIMES;z++)
    {
        send2user += ((temp[z][0]<<16)|(temp[z][1]<<8)|temp[z][2])>>7;
    }

    send2user= send2user>>2;
    send2user &=0xffff; 
    return ret;
}

//裝置檔案訪問操作介面
static const struct file_operations ads8344_fops = {
 .owner  = THIS_MODULE,
 .read  = ads8344_read,
 .write  = ads8344_write,
 .open  = ads8344_open,
 .release = ads8344_release,
 .ioctl  = ads8344_ioctl,
};

static int ads8344_probe(struct spi_device *spi) //監測系統是否有ads8344裝置,並進行設備註冊
{
 printk("we has find spi dev\n");
 int ret = 0;
 struct device *dev;
 printk("we find spi dev! \n");
 mutex_init(&ads8344_data.lock); //初始化lock訊號量
 ads8344_data.spi = spi_dev_get(spi); //獲取SPI裝置
 aads8344_data.major = 0; //定義主裝置號

 ret = register_chrdev(ads8344_data.major, "ads8344", &ads8344_fops);//註冊字元裝置
 if (ret < 0)
  return ret;