static int bma020_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data) { char *p = page; int len = 0; mutex_lock(&bma020.power_lock); printk("bma222_proc_read\n"); bma020_set_mode( BMA020_MODE_NORMAL ); bma020.state |= ACC_ENABLED; bma_acc_enable(); mutex_unlock(&bma020.power_lock); len = (p - page) - off; if (len < 0) { len = 0; } printk("bma_proc_read: success full\n"); *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; }
static int bma020_accelerometer_suspend( struct platform_device* pdev, pm_message_t state ) { printk(" %s \n",__func__); bma020_set_mode( BMA020_MODE_SLEEP ); if (bma020.state & ACC_ENABLED) bma_acc_disable(); return 0; }
static int bma020_accelerometer_resume( struct platform_device* pdev ) { printk(" %s \n",__func__); if (bma020.state & ACC_ENABLED) bma_acc_enable(); bma020_set_mode( BMA020_MODE_NORMAL ); return 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); }
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_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; }
static void bma020_late_resume(struct early_suspend *handler) { printk( "%s : Set MODE NORMAL\n", __func__ ); bma020_set_mode( BMA020_MODE_NORMAL ); }
static void bma020_early_suspend(struct early_suspend *handler) { printk( "%s : Set MODE SLEEP\n", __func__ ); bma020_set_mode( BMA020_MODE_SLEEP ); }
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; } }
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; }