S3C6410 AD驱动(三)--- 驱动源代码

/***********wzk_adc.h *********/


#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/clk.h>
#include <asm/irq.h>
#include <mach/gpio.h>
#include <mach/regs-gpio.h>
#include <mach/gpio-bank-f.h>
#include <mach/map.h>                   //S3C64XX_VA_GPIO
#include <plat/gpio-cfg.h>
#include <mach/hardware.h>
#include <linux/io.h>
#include <asm/io.h>


#include <plat/regs-timer.h>
#include <plat/regs-adc.h>
#include <mach/regs-clock.h>

/*
#include <linux/sched.h>
#include <linux/poll.h>
#include <linux/interrupt.h>
#include <linux/semaphore.h>
#include <linux/timer.h>

#include <asm/irq.h>
#include <asm/uaccess.h>
#include <mach/irqs.h>

#include <linux/timer.h>
#include <linux/jiffies.h>
*/

static void __iomem *base_addr;
static struct clk *adc_clock;

#define ADCCON (SAMSUNG_PA_ADC + S3C_ADCCON)
#define ADCTSC (SAMSUNG_PA_ADC + S3C_ADCTSC)
#define ADCDAT0 (SAMSUNG_PA_ADC + S3C_ADCDAT0)

#define DEVICE_NAME     "adc"

static volatile unsigned long *adccon, *adctsc,*adcdat0;


 

/***********wzk_adc.c*************/


#include "wzk_adc.h"

//#define ADCCON (*(volatile unsigned*)0x7e00b000)

void adc_remap(void)
{
	adccon = ioremap(ADCCON,0x04);
	adctsc = ioremap(ADCTSC,0x04);
	adcdat0 = ioremap(ADCDAT0,0x04);
}

void adc_unmap(void)
{
	iounmap(adccon);
	iounmap(adctsc);
	iounmap(adcdat0);
}

void active_clk(void)
{
	adc_clock = clk_get(NULL,"adc");
	if(!adc_clock)
	{
		printk(KERN_ERR"active clock error!\n");
		return;
	}
	printk("active successed!\n");

	clk_enable(adc_clock);
	return;
}

void disable_clk(void)
{
	if(adc_clock)
	{
		clk_disable(adc_clock);
		clk_put(adc_clock);
		adc_clock = NULL;
	}

	return;
}

//init dev
int init_adc(void)
{
	unsigned tmp;
	writel(0x7fc1,adccon);
	tmp = readl(adccon);
	printk("adccon:%x\n",tmp);

/*
	tmp = readl(adctsc);
	tmp = tmp & 0xfb;
	writel(tmp,adctsc);
	tmp = readl(adctsc);
	printk("adctsc:%x\n",tmp);
*/
	return 0;
}

unsigned int get_adc(void)
{
	unsigned tmp;
	tmp = readl(adccon);
	tmp = tmp | 0x0001;
	writel(tmp,adccon);

	tmp = readl(adccon);
	while(tmp & 0x0001)
	{
		tmp = readl(adccon);
	}
	
	tmp = readl(adccon);
	while(!(tmp & 0x8000))
	{
		tmp = readl(adccon);
	}
	tmp = readl(adcdat0);
	
	
	return (tmp & 0x03ff);
}
	
//close adc
void close_adc(void)
{
	
	return;
}

int s3c6410_adc_open(struct inode *inode,struct file *file)
{
	//init device
	init_adc();

	return 0;
}

int s3c6410_adc_close(struct inode *inode,struct file *file)
{
	close_adc();
	return 0;
}

static int s3c6410_adc_read(struct file *filp,char __user *buff,size_t count,loff_t *offp)
{
	return 0;
}

static unsigned int s3c6410_adc_poll(struct file *file,struct poll_table_struct *wait)
{
	return 0;
}

static long s3c6410_adc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	//TCNTB0
	
	return (long)get_adc();
}

static struct file_operations s3c6410_adc_fops = {
	.owner	= THIS_MODULE,
	.open = s3c6410_adc_open,
	.unlocked_ioctl	= s3c6410_adc_ioctl,
	.release = s3c6410_adc_close,
	.read = s3c6410_adc_read,
	.poll = s3c6410_adc_poll
};

static struct cdev cdev_adc;
struct class * my_class;
dev_t devno;

static int __init s3c6410_adc_init(void)
{
	int ret;
//	dev_t devno;
	printk(KERN_NOTICE "enter s3c6410_adc_init\n");


//	devno = MKDEV(KEY_MAJOR,0);

	ret = alloc_chrdev_region(&devno,0,1,DEVICE_NAME);
	if(ret)
	{
		printk(KERN_NOTICE "can not register led device");
		return ret;
	}
	
	cdev_init(&cdev_adc,&s3c6410_adc_fops);
	cdev_adc.owner = THIS_MODULE;

	ret =cdev_add(&cdev_adc,devno,1);
	if(ret)
	{
		printk(KERN_NOTICE "can not add leds device");
		return ret;
	}

	my_class = class_create(THIS_MODULE,DEVICE_NAME);
	if(IS_ERR(my_class))
	{
		printk("Err: Failed in creating class\n");
		return -1;	
	}

	device_create(my_class,NULL,devno,NULL,DEVICE_NAME);

//	init_dev();

/*
	base_addr = ioremap(SAMSUNG_PA_ADC,0x20);
	if(base_addr == NULL)
	{
		printk(KERN_ERR"railed to remap register block\n");
		return -ENOMEM;
	}
*/
	adc_remap();
	active_clk();

	printk(DEVICE_NAME " initialized\n");

	return 0;
}

static void __exit s3c6410_adc_exit(void)
{
	disable_clk();
	adc_unmap();
	
	device_destroy(my_class,devno);
	class_destroy(my_class);

	cdev_del(&cdev_adc);

	unregister_chrdev_region(devno,1);	

	printk(KERN_NOTICE "s3c6410_adc_exit\n");
}


module_init(s3c6410_adc_init);
module_exit(s3c6410_adc_exit);

MODULE_LICENSE("GPL");


 

你可能感兴趣的:(S3C6410 AD驱动(三)--- 驱动源代码)