Example #1
0
static ssize_t bma020_show_accel_value(struct device *dev,struct device_attribute *attr, char *buf)
{   
	bma020acc_t accel; 
	
	bma020_set_mode(BMA020_MODE_NORMAL);
	bma020_set_range(BMA020_RANGE_2G); 
	bma020_set_bandwidth(BMA020_BW_100HZ);
	
	bma020_read_accel_xyz( &accel);	
    return sprintf(buf, "%d,%d,%d\n", accel.x,accel.y,accel.z);
}
Example #2
0
static void bma_work_func_acc(struct work_struct *work)
{
	bma020acc_t acc;
	int err;
		
	err = bma020_read_accel_xyz(&acc);
	
	input_report_abs(bma020.acc_input_dev, ABS_X, acc.x);
	input_report_abs(bma020.acc_input_dev, ABS_Y, acc.y);
	input_report_abs(bma020.acc_input_dev, ABS_Z, acc.z);
	input_sync(bma020.acc_input_dev);
}
Example #3
0
static int bma020_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data)
{

	bma020acc_t acc;
	bma020_set_mode( BMA020_MODE_NORMAL );
	bma020_read_accel_xyz(&acc);
	p += sprintf(p,"[BMA020]\nX axis: %d\nY axis: %d\nZ axis: %d\n" , acc.x, acc.y, acc.z);
	len = (p - page) - off;
	if (len < 0) {
		len = 0;
	}

	*eof = (len <= count) ? 1 : 0;
	*start = page + off;
	return len;
}
int bma020_ioctl(struct inode *inode, struct file *filp, unsigned int ioctl_num,  unsigned long arg)
{
    bma020acc_t accels;
    unsigned int arg_data;
    int err = 0;

    gprintk("start\n");
    switch( ioctl_num )
    {
    case IOCTL_BMA020_GET_ACC_VALUE :
    {
        bma020_read_accel_xyz( &accels );

        gprintk( "acc data x = %d  /  y =  %d  /  z = %d\n", accels.x, accels.y, accels.z );

        if( copy_to_user( (bma020acc_t*)arg, &accels, sizeof(bma020acc_t) ) )
        {
            err = -EFAULT;
        }

    }
    break;

    case IOC_SET_ACCELEROMETER :
    {
        if( copy_from_user( (unsigned int*)&arg_data, (unsigned int*)arg, sizeof(unsigned int) ) )
        {

        }
        if( arg_data == BMA020_POWER_ON )
        {
            printk( "ioctl : bma020 power on\n" );
            bma020_set_mode( BMA020_MODE_NORMAL );
        }
        else
        {
            printk( "ioctl : bma020 power off\n" );
            bma020_set_mode( BMA020_MODE_SLEEP );
        }
    }
    break;
    default :
        break;
    }
    return err;

}
int bma020_read_accel_avg(int num_avg, bma020acc_t *min, bma020acc_t *max, bma020acc_t *avg )
{
   long x_avg=0, y_avg=0, z_avg=0;   
   int comres=0;
   int i;
   bma020acc_t accel;		                /* read accel data */

   x_avg = 0; y_avg=0; z_avg=0;                  
   max->x = -512; max->y =-512; max->z = -512;
   min->x = 512;  min->y = 512; min->z = 512; 
     

	 for (i=0; i<num_avg; i++) {
	 	comres += bma020_read_accel_xyz(&accel);      /* read 10 acceleration data triples */
		accel.y = -accel.y;
		accel.z = -accel.z;
		
		if (accel.x>max->x)
			max->x = accel.x;
		if (accel.x<min->x) 
			min->x=accel.x;

		if (accel.y>max->y)
			max->y = accel.y;
		if (accel.y<min->y) 
			min->y=accel.y;

		if (accel.z>max->z)
			max->z = accel.z;
		if (accel.z<min->z) 
			min->z=accel.z;
		
		x_avg+= accel.x;
		y_avg+= accel.y;
		z_avg+= accel.z;

		bma020_pause(10);
     }
	 avg->x = x_avg /= num_avg;                             /* calculate averages, min and max values */
	 avg->y = y_avg /= num_avg;
	 avg->z = z_avg /= num_avg;
	 return comres;
}
int bma020_acc_start(void)
{
    int result;

    struct device *dev_t;

    bma020acc_t accels; /* only for test */
    printk("%s \n",__func__);

    result = register_chrdev( BMA150_MAJOR, ACC_DEV_NAME, &acc_fops);

    if (result < 0)
    {
        return result;
    }

    acc_class = class_create (THIS_MODULE, "BMA-dev");

    if (IS_ERR(acc_class))
    {
        unregister_chrdev( BMA150_MAJOR, ACC_DEV_NAME);
        return PTR_ERR( acc_class );
    }

    dev_t = device_create( acc_class, NULL, MKDEV(BMA150_MAJOR, 0), "%s", "accelerometer");

    if (IS_ERR(dev_t))
    {
        return PTR_ERR(dev_t);
    }

    result = i2c_acc_bma020_init();

    if(result)
    {
        return result;
    }

    bma020_chip_init();

    gprintk("[BMA020] read_xyz ==========================\n");
    bma020_read_accel_xyz( &accels );
    gprintk("[BMA020] x = %d  /  y =  %d  /  z = %d\n", accels.x, accels.y, accels.z );

    gprintk("[BMA020] ===================================\n");

    /* only for test */
#if 0
    printk( "before get xyz\n" );
    mdelay(3000);

    while(1)
    {
        bma020_read_accel_xyz( &accels );

        printk( "acc data x = %d  /  y =  %d  /  z = %d\n", accels.x, accels.y, accels.z );

        mdelay(100);
    }
#endif

#ifdef BMA020_PROC_FS
    create_proc_read_entry(DRIVER_PROC_ENTRY, 0, 0, bma020_proc_read, NULL);
#endif	//BMA020_PROC_FS

    bma020_set_mode(BMA020_MODE_SLEEP);
    gprintk("[BMA020] set_mode BMA020_MODE_SLEEP\n");

    return 0;
}
int bma020_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,  unsigned long arg)
{
    int err = 0;
    unsigned char data[6];

    /* check cmd */
    if(_IOC_TYPE(cmd) != BMA150_IOC_MAGIC)
    {
#if DEBUG
        printk("cmd magic type error\n");
#endif
        return -ENOTTY;
    }
    if(_IOC_NR(cmd) > BMA150_IOC_MAXNR)
    {
#if DEBUG
        printk("cmd number error\n");
#endif
        return -ENOTTY;
    }

    if(_IOC_DIR(cmd) & _IOC_READ)
        err = !access_ok(VERIFY_WRITE,(void __user*)arg, _IOC_SIZE(cmd));
    else if(_IOC_DIR(cmd) & _IOC_WRITE)
        err = !access_ok(VERIFY_READ, (void __user*)arg, _IOC_SIZE(cmd));
    if(err)
    {
#if DEBUG
        printk("cmd access_ok error\n");
#endif
        return -EFAULT;
    }
#if 0
    /* check bam150_client */
    if( bma150_client == NULL)
    {
#if DEBUG
        printk("I2C driver not install\n");
#endif
        return -EFAULT;
    }
#endif

    switch(cmd)
    {
    case BMA150_READ_ACCEL_XYZ:
        err = bma020_read_accel_xyz((bma020acc_t*)data);
        if(copy_to_user((bma020acc_t*)arg,(bma020acc_t*)data,6)!=0)
        {
#if DEBUG
            printk("copy_to error\n");
#endif
            return -EFAULT;
        }
        return err;

    case BMA150_SET_RANGE:
        if(copy_from_user(data,(unsigned char*)arg,1)!=0)
        {
#if DEBUG
            printk("[BMA150] copy_from_user error\n");
#endif
            return -EFAULT;
        }
        err = bma020_set_range(*data);
        return err;

    case BMA150_SET_MODE:
        if(copy_from_user(data,(unsigned char*)arg,1)!=0)
        {
#if DEBUG
            printk("[BMA150] copy_from_user error\n");
#endif
            return -EFAULT;
        }
        err = bma020_set_mode(*data);
        return err;

    case BMA150_SET_BANDWIDTH:
        if(copy_from_user(data,(unsigned char*)arg,1)!=0)
        {
#if DEBUG
            printk("[BMA150] copy_from_user error\n");
#endif
            return -EFAULT;
        }
        err = bma020_set_bandwidth(*data);
        return err;

    default:
        return 0;
    }
}
Example #8
0
int bma020_acc_start(void)
{
	int result,err;
	struct input_dev *input_dev;

	struct device *dev_t;
	
	bma020acc_t accels; 
	
	result = register_chrdev( ACC_DEV_MAJOR, ACC_DEV_NAME, &acc_fops);

	if (result < 0) 
	{
		return result;
	}
	
	acc_class = class_create (THIS_MODULE, ACC_DEV_NAME);
	
	if (IS_ERR(acc_class)) 
	{
		unregister_chrdev( ACC_DEV_MAJOR, ACC_DEV_NAME);
		return PTR_ERR( acc_class );
	}

	dev_t = device_create( acc_class, NULL, MKDEV(ACC_DEV_MAJOR, 0), "%s", ACC_DEV_NAME);

	if (IS_ERR(dev_t)) 
	{
		return PTR_ERR(dev_t);
	}
	
	/*For testing*/
	if (device_create_file(dev_t, &dev_attr_acc_file) < 0)
		printk("Failed to create device file %s \n", dev_attr_acc_file.attr.name);
	
	mutex_init(&bma020.power_lock);

	/* hrtimer settings.  we poll for light values using a timer. */
	hrtimer_init(&bma020.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	bma020.acc_poll_delay = ns_to_ktime(240 * NSEC_PER_MSEC);
	bma020.timer.function = bma_timer_func;

	/* the timer just fires off a work queue request.  we need a thread
	   to read the i2c (can be slow and blocking). */
	bma020.wq = create_singlethread_workqueue("bma_wq");
	if (!bma020.wq) {
		err = -ENOMEM;
		printk("%s: could not create workqueue\n", __func__);
		goto err_create_workqueue;
	}
	/* this is the thread function we run on the work queue */
	INIT_WORK(&bma020.work_acc, bma_work_func_acc);

	/* allocate lightsensor-level input_device */
	input_dev = input_allocate_device();
	if (!input_dev) {
		printk("%s: could not allocate input device\n", __func__);
		err = -ENOMEM;
		goto err_input_allocate_device_light;
	}
	input_set_drvdata(input_dev, &bma020);
	input_dev->name = "accel";


	set_bit(EV_ABS, input_dev->evbit);	
	/* acceleration x-axis */
	input_set_capability(input_dev, EV_ABS, ABS_X);
	input_set_abs_params(input_dev, ABS_X, -1024, 1024, 0, 0);
	/* acceleration y-axis */
	input_set_capability(input_dev, EV_ABS, ABS_Y);
	input_set_abs_params(input_dev, ABS_Y, -1024, 1024, 0, 0);
	/* acceleration z-axis */
	input_set_capability(input_dev, EV_ABS, ABS_Z);
	input_set_abs_params(input_dev, ABS_Z, -1024, 1024, 0, 0);

	printk("registering lightsensor-level input device\n");
	err = input_register_device(input_dev);
	if (err < 0) {
		printk("%s: could not register input device\n", __func__);
		input_free_device(input_dev);
		goto err_input_register_device_light;
	}
	bma020.acc_input_dev = input_dev;


	err = sysfs_create_group(&input_dev->dev.kobj,&acc_attribute_group);
	if (err) {
		printk("Creating bma020 attribute group failed");
		goto error_device;
	}
//////////////////////////////////////////////////////////////////////////////
	
	result = i2c_acc_bma020_init();

	if(result)
	{
		return result;
	}

	bma020_chip_init();

	gprintk("[BMA020] read_xyz ==========================\n");
	bma020_read_accel_xyz( &accels );
	gprintk("[BMA020] x = %d  /  y =  %d  /  z = %d\n", accels.x, accels.y, accels.z );

	gprintk("[BMA020] ===================================\n");	

#ifdef BMA020_PROC_FS
	create_proc_read_entry(DRIVER_PROC_ENTRY, 0, 0, bma020_proc_read, NULL);
#endif	//BMA020_PROC_FS

	bma020_set_mode(BMA020_MODE_SLEEP);
	gprintk("[BMA020] set_mode BMA020_MODE_SLEEP\n");
	
	return 0;
error_device:
	sysfs_remove_group(&input_dev->dev.kobj, &acc_attribute_group);
err_input_register_device_light:
	input_unregister_device(bma020.acc_input_dev);
err_input_allocate_device_light:	
	destroy_workqueue(bma020.wq);
err_create_workqueue:
	mutex_destroy(&bma020.power_lock);
exit:
	return err;
}