Android linux adc驱动(s5pv210)

Android linux adc驱动(s5pv210)


struct adc_sensor_t{
	struct s3c_adc_client 	*client;
	struct class		*class;
	struct cdev 		cdev;
	dev_t 			devno;
	int		data;	
	unsigned char		channel;
};

static struct adc_sensor_t adc_sensor_dev;

static ssize_t adc_sensor_read(struct file *file, char __user *buff, size_t count, loff_t *offset)
{
	//unsigned data;
	//unsigned ch;
	//data = 10;
	//ch = 0;
	adc_sensor_dev.data = s3c_adc_read(adc_sensor_dev.client, 
				adc_sensor_dev.channel);
	DLOG(KERN_INFO "data AIN%d is %d\n", adc_sensor_dev.channel, adc_sensor_dev.data);

	if(copy_to_user(buff, 
		(char *)&adc_sensor_dev.data, 
			sizeof(int)))
		return -EFAULT;

	return 0;
}

static long adc_sensor_ioctl(
	struct file *filp,unsigned int cmd,unsigned long arg)
{
	if(cmd == ADC_SENSOR_IOCTL_SETCH){
		if(arg >= ADC_CHANNEL_NUM) return -1;
		adc_sensor_dev.channel = arg;
	}
	
	return 0;
}

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

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

static struct file_operations adc_sensor_fops = {
	.owner = THIS_MODULE,
	.unlocked_ioctl = adc_sensor_ioctl,
	.read = adc_sensor_read,
	.open = adc_sensor_open,
	.release = adc_sensor_release,
};


static int __devinit adc_sensor_probe( struct platform_device *pdev )
{
	struct device *dev = &pdev->dev;
	int ret = -EINVAL;

	DLOG("%s start\n", __func__);
	adc_sensor_dev.devno = MKDEV(DEVICE_MAJOR, DEVICE_MINOR);

	ret = register_chrdev_region(adc_sensor_dev.devno, 
			DEVICE_NUMBER, DEVICE_NAME);
	if(ret < 0){
		ret = alloc_chrdev_region(&adc_sensor_dev.devno, 0, DEVICE_NUMBER, DEVICE_NAME);
		if(ret < 0){
			dev_err(dev, "failed to register device number\n");
			goto err_register_chrdev_region;
		}
	}

	cdev_init(&adc_sensor_dev.cdev, &adc_sensor_fops);
	adc_sensor_dev.cdev.owner = THIS_MODULE;
	ret = cdev_add(&adc_sensor_dev.cdev, 
			adc_sensor_dev.devno, DEVICE_NUMBER);
	if( ret ){
		dev_err(dev, "failed to add device\n");
		goto err_cdev_add;
	}

	adc_sensor_dev.client = s3c_adc_register (pdev, NULL, NULL, 0);
	if(IS_ERR(adc_sensor_dev.client)){
		dev_err(dev, "failed to register adc client\n");
		goto err_s3c_adc_register;
	}
	adc_sensor_dev.class = class_create(THIS_MODULE, DEVICE_NAME);
	if(IS_ERR(adc_sensor_dev.class)){
		DLOG(KERN_ERR "%s:failed to  class_create\n", __func__);
		goto err_class_create;
	}
	device_create(adc_sensor_dev.class, NULL, adc_sensor_dev.devno, NULL, DEVICE_NAME);

	adc_sensor_dev.channel = 4;
	adc_sensor_dev.data = 0;

	return 0;

err_class_create:
err_s3c_adc_register:
	cdev_del(&adc_sensor_dev.cdev );
err_cdev_add:
	unregister_chrdev_region(adc_sensor_dev.devno, DEVICE_NUMBER);
err_register_chrdev_region:
	return ret;
}

static int __devexit adc_sensor_remove(struct platform_device *pdev)
{
	s3c_adc_release(adc_sensor_dev.client);
	cdev_del(&adc_sensor_dev.cdev );
	device_destroy(adc_sensor_dev.class, adc_sensor_dev.devno);
	class_destroy(adc_sensor_dev.class);
	unregister_chrdev_region(adc_sensor_dev.devno, DEVICE_NUMBER);
	return 0;
}

static struct platform_driver adc_sensor_driver = {
	.driver = {
		.name = "adc",
		.owner = THIS_MODULE,
	},
	.probe = adc_sensor_probe,
	.remove = __devexit_p(adc_sensor_remove)
};

static int __init adc_sensor_init(void)
{
	return platform_driver_register(&adc_sensor_driver );
}

static void __exit adc_sensor_exit (void)
{
	platform_driver_unregister(&adc_sensor_driver );
}

module_init(adc_sensor_init);
module_exit(adc_sensor_exit);

MODULE_AUTHOR("jvaemape");
MODULE_DESCRIPTION("S3C2440 ADC Sensor Drive");
MODULE_LICENSE("Dual BSD/GPL");


你可能感兴趣的:(linux,android)